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
15class GrAuditTrail;
16class GrBackendFormat;
17class GrDrawingManager;
18class GrOnFlushCallbackObject;
19class GrOpMemoryPool;
20class GrProgramDesc;
21class GrProgramInfo;
22class GrRecordingContextPriv;
23class GrSurfaceContext;
24class GrSurfaceProxy;
25class GrTextBlobCache;
26class SkArenaAlloc;
27class SkJSONWriter;
28
29class GrRecordingContext : public GrImageContext {
30public:
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
90protected:
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
206private:
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 */
223static inline GrDirectContext* GrAsDirectContext(GrRecordingContext* recording) {
224 return recording ? recording->asDirectContext() : nullptr;
225}
226
227#endif
228