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 "src/gpu/GrDirectContextPriv.h"
9
10 #include "include/gpu/GrContextThreadSafeProxy.h"
11 #include "include/gpu/GrDirectContext.h"
12 #include "src/gpu/GrAuditTrail.h"
13 #include "src/gpu/GrContextThreadSafeProxyPriv.h"
14 #include "src/gpu/GrDrawingManager.h"
15 #include "src/gpu/GrGpu.h"
16 #include "src/gpu/GrMemoryPool.h"
17 #include "src/gpu/GrSurfaceContext.h"
18 #include "src/gpu/GrSurfaceDrawContext.h"
19 #include "src/gpu/GrTexture.h"
20 #include "src/gpu/GrThreadSafePipelineBuilder.h"
21 #include "src/gpu/SkGr.h"
22 #include "src/gpu/effects/GrSkSLFP.h"
23 #include "src/gpu/effects/generated/GrConfigConversionEffect.h"
24 #include "src/gpu/text/GrAtlasManager.h"
25 #include "src/gpu/text/GrTextBlobCache.h"
26 #include "src/image/SkImage_Base.h"
27 #include "src/image/SkImage_Gpu.h"
28
29 #define ASSERT_OWNED_PROXY(P) \
30 SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == fContext)
31 #define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(fContext->singleOwner())
32 #define RETURN_VALUE_IF_ABANDONED(value) if (fContext->abandoned()) { return (value); }
33
refCaps() const34 sk_sp<const GrCaps> GrDirectContextPriv::refCaps() const {
35 return fContext->refCaps();
36 }
37
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)38 void GrDirectContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
39 fContext->addOnFlushCallbackObject(onFlushCBObject);
40 }
41
flushSurfaces(SkSpan<GrSurfaceProxy * > proxies,SkSurface::BackendSurfaceAccess access,const GrFlushInfo & info,const GrBackendSurfaceMutableState * newState)42 GrSemaphoresSubmitted GrDirectContextPriv::flushSurfaces(
43 SkSpan<GrSurfaceProxy*> proxies,
44 SkSurface::BackendSurfaceAccess access,
45 const GrFlushInfo& info,
46 const GrBackendSurfaceMutableState* newState) {
47 ASSERT_SINGLE_OWNER
48 GR_CREATE_TRACE_MARKER_CONTEXT("GrDirectContextPriv", "flushSurfaces", fContext);
49
50 if (fContext->abandoned()) {
51 if (info.fSubmittedProc) {
52 info.fSubmittedProc(info.fSubmittedContext, false);
53 }
54 if (info.fFinishedProc) {
55 info.fFinishedProc(info.fFinishedContext);
56 }
57 return GrSemaphoresSubmitted::kNo;
58 }
59
60 #ifdef SK_DEBUG
61 for (GrSurfaceProxy* proxy : proxies) {
62 SkASSERT(proxy);
63 ASSERT_OWNED_PROXY(proxy);
64 }
65 #endif
66 return fContext->drawingManager()->flushSurfaces(proxies, access, info, newState);
67 }
68
createDDLTask(sk_sp<const SkDeferredDisplayList> ddl,sk_sp<GrRenderTargetProxy> newDest,SkIPoint offset)69 void GrDirectContextPriv::createDDLTask(sk_sp<const SkDeferredDisplayList> ddl,
70 sk_sp<GrRenderTargetProxy> newDest,
71 SkIPoint offset) {
72 fContext->drawingManager()->createDDLTask(std::move(ddl), std::move(newDest), offset);
73 }
74
compile(const GrProgramDesc & desc,const GrProgramInfo & info)75 bool GrDirectContextPriv::compile(const GrProgramDesc& desc, const GrProgramInfo& info) {
76 GrGpu* gpu = this->getGpu();
77 if (!gpu) {
78 return false;
79 }
80
81 return gpu->compile(desc, info);
82 }
83
84
85 //////////////////////////////////////////////////////////////////////////////
86 #if GR_TEST_UTILS
87
dumpCacheStats(SkString * out) const88 void GrDirectContextPriv::dumpCacheStats(SkString* out) const {
89 #if GR_CACHE_STATS
90 fContext->fResourceCache->dumpStats(out);
91 #endif
92 }
93
dumpCacheStatsKeyValuePairs(SkTArray<SkString> * keys,SkTArray<double> * values) const94 void GrDirectContextPriv::dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys,
95 SkTArray<double>* values) const {
96 #if GR_CACHE_STATS
97 fContext->fResourceCache->dumpStatsKeyValuePairs(keys, values);
98 #endif
99 }
100
printCacheStats() const101 void GrDirectContextPriv::printCacheStats() const {
102 SkString out;
103 this->dumpCacheStats(&out);
104 SkDebugf("%s", out.c_str());
105 }
106
107 /////////////////////////////////////////////////
resetGpuStats() const108 void GrDirectContextPriv::resetGpuStats() const {
109 #if GR_GPU_STATS
110 fContext->fGpu->stats()->reset();
111 #endif
112 }
113
dumpGpuStats(SkString * out) const114 void GrDirectContextPriv::dumpGpuStats(SkString* out) const {
115 #if GR_GPU_STATS
116 fContext->fGpu->stats()->dump(out);
117 if (auto builder = fContext->fGpu->pipelineBuilder()) {
118 builder->stats()->dump(out);
119 }
120 #endif
121 }
122
dumpGpuStatsKeyValuePairs(SkTArray<SkString> * keys,SkTArray<double> * values) const123 void GrDirectContextPriv::dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys,
124 SkTArray<double>* values) const {
125 #if GR_GPU_STATS
126 fContext->fGpu->stats()->dumpKeyValuePairs(keys, values);
127 if (auto builder = fContext->fGpu->pipelineBuilder()) {
128 builder->stats()->dumpKeyValuePairs(keys, values);
129 }
130 #endif
131 }
132
printGpuStats() const133 void GrDirectContextPriv::printGpuStats() const {
134 SkString out;
135 this->dumpGpuStats(&out);
136 SkDebugf("%s", out.c_str());
137 }
138
139 /////////////////////////////////////////////////
resetContextStats() const140 void GrDirectContextPriv::resetContextStats() const {
141 #if GR_GPU_STATS
142 fContext->stats()->reset();
143 #endif
144 }
145
dumpContextStats(SkString * out) const146 void GrDirectContextPriv::dumpContextStats(SkString* out) const {
147 #if GR_GPU_STATS
148 return fContext->stats()->dump(out);
149 #endif
150 }
151
dumpContextStatsKeyValuePairs(SkTArray<SkString> * keys,SkTArray<double> * values) const152 void GrDirectContextPriv::dumpContextStatsKeyValuePairs(SkTArray<SkString>* keys,
153 SkTArray<double>* values) const {
154 #if GR_GPU_STATS
155 return fContext->stats()->dumpKeyValuePairs(keys, values);
156 #endif
157 }
158
printContextStats() const159 void GrDirectContextPriv::printContextStats() const {
160 SkString out;
161 this->dumpContextStats(&out);
162 SkDebugf("%s", out.c_str());
163 }
164
165 /////////////////////////////////////////////////
testingOnly_getFontAtlasImage(GrMaskFormat format,unsigned int index)166 sk_sp<SkImage> GrDirectContextPriv::testingOnly_getFontAtlasImage(GrMaskFormat format,
167 unsigned int index) {
168 auto atlasManager = this->getAtlasManager();
169 if (!atlasManager) {
170 return nullptr;
171 }
172
173 unsigned int numActiveProxies;
174 const GrSurfaceProxyView* views = atlasManager->getViews(format, &numActiveProxies);
175 if (index >= numActiveProxies || !views || !views[index].proxy()) {
176 return nullptr;
177 }
178
179 SkColorType colorType = GrColorTypeToSkColorType(GrMaskFormatToColorType(format));
180 SkASSERT(views[index].proxy()->priv().isExact());
181 return sk_make_sp<SkImage_Gpu>(sk_ref_sp(fContext),
182 kNeedNewImageUniqueID,
183 views[index],
184 SkColorInfo(colorType, kPremul_SkAlphaType, nullptr));
185 }
186
testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject * cb)187 void GrDirectContextPriv::testingOnly_flushAndRemoveOnFlushCallbackObject(
188 GrOnFlushCallbackObject* cb) {
189 fContext->flushAndSubmit();
190 fContext->drawingManager()->testingOnly_removeOnFlushCallbackObject(cb);
191 }
192 #endif
193
validPMUPMConversionExists()194 bool GrDirectContextPriv::validPMUPMConversionExists() {
195 ASSERT_SINGLE_OWNER
196
197 if (!fContext->fDidTestPMConversions) {
198 fContext->fPMUPMConversionsRoundTrip =
199 GrConfigConversionEffect::TestForPreservingPMConversions(fContext);
200 fContext->fDidTestPMConversions = true;
201 }
202
203 // The PM<->UPM tests fail or succeed together so we only need to check one.
204 return fContext->fPMUPMConversionsRoundTrip;
205 }
206
createPMToUPMEffect(std::unique_ptr<GrFragmentProcessor> fp)207 std::unique_ptr<GrFragmentProcessor> GrDirectContextPriv::createPMToUPMEffect(
208 std::unique_ptr<GrFragmentProcessor> fp) {
209 ASSERT_SINGLE_OWNER
210 // We should have already called this->priv().validPMUPMConversionExists() in this case
211 SkASSERT(fContext->fDidTestPMConversions);
212 // ...and it should have succeeded
213 SkASSERT(this->validPMUPMConversionExists());
214
215 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToUnpremul);
216 }
217
createUPMToPMEffect(std::unique_ptr<GrFragmentProcessor> fp)218 std::unique_ptr<GrFragmentProcessor> GrDirectContextPriv::createUPMToPMEffect(
219 std::unique_ptr<GrFragmentProcessor> fp) {
220 ASSERT_SINGLE_OWNER
221 // We should have already called this->priv().validPMUPMConversionExists() in this case
222 SkASSERT(fContext->fDidTestPMConversions);
223 // ...and it should have succeeded
224 SkASSERT(this->validPMUPMConversionExists());
225
226 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToPremul);
227 }
228