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:
parent
b0601a4091
commit
67a2aa5853
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user