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