blob: 2a23fe771dd1a3f2a2e1147a7e7a944a16ea2498 [file] [log] [blame]
Robert Phillipsdbaf3172019-02-06 15:12:53 -05001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/GrContextPriv.h"
Robert Phillipsdbaf3172019-02-06 15:12:53 -05009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/gpu/GrContextThreadSafeProxy.h"
11#include "include/gpu/GrTexture.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040012#include "src/gpu/GrAuditTrail.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#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"
Greg Danielf91aeb22019-06-18 09:58:02 -040018#include "src/gpu/GrSkSLFPFactoryCache.h"
Greg Daniel46cfbc62019-06-07 11:43:30 -040019#include "src/gpu/GrSurfaceContextPriv.h"
Mike Klein4b432fa2019-06-06 11:44:05 -050020#include "src/gpu/GrSurfacePriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "src/gpu/GrTextureContext.h"
22#include "src/gpu/SkGr.h"
Greg Daniel6eb8c242019-06-05 10:22:24 -040023#include "src/gpu/effects/generated/GrConfigConversionEffect.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "src/gpu/text/GrTextBlobCache.h"
25#include "src/image/SkImage_Base.h"
26#include "src/image/SkImage_Gpu.h"
Robert Phillipsdbaf3172019-02-06 15:12:53 -050027
Brian Salomonf9a1fdf2019-05-09 10:30:12 -040028#define ASSERT_OWNED_PROXY(P) \
Robert Phillipsdbaf3172019-02-06 15:12:53 -050029 SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == fContext)
Brian Salomonf9a1fdf2019-05-09 10:30:12 -040030#define ASSERT_SINGLE_OWNER \
Robert Phillipsa41c6852019-02-07 10:44:10 -050031 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fContext->singleOwner());)
Brian Salomonf9a1fdf2019-05-09 10:30:12 -040032#define RETURN_VALUE_IF_ABANDONED(value) if (fContext->abandoned()) { return (value); }
33#define RETURN_IF_ABANDONED RETURN_VALUE_IF_ABANDONED(void)
Robert Phillipsdbaf3172019-02-06 15:12:53 -050034
Robert Phillipsa41c6852019-02-07 10:44:10 -050035sk_sp<const GrCaps> GrContextPriv::refCaps() const {
36 return fContext->refCaps();
37}
38
Robert Phillipsdbaf3172019-02-06 15:12:53 -050039sk_sp<GrSkSLFPFactoryCache> GrContextPriv::fpFactoryCache() {
40 return fContext->fpFactoryCache();
41}
42
43sk_sp<GrOpMemoryPool> GrContextPriv::refOpMemoryPool() {
Robert Phillipsd6841482019-02-08 10:29:20 -050044 return fContext->refOpMemoryPool();
Robert Phillipsdbaf3172019-02-06 15:12:53 -050045}
46
Robert Phillipsc5058a62019-02-15 12:52:59 -050047void GrContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
48 fContext->addOnFlushCallbackObject(onFlushCBObject);
49}
50
Robert Phillips292a6b22019-02-14 14:49:02 -050051sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(
52 sk_sp<GrSurfaceProxy> proxy,
53 sk_sp<SkColorSpace> colorSpace,
54 const SkSurfaceProps* props) {
55 return fContext->makeWrappedSurfaceContext(std::move(proxy), std::move(colorSpace), props);
56}
57
58sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(
59 const GrBackendFormat& format,
60 const GrSurfaceDesc& dstDesc,
61 GrSurfaceOrigin origin,
62 GrMipMapped mipMapped,
63 SkBackingFit fit,
64 SkBudgeted isDstBudgeted,
65 sk_sp<SkColorSpace> colorSpace,
66 const SkSurfaceProps* props) {
67 return fContext->makeDeferredSurfaceContext(format, dstDesc, origin, mipMapped, fit,
68 isDstBudgeted, std::move(colorSpace), props);
69}
70
Robert Phillipsb97da532019-02-12 15:24:12 -050071sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContext(
Emircan Uysaler23ca4e72019-06-24 10:53:09 -040072 const GrBackendFormat& format, SkBackingFit fit, int width, int height,
73 GrPixelConfig config, sk_sp<SkColorSpace> colorSpace, int sampleCnt, GrMipMapped mipMapped,
74 GrSurfaceOrigin origin, const SkSurfaceProps* surfaceProps, SkBudgeted budgeted,
75 GrProtected isProtected) {
Robert Phillipsb97da532019-02-12 15:24:12 -050076 return fContext->makeDeferredRenderTargetContext(format, fit, width, height, config,
77 std::move(colorSpace), sampleCnt, mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -040078 origin, surfaceProps, budgeted, isProtected);
Robert Phillipsb97da532019-02-12 15:24:12 -050079}
80
Robert Phillips6f0e02f2019-02-13 11:02:28 -050081sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContextWithFallback(
82 const GrBackendFormat& format,
83 SkBackingFit fit,
84 int width, int height,
85 GrPixelConfig config,
86 sk_sp<SkColorSpace> colorSpace,
87 int sampleCnt,
88 GrMipMapped mipMapped,
89 GrSurfaceOrigin origin,
90 const SkSurfaceProps* surfaceProps,
91 SkBudgeted budgeted) {
92 return fContext->makeDeferredRenderTargetContextWithFallback(format, fit, width, height, config,
93 std::move(colorSpace), sampleCnt,
94 mipMapped, origin, surfaceProps,
95 budgeted);
96}
97
Robert Phillipsdbaf3172019-02-06 15:12:53 -050098sk_sp<GrTextureContext> GrContextPriv::makeBackendTextureContext(const GrBackendTexture& tex,
99 GrSurfaceOrigin origin,
100 sk_sp<SkColorSpace> colorSpace) {
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400101 ASSERT_SINGLE_OWNER
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500102
103 sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendTexture(
104 tex, origin, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType);
105 if (!proxy) {
106 return nullptr;
107 }
108
109 return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
110}
111
112sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
113 const GrBackendTexture& tex,
114 GrSurfaceOrigin origin,
115 int sampleCnt,
116 sk_sp<SkColorSpace> colorSpace,
117 const SkSurfaceProps* props,
118 ReleaseProc releaseProc,
119 ReleaseContext releaseCtx) {
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400120 ASSERT_SINGLE_OWNER
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500121 SkASSERT(sampleCnt > 0);
122
123 sk_sp<GrTextureProxy> proxy(this->proxyProvider()->wrapRenderableBackendTexture(
124 tex, origin, sampleCnt, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, releaseProc,
125 releaseCtx));
126 if (!proxy) {
127 return nullptr;
128 }
129
130 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
131 std::move(colorSpace), props);
132}
133
134sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendRenderTargetRenderTargetContext(
135 const GrBackendRenderTarget& backendRT,
136 GrSurfaceOrigin origin,
137 sk_sp<SkColorSpace> colorSpace,
138 const SkSurfaceProps* surfaceProps,
139 ReleaseProc releaseProc,
140 ReleaseContext releaseCtx) {
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400141 ASSERT_SINGLE_OWNER
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500142
143 sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendRenderTarget(
144 backendRT, origin, releaseProc, releaseCtx);
145 if (!proxy) {
146 return nullptr;
147 }
148
149 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
150 std::move(colorSpace),
151 surfaceProps);
152}
153
154sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureAsRenderTargetRenderTargetContext(
155 const GrBackendTexture& tex,
156 GrSurfaceOrigin origin,
157 int sampleCnt,
158 sk_sp<SkColorSpace> colorSpace,
159 const SkSurfaceProps* props) {
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400160 ASSERT_SINGLE_OWNER
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500161 SkASSERT(sampleCnt > 0);
162 sk_sp<GrSurfaceProxy> proxy(
163 this->proxyProvider()->wrapBackendTextureAsRenderTarget(tex, origin, sampleCnt));
164 if (!proxy) {
165 return nullptr;
166 }
167
168 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
169 std::move(colorSpace),
170 props);
171}
172
173sk_sp<GrRenderTargetContext> GrContextPriv::makeVulkanSecondaryCBRenderTargetContext(
174 const SkImageInfo& imageInfo, const GrVkDrawableInfo& vkInfo, const SkSurfaceProps* props) {
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400175 ASSERT_SINGLE_OWNER
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500176 sk_sp<GrSurfaceProxy> proxy(
177 this->proxyProvider()->wrapVulkanSecondaryCBAsRenderTarget(imageInfo, vkInfo));
178 if (!proxy) {
179 return nullptr;
180 }
181
182 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
183 imageInfo.refColorSpace(),
184 props);
185}
186
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400187GrSemaphoresSubmitted GrContextPriv::flushSurfaces(GrSurfaceProxy* proxies[], int numProxies,
188 const GrFlushInfo& info) {
189 ASSERT_SINGLE_OWNER
190 RETURN_VALUE_IF_ABANDONED(GrSemaphoresSubmitted::kNo)
191 GR_CREATE_TRACE_MARKER_CONTEXT("GrContextPriv", "flushSurfaces", fContext);
192 SkASSERT(numProxies >= 0);
193 SkASSERT(!numProxies || proxies);
194 for (int i = 0; i < numProxies; ++i) {
195 SkASSERT(proxies[i]);
196 ASSERT_OWNED_PROXY(proxies[i]);
197 }
198 return fContext->drawingManager()->flushSurfaces(
199 proxies, numProxies, SkSurface::BackendSurfaceAccess::kNoAccess, info);
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500200}
201
Brian Salomon693bc2b2019-05-09 13:48:00 +0000202void GrContextPriv::flushSurface(GrSurfaceProxy* proxy) {
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400203 this->flushSurfaces(proxy ? &proxy : nullptr, proxy ? 1 : 0, {});
Brian Salomon693bc2b2019-05-09 13:48:00 +0000204}
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500205
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500206void GrContextPriv::moveOpListsToDDL(SkDeferredDisplayList* ddl) {
Robert Phillips292a6b22019-02-14 14:49:02 -0500207 fContext->drawingManager()->moveOpListsToDDL(ddl);
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500208}
209
210void GrContextPriv::copyOpListsFromDDL(const SkDeferredDisplayList* ddl,
211 GrRenderTargetProxy* newDest) {
Robert Phillips6a6de562019-02-15 15:19:15 -0500212 fContext->drawingManager()->copyOpListsFromDDL(ddl, newDest);
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500213}
214
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500215//////////////////////////////////////////////////////////////////////////////
216#ifdef SK_ENABLE_DUMP_GPU
Mike Kleinc0bd9f92019-04-23 12:05:21 -0500217#include "src/utils/SkJSONWriter.h"
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500218SkString GrContextPriv::dump() const {
219 SkDynamicMemoryWStream stream;
220 SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
221 writer.beginObject();
222
223 static const char* kBackendStr[] = {
224 "Metal",
225 "OpenGL",
226 "Vulkan",
227 "Mock",
228 };
229 GR_STATIC_ASSERT(0 == (unsigned)GrBackendApi::kMetal);
230 GR_STATIC_ASSERT(1 == (unsigned)GrBackendApi::kOpenGL);
231 GR_STATIC_ASSERT(2 == (unsigned)GrBackendApi::kVulkan);
232 GR_STATIC_ASSERT(3 == (unsigned)GrBackendApi::kMock);
233 writer.appendString("backend", kBackendStr[(unsigned)fContext->backend()]);
234
235 writer.appendName("caps");
236 fContext->caps()->dumpJSON(&writer);
237
238 writer.appendName("gpu");
239 fContext->fGpu->dumpJSON(&writer);
240
241 // Flush JSON to the memory stream
242 writer.endObject();
243 writer.flush();
244
245 // Null terminate the JSON data in the memory stream
246 stream.write8(0);
247
248 // Allocate a string big enough to hold all the data, then copy out of the stream
249 SkString result(stream.bytesWritten());
250 stream.copyToAndReset(result.writable_str());
251 return result;
252}
253#endif
254
255#if GR_TEST_UTILS
256void GrContextPriv::resetGpuStats() const {
257#if GR_GPU_STATS
258 fContext->fGpu->stats()->reset();
259#endif
260}
261
262void GrContextPriv::dumpCacheStats(SkString* out) const {
263#if GR_CACHE_STATS
264 fContext->fResourceCache->dumpStats(out);
265#endif
266}
267
268void GrContextPriv::dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys,
269 SkTArray<double>* values) const {
270#if GR_CACHE_STATS
271 fContext->fResourceCache->dumpStatsKeyValuePairs(keys, values);
272#endif
273}
274
275void GrContextPriv::printCacheStats() const {
276 SkString out;
277 this->dumpCacheStats(&out);
278 SkDebugf("%s", out.c_str());
279}
280
281void GrContextPriv::dumpGpuStats(SkString* out) const {
282#if GR_GPU_STATS
283 return fContext->fGpu->stats()->dump(out);
284#endif
285}
286
287void GrContextPriv::dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys,
288 SkTArray<double>* values) const {
289#if GR_GPU_STATS
290 return fContext->fGpu->stats()->dumpKeyValuePairs(keys, values);
291#endif
292}
293
294void GrContextPriv::printGpuStats() const {
295 SkString out;
296 this->dumpGpuStats(&out);
297 SkDebugf("%s", out.c_str());
298}
299
300void GrContextPriv::testingOnly_setTextBlobCacheLimit(size_t bytes) {
Robert Phillips2184fb72019-02-21 16:11:41 -0500301 fContext->priv().getTextBlobCache()->setBudget(bytes);
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500302}
303
304sk_sp<SkImage> GrContextPriv::testingOnly_getFontAtlasImage(GrMaskFormat format, unsigned int index) {
305 auto atlasManager = this->getAtlasManager();
306 if (!atlasManager) {
307 return nullptr;
308 }
309
310 unsigned int numActiveProxies;
311 const sk_sp<GrTextureProxy>* proxies = atlasManager->getProxies(format, &numActiveProxies);
312 if (index >= numActiveProxies || !proxies || !proxies[index]) {
313 return nullptr;
314 }
315
316 SkASSERT(proxies[index]->priv().isExact());
317 sk_sp<SkImage> image(new SkImage_Gpu(sk_ref_sp(fContext), kNeedNewImageUniqueID,
318 kPremul_SkAlphaType, proxies[index], nullptr));
319 return image;
320}
321
322void GrContextPriv::testingOnly_purgeAllUnlockedResources() {
323 fContext->fResourceCache->purgeAllUnlocked();
324}
325
326void GrContextPriv::testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject* cb) {
327 fContext->flush();
Robert Phillips292a6b22019-02-14 14:49:02 -0500328 fContext->drawingManager()->testingOnly_removeOnFlushCallbackObject(cb);
Robert Phillipsdbaf3172019-02-06 15:12:53 -0500329}
330#endif
Greg Daniel6eb8c242019-06-05 10:22:24 -0400331
332bool GrContextPriv::validPMUPMConversionExists() {
333 ASSERT_SINGLE_OWNER
334 if (!fContext->fDidTestPMConversions) {
335 fContext->fPMUPMConversionsRoundTrip =
336 GrConfigConversionEffect::TestForPreservingPMConversions(fContext);
337 fContext->fDidTestPMConversions = true;
338 }
339
340 // The PM<->UPM tests fail or succeed together so we only need to check one.
341 return fContext->fPMUPMConversionsRoundTrip;
342}
343
344std::unique_ptr<GrFragmentProcessor> GrContextPriv::createPMToUPMEffect(
345 std::unique_ptr<GrFragmentProcessor> fp) {
346 ASSERT_SINGLE_OWNER
347 // We should have already called this->priv().validPMUPMConversionExists() in this case
348 SkASSERT(fContext->fDidTestPMConversions);
349 // ...and it should have succeeded
350 SkASSERT(this->validPMUPMConversionExists());
351
352 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToUnpremul);
353}
354
355std::unique_ptr<GrFragmentProcessor> GrContextPriv::createUPMToPMEffect(
356 std::unique_ptr<GrFragmentProcessor> fp) {
357 ASSERT_SINGLE_OWNER
358 // We should have already called this->priv().validPMUPMConversionExists() in this case
359 SkASSERT(fContext->fDidTestPMConversions);
360 // ...and it should have succeeded
361 SkASSERT(this->validPMUPMConversionExists());
362
363 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToPremul);
364}
Robert Phillipscb1adb42019-06-10 15:09:34 -0400365
366//////////////////////////////////////////////////////////////////////////////
367
368#include "src/core/SkMipMap.h"
369
370GrBackendTexture GrContextPriv::createBackendTexture(const SkPixmap srcData[], int numLevels,
371 GrRenderable renderable) {
372 if (!fContext->asDirectContext()) {
373 return {};
374 }
375
376 if (this->abandoned()) {
377 return {};
378 }
379
380 if (!srcData || !numLevels) {
381 return {};
382 }
383
384 int baseWidth = srcData[0].width();
385 int baseHeight = srcData[0].height();
386 SkColorType colorType = srcData[0].colorType();
387
388 if (numLevels > 1) {
389 if (numLevels != SkMipMap::ComputeLevelCount(baseWidth, baseHeight) + 1) {
390 return {};
391 }
392
393 int currentWidth = baseWidth;
394 int currentHeight = baseHeight;
395 for (int i = 1; i < numLevels; ++i) {
396 currentWidth = SkTMax(1, currentWidth / 2);
397 currentHeight = SkTMax(1, currentHeight / 2);
398
399 if (srcData[i].colorType() != colorType) {
400 return {};
401 }
402
403 if (srcData[i].width() != currentWidth || srcData[i].height() != currentHeight) {
404 return {};
405 }
406 }
407 }
408
409 GrBackendFormat backendFormat = this->caps()->getBackendFormatFromColorType(colorType);
410 if (!backendFormat.isValid()) {
411 return {};
412 }
413
414 GrGpu* gpu = fContext->fGpu.get();
415
416 // TODO: propagate the array of pixmaps interface to GrGpu
417 return gpu->createBackendTexture(baseWidth, baseHeight, backendFormat,
418 GrMipMapped::kNo, // TODO: use real mipmap setting here
419 renderable, srcData[0].addr(), srcData[0].rowBytes(),
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400420 nullptr, GrProtected::kNo);
Robert Phillipscb1adb42019-06-10 15:09:34 -0400421}