From 67a2aa58534d160c0a04f608d3a25b7b2e83b885 Mon Sep 17 00:00:00 2001 From: Yuqian Li Date: Fri, 6 Apr 2018 16:32:45 -0400 Subject: [PATCH] Do not use CTM for drawDevice or drawSprite Otherwise, imagefilters_xfermodes GM would be rendered wrong in t8888 mode. Bug: skia: Change-Id: I1e06d42f2cf5f52e345ed72f321d811076a647ef Reviewed-on: https://skia-review.googlesource.com/118743 Reviewed-by: Mike Reed Commit-Queue: Yuqian Li --- src/core/SkThreadedBMPDevice.cpp | 16 ++++------------ src/core/SkThreadedBMPDevice.h | 30 +++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/core/SkThreadedBMPDevice.cpp b/src/core/SkThreadedBMPDevice.cpp index 8136023898..c5ba0e2d5d 100644 --- a/src/core/SkThreadedBMPDevice.cpp +++ b/src/core/SkThreadedBMPDevice.cpp @@ -8,7 +8,6 @@ #include "SkThreadedBMPDevice.h" #include "SkPath.h" -#include "SkRectPriv.h" #include "SkSpecialImage.h" #include "SkTaskGroup.h" #include "SkVertices.h" @@ -81,15 +80,6 @@ SkThreadedBMPDevice::DrawState::DrawState(SkThreadedBMPDevice* dev) { fRC = dev->fRCStack.rc(); } -SkIRect SkThreadedBMPDevice::transformDrawBounds(const SkRect& drawBounds) const { - if (drawBounds == SkRectPriv::MakeLargest()) { - return SkRectPriv::MakeILarge(); - } - SkRect transformedBounds; - this->ctm().mapRect(&transformedBounds, drawBounds); - return transformedBounds.roundOut(); -} - SkDraw SkThreadedBMPDevice::DrawState::getDraw() const { SkDraw draw; draw.fDst = fDst; @@ -190,7 +180,8 @@ void SkThreadedBMPDevice::drawBitmap(const SkBitmap& bitmap, const SkMatrix& mat void SkThreadedBMPDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& paint) { SkRect drawBounds = SkRect::MakeXYWH(x, y, bitmap.width(), bitmap.height()); - fQueue.push(drawBounds, [=](SkArenaAlloc*, const DrawState& ds, const SkIRect& tileBounds){ + fQueue.push(drawBounds, [=](SkArenaAlloc*, const DrawState& ds, + const SkIRect& tileBounds){ TileDraw(ds, tileBounds).drawSprite(bitmap, x, y, paint); }); } @@ -232,7 +223,8 @@ void SkThreadedBMPDevice::drawDevice(SkBaseDevice* device, int x, int y, const S SkRect drawBounds = SkRect::MakeXYWH(x, y, device->width(), device->height()); // copy the bitmap because it may deleted after this call SkBitmap* bitmap = fAlloc.make(static_cast(device)->fBitmap); - fQueue.push(drawBounds, [=](SkArenaAlloc*, const DrawState& ds, const SkIRect& tileBounds){ + fQueue.push(drawBounds, [=](SkArenaAlloc*, const DrawState& ds, + const SkIRect& tileBounds){ TileDraw(ds, tileBounds).drawSprite(*bitmap, x, y, paint); }); } diff --git a/src/core/SkThreadedBMPDevice.h b/src/core/SkThreadedBMPDevice.h index ca46f46299..3831b62985 100644 --- a/src/core/SkThreadedBMPDevice.h +++ b/src/core/SkThreadedBMPDevice.h @@ -10,6 +10,7 @@ #include "SkBitmapDevice.h" #include "SkDraw.h" +#include "SkRectPriv.h" #include "SkTaskGroup2D.h" class SkThreadedBMPDevice : public SkBitmapDevice { @@ -71,17 +72,17 @@ private: const SkIRect& tileBounds)>; DrawElement() {} - DrawElement(SkThreadedBMPDevice* device, DrawFn&& drawFn, const SkRect& rawDrawBounds) + DrawElement(SkThreadedBMPDevice* device, DrawFn&& drawFn, const SkIRect& drawBounds) : fInitialized(true) , fDrawFn(std::move(drawFn)) , fDS(device) - , fDrawBounds(device->transformDrawBounds(rawDrawBounds)) {} - DrawElement(SkThreadedBMPDevice* device, InitFn&& initFn, const SkRect& rawDrawBounds) + , fDrawBounds(drawBounds) {} + DrawElement(SkThreadedBMPDevice* device, InitFn&& initFn, const SkIRect& drawBounds) : fInitialized(false) , fNeedInit(true) , fInitFn(std::move(initFn)) , fDS(device) - , fDrawBounds(device->transformDrawBounds(rawDrawBounds)) {} + , fDrawBounds(drawBounds) {} SK_ALWAYS_INLINE bool tryInitOnce(SkArenaAlloc* alloc) { bool t = true; @@ -137,13 +138,14 @@ private: // Push a draw command into the queue. If Fn is DrawFn, we're pushing an element without // the need of initialization. If Fn is InitFn, we're pushing an element with init-once // and the InitFn will generate the DrawFn during initialization. - template + template SK_ALWAYS_INLINE void push(const SkRect& rawDrawBounds, Fn&& fn) { if (fSize == MAX_QUEUE_SIZE) { this->reset(); } SkASSERT(fSize < MAX_QUEUE_SIZE); - new (&fElements[fSize++]) DrawElement(fDevice, std::move(fn), rawDrawBounds); + SkIRect drawBounds = fDevice->transformDrawBounds(rawDrawBounds); + new (&fElements[fSize++]) DrawElement(fDevice, std::move(fn), drawBounds); fTasks->addColumn(); } @@ -159,7 +161,21 @@ private: int fSize; }; - SkIRect transformDrawBounds(const SkRect& drawBounds) const; + template + SkIRect transformDrawBounds(const SkRect& drawBounds) const { + if (drawBounds == SkRectPriv::MakeLargest()) { + return SkRectPriv::MakeILarge(); + } + SkRect transformedBounds; + if (useCTM) { + this->ctm().mapRect(&transformedBounds, drawBounds); + } else { + transformedBounds = drawBounds; + } + return transformedBounds.roundOut(); + } + + template T* cloneArray(const T* array, int count) {