blob: 6fa2d5272841f1e8472d67ce4c3a5a62f6083306 [file] [log] [blame]
Robert Phillips96601082018-05-29 16:13:26 -04001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef DDLTileHelper_DEFINED
9#define DDLTileHelper_DEFINED
10
Adlai Holler7580ad42020-06-24 13:45:25 -040011#include "include/core/SkDeferredDisplayList.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkRect.h"
13#include "include/core/SkRefCnt.h"
14#include "include/core/SkSurfaceCharacterization.h"
Robert Phillips96601082018-05-29 16:13:26 -040015
Robert Phillips96601082018-05-29 16:13:26 -040016class DDLPromiseImageHelper;
Robert Phillips11c67672020-04-23 15:10:03 -040017class PromiseImageCallbackContext;
Robert Phillips96601082018-05-29 16:13:26 -040018class SkCanvas;
19class SkData;
Robert Phillips11c67672020-04-23 15:10:03 -040020class SkDeferredDisplayListRecorder;
Robert Phillips96601082018-05-29 16:13:26 -040021class SkPicture;
22class SkSurface;
23class SkSurfaceCharacterization;
Robert Phillips1a578572020-07-13 13:17:09 -040024class SkTaskGroup;
Robert Phillips96601082018-05-29 16:13:26 -040025
26class DDLTileHelper {
27public:
Robert Phillipsa865a3a2020-02-14 10:49:39 -050028 // The TileData class encapsulates the information and behavior of a single tile when
29 // rendering with DDLs.
Robert Phillips96601082018-05-29 16:13:26 -040030 class TileData {
31 public:
Robert Phillipsa865a3a2020-02-14 10:49:39 -050032 TileData() {}
33 ~TileData();
Robert Phillips96601082018-05-29 16:13:26 -040034
Robert Phillips559f9c12021-01-11 12:29:20 -050035 bool initialized() const { return fID != -1; }
36
Robert Phillips19f466d2020-02-26 10:27:07 -050037 void init(int id,
Robert Phillipsd5f3c982020-07-07 13:18:47 -040038 GrDirectContext*,
Robert Phillips19f466d2020-02-26 10:27:07 -050039 const SkSurfaceCharacterization& dstChar,
Robert Phillips0c088492020-11-10 08:30:50 -050040 const SkIRect& clip,
41 const SkIRect& paddingOutsets);
Robert Phillipsa865a3a2020-02-14 10:49:39 -050042
43 // Convert the compressedPictureData into an SkPicture replacing each image-index
44 // with a promise image.
Robert Phillips96601082018-05-29 16:13:26 -040045 void createTileSpecificSKP(SkData* compressedPictureData,
46 const DDLPromiseImageHelper& helper);
47
Robert Phillipsa865a3a2020-02-14 10:49:39 -050048 // Create the DDL for this tile (i.e., fill in 'fDisplayList').
Robert Phillips96601082018-05-29 16:13:26 -040049 void createDDL();
50
Robert Phillips5dbcca52020-05-29 10:41:33 -040051 void dropDDL() { fDisplayList.reset(); }
52
Robert Phillips6eb5cb92020-03-05 12:52:45 -050053 // Precompile all the programs required to draw this tile's DDL
Robert Phillipsd5f3c982020-07-07 13:18:47 -040054 void precompile(GrDirectContext*);
Robert Phillips6eb5cb92020-03-05 12:52:45 -050055
Robert Phillips24a8e9e2020-03-06 20:26:28 +000056 // Just draw the re-inflated per-tile SKP directly into this tile w/o going through a DDL
57 // first. This is used for determining the overhead of using DDLs (i.e., it replaces
58 // a 'createDDL' and 'draw' pair.
Adlai Hollerb2705682020-10-20 10:11:53 -040059 void drawSKPDirectly(GrRecordingContext*);
Robert Phillips24a8e9e2020-03-06 20:26:28 +000060
Robert Phillips11c67672020-04-23 15:10:03 -040061 // Replay the recorded DDL into the tile surface - filling in 'fBackendTexture'.
Robert Phillipsd5f3c982020-07-07 13:18:47 -040062 void draw(GrDirectContext*);
Robert Phillips96601082018-05-29 16:13:26 -040063
Robert Phillips96601082018-05-29 16:13:26 -040064 void reset();
65
Robert Phillipsa865a3a2020-02-14 10:49:39 -050066 int id() const { return fID; }
Robert Phillips11c67672020-04-23 15:10:03 -040067 SkIRect clipRect() const { return fClip; }
Robert Phillips0c088492020-11-10 08:30:50 -050068 SkISize paddedRectSize() const {
69 return { fClip.width() + fPaddingOutsets.fLeft + fPaddingOutsets.fRight,
70 fClip.height() + fPaddingOutsets.fTop + fPaddingOutsets.fBottom };
71 }
72 SkIVector padOffset() const { return { fPaddingOutsets.fLeft, fPaddingOutsets.fTop }; }
Robert Phillipsa865a3a2020-02-14 10:49:39 -050073
Robert Phillips7b0ed552020-02-20 12:45:19 -050074 SkDeferredDisplayList* ddl() { return fDisplayList.get(); }
75
Robert Phillips0c088492020-11-10 08:30:50 -050076 sk_sp<SkImage> makePromiseImageForDst(SkDeferredDisplayListRecorder*);
Robert Phillips11c67672020-04-23 15:10:03 -040077 void dropCallbackContext() { fCallbackContext.reset(); }
78
Robert Phillipsd5f3c982020-07-07 13:18:47 -040079 static void CreateBackendTexture(GrDirectContext*, TileData*);
80 static void DeleteBackendTexture(GrDirectContext*, TileData*);
Robert Phillips8472a3d2020-04-16 16:27:45 -040081
Robert Phillips96601082018-05-29 16:13:26 -040082 private:
Adlai Hollerb2705682020-10-20 10:11:53 -040083 sk_sp<SkSurface> makeWrappedTileDest(GrRecordingContext* context);
Robert Phillips8472a3d2020-04-16 16:27:45 -040084
Robert Phillips11c67672020-04-23 15:10:03 -040085 sk_sp<PromiseImageCallbackContext> refCallbackContext() { return fCallbackContext; }
86
Robert Phillipsa865a3a2020-02-14 10:49:39 -050087 int fID = -1;
Robert Phillips11c67672020-04-23 15:10:03 -040088 SkIRect fClip; // in the device space of the final SkSurface
Robert Phillips0c088492020-11-10 08:30:50 -050089 SkIRect fPaddingOutsets; // random padding for the output surface
Robert Phillipsbc688322020-12-14 11:38:59 -050090 SkSurfaceCharacterization fPlaybackChar; // characterization for the tile's dst surface
Robert Phillipsa865a3a2020-02-14 10:49:39 -050091
Robert Phillips11c67672020-04-23 15:10:03 -040092 // The callback context holds (via its SkPromiseImageTexture) the backend texture
93 // that is both wrapped in 'fTileSurface' and backs this tile's promise image
94 // (i.e., the one returned by 'makePromiseImage').
95 sk_sp<PromiseImageCallbackContext> fCallbackContext;
96 // 'fTileSurface' wraps the backend texture in 'fCallbackContext' and must exist until
97 // after 'fDisplayList' has been flushed (bc it owns the proxy the DDL's destination
98 // trampoline points at).
99 // TODO: fix the ref-order so we don't need 'fTileSurface' here
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400100 sk_sp<SkSurface> fTileSurface;
Robert Phillips11c67672020-04-23 15:10:03 -0400101
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400102 sk_sp<SkPicture> fReconstitutedPicture;
103 SkTArray<sk_sp<SkImage>> fPromiseImages; // All the promise images in the
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500104 // reconstituted picture
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400105 sk_sp<SkDeferredDisplayList> fDisplayList;
Robert Phillips96601082018-05-29 16:13:26 -0400106 };
107
Robert Phillipsd5f3c982020-07-07 13:18:47 -0400108 DDLTileHelper(GrDirectContext*,
Robert Phillips19f466d2020-02-26 10:27:07 -0500109 const SkSurfaceCharacterization& dstChar,
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500110 const SkIRect& viewport,
Robert Phillips0c088492020-11-10 08:30:50 -0500111 int numDivisions,
112 bool addRandomPaddingToDst);
Robert Phillips96601082018-05-29 16:13:26 -0400113
Robert Phillips889d6132020-06-16 11:11:33 -0400114 void createSKPPerTile(SkData* compressedPictureData, const DDLPromiseImageHelper&);
Robert Phillips96601082018-05-29 16:13:26 -0400115
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500116 void kickOffThreadedWork(SkTaskGroup* recordingTaskGroup,
117 SkTaskGroup* gpuTaskGroup,
Robert Phillipsd5f3c982020-07-07 13:18:47 -0400118 GrDirectContext*);
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500119
Robert Phillips96601082018-05-29 16:13:26 -0400120 void createDDLsInParallel();
121
Robert Phillips11c67672020-04-23 15:10:03 -0400122 // Create the DDL that will compose all the tile images into a final result.
123 void createComposeDDL();
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400124 const sk_sp<SkDeferredDisplayList>& composeDDL() const { return fComposeDDL; }
Robert Phillips11c67672020-04-23 15:10:03 -0400125
Robert Phillipsd5f3c982020-07-07 13:18:47 -0400126 void precompileAndDrawAllTiles(GrDirectContext*);
Robert Phillips96601082018-05-29 16:13:26 -0400127
Robert Phillips24a8e9e2020-03-06 20:26:28 +0000128 // For each tile, create its DDL and then draw it - all on a single thread. This is to allow
129 // comparison w/ just drawing the SKP directly (i.e., drawAllTilesDirectly). The
130 // DDL creations and draws are interleaved to prevent starvation of the GPU.
131 // Note: this is somewhat of a misuse/pessimistic-use of DDLs since they are supposed to
132 // be created on a separate thread.
Robert Phillipsd5f3c982020-07-07 13:18:47 -0400133 void interleaveDDLCreationAndDraw(GrDirectContext*);
Robert Phillips24a8e9e2020-03-06 20:26:28 +0000134
135 // This draws all the per-tile SKPs directly into all of the tiles w/o converting them to
136 // DDLs first - all on a single thread.
Adlai Hollerb2705682020-10-20 10:11:53 -0400137 void drawAllTilesDirectly(GrDirectContext*);
Robert Phillips24a8e9e2020-03-06 20:26:28 +0000138
Robert Phillips11c67672020-04-23 15:10:03 -0400139 void dropCallbackContexts();
Robert Phillips96601082018-05-29 16:13:26 -0400140 void resetAllTiles();
141
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500142 int numTiles() const { return fNumDivisions * fNumDivisions; }
143
Robert Phillipsd5f3c982020-07-07 13:18:47 -0400144 void createBackendTextures(SkTaskGroup*, GrDirectContext*);
145 void deleteBackendTextures(SkTaskGroup*, GrDirectContext*);
Robert Phillips8472a3d2020-04-16 16:27:45 -0400146
Robert Phillips96601082018-05-29 16:13:26 -0400147private:
Robert Phillips11c67672020-04-23 15:10:03 -0400148 int fNumDivisions; // number of tiles along a side
Adlai Holler8e821232020-05-11 13:33:59 -0400149 SkAutoTArray<TileData> fTiles; // 'fNumDivisions' x 'fNumDivisions'
Robert Phillips11c67672020-04-23 15:10:03 -0400150
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400151 sk_sp<SkDeferredDisplayList> fComposeDDL;
Robert Phillips11c67672020-04-23 15:10:03 -0400152
153 const SkSurfaceCharacterization fDstCharacterization;
Robert Phillips96601082018-05-29 16:13:26 -0400154};
155
156#endif