aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2014-09-16 10:32:43 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-16 10:32:43 -0700
commit4815fe5a0a497b676677fb4e4a0f05c511855490 (patch)
tree2c7a2867039516613d8b4b4c32918e3f92041a09 /src/gpu
parente1daac9b2671d723ee26c0fc6e7e54f42d423c6b (diff)
Fix bug in layer hoisting transition to SkRecord backend
Care must be taken when setting up the initial CTM matrix for partial SkRecord playbacks b.c. all the setMatrix calls will concatenate with the initial matrix (which may be different then the CTM that is required to draw correctly). R=mtklein@google.com, bsalomon@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/549143003
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrLayerCache.cpp11
-rw-r--r--src/gpu/GrLayerCache.h22
-rw-r--r--src/gpu/GrLayerHoister.cpp18
-rw-r--r--src/gpu/GrPictureUtils.cpp4
-rw-r--r--src/gpu/GrPictureUtils.h4
-rw-r--r--src/gpu/SkGpuDevice.cpp3
6 files changed, 43 insertions, 19 deletions
diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp
index 0c2e6b0a4d..8e61cb761e 100644
--- a/src/gpu/GrLayerCache.cpp
+++ b/src/gpu/GrLayerCache.cpp
@@ -119,28 +119,31 @@ void GrLayerCache::freeAll() {
GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID,
int start, int stop,
+ const SkIPoint& offset,
const SkMatrix& ctm) {
SkASSERT(pictureID != SK_InvalidGenID && start > 0 && stop > 0);
- GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, ctm));
+ GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, offset, ctm));
fLayerHash.add(layer);
return layer;
}
GrCachedLayer* GrLayerCache::findLayer(uint32_t pictureID,
int start, int stop,
+ const SkIPoint& offset,
const SkMatrix& ctm) {
SkASSERT(pictureID != SK_InvalidGenID && start > 0 && stop > 0);
- return fLayerHash.find(GrCachedLayer::Key(pictureID, start, stop, ctm));
+ return fLayerHash.find(GrCachedLayer::Key(pictureID, start, stop, offset, ctm));
}
GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID,
int start, int stop,
+ const SkIPoint& offset,
const SkMatrix& ctm) {
SkASSERT(pictureID != SK_InvalidGenID && start > 0 && stop > 0);
- GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(pictureID, start, stop, ctm));
+ GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(pictureID, start, stop, offset, ctm));
if (NULL == layer) {
- layer = this->createLayer(pictureID, start, stop, ctm);
+ layer = this->createLayer(pictureID, start, stop, offset, ctm);
}
return layer;
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h
index fc1467e120..15fa246c43 100644
--- a/src/gpu/GrLayerCache.h
+++ b/src/gpu/GrLayerCache.h
@@ -51,15 +51,17 @@ struct GrCachedLayer {
public:
// For SkTDynamicHash
struct Key {
- Key(uint32_t pictureID, int start, int stop, const SkMatrix& ctm)
+ Key(uint32_t pictureID, int start, int stop, const SkIPoint& offset, const SkMatrix& ctm)
: fPictureID(pictureID)
, fStart(start)
, fStop(stop)
+ , fOffset(offset)
, fCTM(ctm) {
fCTM.getType(); // force initialization of type so hashes match
// Key needs to be tightly packed.
GR_STATIC_ASSERT(sizeof(Key) == sizeof(uint32_t) + 2 * sizeof(int) +
+ 2 * sizeof(int32_t) +
9 * sizeof(SkScalar) + sizeof(uint32_t));
}
@@ -67,12 +69,14 @@ public:
return fPictureID == other.fPictureID &&
fStart == other.fStart &&
fStop == other.fStop &&
+ fOffset == other.fOffset &&
fCTM.cheapEqualTo(other.fCTM);
}
uint32_t pictureID() const { return fPictureID; }
int start() const { return fStart; }
int stop() const { return fStop; }
+ const SkIPoint& offset() const { return fOffset; }
const SkMatrix& ctm() const { return fCTM; }
private:
@@ -81,6 +85,8 @@ public:
// The range of commands in the picture this layer represents
const int fStart;
const int fStop;
+ // The offset of the layer in device space
+ const SkIPoint fOffset;
// The CTM applied to this layer in the picture
SkMatrix fCTM;
};
@@ -91,8 +97,9 @@ public:
}
// GrCachedLayer proper
- GrCachedLayer(uint32_t pictureID, int start, int stop, const SkMatrix& ctm)
- : fKey(pictureID, start, stop, ctm)
+ GrCachedLayer(uint32_t pictureID, int start, int stop,
+ const SkIPoint& offset, const SkMatrix& ctm)
+ : fKey(pictureID, start, stop, offset, ctm)
, fTexture(NULL)
, fRect(GrIRect16::MakeEmpty())
, fPlot(NULL)
@@ -107,6 +114,7 @@ public:
uint32_t pictureID() const { return fKey.pictureID(); }
int start() const { return fKey.start(); }
int stop() const { return fKey.stop(); }
+ const SkIPoint& offset() const { return fKey.offset(); }
const SkMatrix& ctm() const { return fKey.ctm(); }
void setTexture(GrTexture* texture, const GrIRect16& rect) {
@@ -171,9 +179,11 @@ public:
// elements by the GrContext
void freeAll();
- GrCachedLayer* findLayer(uint32_t pictureID, int start, int stop, const SkMatrix& ctm);
+ GrCachedLayer* findLayer(uint32_t pictureID, int start, int stop,
+ const SkIPoint& offset, const SkMatrix& ctm);
GrCachedLayer* findLayerOrCreate(uint32_t pictureID,
int start, int stop,
+ const SkIPoint& offset,
const SkMatrix& ctm);
// Inform the cache that layer's cached image is now required.
@@ -227,9 +237,9 @@ private:
int fPlotLocks[kNumPlotsX * kNumPlotsY];
void initAtlas();
- GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop, const SkMatrix& ctm);
+ GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop,
+ const SkIPoint& offset, const SkMatrix& ctm);
-public:
void purgeAll();
// Remove all the layers (and unlock any resources) associated with 'pictureID'
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp
index 49ca338bb2..a29d91ac9d 100644
--- a/src/gpu/GrLayerHoister.cpp
+++ b/src/gpu/GrLayerHoister.cpp
@@ -91,11 +91,18 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
// info.fCTM maps the layer's top/left to the origin.
// Since this layer is atlased, the top/left corner needs
// to be offset to the correct location in the backing texture.
+ SkMatrix initialCTM;
+ initialCTM.setTranslate(SkIntToScalar(-layer->offset().fX),
+ SkIntToScalar(-layer->offset().fY));
+ initialCTM.postTranslate(bound.fLeft, bound.fTop);
+
+ atlasCanvas->translate(SkIntToScalar(-layer->offset().fX),
+ SkIntToScalar(-layer->offset().fY));
atlasCanvas->translate(bound.fLeft, bound.fTop);
atlasCanvas->concat(layer->ctm());
SkRecordPartialDraw(*picture->fRecord.get(), atlasCanvas, bound,
- layer->start()+1, layer->stop());
+ layer->start()+1, layer->stop(), initialCTM);
atlasCanvas->restore();
}
@@ -126,10 +133,16 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
layerCanvas->clear(SK_ColorTRANSPARENT);
+ SkMatrix initialCTM;
+ initialCTM.setTranslate(SkIntToScalar(-layer->offset().fX),
+ SkIntToScalar(-layer->offset().fY));
+
+ layerCanvas->translate(SkIntToScalar(-layer->offset().fX),
+ SkIntToScalar(-layer->offset().fY));
layerCanvas->concat(layer->ctm());
SkRecordPartialDraw(*picture->fRecord.get(), layerCanvas, bound,
- layer->start()+1, layer->stop());
+ layer->start()+1, layer->stop(), initialCTM);
layerCanvas->flush();
}
@@ -151,6 +164,7 @@ void GrLayerHoister::UnlockLayers(GrLayerCache* layerCache, const SkPicture* pic
GrCachedLayer* layer = layerCache->findLayer(picture->uniqueID(),
info.fSaveLayerOpID,
info.fRestoreOpID,
+ info.fOffset,
info.fOriginXform);
layerCache->unlock(layer);
}
diff --git a/src/gpu/GrPictureUtils.cpp b/src/gpu/GrPictureUtils.cpp
index 8810eb8a07..0cc1f1e065 100644
--- a/src/gpu/GrPictureUtils.cpp
+++ b/src/gpu/GrPictureUtils.cpp
@@ -126,8 +126,6 @@ private:
dst.fOffset = SkIPoint::Make(newClip.fLeft, newClip.fTop);
dst.fOriginXform = *fCTM;
dst.fOriginXform.postConcat(src.fOriginXform);
- dst.fOriginXform.postTranslate(SkIntToScalar(-newClip.fLeft),
- SkIntToScalar(-newClip.fTop));
if (NULL == src.fPaint) {
dst.fPaint = NULL;
@@ -191,8 +189,6 @@ private:
slInfo.fSize = SkISize::Make(si.fBounds.width(), si.fBounds.height());
slInfo.fOffset = SkIPoint::Make(si.fBounds.fLeft, si.fBounds.fTop);
slInfo.fOriginXform = *fCTM;
- slInfo.fOriginXform.postTranslate(SkIntToScalar(-si.fBounds.fLeft),
- SkIntToScalar(-si.fBounds.fTop));
if (NULL == si.fPaint) {
slInfo.fPaint = NULL;
diff --git a/src/gpu/GrPictureUtils.h b/src/gpu/GrPictureUtils.h
index 1c6897ce77..55b294ac69 100644
--- a/src/gpu/GrPictureUtils.h
+++ b/src/gpu/GrPictureUtils.h
@@ -26,8 +26,8 @@ public:
uint32_t fPictureID;
// The size of the saveLayer
SkISize fSize;
- // The matrix state in which this layer's draws must occur. It already incorporates
- // the translation needed to map the layer's top-left point to the origin.
+ // The matrix state in which this layer's draws must occur. It does not
+ // include the translation needed to map the layer's top-left point to the origin.
SkMatrix fOriginXform;
// The offset that needs to be passed to drawBitmap to correctly
// position the pre-rendered layer. It is in device space.
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 122af65ff9..b719f84278 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1887,7 +1887,8 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture->uniqueID(),
info.fSaveLayerOpID,
- info.fRestoreOpID,
+ info.fRestoreOpID,
+ info.fOffset,
info.fOriginXform);
GrReplacements::ReplacementInfo* layerInfo = replacements.push();