зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1340627 - part 3 - fix Moz2d for Skia m59. r=mchang
MozReview-Commit-ID: 1fugjwSpOMZ
This commit is contained in:
Родитель
4107093832
Коммит
836ee7f95b
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче