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 <reed@google.com>
Commit-Queue: Yuqian Li <liyuqian@google.com>
This commit is contained in:
Yuqian Li 2018-04-06 16:32:45 -04:00 committed by Skia Commit-Bot
parent b0601a4091
commit 67a2aa5853
2 changed files with 27 additions and 19 deletions

View File

@ -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<false>(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<SkBitmap>(static_cast<SkBitmapDevice*>(device)->fBitmap);
fQueue.push(drawBounds, [=](SkArenaAlloc*, const DrawState& ds, const SkIRect& tileBounds){
fQueue.push<false>(drawBounds, [=](SkArenaAlloc*, const DrawState& ds,
const SkIRect& tileBounds){
TileDraw(ds, tileBounds).drawSprite(*bitmap, x, y, paint);
});
}

View File

@ -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<typename Fn>
template<bool useCTM = true, typename Fn>
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<useCTM>(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<bool useCTM = true>
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<typename T>
T* cloneArray(const T* array, int count) {