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/gpu/GrContextThreadSafeProxy.h" |
11 | #include "src/core/SkArenaAlloc.h" |
12 | #include "src/gpu/GrAuditTrail.h" |
13 | #include "src/gpu/GrCaps.h" |
14 | #include "src/gpu/GrContextThreadSafeProxyPriv.h" |
15 | #include "src/gpu/GrDrawingManager.h" |
16 | #include "src/gpu/GrMemoryPool.h" |
17 | #include "src/gpu/GrProgramDesc.h" |
18 | #include "src/gpu/GrProxyProvider.h" |
19 | #include "src/gpu/GrRecordingContextPriv.h" |
20 | #include "src/gpu/GrRenderTargetContext.h" |
21 | #include "src/gpu/GrSurfaceContext.h" |
22 | #include "src/gpu/SkGr.h" |
23 | #include "src/gpu/effects/GrSkSLFP.h" |
24 | #include "src/gpu/text/GrTextBlobCache.h" |
25 | |
26 | GrRecordingContext::ProgramData::ProgramData(std::unique_ptr<const GrProgramDesc> desc, |
27 | const GrProgramInfo* info) |
28 | : fDesc(std::move(desc)) |
29 | , fInfo(info) { |
30 | } |
31 | |
32 | GrRecordingContext::ProgramData::ProgramData(ProgramData&& other) |
33 | : fDesc(std::move(other.fDesc)) |
34 | , fInfo(other.fInfo) { |
35 | } |
36 | |
37 | GrRecordingContext::ProgramData::~ProgramData() = default; |
38 | |
39 | GrRecordingContext::GrRecordingContext(sk_sp<GrContextThreadSafeProxy> proxy) |
40 | : INHERITED(std::move(proxy)) |
41 | , fAuditTrail(new GrAuditTrail()) { |
42 | } |
43 | |
44 | GrRecordingContext::~GrRecordingContext() = default; |
45 | |
46 | int GrRecordingContext::maxSurfaceSampleCountForColorType(SkColorType colorType) const { |
47 | GrBackendFormat format = |
48 | this->caps()->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType), |
49 | GrRenderable::kYes); |
50 | return this->caps()->maxRenderTargetSampleCount(format); |
51 | } |
52 | |
53 | void GrRecordingContext::setupDrawingManager(bool sortOpsTasks, bool reduceOpsTaskSplitting) { |
54 | GrPathRendererChain::Options prcOptions; |
55 | prcOptions.fAllowPathMaskCaching = this->options().fAllowPathMaskCaching; |
56 | #if GR_TEST_UTILS |
57 | prcOptions.fGpuPathRenderers = this->options().fGpuPathRenderers; |
58 | #endif |
59 | // FIXME: Once this is removed from Chrome and Android, rename to fEnable"". |
60 | if (!this->options().fDisableCoverageCountingPaths) { |
61 | prcOptions.fGpuPathRenderers |= GpuPathRenderers::kCoverageCounting; |
62 | } |
63 | if (this->options().fDisableDistanceFieldPaths) { |
64 | prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall; |
65 | } |
66 | |
67 | fDrawingManager.reset(new GrDrawingManager(this, |
68 | prcOptions, |
69 | sortOpsTasks, |
70 | reduceOpsTaskSplitting)); |
71 | } |
72 | |
73 | void GrRecordingContext::abandonContext() { |
74 | INHERITED::abandonContext(); |
75 | |
76 | this->destroyDrawingManager(); |
77 | } |
78 | |
79 | GrDrawingManager* GrRecordingContext::drawingManager() { |
80 | return fDrawingManager.get(); |
81 | } |
82 | |
83 | void GrRecordingContext::destroyDrawingManager() { |
84 | fDrawingManager.reset(); |
85 | } |
86 | |
87 | GrRecordingContext::Arenas::Arenas(GrOpMemoryPool* opMemoryPool, SkArenaAlloc* recordTimeAllocator) |
88 | : fOpMemoryPool(opMemoryPool) |
89 | , fRecordTimeAllocator(recordTimeAllocator) { |
90 | // OwnedArenas should instantiate these before passing the bare pointer off to this struct. |
91 | SkASSERT(opMemoryPool); |
92 | SkASSERT(recordTimeAllocator); |
93 | } |
94 | |
95 | // Must be defined here so that std::unique_ptr can see the sizes of the various pools, otherwise |
96 | // it can't generate a default destructor for them. |
97 | GrRecordingContext::OwnedArenas::OwnedArenas() {} |
98 | GrRecordingContext::OwnedArenas::~OwnedArenas() {} |
99 | |
100 | GrRecordingContext::OwnedArenas& GrRecordingContext::OwnedArenas::operator=(OwnedArenas&& a) { |
101 | fOpMemoryPool = std::move(a.fOpMemoryPool); |
102 | fRecordTimeAllocator = std::move(a.fRecordTimeAllocator); |
103 | return *this; |
104 | } |
105 | |
106 | GrRecordingContext::Arenas GrRecordingContext::OwnedArenas::get() { |
107 | if (!fOpMemoryPool) { |
108 | // DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory |
109 | // consumed in DDL mode vs. normal mode for a single skp might be a good metric of wasted |
110 | // memory. |
111 | fOpMemoryPool = GrOpMemoryPool::Make(16384, 16384); |
112 | } |
113 | |
114 | if (!fRecordTimeAllocator) { |
115 | // TODO: empirically determine a better number for SkArenaAlloc's firstHeapAllocation param |
116 | fRecordTimeAllocator = std::make_unique<SkArenaAlloc>(sizeof(GrPipeline) * 100); |
117 | } |
118 | |
119 | return {fOpMemoryPool.get(), fRecordTimeAllocator.get()}; |
120 | } |
121 | |
122 | GrRecordingContext::OwnedArenas&& GrRecordingContext::detachArenas() { |
123 | return std::move(fArenas); |
124 | } |
125 | |
126 | GrTextBlobCache* GrRecordingContext::getTextBlobCache() { |
127 | return fThreadSafeProxy->priv().getTextBlobCache(); |
128 | } |
129 | |
130 | const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const { |
131 | return fThreadSafeProxy->priv().getTextBlobCache(); |
132 | } |
133 | |
134 | void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) { |
135 | this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject); |
136 | } |
137 | |
138 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
139 | sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const { |
140 | return fContext->refCaps(); |
141 | } |
142 | |
143 | void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) { |
144 | fContext->addOnFlushCallbackObject(onFlushCBObject); |
145 | } |
146 | |
147 | GrContext* GrRecordingContextPriv::backdoor() { |
148 | return (GrContext*) fContext; |
149 | } |
150 | |
151 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
152 | |
153 | #ifdef SK_ENABLE_DUMP_GPU |
154 | #include "src/utils/SkJSONWriter.h" |
155 | |
156 | void GrRecordingContext::dumpJSON(SkJSONWriter* writer) const { |
157 | writer->beginObject(); |
158 | |
159 | #if GR_GPU_STATS |
160 | writer->appendS32("path_masks_generated" , this->stats()->numPathMasksGenerated()); |
161 | writer->appendS32("path_mask_cache_hits" , this->stats()->numPathMaskCacheHits()); |
162 | #endif |
163 | |
164 | writer->endObject(); |
165 | } |
166 | #else |
167 | void GrRecordingContext::dumpJSON(SkJSONWriter*) const { } |
168 | #endif |
169 | |
170 | #if GR_TEST_UTILS |
171 | |
172 | #if GR_GPU_STATS |
173 | |
174 | void GrRecordingContext::Stats::dump(SkString* out) { |
175 | out->appendf("Num Path Masks Generated: %d\n" , fNumPathMasksGenerated); |
176 | out->appendf("Num Path Mask Cache Hits: %d\n" , fNumPathMaskCacheHits); |
177 | } |
178 | |
179 | void GrRecordingContext::Stats::dumpKeyValuePairs(SkTArray<SkString>* keys, |
180 | SkTArray<double>* values) { |
181 | keys->push_back(SkString("path_masks_generated" )); |
182 | values->push_back(fNumPathMasksGenerated); |
183 | |
184 | keys->push_back(SkString("path_mask_cache_hits" )); |
185 | values->push_back(fNumPathMaskCacheHits); |
186 | } |
187 | |
188 | #endif // GR_GPU_STATS |
189 | #endif // GR_TEST_UTILS |
190 | |
191 | |