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
26GrRecordingContext::ProgramData::ProgramData(std::unique_ptr<const GrProgramDesc> desc,
27 const GrProgramInfo* info)
28 : fDesc(std::move(desc))
29 , fInfo(info) {
30}
31
32GrRecordingContext::ProgramData::ProgramData(ProgramData&& other)
33 : fDesc(std::move(other.fDesc))
34 , fInfo(other.fInfo) {
35}
36
37GrRecordingContext::ProgramData::~ProgramData() = default;
38
39GrRecordingContext::GrRecordingContext(sk_sp<GrContextThreadSafeProxy> proxy)
40 : INHERITED(std::move(proxy))
41 , fAuditTrail(new GrAuditTrail()) {
42}
43
44GrRecordingContext::~GrRecordingContext() = default;
45
46int 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
53void 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
73void GrRecordingContext::abandonContext() {
74 INHERITED::abandonContext();
75
76 this->destroyDrawingManager();
77}
78
79GrDrawingManager* GrRecordingContext::drawingManager() {
80 return fDrawingManager.get();
81}
82
83void GrRecordingContext::destroyDrawingManager() {
84 fDrawingManager.reset();
85}
86
87GrRecordingContext::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.
97GrRecordingContext::OwnedArenas::OwnedArenas() {}
98GrRecordingContext::OwnedArenas::~OwnedArenas() {}
99
100GrRecordingContext::OwnedArenas& GrRecordingContext::OwnedArenas::operator=(OwnedArenas&& a) {
101 fOpMemoryPool = std::move(a.fOpMemoryPool);
102 fRecordTimeAllocator = std::move(a.fRecordTimeAllocator);
103 return *this;
104}
105
106GrRecordingContext::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
122GrRecordingContext::OwnedArenas&& GrRecordingContext::detachArenas() {
123 return std::move(fArenas);
124}
125
126GrTextBlobCache* GrRecordingContext::getTextBlobCache() {
127 return fThreadSafeProxy->priv().getTextBlobCache();
128}
129
130const GrTextBlobCache* GrRecordingContext::getTextBlobCache() const {
131 return fThreadSafeProxy->priv().getTextBlobCache();
132}
133
134void GrRecordingContext::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
135 this->drawingManager()->addOnFlushCallbackObject(onFlushCBObject);
136}
137
138///////////////////////////////////////////////////////////////////////////////////////////////////
139sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const {
140 return fContext->refCaps();
141}
142
143void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
144 fContext->addOnFlushCallbackObject(onFlushCBObject);
145}
146
147GrContext* GrRecordingContextPriv::backdoor() {
148 return (GrContext*) fContext;
149}
150
151///////////////////////////////////////////////////////////////////////////////////////////////////
152
153#ifdef SK_ENABLE_DUMP_GPU
154#include "src/utils/SkJSONWriter.h"
155
156void 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
167void GrRecordingContext::dumpJSON(SkJSONWriter*) const { }
168#endif
169
170#if GR_TEST_UTILS
171
172#if GR_GPU_STATS
173
174void 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
179void 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