Bug 1340627 - part 3 - fix Moz2d for Skia m59. r=mchang

MozReview-Commit-ID: 1fugjwSpOMZ
This commit is contained in:
Lee Salzman 2017-05-09 22:31:07 -04:00
Родитель 4107093832
Коммит 836ee7f95b
2 изменённых файлов: 88 добавлений и 211 удалений

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

@ -7,7 +7,6 @@
#include "SourceSurfaceSkia.h" #include "SourceSurfaceSkia.h"
#include "ScaledFontBase.h" #include "ScaledFontBase.h"
#include "ScaledFontCairo.h" #include "ScaledFontCairo.h"
#include "skia/include/core/SkBitmapDevice.h"
#include "FilterNodeSoftware.h" #include "FilterNodeSoftware.h"
#include "HelpersSkia.h" #include "HelpersSkia.h"
@ -19,7 +18,7 @@
#include "skia/include/core/SkColorFilter.h" #include "skia/include/core/SkColorFilter.h"
#include "skia/include/effects/SkBlurImageFilter.h" #include "skia/include/effects/SkBlurImageFilter.h"
#include "skia/include/effects/SkLayerRasterizer.h" #include "skia/include/effects/SkLayerRasterizer.h"
#include "skia/src/core/SkSpecialImage.h" #include "skia/src/core/SkDevice.h"
#include "Blur.h" #include "Blur.h"
#include "Logging.h" #include "Logging.h"
#include "Tools.h" #include "Tools.h"
@ -30,10 +29,9 @@
#ifdef USE_SKIA_GPU #ifdef USE_SKIA_GPU
#include "GLDefs.h" #include "GLDefs.h"
#include "skia/include/gpu/SkGr.h"
#include "skia/include/gpu/GrContext.h" #include "skia/include/gpu/GrContext.h"
#include "skia/include/gpu/GrDrawContext.h"
#include "skia/include/gpu/gl/GrGLInterface.h" #include "skia/include/gpu/gl/GrGLInterface.h"
#include "skia/src/gpu/GrRenderTargetContext.h"
#include "skia/src/image/SkImage_Gpu.h" #include "skia/src/image/SkImage_Gpu.h"
#endif #endif
@ -302,7 +300,7 @@ DrawTargetSkia::Snapshot()
if (mSurface->peekPixels(&pixmap)) { if (mSurface->peekPixels(&pixmap)) {
image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr); image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
} else { } else {
image = mSurface->makeImageSnapshot(SkBudgeted::kNo); image = mSurface->makeImageSnapshot();
} }
if (!snapshot->InitFromImage(image, mFormat, this)) { if (!snapshot->InitFromImage(image, mFormat, this)) {
return nullptr; return nullptr;
@ -318,23 +316,13 @@ DrawTargetSkia::LockBits(uint8_t** aData, IntSize* aSize,
int32_t* aStride, SurfaceFormat* aFormat, int32_t* aStride, SurfaceFormat* aFormat,
IntPoint* aOrigin) IntPoint* aOrigin)
{ {
// Ensure the layer is at the origin if required.
SkIPoint origin = mCanvas->getTopDevice()->getOrigin();
if (!aOrigin && !origin.isZero()) {
return false;
}
/* Test if the canvas' device has accessible pixels first, as actually
* accessing the pixels may trigger side-effects, even if it fails.
*/
if (!mCanvas->peekPixels(nullptr)) {
return false;
}
SkImageInfo info; SkImageInfo info;
size_t rowBytes; size_t rowBytes;
void* pixels = mCanvas->accessTopLayerPixels(&info, &rowBytes); SkIPoint origin;
if (!pixels) { void* pixels = mCanvas->accessTopLayerPixels(&info, &rowBytes, &origin);
if (!pixels ||
// Ensure the layer is at the origin if required.
(!aOrigin && !origin.isZero())) {
return false; return false;
} }
@ -459,7 +447,11 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Po
&stops->mPositions.front(), &stops->mPositions.front(),
stops->mCount, stops->mCount,
mode, 0, &mat); mode, 0, &mat);
aPaint.setShader(shader); if (shader) {
aPaint.setShader(shader);
} else {
aPaint.setColor(SK_ColorTRANSPARENT);
}
} }
break; break;
} }
@ -487,7 +479,11 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Po
&stops->mPositions.front(), &stops->mPositions.front(),
stops->mCount, stops->mCount,
mode, 0, &mat); mode, 0, &mat);
aPaint.setShader(shader); if (shader) {
aPaint.setShader(shader);
} else {
aPaint.setColor(SK_ColorTRANSPARENT);
}
} }
break; break;
} }
@ -528,7 +524,7 @@ GetClipBounds(SkCanvas *aCanvas)
// getClipBounds because getClipBounds inflates the the bounds // getClipBounds because getClipBounds inflates the the bounds
// by a pixel in each direction to compensate for antialiasing. // by a pixel in each direction to compensate for antialiasing.
SkIRect deviceBounds; SkIRect deviceBounds;
if (!aCanvas->getClipDeviceBounds(&deviceBounds)) { if (!aCanvas->getDeviceClipBounds(&deviceBounds)) {
return Rect(); return Rect();
} }
SkMatrix inverseCTM; SkMatrix inverseCTM;
@ -631,7 +627,7 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
bool forceGroup = SkImageIsMask(image) && bool forceGroup = SkImageIsMask(image) &&
aOptions.mCompositionOp != CompositionOp::OP_OVER; aOptions.mCompositionOp != CompositionOp::OP_OVER;
AutoPaintSetup paint(mCanvas.get(), aOptions, &aDest, forceGroup); AutoPaintSetup paint(mCanvas, aOptions, &aDest, forceGroup);
if (aSurfOptions.mSamplingFilter == SamplingFilter::POINT) { if (aSurfOptions.mSamplingFilter == SamplingFilter::POINT) {
paint.mPaint.setFilterQuality(kNone_SkFilterQuality); paint.mPaint.setFilterQuality(kNone_SkFilterQuality);
} }
@ -774,7 +770,7 @@ DrawTargetSkia::FillRect(const Rect &aRect,
MarkChanged(); MarkChanged();
SkRect rect = RectToSkRect(aRect); SkRect rect = RectToSkRect(aRect);
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern, &aRect, Point(0, 0), &aRect); AutoPaintSetup paint(mCanvas, aOptions, aPattern, &aRect, Point(0, 0), &aRect);
mCanvas->drawRect(rect, paint.mPaint); mCanvas->drawRect(rect, paint.mPaint);
} }
@ -794,7 +790,7 @@ DrawTargetSkia::Stroke(const Path *aPath,
const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath); const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern); AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) { if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
return; return;
} }
@ -883,7 +879,7 @@ DrawTargetSkia::StrokeRect(const Rect &aRect,
if (aStrokeOptions.mDashLength > 0 && !rect.IsEmpty()) { if (aStrokeOptions.mDashLength > 0 && !rect.IsEmpty()) {
IntRect deviceClip(IntPoint(0, 0), mSize); IntRect deviceClip(IntPoint(0, 0), mSize);
SkIRect clipBounds; SkIRect clipBounds;
if (mCanvas->getClipDeviceBounds(&clipBounds)) { if (mCanvas->getDeviceClipBounds(&clipBounds)) {
deviceClip = SkIRectToIntRect(clipBounds); deviceClip = SkIRectToIntRect(clipBounds);
} }
rect = ShrinkClippedStrokedRect(rect, deviceClip, mTransform, aStrokeOptions); rect = ShrinkClippedStrokedRect(rect, deviceClip, mTransform, aStrokeOptions);
@ -893,7 +889,7 @@ DrawTargetSkia::StrokeRect(const Rect &aRect,
} }
MarkChanged(); MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern); AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) { if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
return; return;
} }
@ -909,7 +905,7 @@ DrawTargetSkia::StrokeLine(const Point &aStart,
const DrawOptions &aOptions) const DrawOptions &aOptions)
{ {
MarkChanged(); MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern); AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) { if (!StrokeOptionsToPaint(paint.mPaint, aStrokeOptions)) {
return; return;
} }
@ -931,7 +927,7 @@ DrawTargetSkia::Fill(const Path *aPath,
const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath); const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern); AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (!skiaPath->GetPath().isFinite()) { if (!skiaPath->GetPath().isFinite()) {
return; return;
@ -964,116 +960,6 @@ DrawTargetSkia::ShouldLCDRenderText(FontType aFontType, AntialiasMode aAntialias
} }
#ifdef MOZ_WIDGET_COCOA #ifdef MOZ_WIDGET_COCOA
class CGClipApply : public SkCanvas::ClipVisitor {
public:
explicit CGClipApply(CGContextRef aCGContext)
: mCG(aCGContext) {}
void clipRect(const SkRect& aRect, SkCanvas::ClipOp op, bool antialias) override {
CGRect rect = CGRectMake(aRect.x(), aRect.y(), aRect.width(), aRect.height());
CGContextClipToRect(mCG, rect);
}
void clipRRect(const SkRRect& rrect, SkCanvas::ClipOp op, bool antialias) override {
SkPath path;
path.addRRect(rrect);
clipPath(path, op, antialias);
}
void clipPath(const SkPath& aPath, SkCanvas::ClipOp, bool antialias) override {
SkPath::Iter iter(aPath, true);
SkPoint source[4];
SkPath::Verb verb;
if (!aPath.isFinite()) {
return;
}
if (aPath.isEmpty()) {
// Weirdly, CoreGraphics clips empty paths as all shown
// but empty rects as all clipped. We detect this situation and
// workaround it appropriately
CGContextClipToRect(mCG, CGRectZero);
return;
}
CGMutablePathRef cgPath = CGPathCreateMutable();
MOZ_ASSERT(cgPath);
while ((verb = iter.next(source)) != SkPath::kDone_Verb) {
switch (verb) {
case SkPath::kMove_Verb:
{
SkPoint dest = source[0];
CGPathMoveToPoint(cgPath, nullptr, dest.fX, dest.fY);
break;
}
case SkPath::kLine_Verb:
{
// The first point should be the end point of whatever
// verb we got to get here.
SkPoint second = source[1];
MOZ_ASSERT(!CGPathIsEmpty(cgPath));
CGPathAddLineToPoint(cgPath, nullptr, second.fX, second.fY);
break;
}
case SkPath::kQuad_Verb:
{
SkPoint second = source[1];
SkPoint third = source[2];
MOZ_ASSERT(!CGPathIsEmpty(cgPath));
CGPathAddQuadCurveToPoint(cgPath, nullptr,
second.fX, second.fY,
third.fX, third.fY);
break;
}
case SkPath::kCubic_Verb:
{
SkPoint second = source[1];
SkPoint third = source[2];
SkPoint fourth = source[2];
MOZ_ASSERT(!CGPathIsEmpty(cgPath));
CGPathAddCurveToPoint(cgPath, nullptr,
second.fX, second.fY,
third.fX, third.fY,
fourth.fX, fourth.fY);
break;
}
case SkPath::kClose_Verb:
{
if (!CGPathIsEmpty(cgPath)) {
CGPathCloseSubpath(cgPath);
}
break;
}
default:
{
SkDEBUGFAIL("unknown verb");
break;
}
} // end switch
} // end while
MOZ_ASSERT(!CGPathIsEmpty(cgPath));
CGContextBeginPath(mCG);
CGContextAddPath(mCG, cgPath);
FillRule fillRule = GetFillRule(aPath.getFillType());
if (fillRule == FillRule::FILL_EVEN_ODD) {
CGContextEOClip(mCG);
} else {
CGContextClip(mCG);
}
CGPathRelease(cgPath);
}
private:
CGContextRef mCG;
};
static inline CGAffineTransform static inline CGAffineTransform
GfxMatrixToCGAffineTransform(const Matrix &m) GfxMatrixToCGAffineTransform(const Matrix &m)
{ {
@ -1142,7 +1028,7 @@ GfxMatrixToCGAffineTransform(const Matrix &m)
static bool static bool
SetupCGContext(DrawTargetSkia* aDT, SetupCGContext(DrawTargetSkia* aDT,
CGContextRef aCGContext, CGContextRef aCGContext,
sk_sp<SkCanvas> aCanvas, SkCanvas* aCanvas,
const IntPoint& aOrigin, const IntPoint& aOrigin,
const IntSize& aSize) const IntSize& aSize)
{ {
@ -1157,10 +1043,15 @@ SetupCGContext(DrawTargetSkia* aDT,
// Want to apply clips BEFORE the transform since the transform // Want to apply clips BEFORE the transform since the transform
// will apply to the clips we apply. // will apply to the clips we apply.
// CGClipApply applies clips in device space, so it would be a mistake SkIRect clipBounds;
// to transform these clips. if (!aCanvas->getDeviceClipBounds(&clipBounds)) {
CGClipApply clipApply(aCGContext); clipBounds = SkIRect::MakeXYWH(aOrigin.x, aOrigin.y,
aCanvas->replayClips(&clipApply); aSize.width, aSize.height);
}
CGContextClipToRect(aCGContext,
CGRectMake(clipBounds.x(), clipBounds.y(),
clipBounds.width(), clipBounds.height()));
CGContextConcatCTM(aCGContext, GfxMatrixToCGAffineTransform(aDT->GetTransform())); CGContextConcatCTM(aCGContext, GfxMatrixToCGAffineTransform(aDT->GetTransform()));
return true; return true;
@ -1196,24 +1087,31 @@ SetupCGGlyphs(CGContextRef aCGContext,
// next to each other. // next to each other.
// The context returned from this method will have the origin // The context returned from this method will have the origin
// in the top left and will hvae applied all the neccessary clips // in the top left and will have applied all the neccessary clips
// and transforms to the CGContext. See the comment above // and transforms to the CGContext. See the comment above
// SetupCGContext. // SetupCGContext.
CGContextRef CGContextRef
DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions) DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
{ {
bool needLayer = !mCanvas->isClipEmpty() && !mCanvas->isClipRect();
if (needLayer) {
SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrc);
SkCanvas::SaveLayerRec rec(nullptr, &paint, SkCanvas::kInitWithPrevious_SaveLayerFlag);
mCanvas->saveLayer(rec);
}
uint8_t* data = nullptr;
int32_t stride; int32_t stride;
SurfaceFormat format; SurfaceFormat format;
IntSize size; IntSize size;
IntPoint origin; IntPoint origin;
if (!LockBits(&data, &size, &stride, &format, &origin)) {
uint8_t* aSurfaceData = nullptr;
if (!LockBits(&aSurfaceData, &size, &stride, &format, &origin)) {
NS_WARNING("Could not lock skia bits to wrap CG around"); NS_WARNING("Could not lock skia bits to wrap CG around");
return nullptr; return nullptr;
} }
if ((aSurfaceData == mCanvasData) && mCG && (mCGSize == size)) { if (!needLayer && (data == mCanvasData) && mCG && (mCGSize == size)) {
// If our canvas data still points to the same data, // If our canvas data still points to the same data,
// we can reuse the CG Context // we can reuse the CG Context
CGContextSaveGState(mCG); CGContextSaveGState(mCG);
@ -1232,7 +1130,7 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
CGContextRelease(mCG); CGContextRelease(mCG);
} }
mCanvasData = aSurfaceData; mCanvasData = data;
mCGSize = size; mCGSize = size;
uint32_t bitmapInfo = (format == SurfaceFormat::A8) ? uint32_t bitmapInfo = (format == SurfaceFormat::A8) ?
@ -1249,6 +1147,9 @@ DrawTargetSkia::BorrowCGContext(const DrawOptions &aOptions)
NULL, /* Callback when released */ NULL, /* Callback when released */
NULL); NULL);
if (!mCG) { if (!mCG) {
if (needLayer) {
mCanvas->restore();
}
ReleaseBits(mCanvasData); ReleaseBits(mCanvasData);
NS_WARNING("Could not create bitmap around skia data\n"); NS_WARNING("Could not create bitmap around skia data\n");
return nullptr; return nullptr;
@ -1269,6 +1170,18 @@ DrawTargetSkia::ReturnCGContext(CGContextRef aCGContext)
MOZ_ASSERT(aCGContext == mCG); MOZ_ASSERT(aCGContext == mCG);
ReleaseBits(mCanvasData); ReleaseBits(mCanvasData);
CGContextRestoreGState(aCGContext); CGContextRestoreGState(aCGContext);
bool needLayer = !mCanvas->isClipEmpty() && !mCanvas->isClipRect();
if (needLayer) {
// A layer was used for clipping and is about to be popped by the restore.
// Make sure the CG context referencing it is released first so the popped
// layer doesn't accidentally get used.
if (mCG) {
CGContextRelease(mCG);
mCG = nullptr;
}
mCanvas->restore();
}
} }
CGContextRef CGContextRef
@ -1432,7 +1345,7 @@ DrawTargetSkia::DrawGlyphs(ScaledFont* aFont,
return; return;
} }
AutoPaintSetup paint(mCanvas.get(), aOptions, aPattern); AutoPaintSetup paint(mCanvas, aOptions, aPattern);
if (aStrokeOptions && if (aStrokeOptions &&
!StrokeOptionsToPaint(paint.mPaint, *aStrokeOptions)) { !StrokeOptionsToPaint(paint.mPaint, *aStrokeOptions)) {
return; return;
@ -1552,7 +1465,7 @@ DrawTargetSkia::Mask(const Pattern &aSource,
const DrawOptions &aOptions) const DrawOptions &aOptions)
{ {
MarkChanged(); MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aSource); AutoPaintSetup paint(mCanvas, aOptions, aSource);
SkPaint maskPaint; SkPaint maskPaint;
SetPaintPattern(maskPaint, aMask); SetPaintPattern(maskPaint, aMask);
@ -1572,7 +1485,7 @@ DrawTargetSkia::MaskSurface(const Pattern &aSource,
const DrawOptions &aOptions) const DrawOptions &aOptions)
{ {
MarkChanged(); MarkChanged();
AutoPaintSetup paint(mCanvas.get(), aOptions, aSource, nullptr, -aOffset); AutoPaintSetup paint(mCanvas, aOptions, aSource, nullptr, -aOffset);
sk_sp<SkImage> alphaMask = ExtractAlphaForSurface(aMask); sk_sp<SkImage> alphaMask = ExtractAlphaForSurface(aMask);
if (!alphaMask) { if (!alphaMask) {
@ -1618,8 +1531,8 @@ DrawTarget::Draw3DTransformedSurface(SourceSurface* aSurface, const Matrix4x4& a
if (!dstSurf) { if (!dstSurf) {
return false; return false;
} }
sk_sp<SkCanvas> dstCanvas( std::unique_ptr<SkCanvas> dstCanvas(
SkCanvas::NewRasterDirect( SkCanvas::MakeRasterDirect(
SkImageInfo::Make(xformBounds.width, xformBounds.height, SkImageInfo::Make(xformBounds.width, xformBounds.height,
GfxFormatToSkiaColorType(dstSurf->GetFormat()), GfxFormatToSkiaColorType(dstSurf->GetFormat()),
kPremul_SkAlphaType), kPremul_SkAlphaType),
@ -1716,7 +1629,7 @@ DrawTargetSkia::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFor
#endif #endif
#ifdef DEBUG #ifdef DEBUG
if (!IsBackedByPixels(mCanvas.get())) { if (!IsBackedByPixels(mCanvas)) {
// If our canvas is backed by vector storage such as PDF then we want to // If our canvas is backed by vector storage such as PDF then we want to
// create a new DrawTarget with similar storage to avoid losing fidelity // create a new DrawTarget with similar storage to avoid losing fidelity
// (fidelity will be lost if the returned DT is Snapshot()'ed and drawn // (fidelity will be lost if the returned DT is Snapshot()'ed and drawn
@ -1753,7 +1666,7 @@ DrawTargetSkia::OptimizeGPUSourceSurface(SourceSurface *aSurface) const
} }
// Upload the SkImage to a GrTexture otherwise. // Upload the SkImage to a GrTexture otherwise.
sk_sp<SkImage> texture = image->makeTextureImage(mGrContext.get()); sk_sp<SkImage> texture = image->makeTextureImage(mGrContext.get(), nullptr);
if (texture) { if (texture) {
// Create a new SourceSurfaceSkia whose SkImage contains the GrTexture. // Create a new SourceSurfaceSkia whose SkImage contains the GrTexture.
RefPtr<SourceSurfaceSkia> surface = new SourceSurfaceSkia(); RefPtr<SourceSurfaceSkia> surface = new SourceSurfaceSkia();
@ -1870,7 +1783,7 @@ DrawTargetSkia::CopySurface(SourceSurface *aSurface,
mCanvas->save(); mCanvas->save();
mCanvas->setMatrix(SkMatrix::MakeTrans(SkIntToScalar(aDestination.x), SkIntToScalar(aDestination.y))); mCanvas->setMatrix(SkMatrix::MakeTrans(SkIntToScalar(aDestination.x), SkIntToScalar(aDestination.y)));
mCanvas->clipRect(SkRect::MakeIWH(aSourceRect.width, aSourceRect.height), kReplace_SkClipOp); mCanvas->clipRect(SkRect::MakeIWH(aSourceRect.width, aSourceRect.height), SkClipOp::kReplace_deprecated);
SkPaint paint; SkPaint paint;
if (!image->isOpaque()) { if (!image->isOpaque()) {
@ -1904,7 +1817,7 @@ DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
mSize = aSize; mSize = aSize;
mFormat = aFormat; mFormat = aFormat;
mCanvas = sk_ref_sp(mSurface->getCanvas()); mCanvas = mSurface->getCanvas();
SetPermitSubpixelAA(IsOpaque(mFormat)); SetPermitSubpixelAA(IsOpaque(mFormat));
if (info.isOpaque()) { if (info.isOpaque()) {
@ -1916,13 +1829,13 @@ DrawTargetSkia::Init(const IntSize &aSize, SurfaceFormat aFormat)
bool bool
DrawTargetSkia::Init(SkCanvas* aCanvas) DrawTargetSkia::Init(SkCanvas* aCanvas)
{ {
mCanvas = sk_ref_sp(aCanvas); mCanvas = aCanvas;
SkImageInfo imageInfo = mCanvas->imageInfo(); SkImageInfo imageInfo = mCanvas->imageInfo();
// If the canvas is backed by pixels we clear it to be on the safe side. If // If the canvas is backed by pixels we clear it to be on the safe side. If
// it's not (for example, for PDF output) we don't. // it's not (for example, for PDF output) we don't.
if (IsBackedByPixels(mCanvas.get())) { if (IsBackedByPixels(mCanvas)) {
SkColor clearColor = imageInfo.isOpaque() ? SK_ColorBLACK : SK_ColorTRANSPARENT; SkColor clearColor = imageInfo.isOpaque() ? SK_ColorBLACK : SK_ColorTRANSPARENT;
mCanvas->clear(clearColor); mCanvas->clear(clearColor);
} }
@ -1969,7 +1882,7 @@ DrawTargetSkia::InitWithGrContext(GrContext* aGrContext,
} }
// Create a GPU rendertarget/texture using the supplied GrContext. // Create a GPU rendertarget/texture using the supplied GrContext.
// NewRenderTarget also implicitly clears the underlying texture on creation. // MakeRenderTarget also implicitly clears the underlying texture on creation.
mSurface = mSurface =
SkSurface::MakeRenderTarget(aGrContext, SkSurface::MakeRenderTarget(aGrContext,
SkBudgeted(aCached), SkBudgeted(aCached),
@ -1981,7 +1894,7 @@ DrawTargetSkia::InitWithGrContext(GrContext* aGrContext,
mGrContext = sk_ref_sp(aGrContext); mGrContext = sk_ref_sp(aGrContext);
mSize = aSize; mSize = aSize;
mFormat = aFormat; mFormat = aFormat;
mCanvas = sk_ref_sp(mSurface->getCanvas()); mCanvas = mSurface->getCanvas();
SetPermitSubpixelAA(IsOpaque(mFormat)); SetPermitSubpixelAA(IsOpaque(mFormat));
return true; return true;
} }
@ -2001,7 +1914,7 @@ DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride
mSize = aSize; mSize = aSize;
mFormat = aFormat; mFormat = aFormat;
mCanvas = sk_ref_sp(mSurface->getCanvas()); mCanvas = mSurface->getCanvas();
SetPermitSubpixelAA(IsOpaque(mFormat)); SetPermitSubpixelAA(IsOpaque(mFormat));
return true; return true;
} }
@ -2041,7 +1954,7 @@ DrawTargetSkia::ClearRect(const Rect &aRect)
{ {
MarkChanged(); MarkChanged();
mCanvas->save(); mCanvas->save();
mCanvas->clipRect(RectToSkRect(aRect), kIntersect_SkClipOp, true); mCanvas->clipRect(RectToSkRect(aRect), SkClipOp::kIntersect, true);
SkColor clearColor = (mFormat == SurfaceFormat::B8G8R8X8) ? SK_ColorBLACK : SK_ColorTRANSPARENT; SkColor clearColor = (mFormat == SurfaceFormat::B8G8R8X8) ? SK_ColorBLACK : SK_ColorTRANSPARENT;
mCanvas->clear(clearColor); mCanvas->clear(clearColor);
mCanvas->restore(); mCanvas->restore();
@ -2056,7 +1969,7 @@ DrawTargetSkia::PushClip(const Path *aPath)
const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath); const PathSkia *skiaPath = static_cast<const PathSkia*>(aPath);
mCanvas->save(); mCanvas->save();
mCanvas->clipPath(skiaPath->GetPath(), kIntersect_SkClipOp, true); mCanvas->clipPath(skiaPath->GetPath(), SkClipOp::kIntersect, true);
} }
void void
@ -2072,7 +1985,7 @@ DrawTargetSkia::PushDeviceSpaceClipRects(const IntRect* aRects, uint32_t aCount)
// this region by the current transform, unlike the other SkCanvas // this region by the current transform, unlike the other SkCanvas
// clip methods, so it is just passed through in device-space. // clip methods, so it is just passed through in device-space.
mCanvas->save(); mCanvas->save();
mCanvas->clipRegion(region, kIntersect_SkClipOp); mCanvas->clipRegion(region, SkClipOp::kIntersect);
} }
void void
@ -2081,7 +1994,7 @@ DrawTargetSkia::PushClipRect(const Rect& aRect)
SkRect rect = RectToSkRect(aRect); SkRect rect = RectToSkRect(aRect);
mCanvas->save(); mCanvas->save();
mCanvas->clipRect(rect, kIntersect_SkClipOp, true); mCanvas->clipRect(rect, SkClipOp::kIntersect, true);
} }
void void
@ -2090,40 +2003,6 @@ DrawTargetSkia::PopClip()
mCanvas->restore(); mCanvas->restore();
} }
// Image filter that just passes the source through to the result unmodified.
class CopyLayerImageFilter : public SkImageFilter
{
public:
CopyLayerImageFilter()
: SkImageFilter(nullptr, 0, nullptr)
{}
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source,
const Context& ctx,
SkIPoint* offset) const override {
offset->set(0, 0);
return sk_ref_sp(source);
}
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(CopyLayerImageFilter)
};
sk_sp<SkFlattenable>
CopyLayerImageFilter::CreateProc(SkReadBuffer& buffer)
{
SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 0);
return sk_make_sp<CopyLayerImageFilter>();
}
#ifndef SK_IGNORE_TO_STRING
void
CopyLayerImageFilter::toString(SkString* str) const
{
str->append("CopyLayerImageFilter: ()");
}
#endif
void void
DrawTargetSkia::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask, DrawTargetSkia::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
const Matrix& aMaskTransform, const IntRect& aBounds, const Matrix& aMaskTransform, const IntRect& aBounds,
@ -2150,13 +2029,11 @@ DrawTargetSkia::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
} }
} }
sk_sp<SkImageFilter> backdrop(aCopyBackground ? new CopyLayerImageFilter : nullptr);
SkCanvas::SaveLayerRec saveRec(aBounds.IsEmpty() ? nullptr : &bounds, SkCanvas::SaveLayerRec saveRec(aBounds.IsEmpty() ? nullptr : &bounds,
&paint, &paint,
backdrop.get(),
SkCanvas::kPreserveLCDText_SaveLayerFlag | SkCanvas::kPreserveLCDText_SaveLayerFlag |
(aOpaque ? SkCanvas::kIsOpaque_SaveLayerFlag : 0)); (aOpaque ? SkCanvas::kIsOpaque_SaveLayerFlag : 0) |
(aCopyBackground ? SkCanvas::kInitWithPrevious_SaveLayerFlag : 0));
mCanvas->saveLayer(saveRec); mCanvas->saveLayer(saveRec);
@ -2190,10 +2067,10 @@ DrawTargetSkia::PopLayer()
if (layerDevice->peekPixels(&layerPixmap)) { if (layerDevice->peekPixels(&layerPixmap)) {
layerImage = SkImage::MakeFromRaster(layerPixmap, nullptr, nullptr); layerImage = SkImage::MakeFromRaster(layerPixmap, nullptr, nullptr);
#ifdef USE_SKIA_GPU #ifdef USE_SKIA_GPU
} else if (GrDrawContext* drawCtx = mCanvas->internal_private_accessTopLayerDrawContext()) { } else if (GrRenderTargetContext* drawCtx = mCanvas->internal_private_accessTopLayerRenderTargetContext()) {
drawCtx->prepareForExternalIO(); drawCtx->prepareForExternalIO();
if (GrTexture* tex = drawCtx->accessRenderTarget()->asTexture()) { if (sk_sp<GrTextureProxy> tex = drawCtx->asTextureProxyRef()) {
layerImage = sk_make_sp<SkImage_Gpu>(layerBounds.width(), layerBounds.height(), layerImage = sk_make_sp<SkImage_Gpu>(mGrContext.get(),
kNeedNewImageUniqueID, kNeedNewImageUniqueID,
layerDevice->imageInfo().alphaType(), layerDevice->imageInfo().alphaType(),
tex, nullptr, SkBudgeted::kNo); tex, nullptr, SkBudgeted::kNo);

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

@ -205,7 +205,7 @@ private:
IntSize mSize; IntSize mSize;
sk_sp<SkSurface> mSurface; sk_sp<SkSurface> mSurface;
sk_sp<SkCanvas> mCanvas; SkCanvas* mCanvas;
SourceSurfaceSkia* mSnapshot; SourceSurfaceSkia* mSnapshot;
#ifdef MOZ_WIDGET_COCOA #ifdef MOZ_WIDGET_COCOA