Separate replacement creation from layer discovery

This is a simple refactoring that sets the stage for eliminating GrReplacements::ReplacementInfo and splitting up EXPERIMENTAL_drawPicture to support multi picture draw.

R=bsalomon@google.com

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/559603004
diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp
index 8e61cb7..11a97e4 100644
--- a/src/gpu/GrLayerCache.cpp
+++ b/src/gpu/GrLayerCache.cpp
@@ -120,10 +120,11 @@
 GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID, 
                                          int start, int stop, 
                                          const SkIPoint& offset,
-                                         const SkMatrix& ctm) {
+                                         const SkMatrix& ctm,
+                                         const SkPaint* paint) {
     SkASSERT(pictureID != SK_InvalidGenID && start > 0 && stop > 0);
 
-    GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, offset, ctm));
+    GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, offset, ctm, paint));
     fLayerHash.add(layer);
     return layer;
 }
@@ -139,11 +140,12 @@
 GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID,
                                                int start, int stop,
                                                const SkIPoint& offset,
-                                               const SkMatrix& ctm) {
+                                               const SkMatrix& ctm,
+                                               const SkPaint* paint) {
     SkASSERT(pictureID != SK_InvalidGenID && start > 0 && stop > 0);
     GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(pictureID, start, stop, offset, ctm));
     if (NULL == layer) {
-        layer = this->createLayer(pictureID, start, stop, offset, ctm);
+        layer = this->createLayer(pictureID, start, stop, offset, ctm, paint);
     }
 
     return layer;
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h
index 15fa246..1fb4c10 100644
--- a/src/gpu/GrLayerCache.h
+++ b/src/gpu/GrLayerCache.h
@@ -98,8 +98,10 @@
 
     // GrCachedLayer proper
     GrCachedLayer(uint32_t pictureID, int start, int stop,
-                  const SkIPoint& offset, const SkMatrix& ctm) 
+                  const SkIPoint& offset, const SkMatrix& ctm,
+                  const SkPaint* paint)
         : fKey(pictureID, start, stop, offset, ctm)
+        , fPaint(paint)
         , fTexture(NULL)
         , fRect(GrIRect16::MakeEmpty())
         , fPlot(NULL)
@@ -122,6 +124,7 @@
         fRect = rect;
     }
     GrTexture* texture() { return fTexture; }
+    const SkPaint* paint() const { return fPaint; }
     const GrIRect16& rect() const { return fRect; }
 
     void setPlot(GrPlot* plot) {
@@ -141,6 +144,10 @@
 private:
     const Key       fKey;
 
+    // The paint used when dropping the layer down into the owning canvas.
+    // Can be NULL.
+    const SkPaint*  fPaint;
+
     // fTexture is a ref on the atlasing texture for atlased layers and a
     // ref on a GrTexture for non-atlased textures.
     GrTexture*      fTexture;
@@ -184,7 +191,8 @@
     GrCachedLayer* findLayerOrCreate(uint32_t pictureID,
                                      int start, int stop, 
                                      const SkIPoint& offset,
-                                     const SkMatrix& ctm);
+                                     const SkMatrix& ctm,
+                                     const SkPaint* paint);
 
     // Inform the cache that layer's cached image is now required. 
     // Return true if the layer must be re-rendered. Return false if the
@@ -238,7 +246,8 @@
 
     void initAtlas();
     GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop, 
-                               const SkIPoint& offset, const SkMatrix& ctm);
+                               const SkIPoint& offset, const SkMatrix& ctm,
+                               const SkPaint* paint);
 
     void purgeAll();
 
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 0ec2b85..ebe3a56 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1842,6 +1842,34 @@
     result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
 }
 
+static void convert_layers_to_replacements(const SkTDArray<GrCachedLayer*>& layers,
+                                           GrReplacements* replacements) {
+    // TODO: just replace GrReplacements::ReplacementInfo with GrCachedLayer?
+    for (int i = 0; i < layers.count(); ++i) {
+        GrReplacements::ReplacementInfo* layerInfo = replacements->push();
+        layerInfo->fStart = layers[i]->start();
+        layerInfo->fStop = layers[i]->stop();
+        layerInfo->fPos = layers[i]->offset();;
+
+        SkBitmap bm;
+        wrap_texture(layers[i]->texture(),
+                     !layers[i]->isAtlased() ? layers[i]->rect().width()
+                                             : layers[i]->texture()->width(),
+                     !layers[i]->isAtlased() ? layers[i]->rect().height()
+                                             : layers[i]->texture()->height(),
+                     &bm);
+        layerInfo->fImage = SkImage::NewTexture(bm);
+
+        // TODO: copy this?
+        layerInfo->fPaint = layers[i]->paint();
+
+        layerInfo->fSrcRect = SkIRect::MakeXYWH(layers[i]->rect().fLeft,
+                                                layers[i]->rect().fTop,
+                                                layers[i]->rect().width(),
+                                                layers[i]->rect().height());
+    }
+}
+
 bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* picture,
                                            const SkMatrix* matrix, const SkPaint* paint) {
     // todo: should handle these natively
@@ -1875,8 +1903,6 @@
         return false;
     }
 
-    GrReplacements replacements;
-
     SkTDArray<GrCachedLayer*> atlased, nonAtlased;
     atlased.setReserve(gpuData->numSaveLayers());
 
@@ -1885,16 +1911,12 @@
         if (pullForward[i]) {
             const GrAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
 
-            GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture->uniqueID(), 
+            GrCachedLayer* layer = fContext->getLayerCache()->findLayerOrCreate(picture->uniqueID(),
                                                                                 info.fSaveLayerOpID, 
                                                                                 info.fRestoreOpID,
                                                                                 info.fOffset,
-                                                                                info.fOriginXform);
-
-            GrReplacements::ReplacementInfo* layerInfo = replacements.push();
-            layerInfo->fStart = info.fSaveLayerOpID;
-            layerInfo->fStop = info.fRestoreOpID;
-            layerInfo->fPos = info.fOffset;
+                                                                                info.fOriginXform,
+                                                                                info.fPaint);
 
             GrTextureDesc desc;
             desc.fFlags = kRenderTarget_GrTextureFlagBit;
@@ -1909,21 +1931,6 @@
                 continue;
             }
 
-            SkBitmap bm;
-            wrap_texture(layer->texture(),
-                         !layer->isAtlased() ? desc.fWidth : layer->texture()->width(),
-                         !layer->isAtlased() ? desc.fHeight : layer->texture()->height(),
-                         &bm);
-            layerInfo->fImage = SkImage::NewTexture(bm);
-
-            SkASSERT(info.fPaint);
-            layerInfo->fPaint = info.fPaint;
-
-            layerInfo->fSrcRect = SkIRect::MakeXYWH(layer->rect().fLeft,
-                                                    layer->rect().fTop,
-                                                    layer->rect().width(),
-                                                    layer->rect().height());
-
             if (needsRendering) {
                 if (layer->isAtlased()) {
                     *atlased.append() = layer;
@@ -1936,6 +1943,11 @@
 
     GrLayerHoister::DrawLayers(picture, atlased, nonAtlased);
 
+    GrReplacements replacements;
+
+    convert_layers_to_replacements(atlased, &replacements);
+    convert_layers_to_replacements(nonAtlased, &replacements);
+
     // Render the entire picture using new layers
     GrRecordReplaceDraw(*picture->fRecord, mainCanvas, picture->fBBH.get(), &replacements, NULL);
 
diff --git a/tests/GpuLayerCacheTest.cpp b/tests/GpuLayerCacheTest.cpp
index 66117e6..c9b88f5 100644
--- a/tests/GpuLayerCacheTest.cpp
+++ b/tests/GpuLayerCacheTest.cpp
@@ -34,7 +34,8 @@
         GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(), 
                                                         idOffset+i+1, idOffset+i+2, 
                                                         SkIPoint::Make(0, 0),
-                                                        SkMatrix::I());
+                                                        SkMatrix::I(),
+                                                        NULL);
         REPORTER_ASSERT(reporter, layer);
         GrCachedLayer* temp = cache->findLayer(picture.uniqueID(), idOffset+i+1, idOffset+i+2, 
                                                SkIPoint::Make(0, 0), SkMatrix::I());
@@ -47,6 +48,7 @@
         REPORTER_ASSERT(reporter, layer->stop() == idOffset + i + 2);
         REPORTER_ASSERT(reporter, layer->ctm() == SkMatrix::I());
         REPORTER_ASSERT(reporter, NULL == layer->texture());
+        REPORTER_ASSERT(reporter, NULL == layer->paint());
         REPORTER_ASSERT(reporter, !layer->isAtlased());
     }