1 | /* |
2 | * Copyright 2019 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 GrRecordingContext_DEFINED |
9 | #define GrRecordingContext_DEFINED |
10 | |
11 | #include "include/core/SkRefCnt.h" |
12 | #include "include/private/GrImageContext.h" |
13 | #include "include/private/SkTArray.h" |
14 | |
15 | class GrAuditTrail; |
16 | class GrBackendFormat; |
17 | class GrDrawingManager; |
18 | class GrOnFlushCallbackObject; |
19 | class GrOpMemoryPool; |
20 | class GrProgramDesc; |
21 | class GrProgramInfo; |
22 | class GrRecordingContextPriv; |
23 | class GrSurfaceContext; |
24 | class GrSurfaceProxy; |
25 | class GrTextBlobCache; |
26 | class SkArenaAlloc; |
27 | class SkJSONWriter; |
28 | |
29 | class GrRecordingContext : public GrImageContext { |
30 | public: |
31 | ~GrRecordingContext() override; |
32 | |
33 | SK_API GrBackendFormat defaultBackendFormat(SkColorType ct, GrRenderable renderable) const { |
34 | return INHERITED::defaultBackendFormat(ct, renderable); |
35 | } |
36 | |
37 | /** |
38 | * Reports whether the GrDirectContext associated with this GrRecordingContext is abandoned. |
39 | * When called on a GrDirectContext it may actively check whether the underlying 3D API |
40 | * device/context has been disconnected before reporting the status. If so, calling this |
41 | * method will transition the GrDirectContext to the abandoned state. |
42 | */ |
43 | bool abandoned() override { return INHERITED::abandoned(); } |
44 | |
45 | /* |
46 | * Can a SkSurface be created with the given color type. To check whether MSAA is supported |
47 | * use maxSurfaceSampleCountForColorType(). |
48 | */ |
49 | SK_API bool colorTypeSupportedAsSurface(SkColorType colorType) const { |
50 | if (kR16G16_unorm_SkColorType == colorType || |
51 | kA16_unorm_SkColorType == colorType || |
52 | kA16_float_SkColorType == colorType || |
53 | kR16G16_float_SkColorType == colorType || |
54 | kR16G16B16A16_unorm_SkColorType == colorType || |
55 | kGray_8_SkColorType == colorType) { |
56 | return false; |
57 | } |
58 | |
59 | return this->maxSurfaceSampleCountForColorType(colorType) > 0; |
60 | } |
61 | |
62 | /** |
63 | * Gets the maximum supported sample count for a color type. 1 is returned if only non-MSAA |
64 | * rendering is supported for the color type. 0 is returned if rendering to this color type |
65 | * is not supported at all. |
66 | */ |
67 | SK_API int maxSurfaceSampleCountForColorType(SkColorType) const; |
68 | |
69 | // Provides access to functions that aren't part of the public API. |
70 | GrRecordingContextPriv priv(); |
71 | const GrRecordingContextPriv priv() const; // NOLINT(readability-const-return-type) |
72 | |
73 | // The collection of specialized memory arenas for different types of data recorded by a |
74 | // GrRecordingContext. Arenas does not maintain ownership of the pools it groups together. |
75 | class Arenas { |
76 | public: |
77 | Arenas(GrOpMemoryPool*, SkArenaAlloc*); |
78 | |
79 | // For storing GrOp-derived classes recorded by a GrRecordingContext |
80 | GrOpMemoryPool* opMemoryPool() { return fOpMemoryPool; } |
81 | |
82 | // For storing pipelines and other complex data as-needed by ops |
83 | SkArenaAlloc* recordTimeAllocator() { return fRecordTimeAllocator; } |
84 | |
85 | private: |
86 | GrOpMemoryPool* fOpMemoryPool; |
87 | SkArenaAlloc* fRecordTimeAllocator; |
88 | }; |
89 | |
90 | protected: |
91 | friend class GrRecordingContextPriv; // for hidden functions |
92 | friend class SkDeferredDisplayList; // for OwnedArenas |
93 | friend class SkDeferredDisplayListPriv; // for ProgramData |
94 | |
95 | // Like Arenas, but preserves ownership of the underlying pools. |
96 | class OwnedArenas { |
97 | public: |
98 | OwnedArenas(); |
99 | ~OwnedArenas(); |
100 | |
101 | Arenas get(); |
102 | |
103 | OwnedArenas& operator=(OwnedArenas&&); |
104 | |
105 | private: |
106 | std::unique_ptr<GrOpMemoryPool> fOpMemoryPool; |
107 | std::unique_ptr<SkArenaAlloc> fRecordTimeAllocator; |
108 | }; |
109 | |
110 | GrRecordingContext(sk_sp<GrContextThreadSafeProxy>); |
111 | void setupDrawingManager(bool sortOpsTasks, bool reduceOpsTaskSplitting); |
112 | |
113 | void abandonContext() override; |
114 | |
115 | GrDrawingManager* drawingManager(); |
116 | |
117 | // There is no going back from this method. It should only be called to control the timing |
118 | // during abandon or destruction of the context. |
119 | void destroyDrawingManager(); |
120 | |
121 | Arenas arenas() { return fArenas.get(); } |
122 | // This entry point should only be used for DDL creation where we want the ops' lifetime to |
123 | // match that of the DDL. |
124 | OwnedArenas&& detachArenas(); |
125 | |
126 | struct ProgramData { |
127 | ProgramData(std::unique_ptr<const GrProgramDesc>, const GrProgramInfo*); |
128 | ProgramData(ProgramData&&); // for SkTArray |
129 | ProgramData(const ProgramData&) = delete; |
130 | ~ProgramData(); |
131 | |
132 | const GrProgramDesc& desc() const { return *fDesc; } |
133 | const GrProgramInfo& info() const { return *fInfo; } |
134 | |
135 | private: |
136 | // TODO: store the GrProgramDescs in the 'fRecordTimeData' arena |
137 | std::unique_ptr<const GrProgramDesc> fDesc; |
138 | // The program infos should be stored in 'fRecordTimeData' so do not need to be ref |
139 | // counted or deleted in the destructor. |
140 | const GrProgramInfo* fInfo = nullptr; |
141 | }; |
142 | |
143 | // This entry point gives the recording context a chance to cache the provided |
144 | // programInfo. The DDL context takes this opportunity to store programInfos as a sidecar |
145 | // to the DDL. |
146 | virtual void recordProgramInfo(const GrProgramInfo*) {} |
147 | // This asks the recording context to return any programInfos it may have collected |
148 | // via the 'recordProgramInfo' call. It is up to the caller to ensure that the lifetime |
149 | // of the programInfos matches the intended use. For example, in DDL-record mode it |
150 | // is known that all the programInfos will have been allocated in an arena with the |
151 | // same lifetime at the DDL itself. |
152 | virtual void detachProgramData(SkTArray<ProgramData>*) {} |
153 | |
154 | GrTextBlobCache* getTextBlobCache(); |
155 | const GrTextBlobCache* getTextBlobCache() const; |
156 | |
157 | /** |
158 | * Registers an object for flush-related callbacks. (See GrOnFlushCallbackObject.) |
159 | * |
160 | * NOTE: the drawing manager tracks this object as a raw pointer; it is up to the caller to |
161 | * ensure its lifetime is tied to that of the context. |
162 | */ |
163 | void addOnFlushCallbackObject(GrOnFlushCallbackObject*); |
164 | |
165 | GrAuditTrail* auditTrail() { return fAuditTrail.get(); } |
166 | |
167 | GrRecordingContext* asRecordingContext() override { return this; } |
168 | |
169 | class Stats { |
170 | public: |
171 | Stats() = default; |
172 | |
173 | #if GR_GPU_STATS |
174 | void reset() { *this = {}; } |
175 | |
176 | int numPathMasksGenerated() const { return fNumPathMasksGenerated; } |
177 | void incNumPathMasksGenerated() { fNumPathMasksGenerated++; } |
178 | |
179 | int numPathMaskCacheHits() const { return fNumPathMaskCacheHits; } |
180 | void incNumPathMasksCacheHits() { fNumPathMaskCacheHits++; } |
181 | |
182 | #if GR_TEST_UTILS |
183 | void dump(SkString* out); |
184 | void dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values); |
185 | #endif |
186 | |
187 | private: |
188 | int fNumPathMasksGenerated{0}; |
189 | int fNumPathMaskCacheHits{0}; |
190 | |
191 | #else // GR_GPU_STATS |
192 | void incNumPathMasksGenerated() {} |
193 | void incNumPathMasksCacheHits() {} |
194 | |
195 | #if GR_TEST_UTILS |
196 | void dump(SkString*) {} |
197 | void dumpKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) {} |
198 | #endif |
199 | #endif // GR_GPU_STATS |
200 | } fStats; |
201 | |
202 | Stats* stats() { return &fStats; } |
203 | const Stats* stats() const { return &fStats; } |
204 | void dumpJSON(SkJSONWriter*) const; |
205 | |
206 | private: |
207 | OwnedArenas fArenas; |
208 | |
209 | std::unique_ptr<GrDrawingManager> fDrawingManager; |
210 | |
211 | std::unique_ptr<GrAuditTrail> fAuditTrail; |
212 | |
213 | #ifdef GR_TEST_UTILS |
214 | int fSuppressWarningMessages = 0; |
215 | #endif |
216 | |
217 | typedef GrImageContext INHERITED; |
218 | }; |
219 | |
220 | /** |
221 | * Safely cast a possibly-null recording context to direct context. |
222 | */ |
223 | static inline GrDirectContext* GrAsDirectContext(GrRecordingContext* recording) { |
224 | return recording ? recording->asDirectContext() : nullptr; |
225 | } |
226 | |
227 | #endif |
228 | |