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