Add clip to layer cache

This CL adds the clip region to the GPU layer hoisting image cache. It also switches back to the old caching behavior of using the entire CTM in the cache key rather then just the upper 2x2. This latter change is to focus more on hoisting rather then caching.

It also includes 2 smaller fixes:
a) layer's that have an image filter are no longer atlased (b.c. doing so complicates applying the image filter)

b) the result of clipping the layer's bounds to the current clip is used as the hoisted layer's size. This reduces the amount of pixels drawn to match a normal (non-hoisted) draw pass.

Review URL: https://codereview.chromium.org/640773004
diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp
index 7c2a8bd..154c6f3 100644
--- a/src/gpu/GrLayerCache.cpp
+++ b/src/gpu/GrLayerCache.cpp
@@ -129,30 +129,33 @@
 
 GrCachedLayer* GrLayerCache::createLayer(uint32_t pictureID, 
                                          int start, int stop, 
+                                         const SkIRect& bounds,
                                          const SkMatrix& ctm,
                                          const SkPaint* paint) {
     SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0);
 
-    GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, ctm, paint));
+    GrCachedLayer* layer = SkNEW_ARGS(GrCachedLayer, (pictureID, start, stop, bounds, ctm, paint));
     fLayerHash.add(layer);
     return layer;
 }
 
 GrCachedLayer* GrLayerCache::findLayer(uint32_t pictureID,
                                        int start, 
+                                       const SkIRect& bounds,
                                        const SkMatrix& ctm) {
     SkASSERT(pictureID != SK_InvalidGenID && start > 0);
-    return fLayerHash.find(GrCachedLayer::Key(pictureID, start, ctm));
+    return fLayerHash.find(GrCachedLayer::Key(pictureID, start, bounds, ctm));
 }
 
 GrCachedLayer* GrLayerCache::findLayerOrCreate(uint32_t pictureID,
                                                int start, int stop,
+                                               const SkIRect& bounds,
                                                const SkMatrix& ctm,
                                                const SkPaint* paint) {
     SkASSERT(pictureID != SK_InvalidGenID && start >= 0 && stop > 0);
-    GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(pictureID, start, ctm));
+    GrCachedLayer* layer = fLayerHash.find(GrCachedLayer::Key(pictureID, start, bounds, ctm));
     if (NULL == layer) {
-        layer = this->createLayer(pictureID, start, stop, ctm, paint);
+        layer = this->createLayer(pictureID, start, stop, bounds, ctm, paint);
     }
 
     return layer;
@@ -455,11 +458,7 @@
         }
 
         SkString fileName(dirName);
-        fileName.append("\\");
-        fileName.appendU32(layer->fKey.pictureID());
-        fileName.append("-");
-        fileName.appendU32(layer->fKey.start());
-        fileName.append(".png");
+        fileName.appendf("\\%d-%d.png", layer->fKey.pictureID(), layer->fKey.start());
 
         layer->texture()->surfacePriv().savePixels(fileName.c_str());
     }
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h
index d8c5ad9..aa0d325 100644
--- a/src/gpu/GrLayerCache.h
+++ b/src/gpu/GrLayerCache.h
@@ -51,36 +51,41 @@
 public:
     // For SkTDynamicHash
     struct Key {
-        // TODO: the key needs to include the clip
-        Key(uint32_t pictureID, int start, const SkMatrix& ctm) 
+        Key(uint32_t pictureID, int start, const SkIRect& bounds, const SkMatrix& ctm)
         : fPictureID(pictureID)
-        , fStart(start) {
-            fCTM[0] = ctm.getScaleX();
-            fCTM[1] = ctm.getSkewX();
-            fCTM[2] = ctm.getSkewY();
-            fCTM[3] = ctm.getScaleY();
+        , fStart(start)
+        , fBounds(bounds)
+        , 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) +      // picture ID
                                             sizeof(int) +           // start index
-                                            4 * sizeof(SkScalar));  // 2x2 from CTM
+                                            4 * sizeof(uint32_t) +  // bounds
+                                            9 * sizeof(SkScalar) + sizeof(uint32_t)); // matrix
         }
 
         bool operator==(const Key& other) const {
             return fPictureID == other.fPictureID &&
                    fStart == other.fStart &&
-                   0 == memcmp(fCTM, other.fCTM, sizeof(fCTM));
+                   fBounds == other.fBounds &&
+                   fCTM.cheapEqualTo(other.fCTM);
         }
 
         uint32_t pictureID() const { return fPictureID; }
         int start() const { return fStart; }
+        const SkIRect& bound() const { return fBounds; }
+        const SkMatrix& ctm() const { return fCTM; }
 
     private:
         // ID of the picture of which this layer is a part
         const uint32_t fPictureID;
         // The the index of the saveLayer command in the picture
         const int      fStart;
+        // The bounds of the layer. The TL corner is its offset.
+        const SkIRect  fBounds;
         // The 2x2 portion of the CTM applied to this layer in the picture
-        SkScalar       fCTM[4];
+        SkMatrix       fCTM;
     };
 
     static const Key& GetKey(const GrCachedLayer& layer) { return layer.fKey; }
@@ -90,8 +95,9 @@
 
     // GrCachedLayer proper
     GrCachedLayer(uint32_t pictureID, int start, int stop,
-                  const SkMatrix& ctm, const SkPaint* paint)
-        : fKey(pictureID, start, ctm)
+                  const SkIRect& bounds, const SkMatrix& ctm,
+                  const SkPaint* paint)
+        : fKey(pictureID, start, bounds, ctm)
         , fStop(stop)
         , fPaint(paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL)
         , fTexture(NULL)
@@ -109,6 +115,7 @@
 
     uint32_t pictureID() const { return fKey.pictureID(); }
     int start() const { return fKey.start(); }
+    const SkIRect& bound() const { return fKey.bound(); }
 
     int stop() const { return fStop; }
     void setTexture(GrTexture* texture, const GrIRect16& rect) {
@@ -193,9 +200,11 @@
     // elements by the GrContext
     void freeAll();
 
-    GrCachedLayer* findLayer(uint32_t pictureID, int start, const SkMatrix& ctm);
+    GrCachedLayer* findLayer(uint32_t pictureID, int start, 
+                             const SkIRect& bounds, const SkMatrix& ctm);
     GrCachedLayer* findLayerOrCreate(uint32_t pictureID,
                                      int start, int stop, 
+                                     const SkIRect& bounds,
                                      const SkMatrix& ctm,
                                      const SkPaint* paint);
 
@@ -265,7 +274,8 @@
 
     void initAtlas();
     GrCachedLayer* createLayer(uint32_t pictureID, int start, int stop, 
-                               const SkMatrix& ctm, const SkPaint* paint);
+                               const SkIRect& bounds, const SkMatrix& ctm, 
+                               const SkPaint* paint);
 
     void purgeAll();
 
diff --git a/src/gpu/GrLayerHoister.cpp b/src/gpu/GrLayerHoister.cpp
index e9e3a3f..929c122 100644
--- a/src/gpu/GrLayerHoister.cpp
+++ b/src/gpu/GrLayerHoister.cpp
@@ -7,10 +7,11 @@
 
 #include "GrLayerCache.h"
 #include "GrLayerHoister.h"
-#include "SkCanvas.h"
-#include "SkRecordDraw.h"
 #include "GrRecordReplaceDraw.h"
+
+#include "SkCanvas.h"
 #include "SkGrPixelRef.h"
+#include "SkRecordDraw.h"
 #include "SkSurface.h"
 
 // Create the layer information for the hoisted layer and secure the
@@ -18,6 +19,7 @@
 static void prepare_for_hoisting(GrLayerCache* layerCache, 
                                  const SkPicture* topLevelPicture,
                                  const GrAccelData::SaveLayerInfo& info,
+                                 const SkIRect& layerRect,
                                  SkTDArray<GrHoistedLayer>* atlased,
                                  SkTDArray<GrHoistedLayer>* nonAtlased,
                                  SkTDArray<GrHoistedLayer>* recycled) {
@@ -26,17 +28,22 @@
     GrCachedLayer* layer = layerCache->findLayerOrCreate(pict->uniqueID(),
                                                          info.fSaveLayerOpID,
                                                          info.fRestoreOpID,
+                                                         layerRect,
                                                          info.fOriginXform,
                                                          info.fPaint);
 
     GrTextureDesc desc;
     desc.fFlags = kRenderTarget_GrTextureFlagBit;
-    desc.fWidth = info.fSize.fWidth;
-    desc.fHeight = info.fSize.fHeight;
+    desc.fWidth = layerRect.width();
+    desc.fHeight = layerRect.height();
     desc.fConfig = kSkia8888_GrPixelConfig;
     // TODO: need to deal with sample count
 
-    bool needsRendering = layerCache->lock(layer, desc, info.fHasNestedLayers || info.fIsNested);
+
+    bool disallowAtlasing = info.fHasNestedLayers || info.fIsNested ||
+                            (layer->paint() && layer->paint()->getImageFilter());
+
+    bool needsRendering = layerCache->lock(layer, desc, disallowAtlasing);
     if (NULL == layer->texture()) {
         // GPU resources could not be secured for the hoisting of this layer
         return;
@@ -57,7 +64,7 @@
     layerCache->addUse(layer);
     hl->fLayer = layer;
     hl->fPicture = pict;
-    hl->fOffset = info.fOffset;
+    hl->fOffset = SkIPoint::Make(layerRect.fLeft, layerRect.fTop);
     hl->fCTM = info.fOriginXform;
 }
 
@@ -68,7 +75,6 @@
                                        SkTDArray<GrHoistedLayer>* atlased,
                                        SkTDArray<GrHoistedLayer>* nonAtlased,
                                        SkTDArray<GrHoistedLayer>* recycled) {
-
     GrLayerCache* layerCache = context->getLayerCache();
 
     layerCache->processDeletedPictures();
@@ -102,15 +108,15 @@
 
         const GrAccelData::SaveLayerInfo& info = topLevelGPUData->saveLayerInfo(i);
 
-        SkRect layerRect = SkRect::MakeXYWH(SkIntToScalar(info.fOffset.fX),
-                                            SkIntToScalar(info.fOffset.fY),
-                                            SkIntToScalar(info.fSize.fWidth),
-                                            SkIntToScalar(info.fSize.fHeight));
-
-        if (!SkRect::Intersects(query, layerRect)) {
+        SkRect layerRect = SkRect::Make(info.fBounds);
+        if (!layerRect.intersect(query)) {
             continue;
         }
 
+
+        SkIRect ir;
+        layerRect.roundOut(&ir);
+
         // TODO: ignore perspective projected layers here!
         // TODO: once this code is more stable unsuitable layers can
         // just be omitted during the optimization stage
@@ -118,7 +124,7 @@
             continue;
         }
 
-        prepare_for_hoisting(layerCache, topLevelPicture, info, atlased, nonAtlased, recycled);
+        prepare_for_hoisting(layerCache, topLevelPicture, info, ir, atlased, nonAtlased, recycled);
         anyHoisted = true;
     }
 
diff --git a/src/gpu/GrPictureUtils.cpp b/src/gpu/GrPictureUtils.cpp
index da238ce..a215a0e 100644
--- a/src/gpu/GrPictureUtils.cpp
+++ b/src/gpu/GrPictureUtils.cpp
@@ -108,15 +108,14 @@
         for (int i = 0; i < childData->numSaveLayers(); ++i) {
             const GrAccelData::SaveLayerInfo& src = childData->saveLayerInfo(i);
 
-            this->updateStackForSaveLayer();
-
-            // TODO: need to store an SkRect in GrAccelData::SaveLayerInfo?
-            SkRect srcRect = SkRect::MakeXYWH(SkIntToScalar(src.fOffset.fX),
-                                              SkIntToScalar(src.fOffset.fY),
-                                              SkIntToScalar(src.fSize.width()),
-                                              SkIntToScalar(src.fSize.height()));
+            SkRect srcRect = SkRect::Make(src.fBounds);
             SkIRect newClip(fCurrentClipBounds);
-            newClip.intersect(this->adjustAndMap(srcRect, dp.paint));
+
+            if (!newClip.intersect(this->adjustAndMap(srcRect, dp.paint))) {
+                continue;
+            }
+
+            this->updateStackForSaveLayer();
 
             GrAccelData::SaveLayerInfo& dst = fAccelData->addSaveLayerInfo();
 
@@ -124,8 +123,7 @@
             // it belongs to a sub-picture.
             dst.fPicture = src.fPicture ? src.fPicture : static_cast<const SkPicture*>(dp.picture);
             dst.fPicture->ref();
-            dst.fSize = SkISize::Make(newClip.width(), newClip.height());
-            dst.fOffset = SkIPoint::Make(newClip.fLeft, newClip.fTop);
+            dst.fBounds = newClip;
             dst.fOriginXform = src.fOriginXform;
             dst.fOriginXform.postConcat(*fCTM);
             if (src.fPaint) {
@@ -181,8 +179,7 @@
         GrAccelData::SaveLayerInfo& slInfo = fAccelData->addSaveLayerInfo();
 
         SkASSERT(NULL == slInfo.fPicture);  // This layer is in the top-most picture
-        slInfo.fSize = SkISize::Make(si.fBounds.width(), si.fBounds.height());
-        slInfo.fOffset = SkIPoint::Make(si.fBounds.fLeft, si.fBounds.fTop);
+        slInfo.fBounds = si.fBounds;
         slInfo.fOriginXform = *fCTM;
         if (si.fPaint) {
             slInfo.fPaint = SkNEW_ARGS(SkPaint, (*si.fPaint));
diff --git a/src/gpu/GrPictureUtils.h b/src/gpu/GrPictureUtils.h
index 07c32de..7bcf632 100644
--- a/src/gpu/GrPictureUtils.h
+++ b/src/gpu/GrPictureUtils.h
@@ -26,14 +26,11 @@
         // this pointer is NULL. If it is a nested picture then the pointer
         // is non-NULL and owns a ref on the picture.
         const SkPicture* fPicture;
-        // The size of the saveLayer
-        SkISize fSize;
+        // The device space bounds of this layer.
+        SkIRect fBounds;
         // 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.
-        SkIPoint fOffset;
         // The paint to use on restore. Can be NULL since it is optional.
         const SkPaint* fPaint;
         // The ID of this saveLayer in the picture. 0 is an invalid ID.
diff --git a/tests/GpuLayerCacheTest.cpp b/tests/GpuLayerCacheTest.cpp
index f7b2d6e..62f6ec7 100644
--- a/tests/GpuLayerCacheTest.cpp
+++ b/tests/GpuLayerCacheTest.cpp
@@ -36,11 +36,12 @@
     for (int i = 0; i < numToAdd; ++i) {
         GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(), 
                                                         idOffset+i+1, idOffset+i+2, 
+                                                        SkIRect::MakeEmpty(),
                                                         SkMatrix::I(),
                                                         NULL);
         REPORTER_ASSERT(reporter, layer);
-        GrCachedLayer* temp = cache->findLayer(picture.uniqueID(), idOffset+i+1,
-                                               SkMatrix::I());
+        GrCachedLayer* temp = cache->findLayer(picture.uniqueID(), idOffset + i + 1,
+                                               SkIRect::MakeEmpty(), SkMatrix::I());
         REPORTER_ASSERT(reporter, temp == layer);
 
         REPORTER_ASSERT(reporter, TestingAccess::NumLayers(cache) == idOffset + i + 1);
@@ -108,7 +109,8 @@
         create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
 
         for (int i = 0; i < kInitialNumLayers; ++i) {
-            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, SkMatrix::I());
+            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, 
+                                                   SkIRect::MakeEmpty(), SkMatrix::I());
             REPORTER_ASSERT(reporter, layer);
 
             lock_layer(reporter, &cache, layer);
@@ -125,13 +127,15 @@
 
         // Unlock the textures
         for (int i = 0; i < kInitialNumLayers; ++i) {
-            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, SkMatrix::I());
+            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, 
+                                                   SkIRect::MakeEmpty(), SkMatrix::I());
             REPORTER_ASSERT(reporter, layer);
             cache.removeUse(layer);
         }
 
         for (int i = 0; i < kInitialNumLayers; ++i) {
-            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, SkMatrix::I());
+            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, 
+                                                   SkIRect::MakeEmpty(), SkMatrix::I());
             REPORTER_ASSERT(reporter, layer);
 
             // All the layers should be unlocked
@@ -153,7 +157,8 @@
             // will force out the first atlased layer
             create_layers(reporter, &cache, *picture, 1, kInitialNumLayers);
             GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), 
-                                                   kInitialNumLayers+1, SkMatrix::I());
+                                                   kInitialNumLayers+1, 
+                                                   SkIRect::MakeEmpty(), SkMatrix::I());
             REPORTER_ASSERT(reporter, layer);
 
             lock_layer(reporter, &cache, layer);
@@ -161,7 +166,8 @@
         }
 
         for (int i = 0; i < kInitialNumLayers+1; ++i) {
-            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, SkMatrix::I());
+            GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i + 1,
+                                                   SkIRect::MakeEmpty(), SkMatrix::I());
             // 3 old layers plus the new one should be in the atlas.
             if (1 == i || 2 == i || 3 == i || 5 == i) {
                 REPORTER_ASSERT(reporter, layer);
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index b539d06..d10d2b2 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -981,69 +981,69 @@
             const GrAccelData::SaveLayerInfo& info7 = gpuData->saveLayerInfo(6);
 
             REPORTER_ASSERT(reporter, NULL == info0.fPicture);
-            REPORTER_ASSERT(reporter, kWidth == info0.fSize.fWidth &&
-                                      kHeight == info0.fSize.fHeight);
+            REPORTER_ASSERT(reporter, kWidth == info0.fBounds.width() &&
+                                      kHeight == info0.fBounds.height());
             REPORTER_ASSERT(reporter, info0.fOriginXform.isIdentity());
-            REPORTER_ASSERT(reporter, 0 == info0.fOffset.fX && 0 == info0.fOffset.fY);
+            REPORTER_ASSERT(reporter, 0 == info0.fBounds.fLeft && 0 == info0.fBounds.fTop);
             REPORTER_ASSERT(reporter, NULL == info0.fPaint);
             REPORTER_ASSERT(reporter, !info0.fIsNested && !info0.fHasNestedLayers);
 
             REPORTER_ASSERT(reporter, NULL == info1.fPicture);
-            REPORTER_ASSERT(reporter, kWidth == info1.fSize.fWidth &&
-                                      kHeight == info1.fSize.fHeight);
+            REPORTER_ASSERT(reporter, kWidth == info1.fBounds.width() &&
+                                      kHeight == info1.fBounds.height());
             REPORTER_ASSERT(reporter, info1.fOriginXform.isIdentity());
-            REPORTER_ASSERT(reporter, 0 == info1.fOffset.fX && 0 == info1.fOffset.fY);
+            REPORTER_ASSERT(reporter, 0 == info1.fBounds.fLeft && 0 == info1.fBounds.fTop);
             REPORTER_ASSERT(reporter, NULL == info1.fPaint);
             REPORTER_ASSERT(reporter, !info1.fIsNested &&
                                       info1.fHasNestedLayers); // has a nested SL
 
             REPORTER_ASSERT(reporter, NULL == info2.fPicture);
-            REPORTER_ASSERT(reporter, kWidth / 2 == info2.fSize.fWidth &&
-                                      kHeight/2 == info2.fSize.fHeight); // bound reduces size
+            REPORTER_ASSERT(reporter, kWidth / 2 == info2.fBounds.width() &&
+                                      kHeight / 2 == info2.fBounds.height()); // bound reduces size
             REPORTER_ASSERT(reporter, !info2.fOriginXform.isIdentity());
-            REPORTER_ASSERT(reporter, kWidth/2 == info2.fOffset.fX &&   // translated
-                                      kHeight/2 == info2.fOffset.fY);
+            REPORTER_ASSERT(reporter, kWidth / 2 == info2.fBounds.fLeft &&   // translated
+                                      kHeight / 2 == info2.fBounds.fTop);
             REPORTER_ASSERT(reporter, NULL == info1.fPaint);
             REPORTER_ASSERT(reporter, info2.fIsNested && !info2.fHasNestedLayers); // is nested
 
             REPORTER_ASSERT(reporter, NULL == info3.fPicture);
-            REPORTER_ASSERT(reporter, kWidth == info3.fSize.fWidth &&
-                                      kHeight == info3.fSize.fHeight);
+            REPORTER_ASSERT(reporter, kWidth == info3.fBounds.width() &&
+                                      kHeight == info3.fBounds.height());
             REPORTER_ASSERT(reporter, info3.fOriginXform.isIdentity());
-            REPORTER_ASSERT(reporter, 0 == info3.fOffset.fX && 0 == info3.fOffset.fY);
+            REPORTER_ASSERT(reporter, 0 == info3.fBounds.fLeft && 0 == info3.fBounds.fTop);
             REPORTER_ASSERT(reporter, info3.fPaint);
             REPORTER_ASSERT(reporter, !info3.fIsNested && !info3.fHasNestedLayers);
 
             REPORTER_ASSERT(reporter, NULL == info4.fPicture);
-            REPORTER_ASSERT(reporter, kWidth == info4.fSize.fWidth &&
-                                      kHeight == info4.fSize.fHeight);
-            REPORTER_ASSERT(reporter, 0 == info4.fOffset.fX && 0 == info4.fOffset.fY);
+            REPORTER_ASSERT(reporter, kWidth == info4.fBounds.width() &&
+                                      kHeight == info4.fBounds.height());
+            REPORTER_ASSERT(reporter, 0 == info4.fBounds.fLeft && 0 == info4.fBounds.fTop);
             REPORTER_ASSERT(reporter, info4.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, info4.fPaint);
             REPORTER_ASSERT(reporter, !info4.fIsNested &&
                                       info4.fHasNestedLayers); // has a nested SL
 
             REPORTER_ASSERT(reporter, child == info5.fPicture); // in a child picture
-            REPORTER_ASSERT(reporter, kWidth == info5.fSize.fWidth &&
-                                      kHeight == info5.fSize.fHeight);
-            REPORTER_ASSERT(reporter, 0 == info5.fOffset.fX && 0 == info5.fOffset.fY);
+            REPORTER_ASSERT(reporter, kWidth == info5.fBounds.width() &&
+                                      kHeight == info5.fBounds.height());
+            REPORTER_ASSERT(reporter, 0 == info5.fBounds.fLeft && 0 == info5.fBounds.fTop);
             REPORTER_ASSERT(reporter, info5.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, NULL == info5.fPaint);
             REPORTER_ASSERT(reporter, info5.fIsNested && !info5.fHasNestedLayers); // is nested
 
             REPORTER_ASSERT(reporter, NULL == info6.fPicture);
-            REPORTER_ASSERT(reporter, kWidth == info6.fSize.fWidth &&
-                                      kHeight == info6.fSize.fHeight);
-            REPORTER_ASSERT(reporter, 0 == info6.fOffset.fX && 0 == info6.fOffset.fY);
+            REPORTER_ASSERT(reporter, kWidth == info6.fBounds.width() &&
+                                      kHeight == info6.fBounds.height());
+            REPORTER_ASSERT(reporter, 0 == info6.fBounds.fLeft && 0 == info6.fBounds.fTop);
             REPORTER_ASSERT(reporter, info6.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, info6.fPaint);
             REPORTER_ASSERT(reporter, !info6.fIsNested &&
                                       info6.fHasNestedLayers); // has a nested SL
 
             REPORTER_ASSERT(reporter, child == info7.fPicture); // in a child picture
-            REPORTER_ASSERT(reporter, kWidth == info7.fSize.fWidth &&
-                                      kHeight == info7.fSize.fHeight);
-            REPORTER_ASSERT(reporter, 0 == info7.fOffset.fX && 0 == info7.fOffset.fY);
+            REPORTER_ASSERT(reporter, kWidth == info7.fBounds.width() &&
+                                      kHeight == info7.fBounds.height());
+            REPORTER_ASSERT(reporter, 0 == info7.fBounds.fLeft && 0 == info7.fBounds.fTop);
             REPORTER_ASSERT(reporter, info7.fOriginXform.isIdentity());
             REPORTER_ASSERT(reporter, NULL == info7.fPaint);
             REPORTER_ASSERT(reporter, info7.fIsNested && !info7.fHasNestedLayers); // is nested