• 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/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