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