Bug 1258751: Delete the CoreGraphics backend. r=mstange

This commit is contained in:
Mason Chang 2016-10-18 23:22:44 -04:00
Родитель 8377010e6a
Коммит cd84eadb22
19 изменённых файлов: 122 добавлений и 3062 удалений

Просмотреть файл

@ -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);