diff options
author | robertphillips <robertphillips@google.com> | 2014-11-24 09:49:17 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-24 09:49:17 -0800 |
commit | 30d7841f906116c3945ec8125a816a5c5462fed0 (patch) | |
tree | 40fecb4654dc961252b95364d015d8db601c1bce /src/gpu | |
parent | 7ef849d45a4de02697697ea213bfae7c215a0c38 (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.cpp | 27 | ||||
-rw-r--r-- | src/gpu/GrLayerHoister.h | 4 | ||||
-rw-r--r-- | src/gpu/GrRecordReplaceDraw.cpp | 13 | ||||
-rw-r--r-- | src/gpu/GrRecordReplaceDraw.h | 12 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 13 |
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); |