aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2014-11-24 09:49:17 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-11-24 09:49:17 -0800
commit30d7841f906116c3945ec8125a816a5c5462fed0 (patch)
tree40fecb4654dc961252b95364d015d8db601c1bce /src/gpu
parent7ef849d45a4de02697697ea213bfae7c215a0c38 (diff)
Add support for hoisting layers in pictures drawn with a matrix
Although Chromium doesn't use the drawPicture matrix parameter for their tiling, our local code does. Without such drawPicture calls break layer hoisting. BUG=skia:2315 Review URL: https://codereview.chromium.org/748853002
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrLayerHoister.cpp27
-rw-r--r--src/gpu/GrLayerHoister.h4
-rw-r--r--src/gpu/GrRecordReplaceDraw.cpp13
-rw-r--r--src/gpu/GrRecordReplaceDraw.h12
-rw-r--r--src/gpu/SkGpuDevice.cpp13
5 files changed, 42 insertions, 27 deletions
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp
index b53c1b80cd..b7653ee295 100644
--- a/src/gpu/GrLayerHoister.cpp
+++ b/src/gpu/GrLayerHoister.cpp
@@ -19,6 +19,7 @@
// required texture/render target resources.
static void prepare_for_hoisting(GrLayerCache* layerCache,
const SkPicture* topLevelPicture,
+ const SkMatrix& matrix,
const SkLayerInfo::BlockInfo& info,
const SkIRect& layerRect,
SkTDArray<GrHoistedLayer>* needRendering,
@@ -27,7 +28,9 @@ static void prepare_for_hoisting(GrLayerCache* layerCache,
int numSamples) {
const SkPicture* pict = info.fPicture ? info.fPicture : topLevelPicture;
- SkMatrix combined = SkMatrix::Concat(info.fPreMat, info.fLocalMat);
+ SkMatrix combined = matrix;
+ combined.preConcat(info.fPreMat);
+ combined.preConcat(info.fLocalMat);
GrCachedLayer* layer = layerCache->findLayerOrCreate(pict->uniqueID(),
info.fSaveLayerOpID,
@@ -73,7 +76,8 @@ static void prepare_for_hoisting(GrLayerCache* layerCache,
hl->fPicture = pict;
hl->fOffset = SkIPoint::Make(layerRect.fLeft, layerRect.fTop);
hl->fLocalMat = info.fLocalMat;
- hl->fPreMat = info.fPreMat;
+ hl->fPreMat = matrix;
+ hl->fPreMat.preConcat(info.fPreMat);
}
// Atlased layers must be small enough to fit in the atlas, not have a
@@ -81,6 +85,7 @@ static void prepare_for_hoisting(GrLayerCache* layerCache,
// TODO: allow leaf nested layers to appear in the atlas.
void GrLayerHoister::FindLayersToAtlas(GrContext* context,
const SkPicture* topLevelPicture,
+ const SkMatrix& initialMat,
const SkRect& query,
SkTDArray<GrHoistedLayer>* atlased,
SkTDArray<GrHoistedLayer>* recycled,
@@ -119,25 +124,27 @@ void GrLayerHoister::FindLayersToAtlas(GrContext* context,
continue;
}
- SkRect layerRect = info.fBounds;
+ SkRect layerRect;
+ initialMat.mapRect(&layerRect, info.fBounds);
if (!layerRect.intersect(query)) {
continue;
}
- SkIRect ir;
- layerRect.roundOut(&ir);
+ const SkIRect ir = layerRect.roundOut();
if (!GrLayerCache::PlausiblyAtlasable(ir.width(), ir.height())) {
continue;
}
- prepare_for_hoisting(layerCache, topLevelPicture, info, ir, atlased, recycled, true, 0);
+ prepare_for_hoisting(layerCache, topLevelPicture, initialMat,
+ info, ir, atlased, recycled, true, 0);
}
}
void GrLayerHoister::FindLayersToHoist(GrContext* context,
const SkPicture* topLevelPicture,
+ const SkMatrix& initialMat,
const SkRect& query,
SkTDArray<GrHoistedLayer>* needRendering,
SkTDArray<GrHoistedLayer>* recycled,
@@ -166,15 +173,15 @@ void GrLayerHoister::FindLayersToHoist(GrContext* context,
continue;
}
- SkRect layerRect = info.fBounds;
+ SkRect layerRect;
+ initialMat.mapRect(&layerRect, info.fBounds);
if (!layerRect.intersect(query)) {
continue;
}
- SkIRect ir;
- layerRect.roundOut(&ir);
+ const SkIRect ir = layerRect.roundOut();
- prepare_for_hoisting(layerCache, topLevelPicture, info, ir,
+ prepare_for_hoisting(layerCache, topLevelPicture, initialMat, info, ir,
needRendering, recycled, false, numSamples);
}
}
diff --git a/src/gpu/GrLayerHoister.h b/src/gpu/GrLayerHoister.h
index 12d8a842a0..84c7896abe 100644
--- a/src/gpu/GrLayerHoister.h
+++ b/src/gpu/GrLayerHoister.h
@@ -36,6 +36,7 @@ public:
layers can be inside nested sub-pictures.
@param context Owner of the layer cache (the source of new layers)
@param topLevelPicture The top-level picture that is about to be rendered
+ @param initialMat The CTM of the canvas into which the layers will be drawn
@param query The rectangle that is about to be drawn.
@param atlasedNeedRendering Out parameter storing the layers that
should be hoisted to the atlas
@@ -44,6 +45,7 @@ public:
*/
static void FindLayersToAtlas(GrContext* context,
const SkPicture* topLevelPicture,
+ const SkMatrix& initialMat,
const SkRect& query,
SkTDArray<GrHoistedLayer>* atlasedNeedRendering,
SkTDArray<GrHoistedLayer>* recycled,
@@ -53,6 +55,7 @@ public:
layers can be inside nested sub-pictures.
@param context Owner of the layer cache (the source of new layers)
@param topLevelPicture The top-level picture that is about to be rendered
+ @param initialMat The CTM of the canvas into which the layers will be drawn
@param query The rectangle that is about to be drawn.
@param needRendering Out parameter storing the layers that need rendering.
This should never include atlased layers.
@@ -61,6 +64,7 @@ public:
*/
static void FindLayersToHoist(GrContext* context,
const SkPicture* topLevelPicture,
+ const SkMatrix& initialMat,
const SkRect& query,
SkTDArray<GrHoistedLayer>* needRendering,
SkTDArray<GrHoistedLayer>* recycled,
diff --git a/src/gpu/GrRecordReplaceDraw.cpp b/src/gpu/GrRecordReplaceDraw.cpp
index 812584f08c..49ddf9a76c 100644
--- a/src/gpu/GrRecordReplaceDraw.cpp
+++ b/src/gpu/GrRecordReplaceDraw.cpp
@@ -12,7 +12,7 @@
#include "SkRecords.h"
GrReplacements::ReplacementInfo* GrReplacements::newReplacement(uint32_t pictureID,
- unsigned int start,
+ unsigned start,
const SkMatrix& ctm) {
ReplacementInfo* replacement = SkNEW_ARGS(ReplacementInfo, (pictureID, start, ctm));
fReplacementHash.add(replacement);
@@ -31,14 +31,13 @@ void GrReplacements::freeAll() {
}
const GrReplacements::ReplacementInfo* GrReplacements::lookupByStart(uint32_t pictureID,
- size_t start,
+ unsigned start,
const SkMatrix& ctm) const {
return fReplacementHash.find(ReplacementInfo::Key(pictureID, start, ctm));
}
static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo* ri,
- SkCanvas* canvas,
- const SkMatrix& initialMatrix) {
+ SkCanvas* canvas) {
SkRect src = SkRect::Make(ri->fSrcRect);
SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
SkIntToScalar(ri->fPos.fY),
@@ -46,7 +45,7 @@ static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo
SkIntToScalar(ri->fSrcRect.height()));
canvas->save();
- canvas->setMatrix(initialMatrix);
+ canvas->setMatrix(SkMatrix::I());
canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint);
canvas->restore();
}
@@ -131,7 +130,7 @@ public:
// For a saveLayer command, check if it can be replaced by a drawBitmap
// call and, if so, draw it and then update the current op index accordingly.
- size_t startOffset;
+ unsigned startOffset;
if (fOps.count()) {
startOffset = fOps[fIndex];
} else {
@@ -146,7 +145,7 @@ public:
if (ri) {
fNumReplaced++;
- draw_replacement_bitmap(ri, fCanvas, fInitialMatrix);
+ draw_replacement_bitmap(ri, fCanvas);
if (fPicture->fBBH.get()) {
while (fOps[fIndex] < ri->fStop) {
diff --git a/src/gpu/GrRecordReplaceDraw.h b/src/gpu/GrRecordReplaceDraw.h
index 9110ac82f9..fabeec1020 100644
--- a/src/gpu/GrRecordReplaceDraw.h
+++ b/src/gpu/GrRecordReplaceDraw.h
@@ -32,7 +32,7 @@ public:
class ReplacementInfo {
public:
struct Key {
- Key(uint32_t pictureID, unsigned int start, const SkMatrix& ctm)
+ Key(uint32_t pictureID, unsigned start, const SkMatrix& ctm)
: fPictureID(pictureID)
, fStart(start)
, fCTM(ctm) {
@@ -55,9 +55,9 @@ public:
unsigned int start() const { return fStart; }
private:
- const uint32_t fPictureID;
- const unsigned int fStart;
- const SkMatrix fCTM;
+ const uint32_t fPictureID;
+ const unsigned fStart;
+ const SkMatrix fCTM;
};
static const Key& GetKey(const ReplacementInfo& layer) { return layer.fKey; }
@@ -86,11 +86,11 @@ public:
~GrReplacements() { this->freeAll(); }
// Add a new replacement range.
- ReplacementInfo* newReplacement(uint32_t pictureID, unsigned int start, const SkMatrix& ctm);
+ ReplacementInfo* newReplacement(uint32_t pictureID, unsigned start, const SkMatrix& ctm);
// look up a replacement range by its pictureID, start offset and the CTM
// TODO: also need to add clip to lookup
- const ReplacementInfo* lookupByStart(uint32_t pictureID, size_t start,
+ const ReplacementInfo* lookupByStart(uint32_t pictureID, unsigned start,
const SkMatrix& ctm) const;
private:
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index fa7d89894d..158fa912dc 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -23,6 +23,7 @@
#include "SkGrTexturePixelRef.h"
+#include "SkCanvasPriv.h"
#include "SkDeviceImageFilterProxy.h"
#include "SkDrawProcs.h"
#include "SkGlyphCache.h"
@@ -1788,8 +1789,8 @@ SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps
bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* mainPicture,
const SkMatrix* matrix, const SkPaint* paint) {
- // todo: should handle these natively
- if (matrix || paint) {
+ // todo: should handle this natively
+ if (paint) {
return false;
}
@@ -1805,9 +1806,14 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
return true;
}
+ SkAutoCanvasMatrixPaint acmp(mainCanvas, matrix, paint, mainPicture->cullRect());
+
+ const SkMatrix initialMatrix = mainCanvas->getTotalMatrix();
+
SkTDArray<GrHoistedLayer> atlasedNeedRendering, atlasedRecycled;
GrLayerHoister::FindLayersToAtlas(fContext, mainPicture,
+ initialMatrix,
clipBounds,
&atlasedNeedRendering, &atlasedRecycled,
fRenderTarget->numSamples());
@@ -1817,6 +1823,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
SkTDArray<GrHoistedLayer> needRendering, recycled;
GrLayerHoister::FindLayersToHoist(fContext, mainPicture,
+ initialMatrix,
clipBounds,
&needRendering, &recycled,
fRenderTarget->numSamples());
@@ -1829,8 +1836,6 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
GrLayerHoister::ConvertLayersToReplacements(recycled, &replacements);
// Render the entire picture using new layers
- const SkMatrix initialMatrix = mainCanvas->getTotalMatrix();
-
GrRecordReplaceDraw(mainPicture, mainCanvas, &replacements, initialMatrix, NULL);
GrLayerHoister::UnlockLayers(fContext, needRendering);