Update DDL testing harness to support drawing DDL w/ integer offsets

This isn't hooked up anywhere but breaks up the omnibus CL.

Change-Id: I15c200e57450e7cc8ee95a3f7969926d0eb8487f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/333129
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/tools/DDLTileHelper.cpp b/tools/DDLTileHelper.cpp
index 9e50619..3ff7699 100644
--- a/tools/DDLTileHelper.cpp
+++ b/tools/DDLTileHelper.cpp
@@ -22,11 +22,14 @@
 void DDLTileHelper::TileData::init(int id,
                                    GrDirectContext* direct,
                                    const SkSurfaceCharacterization& dstSurfaceCharacterization,
-                                   const SkIRect& clip) {
+                                   const SkIRect& clip,
+                                   const SkIRect& paddingOutsets) {
     fID = id;
     fClip = clip;
+    fPaddingOutsets = paddingOutsets;
 
-    fCharacterization = dstSurfaceCharacterization.createResized(clip.width(), clip.height());
+    fCharacterization = dstSurfaceCharacterization.createResized(this->paddedRectSize().width(),
+                                                                 this->paddedRectSize().height());
     SkASSERT(fCharacterization.isValid());
 
     GrBackendFormat backendFormat = direct->defaultBackendFormat(fCharacterization.colorType(),
@@ -78,6 +81,7 @@
         }
     }
 
+    // We always record the DDL in the (0,0) .. (clipWidth, clipHeight) coordinates
     recordingCanvas->clipRect(SkRect::MakeWH(fClip.width(), fClip.height()));
     recordingCanvas->translate(-fClip.fLeft, -fClip.fTop);
 
@@ -98,14 +102,15 @@
     for (int i = 0; i < this->numTiles(); ++i) {
         TileData* tile = &fTiles[i];
 
-        sk_sp<SkImage> promiseImage = tile->makePromiseImage(&recorder);
+        sk_sp<SkImage> promiseImage = tile->makePromiseImageForDst(&recorder);
 
-        SkIRect clipRect = tile->clipRect();
+        SkRect dstRect = SkRect::Make(tile->clipRect());
+        SkIRect srcRect = tile->clipRect();
+        srcRect.offsetTo(tile->padOffset().x(), tile->padOffset().y());
 
-        SkASSERT(clipRect.width() == promiseImage->width() &&
-                 clipRect.height() == promiseImage->height());
+        SkASSERT(promiseImage->bounds().contains(srcRect));
 
-        recordingCanvas->drawImage(promiseImage, clipRect.fLeft, clipRect.fTop);
+        recordingCanvas->drawImageRect(promiseImage.get(), srcRect, dstRect, nullptr);
     }
 
     fComposeDDL = recorder.detach();
@@ -148,6 +153,7 @@
     if (fTileSurface) {
         SkCanvas* tileCanvas = fTileSurface->getCanvas();
 
+        SkASSERT(this->padOffset().isZero() && this->paddedRectSize() == fClip.size());
         tileCanvas->clipRect(SkRect::MakeWH(fClip.width(), fClip.height()));
         tileCanvas->translate(-fClip.fLeft, -fClip.fTop);
 
@@ -167,7 +173,7 @@
     // (maybe in GrDrawingManager::addDDLTarget).
     fTileSurface = this->makeWrappedTileDest(direct);
     if (fTileSurface) {
-        fTileSurface->draw(fDisplayList);
+        fTileSurface->draw(fDisplayList, this->padOffset().x(), this->padOffset().y());
 
         // We can't snap an image here bc, since we're using wrapped backend textures for the
         // surfaces, that would incur a copy.
@@ -181,14 +187,15 @@
     fTileSurface = nullptr;
 }
 
-sk_sp<SkImage> DDLTileHelper::TileData::makePromiseImage(SkDeferredDisplayListRecorder* recorder) {
+sk_sp<SkImage> DDLTileHelper::TileData::makePromiseImageForDst(
+                                                        SkDeferredDisplayListRecorder* recorder) {
     SkASSERT(fCallbackContext);
 
     // The promise image gets a ref on the promise callback context
     sk_sp<SkImage> promiseImage =
             recorder->makePromiseTexture(fCallbackContext->backendFormat(),
-                                         fClip.width(),
-                                         fClip.height(),
+                                         this->paddedRectSize().width(),
+                                         this->paddedRectSize().height(),
                                          GrMipmapped::kNo,
                                          GrSurfaceOrigin::kBottomLeft_GrSurfaceOrigin,
                                          fCharacterization.colorType(),
@@ -230,7 +237,8 @@
 DDLTileHelper::DDLTileHelper(GrDirectContext* direct,
                              const SkSurfaceCharacterization& dstChar,
                              const SkIRect& viewport,
-                             int numDivisions)
+                             int numDivisions,
+                             bool addRandomPaddingToDst)
         : fNumDivisions(numDivisions)
         , fTiles(numDivisions * numDivisions)
         , fDstCharacterization(dstChar) {
@@ -239,6 +247,8 @@
     int xTileSize = viewport.width()/fNumDivisions;
     int yTileSize = viewport.height()/fNumDivisions;
 
+    SkRandom rand;
+
     // Create the destination tiles
     for (int y = 0, yOff = 0; y < fNumDivisions; ++y, yOff += yTileSize) {
         int ySize = (y < fNumDivisions-1) ? yTileSize : viewport.height()-yOff;
@@ -250,7 +260,14 @@
 
             SkASSERT(viewport.contains(clip));
 
-            fTiles[y*fNumDivisions+x].init(y*fNumDivisions+x, direct, dstChar, clip);
+            static const uint32_t kMaxPad = 64;
+            int32_t lPad = addRandomPaddingToDst ? rand.nextRangeU(0, kMaxPad) : 0;
+            int32_t tPad = addRandomPaddingToDst ? rand.nextRangeU(0, kMaxPad) : 0;
+            int32_t rPad = addRandomPaddingToDst ? rand.nextRangeU(0, kMaxPad) : 0;
+            int32_t bPad = addRandomPaddingToDst ? rand.nextRangeU(0, kMaxPad) : 0;
+
+            fTiles[y*fNumDivisions+x].init(y*fNumDivisions+x, direct, dstChar, clip,
+                                           {lPad, tPad, rPad, bPad});
         }
     }
 }