зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1444506 - part 2 - Moz2D fixes for Skia m66 update. r=jrmuizel
This commit is contained in:
Родитель
0b0a32c642
Коммит
5eb6435f7a
|
@ -12,6 +12,7 @@
|
|||
#include "HelpersSkia.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
|
||||
#include "skia/include/core/SkSurface.h"
|
||||
#include "skia/include/core/SkTypeface.h"
|
||||
|
@ -19,7 +20,6 @@
|
|||
#include "skia/include/core/SkColorFilter.h"
|
||||
#include "skia/include/core/SkRegion.h"
|
||||
#include "skia/include/effects/SkBlurImageFilter.h"
|
||||
#include "skia/include/effects/SkLayerRasterizer.h"
|
||||
#include "skia/src/core/SkDevice.h"
|
||||
#include "Blur.h"
|
||||
#include "Logging.h"
|
||||
|
@ -33,9 +33,8 @@
|
|||
#ifdef USE_SKIA_GPU
|
||||
#include "GLDefs.h"
|
||||
#include "skia/include/gpu/GrContext.h"
|
||||
#include "skia/include/gpu/GrTexture.h"
|
||||
#include "skia/include/gpu/gl/GrGLInterface.h"
|
||||
#include "skia/src/gpu/GrRenderTargetContext.h"
|
||||
#include "skia/src/image/SkImage_Gpu.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
|
@ -394,34 +393,36 @@ ExtractSubset(sk_sp<SkImage> aImage, const IntRect& aRect)
|
|||
return aImage->makeSubset(subsetRect);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
SkImageIsMask(const sk_sp<SkImage>& aImage)
|
||||
static void
|
||||
FreeBitmapPixels(void* aBuf, void*)
|
||||
{
|
||||
SkPixmap pixmap;
|
||||
if (aImage->peekPixels(&pixmap)) {
|
||||
return pixmap.colorType() == kAlpha_8_SkColorType;
|
||||
#ifdef USE_SKIA_GPU
|
||||
}
|
||||
if (GrTexture* tex = aImage->getTexture()) {
|
||||
return GrPixelConfigIsAlphaOnly(tex->config());
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
sk_free(aBuf);
|
||||
}
|
||||
|
||||
static bool
|
||||
ExtractAlphaBitmap(const sk_sp<SkImage>& aImage, SkBitmap* aResultBitmap)
|
||||
{
|
||||
SkImageInfo info = SkImageInfo::MakeA8(aImage->width(), aImage->height());
|
||||
SkBitmap bitmap;
|
||||
if (!bitmap.tryAllocPixels(info, SkAlign4(info.minRowBytes())) ||
|
||||
!aImage->readPixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), 0, 0)) {
|
||||
gfxWarning() << "Failed reading alpha pixels for Skia bitmap";
|
||||
return false;
|
||||
// Skia does not fully allocate the last row according to stride.
|
||||
// Since some of our algorithms (i.e. blur) depend on this, we must allocate
|
||||
// the bitmap pixels manually.
|
||||
size_t stride = SkAlign4(info.minRowBytes());
|
||||
CheckedInt<size_t> size = stride;
|
||||
size *= info.height();
|
||||
if (size.isValid()) {
|
||||
void* buf = sk_malloc_flags(size.value(), 0);
|
||||
if (buf) {
|
||||
SkBitmap bitmap;
|
||||
if (bitmap.installPixels(info, buf, stride, FreeBitmapPixels, nullptr) &&
|
||||
aImage->readPixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), 0, 0)) {
|
||||
*aResultBitmap = bitmap;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aResultBitmap = bitmap;
|
||||
return true;
|
||||
gfxWarning() << "Failed reading alpha pixels for Skia bitmap";
|
||||
return false;
|
||||
}
|
||||
|
||||
static sk_sp<SkImage>
|
||||
|
@ -431,7 +432,7 @@ ExtractAlphaForSurface(SourceSurface* aSurface)
|
|||
if (!image) {
|
||||
return nullptr;
|
||||
}
|
||||
if (SkImageIsMask(image)) {
|
||||
if (image->isAlphaOnly()) {
|
||||
return image;
|
||||
}
|
||||
|
||||
|
@ -446,7 +447,7 @@ ExtractAlphaForSurface(SourceSurface* aSurface)
|
|||
}
|
||||
|
||||
static void
|
||||
SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Point aOffset = Point(0, 0), const Rect* aBounds = nullptr)
|
||||
SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, const SkMatrix* aMatrix = nullptr, const Rect* aBounds = nullptr)
|
||||
{
|
||||
switch (aPattern.GetType()) {
|
||||
case PatternType::COLOR: {
|
||||
|
@ -468,7 +469,9 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Po
|
|||
|
||||
SkMatrix mat;
|
||||
GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
|
||||
mat.postTranslate(SkFloatToScalar(aOffset.x), SkFloatToScalar(aOffset.y));
|
||||
if (aMatrix) {
|
||||
mat.postConcat(*aMatrix);
|
||||
}
|
||||
sk_sp<SkShader> shader = SkGradientShader::MakeLinear(points,
|
||||
&stops->mColors.front(),
|
||||
&stops->mPositions.front(),
|
||||
|
@ -497,7 +500,9 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Po
|
|||
|
||||
SkMatrix mat;
|
||||
GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
|
||||
mat.postTranslate(SkFloatToScalar(aOffset.x), SkFloatToScalar(aOffset.y));
|
||||
if (aMatrix) {
|
||||
mat.postConcat(*aMatrix);
|
||||
}
|
||||
sk_sp<SkShader> shader = SkGradientShader::MakeTwoPointConical(points[0],
|
||||
SkFloatToScalar(pat.mRadius1),
|
||||
points[1],
|
||||
|
@ -524,7 +529,9 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0, Po
|
|||
|
||||
SkMatrix mat;
|
||||
GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
|
||||
mat.postTranslate(SkFloatToScalar(aOffset.x), SkFloatToScalar(aOffset.y));
|
||||
if (aMatrix) {
|
||||
mat.postConcat(*aMatrix);
|
||||
}
|
||||
|
||||
if (!pat.mSamplingRect.IsEmpty()) {
|
||||
image = ExtractSubset(image, pat.mSamplingRect);
|
||||
|
@ -564,11 +571,11 @@ GetClipBounds(SkCanvas *aCanvas)
|
|||
}
|
||||
|
||||
struct AutoPaintSetup {
|
||||
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Pattern& aPattern, const Rect* aMaskBounds = nullptr, Point aOffset = Point(0, 0), const Rect* aSourceBounds = nullptr)
|
||||
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Pattern& aPattern, const Rect* aMaskBounds = nullptr, const SkMatrix* aMatrix = nullptr, const Rect* aSourceBounds = nullptr)
|
||||
: mNeedsRestore(false), mAlpha(1.0)
|
||||
{
|
||||
Init(aCanvas, aOptions, aMaskBounds, false);
|
||||
SetPaintPattern(mPaint, aPattern, mAlpha, aOffset, aSourceBounds);
|
||||
SetPaintPattern(mPaint, aPattern, mAlpha, aMatrix, aSourceBounds);
|
||||
}
|
||||
|
||||
AutoPaintSetup(SkCanvas *aCanvas, const DrawOptions& aOptions, const Rect* aMaskBounds = nullptr, bool aForceGroup = false)
|
||||
|
@ -651,7 +658,7 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface,
|
|||
|
||||
SkRect destRect = RectToSkRect(aDest);
|
||||
SkRect sourceRect = RectToSkRect(aSource);
|
||||
bool forceGroup = SkImageIsMask(image) &&
|
||||
bool forceGroup = image->isAlphaOnly() &&
|
||||
aOptions.mCompositionOp != CompositionOp::OP_OVER;
|
||||
|
||||
AutoPaintSetup paint(mCanvas, aOptions, &aDest, forceGroup);
|
||||
|
@ -730,9 +737,7 @@ DrawTargetSkia::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
|||
AlphaBoxBlur blur(Rect(0, 0, blurMask.width(), blurMask.height()),
|
||||
int32_t(blurMask.rowBytes()),
|
||||
aSigma, aSigma);
|
||||
blurMask.lockPixels();
|
||||
blur.Blur(reinterpret_cast<uint8_t*>(blurMask.getPixels()));
|
||||
blurMask.unlockPixels();
|
||||
blurMask.notifyPixelsChanged();
|
||||
|
||||
shadowPaint.setColor(ColorToSkColor(aColor, 1.0f));
|
||||
|
@ -797,7 +802,7 @@ DrawTargetSkia::FillRect(const Rect &aRect,
|
|||
|
||||
MarkChanged();
|
||||
SkRect rect = RectToSkRect(aRect);
|
||||
AutoPaintSetup paint(mCanvas, aOptions, aPattern, &aRect, Point(0, 0), &aRect);
|
||||
AutoPaintSetup paint(mCanvas, aOptions, aPattern, &aRect, nullptr, &aRect);
|
||||
|
||||
mCanvas->drawRect(rect, paint.mPaint);
|
||||
}
|
||||
|
@ -1516,18 +1521,39 @@ DrawTargetSkia::Mask(const Pattern &aSource,
|
|||
const Pattern &aMask,
|
||||
const DrawOptions &aOptions)
|
||||
{
|
||||
SkIRect maskBounds;
|
||||
if (!mCanvas->getDeviceClipBounds(&maskBounds)) {
|
||||
return;
|
||||
}
|
||||
SkPoint maskOrigin;
|
||||
maskOrigin.iset(maskBounds.fLeft, maskBounds.fTop);
|
||||
|
||||
SkMatrix maskMatrix = mCanvas->getTotalMatrix();
|
||||
maskMatrix.postTranslate(-maskOrigin.fX, -maskOrigin.fY);
|
||||
|
||||
MarkChanged();
|
||||
AutoPaintSetup paint(mCanvas, aOptions, aSource);
|
||||
AutoPaintSetup paint(mCanvas, aOptions, aSource, nullptr, &maskMatrix);
|
||||
|
||||
SkPaint maskPaint;
|
||||
SetPaintPattern(maskPaint, aMask);
|
||||
|
||||
SkLayerRasterizer::Builder builder;
|
||||
builder.addLayer(maskPaint);
|
||||
sk_sp<SkLayerRasterizer> raster(builder.detach());
|
||||
paint.mPaint.setRasterizer(raster);
|
||||
SkBitmap maskBitmap;
|
||||
if (!maskBitmap.tryAllocPixelsFlags(
|
||||
SkImageInfo::MakeA8(maskBounds.width(), maskBounds.height()),
|
||||
SkBitmap::kZeroPixels_AllocFlag)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mCanvas->drawPaint(paint.mPaint);
|
||||
SkCanvas maskCanvas(maskBitmap);
|
||||
maskCanvas.setMatrix(maskMatrix);
|
||||
maskCanvas.drawPaint(maskPaint);
|
||||
|
||||
mCanvas->save();
|
||||
mCanvas->resetMatrix();
|
||||
|
||||
mCanvas->drawBitmap(maskBitmap, maskOrigin.fX, maskOrigin.fY, &paint.mPaint);
|
||||
|
||||
mCanvas->restore();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1537,7 +1563,9 @@ DrawTargetSkia::MaskSurface(const Pattern &aSource,
|
|||
const DrawOptions &aOptions)
|
||||
{
|
||||
MarkChanged();
|
||||
AutoPaintSetup paint(mCanvas, aOptions, aSource, nullptr, -aOffset);
|
||||
|
||||
SkMatrix invOffset = SkMatrix::MakeTrans(SkFloatToScalar(-aOffset.x), SkFloatToScalar(-aOffset.y));
|
||||
AutoPaintSetup paint(mCanvas, aOptions, aSource, nullptr, &invOffset);
|
||||
|
||||
sk_sp<SkImage> alphaMask = ExtractAlphaForSurface(aMask);
|
||||
if (!alphaMask) {
|
||||
|
@ -1796,25 +1824,45 @@ DrawTargetSkia::OptimizeSourceSurface(SourceSurface *aSurface) const
|
|||
return dataSurface.forget();
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
static inline GrGLenum
|
||||
GfxFormatToGrGLFormat(SurfaceFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case SurfaceFormat::B8G8R8A8:
|
||||
return LOCAL_GL_BGRA8_EXT;
|
||||
case SurfaceFormat::B8G8R8X8:
|
||||
// We probably need to do something here.
|
||||
return LOCAL_GL_BGRA8_EXT;
|
||||
case SurfaceFormat::R5G6B5_UINT16:
|
||||
return LOCAL_GL_RGB565;
|
||||
case SurfaceFormat::A8:
|
||||
return LOCAL_GL_ALPHA8;
|
||||
default:
|
||||
return LOCAL_GL_RGBA8;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
already_AddRefed<SourceSurface>
|
||||
DrawTargetSkia::CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const
|
||||
{
|
||||
#ifdef USE_SKIA_GPU
|
||||
if (aSurface.mType == NativeSurfaceType::OPENGL_TEXTURE && UsingSkiaGPU()) {
|
||||
// Wrap the OpenGL texture id in a Skia texture handle.
|
||||
GrBackendTextureDesc texDesc;
|
||||
texDesc.fWidth = aSurface.mSize.width;
|
||||
texDesc.fHeight = aSurface.mSize.height;
|
||||
texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
|
||||
texDesc.fConfig = GfxFormatToGrConfig(aSurface.mFormat);
|
||||
|
||||
GrGLTextureInfo texInfo;
|
||||
texInfo.fTarget = LOCAL_GL_TEXTURE_2D;
|
||||
texInfo.fID = (GrGLuint)(uintptr_t)aSurface.mSurface;
|
||||
texDesc.fTextureHandle = reinterpret_cast<GrBackendObject>(&texInfo);
|
||||
|
||||
texInfo.fFormat = GfxFormatToGrGLFormat(aSurface.mFormat);
|
||||
GrBackendTexture texDesc(aSurface.mSize.width,
|
||||
aSurface.mSize.height,
|
||||
GrMipMapped::kNo,
|
||||
texInfo);
|
||||
sk_sp<SkImage> texture =
|
||||
SkImage::MakeFromAdoptedTexture(mGrContext.get(), texDesc,
|
||||
kTopLeft_GrSurfaceOrigin,
|
||||
GfxFormatToSkiaColorType(aSurface.mFormat),
|
||||
GfxFormatToSkiaAlphaType(aSurface.mFormat));
|
||||
RefPtr<SourceSurfaceSkia> newSurf = new SourceSurfaceSkia();
|
||||
if (texture && newSurf->InitFromImage(texture, aSurface.mFormat)) {
|
||||
|
@ -1851,7 +1899,7 @@ DrawTargetSkia::CopySurface(SourceSurface *aSurface,
|
|||
}
|
||||
// drawImage with A8 images ends up doing a mask operation
|
||||
// so we need to clear before
|
||||
if (SkImageIsMask(image)) {
|
||||
if (image->isAlphaOnly()) {
|
||||
mCanvas->clear(SK_ColorTRANSPARENT);
|
||||
}
|
||||
mCanvas->drawImage(image, -SkIntToScalar(aSourceRect.X()), -SkIntToScalar(aSourceRect.Y()), &paint);
|
||||
|
@ -2102,7 +2150,6 @@ DrawTargetSkia::PushLayerWithBlend(bool aOpaque, Float aOpacity, SourceSurface*
|
|||
SkCanvas::SaveLayerRec saveRec(aBounds.IsEmpty() ? nullptr : &bounds,
|
||||
&paint,
|
||||
SkCanvas::kPreserveLCDText_SaveLayerFlag |
|
||||
(aOpaque ? SkCanvas::kIsOpaque_SaveLayerFlag : 0) |
|
||||
(aCopyBackground ? SkCanvas::kInitWithPrevious_SaveLayerFlag : 0));
|
||||
|
||||
mCanvas->saveLayer(saveRec);
|
||||
|
@ -2132,21 +2179,7 @@ DrawTargetSkia::PopLayer()
|
|||
// skip implicitly drawing the layer.
|
||||
sk_sp<SkBaseDevice> layerDevice = sk_ref_sp(mCanvas->getTopDevice());
|
||||
SkIRect layerBounds = layerDevice->getGlobalBounds();
|
||||
sk_sp<SkImage> layerImage;
|
||||
SkPixmap layerPixmap;
|
||||
if (layerDevice->peekPixels(&layerPixmap)) {
|
||||
layerImage = SkImage::MakeFromRaster(layerPixmap, nullptr, nullptr);
|
||||
#ifdef USE_SKIA_GPU
|
||||
} else if (GrRenderTargetContext* drawCtx = mCanvas->internal_private_accessTopLayerRenderTargetContext()) {
|
||||
drawCtx->prepareForExternalIO();
|
||||
if (sk_sp<GrTextureProxy> tex = drawCtx->asTextureProxyRef()) {
|
||||
layerImage = sk_make_sp<SkImage_Gpu>(mGrContext.get(),
|
||||
kNeedNewImageUniqueID,
|
||||
layerDevice->imageInfo().alphaType(),
|
||||
tex, nullptr, SkBudgeted::kNo);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
sk_sp<SkImage> layerImage = layerDevice->snapshotImage();
|
||||
|
||||
// Restore the background with the layer's device left alive.
|
||||
mCanvas->restore();
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
#include "skia/include/core/SkCanvas.h"
|
||||
#include "skia/include/effects/SkDashPathEffect.h"
|
||||
#include "skia/include/core/SkShader.h"
|
||||
#ifdef USE_SKIA_GPU
|
||||
#include "skia/include/gpu/GrTypes.h"
|
||||
#endif
|
||||
#include "mozilla/Assertions.h"
|
||||
#include <vector>
|
||||
#include "nsDebug.h"
|
||||
|
@ -78,27 +75,6 @@ MakeSkiaImageInfo(const IntSize& aSize, SurfaceFormat aFormat)
|
|||
GfxFormatToSkiaAlphaType(aFormat));
|
||||
}
|
||||
|
||||
#ifdef USE_SKIA_GPU
|
||||
static inline GrPixelConfig
|
||||
GfxFormatToGrConfig(SurfaceFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case SurfaceFormat::B8G8R8A8:
|
||||
return kBGRA_8888_GrPixelConfig;
|
||||
case SurfaceFormat::B8G8R8X8:
|
||||
// We probably need to do something here.
|
||||
return kBGRA_8888_GrPixelConfig;
|
||||
case SurfaceFormat::R5G6B5_UINT16:
|
||||
return kRGB_565_GrPixelConfig;
|
||||
case SurfaceFormat::A8:
|
||||
return kAlpha_8_GrPixelConfig;
|
||||
default:
|
||||
return kRGBA_8888_GrPixelConfig;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
static inline void
|
||||
GfxMatrixToSkiaMatrix(const Matrix& mat, SkMatrix& retval)
|
||||
{
|
||||
|
|
|
@ -58,8 +58,7 @@ PrintTargetSkPDF::BeginPrinting(const nsAString& aTitle,
|
|||
metadata.fModified.fDateTime = now;
|
||||
|
||||
// SkDocument stores a non-owning raw pointer to aStream
|
||||
mPDFDoc = SkDocument::MakePDF(mOStream.get(), SK_ScalarDefaultRasterDPI,
|
||||
metadata, /*jpegEncoder*/ nullptr, true);
|
||||
mPDFDoc = SkDocument::MakePDF(mOStream.get(), metadata);
|
||||
|
||||
return mPDFDoc ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -127,9 +126,7 @@ PrintTargetSkPDF::GetReferenceDrawTarget()
|
|||
if (!mRefDT) {
|
||||
SkDocument::PDFMetadata metadata;
|
||||
// SkDocument stores a non-owning raw pointer to aStream
|
||||
mRefPDFDoc = SkDocument::MakePDF(&mRefOStream,
|
||||
SK_ScalarDefaultRasterDPI,
|
||||
metadata, nullptr, true);
|
||||
mRefPDFDoc = SkDocument::MakePDF(&mRefOStream, metadata);
|
||||
if (!mRefPDFDoc) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче