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/private/GrRecordingContext.h"
9
10 #include "include/gpu/GrContext.h"
11 #include "src/core/SkArenaAlloc.h"
12 #include "src/gpu/GrAuditTrail.h"
13 #include "src/gpu/GrCaps.h"
14 #include "src/gpu/GrDrawingManager.h"
15 #include "src/gpu/GrMemoryPool.h"
16 #include "src/gpu/GrProgramDesc.h"
17 #include "src/gpu/GrProxyProvider.h"
18 #include "src/gpu/GrRecordingContextPriv.h"
19 #include "src/gpu/GrRenderTargetContext.h"
20 #include "src/gpu/GrSurfaceContext.h"
21 #include "src/gpu/SkGr.h"
22 #include "src/gpu/effects/GrSkSLFP.h"
23 #include "src/gpu/text/GrTextBlobCache.h"
24
25 #define ASSERT_SINGLE_OWNER_PRIV \
26 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
27
ProgramData(std::unique_ptr<const GrProgramDesc> desc,const GrProgramInfo * info)28 GrRecordingContext::ProgramData::ProgramData(std::unique_ptr<const GrProgramDesc> desc,
29 const GrProgramInfo* info)
30 : fDesc(std::move(desc))
31 , fInfo(info) {
32 }
33
ProgramData(ProgramData && other)34 GrRecordingContext::ProgramData::ProgramData(ProgramData&& other)
35 : fDesc(std::move(other.fDesc))
36 , fInfo(other.fInfo) {
37 }
38
~ProgramData()39 GrRecordingContext::ProgramData::~ProgramData() {}
40
GrRecordingContext(GrBackendApi backend,const GrContextOptions & options,uint32_t contextID)41 GrRecordingContext::GrRecordingContext(GrBackendApi backend,
42 const GrContextOptions& options,
43 uint32_t contextID)
44 : INHERITED(backend, options, contextID)
45 , fAuditTrail(new GrAuditTrail()) {
46 }
47
~GrRecordingContext()48 GrRecordingContext::~GrRecordingContext() { }
49
50 /**
51 * TODO: move textblob draw calls below context (see comment below)
52 */
textblobcache_overbudget_CB(void * data)53 static void textblobcache_overbudget_CB(void* data) {
54 SkASSERT(data);
55 GrRecordingContext* context = reinterpret_cast<GrRecordingContext*>(data);
56
57 GrContext* direct = context->priv().asDirectContext();
58 if (!direct) {
59 return;
60 }
61
62 // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
63 // GrRenderTargetContext to perform a necessary flush. The solution is to move drawText calls
64 // to below the GrContext level, but this is not trivial because they call drawPath on
65 // SkGpuDevice.
66 direct->flush();
67 }
68
init(sk_sp<const GrCaps> caps)69 bool GrRecordingContext::init(sk_sp<const GrCaps> caps) {
70
71 if (!INHERITED::init(std::move(caps))) {
72 return false;
73 }
74
75 fStrikeCache.reset(new GrStrikeCache{});
76
77 fTextBlobCache.reset(new GrTextBlobCache(textblobcache_overbudget_CB, this,
78 this->contextID()));
79
80 return true;
81 }
82
setupDrawingManager(bool sortOpsTasks,bool reduceOpsTaskSplitting)83 void GrRecordingContext::setupDrawingManager(bool sortOpsTasks, bool reduceOpsTaskSplitting) {
84 GrPathRendererChain::Options prcOptions;
85 prcOptions.fAllowPathMaskCaching = this->options().fAllowPathMaskCaching;
86 #if GR_TEST_UTILS
87 prcOptions.fGpuPathRenderers = this->options().fGpuPathRenderers;
88 #endif
89 // FIXME: Once this is removed from Chrome and Android, rename to fEnable"".
90 if (!this->options().fDisableCoverageCountingPaths) {
91 prcOptions.fGpuPathRenderers |= GpuPathRenderers::kCoverageCounting;
92 }
93 if (this->options().fDisableDistanceFieldPaths) {
94 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
95 }
96
97 if (!this->proxyProvider()->renderingDirectly()) {
98 // DDL TODO: remove this crippling of the path renderer chain
99 // Disable the small path renderer bc of the proxies in the atlas. They need to be
100 // unified when the opsTasks are added back to the destination drawing manager.
101 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
102 }
103
104 GrTextContext::Options textContextOptions;
105 textContextOptions.fMaxDistanceFieldFontSize = this->options().fGlyphsAsPathsFontSize;
106 textContextOptions.fMinDistanceFieldFontSize = this->options().fMinDistanceFieldFontSize;
107 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = false;
108 #if SK_SUPPORT_ATLAS_TEXT
109 if (GrContextOptions::Enable::kYes == this->options().fDistanceFieldGlyphVerticesAlwaysHaveW) {
110 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = true;
111 }
112 #endif
113
114 fDrawingManager.reset(new GrDrawingManager(this,
115 prcOptions,
116 textContextOptions,
117 sortOpsTasks,
118 reduceOpsTaskSplitting));
119 }
120
abandonContext()121 void GrRecordingContext::abandonContext() {
122 INHERITED::abandonContext();
123
124 fStrikeCache->freeAll();
125 fTextBlobCache->freeAll();
126 }
127
drawingManager()128 GrDrawingManager* GrRecordingContext::drawingManager() {
129 return fDrawingManager.get();
130 }
131
Arenas(GrOpMemoryPool * opMemoryPool,SkArenaAlloc * recordTimeAllocator)132 GrRecordingContext::Arenas::Arenas(GrOpMemoryPool* opMemoryPool, SkArenaAlloc* recordTimeAllocator)
133 : fOpMemoryPool(opMemoryPool)
134 , fRecordTimeAllocator(recordTimeAllocator) {
135 // OwnedArenas should instantiate these before passing the bare pointer off to this struct.
136 SkASSERT(opMemoryPool);
137 SkASSERT(recordTimeAllocator);
138 }
139
140 // Must be defined here so that std::unique_ptr can see the sizes of the various pools, otherwise
141 // it can't generate a default destructor for them.
OwnedArenas()142 GrRecordingContext::OwnedArenas::OwnedArenas() {}
~OwnedArenas()143 GrRecordingContext::OwnedArenas::~OwnedArenas() {}
144
operator =(OwnedArenas && a)145 GrRecordingContext::OwnedArenas& GrRecordingContext::OwnedArenas::operator=(OwnedArenas&& a) {
146 fOpMemoryPool = std::move(a.fOpMemoryPool);
147 fRecordTimeAllocator = std::move(a.fRecordTimeAllocator);
148 return *this;
149 }
150
get()151 GrRecordingContext::Arenas GrRecordingContext::OwnedArenas::get() {
152 if (!fOpMemoryPool) {
153 // DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory
154 // consumed in DDL mode vs. normal mode for a single skp might be a good metric of wasted
155 // memory.
156 fOpMemoryPool = GrOpMemoryPool::Make(16384, 16384);
157 }
158
159 if (!fRecordTimeAllocator) {
160 // TODO: empirically determine a better number for SkArenaAlloc's firstHeapAllocation param
161 fRecordTimeAllocator = std::make_unique<SkArenaAlloc>(sizeof(GrPipeline) * 100);
162 }
163
164 return {fOpMemoryPool.get(), fRecordTimeAllocator.get()};
165 }
166
detachArenas()167 GrRecordingContext::OwnedArenas&& GrRecordingContext::detachArenas() {
168 return std::move(fArenas);
169 }
170
getTextBlobCache()171 GrTextBlobCache* GrRecordingContext::getTextBlobCache() {
172 return fTextBlobCache.get();
173 }
174
getTextBlobCache() const175 const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const {
176 return fTextBlobCache.get();
177 }
178
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)179 void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
180 this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
181 }
182
183 ///////////////////////////////////////////////////////////////////////////////////////////////////
refCaps() const184 sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const {
185 return fContext->refCaps();
186 }
187
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)188 void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
189 fContext->addOnFlushCallbackObject(onFlushCBObject);
190 }
191
backdoor()192 GrContext* GrRecordingContextPriv::backdoor() {
193 return (GrContext*) fContext;
194 }
195
196