• 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 #include "include/gpu/GrRecordingContext.h"
9 
10 #include "include/core/SkCapabilities.h"
11 #include "include/core/SkTypes.h"
12 #include "include/gpu/GrContextThreadSafeProxy.h"
13 #include "src/base/SkArenaAlloc.h"
14 #include "src/gpu/ganesh/GrAuditTrail.h"
15 #include "src/gpu/ganesh/GrCaps.h"
16 #include "src/gpu/ganesh/GrContextThreadSafeProxyPriv.h"
17 #include "src/gpu/ganesh/GrDrawingManager.h"
18 #include "src/gpu/ganesh/GrMemoryPool.h"
19 #include "src/gpu/ganesh/GrProgramDesc.h"
20 #include "src/gpu/ganesh/GrProxyProvider.h"
21 #include "src/gpu/ganesh/GrRecordingContextPriv.h"
22 #include "src/gpu/ganesh/SkGr.h"
23 #include "src/gpu/ganesh/SurfaceContext.h"
24 #include "src/gpu/ganesh/effects/GrSkSLFP.h"
25 #include "src/gpu/ganesh/ops/AtlasTextOp.h"
26 #include "src/text/gpu/TextBlob.h"
27 #include "src/text/gpu/TextBlobRedrawCoordinator.h"
28 
29 
30 using TextBlobRedrawCoordinator = sktext::gpu::TextBlobRedrawCoordinator;
31 
ProgramData(std::unique_ptr<const GrProgramDesc> desc,const GrProgramInfo * info)32 GrRecordingContext::ProgramData::ProgramData(std::unique_ptr<const GrProgramDesc> desc,
33                                              const GrProgramInfo* info)
34         : fDesc(std::move(desc))
35         , fInfo(info) {
36 }
37 
ProgramData(ProgramData && other)38 GrRecordingContext::ProgramData::ProgramData(ProgramData&& other)
39         : fDesc(std::move(other.fDesc))
40         , fInfo(other.fInfo) {
41 }
42 
43 GrRecordingContext::ProgramData::~ProgramData() = default;
44 
GrRecordingContext(sk_sp<GrContextThreadSafeProxy> proxy,bool ddlRecording)45 GrRecordingContext::GrRecordingContext(sk_sp<GrContextThreadSafeProxy> proxy, bool ddlRecording)
46         : INHERITED(std::move(proxy))
47         , fAuditTrail(new GrAuditTrail())
48         , fArenas(ddlRecording) {
49     fProxyProvider = std::make_unique<GrProxyProvider>(this);
50 }
51 
~GrRecordingContext()52 GrRecordingContext::~GrRecordingContext() {
53     skgpu::ganesh::AtlasTextOp::ClearCache();
54 }
55 
init()56 bool GrRecordingContext::init() {
57     if (!INHERITED::init()) {
58         return false;
59     }
60 
61     skgpu::v1::PathRendererChain::Options prcOptions;
62     prcOptions.fAllowPathMaskCaching = this->options().fAllowPathMaskCaching;
63 #if GR_TEST_UTILS
64     prcOptions.fGpuPathRenderers = this->options().fGpuPathRenderers;
65 #endif
66     // FIXME: Once this is removed from Chrome and Android, rename to fEnable"".
67     if (this->options().fDisableDistanceFieldPaths) {
68         prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
69     }
70 
71     bool reduceOpsTaskSplitting = true;
72     if (this->caps()->avoidReorderingRenderTasks()) {
73         reduceOpsTaskSplitting = false;
74     } else if (GrContextOptions::Enable::kYes == this->options().fReduceOpsTaskSplitting) {
75         reduceOpsTaskSplitting = true;
76     } else if (GrContextOptions::Enable::kNo == this->options().fReduceOpsTaskSplitting) {
77         reduceOpsTaskSplitting = false;
78     }
79     fDrawingManager.reset(new GrDrawingManager(this,
80                                                prcOptions,
81                                                reduceOpsTaskSplitting));
82     return true;
83 }
84 
abandonContext()85 void GrRecordingContext::abandonContext() {
86     INHERITED::abandonContext();
87 
88     this->destroyDrawingManager();
89 }
90 
drawingManager()91 GrDrawingManager* GrRecordingContext::drawingManager() {
92     return fDrawingManager.get();
93 }
94 
destroyDrawingManager()95 void GrRecordingContext::destroyDrawingManager() {
96     fDrawingManager.reset();
97 }
98 
Arenas(SkArenaAlloc * recordTimeAllocator,sktext::gpu::SubRunAllocator * subRunAllocator)99 GrRecordingContext::Arenas::Arenas(SkArenaAlloc* recordTimeAllocator,
100                                    sktext::gpu::SubRunAllocator* subRunAllocator)
101         : fRecordTimeAllocator(recordTimeAllocator)
102         , fRecordTimeSubRunAllocator(subRunAllocator) {
103     // OwnedArenas should instantiate these before passing the bare pointer off to this struct.
104     SkASSERT(subRunAllocator);
105 }
106 
107 // Must be defined here so that std::unique_ptr can see the sizes of the various pools, otherwise
108 // it can't generate a default destructor for them.
OwnedArenas(bool ddlRecording)109 GrRecordingContext::OwnedArenas::OwnedArenas(bool ddlRecording) : fDDLRecording(ddlRecording) {}
~OwnedArenas()110 GrRecordingContext::OwnedArenas::~OwnedArenas() {}
111 
operator =(OwnedArenas && a)112 GrRecordingContext::OwnedArenas& GrRecordingContext::OwnedArenas::operator=(OwnedArenas&& a) {
113     fDDLRecording = a.fDDLRecording;
114     fRecordTimeAllocator = std::move(a.fRecordTimeAllocator);
115     fRecordTimeSubRunAllocator = std::move(a.fRecordTimeSubRunAllocator);
116     return *this;
117 }
118 
get()119 GrRecordingContext::Arenas GrRecordingContext::OwnedArenas::get() {
120     if (!fRecordTimeAllocator && fDDLRecording) {
121         // TODO: empirically determine a better number for SkArenaAlloc's firstHeapAllocation param
122         fRecordTimeAllocator = std::make_unique<SkArenaAlloc>(1024);
123     }
124 
125     if (!fRecordTimeSubRunAllocator) {
126         fRecordTimeSubRunAllocator = std::make_unique<sktext::gpu::SubRunAllocator>();
127     }
128 
129     return {fRecordTimeAllocator.get(), fRecordTimeSubRunAllocator.get()};
130 }
131 
detachArenas()132 GrRecordingContext::OwnedArenas&& GrRecordingContext::detachArenas() {
133     return std::move(fArenas);
134 }
135 
getTextBlobRedrawCoordinator()136 TextBlobRedrawCoordinator* GrRecordingContext::getTextBlobRedrawCoordinator() {
137     return fThreadSafeProxy->priv().getTextBlobRedrawCoordinator();
138 }
139 
getTextBlobRedrawCoordinator() const140 const TextBlobRedrawCoordinator* GrRecordingContext::getTextBlobRedrawCoordinator() const {
141     return fThreadSafeProxy->priv().getTextBlobRedrawCoordinator();
142 }
143 
threadSafeCache()144 GrThreadSafeCache* GrRecordingContext::threadSafeCache() {
145     return fThreadSafeProxy->priv().threadSafeCache();
146 }
147 
threadSafeCache() const148 const GrThreadSafeCache* GrRecordingContext::threadSafeCache() const {
149     return fThreadSafeProxy->priv().threadSafeCache();
150 }
151 
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)152 void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
153     this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
154 }
155 
156 ////////////////////////////////////////////////////////////////////////////////
157 
skCapabilities() const158 sk_sp<const SkCapabilities> GrRecordingContext::skCapabilities() const {
159     return this->refCaps();
160 }
161 
maxTextureSize() const162 int GrRecordingContext::maxTextureSize() const { return this->caps()->maxTextureSize(); }
163 
maxRenderTargetSize() const164 int GrRecordingContext::maxRenderTargetSize() const { return this->caps()->maxRenderTargetSize(); }
165 
colorTypeSupportedAsImage(SkColorType colorType) const166 bool GrRecordingContext::colorTypeSupportedAsImage(SkColorType colorType) const {
167     GrBackendFormat format =
168             this->caps()->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
169                                                   GrRenderable::kNo);
170     return format.isValid();
171 }
172 
173 ///////////////////////////////////////////////////////////////////////////////////////////////////
174 
175 #ifdef SK_ENABLE_DUMP_GPU
176 #include "src/utils/SkJSONWriter.h"
177 
dumpJSON(SkJSONWriter * writer) const178 void GrRecordingContext::dumpJSON(SkJSONWriter* writer) const {
179     writer->beginObject();
180 
181 #if GR_GPU_STATS
182     writer->appendS32("path_masks_generated", this->stats()->numPathMasksGenerated());
183     writer->appendS32("path_mask_cache_hits", this->stats()->numPathMaskCacheHits());
184 #endif
185 
186     writer->endObject();
187 }
188 #else
dumpJSON(SkJSONWriter *) const189 void GrRecordingContext::dumpJSON(SkJSONWriter*) const { }
190 #endif
191 
192 #if GR_TEST_UTILS
193 
194 #if GR_GPU_STATS
195 
dump(SkString * out) const196 void GrRecordingContext::Stats::dump(SkString* out) const {
197     out->appendf("Num Path Masks Generated: %d\n", fNumPathMasksGenerated);
198     out->appendf("Num Path Mask Cache Hits: %d\n", fNumPathMaskCacheHits);
199 }
200 
dumpKeyValuePairs(SkTArray<SkString> * keys,SkTArray<double> * values) const201 void GrRecordingContext::Stats::dumpKeyValuePairs(SkTArray<SkString>* keys,
202                                                   SkTArray<double>* values) const {
203     keys->push_back(SkString("path_masks_generated"));
204     values->push_back(fNumPathMasksGenerated);
205 
206     keys->push_back(SkString("path_mask_cache_hits"));
207     values->push_back(fNumPathMaskCacheHits);
208 }
209 
dumpKeyValuePairs(SkTArray<SkString> * keys,SkTArray<double> * values) const210 void GrRecordingContext::DMSAAStats::dumpKeyValuePairs(SkTArray<SkString>* keys,
211                                                        SkTArray<double>* values) const {
212     keys->push_back(SkString("dmsaa_render_passes"));
213     values->push_back(fNumRenderPasses);
214 
215     keys->push_back(SkString("dmsaa_multisample_render_passes"));
216     values->push_back(fNumMultisampleRenderPasses);
217 
218     for (const auto& [name, count] : fTriggerCounts) {
219         keys->push_back(SkStringPrintf("dmsaa_trigger_%s", name.c_str()));
220         values->push_back(count);
221     }
222 }
223 
dump() const224 void GrRecordingContext::DMSAAStats::dump() const {
225     SkDebugf("DMSAA Render Passes: %d\n", fNumRenderPasses);
226     SkDebugf("DMSAA Multisample Render Passes: %d\n", fNumMultisampleRenderPasses);
227     if (!fTriggerCounts.empty()) {
228         SkDebugf("DMSAA Triggers:\n");
229         for (const auto& [name, count] : fTriggerCounts) {
230             SkDebugf("    %s: %d\n", name.c_str(), count);
231         }
232     }
233 }
234 
merge(const DMSAAStats & stats)235 void GrRecordingContext::DMSAAStats::merge(const DMSAAStats& stats) {
236     fNumRenderPasses += stats.fNumRenderPasses;
237     fNumMultisampleRenderPasses += stats.fNumMultisampleRenderPasses;
238     for (const auto& [name, count] : stats.fTriggerCounts) {
239         fTriggerCounts[name] += count;
240     }
241 }
242 
243 #endif // GR_GPU_STATS
244 #endif // GR_TEST_UTILS
245