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