mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1160335. Make DrawTargetCG's transform handling better. r=mstange
This let's us avoid depending on Save() and Restore() to have the right transform at the right time.
This commit is contained in:
parent
8e254c0468
commit
f8a6b0ef50
@ -275,16 +275,20 @@ class UnboundnessFixer
|
||||
public:
|
||||
UnboundnessFixer() : mLayerCg(nullptr) {}
|
||||
|
||||
CGContextRef Check(CGContextRef baseCg, CompositionOp blend, const Rect* maskBounds = nullptr)
|
||||
CGContextRef Check(DrawTargetCG* dt, CompositionOp blend, const Rect* maskBounds = nullptr)
|
||||
{
|
||||
MOZ_ASSERT(baseCg);
|
||||
MOZ_ASSERT(dt->mCg);
|
||||
if (!IsOperatorBoundByMask(blend)) {
|
||||
mClipBounds = CGContextGetClipBoundingBox(baseCg);
|
||||
// The clip bounding box will be in user space so we need to clear our transform first
|
||||
CGContextSetCTM(dt->mCg, dt->mOriginalTransform);
|
||||
mClipBounds = CGContextGetClipBoundingBox(dt->mCg);
|
||||
|
||||
// If we're entirely clipped out or if the drawing operation covers the entire clip then
|
||||
// we don't need to create a temporary surface.
|
||||
if (CGRectIsEmpty(mClipBounds) ||
|
||||
(maskBounds && maskBounds->Contains(CGRectToRect(mClipBounds)))) {
|
||||
return baseCg;
|
||||
CGContextConcatCTM(dt->mCg, GfxMatrixToCGAffineTransform(dt->mTransform));
|
||||
return dt->mCg;
|
||||
}
|
||||
|
||||
// TransparencyLayers aren't blended using the blend mode so
|
||||
@ -292,7 +296,7 @@ class UnboundnessFixer
|
||||
|
||||
//XXX: The size here is in default user space units, of the layer relative to the graphics context.
|
||||
// is the clip bounds still correct if, for example, we have a scale applied to the context?
|
||||
mLayer = CGLayerCreateWithContext(baseCg, mClipBounds.size, nullptr);
|
||||
mLayer = CGLayerCreateWithContext(dt->mCg, mClipBounds.size, nullptr);
|
||||
mLayerCg = CGLayerGetContext(mLayer);
|
||||
// CGContext's default to have the origin at the bottom left
|
||||
// so flip it to the top left and adjust for the origin
|
||||
@ -302,23 +306,27 @@ class UnboundnessFixer
|
||||
}
|
||||
CGContextTranslateCTM(mLayerCg, -mClipBounds.origin.x, mClipBounds.origin.y + mClipBounds.size.height);
|
||||
CGContextScaleCTM(mLayerCg, 1, -1);
|
||||
CGContextConcatCTM(mLayerCg, GfxMatrixToCGAffineTransform(dt->mTransform));
|
||||
|
||||
return mLayerCg;
|
||||
} else {
|
||||
return baseCg;
|
||||
return dt->mCg;
|
||||
}
|
||||
}
|
||||
|
||||
void Fix(CGContextRef baseCg)
|
||||
void Fix(DrawTargetCG *dt)
|
||||
{
|
||||
if (mLayerCg) {
|
||||
// we pushed a layer so draw it to baseCg
|
||||
MOZ_ASSERT(baseCg);
|
||||
CGContextTranslateCTM(baseCg, 0, mClipBounds.size.height);
|
||||
CGContextScaleCTM(baseCg, 1, -1);
|
||||
// we pushed a layer so draw it to dt->mCg
|
||||
MOZ_ASSERT(dt->mCg);
|
||||
CGContextTranslateCTM(dt->mCg, 0, mClipBounds.size.height);
|
||||
CGContextScaleCTM(dt->mCg, 1, -1);
|
||||
mClipBounds.origin.y *= -1;
|
||||
CGContextDrawLayerAtPoint(baseCg, mClipBounds.origin, mLayer);
|
||||
CGContextDrawLayerAtPoint(dt->mCg, mClipBounds.origin, mLayer);
|
||||
CGContextRelease(mLayerCg);
|
||||
|
||||
// Reset the transform
|
||||
CGContextConcatCTM(dt->mCg, GfxMatrixToCGAffineTransform(dt->mTransform));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -339,15 +347,13 @@ DrawTargetCG::DrawSurface(SourceSurface *aSurface,
|
||||
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp, &aDest);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp, &aDest);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
|
||||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
CGContextSetInterpolationQuality(cg, InterpolationQualityFromFilter(aSurfOptions.mFilter));
|
||||
|
||||
CGImageRef image = GetRetainedImageFromSourceSurface(aSurface);
|
||||
@ -381,7 +387,7 @@ DrawTargetCG::DrawSurface(SourceSurface *aSurface,
|
||||
CGImageRelease(image);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
@ -894,7 +900,7 @@ DrawTargetCG::MaskSurface(const Pattern &aSource,
|
||||
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
@ -902,7 +908,6 @@ DrawTargetCG::MaskSurface(const Pattern &aSource,
|
||||
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
|
||||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
CGImageRef image = GetRetainedImageFromSourceSurface(aMask);
|
||||
|
||||
// use a negative-y so that the mask image draws right ways up
|
||||
@ -924,12 +929,18 @@ DrawTargetCG::MaskSurface(const Pattern &aSource,
|
||||
|
||||
CGImageRelease(image);
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DrawTargetCG::SetTransform(const Matrix &aTransform)
|
||||
{
|
||||
mTransform = aTransform;
|
||||
CGContextSetCTM(mCg, mOriginalTransform);
|
||||
CGContextConcatCTM(mCg, GfxMatrixToCGAffineTransform(aTransform));
|
||||
}
|
||||
|
||||
void
|
||||
DrawTargetCG::FillRect(const Rect &aRect,
|
||||
@ -945,7 +956,7 @@ DrawTargetCG::FillRect(const Rect &aRect,
|
||||
CGContextSaveGState(mCg);
|
||||
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp, &aRect);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp, &aRect);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
@ -954,8 +965,6 @@ DrawTargetCG::FillRect(const Rect &aRect,
|
||||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
if (isGradient(aPattern)) {
|
||||
CGContextClipToRect(cg, RectToCGRect(aRect));
|
||||
CGRect clipBounds = CGContextGetClipBoundingBox(cg);
|
||||
@ -989,7 +998,7 @@ DrawTargetCG::FillRect(const Rect &aRect,
|
||||
CGContextFillRect(cg, RectToCGRect(aRect));
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
@ -1169,7 +1178,7 @@ DrawTargetCG::StrokeLine(const Point &aP1, const Point &aP2, const Pattern &aPat
|
||||
CGContextSaveGState(mCg);
|
||||
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
@ -1177,8 +1186,6 @@ DrawTargetCG::StrokeLine(const Point &aP1, const Point &aP2, const Pattern &aPat
|
||||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
CGContextBeginPath(cg);
|
||||
CGContextMoveToPoint(cg, p1.x, p1.y);
|
||||
CGContextAddLineToPoint(cg, p2.x, p2.y);
|
||||
@ -1196,7 +1203,7 @@ DrawTargetCG::StrokeLine(const Point &aP1, const Point &aP2, const Pattern &aPat
|
||||
CGContextStrokePath(cg);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
@ -1247,7 +1254,7 @@ DrawTargetCG::StrokeRect(const Rect &aRect,
|
||||
CGContextSaveGState(mCg);
|
||||
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
@ -1267,8 +1274,6 @@ DrawTargetCG::StrokeRect(const Rect &aRect,
|
||||
CGContextSetShouldAntialias(cg,
|
||||
aDrawOptions.mAntialiasMode != AntialiasMode::NONE && !pixelAlignedStroke);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
SetStrokeOptions(cg, aStrokeOptions);
|
||||
|
||||
if (isGradient(aPattern)) {
|
||||
@ -1296,7 +1301,7 @@ DrawTargetCG::StrokeRect(const Rect &aRect,
|
||||
CGContextStrokePath(cg);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
@ -1311,7 +1316,6 @@ DrawTargetCG::ClearRect(const Rect &aRect)
|
||||
MarkChanged();
|
||||
|
||||
CGContextSaveGState(mCg);
|
||||
CGContextConcatCTM(mCg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
CGContextClearRect(mCg, RectToCGRect(aRect));
|
||||
|
||||
@ -1334,7 +1338,7 @@ DrawTargetCG::Stroke(const Path *aPath, const Pattern &aPattern, const StrokeOpt
|
||||
CGContextSaveGState(mCg);
|
||||
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
@ -1343,8 +1347,6 @@ DrawTargetCG::Stroke(const Path *aPath, const Pattern &aPattern, const StrokeOpt
|
||||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
|
||||
CGContextBeginPath(cg);
|
||||
|
||||
@ -1367,7 +1369,7 @@ DrawTargetCG::Stroke(const Path *aPath, const Pattern &aPattern, const StrokeOpt
|
||||
CGContextStrokePath(cg);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
@ -1386,7 +1388,7 @@ DrawTargetCG::Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions
|
||||
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
@ -1394,8 +1396,6 @@ DrawTargetCG::Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions
|
||||
CGContextSetAlpha(cg, aDrawOptions.mAlpha);
|
||||
CGContextSetShouldAntialias(cg, aDrawOptions.mAntialiasMode != AntialiasMode::NONE);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
CGContextBeginPath(cg);
|
||||
// XXX: we could put fill mode into the path fill rule if we wanted
|
||||
const PathCG *cgPath = static_cast<const PathCG*>(aPath);
|
||||
@ -1429,7 +1429,7 @@ DrawTargetCG::Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions
|
||||
CGContextFillPath(cg);
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(mCg);
|
||||
}
|
||||
|
||||
@ -1515,7 +1515,7 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa
|
||||
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aDrawOptions.mCompositionOp));
|
||||
UnboundnessFixer fixer;
|
||||
CGContextRef cg = fixer.Check(mCg, aDrawOptions.mCompositionOp);
|
||||
CGContextRef cg = fixer.Check(this, aDrawOptions.mCompositionOp);
|
||||
if (MOZ2D_ERROR_IF(!cg)) {
|
||||
return;
|
||||
}
|
||||
@ -1526,8 +1526,6 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa
|
||||
CGContextSetShouldSmoothFonts(cg, aDrawOptions.mAntialiasMode == AntialiasMode::SUBPIXEL);
|
||||
}
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
|
||||
ScaledFontMac* macFont = static_cast<ScaledFontMac*>(aFont);
|
||||
|
||||
// This code can execute millions of times in short periods, so we want to
|
||||
@ -1597,7 +1595,7 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa
|
||||
}
|
||||
}
|
||||
|
||||
fixer.Fix(mCg);
|
||||
fixer.Fix(this);
|
||||
CGContextRestoreGState(cg);
|
||||
}
|
||||
|
||||
@ -1625,6 +1623,7 @@ DrawTargetCG::CopySurface(SourceSurface *aSurface,
|
||||
// XXX: it might be more efficient for us to do the copy directly if we have access to the bits
|
||||
|
||||
CGContextSaveGState(mCg);
|
||||
CGContextSetCTM(mCg, mOriginalTransform);
|
||||
|
||||
// CopySurface ignores the clip, so we need to use private API to temporarily reset it
|
||||
CGContextResetClip(mCg);
|
||||
@ -1664,6 +1663,7 @@ DrawTargetCG::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
|
||||
|
||||
IntSize size = aSurface->GetSize();
|
||||
CGContextSaveGState(mCg);
|
||||
CGContextSetCTM(mCg, mOriginalTransform);
|
||||
//XXX do we need to do the fixup here?
|
||||
CGContextSetBlendMode(mCg, ToBlendMode(aOperator));
|
||||
|
||||
@ -1682,7 +1682,6 @@ DrawTargetCG::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
|
||||
|
||||
CGImageRelease(image);
|
||||
CGContextRestoreGState(mCg);
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1774,6 +1773,7 @@ DrawTargetCG::Init(BackendType aType,
|
||||
// so flip it to the top left
|
||||
CGContextTranslateCTM(mCg, 0, mSize.height);
|
||||
CGContextScaleCTM(mCg, 1, -1);
|
||||
mOriginalTransform = CGContextGetCTM(mCg);
|
||||
// See Bug 722164 for performance details
|
||||
// Medium or higher quality lead to expensive interpolation
|
||||
// for canvas we want to use low quality interpolation
|
||||
@ -1879,6 +1879,7 @@ DrawTargetCG::Init(CGContextRef cgContext, const IntSize &aSize)
|
||||
//
|
||||
// CGContextTranslateCTM(mCg, 0, mSize.height);
|
||||
// CGContextScaleCTM(mCg, 1, -1);
|
||||
mOriginalTransform = CGContextGetCTM(mCg);
|
||||
|
||||
mFormat = SurfaceFormat::B8G8R8A8;
|
||||
if (GetContextType(mCg) == CG_CONTEXT_TYPE_BITMAP) {
|
||||
@ -1963,18 +1964,9 @@ DrawTargetCG::PushClipRect(const Rect &aRect)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
mSavedClipBounds.push_back(CGContextGetClipBoundingBox(mCg));
|
||||
#endif
|
||||
|
||||
CGContextSaveGState(mCg);
|
||||
|
||||
/* We go through a bit of trouble to temporarilly set the transform
|
||||
* while we add the path */
|
||||
CGAffineTransform previousTransform = CGContextGetCTM(mCg);
|
||||
CGContextConcatCTM(mCg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
CGContextClipToRect(mCg, RectToCGRect(aRect));
|
||||
CGContextSetCTM(mCg, previousTransform);
|
||||
}
|
||||
|
||||
|
||||
@ -1985,10 +1977,6 @@ DrawTargetCG::PushClip(const Path *aPath)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
mSavedClipBounds.push_back(CGContextGetClipBoundingBox(mCg));
|
||||
#endif
|
||||
|
||||
CGContextSaveGState(mCg);
|
||||
|
||||
CGContextBeginPath(mCg);
|
||||
@ -2009,7 +1997,6 @@ DrawTargetCG::PushClip(const Path *aPath)
|
||||
* while we add the path. XXX: this could be improved if we keep
|
||||
* the CTM as resident state on the DrawTarget. */
|
||||
CGContextSaveGState(mCg);
|
||||
CGContextConcatCTM(mCg, GfxMatrixToCGAffineTransform(mTransform));
|
||||
CGContextAddPath(mCg, cgPath->GetPath());
|
||||
CGContextRestoreGState(mCg);
|
||||
|
||||
@ -2023,13 +2010,6 @@ void
|
||||
DrawTargetCG::PopClip()
|
||||
{
|
||||
CGContextRestoreGState(mCg);
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!mSavedClipBounds.empty(), "Unbalanced PopClip");
|
||||
MOZ_ASSERT(CGRectEqualToRect(mSavedClipBounds.back(), CGContextGetClipBoundingBox(mCg)),
|
||||
"PopClip didn't restore original clip");
|
||||
mSavedClipBounds.pop_back();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -2064,8 +2044,6 @@ BorrowedCGContext::BorrowCGContextFromDrawTarget(DrawTarget *aDT)
|
||||
// save the state to make it easier for callers to avoid mucking with things
|
||||
CGContextSaveGState(cg);
|
||||
|
||||
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(cgDT->mTransform));
|
||||
|
||||
return cg;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -19,7 +19,7 @@ namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
static inline CGAffineTransform
|
||||
GfxMatrixToCGAffineTransform(Matrix m)
|
||||
GfxMatrixToCGAffineTransform(const Matrix &m)
|
||||
{
|
||||
CGAffineTransform t;
|
||||
t.a = m._11;
|
||||
@ -113,6 +113,7 @@ class DrawTargetCG : public DrawTarget
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCG, override)
|
||||
friend class BorrowedCGContext;
|
||||
friend class UnboundnessFixer;
|
||||
friend class SourceSurfaceCGBitmapContext;
|
||||
DrawTargetCG();
|
||||
virtual ~DrawTargetCG();
|
||||
@ -173,6 +174,7 @@ public:
|
||||
|
||||
virtual IntSize GetSize() override { return mSize; }
|
||||
|
||||
virtual void SetTransform(const Matrix &aTransform) override;
|
||||
|
||||
/* This is for creating good compatible surfaces */
|
||||
virtual TemporaryRef<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
|
||||
@ -196,6 +198,7 @@ private:
|
||||
IntSize mSize;
|
||||
CGColorSpaceRef mColorSpace;
|
||||
CGContextRef mCg;
|
||||
CGAffineTransform mOriginalTransform;
|
||||
|
||||
/**
|
||||
* The image buffer, if the buffer is owned by this class.
|
||||
@ -207,10 +210,6 @@ private:
|
||||
|
||||
RefPtr<SourceSurfaceCGContext> mSnapshot;
|
||||
bool mMayContainInvalidPremultipliedData;
|
||||
|
||||
#ifdef DEBUG
|
||||
std::vector<CGRect> mSavedClipBounds;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user