Try out scalar picture sizes

This paves the way for removing the 'fTile' parameter from SkPictureShader (although that should be a different CL). If we like this we could also move to providing an entire cull SkRect.

R=reed@google.com, mtklein@google.com, fmalita@google.com, fmalita@chromium.org

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/513983002
diff --git a/src/core/SkBBoxRecord.cpp b/src/core/SkBBoxRecord.cpp
index 5837a88..5fe42f9 100644
--- a/src/core/SkBBoxRecord.cpp
+++ b/src/core/SkBBoxRecord.cpp
@@ -313,8 +313,7 @@
 
 void SkBBoxRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                  const SkPaint* paint) {
-    SkRect bounds = SkRect::MakeWH(SkIntToScalar(picture->width()),
-                                   SkIntToScalar(picture->height()));
+    SkRect bounds = picture->cullRect();
     // todo: wonder if we should allow passing an optional matrix to transformBounds so we don't
     // end up transforming the rect twice.
     if (matrix) {
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 16459b0..2b08a94 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -2445,7 +2445,7 @@
         }
     }
 
-    SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->width(), picture->height());
+    SkAutoCanvasMatrixPaint acmp(this, matrix, paint, picture->cullRect());
 
     picture->draw(this);
 }
@@ -2549,16 +2549,16 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 SkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatrix* matrix,
-                                                 const SkPaint* paint, int width, int height)
+                                                 const SkPaint* paint, const SkRect& bounds)
     : fCanvas(canvas)
     , fSaveCount(canvas->getSaveCount())
 {
     if (NULL != paint) {
-        SkRect bounds = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
+        SkRect newBounds = bounds;
         if (matrix) {
-            matrix->mapRect(&bounds);
+            matrix->mapRect(&newBounds);
         }
-        canvas->saveLayer(&bounds, paint);
+        canvas->saveLayer(&newBounds, paint);
     } else if (NULL != matrix) {
         canvas->save();
     }
diff --git a/src/core/SkCanvasPriv.h b/src/core/SkCanvasPriv.h
index 9f66baa..dfae154 100644
--- a/src/core/SkCanvasPriv.h
+++ b/src/core/SkCanvasPriv.h
@@ -12,7 +12,7 @@
 
 class SkAutoCanvasMatrixPaint : SkNoncopyable {
 public:
-    SkAutoCanvasMatrixPaint(SkCanvas*, const SkMatrix*, const SkPaint*, int width, int height);
+    SkAutoCanvasMatrixPaint(SkCanvas*, const SkMatrix*, const SkPaint*, const SkRect& bounds);
     ~SkAutoCanvasMatrixPaint();
 
 private:
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index e958f96..92551d3 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -262,11 +262,11 @@
 #endif
 
 // fRecord OK
-SkPicture::SkPicture(int width, int height,
+SkPicture::SkPicture(SkScalar width, SkScalar height,
                      const SkPictureRecord& record,
                      bool deepCopyOps)
-    : fWidth(width)
-    , fHeight(height)
+    : fCullWidth(width)
+    , fCullHeight(height)
     , fAnalysis() {
     this->needsNewGenID();
 
@@ -277,10 +277,11 @@
 
 // Create an SkPictureData-backed SkPicture from an SkRecord.
 // This for compatibility with serialization code only.  This is not cheap.
-static SkPicture* backport(const SkRecord& src, int width, int height) {
+static SkPicture* backport(const SkRecord& src, const SkRect& cullRect) {
     SkPictureRecorder recorder;
     SkRecordDraw(src,
-                 recorder.DEPRECATED_beginRecording(width, height), NULL/*bbh*/, NULL/*callback*/);
+                 recorder.DEPRECATED_beginRecording(cullRect.width(), cullRect.height()), 
+                 NULL/*bbh*/, NULL/*callback*/);
     return recorder.endRecording();
 }
 
@@ -351,7 +352,7 @@
     // If the query contains the whole picture, don't bother with the BBH.
     SkRect clipBounds = { 0, 0, 0, 0 };
     (void)canvas->getClipBounds(&clipBounds);
-    const bool useBBH = !clipBounds.contains(SkRect::MakeWH(this->width(), this->height()));
+    const bool useBBH = !clipBounds.contains(this->cullRect());
 
     if (NULL != fData.get()) {
         SkPicturePlayback playback(this);
@@ -392,7 +393,32 @@
     // Check magic bytes.
     SkPictInfo info;
     SkASSERT(sizeof(kMagic) == sizeof(info.fMagic));
-    if (!stream->read(&info, sizeof(info)) || !IsValidPictInfo(info)) {
+
+    if (!stream->read(&info.fMagic, sizeof(kMagic))) {
+        return false;
+    }
+
+    info.fVersion = stream->readU32();
+
+#ifndef V35_COMPATIBILITY_CODE
+    if (info.fVersion < 35) {
+        info.fCullRect.fLeft = 0;
+        info.fCullRect.fTop = 0;
+        info.fCullRect.fRight = SkIntToScalar(stream->readU32());
+        info.fCullRect.fBottom = SkIntToScalar(stream->readU32());
+    } else {
+#endif
+        info.fCullRect.fLeft = stream->readScalar();
+        info.fCullRect.fTop = stream->readScalar();
+        info.fCullRect.fRight = stream->readScalar();
+        info.fCullRect.fBottom = stream->readScalar();
+#ifndef V35_COMPATIBILITY_CODE
+    }
+#endif
+
+    info.fFlags = stream->readU32();
+
+    if (!IsValidPictInfo(info)) {
         return false;
     }
 
@@ -403,11 +429,33 @@
 }
 
 // fRecord OK
-bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo) {
+bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer* buffer, SkPictInfo* pInfo) {
     // Check magic bytes.
     SkPictInfo info;
     SkASSERT(sizeof(kMagic) == sizeof(info.fMagic));
-    if (!buffer.readByteArray(&info, sizeof(info)) || !IsValidPictInfo(info)) {
+
+    if (!buffer->readByteArray(&info.fMagic, sizeof(kMagic))) {
+        return false;
+    }
+
+    info.fVersion = buffer->readUInt();
+
+#ifndef V35_COMPATIBILITY_CODE
+    if (info.fVersion < 35) {
+        info.fCullRect.fLeft = 0;
+        info.fCullRect.fTop = 0;
+        info.fCullRect.fRight = SkIntToScalar(buffer->readUInt());
+        info.fCullRect.fBottom = SkIntToScalar(buffer->readUInt());
+    } else {
+#endif
+        buffer->readRect(&info.fCullRect);
+#ifndef V35_COMPATIBILITY_CODE
+    }
+#endif
+
+    info.fFlags = buffer->readUInt();
+
+    if (!IsValidPictInfo(info)) {
         return false;
     }
 
@@ -418,19 +466,20 @@
 }
 
 // fRecord OK
-SkPicture::SkPicture(SkPictureData* data, int width, int height)
+SkPicture::SkPicture(SkPictureData* data, SkScalar width, SkScalar height)
     : fData(data)
-    , fWidth(width)
-    , fHeight(height)
+    , fCullWidth(width)
+    , fCullHeight(height)
     , fAnalysis() {
     this->needsNewGenID();
 }
 
 SkPicture* SkPicture::Forwardport(const SkPicture& src) {
     SkAutoTDelete<SkRecord> record(SkNEW(SkRecord));
-    SkRecorder canvas(record.get(), src.width(), src.height());
+    SkRecorder canvas(record.get(), src.cullRect().width(), src.cullRect().height());
     src.draw(&canvas);
-    return SkNEW_ARGS(SkPicture, (src.width(), src.height(), record.detach(), NULL/*bbh*/));
+    return SkNEW_ARGS(SkPicture, (src.cullRect().width(), src.cullRect().height(), 
+                                  record.detach(), NULL/*bbh*/));
 }
 
 // fRecord OK
@@ -447,7 +496,7 @@
         if (NULL == data) {
             return NULL;
         }
-        const SkPicture src(data, info.fWidth, info.fHeight);
+        const SkPicture src(data, info.fCullRect.width(), info.fCullRect.height());
         return Forwardport(src);
     }
 
@@ -458,7 +507,7 @@
 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) {
     SkPictInfo info;
 
-    if (!InternalOnly_BufferIsSKP(buffer, &info)) {
+    if (!InternalOnly_BufferIsSKP(&buffer, &info)) {
         return NULL;
     }
 
@@ -468,7 +517,7 @@
         if (NULL == data) {
             return NULL;
         }
-        const SkPicture src(data, info.fWidth, info.fHeight);
+        const SkPicture src(data, info.fCullRect.width(), info.fCullRect.height());
         return Forwardport(src);
     }
 
@@ -484,8 +533,7 @@
 
     // Set picture info after magic bytes in the header
     info->fVersion = CURRENT_PICTURE_VERSION;
-    info->fWidth = fWidth;
-    info->fHeight = fHeight;
+    info->fCullRect = this->cullRect();
     info->fFlags = SkPictInfo::kCrossProcess_Flag;
     // TODO: remove this flag, since we're always float (now)
     info->fFlags |= SkPictInfo::kScalarIsFloat_Flag;
@@ -502,13 +550,14 @@
     // If we're a new-format picture, backport to old format for serialization.
     SkAutoTDelete<SkPicture> oldFormat;
     if (NULL == data && NULL != fRecord.get()) {
-        oldFormat.reset(backport(*fRecord, fWidth, fHeight));
+        oldFormat.reset(backport(*fRecord, this->cullRect()));
         data = oldFormat->fData.get();
         SkASSERT(NULL != data);
     }
 
     SkPictInfo info;
     this->createHeader(&info);
+    SkASSERT(sizeof(SkPictInfo) == 32);
     stream->write(&info, sizeof(info));
 
     if (NULL != data) {
@@ -526,14 +575,17 @@
     // If we're a new-format picture, backport to old format for serialization.
     SkAutoTDelete<SkPicture> oldFormat;
     if (NULL == data && NULL != fRecord.get()) {
-        oldFormat.reset(backport(*fRecord, fWidth, fHeight));
+        oldFormat.reset(backport(*fRecord, this->cullRect()));
         data = oldFormat->fData.get();
         SkASSERT(NULL != data);
     }
 
     SkPictInfo info;
     this->createHeader(&info);
-    buffer.writeByteArray(&info, sizeof(info));
+    buffer.writeByteArray(&info.fMagic, sizeof(info.fMagic));
+    buffer.writeUInt(info.fVersion);
+    buffer.writeRect(info.fCullRect);
+    buffer.writeUInt(info.fFlags);
 
     if (NULL != data) {
         buffer.writeBool(true);
@@ -605,9 +657,9 @@
 }
 
 // fRecord OK
-SkPicture::SkPicture(int width, int height, SkRecord* record, SkBBoxHierarchy* bbh)
-    : fWidth(width)
-    , fHeight(height)
+SkPicture::SkPicture(SkScalar width, SkScalar height, SkRecord* record, SkBBoxHierarchy* bbh)
+    : fCullWidth(width)
+    , fCullHeight(height)
     , fRecord(record)
     , fBBH(SkSafeRef(bbh))
     , fAnalysis(*record) {
diff --git a/src/core/SkPictureData.h b/src/core/SkPictureData.h
index a5f1ae0..019bfb2 100644
--- a/src/core/SkPictureData.h
+++ b/src/core/SkPictureData.h
@@ -37,8 +37,7 @@
 
     char        fMagic[8];
     uint32_t    fVersion;
-    uint32_t    fWidth;
-    uint32_t    fHeight;
+    SkRect      fCullRect;
     uint32_t    fFlags;
 };
 
diff --git a/src/core/SkPictureRecorder.cpp b/src/core/SkPictureRecorder.cpp
index d90f885..fadb937 100644
--- a/src/core/SkPictureRecorder.cpp
+++ b/src/core/SkPictureRecorder.cpp
@@ -17,7 +17,7 @@
 
 SkPictureRecorder::~SkPictureRecorder() {}
 
-SkCanvas* SkPictureRecorder::beginRecording(int width, int height,
+SkCanvas* SkPictureRecorder::beginRecording(SkScalar width, SkScalar height,
                                             SkBBHFactory* bbhFactory /* = NULL */,
                                             uint32_t recordFlags /* = 0 */) {
 #ifdef SK_PICTURE_USE_SK_RECORD
@@ -27,11 +27,11 @@
 #endif
 }
 
-SkCanvas* SkPictureRecorder::DEPRECATED_beginRecording(int width, int height,
+SkCanvas* SkPictureRecorder::DEPRECATED_beginRecording(SkScalar width, SkScalar height,
                                                        SkBBHFactory* bbhFactory /* = NULL */,
                                                        uint32_t recordFlags /* = 0 */) {
-    fWidth = width;
-    fHeight = height;
+    fCullWidth = width;
+    fCullHeight = height;
 
     const SkISize size = SkISize::Make(width, height);
 
@@ -49,10 +49,10 @@
     return this->getRecordingCanvas();
 }
 
-SkCanvas* SkPictureRecorder::EXPERIMENTAL_beginRecording(int width, int height,
+SkCanvas* SkPictureRecorder::EXPERIMENTAL_beginRecording(SkScalar width, SkScalar height,
                                                          SkBBHFactory* bbhFactory /* = NULL */) {
-    fWidth = width;
-    fHeight = height;
+    fCullWidth = width;
+    fCullHeight = height;
 
     if (NULL != bbhFactory) {
         fBBH.reset((*bbhFactory)(width, height));
@@ -75,13 +75,15 @@
     SkPicture* picture = NULL;
 
     if (NULL != fRecord.get()) {
-        picture = SkNEW_ARGS(SkPicture, (fWidth, fHeight, fRecord.detach(), fBBH.get()));
+        picture = SkNEW_ARGS(SkPicture, (fCullWidth, fCullHeight, 
+                                         fRecord.detach(), fBBH.get()));
     }
 
     if (NULL != fPictureRecord.get()) {
         fPictureRecord->endRecording();
         const bool deepCopyOps = false;
-        picture = SkNEW_ARGS(SkPicture, (fWidth, fHeight, *fPictureRecord.get(), deepCopyOps));
+        picture = SkNEW_ARGS(SkPicture, (fCullWidth, fCullHeight, 
+                                         *fPictureRecord.get(), deepCopyOps));
     }
 
     return picture;
@@ -104,7 +106,8 @@
 
     if (NULL != fPictureRecord.get()) {
         const bool deepCopyOps = true;
-        SkPicture picture(fWidth, fHeight, *fPictureRecord.get(), deepCopyOps);
+        SkPicture picture(fCullWidth, fCullHeight, 
+                          *fPictureRecord.get(), deepCopyOps);
         picture.draw(canvas);
     }
 }
diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
index 3e0eb65..73ab170 100644
--- a/src/core/SkPictureShader.cpp
+++ b/src/core/SkPictureShader.cpp
@@ -22,10 +22,9 @@
                                  const SkMatrix* localMatrix, const SkRect* tile)
     : INHERITED(localMatrix)
     , fPicture(SkRef(picture))
+    , fTile(NULL != tile ? *tile : picture->cullRect())
     , fTmx(tmx)
     , fTmy(tmy) {
-    fTile = tile ? *tile : SkRect::MakeWH(SkIntToScalar(picture->width()),
-                                          SkIntToScalar(picture->height()));
 }
 
 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
@@ -43,8 +42,7 @@
 
 SkPictureShader* SkPictureShader::Create(const SkPicture* picture, TileMode tmx, TileMode tmy,
                                          const SkMatrix* localMatrix, const SkRect* tile) {
-    if (!picture || 0 == picture->width() || 0 == picture->height()
-        || (NULL != tile && tile->isEmpty())) {
+    if (!picture || picture->cullRect().isEmpty() || (NULL != tile && tile->isEmpty())) {
         return NULL;
     }
     return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy, localMatrix, tile));
@@ -70,7 +68,7 @@
 }
 
 SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatrix* localM) const {
-    SkASSERT(fPicture && fPicture->width() > 0 && fPicture->height() > 0);
+    SkASSERT(fPicture && !fPicture->cullRect().isEmpty());
 
     SkMatrix m;
     m.setConcat(matrix, this->getLocalMatrix());
@@ -201,9 +199,11 @@
         "clamp", "repeat", "mirror"
     };
 
-    str->appendf("PictureShader: [%d:%d] ",
-                 fPicture ? fPicture->width() : 0,
-                 fPicture ? fPicture->height() : 0);
+    str->appendf("PictureShader: [%f:%f:%f:%f] ",
+                 fPicture ? fPicture->cullRect().fLeft : 0,
+                 fPicture ? fPicture->cullRect().fTop : 0,
+                 fPicture ? fPicture->cullRect().fRight : 0,
+                 fPicture ? fPicture->cullRect().fBottom : 0);
 
     str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
 
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 7985e2b..0117ade 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -321,7 +321,7 @@
     }
 
     Bounds bounds(const DrawPicture& op) const {
-        SkRect dst = SkRect::MakeWH(op.picture->width(), op.picture->height());
+        SkRect dst = op.picture->cullRect();
         if (op.matrix) {
             op.matrix->mapRect(&dst);
         }
diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp
index c28175a..3ca0c09 100644
--- a/src/effects/SkPictureImageFilter.cpp
+++ b/src/effects/SkPictureImageFilter.cpp
@@ -13,19 +13,16 @@
 #include "SkValidationUtils.h"
 
 SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, uint32_t uniqueID)
-  : INHERITED(0, 0, NULL, uniqueID),
-    fPicture(picture),
-    fCropRect(SkRect::MakeWH(picture ? SkIntToScalar(picture->width()) : 0,
-                             picture ? SkIntToScalar(picture->height()) : 0)) {
-    SkSafeRef(fPicture);
+    : INHERITED(0, 0, NULL, uniqueID)
+    , fPicture(SkSafeRef(picture))
+    , fCropRect(NULL != picture ? picture->cullRect() : SkRect::MakeEmpty()) {
 }
 
 SkPictureImageFilter::SkPictureImageFilter(const SkPicture* picture, const SkRect& cropRect,
                                            uint32_t uniqueID)
-  : INHERITED(0, 0, NULL, uniqueID),
-    fPicture(picture),
-    fCropRect(cropRect) {
-    SkSafeRef(fPicture);
+    : INHERITED(0, 0, NULL, uniqueID)
+    , fPicture(SkSafeRef(picture))
+    , fCropRect(cropRect) {
 }
 
 SkPictureImageFilter::~SkPictureImageFilter() {
diff --git a/src/gpu/GrPictureUtils.cpp b/src/gpu/GrPictureUtils.cpp
index 521160a..4b0f77f 100644
--- a/src/gpu/GrPictureUtils.cpp
+++ b/src/gpu/GrPictureUtils.cpp
@@ -23,10 +23,11 @@
     CollectLayers(const SkPicture* pict, GrAccelData* accelData)
         : fPictureID(pict->uniqueID())
         , fCTM(&SkMatrix::I())
-        , fCurrentClipBounds(SkIRect::MakeXYWH(0, 0, pict->width(), pict->height()))
         , fSaveLayersInStack(0)
         , fAccelData(accelData) {
 
+        pict->cullRect().roundOut(&fCurrentClipBounds);
+
         if (NULL == pict->fRecord.get()) {
             return;
         }
@@ -255,7 +256,7 @@
 // GPUOptimize is only intended to be called within the context of SkGpuDevice's
 // EXPERIMENTAL_optimize method.
 const GrAccelData* GPUOptimize(const SkPicture* pict) {
-    if (NULL == pict || 0 == pict->width() || 0 == pict->height()) {
+    if (NULL == pict || pict->cullRect().isEmpty()) {
         return NULL;
     }
 
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 5e3d153..e7b64a4 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -434,13 +434,15 @@
 
 void SkDumpCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                  const SkPaint* paint) {
-    this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p) %d:%d", picture,
-               picture->width(), picture->height());
+    this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p) %f:%f:%f:%f", picture,
+               picture->cullRect().fLeft, picture->cullRect().fTop,
+               picture->cullRect().fRight, picture->cullRect().fBottom);
     fNestLevel += 1;
     this->INHERITED::onDrawPicture(picture, matrix, paint);
     fNestLevel -= 1;
-    this->dump(kDrawPicture_Verb, NULL, "endPicture(%p) %d:%d", &picture,
-               picture->width(), picture->height());
+    this->dump(kDrawPicture_Verb, NULL, "endPicture(%p) %f:%f:%f:%f", &picture,
+               picture->cullRect().fLeft, picture->cullRect().fTop,
+               picture->cullRect().fRight, picture->cullRect().fBottom);
 }
 
 void SkDumpCanvas::drawVertices(VertexMode vmode, int vertexCount,
diff --git a/src/utils/SkGatherPixelRefsAndRects.cpp b/src/utils/SkGatherPixelRefsAndRects.cpp
index f46fe8e..ee5b147 100644
--- a/src/utils/SkGatherPixelRefsAndRects.cpp
+++ b/src/utils/SkGatherPixelRefsAndRects.cpp
@@ -11,15 +11,15 @@
 
 void SkPictureUtils::GatherPixelRefsAndRects(SkPicture* pict,
                                              SkPictureUtils::SkPixelRefContainer* prCont) {
-    if (0 == pict->width() || 0 == pict->height()) {
+    if (pict->cullRect().isEmpty()) {
         return ;
     }
 
-    SkGatherPixelRefsAndRectsDevice device(pict->width(), pict->height(), prCont);
+    SkGatherPixelRefsAndRectsDevice device(SkScalarCeilToInt(pict->cullRect().width()), 
+                                           SkScalarCeilToInt(pict->cullRect().height()), 
+                                           prCont);
     SkNoSaveLayerCanvas canvas(&device);
 
-    canvas.clipRect(SkRect::MakeWH(SkIntToScalar(pict->width()),
-                                   SkIntToScalar(pict->height())),
-                    SkRegion::kIntersect_Op, false);
+    canvas.clipRect(pict->cullRect(), SkRegion::kIntersect_Op, false);
     canvas.drawPicture(pict);
 }
diff --git a/src/utils/SkPictureUtils.cpp b/src/utils/SkPictureUtils.cpp
index 85d523f..4f4d2bf 100644
--- a/src/utils/SkPictureUtils.cpp
+++ b/src/utils/SkPictureUtils.cpp
@@ -196,16 +196,16 @@
     }
 
     // this test also handles if either area or pict's width/height are empty
-    if (!SkRect::Intersects(area,
-                            SkRect::MakeWH(SkIntToScalar(pict->width()),
-                                           SkIntToScalar(pict->height())))) {
+    if (!SkRect::Intersects(area, pict->cullRect())) {
         return NULL;
     }
 
     SkTDArray<SkPixelRef*> array;
     PixelRefSet prset(&array);
 
-    GatherPixelRefDevice device(pict->width(), pict->height(), &prset);
+    GatherPixelRefDevice device(SkScalarCeilToInt(pict->cullRect().width()), 
+                                SkScalarCeilToInt(pict->cullRect().height()), 
+                                &prset);
     SkNoSaveLayerCanvas canvas(&device);
 
     canvas.clipRect(area, SkRegion::kIntersect_Op, false);
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index 2b0eab7..85fb7a4 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -14,11 +14,10 @@
 #include "SkDevice.h"
 #include "SkXfermode.h"
 
-SkDebugCanvas::SkDebugCanvas(int width, int height)
-        : INHERITED(width, height)
+SkDebugCanvas::SkDebugCanvas(int windowWidth, int windowHeight)
+        : INHERITED(windowWidth, windowHeight)
         , fPicture(NULL)
-        , fWidth(width)
-        , fHeight(height)
+        , fWindowSize(SkISize::Make(windowWidth, windowHeight))
         , fFilter(false)
         , fMegaVizMode(false)
         , fIndex(0)
@@ -76,7 +75,7 @@
 
     SkCanvas canvas(bitmap);
     canvas.translate(SkIntToScalar(-x), SkIntToScalar(-y));
-    applyUserTransform(&canvas);
+    this->applyUserTransform(&canvas);
 
     int layer = 0;
     SkColor prev = bitmap.getColor(0,0);
@@ -255,10 +254,10 @@
         }
         canvas->clear(SK_ColorTRANSPARENT);
         canvas->resetMatrix();
-        SkRect rect = SkRect::MakeWH(SkIntToScalar(fWidth),
-                                     SkIntToScalar(fHeight));
-        canvas->clipRect(rect, SkRegion::kReplace_Op );
-        applyUserTransform(canvas);
+        SkRect rect = SkRect::MakeWH(SkIntToScalar(fWindowSize.fWidth), 
+                                     SkIntToScalar(fWindowSize.fHeight));
+        canvas->clipRect(rect, SkRegion::kReplace_Op);
+        this->applyUserTransform(canvas);
         fOutstandingSaveCount = 0;
     }
 
@@ -292,17 +291,7 @@
 
     for (; i <= index; i++) {
         if (i == index && fFilter) {
-            SkPaint p;
-            p.setColor(0xAAFFFFFF);
-            canvas->save();
-            canvas->resetMatrix();
-            SkRect mask;
-            mask.set(SkIntToScalar(0), SkIntToScalar(0),
-                    SkIntToScalar(fWidth), SkIntToScalar(fHeight));
-            canvas->clipRect(mask, SkRegion::kReplace_Op, false);
-            canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
-                    SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
-            canvas->restore();
+            canvas->clear(0xAAFFFFFF);
         }
 
         if (fCommandVector[i]->isVisible()) {
@@ -321,12 +310,13 @@
     }
 
     if (fMegaVizMode) {
-        SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight));
+        SkRect r = SkRect::MakeWH(SkIntToScalar(fWindowSize.fWidth), 
+                                  SkIntToScalar(fWindowSize.fHeight));
         r.outset(SK_Scalar1, SK_Scalar1);
 
         canvas->save();
         // nuke the CTM
-        canvas->setMatrix(SkMatrix::I());
+        canvas->resetMatrix();
         // turn off clipping
         canvas->clipRect(r, SkRegion::kReplace_Op);
 
diff --git a/src/utils/debugger/SkDebugCanvas.h b/src/utils/debugger/SkDebugCanvas.h
index 94ad426..2e9a032 100644
--- a/src/utils/debugger/SkDebugCanvas.h
+++ b/src/utils/debugger/SkDebugCanvas.h
@@ -145,10 +145,7 @@
      */
     void toggleCommand(int index, bool toggle);
 
-    void setBounds(int width, int height) {
-        fWidth = width;
-        fHeight = height;
-    }
+    void setWindowSize(int width, int height) { fWindowSize.set(width, height); }
 
     void setUserMatrix(SkMatrix matrix) {
         fUserMatrix = matrix;
@@ -259,8 +256,7 @@
 private:
     SkTDArray<SkDrawCommand*> fCommandVector;
     SkPicture* fPicture;
-    int fWidth;
-    int fHeight;
+    SkISize fWindowSize;
     bool fFilter;
     bool fMegaVizMode;
     int fIndex;
diff --git a/src/utils/debugger/SkDrawCommand.cpp b/src/utils/debugger/SkDrawCommand.cpp
index 3b1a028..3a07396 100644
--- a/src/utils/debugger/SkDrawCommand.cpp
+++ b/src/utils/debugger/SkDrawCommand.cpp
@@ -523,7 +523,9 @@
     }
 
     SkString* temp = new SkString;
-    temp->appendf("SkPicture: W: %d H: %d", picture->width(), picture->height());
+    temp->appendf("SkPicture: L: %f T: %f R: %f B: %f",
+                  picture->cullRect().fLeft, picture->cullRect().fTop,
+                  picture->cullRect().fRight, picture->cullRect().fBottom);
     fInfo.push(temp);
     if (NULL != matrix) {
         fInfo.push(SkObjectParser::MatrixToString(*matrix));
@@ -541,9 +543,7 @@
     canvas->clear(0xFFFFFFFF);
     canvas->save();
 
-    SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
-                                   SkIntToScalar(fPicture->height()));
-    xlate_and_scale_to_bounds(canvas, bounds);
+    xlate_and_scale_to_bounds(canvas, fPicture->cullRect());
 
     canvas->drawPicture(fPicture.get());