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/GrContextPriv.h"
9
10 #include "include/gpu/GrContextThreadSafeProxy.h"
11 #include "include/gpu/GrTexture.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/GrRenderTargetContext.h"
18 #include "src/gpu/GrSkSLFPFactoryCache.h"
19 #include "src/gpu/GrSurfaceContextPriv.h"
20 #include "src/gpu/GrSurfacePriv.h"
21 #include "src/gpu/GrTextureContext.h"
22 #include "src/gpu/SkGr.h"
23 #include "src/gpu/effects/generated/GrConfigConversionEffect.h"
24 #include "src/gpu/text/GrTextBlobCache.h"
25 #include "src/image/SkImage_Base.h"
26 #include "src/image/SkImage_Gpu.h"
27
28 #define ASSERT_OWNED_PROXY(P) \
29 SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == fContext)
30 #define ASSERT_SINGLE_OWNER \
31 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fContext->singleOwner());)
32 #define RETURN_VALUE_IF_ABANDONED(value) if (fContext->abandoned()) { return (value); }
33 #define RETURN_IF_ABANDONED RETURN_VALUE_IF_ABANDONED(void)
34
refCaps() const35 sk_sp<const GrCaps> GrContextPriv::refCaps() const {
36 return fContext->refCaps();
37 }
38
fpFactoryCache()39 sk_sp<GrSkSLFPFactoryCache> GrContextPriv::fpFactoryCache() {
40 return fContext->fpFactoryCache();
41 }
42
refOpMemoryPool()43 sk_sp<GrOpMemoryPool> GrContextPriv::refOpMemoryPool() {
44 return fContext->refOpMemoryPool();
45 }
46
addOnFlushCallbackObject(GrOnFlushCallbackObject * onFlushCBObject)47 void GrContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
48 fContext->addOnFlushCallbackObject(onFlushCBObject);
49 }
50
makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)51 std::unique_ptr<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(
52 sk_sp<GrSurfaceProxy> proxy,
53 GrColorType colorType,
54 SkAlphaType alphaType,
55 sk_sp<SkColorSpace> colorSpace,
56 const SkSurfaceProps* props) {
57 return fContext->makeWrappedSurfaceContext(std::move(proxy), colorType, alphaType,
58 std::move(colorSpace), props);
59 }
60
makeDeferredTextureContext(SkBackingFit fit,int width,int height,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace,GrMipMapped mipMapped,GrSurfaceOrigin origin,SkBudgeted budgeted,GrProtected isProtected)61 std::unique_ptr<GrTextureContext> GrContextPriv::makeDeferredTextureContext(
62 SkBackingFit fit,
63 int width,
64 int height,
65 GrColorType colorType,
66 SkAlphaType alphaType,
67 sk_sp<SkColorSpace> colorSpace,
68 GrMipMapped mipMapped,
69 GrSurfaceOrigin origin,
70 SkBudgeted budgeted,
71 GrProtected isProtected) {
72 return fContext->makeDeferredTextureContext(fit, width, height, colorType, alphaType,
73 std::move(colorSpace), mipMapped, origin, budgeted,
74 isProtected);
75 }
76
makeDeferredRenderTargetContext(SkBackingFit fit,int width,int height,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted,GrProtected isProtected)77 std::unique_ptr<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContext(
78 SkBackingFit fit,
79 int width,
80 int height,
81 GrColorType colorType,
82 sk_sp<SkColorSpace> colorSpace,
83 int sampleCnt,
84 GrMipMapped mipMapped,
85 GrSurfaceOrigin origin,
86 const SkSurfaceProps* surfaceProps,
87 SkBudgeted budgeted,
88 GrProtected isProtected) {
89 return fContext->makeDeferredRenderTargetContext(fit, width, height, colorType,
90 std::move(colorSpace), sampleCnt, mipMapped,
91 origin, surfaceProps, budgeted, isProtected);
92 }
93
makeDeferredRenderTargetContextWithFallback(SkBackingFit fit,int width,int height,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,int sampleCnt,GrMipMapped mipMapped,GrSurfaceOrigin origin,const SkSurfaceProps * surfaceProps,SkBudgeted budgeted,GrProtected isProtected)94 std::unique_ptr<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContextWithFallback(
95 SkBackingFit fit, int width, int height, GrColorType colorType,
96 sk_sp<SkColorSpace> colorSpace, int sampleCnt, GrMipMapped mipMapped,
97 GrSurfaceOrigin origin, const SkSurfaceProps* surfaceProps, SkBudgeted budgeted,
98 GrProtected isProtected) {
99 return fContext->makeDeferredRenderTargetContextWithFallback(
100 fit, width, height, colorType, std::move(colorSpace), sampleCnt, mipMapped, origin,
101 surfaceProps, budgeted, isProtected);
102 }
103
makeBackendTextureContext(const GrBackendTexture & tex,GrSurfaceOrigin origin,GrColorType colorType,SkAlphaType alphaType,sk_sp<SkColorSpace> colorSpace)104 std::unique_ptr<GrTextureContext> GrContextPriv::makeBackendTextureContext(
105 const GrBackendTexture& tex,
106 GrSurfaceOrigin origin,
107 GrColorType colorType,
108 SkAlphaType alphaType,
109 sk_sp<SkColorSpace> colorSpace) {
110 ASSERT_SINGLE_OWNER
111
112 sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendTexture(
113 tex, colorType, origin, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType);
114 if (!proxy) {
115 return nullptr;
116 }
117
118 return this->drawingManager()->makeTextureContext(std::move(proxy), colorType, alphaType,
119 std::move(colorSpace));
120 }
121
makeBackendTextureRenderTargetContext(const GrBackendTexture & tex,GrSurfaceOrigin origin,int sampleCnt,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props,ReleaseProc releaseProc,ReleaseContext releaseCtx)122 std::unique_ptr<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
123 const GrBackendTexture& tex,
124 GrSurfaceOrigin origin,
125 int sampleCnt,
126 GrColorType colorType,
127 sk_sp<SkColorSpace> colorSpace,
128 const SkSurfaceProps* props,
129 ReleaseProc releaseProc,
130 ReleaseContext releaseCtx) {
131 ASSERT_SINGLE_OWNER
132 SkASSERT(sampleCnt > 0);
133
134 sk_sp<GrTextureProxy> proxy(this->proxyProvider()->wrapRenderableBackendTexture(
135 tex, origin, sampleCnt, colorType, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
136 releaseProc, releaseCtx));
137 if (!proxy) {
138 return nullptr;
139 }
140
141 return this->drawingManager()->makeRenderTargetContext(std::move(proxy), colorType,
142 std::move(colorSpace), props);
143 }
144
makeBackendRenderTargetRenderTargetContext(const GrBackendRenderTarget & backendRT,GrSurfaceOrigin origin,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * surfaceProps,ReleaseProc releaseProc,ReleaseContext releaseCtx)145 std::unique_ptr<GrRenderTargetContext> GrContextPriv::makeBackendRenderTargetRenderTargetContext(
146 const GrBackendRenderTarget& backendRT,
147 GrSurfaceOrigin origin,
148 GrColorType colorType,
149 sk_sp<SkColorSpace> colorSpace,
150 const SkSurfaceProps* surfaceProps,
151 ReleaseProc releaseProc,
152 ReleaseContext releaseCtx) {
153 ASSERT_SINGLE_OWNER
154
155 sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendRenderTarget(
156 backendRT, colorType, origin, releaseProc, releaseCtx);
157 if (!proxy) {
158 return nullptr;
159 }
160
161 return this->drawingManager()->makeRenderTargetContext(std::move(proxy), colorType,
162 std::move(colorSpace), surfaceProps);
163 }
164
165 std::unique_ptr<GrRenderTargetContext>
makeBackendTextureAsRenderTargetRenderTargetContext(const GrBackendTexture & tex,GrSurfaceOrigin origin,int sampleCnt,GrColorType colorType,sk_sp<SkColorSpace> colorSpace,const SkSurfaceProps * props)166 GrContextPriv::makeBackendTextureAsRenderTargetRenderTargetContext(const GrBackendTexture& tex,
167 GrSurfaceOrigin origin,
168 int sampleCnt,
169 GrColorType colorType,
170 sk_sp<SkColorSpace> colorSpace,
171 const SkSurfaceProps* props) {
172 ASSERT_SINGLE_OWNER
173 SkASSERT(sampleCnt > 0);
174 sk_sp<GrSurfaceProxy> proxy(
175 this->proxyProvider()->wrapBackendTextureAsRenderTarget(tex, colorType,
176 origin, sampleCnt));
177 if (!proxy) {
178 return nullptr;
179 }
180
181 return this->drawingManager()->makeRenderTargetContext(std::move(proxy), colorType,
182 std::move(colorSpace), props);
183 }
184
makeVulkanSecondaryCBRenderTargetContext(const SkImageInfo & imageInfo,const GrVkDrawableInfo & vkInfo,const SkSurfaceProps * props)185 std::unique_ptr<GrRenderTargetContext> GrContextPriv::makeVulkanSecondaryCBRenderTargetContext(
186 const SkImageInfo& imageInfo, const GrVkDrawableInfo& vkInfo, const SkSurfaceProps* props) {
187 ASSERT_SINGLE_OWNER
188 sk_sp<GrSurfaceProxy> proxy(
189 this->proxyProvider()->wrapVulkanSecondaryCBAsRenderTarget(imageInfo, vkInfo));
190 if (!proxy) {
191 return nullptr;
192 }
193
194 return this->drawingManager()->makeRenderTargetContext(
195 std::move(proxy),
196 SkColorTypeToGrColorType(imageInfo.colorType()),
197 imageInfo.refColorSpace(),
198 props);
199 }
200
flushSurfaces(GrSurfaceProxy * proxies[],int numProxies,const GrFlushInfo & info)201 GrSemaphoresSubmitted GrContextPriv::flushSurfaces(GrSurfaceProxy* proxies[], int numProxies,
202 const GrFlushInfo& info) {
203 ASSERT_SINGLE_OWNER
204 RETURN_VALUE_IF_ABANDONED(GrSemaphoresSubmitted::kNo)
205 GR_CREATE_TRACE_MARKER_CONTEXT("GrContextPriv", "flushSurfaces", fContext);
206 SkASSERT(numProxies >= 0);
207 SkASSERT(!numProxies || proxies);
208 for (int i = 0; i < numProxies; ++i) {
209 SkASSERT(proxies[i]);
210 ASSERT_OWNED_PROXY(proxies[i]);
211 }
212 return fContext->drawingManager()->flushSurfaces(
213 proxies, numProxies, SkSurface::BackendSurfaceAccess::kNoAccess, info);
214 }
215
flushSurface(GrSurfaceProxy * proxy)216 void GrContextPriv::flushSurface(GrSurfaceProxy* proxy) {
217 this->flushSurfaces(proxy ? &proxy : nullptr, proxy ? 1 : 0, {});
218 }
219
moveRenderTasksToDDL(SkDeferredDisplayList * ddl)220 void GrContextPriv::moveRenderTasksToDDL(SkDeferredDisplayList* ddl) {
221 fContext->drawingManager()->moveRenderTasksToDDL(ddl);
222 }
223
copyRenderTasksFromDDL(const SkDeferredDisplayList * ddl,GrRenderTargetProxy * newDest)224 void GrContextPriv::copyRenderTasksFromDDL(const SkDeferredDisplayList* ddl,
225 GrRenderTargetProxy* newDest) {
226 fContext->drawingManager()->copyRenderTasksFromDDL(ddl, newDest);
227 }
228
229 //////////////////////////////////////////////////////////////////////////////
230
231 #if GR_TEST_UTILS
resetGpuStats() const232 void GrContextPriv::resetGpuStats() const {
233 #if GR_GPU_STATS
234 fContext->fGpu->stats()->reset();
235 #endif
236 }
237
dumpCacheStats(SkString * out) const238 void GrContextPriv::dumpCacheStats(SkString* out) const {
239 #if GR_CACHE_STATS
240 fContext->fResourceCache->dumpStats(out);
241 #endif
242 }
243
dumpCacheStatsKeyValuePairs(SkTArray<SkString> * keys,SkTArray<double> * values) const244 void GrContextPriv::dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys,
245 SkTArray<double>* values) const {
246 #if GR_CACHE_STATS
247 fContext->fResourceCache->dumpStatsKeyValuePairs(keys, values);
248 #endif
249 }
250
printCacheStats() const251 void GrContextPriv::printCacheStats() const {
252 SkString out;
253 this->dumpCacheStats(&out);
254 SkDebugf("%s", out.c_str());
255 }
256
dumpGpuStats(SkString * out) const257 void GrContextPriv::dumpGpuStats(SkString* out) const {
258 #if GR_GPU_STATS
259 return fContext->fGpu->stats()->dump(out);
260 #endif
261 }
262
dumpGpuStatsKeyValuePairs(SkTArray<SkString> * keys,SkTArray<double> * values) const263 void GrContextPriv::dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys,
264 SkTArray<double>* values) const {
265 #if GR_GPU_STATS
266 return fContext->fGpu->stats()->dumpKeyValuePairs(keys, values);
267 #endif
268 }
269
printGpuStats() const270 void GrContextPriv::printGpuStats() const {
271 SkString out;
272 this->dumpGpuStats(&out);
273 SkDebugf("%s", out.c_str());
274 }
275
testingOnly_setTextBlobCacheLimit(size_t bytes)276 void GrContextPriv::testingOnly_setTextBlobCacheLimit(size_t bytes) {
277 fContext->priv().getTextBlobCache()->setBudget(bytes);
278 }
279
testingOnly_getFontAtlasImage(GrMaskFormat format,unsigned int index)280 sk_sp<SkImage> GrContextPriv::testingOnly_getFontAtlasImage(GrMaskFormat format, unsigned int index) {
281 auto atlasManager = this->getAtlasManager();
282 if (!atlasManager) {
283 return nullptr;
284 }
285
286 unsigned int numActiveProxies;
287 const sk_sp<GrTextureProxy>* proxies = atlasManager->getProxies(format, &numActiveProxies);
288 if (index >= numActiveProxies || !proxies || !proxies[index]) {
289 return nullptr;
290 }
291
292 SkASSERT(proxies[index]->priv().isExact());
293 sk_sp<SkImage> image(new SkImage_Gpu(sk_ref_sp(fContext), kNeedNewImageUniqueID,
294 kPremul_SkAlphaType, proxies[index], nullptr));
295 return image;
296 }
297
testingOnly_purgeAllUnlockedResources()298 void GrContextPriv::testingOnly_purgeAllUnlockedResources() {
299 fContext->fResourceCache->purgeAllUnlocked();
300 }
301
testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject * cb)302 void GrContextPriv::testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
303 fContext->flush();
304 fContext->drawingManager()->testingOnly_removeOnFlushCallbackObject(cb);
305 }
306 #endif
307
validPMUPMConversionExists()308 bool GrContextPriv::validPMUPMConversionExists() {
309 ASSERT_SINGLE_OWNER
310 if (!fContext->fDidTestPMConversions) {
311 fContext->fPMUPMConversionsRoundTrip =
312 GrConfigConversionEffect::TestForPreservingPMConversions(fContext);
313 fContext->fDidTestPMConversions = true;
314 }
315
316 // The PM<->UPM tests fail or succeed together so we only need to check one.
317 return fContext->fPMUPMConversionsRoundTrip;
318 }
319
createPMToUPMEffect(std::unique_ptr<GrFragmentProcessor> fp)320 std::unique_ptr<GrFragmentProcessor> GrContextPriv::createPMToUPMEffect(
321 std::unique_ptr<GrFragmentProcessor> fp) {
322 ASSERT_SINGLE_OWNER
323 // We should have already called this->priv().validPMUPMConversionExists() in this case
324 SkASSERT(fContext->fDidTestPMConversions);
325 // ...and it should have succeeded
326 SkASSERT(this->validPMUPMConversionExists());
327
328 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToUnpremul);
329 }
330
createUPMToPMEffect(std::unique_ptr<GrFragmentProcessor> fp)331 std::unique_ptr<GrFragmentProcessor> GrContextPriv::createUPMToPMEffect(
332 std::unique_ptr<GrFragmentProcessor> fp) {
333 ASSERT_SINGLE_OWNER
334 // We should have already called this->priv().validPMUPMConversionExists() in this case
335 SkASSERT(fContext->fDidTestPMConversions);
336 // ...and it should have succeeded
337 SkASSERT(this->validPMUPMConversionExists());
338
339 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToPremul);
340 }
341