Fuse GrReplacements and GrLayerCache
authorrobertphillips <robertphillips@google.com>
Wed, 3 Dec 2014 15:33:57 +0000 (07:33 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 3 Dec 2014 15:33:57 +0000 (07:33 -0800)
The conversion step from GrCachedLayer to ReplacementInfo isn't necessary.

Review URL: https://codereview.chromium.org/769533004

12 files changed:
src/core/SkLayerInfo.h
src/core/SkMultiPictureDraw.cpp
src/core/SkRecordDraw.cpp
src/gpu/GrLayerCache.cpp
src/gpu/GrLayerCache.h
src/gpu/GrLayerHoister.cpp
src/gpu/GrLayerHoister.h
src/gpu/GrRecordReplaceDraw.cpp
src/gpu/GrRecordReplaceDraw.h
src/gpu/SkGpuDevice.cpp
tests/GpuLayerCacheTest.cpp
tests/RecordReplaceDrawTest.cpp

index 6ed77c9..add57d7 100644 (file)
@@ -53,7 +53,7 @@ public:
         // The variable length key for this saveLayer block. It stores the
         // thread of drawPicture and saveLayer operation indices that lead to this
         // saveLayer (including its own op index). The BlockInfo owns this memory.
-        int*    fKey;
+        unsigned* fKey;
         int     fKeySize;  // # of ints
     };
 
index bd1e8fe..ed099a0 100644 (file)
@@ -15,6 +15,7 @@
 #include "SkTaskGroup.h"
 
 #if SK_SUPPORT_GPU
+#include "GrContext.h"
 #include "GrLayerHoister.h"
 #include "GrRecordReplaceDraw.h"
 #include "GrRenderTarget.h"
@@ -168,13 +169,9 @@ void SkMultiPictureDraw::draw() {
 
             GrLayerHoister::DrawLayers(context, needRendering);
 
-            GrReplacements replacements;
-
-            GrLayerHoister::ConvertLayersToReplacements(picture, needRendering, &replacements);
-            GrLayerHoister::ConvertLayersToReplacements(picture, recycled, &replacements);
-
             // Render the entire picture using new layers
-            GrRecordReplaceDraw(picture, canvas, &replacements, initialMatrix, NULL);
+            GrRecordReplaceDraw(picture, canvas, context->getLayerCache(),
+                                initialMatrix, NULL);
 
             GrLayerHoister::UnlockLayers(context, needRendering);
             GrLayerHoister::UnlockLayers(context, recycled);
index 4801f66..47bafe3 100644 (file)
@@ -691,10 +691,10 @@ private:
 
             // Store 'saveLayer ops from enclosing picture' + drawPict op + 'ops from sub-picture'
             dst.fKeySize = fSaveLayerOpStack.count() + src.fKeySize + 1;
-            dst.fKey = SkNEW_ARRAY(int, dst.fKeySize);
-            memcpy(dst.fKey, fSaveLayerOpStack.begin(), fSaveLayerOpStack.count() * sizeof(int));
+            dst.fKey = SkNEW_ARRAY(unsigned, dst.fKeySize);
+            memcpy(dst.fKey, fSaveLayerOpStack.begin(), fSaveLayerOpStack.count() * sizeof(unsigned));
             dst.fKey[fSaveLayerOpStack.count()] = fFillBounds.currentOp();
-            memcpy(&dst.fKey[fSaveLayerOpStack.count()+1], src.fKey, src.fKeySize * sizeof(int));
+            memcpy(&dst.fKey[fSaveLayerOpStack.count()+1], src.fKey, src.fKeySize * sizeof(unsigned));
         }
     }
 
@@ -766,8 +766,8 @@ private:
         block.fIsNested = fSaveLayersInStack > 0;
 
         block.fKeySize = fSaveLayerOpStack.count();
-        block.fKey = SkNEW_ARRAY(int, block.fKeySize);
-        memcpy(block.fKey, fSaveLayerOpStack.begin(), block.fKeySize * sizeof(int));
+        block.fKey = SkNEW_ARRAY(unsigned, block.fKeySize);
+        memcpy(block.fKey, fSaveLayerOpStack.begin(), block.fKeySize * sizeof(unsigned));
 
         fSaveLayerOpStack.pop();
     }
@@ -776,7 +776,7 @@ private:
     int                      fSaveLayersInStack;
     SkTDArray<SaveLayerInfo> fSaveLayerStack;
     // The op code indices of all the currently active saveLayers
-    SkTDArray<int>           fSaveLayerOpStack;
+    SkTDArray<unsigned>      fSaveLayerOpStack;
     SkLayerInfo*             fAccelData;
     const SkPicture::SnapshotArray* fPictList;
 
index c347512..fc5be5f 100644 (file)
@@ -125,7 +125,7 @@ GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID,
                                          int start, int stop,
                                          const SkIRect& bounds,
                                          const SkMatrix& initialMat,
-                                         const int* key,
+                                         const unsigned* key,
                                          int keySize,
                                          const SkPaint* paint) {
     SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0);
@@ -137,7 +137,7 @@ GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID,
 }
 
 GrCachedLayer* GrLayerCache::findLayer(uint32_t pictureID, const SkMatrix& initialMat,
-                                       const int* key, int keySize) {
+                                       const unsigned* key, int keySize) {
     SkASSERT(pictureID != SK_InvalidGenID);
     return fLayerHash.find(GrCachedLayer::Key(pictureID, initialMat, key, keySize));
 }
@@ -146,7 +146,7 @@ GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID,
                                                int start, int stop,
                                                const SkIRect& bounds,
                                                const SkMatrix& initialMat,
-                                               const int* key,
+                                               const unsigned* key,
                                                int keySize,
                                                const SkPaint* paint) {
     SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0);
@@ -209,9 +209,8 @@ bool GrLayerCache::tryToAtlas(GrCachedLayer* layer,
                 pictInfo->incPlotUsage(plot->id());
 #endif
                 // The layer was successfully added to the atlas
-                GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY,
-                                                       SkToS16(desc.fWidth),
-                                                       SkToS16(desc.fHeight));
+                const SkIRect bounds = SkIRect::MakeXYWH(loc.fX, loc.fY, 
+                                                         desc.fWidth, desc.fHeight);
                 layer->setTexture(fAtlas->getTexture(), bounds);
                 layer->setPlot(plot);
                 layer->setLocked(true);
@@ -250,7 +249,7 @@ bool GrLayerCache::lock(GrCachedLayer* layer, const GrSurfaceDesc& desc, bool* n
         return false;
     }
 
-    layer->setTexture(tex, GrIRect16::MakeWH(SkToS16(desc.fWidth), SkToS16(desc.fHeight)));
+    layer->setTexture(tex, SkIRect::MakeWH(desc.fWidth, desc.fHeight));
     layer->setLocked(true);
     *needsRendering = true;
     return true;
@@ -289,11 +288,11 @@ void GrLayerCache::unlock(GrCachedLayer* layer) {
         }
 
         layer->setPlot(NULL);
-        layer->setTexture(NULL, GrIRect16::MakeEmpty());
+        layer->setTexture(NULL, SkIRect::MakeEmpty());
 #endif
 
     } else {
-        layer->setTexture(NULL, GrIRect16::MakeEmpty());
+        layer->setTexture(NULL, SkIRect::MakeEmpty());
     }
 
     layer->setLocked(false);
index 967503d..b9b59d0 100644 (file)
@@ -77,7 +77,7 @@ public:
     // For SkTDynamicHash
     struct Key {
         Key(uint32_t pictureID, const SkMatrix& initialMat, 
-            const int* key, int keySize, bool copyKey = false)
+            const unsigned* key, int keySize, bool copyKey = false)
         : fKeySize(keySize) 
         , fFreeKey(copyKey) {
             fIDMatrix.fPictureID = pictureID;
@@ -85,8 +85,8 @@ public:
             fIDMatrix.fInitialMat.getType(); // force initialization of type so hashes match
 
             if (copyKey) {
-                int* tempKey = SkNEW_ARRAY(int, keySize);
-                memcpy(tempKey, key, keySize*sizeof(int));
+                unsigned* tempKey = SkNEW_ARRAY(unsigned, keySize);
+                memcpy(tempKey, key, keySize*sizeof(unsigned));
                 fKey = tempKey;
             } else {
                 fKey = key;
@@ -115,7 +115,7 @@ public:
         uint32_t pictureID() const { return fIDMatrix.fPictureID; }
 
         // TODO: remove these when GrCachedLayer & ReplacementInfo fuse
-        const int* key() const { SkASSERT(fFreeKey);  return fKey; }
+        const unsigned* key() const { SkASSERT(fFreeKey);  return fKey; }
         int keySize() const { SkASSERT(fFreeKey); return fKeySize; }
 
         uint32_t hash() const {
@@ -133,18 +133,18 @@ public:
             SkMatrix fInitialMat;
         }              fIDMatrix;
 
-        const int*     fKey;
-        const int      fKeySize;
-        bool           fFreeKey;
+        const unsigned* fKey;
+        const int       fKeySize;
+        bool            fFreeKey;
     };
 
     static const Key& GetKey(const GrCachedLayer& layer) { return layer.fKey; }
     static uint32_t Hash(const Key& key) { return key.hash(); }
 
     // GrCachedLayer proper
-    GrCachedLayer(uint32_t pictureID, int start, int stop,
+    GrCachedLayer(uint32_t pictureID, unsigned start, unsigned stop,
                   const SkIRect& bounds, const SkMatrix& ctm,
-                  const int* key, int keySize,
+                  const unsigned* key, int keySize,
                   const SkPaint* paint)
         : fKey(pictureID, ctm, key, keySize, true)
         , fStart(start)
@@ -152,11 +152,11 @@ public:
         , fBounds(bounds)
         , fPaint(paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL)
         , fTexture(NULL)
-        , fRect(GrIRect16::MakeEmpty())
+        , fRect(SkIRect::MakeEmpty())
         , fPlot(NULL)
         , fUses(0)
         , fLocked(false) {
-        SkASSERT(SK_InvalidGenID != pictureID && start >= 0 && stop >= 0);
+        SkASSERT(SK_InvalidGenID != pictureID);
     }
 
     ~GrCachedLayer() {
@@ -166,20 +166,20 @@ public:
 
     uint32_t pictureID() const { return fKey.pictureID(); }
     // TODO: remove these when GrCachedLayer & ReplacementInfo fuse
-    const int* key() const { return fKey.key(); }
+    const unsigned* key() const { return fKey.key(); }
     int keySize() const { return fKey.keySize(); }
 
-    int start() const { return fStart; }
+    unsigned start() const { return fStart; }
     // TODO: make bound debug only
     const SkIRect& bound() const { return fBounds; }
-    int stop() const { return fStop; }
-    void setTexture(GrTexture* texture, const GrIRect16& rect) {
+    unsigned stop() const { return fStop; }
+    void setTexture(GrTexture* texture, const SkIRect& rect) {
         SkRefCnt_SafeAssign(fTexture, texture);
         fRect = rect;
     }
     GrTexture* texture() { return fTexture; }
     const SkPaint* paint() const { return fPaint; }
-    const GrIRect16& rect() const { return fRect; }
+    const SkIRect& rect() const { return fRect; }
 
     void setPlot(GrPlot* plot) {
         SkASSERT(NULL == plot || NULL == fPlot);
@@ -199,9 +199,9 @@ private:
     const Key       fKey;
 
     // The "saveLayer" operation index of the cached layer
-    const int       fStart;
+    const unsigned  fStart;
     // The final "restore" operation index of the cached layer
-    const int       fStop;
+    const unsigned  fStop;
 
     const SkIRect   fBounds;
 
@@ -216,7 +216,7 @@ private:
     // For both atlased and non-atlased layers 'fRect' contains the  bound of
     // the layer in whichever texture it resides. It is empty when 'fTexture'
     // is NULL.
-    GrIRect16       fRect;
+    SkIRect         fRect;
 
     // For atlased layers, fPlot stores the atlas plot in which the layer rests.
     // It is always NULL for non-atlased layers.
@@ -259,11 +259,13 @@ public:
     // elements by the GrContext
     void freeAll();
 
+    GrCachedLayer* findLayer(uint32_t pictureID, const SkMatrix& ctm,
+                             const unsigned* key, int keySize);
     GrCachedLayer* findLayerOrCreate(uint32_t pictureID,
                                      int start, int stop, 
                                      const SkIRect& bounds,
                                      const SkMatrix& initialMat,
-                                     const int* key, int keySize,
+                                     const unsigned* key, int keySize,
                                      const SkPaint* paint);
 
     // Attempt to place 'layer' in the atlas. Return true on success; false on failure.
@@ -346,7 +348,7 @@ private:
     void initAtlas();
     GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop,
                                const SkIRect& bounds, const SkMatrix& initialMat,
-                               const int* key, int keySize,
+                               const unsigned* key, int keySize,
                                const SkPaint* paint);
 
     // Remove all the layers (and unlock any resources) associated with 'pictureID'
@@ -367,8 +369,6 @@ private:
     // for testing
     friend class TestingAccess;
     int numLayers() const { return fLayerHash.count(); }
-    GrCachedLayer* findLayer(uint32_t pictureID, const SkMatrix& ctm,
-                             const int* key, int keySize);
 };
 
 #endif
index 4e78368..a17c7dd 100644 (file)
@@ -72,7 +72,6 @@ static void prepare_for_hoisting(GrLayerCache* layerCache,
     layerCache->addUse(layer);
     hl->fLayer = layer;
     hl->fPicture = pict;
-    hl->fOffset = SkIPoint::Make(layerRect.fLeft, layerRect.fTop);
     hl->fLocalMat = info.fLocalMat;
     hl->fInitialMat = initialMat;
     hl->fPreMat = initialMat;
@@ -185,46 +184,6 @@ void GrLayerHoister::FindLayersToHoist(GrContext* context,
     }
 }
 
-static void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* result) {
-    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
-    result->setInfo(info);
-    result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
-}
-
-void GrLayerHoister::ConvertLayersToReplacements(const SkPicture* topLevelPicture,
-                                                 const SkTDArray<GrHoistedLayer>& layers,
-                                                 GrReplacements* replacements) {
-    // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer?
-    for (int i = 0; i < layers.count(); ++i) {
-        GrCachedLayer* layer = layers[i].fLayer;
-
-        GrReplacements::ReplacementInfo* layerInfo =
-                    replacements->newReplacement(topLevelPicture->uniqueID(),
-                                                 layers[i].fInitialMat,
-                                                 layer->key(), layer->keySize());
-        layerInfo->fStop = layer->stop();
-        layerInfo->fPos = layers[i].fOffset;
-
-        SkBitmap bm;
-        wrap_texture(layers[i].fLayer->texture(),
-                     !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().width()
-                                                    : layers[i].fLayer->texture()->width(),
-                     !layers[i].fLayer->isAtlased() ? layers[i].fLayer->rect().height()
-                                                    : layers[i].fLayer->texture()->height(),
-                     &bm);
-        layerInfo->fImage = SkImage::NewTexture(bm);
-
-        layerInfo->fPaint = layers[i].fLayer->paint()
-                                ? SkNEW_ARGS(SkPaint, (*layers[i].fLayer->paint()))
-                                : NULL;
-
-        layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i].fLayer->rect().fLeft,
-                                                layers[i].fLayer->rect().fTop,
-                                                layers[i].fLayer->rect().width(),
-                                                layers[i].fLayer->rect().height());
-    }
-}
-
 void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
                                        const SkTDArray<GrHoistedLayer>& atlased) {
     if (atlased.count() > 0) {
@@ -241,7 +200,7 @@ void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
         for (int i = 0; i < atlased.count(); ++i) {
             const GrCachedLayer* layer = atlased[i].fLayer;
             const SkPicture* pict = atlased[i].fPicture;
-            const SkIPoint offset = atlased[i].fOffset;
+            const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->bound().fTop);
             SkDEBUGCODE(const SkPaint* layerPaint = layer->paint();)
 
             SkASSERT(!layerPaint || !layerPaint->getImageFilter());
@@ -250,10 +209,7 @@ void GrLayerHoister::DrawLayersToAtlas(GrContext* context,
 
             // Add a rect clip to make sure the rendering doesn't
             // extend beyond the boundaries of the atlased sub-rect
-            SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
-                                            SkIntToScalar(layer->rect().fTop),
-                                            SkIntToScalar(layer->rect().width()),
-                                            SkIntToScalar(layer->rect().height()));
+            const SkRect bound = SkRect::Make(layer->rect());
             atlasCanvas->clipRect(bound);
 
             // Since 'clear' doesn't respect the clip we need to draw a rect
@@ -285,7 +241,7 @@ void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
     for (int i = 0; i < layers.count(); ++i) {
         GrCachedLayer* layer = layers[i].fLayer;
         const SkPicture* pict = layers[i].fPicture;
-        const SkIPoint& offset = layers[i].fOffset;
+        const SkIPoint offset = SkIPoint::Make(layer->bound().fLeft, layer->bound().fTop);
 
         // Each non-atlased layer has its own GrTexture
         SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
@@ -297,11 +253,7 @@ void GrLayerHoister::DrawLayers(GrContext* context, const SkTDArray<GrHoistedLay
 
         // Add a rect clip to make sure the rendering doesn't
         // extend beyond the boundaries of the layer
-        SkRect bound = SkRect::MakeXYWH(SkIntToScalar(layer->rect().fLeft),
-                                        SkIntToScalar(layer->rect().fTop),
-                                        SkIntToScalar(layer->rect().width()),
-                                        SkIntToScalar(layer->rect().height()));
-
+        const SkRect bound = SkRect::Make(layer->rect());
         layerCanvas->clipRect(bound);
 
         layerCanvas->clear(SK_ColorTRANSPARENT);
index a28f887..2d68a94 100644 (file)
@@ -20,7 +20,6 @@ public:
     const SkPicture* fPicture;  // the picture that actually contains the layer
                                 // (not necessarily the top-most picture)
     GrCachedLayer*   fLayer;
-    SkIPoint         fOffset;
     SkMatrix         fInitialMat;
     SkMatrix         fPreMat;
     SkMatrix         fLocalMat;
index 3701dda..852c51f 100644 (file)
@@ -5,50 +5,34 @@
  * found in the LICENSE file.
  */
 
+#include "GrContext.h"
+#include "GrLayerCache.h"
 #include "GrRecordReplaceDraw.h"
 #include "SkCanvasPriv.h"
+#include "SkGrPixelRef.h"
 #include "SkImage.h"
 #include "SkRecordDraw.h"
 #include "SkRecords.h"
 
-GrReplacements::ReplacementInfo* GrReplacements::newReplacement(uint32_t pictureID,
-                                                                const SkMatrix& initialMat,
-                                                                const int* key, int keySize) {
-    ReplacementInfo* replacement = SkNEW_ARGS(ReplacementInfo, (pictureID, initialMat,
-                                                                key, keySize));
-    fReplacementHash.add(replacement);
-    return replacement;
+static inline void wrap_texture(GrTexture* texture, int width, int height, SkBitmap* result) {
+    SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
+    result->setInfo(info);
+    result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
 }
 
-void GrReplacements::freeAll() {
-    SkTDynamicHash<ReplacementInfo, ReplacementInfo::Key>::Iter iter(&fReplacementHash);
+static inline void draw_replacement_bitmap(GrCachedLayer* layer, SkCanvas* canvas) {
+    const SkRect src = SkRect::Make(layer->rect());
+    const SkRect dst = SkRect::Make(layer->bound());
 
-    for (; !iter.done(); ++iter) {
-        ReplacementInfo* replacement = &(*iter);
-        SkDELETE(replacement);
-    }
-
-    fReplacementHash.reset();
-}
-
-const GrReplacements::ReplacementInfo* GrReplacements::lookup(uint32_t pictureID,
-                                                              const SkMatrix& initialMat,
-                                                              const int* key,
-                                                              int keySize) const {
-    return fReplacementHash.find(ReplacementInfo::Key(pictureID, initialMat, key, keySize));
-}
-
-static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo* ri,
-                                           SkCanvas* canvas) {
-    SkRect src = SkRect::Make(ri->fSrcRect);
-    SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
-                                  SkIntToScalar(ri->fPos.fY),
-                                  SkIntToScalar(ri->fSrcRect.width()),
-                                  SkIntToScalar(ri->fSrcRect.height()));
+    SkBitmap bm;
+    wrap_texture(layer->texture(),
+                 !layer->isAtlased() ? layer->rect().width()  : layer->texture()->width(),
+                 !layer->isAtlased() ? layer->rect().height() : layer->texture()->height(),
+                 &bm);
 
     canvas->save();
     canvas->setMatrix(SkMatrix::I());
-    canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint);
+    canvas->drawBitmapRectToRect(bm, &src, dst, layer->paint());
     canvas->restore();
 }
 
@@ -56,19 +40,18 @@ static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo
 // also draws them with replaced layers.
 class ReplaceDraw : public SkRecords::Draw {
 public:
-    ReplaceDraw(SkCanvas* canvas,
+    ReplaceDraw(SkCanvas* canvas, GrLayerCache* layerCache,
                 SkPicture const* const drawablePicts[], int drawableCount,
                 const SkPicture* topLevelPicture,
                 const SkPicture* picture,
-                const GrReplacements* replacements,
                 const SkMatrix& initialMatrix,
                 SkDrawPictureCallback* callback,
-                const int* opIndices, int numIndices)
+                const unsigned* opIndices, int numIndices)
         : INHERITED(canvas, drawablePicts, NULL, drawableCount)
         , fCanvas(canvas)
+        , fLayerCache(layerCache)
         , fTopLevelPicture(topLevelPicture)
         , fPicture(picture)
-        , fReplacements(replacements)
         , fInitialMatrix(initialMatrix)
         , fCallback(callback)
         , fIndex(0)
@@ -137,8 +120,9 @@ public:
         SkAutoCanvasMatrixPaint acmp(fCanvas, &dp.matrix, dp.paint, dp.picture->cullRect());
 
         // Draw sub-pictures with the same replacement list but a different picture
-        ReplaceDraw draw(fCanvas, this->drawablePicts(), this->drawableCount(),
-                         fTopLevelPicture, dp.picture, fReplacements, fInitialMatrix, fCallback,
+        ReplaceDraw draw(fCanvas, fLayerCache, 
+                         this->drawablePicts(), this->drawableCount(),
+                         fTopLevelPicture, dp.picture, fInitialMatrix, fCallback,
                          fOpIndexStack.begin(), fOpIndexStack.count());
 
         fNumReplaced += draw.draw();
@@ -158,23 +142,23 @@ public:
 
         fOpIndexStack.push(startOffset);
 
-        const GrReplacements::ReplacementInfo* ri = fReplacements->lookup(
-                                                                    fTopLevelPicture->uniqueID(),
-                                                                    fInitialMatrix,
-                                                                    fOpIndexStack.begin(),
-                                                                    fOpIndexStack.count());
+        GrCachedLayer* layer = fLayerCache->findLayer(fTopLevelPicture->uniqueID(),
+                                                      fInitialMatrix,
+                                                      fOpIndexStack.begin(),
+                                                      fOpIndexStack.count());
 
-        if (ri) {
+        if (layer) {
             fNumReplaced++;
-            draw_replacement_bitmap(ri, fCanvas);
+
+            draw_replacement_bitmap(layer, fCanvas);
 
             if (fPicture->fBBH.get()) {
-                while (fOps[fIndex] < ri->fStop) {
+                while (fOps[fIndex] < layer->stop()) {
                     ++fIndex;
                 }
-                SkASSERT(fOps[fIndex] == ri->fStop);
+                SkASSERT(fOps[fIndex] == layer->stop());
             } else {
-                fIndex = ri->fStop;
+                fIndex = layer->stop();
             }
             fOpIndexStack.pop();
             return;
@@ -188,9 +172,9 @@ public:
 
 private:
     SkCanvas*              fCanvas;
+    GrLayerCache*          fLayerCache;
     const SkPicture*       fTopLevelPicture;
     const SkPicture*       fPicture;
-    const GrReplacements*  fReplacements;
     const SkMatrix         fInitialMatrix;
     SkDrawPictureCallback* fCallback;
 
@@ -199,22 +183,21 @@ private:
     int                    fNumReplaced;
 
     // The op code indices of all the enclosing drawPicture and saveLayer calls
-    SkTDArray<int>         fOpIndexStack;
+    SkTDArray<unsigned>    fOpIndexStack;
 
     typedef Draw INHERITED;
 };
 
 int GrRecordReplaceDraw(const SkPicture* picture,
                         SkCanvas* canvas,
-                        const GrReplacements* replacements,
+                        GrLayerCache* layerCache,
                         const SkMatrix& initialMatrix,
                         SkDrawPictureCallback* callback) {
     SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
 
     // TODO: drawablePicts?
-    ReplaceDraw draw(canvas, NULL, 0,
+    ReplaceDraw draw(canvas, layerCache, NULL, 0,
                      picture, picture,
-                     replacements, initialMatrix, callback, NULL, 0);
-
+                     initialMatrix, callback, NULL, 0);
     return draw.draw();
 }
index 538661a..c0dd0b6 100644 (file)
 #ifndef GrRecordReplaceDraw_DEFINED
 #define GrRecordReplaceDraw_DEFINED
 
-#include "SkChecksum.h"
 #include "SkDrawPictureCallback.h"
-#include "SkImage.h"
-#include "SkRect.h"
-#include "SkTDynamicHash.h"
 
-class SkBBoxHierarchy;
-class SkBitmap;
+class GrLayerCache;
 class SkCanvas;
-class SkImage;
 class SkMatrix;
-class SkPaint;
 class SkPicture;
-class SkRecord;
-
-// GrReplacements collects op ranges that can be replaced with
-// a single drawBitmap call (using a precomputed bitmap).
-class GrReplacements {
-public:
-    // All the operations between fStart and fStop (inclusive) will be replaced with
-    // a single drawBitmap call using fPos, fImage and fPaint.
-    class ReplacementInfo {
-    public:
-        struct Key {
-            Key(uint32_t pictureID, const SkMatrix& initialMat,
-                const int* key, int keySize, bool copyKey = false)
-            : fKeySize(keySize)
-            , fFreeKey(copyKey) {
-                fIDMatrix.fPictureID = pictureID;
-                fIDMatrix.fInitialMat = initialMat;
-                fIDMatrix.fInitialMat.getType(); // force initialization of type so hashes match
-
-                if (copyKey) {
-                    int* tempKey = SkNEW_ARRAY(int, keySize);
-                    memcpy(tempKey, key, keySize * sizeof(int));
-                    fKey = tempKey;
-                } else {
-                    fKey = key;
-                }
-
-                // The pictureID/matrix portion needs to be tightly packed.
-                GR_STATIC_ASSERT(sizeof(IDMatrix) == sizeof(uint32_t)+                // pictureID
-                                              9 * sizeof(SkScalar)+sizeof(uint32_t)); // matrix
-            }
-
-            ~Key() {
-                if (fFreeKey) {
-                    SkDELETE_ARRAY(fKey);
-                }
-            }
-            bool operator==(const Key& other) const {
-                if (fKeySize != other.fKeySize) {
-                    return false;
-                }
-                return fIDMatrix.fPictureID == other.fIDMatrix.fPictureID &&
-                       fIDMatrix.fInitialMat.cheapEqualTo(other.fIDMatrix.fInitialMat) &&
-                       !memcmp(fKey, other.fKey, fKeySize * sizeof(int));
-            }
-
-            uint32_t hash() const {
-                uint32_t hash = SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(fKey),
-                                                    fKeySize * sizeof(int));
-                return SkChecksum::Murmur3(reinterpret_cast<const uint32_t*>(&fIDMatrix),
-                                           sizeof(IDMatrix), hash);
-            }
-
-        private:
-            struct IDMatrix {
-                uint32_t fPictureID;
-                SkMatrix fInitialMat;
-            }              fIDMatrix;
-
-            const int*     fKey;
-            const int      fKeySize;
-            const bool     fFreeKey;
-        };
-
-        static const Key& GetKey(const ReplacementInfo& layer) { return layer.fKey; }
-        static uint32_t Hash(const Key& key) { return key.hash(); }
-
-        ReplacementInfo(uint32_t pictureID, const SkMatrix& initialMat,
-                        const int* key, int keySize)
-            : fKey(pictureID, initialMat, key, keySize, true)
-            , fImage(NULL)
-            , fPaint(NULL) {
-        }
-        ~ReplacementInfo() { fImage->unref(); SkDELETE(fPaint); }
-
-        const Key       fKey;
-        unsigned        fStop;
-        SkIPoint        fPos;
-        SkImage*        fImage;  // Owns a ref
-        const SkPaint*  fPaint;  // Owned by this object
-
-        SkIRect         fSrcRect;
-    };
-
-    ~GrReplacements() { this->freeAll(); }
-
-    // Add a new replacement range.
-    ReplacementInfo* newReplacement(uint32_t pictureID, const SkMatrix& initialMat,
-                                    const int* key, int keySize);
-
-    const ReplacementInfo* lookup(uint32_t pictureID, const SkMatrix& initalMat,
-                                  const int* key, int keySize) const;
-
-private:
-    SkTDynamicHash<ReplacementInfo, ReplacementInfo::Key> fReplacementHash;
-
-    void freeAll();
-};
 
 // Draw an SkPicture into an SkCanvas replacing saveLayer/restore blocks with
 // drawBitmap calls.  A convenience wrapper around SkRecords::Draw.
 // It returns the number of saveLayer/restore blocks replaced with drawBitmap calls.
 int GrRecordReplaceDraw(const SkPicture*,
                         SkCanvas*,
-                        const GrReplacements*,
+                        GrLayerCache* layerCache,
                         const SkMatrix& initialMatrix,
                         SkDrawPictureCallback*);
 
index 3f08aa4..407f360 100644 (file)
@@ -1863,13 +1863,9 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
 
     GrLayerHoister::DrawLayers(fContext, needRendering);
 
-    GrReplacements replacements;
-
-    GrLayerHoister::ConvertLayersToReplacements(mainPicture, needRendering, &replacements);
-    GrLayerHoister::ConvertLayersToReplacements(mainPicture, recycled, &replacements);
-
     // Render the entire picture using new layers
-    GrRecordReplaceDraw(mainPicture, mainCanvas, &replacements, initialMatrix, NULL);
+    GrRecordReplaceDraw(mainPicture, mainCanvas, fContext->getLayerCache(),
+                        initialMatrix, NULL);
 
     GrLayerHoister::UnlockLayers(fContext, needRendering);
     GrLayerHoister::UnlockLayers(fContext, recycled);
index 43a845b..cba331f 100644 (file)
@@ -15,7 +15,7 @@
 
 class TestingAccess {
 public:
-    static int NumLayers(GrLayerCache* cache) {
+    static unsigned NumLayers(GrLayerCache* cache) {
         return cache->numLayers();
     }
     static void Purge(GrLayerCache* cache, uint32_t pictureID) {
@@ -25,7 +25,8 @@ public:
         return layer->uses();
     }
     static GrCachedLayer* Find(GrLayerCache* cache, uint32_t pictureID,
-                               const SkMatrix& initialMat, const int* key, int keySize) {
+                               const SkMatrix& initialMat, 
+                               const unsigned* key, int keySize) {
         return cache->findLayer(pictureID, initialMat, key, keySize);
     }
 };
@@ -34,11 +35,11 @@ public:
 static void create_layers(skiatest::Reporter* reporter,
                           GrLayerCache* cache,
                           const SkPicture& picture,
-                          int numToAdd,
-                          int idOffset) {
+                          unsigned numToAdd,
+                          unsigned idOffset) {
 
-    for (int i = 0; i < numToAdd; ++i) {
-        int indices[1] = { idOffset+i+1 };
+    for (unsigned i = 0; i < numToAdd; ++i) {
+        unsigned indices[1] = { idOffset+i+1 };
         GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(), 
                                                         idOffset+i+1, idOffset+i+2, 
                                                         SkIRect::MakeEmpty(),
@@ -116,8 +117,8 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
 
         create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
 
-        for (int i = 0; i < kInitialNumLayers; ++i) {
-            int indices[1] = { i + 1 };
+        for (unsigned i = 0; i < kInitialNumLayers; ++i) {
+            unsigned indices[1] = { i + 1 };
             GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                        indices, 1);
             REPORTER_ASSERT(reporter, layer);
@@ -135,8 +136,8 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
         }
 
         // Unlock the textures
-        for (int i = 0; i < kInitialNumLayers; ++i) {
-            int indices[1] = { i+1 };
+        for (unsigned i = 0; i < kInitialNumLayers; ++i) {
+            unsigned indices[1] = { i+1 };
 
             GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                        indices, 1);
@@ -144,8 +145,8 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
             cache.removeUse(layer);
         }
 
-        for (int i = 0; i < kInitialNumLayers; ++i) {
-            int indices[1] = { i+1 };
+        for (unsigned i = 0; i < kInitialNumLayers; ++i) {
+            unsigned indices[1] = { i+1 };
 
             GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                        indices, 1);
@@ -172,7 +173,7 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
         }
 
         {
-            int indices[1] = { kInitialNumLayers+1 };
+            unsigned indices[1] = { kInitialNumLayers+1 };
 
             // Add an additional layer. Since all the layers are unlocked this 
             // will force out the first atlased layer
@@ -185,8 +186,8 @@ DEF_GPUTEST(GpuLayerCache, reporter, factory) {
             cache.removeUse(layer);
         }
 
-        for (int i = 0; i < kInitialNumLayers+1; ++i) {
-            int indices[1] = { i+1 };
+        for (unsigned i = 0; i < kInitialNumLayers+1; ++i) {
+            unsigned indices[1] = { i+1 };
 
             GrCachedLayer* layer = TestingAccess::Find(&cache, picture->uniqueID(), SkMatrix::I(),
                                                        indices, 1);
index 8fc824d..edd4766 100644 (file)
@@ -9,6 +9,8 @@
 
 #include "Test.h"
 
+#include "GrContextFactory.h"
+#include "GrLayerCache.h"
 #include "GrRecordReplaceDraw.h"
 #include "RecordTestUtils.h"
 #include "SkBBHFactory.h"
@@ -47,9 +49,8 @@ DEF_TEST(RecordReplaceDraw_Abort, r) {
     SkRecord rerecord;
     SkRecorder canvas(&rerecord, kWidth, kHeight);
 
-    GrReplacements replacements;
     JustOneDraw callback;
-    GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), &callback);
+    GrRecordReplaceDraw(pic, &canvas, NULL, SkMatrix::I(), &callback);
 
     REPORTER_ASSERT(r, 3 == rerecord.count());
     assert_type<SkRecords::Save>(r, rerecord, 0);
@@ -74,8 +75,7 @@ DEF_TEST(RecordReplaceDraw_Unbalanced, r) {
     SkRecord rerecord;
     SkRecorder canvas(&rerecord, kWidth, kHeight);
 
-    GrReplacements replacements;
-    GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), NULL/*callback*/);
+    GrRecordReplaceDraw(pic, &canvas, NULL, SkMatrix::I(), NULL/*callback*/);
 
     REPORTER_ASSERT(r, 4 == rerecord.count());
     assert_type<SkRecords::Save>(r, rerecord, 0);
@@ -84,20 +84,8 @@ DEF_TEST(RecordReplaceDraw_Unbalanced, r) {
     assert_type<SkRecords::Restore>(r, rerecord, 3);
 }
 
-static SkImage* make_image(SkColor color) {
-    const SkPMColor pmcolor = SkPreMultiplyColor(color);
-    const SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
-    const size_t rowBytes = info.minRowBytes();
-    const size_t size = rowBytes * info.height();
-
-    SkAutoMalloc addr(size);
-    sk_memset32((SkPMColor*)addr.get(), pmcolor, SkToInt(size >> 2));
-
-    return SkImage::NewRasterCopy(info, addr.get(), rowBytes);
-}
-
 // Test out the layer replacement functionality with and w/o a BBH
-void test_replacements(skiatest::Reporter* r, bool useBBH) {
+void test_replacements(skiatest::Reporter* r, GrContext* context, bool useBBH) {
     SkAutoTUnref<const SkPicture> pic;
 
     {
@@ -115,34 +103,53 @@ void test_replacements(skiatest::Reporter* r, bool useBBH) {
         pic.reset(recorder.endRecording());
     }
 
-    int key[1] = { 0 };
+    unsigned key[1] = { 0 };
 
-    GrReplacements replacements;
-    GrReplacements::ReplacementInfo* ri = replacements.newReplacement(pic->uniqueID(), 
-                                                                      SkMatrix::I(), key, 1);
-    ri->fStop = 2;
-    ri->fPos.set(0, 0);
-    ri->fImage = make_image(SK_ColorRED);
-    ri->fPaint = SkNEW(SkPaint);
-    ri->fSrcRect = SkIRect::MakeWH(kWidth, kHeight);
+    GrLayerCache* layerCache = context->getLayerCache();
+    GrCachedLayer* layer = layerCache->findLayerOrCreate(pic->uniqueID(), 0, 2, 
+                                                         SkIRect::MakeWH(kWidth, kHeight),
+                                                         SkMatrix::I(), key, 1, SkNEW(SkPaint));
+
+    GrSurfaceDesc desc;
+    desc.fConfig = kSkia8888_GrPixelConfig;
+    desc.fFlags = kRenderTarget_GrSurfaceFlag;
+    desc.fWidth = kWidth;
+    desc.fHeight = kHeight;
+    desc.fSampleCnt = 0;
+
+    SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
+    layer->setTexture(texture, SkIRect::MakeWH(kWidth, kHeight));
 
     SkAutoTUnref<SkBBoxHierarchy> bbh;
 
     SkRecord rerecord;
     SkRecorder canvas(&rerecord, kWidth, kHeight);
-    GrRecordReplaceDraw(pic, &canvas, &replacements, SkMatrix::I(), NULL/*callback*/);
+    GrRecordReplaceDraw(pic, &canvas, layerCache, SkMatrix::I(), NULL/*callback*/);
 
     REPORTER_ASSERT(r, 7 == rerecord.count());
     assert_type<SkRecords::Save>(r, rerecord, 0);
     assert_type<SkRecords::Save>(r, rerecord, 1);
     assert_type<SkRecords::SetMatrix>(r, rerecord, 2);
-    assert_type<SkRecords::DrawImageRect>(r, rerecord, 3);
+    assert_type<SkRecords::DrawBitmapRectToRect>(r, rerecord, 3);
     assert_type<SkRecords::Restore>(r, rerecord, 4);
     assert_type<SkRecords::DrawRect>(r, rerecord, 5);
     assert_type<SkRecords::Restore>(r, rerecord, 6);
 }
 
-DEF_TEST(RecordReplaceDraw_Replace, r)        { test_replacements(r, false); }
-DEF_TEST(RecordReplaceDraw_ReplaceWithBBH, r) { test_replacements(r, true); }
+DEF_GPUTEST(RecordReplaceDraw, r, factory) { 
+    for (int type = 0; type < GrContextFactory::kLastGLContextType; ++type) {
+        GrContextFactory::GLContextType glType = static_cast<GrContextFactory::GLContextType>(type);
+        if (!GrContextFactory::IsRenderingGLContext(glType)) {
+            continue;
+        }
+        GrContext* context = factory->get(glType);
+        if (NULL == context) {
+            continue;
+        }
+
+        test_replacements(r, context, true);
+        test_replacements(r, context, false);
+    }
+}
 
 #endif