2222void DDLTileHelper::TileData::init (int id,
2323 GrDirectContext* direct,
2424 const SkSurfaceCharacterization& dstSurfaceCharacterization,
25- const SkIRect& clip) {
25+ const SkIRect& clip,
26+ const SkIRect& paddingOutsets) {
2627 fID = id;
2728 fClip = clip;
29+ fPaddingOutsets = paddingOutsets;
2830
29- fCharacterization = dstSurfaceCharacterization.createResized (clip.width (), clip.height ());
31+ fCharacterization = dstSurfaceCharacterization.createResized (this ->paddedRectSize ().width (),
32+ this ->paddedRectSize ().height ());
3033 SkASSERT (fCharacterization .isValid ());
3134
3235 GrBackendFormat backendFormat = direct->defaultBackendFormat (fCharacterization .colorType (),
@@ -78,6 +81,7 @@ void DDLTileHelper::TileData::createDDL() {
7881 }
7982 }
8083
84+ // We always record the DDL in the (0,0) .. (clipWidth, clipHeight) coordinates
8185 recordingCanvas->clipRect (SkRect::MakeWH (fClip .width (), fClip .height ()));
8286 recordingCanvas->translate (-fClip .fLeft , -fClip .fTop );
8387
@@ -98,14 +102,15 @@ void DDLTileHelper::createComposeDDL() {
98102 for (int i = 0 ; i < this ->numTiles (); ++i) {
99103 TileData* tile = &fTiles [i];
100104
101- sk_sp<SkImage> promiseImage = tile->makePromiseImage (&recorder);
105+ sk_sp<SkImage> promiseImage = tile->makePromiseImageForDst (&recorder);
102106
103- SkIRect clipRect = tile->clipRect ();
107+ SkRect dstRect = SkRect::Make (tile->clipRect ());
108+ SkIRect srcRect = tile->clipRect ();
109+ srcRect.offsetTo (tile->padOffset ().x (), tile->padOffset ().y ());
104110
105- SkASSERT (clipRect.width () == promiseImage->width () &&
106- clipRect.height () == promiseImage->height ());
111+ SkASSERT (promiseImage->bounds ().contains (srcRect));
107112
108- recordingCanvas->drawImage (promiseImage, clipRect. fLeft , clipRect. fTop );
113+ recordingCanvas->drawImageRect (promiseImage. get (), srcRect, dstRect, nullptr );
109114 }
110115
111116 fComposeDDL = recorder.detach ();
@@ -148,6 +153,7 @@ void DDLTileHelper::TileData::drawSKPDirectly(GrRecordingContext* context) {
148153 if (fTileSurface ) {
149154 SkCanvas* tileCanvas = fTileSurface ->getCanvas ();
150155
156+ SkASSERT (this ->padOffset ().isZero () && this ->paddedRectSize () == fClip .size ());
151157 tileCanvas->clipRect (SkRect::MakeWH (fClip .width (), fClip .height ()));
152158 tileCanvas->translate (-fClip .fLeft , -fClip .fTop );
153159
@@ -167,7 +173,7 @@ void DDLTileHelper::TileData::draw(GrDirectContext* direct) {
167173 // (maybe in GrDrawingManager::addDDLTarget).
168174 fTileSurface = this ->makeWrappedTileDest (direct);
169175 if (fTileSurface ) {
170- fTileSurface ->draw (fDisplayList );
176+ fTileSurface ->draw (fDisplayList , this -> padOffset (). x (), this -> padOffset (). y () );
171177
172178 // We can't snap an image here bc, since we're using wrapped backend textures for the
173179 // surfaces, that would incur a copy.
@@ -181,14 +187,15 @@ void DDLTileHelper::TileData::reset() {
181187 fTileSurface = nullptr ;
182188}
183189
184- sk_sp<SkImage> DDLTileHelper::TileData::makePromiseImage (SkDeferredDisplayListRecorder* recorder) {
190+ sk_sp<SkImage> DDLTileHelper::TileData::makePromiseImageForDst (
191+ SkDeferredDisplayListRecorder* recorder) {
185192 SkASSERT (fCallbackContext );
186193
187194 // The promise image gets a ref on the promise callback context
188195 sk_sp<SkImage> promiseImage =
189196 recorder->makePromiseTexture (fCallbackContext ->backendFormat (),
190- fClip .width (),
191- fClip .height (),
197+ this -> paddedRectSize () .width (),
198+ this -> paddedRectSize () .height (),
192199 GrMipmapped::kNo ,
193200 GrSurfaceOrigin::kBottomLeft_GrSurfaceOrigin ,
194201 fCharacterization .colorType (),
@@ -230,7 +237,8 @@ void DDLTileHelper::TileData::DeleteBackendTexture(GrDirectContext*, TileData* t
230237DDLTileHelper::DDLTileHelper (GrDirectContext* direct,
231238 const SkSurfaceCharacterization& dstChar,
232239 const SkIRect& viewport,
233- int numDivisions)
240+ int numDivisions,
241+ bool addRandomPaddingToDst)
234242 : fNumDivisions(numDivisions)
235243 , fTiles(numDivisions * numDivisions)
236244 , fDstCharacterization(dstChar) {
@@ -239,6 +247,8 @@ DDLTileHelper::DDLTileHelper(GrDirectContext* direct,
239247 int xTileSize = viewport.width ()/fNumDivisions ;
240248 int yTileSize = viewport.height ()/fNumDivisions ;
241249
250+ SkRandom rand;
251+
242252 // Create the destination tiles
243253 for (int y = 0 , yOff = 0 ; y < fNumDivisions ; ++y, yOff += yTileSize) {
244254 int ySize = (y < fNumDivisions -1 ) ? yTileSize : viewport.height ()-yOff;
@@ -250,7 +260,14 @@ DDLTileHelper::DDLTileHelper(GrDirectContext* direct,
250260
251261 SkASSERT (viewport.contains (clip));
252262
253- fTiles [y*fNumDivisions +x].init (y*fNumDivisions +x, direct, dstChar, clip);
263+ static const uint32_t kMaxPad = 64 ;
264+ int32_t lPad = addRandomPaddingToDst ? rand.nextRangeU (0 , kMaxPad ) : 0 ;
265+ int32_t tPad = addRandomPaddingToDst ? rand.nextRangeU (0 , kMaxPad ) : 0 ;
266+ int32_t rPad = addRandomPaddingToDst ? rand.nextRangeU (0 , kMaxPad ) : 0 ;
267+ int32_t bPad = addRandomPaddingToDst ? rand.nextRangeU (0 , kMaxPad ) : 0 ;
268+
269+ fTiles [y*fNumDivisions +x].init (y*fNumDivisions +x, direct, dstChar, clip,
270+ {lPad, tPad, rPad, bPad});
254271 }
255272 }
256273}
0 commit comments