xref: /aosp_15_r20/external/skia/tools/DDLTileHelper.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2018 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef DDLTileHelper_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define DDLTileHelper_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrDeferredDisplayList.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/GrSurfaceCharacterization.h"
17*c8dee2aaSAndroid Build Coastguard Worker 
18*c8dee2aaSAndroid Build Coastguard Worker class DDLPromiseImageHelper;
19*c8dee2aaSAndroid Build Coastguard Worker class PromiseImageCallbackContext;
20*c8dee2aaSAndroid Build Coastguard Worker class SkCanvas;
21*c8dee2aaSAndroid Build Coastguard Worker class SkData;
22*c8dee2aaSAndroid Build Coastguard Worker class GrDeferredDisplayListRecorder;
23*c8dee2aaSAndroid Build Coastguard Worker class SkImage;
24*c8dee2aaSAndroid Build Coastguard Worker class SkPicture;
25*c8dee2aaSAndroid Build Coastguard Worker class SkSurface;
26*c8dee2aaSAndroid Build Coastguard Worker class GrSurfaceCharacterization;
27*c8dee2aaSAndroid Build Coastguard Worker class SkTaskGroup;
28*c8dee2aaSAndroid Build Coastguard Worker 
29*c8dee2aaSAndroid Build Coastguard Worker class DDLTileHelper {
30*c8dee2aaSAndroid Build Coastguard Worker public:
31*c8dee2aaSAndroid Build Coastguard Worker     // The TileData class encapsulates the information and behavior of a single tile when
32*c8dee2aaSAndroid Build Coastguard Worker     // rendering with DDLs.
33*c8dee2aaSAndroid Build Coastguard Worker     class TileData {
34*c8dee2aaSAndroid Build Coastguard Worker     public:
35*c8dee2aaSAndroid Build Coastguard Worker         TileData();
36*c8dee2aaSAndroid Build Coastguard Worker         ~TileData();
37*c8dee2aaSAndroid Build Coastguard Worker 
initialized()38*c8dee2aaSAndroid Build Coastguard Worker         bool initialized() const { return fID != -1; }
39*c8dee2aaSAndroid Build Coastguard Worker 
40*c8dee2aaSAndroid Build Coastguard Worker         void init(int id,
41*c8dee2aaSAndroid Build Coastguard Worker                   GrDirectContext*,
42*c8dee2aaSAndroid Build Coastguard Worker                   const GrSurfaceCharacterization& dstChar,
43*c8dee2aaSAndroid Build Coastguard Worker                   const SkIRect& clip,
44*c8dee2aaSAndroid Build Coastguard Worker                   const SkIRect& paddingOutsets);
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker         // Create the DDL for this tile (i.e., fill in 'fDisplayList').
47*c8dee2aaSAndroid Build Coastguard Worker         void createDDL(const SkPicture*);
48*c8dee2aaSAndroid Build Coastguard Worker 
dropDDL()49*c8dee2aaSAndroid Build Coastguard Worker         void dropDDL() { fDisplayList.reset(); }
50*c8dee2aaSAndroid Build Coastguard Worker 
51*c8dee2aaSAndroid Build Coastguard Worker         // Precompile all the programs required to draw this tile's DDL
52*c8dee2aaSAndroid Build Coastguard Worker         void precompile(GrDirectContext*);
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker         // Just draw the re-inflated per-tile SKP directly into this tile w/o going through a DDL
55*c8dee2aaSAndroid Build Coastguard Worker         // first. This is used for determining the overhead of using DDLs (i.e., it replaces
56*c8dee2aaSAndroid Build Coastguard Worker         // a 'createDDL' and 'draw' pair.
57*c8dee2aaSAndroid Build Coastguard Worker         void drawSKPDirectly(GrDirectContext*, const SkPicture*);
58*c8dee2aaSAndroid Build Coastguard Worker 
59*c8dee2aaSAndroid Build Coastguard Worker         // Replay the recorded DDL into the tile surface - filling in 'fBackendTexture'.
60*c8dee2aaSAndroid Build Coastguard Worker         void draw(GrDirectContext*);
61*c8dee2aaSAndroid Build Coastguard Worker 
62*c8dee2aaSAndroid Build Coastguard Worker         void reset();
63*c8dee2aaSAndroid Build Coastguard Worker 
id()64*c8dee2aaSAndroid Build Coastguard Worker         int id() const { return fID; }
clipRect()65*c8dee2aaSAndroid Build Coastguard Worker         SkIRect clipRect() const { return fClip; }
paddedRectSize()66*c8dee2aaSAndroid Build Coastguard Worker         SkISize paddedRectSize() const {
67*c8dee2aaSAndroid Build Coastguard Worker             return { fClip.width() + fPaddingOutsets.fLeft + fPaddingOutsets.fRight,
68*c8dee2aaSAndroid Build Coastguard Worker                      fClip.height() + fPaddingOutsets.fTop + fPaddingOutsets.fBottom };
69*c8dee2aaSAndroid Build Coastguard Worker         }
padOffset()70*c8dee2aaSAndroid Build Coastguard Worker         SkIVector padOffset() const { return { fPaddingOutsets.fLeft, fPaddingOutsets.fTop }; }
71*c8dee2aaSAndroid Build Coastguard Worker 
ddl()72*c8dee2aaSAndroid Build Coastguard Worker         GrDeferredDisplayList* ddl() { return fDisplayList.get(); }
73*c8dee2aaSAndroid Build Coastguard Worker 
74*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkImage> makePromiseImageForDst(sk_sp<GrContextThreadSafeProxy>);
dropCallbackContext()75*c8dee2aaSAndroid Build Coastguard Worker         void dropCallbackContext() { fCallbackContext.reset(); }
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker         static void CreateBackendTexture(GrDirectContext*, TileData*);
78*c8dee2aaSAndroid Build Coastguard Worker         static void DeleteBackendTexture(GrDirectContext*, TileData*);
79*c8dee2aaSAndroid Build Coastguard Worker 
80*c8dee2aaSAndroid Build Coastguard Worker     private:
81*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface> makeWrappedTileDest(GrRecordingContext* context);
82*c8dee2aaSAndroid Build Coastguard Worker 
refCallbackContext()83*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<PromiseImageCallbackContext> refCallbackContext() { return fCallbackContext; }
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker         int                       fID = -1;
86*c8dee2aaSAndroid Build Coastguard Worker         SkIRect                   fClip;             // in the device space of the final SkSurface
87*c8dee2aaSAndroid Build Coastguard Worker         SkIRect                   fPaddingOutsets;   // random padding for the output surface
88*c8dee2aaSAndroid Build Coastguard Worker         GrSurfaceCharacterization fPlaybackChar;     // characterization for the tile's dst surface
89*c8dee2aaSAndroid Build Coastguard Worker 
90*c8dee2aaSAndroid Build Coastguard Worker         // The callback context holds (via its GrPromiseImageTexture) the backend texture
91*c8dee2aaSAndroid Build Coastguard Worker         // that is both wrapped in 'fTileSurface' and backs this tile's promise image
92*c8dee2aaSAndroid Build Coastguard Worker         // (i.e., the one returned by 'makePromiseImage').
93*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<PromiseImageCallbackContext> fCallbackContext;
94*c8dee2aaSAndroid Build Coastguard Worker         // 'fTileSurface' wraps the backend texture in 'fCallbackContext' and must exist until
95*c8dee2aaSAndroid Build Coastguard Worker         // after 'fDisplayList' has been flushed (bc it owns the proxy the DDL's destination
96*c8dee2aaSAndroid Build Coastguard Worker         // trampoline points at).
97*c8dee2aaSAndroid Build Coastguard Worker         // TODO: fix the ref-order so we don't need 'fTileSurface' here
98*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<SkSurface>              fTileSurface;
99*c8dee2aaSAndroid Build Coastguard Worker 
100*c8dee2aaSAndroid Build Coastguard Worker         sk_sp<GrDeferredDisplayList>  fDisplayList;
101*c8dee2aaSAndroid Build Coastguard Worker     };
102*c8dee2aaSAndroid Build Coastguard Worker 
103*c8dee2aaSAndroid Build Coastguard Worker     DDLTileHelper(GrDirectContext*,
104*c8dee2aaSAndroid Build Coastguard Worker                   const GrSurfaceCharacterization& dstChar,
105*c8dee2aaSAndroid Build Coastguard Worker                   const SkIRect& viewport,
106*c8dee2aaSAndroid Build Coastguard Worker                   int numXDivisions, int numYDivisions,
107*c8dee2aaSAndroid Build Coastguard Worker                   bool addRandomPaddingToDst);
108*c8dee2aaSAndroid Build Coastguard Worker 
109*c8dee2aaSAndroid Build Coastguard Worker     void kickOffThreadedWork(SkTaskGroup* recordingTaskGroup,
110*c8dee2aaSAndroid Build Coastguard Worker                              SkTaskGroup* gpuTaskGroup,
111*c8dee2aaSAndroid Build Coastguard Worker                              GrDirectContext*,
112*c8dee2aaSAndroid Build Coastguard Worker                              SkPicture*);
113*c8dee2aaSAndroid Build Coastguard Worker 
114*c8dee2aaSAndroid Build Coastguard Worker     void createDDLsInParallel(SkPicture*);
115*c8dee2aaSAndroid Build Coastguard Worker 
116*c8dee2aaSAndroid Build Coastguard Worker     // Create the DDL that will compose all the tile images into a final result.
117*c8dee2aaSAndroid Build Coastguard Worker     void createComposeDDL();
composeDDL()118*c8dee2aaSAndroid Build Coastguard Worker     const sk_sp<GrDeferredDisplayList>& composeDDL() const { return fComposeDDL; }
119*c8dee2aaSAndroid Build Coastguard Worker 
120*c8dee2aaSAndroid Build Coastguard Worker     // For each tile, create its DDL and then draw it - all on a single thread. This is to allow
121*c8dee2aaSAndroid Build Coastguard Worker     // comparison w/ just drawing the SKP directly (i.e., drawAllTilesDirectly). The
122*c8dee2aaSAndroid Build Coastguard Worker     // DDL creations and draws are interleaved to prevent starvation of the GPU.
123*c8dee2aaSAndroid Build Coastguard Worker     // Note: this is somewhat of a misuse/pessimistic-use of DDLs since they are supposed to
124*c8dee2aaSAndroid Build Coastguard Worker     // be created on a separate thread.
125*c8dee2aaSAndroid Build Coastguard Worker     void interleaveDDLCreationAndDraw(GrDirectContext*, SkPicture*);
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker     // This draws all the per-tile SKPs directly into all of the tiles w/o converting them to
128*c8dee2aaSAndroid Build Coastguard Worker     // DDLs first - all on a single thread.
129*c8dee2aaSAndroid Build Coastguard Worker     void drawAllTilesDirectly(GrDirectContext*, SkPicture*);
130*c8dee2aaSAndroid Build Coastguard Worker 
131*c8dee2aaSAndroid Build Coastguard Worker     void dropCallbackContexts();
132*c8dee2aaSAndroid Build Coastguard Worker     void resetAllTiles();
133*c8dee2aaSAndroid Build Coastguard Worker 
numTiles()134*c8dee2aaSAndroid Build Coastguard Worker     int numTiles() const { return fNumXDivisions * fNumYDivisions; }
135*c8dee2aaSAndroid Build Coastguard Worker 
136*c8dee2aaSAndroid Build Coastguard Worker     void createBackendTextures(SkTaskGroup*, GrDirectContext*);
137*c8dee2aaSAndroid Build Coastguard Worker     void deleteBackendTextures(SkTaskGroup*, GrDirectContext*);
138*c8dee2aaSAndroid Build Coastguard Worker 
139*c8dee2aaSAndroid Build Coastguard Worker private:
140*c8dee2aaSAndroid Build Coastguard Worker     int                                    fNumXDivisions; // number of tiles horizontally
141*c8dee2aaSAndroid Build Coastguard Worker     int                                    fNumYDivisions; // number of tiles vertically
142*c8dee2aaSAndroid Build Coastguard Worker     skia_private::AutoTArray<TileData>   fTiles;        // 'fNumXDivisions' x
143*c8dee2aaSAndroid Build Coastguard Worker     // 'fNumYDivisions'
144*c8dee2aaSAndroid Build Coastguard Worker 
145*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<GrDeferredDisplayList>           fComposeDDL;
146*c8dee2aaSAndroid Build Coastguard Worker 
147*c8dee2aaSAndroid Build Coastguard Worker     const GrSurfaceCharacterization        fDstCharacterization;
148*c8dee2aaSAndroid Build Coastguard Worker };
149*c8dee2aaSAndroid Build Coastguard Worker 
150*c8dee2aaSAndroid Build Coastguard Worker #endif
151