зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1258751: Delete the CoreGraphics backend. r=mstange
This commit is contained in:
Родитель
8377010e6a
Коммит
cd84eadb22
|
@ -1467,7 +1467,6 @@ public:
|
|||
static bool DoesBackendSupportDataDrawtarget(BackendType aType);
|
||||
|
||||
#ifdef XP_DARWIN
|
||||
static already_AddRefed<DrawTarget> CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize);
|
||||
static already_AddRefed<GlyphRenderingOptions>
|
||||
CreateCGGlyphRenderingOptions(const Color &aFontSmoothingBackgroundColor);
|
||||
#endif
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,227 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_gfx_DrawTargetCG_h
|
||||
#define mozilla_gfx_DrawTargetCG_h
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#else
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#endif
|
||||
|
||||
#include "2D.h"
|
||||
#include "Rect.h"
|
||||
#include "PathCG.h"
|
||||
#include "SourceSurfaceCG.h"
|
||||
#include "GLDefs.h"
|
||||
#include "Tools.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
static inline CGAffineTransform
|
||||
GfxMatrixToCGAffineTransform(const Matrix &m)
|
||||
{
|
||||
CGAffineTransform t;
|
||||
t.a = m._11;
|
||||
t.b = m._12;
|
||||
t.c = m._21;
|
||||
t.d = m._22;
|
||||
t.tx = m._31;
|
||||
t.ty = m._32;
|
||||
return t;
|
||||
}
|
||||
|
||||
static inline Rect
|
||||
CGRectToRect(CGRect rect)
|
||||
{
|
||||
return Rect(rect.origin.x,
|
||||
rect.origin.y,
|
||||
rect.size.width,
|
||||
rect.size.height);
|
||||
}
|
||||
|
||||
static inline Point
|
||||
CGPointToPoint(CGPoint point)
|
||||
{
|
||||
return Point(point.x, point.y);
|
||||
}
|
||||
|
||||
static inline void
|
||||
SetStrokeOptions(CGContextRef cg, const StrokeOptions &aStrokeOptions)
|
||||
{
|
||||
switch (aStrokeOptions.mLineCap)
|
||||
{
|
||||
case CapStyle::BUTT:
|
||||
CGContextSetLineCap(cg, kCGLineCapButt);
|
||||
break;
|
||||
case CapStyle::ROUND:
|
||||
CGContextSetLineCap(cg, kCGLineCapRound);
|
||||
break;
|
||||
case CapStyle::SQUARE:
|
||||
CGContextSetLineCap(cg, kCGLineCapSquare);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (aStrokeOptions.mLineJoin)
|
||||
{
|
||||
case JoinStyle::BEVEL:
|
||||
CGContextSetLineJoin(cg, kCGLineJoinBevel);
|
||||
break;
|
||||
case JoinStyle::ROUND:
|
||||
CGContextSetLineJoin(cg, kCGLineJoinRound);
|
||||
break;
|
||||
case JoinStyle::MITER:
|
||||
case JoinStyle::MITER_OR_BEVEL:
|
||||
CGContextSetLineJoin(cg, kCGLineJoinMiter);
|
||||
break;
|
||||
}
|
||||
|
||||
CGContextSetLineWidth(cg, aStrokeOptions.mLineWidth);
|
||||
CGContextSetMiterLimit(cg, aStrokeOptions.mMiterLimit);
|
||||
|
||||
// XXX: rename mDashLength to dashLength
|
||||
if (aStrokeOptions.mDashLength > 0) {
|
||||
// we use a regular array instead of a std::vector here because we don't want to leak the <vector> include
|
||||
CGFloat *dashes = new CGFloat[aStrokeOptions.mDashLength];
|
||||
for (size_t i=0; i<aStrokeOptions.mDashLength; i++) {
|
||||
dashes[i] = aStrokeOptions.mDashPattern[i];
|
||||
}
|
||||
CGContextSetLineDash(cg, aStrokeOptions.mDashOffset, dashes, aStrokeOptions.mDashLength);
|
||||
delete[] dashes;
|
||||
}
|
||||
}
|
||||
|
||||
class GlyphRenderingOptionsCG : public GlyphRenderingOptions
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsCG, override)
|
||||
|
||||
explicit GlyphRenderingOptionsCG(const Color &aFontSmoothingBackgroundColor)
|
||||
: mFontSmoothingBackgroundColor(aFontSmoothingBackgroundColor)
|
||||
{}
|
||||
|
||||
const Color &FontSmoothingBackgroundColor() const { return mFontSmoothingBackgroundColor; }
|
||||
|
||||
virtual FontType GetType() const override { return FontType::MAC; }
|
||||
|
||||
private:
|
||||
Color mFontSmoothingBackgroundColor;
|
||||
};
|
||||
|
||||
class DrawTargetCG : public DrawTarget
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCG, override)
|
||||
friend class BorrowedCGContext;
|
||||
friend class UnboundnessFixer;
|
||||
friend class SourceSurfaceCGBitmapContext;
|
||||
DrawTargetCG();
|
||||
virtual ~DrawTargetCG();
|
||||
|
||||
virtual DrawTargetType GetType() const override;
|
||||
virtual BackendType GetBackendType() const override;
|
||||
virtual already_AddRefed<SourceSurface> Snapshot() override;
|
||||
virtual void DetachAllSnapshots() override { MarkChanged(); }
|
||||
|
||||
virtual void DrawSurface(SourceSurface *aSurface,
|
||||
const Rect &aDest,
|
||||
const Rect &aSource,
|
||||
const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
virtual void DrawFilter(FilterNode *aNode,
|
||||
const Rect &aSourceRect,
|
||||
const Point &aDestPoint,
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
virtual void MaskSurface(const Pattern &aSource,
|
||||
SourceSurface *aMask,
|
||||
Point aOffset,
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
virtual void FillRect(const Rect &aRect,
|
||||
const Pattern &aPattern,
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
|
||||
|
||||
//XXX: why do we take a reference to SurfaceFormat?
|
||||
bool Init(BackendType aType, const IntSize &aSize, SurfaceFormat&);
|
||||
bool Init(BackendType aType, unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat);
|
||||
bool Init(CGContextRef cgContext, const IntSize &aSize);
|
||||
|
||||
// Flush if using IOSurface context
|
||||
virtual void Flush() override;
|
||||
|
||||
virtual void DrawSurfaceWithShadow(SourceSurface *, const Point &, const Color &, const Point &, Float, CompositionOp) override;
|
||||
virtual void ClearRect(const Rect &) override;
|
||||
virtual void CopySurface(SourceSurface *, const IntRect&, const IntPoint&) override;
|
||||
virtual void StrokeRect(const Rect &, const Pattern &, const StrokeOptions&, const DrawOptions&) override;
|
||||
virtual void StrokeLine(const Point &, const Point &, const Pattern &, const StrokeOptions &, const DrawOptions &) override;
|
||||
virtual void Stroke(const Path *, const Pattern &, const StrokeOptions &, const DrawOptions &) override;
|
||||
virtual void Fill(const Path *, const Pattern &, const DrawOptions &) override;
|
||||
virtual void FillGlyphs(ScaledFont *, const GlyphBuffer&, const Pattern &, const DrawOptions &, const GlyphRenderingOptions *) override;
|
||||
virtual void Mask(const Pattern &aSource,
|
||||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions = DrawOptions()) override;
|
||||
virtual void PushClip(const Path *) override;
|
||||
virtual void PushClipRect(const Rect &aRect) override;
|
||||
virtual void PopClip() override;
|
||||
virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromNativeSurface(const NativeSurface&) const override { return nullptr;}
|
||||
virtual already_AddRefed<DrawTarget> CreateSimilarDrawTarget(const IntSize &, SurfaceFormat) const override;
|
||||
virtual already_AddRefed<PathBuilder> CreatePathBuilder(FillRule) const override;
|
||||
virtual already_AddRefed<GradientStops> CreateGradientStops(GradientStop *, uint32_t,
|
||||
ExtendMode aExtendMode = ExtendMode::CLAMP) const override;
|
||||
virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
|
||||
|
||||
virtual void *GetNativeSurface(NativeSurfaceType) override;
|
||||
|
||||
virtual IntSize GetSize() override { return mSize; }
|
||||
|
||||
virtual void SetTransform(const Matrix &aTransform) override;
|
||||
|
||||
/* This is for creating good compatible surfaces */
|
||||
virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat) const override;
|
||||
virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const override;
|
||||
CGContextRef GetCGContext() {
|
||||
return mCg;
|
||||
}
|
||||
|
||||
// 32767 is the maximum size supported by cairo. We clamp to that to make it
|
||||
// easier to interoperate.
|
||||
static size_t GetMaxSurfaceSize() {
|
||||
return 32767;
|
||||
}
|
||||
|
||||
private:
|
||||
void MarkChanged();
|
||||
|
||||
IntSize mSize;
|
||||
CGColorSpaceRef mColorSpace;
|
||||
CGContextRef mCg;
|
||||
CGAffineTransform mOriginalTransform;
|
||||
|
||||
/**
|
||||
* The image buffer, if the buffer is owned by this class.
|
||||
* If the DrawTarget was created for a pre-existing buffer or if the buffer's
|
||||
* lifetime is managed by CoreGraphics, mData will be null.
|
||||
* Data owned by DrawTargetCG will be deallocated in the destructor.
|
||||
*/
|
||||
AlignedArray<uint8_t> mData;
|
||||
|
||||
RefPtr<SourceSurfaceCGContext> mSnapshot;
|
||||
bool mMayContainInvalidPremultipliedData;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -37,7 +37,6 @@
|
|||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include "mozilla/Vector.h"
|
||||
#include "ScaledFontMac.h"
|
||||
#include "DrawTargetCG.h"
|
||||
#include "CGTextDrawing.h"
|
||||
#endif
|
||||
|
||||
|
@ -869,6 +868,19 @@ private:
|
|||
CGContextRef mCG;
|
||||
};
|
||||
|
||||
static inline CGAffineTransform
|
||||
GfxMatrixToCGAffineTransform(const Matrix &m)
|
||||
{
|
||||
CGAffineTransform t;
|
||||
t.a = m._11;
|
||||
t.b = m._12;
|
||||
t.c = m._21;
|
||||
t.d = m._22;
|
||||
t.tx = m._31;
|
||||
t.ty = m._32;
|
||||
return t;
|
||||
}
|
||||
|
||||
/***
|
||||
* We have to do a lot of work to draw glyphs with CG because
|
||||
* CG assumes that the origin of rects are in the bottom left
|
||||
|
@ -1053,47 +1065,16 @@ DrawTargetSkia::ReturnCGContext(CGContextRef aCGContext)
|
|||
CGContextRef
|
||||
BorrowedCGContext::BorrowCGContextFromDrawTarget(DrawTarget *aDT)
|
||||
{
|
||||
if (aDT->GetBackendType() == BackendType::SKIA) {
|
||||
DrawTargetSkia* skiaDT = static_cast<DrawTargetSkia*>(aDT);
|
||||
return skiaDT->BorrowCGContext(DrawOptions());
|
||||
} else if (aDT->GetBackendType() == BackendType::COREGRAPHICS) {
|
||||
DrawTargetCG* cgDT = static_cast<DrawTargetCG*>(aDT);
|
||||
cgDT->Flush();
|
||||
cgDT->MarkChanged();
|
||||
|
||||
// swap out the context
|
||||
CGContextRef cg = cgDT->mCg;
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return nullptr;
|
||||
}
|
||||
cgDT->mCg = nullptr;
|
||||
|
||||
// save the state to make it easier for callers to avoid mucking with things
|
||||
CGContextSaveGState(cg);
|
||||
|
||||
return cg;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false);
|
||||
return nullptr;
|
||||
DrawTargetSkia* skiaDT = static_cast<DrawTargetSkia*>(aDT);
|
||||
return skiaDT->BorrowCGContext(DrawOptions());
|
||||
}
|
||||
|
||||
void
|
||||
BorrowedCGContext::ReturnCGContextToDrawTarget(DrawTarget *aDT, CGContextRef cg)
|
||||
{
|
||||
if (aDT->GetBackendType() == BackendType::SKIA) {
|
||||
DrawTargetSkia* skiaDT = static_cast<DrawTargetSkia*>(aDT);
|
||||
skiaDT->ReturnCGContext(cg);
|
||||
return;
|
||||
} else if (aDT->GetBackendType() == BackendType::COREGRAPHICS) {
|
||||
DrawTargetCG* cgDT = static_cast<DrawTargetCG*>(aDT);
|
||||
|
||||
CGContextRestoreGState(cg);
|
||||
cgDT->mCg = cg;
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(false);
|
||||
DrawTargetSkia* skiaDT = static_cast<DrawTargetSkia*>(aDT);
|
||||
skiaDT->ReturnCGContext(cg);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -34,10 +34,6 @@
|
|||
#include "ScaledFontFontconfig.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_DARWIN
|
||||
#include "DrawTargetCG.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include "DrawTargetD2D1.h"
|
||||
#include "ScaledFontDWrite.h"
|
||||
|
@ -319,17 +315,6 @@ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFor
|
|||
}
|
||||
break;
|
||||
}
|
||||
#elif defined XP_DARWIN
|
||||
case BackendType::COREGRAPHICS:
|
||||
case BackendType::COREGRAPHICS_ACCELERATED:
|
||||
{
|
||||
RefPtr<DrawTargetCG> newTarget;
|
||||
newTarget = new DrawTargetCG();
|
||||
if (newTarget->Init(aBackend, aSize, aFormat)) {
|
||||
retVal = newTarget;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SKIA
|
||||
case BackendType::SKIA:
|
||||
|
@ -402,15 +387,6 @@ Factory::CreateDrawTargetForData(BackendType aBackend,
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef XP_DARWIN
|
||||
case BackendType::COREGRAPHICS:
|
||||
{
|
||||
RefPtr<DrawTargetCG> newTarget = new DrawTargetCG();
|
||||
if (newTarget->Init(aBackend, aData, aSize, aStride, aFormat))
|
||||
return newTarget.forget();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_CAIRO
|
||||
case BackendType::CAIRO:
|
||||
{
|
||||
|
@ -458,11 +434,9 @@ Factory::DoesBackendSupportDataDrawtarget(BackendType aType)
|
|||
case BackendType::DIRECT2D1_1:
|
||||
case BackendType::RECORDING:
|
||||
case BackendType::NONE:
|
||||
case BackendType::COREGRAPHICS_ACCELERATED:
|
||||
case BackendType::BACKEND_LAST:
|
||||
return false;
|
||||
case BackendType::CAIRO:
|
||||
case BackendType::COREGRAPHICS:
|
||||
case BackendType::SKIA:
|
||||
return true;
|
||||
}
|
||||
|
@ -475,12 +449,7 @@ Factory::GetMaxSurfaceSize(BackendType aType)
|
|||
{
|
||||
switch (aType) {
|
||||
case BackendType::CAIRO:
|
||||
case BackendType::COREGRAPHICS:
|
||||
return DrawTargetCairo::GetMaxSurfaceSize();
|
||||
#ifdef XP_MACOSX
|
||||
case BackendType::COREGRAPHICS_ACCELERATED:
|
||||
return DrawTargetCG::GetMaxSurfaceSize();
|
||||
#endif
|
||||
#ifdef USE_SKIA
|
||||
case BackendType::SKIA:
|
||||
return DrawTargetSkia::GetMaxSurfaceSize();
|
||||
|
@ -777,36 +746,6 @@ Factory::CreateSourceSurfaceForCairoSurface(cairo_surface_t* aSurface, const Int
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef XP_DARWIN
|
||||
already_AddRefed<DrawTarget>
|
||||
Factory::CreateDrawTargetForCairoCGContext(CGContextRef cg, const IntSize& aSize)
|
||||
{
|
||||
if (!AllowedSurfaceSize(aSize)) {
|
||||
gfxCriticalError(LoggerOptionsBasedOnSize(aSize)) << "Failed to allocate a surface due to invalid size (CG) " << aSize;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> retVal;
|
||||
|
||||
RefPtr<DrawTargetCG> newTarget = new DrawTargetCG();
|
||||
|
||||
if (newTarget->Init(cg, aSize)) {
|
||||
retVal = newTarget;
|
||||
}
|
||||
|
||||
if (mRecorder && retVal) {
|
||||
return MakeAndAddRef<DrawTargetRecording>(mRecorder, retVal);
|
||||
}
|
||||
return retVal.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<GlyphRenderingOptions>
|
||||
Factory::CreateCGGlyphRenderingOptions(const Color &aFontSmoothingBackgroundColor)
|
||||
{
|
||||
return MakeAndAddRef<GlyphRenderingOptionsCG>(aFontSmoothingBackgroundColor);
|
||||
}
|
||||
#endif
|
||||
|
||||
already_AddRefed<DataSourceSurface>
|
||||
Factory::CreateWrappingDataSourceSurface(uint8_t *aData,
|
||||
int32_t aStride,
|
||||
|
@ -830,6 +769,14 @@ Factory::CreateWrappingDataSourceSurface(uint8_t *aData,
|
|||
return newSurf.forget();
|
||||
}
|
||||
|
||||
#ifdef XP_DARWIN
|
||||
already_AddRefed<GlyphRenderingOptions>
|
||||
Factory::CreateCGGlyphRenderingOptions(const Color &aFontSmoothingBackgroundColor)
|
||||
{
|
||||
return MakeAndAddRef<GlyphRenderingOptionsCG>(aFontSmoothingBackgroundColor);
|
||||
}
|
||||
#endif
|
||||
|
||||
already_AddRefed<DataSourceSurface>
|
||||
Factory::CreateDataSourceSurface(const IntSize &aSize,
|
||||
SurfaceFormat aFormat,
|
||||
|
|
|
@ -5,13 +5,85 @@
|
|||
|
||||
#include "PathCG.h"
|
||||
#include <math.h>
|
||||
#include "DrawTargetCG.h"
|
||||
#include "Logging.h"
|
||||
#include "PathHelpers.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
static inline Rect
|
||||
CGRectToRect(CGRect rect)
|
||||
{
|
||||
return Rect(rect.origin.x,
|
||||
rect.origin.y,
|
||||
rect.size.width,
|
||||
rect.size.height);
|
||||
}
|
||||
|
||||
static inline Point
|
||||
CGPointToPoint(CGPoint point)
|
||||
{
|
||||
return Point(point.x, point.y);
|
||||
}
|
||||
|
||||
static inline void
|
||||
SetStrokeOptions(CGContextRef cg, const StrokeOptions &aStrokeOptions)
|
||||
{
|
||||
switch (aStrokeOptions.mLineCap)
|
||||
{
|
||||
case CapStyle::BUTT:
|
||||
CGContextSetLineCap(cg, kCGLineCapButt);
|
||||
break;
|
||||
case CapStyle::ROUND:
|
||||
CGContextSetLineCap(cg, kCGLineCapRound);
|
||||
break;
|
||||
case CapStyle::SQUARE:
|
||||
CGContextSetLineCap(cg, kCGLineCapSquare);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (aStrokeOptions.mLineJoin)
|
||||
{
|
||||
case JoinStyle::BEVEL:
|
||||
CGContextSetLineJoin(cg, kCGLineJoinBevel);
|
||||
break;
|
||||
case JoinStyle::ROUND:
|
||||
CGContextSetLineJoin(cg, kCGLineJoinRound);
|
||||
break;
|
||||
case JoinStyle::MITER:
|
||||
case JoinStyle::MITER_OR_BEVEL:
|
||||
CGContextSetLineJoin(cg, kCGLineJoinMiter);
|
||||
break;
|
||||
}
|
||||
|
||||
CGContextSetLineWidth(cg, aStrokeOptions.mLineWidth);
|
||||
CGContextSetMiterLimit(cg, aStrokeOptions.mMiterLimit);
|
||||
|
||||
// XXX: rename mDashLength to dashLength
|
||||
if (aStrokeOptions.mDashLength > 0) {
|
||||
// we use a regular array instead of a std::vector here because we don't want to leak the <vector> include
|
||||
CGFloat *dashes = new CGFloat[aStrokeOptions.mDashLength];
|
||||
for (size_t i=0; i<aStrokeOptions.mDashLength; i++) {
|
||||
dashes[i] = aStrokeOptions.mDashPattern[i];
|
||||
}
|
||||
CGContextSetLineDash(cg, aStrokeOptions.mDashOffset, dashes, aStrokeOptions.mDashLength);
|
||||
delete[] dashes;
|
||||
}
|
||||
}
|
||||
|
||||
static inline CGAffineTransform
|
||||
GfxMatrixToCGAffineTransform(const Matrix &m)
|
||||
{
|
||||
CGAffineTransform t;
|
||||
t.a = m._11;
|
||||
t.b = m._12;
|
||||
t.c = m._21;
|
||||
t.d = m._22;
|
||||
t.tx = m._31;
|
||||
t.ty = m._32;
|
||||
return t;
|
||||
}
|
||||
|
||||
PathBuilderCG::~PathBuilderCG()
|
||||
{
|
||||
CGPathRelease(mCGPath);
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
|
||||
virtual already_AddRefed<Path> Finish();
|
||||
|
||||
virtual BackendType GetBackendType() const { return BackendType::COREGRAPHICS; }
|
||||
virtual BackendType GetBackendType() const { return BackendType::SKIA; }
|
||||
|
||||
private:
|
||||
friend class PathCG;
|
||||
|
@ -80,7 +80,7 @@ public:
|
|||
|
||||
// Paths will always return BackendType::COREGRAPHICS, but note that they
|
||||
// are compatible with BackendType::COREGRAPHICS_ACCELERATED backend.
|
||||
virtual BackendType GetBackendType() const { return BackendType::COREGRAPHICS; }
|
||||
virtual BackendType GetBackendType() const { return BackendType::SKIA; }
|
||||
|
||||
virtual already_AddRefed<PathBuilder> CopyToBuilder(FillRule aFillRule) const;
|
||||
virtual already_AddRefed<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "skia/include/core/SkPath.h"
|
||||
#include "skia/include/ports/SkTypeface_mac.h"
|
||||
#endif
|
||||
#include "DrawTargetCG.h"
|
||||
#include <vector>
|
||||
#include <dlfcn.h>
|
||||
#ifdef MOZ_WIDGET_UIKIT
|
||||
|
@ -87,61 +86,9 @@ SkTypeface* ScaledFontMac::GetSkTypeface()
|
|||
already_AddRefed<Path>
|
||||
ScaledFontMac::GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget)
|
||||
{
|
||||
if (aTarget->GetBackendType() == BackendType::COREGRAPHICS ||
|
||||
aTarget->GetBackendType() == BackendType::COREGRAPHICS_ACCELERATED) {
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
|
||||
// XXX: we could probably fold both of these transforms together to avoid extra work
|
||||
CGAffineTransform flip = CGAffineTransformMakeScale(1, -1);
|
||||
|
||||
CGPathRef glyphPath = ::CGFontGetGlyphPath(mFont, &flip, 0, aBuffer.mGlyphs[i].mIndex);
|
||||
|
||||
CGAffineTransform matrix = CGAffineTransformMake(mSize, 0, 0, mSize,
|
||||
aBuffer.mGlyphs[i].mPosition.x,
|
||||
aBuffer.mGlyphs[i].mPosition.y);
|
||||
CGPathAddPath(path, &matrix, glyphPath);
|
||||
CGPathRelease(glyphPath);
|
||||
}
|
||||
RefPtr<Path> ret = new PathCG(path, FillRule::FILL_WINDING);
|
||||
CGPathRelease(path);
|
||||
return ret.forget();
|
||||
#else
|
||||
//TODO: probably want CTFontCreatePathForGlyph
|
||||
MOZ_CRASH("GFX: This needs implemented 1");
|
||||
#endif
|
||||
}
|
||||
return ScaledFontBase::GetPathForGlyphs(aBuffer, aTarget);
|
||||
}
|
||||
|
||||
void
|
||||
ScaledFontMac::CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, BackendType aBackendType, const Matrix *aTransformHint)
|
||||
{
|
||||
if (!(aBackendType == BackendType::COREGRAPHICS || aBackendType == BackendType::COREGRAPHICS_ACCELERATED)) {
|
||||
ScaledFontBase::CopyGlyphsToBuilder(aBuffer, aBuilder, aBackendType, aTransformHint);
|
||||
return;
|
||||
}
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
PathBuilderCG *pathBuilderCG =
|
||||
static_cast<PathBuilderCG*>(aBuilder);
|
||||
// XXX: check builder type
|
||||
for (unsigned int i = 0; i < aBuffer.mNumGlyphs; i++) {
|
||||
// XXX: we could probably fold both of these transforms together to avoid extra work
|
||||
CGAffineTransform flip = CGAffineTransformMakeScale(1, -1);
|
||||
CGPathRef glyphPath = ::CGFontGetGlyphPath(mFont, &flip, 0, aBuffer.mGlyphs[i].mIndex);
|
||||
|
||||
CGAffineTransform matrix = CGAffineTransformMake(mSize, 0, 0, mSize,
|
||||
aBuffer.mGlyphs[i].mPosition.x,
|
||||
aBuffer.mGlyphs[i].mPosition.y);
|
||||
CGPathAddPath(pathBuilderCG->mCGPath, &matrix, glyphPath);
|
||||
CGPathRelease(glyphPath);
|
||||
}
|
||||
#else
|
||||
//TODO: probably want CTFontCreatePathForGlyph
|
||||
MOZ_CRASH("GFX: This needs implemented 2");
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CalcTableChecksum(const uint32_t *tableStart, uint32_t length, bool skipChecksumAdjust = false)
|
||||
{
|
||||
|
|
|
@ -20,6 +20,23 @@
|
|||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
class GlyphRenderingOptionsCG : public GlyphRenderingOptions
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsCG, override)
|
||||
|
||||
explicit GlyphRenderingOptionsCG(const Color &aFontSmoothingBackgroundColor)
|
||||
: mFontSmoothingBackgroundColor(aFontSmoothingBackgroundColor)
|
||||
{}
|
||||
|
||||
const Color &FontSmoothingBackgroundColor() const { return mFontSmoothingBackgroundColor; }
|
||||
|
||||
virtual FontType GetType() const override { return FontType::MAC; }
|
||||
|
||||
private:
|
||||
Color mFontSmoothingBackgroundColor;
|
||||
};
|
||||
|
||||
class ScaledFontMac : public ScaledFontBase
|
||||
{
|
||||
public:
|
||||
|
@ -32,7 +49,6 @@ public:
|
|||
virtual SkTypeface* GetSkTypeface();
|
||||
#endif
|
||||
virtual already_AddRefed<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
|
||||
virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, BackendType aBackendType, const Matrix *aTransformHint);
|
||||
virtual bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton);
|
||||
|
||||
#ifdef USE_CAIRO_SCALED_FONT
|
||||
|
@ -40,7 +56,6 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
friend class DrawTargetCG;
|
||||
friend class DrawTargetSkia;
|
||||
CGFontRef mFont;
|
||||
CTFontRef mCTFont; // only created if CTFontDrawGlyphs is available, otherwise null
|
||||
|
|
|
@ -1,461 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "SourceSurfaceCG.h"
|
||||
#include "DrawTargetCG.h"
|
||||
#include "DataSourceSurfaceWrapper.h"
|
||||
#include "DataSurfaceHelpers.h"
|
||||
#include "mozilla/Types.h" // for decltype
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
#include "MacIOSurface.h"
|
||||
#endif
|
||||
#include "Tools.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
|
||||
SourceSurfaceCG::~SourceSurfaceCG()
|
||||
{
|
||||
CGImageRelease(mImage);
|
||||
}
|
||||
|
||||
IntSize
|
||||
SourceSurfaceCG::GetSize() const
|
||||
{
|
||||
IntSize size;
|
||||
size.width = CGImageGetWidth(mImage);
|
||||
size.height = CGImageGetHeight(mImage);
|
||||
return size;
|
||||
}
|
||||
|
||||
SurfaceFormat
|
||||
SourceSurfaceCG::GetFormat() const
|
||||
{
|
||||
return mFormat;
|
||||
}
|
||||
|
||||
already_AddRefed<DataSourceSurface>
|
||||
SourceSurfaceCG::GetDataSurface()
|
||||
{
|
||||
//XXX: we should be more disciplined about who takes a reference and where
|
||||
CGImageRetain(mImage);
|
||||
RefPtr<DataSourceSurface> dataSurf = new DataSourceSurfaceCG(mImage);
|
||||
|
||||
// We also need to make sure that the returned surface has
|
||||
// surface->GetType() == SurfaceType::DATA.
|
||||
return MakeAndAddRef<DataSourceSurfaceWrapper>(dataSurf);
|
||||
}
|
||||
|
||||
static void releaseCallback(void *info, const void *data, size_t size) {
|
||||
free(info);
|
||||
}
|
||||
|
||||
CGImageRef
|
||||
CreateCGImage(void *aInfo,
|
||||
const void *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat)
|
||||
{
|
||||
return CreateCGImage(releaseCallback,
|
||||
aInfo,
|
||||
aData,
|
||||
aSize,
|
||||
aStride,
|
||||
aFormat);
|
||||
}
|
||||
|
||||
CGImageRef
|
||||
CreateCGImage(CGDataProviderReleaseDataCallback aCallback,
|
||||
void *aInfo,
|
||||
const void *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat)
|
||||
{
|
||||
//XXX: we should avoid creating this colorspace everytime
|
||||
CGColorSpaceRef colorSpace = nullptr;
|
||||
CGBitmapInfo bitinfo = 0;
|
||||
int bitsPerComponent = 0;
|
||||
int bitsPerPixel = 0;
|
||||
|
||||
switch (aFormat) {
|
||||
case SurfaceFormat::B8G8R8A8:
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
bitinfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
|
||||
bitsPerComponent = 8;
|
||||
bitsPerPixel = 32;
|
||||
break;
|
||||
|
||||
case SurfaceFormat::B8G8R8X8:
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
bitinfo = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
|
||||
bitsPerComponent = 8;
|
||||
bitsPerPixel = 32;
|
||||
break;
|
||||
|
||||
case SurfaceFormat::A8:
|
||||
// XXX: why don't we set a colorspace here?
|
||||
bitsPerComponent = 8;
|
||||
bitsPerPixel = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("GFX: CreateCGImage");
|
||||
}
|
||||
|
||||
size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height);
|
||||
if (bufLen == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(aInfo,
|
||||
aData,
|
||||
bufLen,
|
||||
aCallback);
|
||||
|
||||
CGImageRef image;
|
||||
if (aFormat == SurfaceFormat::A8) {
|
||||
CGFloat decode[] = {1.0, 0.0};
|
||||
image = CGImageMaskCreate (aSize.width, aSize.height,
|
||||
bitsPerComponent,
|
||||
bitsPerPixel,
|
||||
aStride,
|
||||
dataProvider,
|
||||
decode,
|
||||
true);
|
||||
} else {
|
||||
image = CGImageCreate (aSize.width, aSize.height,
|
||||
bitsPerComponent,
|
||||
bitsPerPixel,
|
||||
aStride,
|
||||
colorSpace,
|
||||
bitinfo,
|
||||
dataProvider,
|
||||
nullptr,
|
||||
true,
|
||||
kCGRenderingIntentDefault);
|
||||
}
|
||||
|
||||
CGDataProviderRelease(dataProvider);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
bool
|
||||
SourceSurfaceCG::InitFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat)
|
||||
{
|
||||
assert(aSize.width >= 0 && aSize.height >= 0);
|
||||
|
||||
size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height);
|
||||
if (bufLen == 0) {
|
||||
mImage = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
void *data = malloc(bufLen);
|
||||
// Copy all the data except the stride padding on the very last
|
||||
// row since we can't guarantee that is readable.
|
||||
memcpy(data, aData, bufLen - aStride + (aSize.width * BytesPerPixel(aFormat)));
|
||||
|
||||
mFormat = aFormat;
|
||||
mImage = CreateCGImage(data, data, aSize, aStride, aFormat);
|
||||
|
||||
return mImage != nullptr;
|
||||
}
|
||||
|
||||
DataSourceSurfaceCG::~DataSourceSurfaceCG()
|
||||
{
|
||||
CGImageRelease(mImage);
|
||||
free(CGBitmapContextGetData(mCg));
|
||||
CGContextRelease(mCg);
|
||||
}
|
||||
|
||||
IntSize
|
||||
DataSourceSurfaceCG::GetSize() const
|
||||
{
|
||||
IntSize size;
|
||||
size.width = CGImageGetWidth(mImage);
|
||||
size.height = CGImageGetHeight(mImage);
|
||||
return size;
|
||||
}
|
||||
|
||||
bool
|
||||
DataSourceSurfaceCG::InitFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat)
|
||||
{
|
||||
if (aSize.width <= 0 || aSize.height <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height);
|
||||
if (bufLen == 0) {
|
||||
mImage = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
void *data = malloc(bufLen);
|
||||
memcpy(data, aData, bufLen - aStride + (aSize.width * BytesPerPixel(aFormat)));
|
||||
|
||||
mFormat = aFormat;
|
||||
mImage = CreateCGImage(data, data, aSize, aStride, aFormat);
|
||||
|
||||
if (!mImage) {
|
||||
free(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CGContextRef CreateBitmapContextForImage(CGImageRef image)
|
||||
{
|
||||
CGColorSpaceRef colorSpace;
|
||||
|
||||
size_t width = CGImageGetWidth(image);
|
||||
size_t height = CGImageGetHeight(image);
|
||||
|
||||
int bitmapBytesPerRow = (width * 4);
|
||||
int bitmapByteCount = (bitmapBytesPerRow * height);
|
||||
|
||||
void *data = calloc(bitmapByteCount, 1);
|
||||
//XXX: which color space should we be using here?
|
||||
colorSpace = CGColorSpaceCreateDeviceRGB();
|
||||
assert(colorSpace);
|
||||
|
||||
// we'd like to pass nullptr as the first parameter
|
||||
// to let Quartz manage this memory for us. However,
|
||||
// on 10.5 and older CGBitmapContextGetData will return
|
||||
// nullptr instead of the associated buffer so we need
|
||||
// to manage it ourselves.
|
||||
CGContextRef cg = CGBitmapContextCreate(data,
|
||||
width,
|
||||
height,
|
||||
8,
|
||||
bitmapBytesPerRow,
|
||||
colorSpace,
|
||||
kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
|
||||
assert(cg);
|
||||
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
|
||||
return cg;
|
||||
}
|
||||
|
||||
DataSourceSurfaceCG::DataSourceSurfaceCG(CGImageRef aImage)
|
||||
{
|
||||
mFormat = SurfaceFormat::B8G8R8A8;
|
||||
mImage = aImage;
|
||||
mCg = CreateBitmapContextForImage(aImage);
|
||||
if (mCg == nullptr) {
|
||||
// error creating context
|
||||
return;
|
||||
}
|
||||
|
||||
// Get image width, height. We'll use the entire image.
|
||||
CGFloat w = CGImageGetWidth(aImage);
|
||||
CGFloat h = CGImageGetHeight(aImage);
|
||||
CGRect rect = {{0,0},{w,h}};
|
||||
|
||||
// Draw the image to the bitmap context. Once we draw, the memory
|
||||
// allocated for the context for rendering will then contain the
|
||||
// raw image data in the specified color space.
|
||||
CGContextDrawImage(mCg, rect, aImage);
|
||||
|
||||
// Now we can get a pointer to the image data associated with the bitmap
|
||||
// context.
|
||||
mData = CGBitmapContextGetData(mCg);
|
||||
assert(mData);
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
DataSourceSurfaceCG::GetData()
|
||||
{
|
||||
// See http://developer.apple.com/library/mac/#qa/qa1509/_index.html
|
||||
// the following only works on 10.5+, the Q&A above suggests a method
|
||||
// that can be used for earlier versions
|
||||
//CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));
|
||||
//unsigned char *dataPtr = CFDataGetBytePtr(data);
|
||||
//CFDataRelease(data);
|
||||
// unfortunately the the method above only works for read-only access and
|
||||
// we need read-write for DataSourceSurfaces
|
||||
return (unsigned char*)mData;
|
||||
}
|
||||
|
||||
SourceSurfaceCGBitmapContext::SourceSurfaceCGBitmapContext(DrawTargetCG *aDrawTarget)
|
||||
{
|
||||
mDrawTarget = aDrawTarget;
|
||||
mFormat = aDrawTarget->GetFormat();
|
||||
mCg = (CGContextRef)aDrawTarget->GetNativeSurface(NativeSurfaceType::CGCONTEXT);
|
||||
if (!mCg)
|
||||
abort();
|
||||
|
||||
mSize.width = CGBitmapContextGetWidth(mCg);
|
||||
mSize.height = CGBitmapContextGetHeight(mCg);
|
||||
mStride = CGBitmapContextGetBytesPerRow(mCg);
|
||||
mData = CGBitmapContextGetData(mCg);
|
||||
|
||||
mImage = nullptr;
|
||||
}
|
||||
|
||||
void SourceSurfaceCGBitmapContext::EnsureImage() const
|
||||
{
|
||||
// Instead of using CGBitmapContextCreateImage we create
|
||||
// a CGImage around the data associated with the CGBitmapContext
|
||||
// we do this to avoid the vm_copy that CGBitmapContextCreateImage.
|
||||
// vm_copy tends to cause all sorts of unexpected performance problems
|
||||
// because of the mm tricks that vm_copy does. Using a regular
|
||||
// memcpy when the bitmap context is modified gives us more predictable
|
||||
// performance characteristics.
|
||||
if (!mImage) {
|
||||
if (!mData) abort();
|
||||
mImage = CreateCGImage(nullptr, mData, mSize, mStride, mFormat);
|
||||
}
|
||||
}
|
||||
|
||||
IntSize
|
||||
SourceSurfaceCGBitmapContext::GetSize() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceCGBitmapContext::DrawTargetWillChange()
|
||||
{
|
||||
if (mDrawTarget) {
|
||||
// This will break the weak reference we hold to mCg
|
||||
size_t stride = CGBitmapContextGetBytesPerRow(mCg);
|
||||
size_t height = CGBitmapContextGetHeight(mCg);
|
||||
|
||||
size_t bufLen = BufferSizeFromStrideAndHeight(stride, height);
|
||||
if (bufLen == 0) {
|
||||
mDataHolder.Dealloc();
|
||||
mData = nullptr;
|
||||
} else {
|
||||
static_assert(sizeof(decltype(mDataHolder[0])) == 1,
|
||||
"mDataHolder.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
|
||||
mDataHolder.Realloc(/* actually an object count */ bufLen);
|
||||
mData = mDataHolder;
|
||||
|
||||
// copy out the data from the CGBitmapContext
|
||||
// we'll maintain ownership of mData until
|
||||
// we transfer it to mImage
|
||||
memcpy(mData, CGBitmapContextGetData(mCg), bufLen);
|
||||
}
|
||||
|
||||
// drop the current image for the data associated with the CGBitmapContext
|
||||
if (mImage)
|
||||
CGImageRelease(mImage);
|
||||
mImage = nullptr;
|
||||
|
||||
mCg = nullptr;
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceCGBitmapContext::DrawTargetWillGoAway()
|
||||
{
|
||||
if (mDrawTarget) {
|
||||
if (mDrawTarget->mData != CGBitmapContextGetData(mCg)) {
|
||||
DrawTargetWillChange();
|
||||
return;
|
||||
}
|
||||
|
||||
// Instead of copying the data over, we can just swap it.
|
||||
mDataHolder.Swap(mDrawTarget->mData);
|
||||
mData = mDataHolder;
|
||||
mCg = nullptr;
|
||||
mDrawTarget = nullptr;
|
||||
// mImage is still valid because it still points to the same data.
|
||||
}
|
||||
}
|
||||
|
||||
SourceSurfaceCGBitmapContext::~SourceSurfaceCGBitmapContext()
|
||||
{
|
||||
if (mImage)
|
||||
CGImageRelease(mImage);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
SourceSurfaceCGIOSurfaceContext::SourceSurfaceCGIOSurfaceContext(DrawTargetCG *aDrawTarget)
|
||||
{
|
||||
CGContextRef cg = (CGContextRef)aDrawTarget->GetNativeSurface(NativeSurfaceType::CGCONTEXT_ACCELERATED);
|
||||
|
||||
RefPtr<MacIOSurface> surf = MacIOSurface::IOSurfaceContextGetSurface(cg);
|
||||
|
||||
mFormat = aDrawTarget->GetFormat();
|
||||
mSize.width = surf->GetWidth();
|
||||
mSize.height = surf->GetHeight();
|
||||
|
||||
// TODO use CreateImageFromIOSurfaceContext instead of reading back the surface
|
||||
//mImage = MacIOSurface::CreateImageFromIOSurfaceContext(cg);
|
||||
mImage = nullptr;
|
||||
|
||||
aDrawTarget->Flush();
|
||||
surf->Lock();
|
||||
size_t bytesPerRow = surf->GetBytesPerRow();
|
||||
size_t ioHeight = surf->GetHeight();
|
||||
void* ioData = surf->GetBaseAddress();
|
||||
// XXX If the width is much less then the stride maybe
|
||||
// we should repack the image?
|
||||
mData = malloc(ioHeight*bytesPerRow);
|
||||
memcpy(mData, ioData, ioHeight*(bytesPerRow));
|
||||
mStride = bytesPerRow;
|
||||
surf->Unlock();
|
||||
}
|
||||
|
||||
void SourceSurfaceCGIOSurfaceContext::EnsureImage() const
|
||||
{
|
||||
// TODO Use CreateImageFromIOSurfaceContext and remove this
|
||||
|
||||
// Instead of using CGBitmapContextCreateImage we create
|
||||
// a CGImage around the data associated with the CGBitmapContext
|
||||
// we do this to avoid the vm_copy that CGBitmapContextCreateImage.
|
||||
// vm_copy tends to cause all sorts of unexpected performance problems
|
||||
// because of the mm tricks that vm_copy does. Using a regular
|
||||
// memcpy when the bitmap context is modified gives us more predictable
|
||||
// performance characteristics.
|
||||
if (!mImage) {
|
||||
mImage = CreateCGImage(mData, mData, mSize, mStride, SurfaceFormat::B8G8R8A8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IntSize
|
||||
SourceSurfaceCGIOSurfaceContext::GetSize() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
void
|
||||
SourceSurfaceCGIOSurfaceContext::DrawTargetWillChange()
|
||||
{
|
||||
}
|
||||
|
||||
SourceSurfaceCGIOSurfaceContext::~SourceSurfaceCGIOSurfaceContext()
|
||||
{
|
||||
if (mImage)
|
||||
CGImageRelease(mImage);
|
||||
else
|
||||
free(mData);
|
||||
}
|
||||
|
||||
unsigned char*
|
||||
SourceSurfaceCGIOSurfaceContext::GetData()
|
||||
{
|
||||
return (unsigned char*)mData;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
|
@ -1,212 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _MOZILLA_GFX_SOURCESURFACECG_H
|
||||
#define _MOZILLA_GFX_SOURCESURFACECG_H
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#else
|
||||
#include <CoreGraphics/CoreGraphics.h>
|
||||
#endif
|
||||
|
||||
#include "2D.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
class MacIOSurface;
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
CGImageRef
|
||||
CreateCGImage(CGDataProviderReleaseDataCallback aCallback,
|
||||
void *aInfo,
|
||||
const void *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat);
|
||||
|
||||
CGImageRef
|
||||
CreateCGImage(void *aInfo,
|
||||
const void *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat);
|
||||
|
||||
class DrawTargetCG;
|
||||
|
||||
class SourceSurfaceCG : public SourceSurface
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceCG)
|
||||
SourceSurfaceCG() {}
|
||||
explicit SourceSurfaceCG(CGImageRef aImage) : mImage(aImage) {}
|
||||
~SourceSurfaceCG();
|
||||
|
||||
virtual SurfaceType GetType() const { return SurfaceType::COREGRAPHICS_IMAGE; }
|
||||
virtual IntSize GetSize() const;
|
||||
virtual SurfaceFormat GetFormat() const;
|
||||
virtual already_AddRefed<DataSourceSurface> GetDataSurface();
|
||||
|
||||
CGImageRef GetImage() { return mImage; }
|
||||
|
||||
bool InitFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat);
|
||||
|
||||
private:
|
||||
CGImageRef mImage;
|
||||
|
||||
/* It might be better to just use the bitmap info from the CGImageRef to
|
||||
* deduce the format to save space in SourceSurfaceCG,
|
||||
* for now we just store it in mFormat */
|
||||
SurfaceFormat mFormat;
|
||||
};
|
||||
|
||||
class DataSourceSurfaceCG : public DataSourceSurface
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCG)
|
||||
DataSourceSurfaceCG() {}
|
||||
explicit DataSourceSurfaceCG(CGImageRef aImage);
|
||||
~DataSourceSurfaceCG();
|
||||
|
||||
virtual SurfaceType GetType() const { return SurfaceType::DATA; }
|
||||
virtual IntSize GetSize() const;
|
||||
virtual SurfaceFormat GetFormat() const { return mFormat; }
|
||||
|
||||
CGImageRef GetImage() { return mImage; }
|
||||
|
||||
bool InitFromData(unsigned char *aData,
|
||||
const IntSize &aSize,
|
||||
int32_t aStride,
|
||||
SurfaceFormat aFormat);
|
||||
|
||||
virtual unsigned char *GetData();
|
||||
|
||||
virtual int32_t Stride() { return CGImageGetBytesPerRow(mImage); }
|
||||
|
||||
|
||||
private:
|
||||
CGContextRef mCg;
|
||||
CGImageRef mImage;
|
||||
SurfaceFormat mFormat;
|
||||
//XXX: we don't need to store mData we can just get it from the CGContext
|
||||
void *mData;
|
||||
/* It might be better to just use the bitmap info from the CGImageRef to
|
||||
* deduce the format to save space in SourceSurfaceCG,
|
||||
* for now we just store it in mFormat */
|
||||
};
|
||||
|
||||
class SourceSurfaceCGContext : public DataSourceSurface
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCGContext)
|
||||
virtual void DrawTargetWillChange() = 0;
|
||||
virtual void DrawTargetWillGoAway() = 0;
|
||||
virtual CGImageRef GetImage() = 0;
|
||||
};
|
||||
|
||||
class SourceSurfaceCGBitmapContext : public SourceSurfaceCGContext
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCGBitmapContext)
|
||||
explicit SourceSurfaceCGBitmapContext(DrawTargetCG *);
|
||||
~SourceSurfaceCGBitmapContext();
|
||||
|
||||
virtual SurfaceType GetType() const { return SurfaceType::COREGRAPHICS_CGCONTEXT; }
|
||||
virtual IntSize GetSize() const;
|
||||
virtual SurfaceFormat GetFormat() const { return mFormat; }
|
||||
virtual already_AddRefed<DataSourceSurface> GetDataSurface()
|
||||
{
|
||||
// This call to DrawTargetWillChange() is needed to make a local copy of
|
||||
// the data from mDrawTarget. If we don't do that, the data can end up
|
||||
// getting deleted before the CGImageRef it belongs to.
|
||||
//
|
||||
// Another reason we need a local copy of the data is that the data in
|
||||
// mDrawTarget could change when someone touches the original DrawTargetCG
|
||||
// object. But a SourceSurface object should be immutable.
|
||||
//
|
||||
// For more information see bug 925448.
|
||||
DrawTargetWillChange();
|
||||
RefPtr<DataSourceSurface> copy(this);
|
||||
return copy.forget();
|
||||
}
|
||||
|
||||
CGImageRef GetImage() { EnsureImage(); return mImage; }
|
||||
|
||||
virtual unsigned char *GetData() { return static_cast<unsigned char*>(mData); }
|
||||
|
||||
virtual int32_t Stride() { return mStride; }
|
||||
|
||||
private:
|
||||
//XXX: do the other backends friend their DrawTarget?
|
||||
friend class DrawTargetCG;
|
||||
virtual void DrawTargetWillChange();
|
||||
virtual void DrawTargetWillGoAway();
|
||||
void EnsureImage() const;
|
||||
|
||||
// We hold a weak reference to these two objects.
|
||||
// The cycle is broken by DrawTargetWillChange
|
||||
DrawTargetCG *mDrawTarget;
|
||||
CGContextRef mCg;
|
||||
SurfaceFormat mFormat;
|
||||
|
||||
mutable CGImageRef mImage;
|
||||
|
||||
// mData can be owned by three different things:
|
||||
// mImage, mCg or SourceSurfaceCGBitmapContext
|
||||
void *mData;
|
||||
|
||||
// The image buffer, if the buffer is owned by this class.
|
||||
AlignedArray<uint8_t> mDataHolder;
|
||||
|
||||
int32_t mStride;
|
||||
IntSize mSize;
|
||||
};
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
class SourceSurfaceCGIOSurfaceContext : public SourceSurfaceCGContext
|
||||
{
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCGIOSurfaceContext)
|
||||
explicit SourceSurfaceCGIOSurfaceContext(DrawTargetCG *);
|
||||
~SourceSurfaceCGIOSurfaceContext();
|
||||
|
||||
virtual SurfaceType GetType() const { return SurfaceType::COREGRAPHICS_CGCONTEXT; }
|
||||
virtual IntSize GetSize() const;
|
||||
virtual SurfaceFormat GetFormat() const { return mFormat; }
|
||||
|
||||
CGImageRef GetImage() { EnsureImage(); return mImage; }
|
||||
|
||||
virtual unsigned char *GetData();
|
||||
|
||||
virtual int32_t Stride() { return mStride; }
|
||||
|
||||
private:
|
||||
//XXX: do the other backends friend their DrawTarget?
|
||||
friend class DrawTargetCG;
|
||||
virtual void DrawTargetWillChange();
|
||||
virtual void DrawTargetWillGoAway() { DrawTargetWillChange(); }
|
||||
void EnsureImage() const;
|
||||
|
||||
SurfaceFormat mFormat;
|
||||
mutable CGImageRef mImage;
|
||||
MacIOSurface* mIOSurface;
|
||||
|
||||
void *mData;
|
||||
int32_t mStride;
|
||||
|
||||
IntSize mSize;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // _MOZILLA_GFX_SOURCESURFACECG_H
|
|
@ -132,8 +132,6 @@ enum class DrawTargetType : int8_t {
|
|||
enum class BackendType : int8_t {
|
||||
NONE = 0,
|
||||
DIRECT2D, // Used for version independent D2D objects.
|
||||
COREGRAPHICS,
|
||||
COREGRAPHICS_ACCELERATED,
|
||||
CAIRO,
|
||||
SKIA,
|
||||
RECORDING,
|
||||
|
|
|
@ -64,11 +64,9 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):
|
|||
'MacIOSurface.h',
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
'DrawTargetCG.cpp',
|
||||
'NativeFontResourceMac.cpp',
|
||||
'PathCG.cpp',
|
||||
'ScaledFontMac.cpp',
|
||||
'SourceSurfaceCG.cpp',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
SOURCES += [
|
||||
|
|
|
@ -1491,8 +1491,6 @@ gfxPlatform::BackendTypeForName(const nsCString& aName)
|
|||
return BackendType::DIRECT2D;
|
||||
if (aName.EqualsLiteral("direct2d1.1"))
|
||||
return BackendType::DIRECT2D1_1;
|
||||
if (aName.EqualsLiteral("cg"))
|
||||
return BackendType::COREGRAPHICS;
|
||||
return BackendType::NONE;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,10 +103,6 @@ GetBackendName(mozilla::gfx::BackendType aBackend)
|
|||
switch (aBackend) {
|
||||
case mozilla::gfx::BackendType::DIRECT2D:
|
||||
return "direct2d";
|
||||
case mozilla::gfx::BackendType::COREGRAPHICS_ACCELERATED:
|
||||
return "quartz accelerated";
|
||||
case mozilla::gfx::BackendType::COREGRAPHICS:
|
||||
return "quartz";
|
||||
case mozilla::gfx::BackendType::CAIRO:
|
||||
return "cairo";
|
||||
case mozilla::gfx::BackendType::SKIA:
|
||||
|
|
|
@ -74,10 +74,8 @@ gfxPlatformMac::gfxPlatformMac()
|
|||
DisableFontActivation();
|
||||
mFontAntiAliasingThreshold = ReadAntiAliasingThreshold();
|
||||
|
||||
uint32_t canvasMask = BackendTypeBit(BackendType::SKIA) |
|
||||
BackendTypeBit(BackendType::COREGRAPHICS);
|
||||
uint32_t contentMask = BackendTypeBit(BackendType::COREGRAPHICS) |
|
||||
BackendTypeBit(BackendType::SKIA);
|
||||
uint32_t canvasMask = BackendTypeBit(BackendType::SKIA);
|
||||
uint32_t contentMask = BackendTypeBit(BackendType::SKIA);
|
||||
InitBackendPrefs(canvasMask, BackendType::SKIA,
|
||||
contentMask, BackendType::SKIA);
|
||||
|
||||
|
|
|
@ -93,9 +93,6 @@ PrintTranslator::GetDesiredFontType()
|
|||
return FontType::CAIRO;
|
||||
case BackendType::SKIA:
|
||||
return FontType::SKIA;
|
||||
case BackendType::COREGRAPHICS:
|
||||
case BackendType::COREGRAPHICS_ACCELERATED:
|
||||
return FontType::COREGRAPHICS;
|
||||
default:
|
||||
return FontType::CAIRO;
|
||||
}
|
||||
|
|
|
@ -466,10 +466,7 @@ GenerateMaskSurface(const PaintFramesParams& aParams,
|
|||
// when mask-mode is not add(source over). Switch to skia when CG backend
|
||||
// detected.
|
||||
RefPtr<DrawTarget> maskDT =
|
||||
(ctx.GetDrawTarget()->GetBackendType() == BackendType::COREGRAPHICS)
|
||||
? Factory::CreateDrawTarget(BackendType::SKIA, maskSurfaceRect.Size(),
|
||||
SurfaceFormat::A8)
|
||||
: ctx.GetDrawTarget()->CreateSimilarDrawTarget(maskSurfaceRect.Size(),
|
||||
ctx.GetDrawTarget()->CreateSimilarDrawTarget(maskSurfaceRect.Size(),
|
||||
SurfaceFormat::A8);
|
||||
if (!maskDT || !maskDT->IsValid()) {
|
||||
return DrawResult::TEMPORARY_ERROR;
|
||||
|
|
|
@ -352,16 +352,7 @@ private:
|
|||
RefPtr<gfxQuartzSurface> targetSurface;
|
||||
|
||||
RefPtr<gfxContext> targetContext;
|
||||
if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(gfx::BackendType::COREGRAPHICS)) {
|
||||
RefPtr<gfx::DrawTarget> dt =
|
||||
gfx::Factory::CreateDrawTargetForCairoCGContext(aContext, backingSize);
|
||||
if (!dt || !dt->IsValid()) {
|
||||
gfxDevCrash(mozilla::gfx::LogReason::InvalidContext) << "Window context problem 1 " << backingSize;
|
||||
return;
|
||||
}
|
||||
dt->AddUserData(&gfxContext::sDontUseAsSourceKey, dt, nullptr);
|
||||
targetContext = gfxContext::CreateOrNull(dt);
|
||||
} else if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(gfx::BackendType::CAIRO)) {
|
||||
if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(gfx::BackendType::CAIRO)) {
|
||||
// This is dead code unless you mess with prefs, but keep it around for
|
||||
// debugging.
|
||||
targetSurface = new gfxQuartzSurface(aContext, backingSize);
|
||||
|
|
Загрузка…
Ссылка в новой задаче