blob: 7319ba5387f7f63afee1251f131dd9314b816b2d [file] [log] [blame]
bsalomon@google.com27847de2011-02-22 20:59:41 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2011 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.
bsalomon@google.com27847de2011-02-22 20:59:41 +00006 */
7
Brian Salomon6fc04f82019-10-02 19:11:55 -04008#include "include/gpu/GrContext.h"
9
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkTraceMemoryDump.h"
11#include "include/gpu/GrBackendSemaphore.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/private/SkDeferredDisplayList.h"
13#include "include/private/SkImageInfoPriv.h"
14#include "src/core/SkMakeUnique.h"
15#include "src/core/SkTaskGroup.h"
Brian Salomon6fc04f82019-10-02 19:11:55 -040016#include "src/gpu/GrClientMappedBufferManager.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#include "src/gpu/GrDrawingManager.h"
18#include "src/gpu/GrGpu.h"
19#include "src/gpu/GrMemoryPool.h"
20#include "src/gpu/GrPathRendererChain.h"
21#include "src/gpu/GrProxyProvider.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040022#include "src/gpu/GrRenderTargetProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/GrResourceCache.h"
24#include "src/gpu/GrResourceProvider.h"
25#include "src/gpu/GrSemaphore.h"
Brian Osman5e7fbfd2019-05-03 13:13:35 -040026#include "src/gpu/GrShaderUtils.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050027#include "src/gpu/GrSoftwarePathRenderer.h"
28#include "src/gpu/GrTracing.h"
29#include "src/gpu/SkGr.h"
30#include "src/gpu/ccpr/GrCoverageCountingPathRenderer.h"
31#include "src/gpu/effects/GrSkSLFP.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050032#include "src/gpu/text/GrTextBlobCache.h"
33#include "src/gpu/text/GrTextContext.h"
34#include "src/image/SkSurface_Gpu.h"
Mike Klein0ec1c572018-12-04 11:52:51 -050035#include <atomic>
Greg Danielb76a72a2017-07-13 15:07:54 -040036
Robert Phillipse78b7252017-04-06 07:59:41 -040037#define ASSERT_OWNED_PROXY(P) \
Brian Salomonfd98c2c2018-07-31 17:25:29 -040038 SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == this)
Robert Phillips7ee385e2017-03-30 08:02:11 -040039
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000040#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
joshualitt1de610a2016-01-06 08:26:09 -080041#define ASSERT_SINGLE_OWNER \
Robert Phillipsa41c6852019-02-07 10:44:10 -050042 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
Robert Phillipsa9162df2019-02-11 14:12:03 -050043#define RETURN_IF_ABANDONED if (this->abandoned()) { return; }
44#define RETURN_FALSE_IF_ABANDONED if (this->abandoned()) { return false; }
45#define RETURN_NULL_IF_ABANDONED if (this->abandoned()) { return nullptr; }
bsalomon@google.combc4b6542011-11-19 13:56:11 +000046
robertphillipsea461502015-05-26 11:38:03 -070047////////////////////////////////////////////////////////////////////////////////
48
Robert Phillipsa41c6852019-02-07 10:44:10 -050049GrContext::GrContext(GrBackendApi backend, const GrContextOptions& options, int32_t contextID)
50 : INHERITED(backend, options, contextID) {
halcanary96fcdcc2015-08-27 07:41:13 -070051 fResourceCache = nullptr;
52 fResourceProvider = nullptr;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000053}
54
Robert Phillips292a6b22019-02-14 14:49:02 -050055GrContext::~GrContext() {
56 ASSERT_SINGLE_OWNER
57
Robert Phillips6a6de562019-02-15 15:19:15 -050058 if (this->drawingManager()) {
59 this->drawingManager()->cleanup();
Robert Phillips292a6b22019-02-14 14:49:02 -050060 }
61 delete fResourceProvider;
62 delete fResourceCache;
Robert Phillips292a6b22019-02-14 14:49:02 -050063}
64
Robert Phillipsbb606772019-02-04 17:50:57 -050065bool GrContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) {
Greg Danielb76a72a2017-07-13 15:07:54 -040066 ASSERT_SINGLE_OWNER
Robert Phillipsfde6fa02018-03-02 08:53:14 -050067 SkASSERT(fThreadSafeProxy); // needs to have been initialized by derived classes
Robert Phillipsa41c6852019-02-07 10:44:10 -050068 SkASSERT(this->proxyProvider());
Robert Phillips88260b52018-01-19 12:56:09 -050069
Robert Phillipsbb606772019-02-04 17:50:57 -050070 if (!INHERITED::init(std::move(caps), std::move(FPFactoryCache))) {
71 return false;
72 }
73
74 SkASSERT(this->caps());
Herb Derbya00da612019-03-04 17:10:01 -050075 SkASSERT(this->getGrStrikeCache());
Robert Phillips2184fb72019-02-21 16:11:41 -050076 SkASSERT(this->getTextBlobCache());
Robert Phillipsbb606772019-02-04 17:50:57 -050077
Robert Phillips88260b52018-01-19 12:56:09 -050078 if (fGpu) {
Robert Phillipsa41c6852019-02-07 10:44:10 -050079 fResourceCache = new GrResourceCache(this->caps(), this->singleOwner(), this->contextID());
Robert Phillips12c46292019-04-23 07:36:17 -040080 fResourceProvider = new GrResourceProvider(fGpu.get(), fResourceCache, this->singleOwner());
Robert Phillips88260b52018-01-19 12:56:09 -050081 }
82
Robert Phillips88260b52018-01-19 12:56:09 -050083 if (fResourceCache) {
Robert Phillipsa41c6852019-02-07 10:44:10 -050084 fResourceCache->setProxyProvider(this->proxyProvider());
Robert Phillips88260b52018-01-19 12:56:09 -050085 }
Robert Phillips1afd4cd2018-01-08 13:40:32 -050086
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000087 fDidTestPMConversions = false;
88
Robert Phillipsfde6fa02018-03-02 08:53:14 -050089 // DDL TODO: we need to think through how the task group & persistent cache
90 // get passed on to/shared between all the DDLRecorders created with this context.
Robert Phillipsc1541ae2019-02-04 12:05:37 -050091 if (this->options().fExecutor) {
92 fTaskGroup = skstd::make_unique<SkTaskGroup>(*this->options().fExecutor);
Brian Osman51279982017-08-23 10:12:00 -040093 }
94
Robert Phillipsc1541ae2019-02-04 12:05:37 -050095 fPersistentCache = this->options().fPersistentCache;
Brian Osman5e7fbfd2019-05-03 13:13:35 -040096 fShaderErrorHandler = this->options().fShaderErrorHandler;
97 if (!fShaderErrorHandler) {
98 fShaderErrorHandler = GrShaderUtils::DefaultShaderErrorHandler();
99 }
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400100
Brian Salomon6fc04f82019-10-02 19:11:55 -0400101 fMappedBufferManager = skstd::make_unique<GrClientMappedBufferManager>();
102
Brian Salomon91a3e522017-06-23 10:58:19 -0400103 return true;
bsalomon@google.comc0af3172012-06-15 14:10:09 +0000104}
105
Robert Phillips4217ea72019-01-30 13:08:28 -0500106sk_sp<GrContextThreadSafeProxy> GrContext::threadSafeProxy() {
107 return fThreadSafeProxy;
108}
109
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400110//////////////////////////////////////////////////////////////////////////////
111
bsalomon2354f842014-07-28 13:48:36 -0700112void GrContext::abandonContext() {
Robert Phillipsa9162df2019-02-11 14:12:03 -0500113 if (this->abandoned()) {
114 return;
115 }
joshualitt1de610a2016-01-06 08:26:09 -0800116
Robert Phillipsa9162df2019-02-11 14:12:03 -0500117 INHERITED::abandonContext();
118
Brian Salomon6fc04f82019-10-02 19:11:55 -0400119 fMappedBufferManager->abandon();
120
bsalomond309e7a2015-04-30 14:18:54 -0700121 fResourceProvider->abandon();
robertphillips0dfa62c2015-11-16 06:23:31 -0800122
Robert Phillipsa9162df2019-02-11 14:12:03 -0500123 // Need to cleanup the drawing manager first so all the render targets
robertphillips0dfa62c2015-11-16 06:23:31 -0800124 // will be released/forgotten before they too are abandoned.
Robert Phillips6a6de562019-02-15 15:19:15 -0500125 this->drawingManager()->cleanup();
robertphillips0dfa62c2015-11-16 06:23:31 -0800126
bsalomon@google.com205d4602011-04-25 12:43:45 +0000127 // abandon first to so destructors
128 // don't try to free the resources in the API.
bsalomon0ea80f42015-02-11 10:49:59 -0800129 fResourceCache->abandonAll();
bsalomonc8dc1f72014-08-21 13:02:13 -0700130
bsalomon6e2aad42016-04-01 11:54:31 -0700131 fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
Brian Salomon6fc04f82019-10-02 19:11:55 -0400132
133 fMappedBufferManager.reset();
Khushalc421ca12018-06-26 14:38:34 -0700134}
135
bsalomon6e2aad42016-04-01 11:54:31 -0700136void GrContext::releaseResourcesAndAbandonContext() {
Brian Salomon614c1a82018-12-19 15:42:06 -0500137 if (this->abandoned()) {
138 return;
139 }
Robert Phillipsa9162df2019-02-11 14:12:03 -0500140
141 INHERITED::abandonContext();
142
Brian Salomon6fc04f82019-10-02 19:11:55 -0400143 fMappedBufferManager.reset();
144
bsalomon6e2aad42016-04-01 11:54:31 -0700145 fResourceProvider->abandon();
146
Robert Phillipsa9162df2019-02-11 14:12:03 -0500147 // Need to cleanup the drawing manager first so all the render targets
bsalomon6e2aad42016-04-01 11:54:31 -0700148 // will be released/forgotten before they too are abandoned.
Robert Phillips6a6de562019-02-15 15:19:15 -0500149 this->drawingManager()->cleanup();
bsalomon6e2aad42016-04-01 11:54:31 -0700150
151 // Release all resources in the backend 3D API.
152 fResourceCache->releaseAll();
153
154 fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000155}
156
Brian Salomon1f05d452019-02-08 12:33:08 -0500157void GrContext::resetGLTextureBindings() {
158 if (this->abandoned() || this->backend() != GrBackendApi::kOpenGL) {
159 return;
160 }
161 fGpu->resetTextureBindings();
162}
163
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000164void GrContext::resetContext(uint32_t state) {
joshualitt1de610a2016-01-06 08:26:09 -0800165 ASSERT_SINGLE_OWNER
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000166 fGpu->markContextDirty(state);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000167}
168
169void GrContext::freeGpuResources() {
joshualitt1de610a2016-01-06 08:26:09 -0800170 ASSERT_SINGLE_OWNER
171
Robert Phillips2184fb72019-02-21 16:11:41 -0500172 // TODO: the glyph cache doesn't hold any GpuResources so this call should not be needed here.
173 // Some slack in the GrTextBlob's implementation requires it though. That could be fixed.
Herb Derbya00da612019-03-04 17:10:01 -0500174 this->getGrStrikeCache()->freeAll();
robertphillips68737822015-10-29 12:12:21 -0700175
Robert Phillips6a6de562019-02-15 15:19:15 -0500176 this->drawingManager()->freeGpuResources();
bsalomon3033b9f2015-04-13 11:09:56 -0700177
178 fResourceCache->purgeAllUnlocked();
bsalomon@google.com27847de2011-02-22 20:59:41 +0000179}
180
Robert Phillips6eba0632018-03-28 12:25:42 -0400181void GrContext::purgeUnlockedResources(bool scratchResourcesOnly) {
182 ASSERT_SINGLE_OWNER
183 fResourceCache->purgeUnlockedResources(scratchResourcesOnly);
184 fResourceCache->purgeAsNeeded();
Robert Phillips2184fb72019-02-21 16:11:41 -0500185
186 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
187 // place to purge stale blobs
188 this->getTextBlobCache()->purgeStaleBlobs();
Robert Phillips6eba0632018-03-28 12:25:42 -0400189}
190
Jim Van Verth76d917c2017-12-13 09:26:37 -0500191void GrContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed) {
Yuqian Li40aa85f2019-07-02 13:45:00 -0700192 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
193
Brian Salomon5e150852017-03-22 14:53:13 -0400194 ASSERT_SINGLE_OWNER
Chris Dalton6c3879d2018-11-01 11:13:19 -0600195
Brian Salomon6fc04f82019-10-02 19:11:55 -0400196 if (this->abandoned()) {
197 return;
198 }
199
200 fMappedBufferManager->process();
Chris Dalton6c3879d2018-11-01 11:13:19 -0600201 auto purgeTime = GrStdSteadyClock::now() - msNotUsed;
202
Jim Van Verth76d917c2017-12-13 09:26:37 -0500203 fResourceCache->purgeAsNeeded();
Chris Dalton6c3879d2018-11-01 11:13:19 -0600204 fResourceCache->purgeResourcesNotUsedSince(purgeTime);
205
Robert Phillips6a6de562019-02-15 15:19:15 -0500206 if (auto ccpr = this->drawingManager()->getCoverageCountingPathRenderer()) {
Robert Phillipsa41c6852019-02-07 10:44:10 -0500207 ccpr->purgeCacheEntriesOlderThan(this->proxyProvider(), purgeTime);
Chris Dalton6c3879d2018-11-01 11:13:19 -0600208 }
Jim Van Verth76d917c2017-12-13 09:26:37 -0500209
Robert Phillips2184fb72019-02-21 16:11:41 -0500210 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
211 // place to purge stale blobs
212 this->getTextBlobCache()->purgeStaleBlobs();
Brian Salomon5e150852017-03-22 14:53:13 -0400213}
214
Derek Sollenberger5480a182017-05-25 16:43:59 -0400215void GrContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
216 ASSERT_SINGLE_OWNER
217 fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources);
218}
219
commit-bot@chromium.org95c20032014-05-09 14:29:32 +0000220void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
joshualitt1de610a2016-01-06 08:26:09 -0800221 ASSERT_SINGLE_OWNER
222
bsalomon71cb0c22014-11-14 12:10:14 -0800223 if (resourceCount) {
bsalomon0ea80f42015-02-11 10:49:59 -0800224 *resourceCount = fResourceCache->getBudgetedResourceCount();
bsalomon71cb0c22014-11-14 12:10:14 -0800225 }
226 if (resourceBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800227 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
bsalomon71cb0c22014-11-14 12:10:14 -0800228 }
commit-bot@chromium.orgd8a57af2014-03-19 21:19:16 +0000229}
230
Derek Sollenbergeree479142017-05-24 11:41:33 -0400231size_t GrContext::getResourceCachePurgeableBytes() const {
232 ASSERT_SINGLE_OWNER
233 return fResourceCache->getPurgeableBytes();
234}
235
Adrienne Walker0f827972019-03-26 13:46:14 -0700236size_t GrContext::ComputeTextureSize(SkColorType type, int width, int height, GrMipMapped mipMapped,
237 bool useNextPow2) {
238 int colorSamplesPerPixel = 1;
239 return GrSurface::ComputeSize(SkColorType2GrPixelConfig(type), width, height,
240 colorSamplesPerPixel, mipMapped, useNextPow2);
241}
242
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000243////////////////////////////////////////////////////////////////////////////////
244
Robert Phillipsbb606772019-02-04 17:50:57 -0500245int GrContext::maxTextureSize() const { return this->caps()->maxTextureSize(); }
Brian Salomonf932a632018-04-05 12:46:09 -0400246
Robert Phillipsbb606772019-02-04 17:50:57 -0500247int GrContext::maxRenderTargetSize() const { return this->caps()->maxRenderTargetSize(); }
Brian Salomonf932a632018-04-05 12:46:09 -0400248
Brian Salomonbdecacf2018-02-02 20:32:49 -0500249bool GrContext::colorTypeSupportedAsImage(SkColorType colorType) const {
Greg Daniel7bfc9132019-08-14 14:23:53 -0400250 GrBackendFormat format =
251 this->caps()->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
252 GrRenderable::kNo);
253 return format.isValid();
Brian Salomonbdecacf2018-02-02 20:32:49 -0500254}
255
256int GrContext::maxSurfaceSampleCountForColorType(SkColorType colorType) const {
Greg Danieleadfac92019-08-02 09:03:53 -0400257 GrBackendFormat format =
258 this->caps()->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
259 GrRenderable::kYes);
260 return this->caps()->maxRenderTargetSampleCount(format);
Brian Salomonbdecacf2018-02-02 20:32:49 -0500261}
262
263////////////////////////////////////////////////////////////////////////////////
264
Greg Daniel06be0792019-04-22 15:53:23 -0400265bool GrContext::wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[]) {
Brian Salomon9ff5acb2019-05-08 09:04:47 -0400266 if (!fGpu || fGpu->caps()->semaphoreSupport()) {
Greg Daniel06be0792019-04-22 15:53:23 -0400267 return false;
268 }
269 for (int i = 0; i < numSemaphores; ++i) {
270 sk_sp<GrSemaphore> sema = fResourceProvider->wrapBackendSemaphore(
271 waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait,
272 kAdopt_GrWrapOwnership);
273 fGpu->waitSemaphore(std::move(sema));
274 }
275 return true;
276}
277
278////////////////////////////////////////////////////////////////////////////////
279
Greg Daniel797efca2019-05-09 14:04:20 -0400280GrSemaphoresSubmitted GrContext::flush(const GrFlushInfo& info,
281 const GrPrepareForExternalIORequests& externalRequests) {
Greg Daniel51316782017-08-02 15:10:09 +0000282 ASSERT_SINGLE_OWNER
Robert Phillipsa9162df2019-02-11 14:12:03 -0500283 if (this->abandoned()) {
284 return GrSemaphoresSubmitted::kNo;
285 }
Greg Daniel51316782017-08-02 15:10:09 +0000286
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400287 return this->drawingManager()->flush(nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess,
Greg Daniel797efca2019-05-09 14:04:20 -0400288 info, externalRequests);
Greg Daniel51316782017-08-02 15:10:09 +0000289}
290
Greg Daniela870b462019-01-08 15:49:46 -0500291////////////////////////////////////////////////////////////////////////////////
292
Brian Salomonb0d8b762019-05-06 16:58:22 -0400293void GrContext::checkAsyncWorkCompletion() {
294 if (fGpu) {
295 fGpu->checkFinishProcs();
296 }
297}
298
299////////////////////////////////////////////////////////////////////////////////
300
Greg Daniela870b462019-01-08 15:49:46 -0500301void GrContext::storeVkPipelineCacheData() {
302 if (fGpu) {
303 fGpu->storeVkPipelineCacheData();
304 }
305}
306
307////////////////////////////////////////////////////////////////////////////////
308
Khushal3e7548c2018-05-23 15:45:01 -0700309bool GrContext::supportsDistanceFieldText() const {
Robert Phillipsbb606772019-02-04 17:50:57 -0500310 return this->caps()->shaderCaps()->supportsDistanceFieldText();
Khushal3e7548c2018-05-23 15:45:01 -0700311}
312
bsalomon37f9a262015-02-02 13:00:10 -0800313//////////////////////////////////////////////////////////////////////////////
314
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500315void GrContext::getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const {
joshualitt1de610a2016-01-06 08:26:09 -0800316 ASSERT_SINGLE_OWNER
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500317 if (maxResources) {
Robert Phillipscf39f372019-09-03 10:29:20 -0400318 *maxResources = -1;
bsalomon37f9a262015-02-02 13:00:10 -0800319 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500320 if (maxResourceBytes) {
Robert Phillipscf39f372019-09-03 10:29:20 -0400321 *maxResourceBytes = this->getResourceCacheLimit();
bsalomon37f9a262015-02-02 13:00:10 -0800322 }
323}
324
Robert Phillipscf39f372019-09-03 10:29:20 -0400325size_t GrContext::getResourceCacheLimit() const {
joshualitt1de610a2016-01-06 08:26:09 -0800326 ASSERT_SINGLE_OWNER
Robert Phillipscf39f372019-09-03 10:29:20 -0400327 return fResourceCache->getMaxResourceBytes();
328}
329
330void GrContext::setResourceCacheLimits(int unused, size_t maxResourceBytes) {
331 ASSERT_SINGLE_OWNER
332 this->setResourceCacheLimit(maxResourceBytes);
333}
334
335void GrContext::setResourceCacheLimit(size_t maxResourceBytes) {
336 ASSERT_SINGLE_OWNER
337 fResourceCache->setLimit(maxResourceBytes);
bsalomon37f9a262015-02-02 13:00:10 -0800338}
339
ericrk0a5fa482015-09-15 14:16:10 -0700340//////////////////////////////////////////////////////////////////////////////
ericrk0a5fa482015-09-15 14:16:10 -0700341void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
joshualitt1de610a2016-01-06 08:26:09 -0800342 ASSERT_SINGLE_OWNER
ericrk0a5fa482015-09-15 14:16:10 -0700343 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
Khushal71652e22018-10-29 13:05:36 -0700344 traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
Robert Phillips2184fb72019-02-21 16:11:41 -0500345 this->getTextBlobCache()->usedBytes());
ericrk0a5fa482015-09-15 14:16:10 -0700346}
Brian Osman71a18892017-08-10 10:23:25 -0400347
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400348//////////////////////////////////////////////////////////////////////////////
349GrBackendTexture GrContext::createBackendTexture(int width, int height,
Greg Danielf91aeb22019-06-18 09:58:02 -0400350 const GrBackendFormat& backendFormat,
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400351 GrMipMapped mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400352 GrRenderable renderable,
353 GrProtected isProtected) {
Brian Salomonc42eb662019-06-24 17:13:00 -0400354 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400355 if (!this->asDirectContext()) {
356 return GrBackendTexture();
357 }
358
359 if (this->abandoned()) {
360 return GrBackendTexture();
361 }
362
Robert Phillipsf0313ee2019-05-21 13:51:11 -0400363 return fGpu->createBackendTexture(width, height, backendFormat,
364 mipMapped, renderable,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400365 nullptr, 0, nullptr, isProtected);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400366}
367
368GrBackendTexture GrContext::createBackendTexture(int width, int height,
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400369 SkColorType skColorType,
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400370 GrMipMapped mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400371 GrRenderable renderable,
372 GrProtected isProtected) {
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400373 if (!this->asDirectContext()) {
374 return GrBackendTexture();
375 }
376
377 if (this->abandoned()) {
378 return GrBackendTexture();
379 }
380
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400381 const GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400382
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400383 return this->createBackendTexture(width, height, format, mipMapped, renderable, isProtected);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400384}
385
Robert Phillips02dc0302019-07-02 17:58:27 -0400386GrBackendTexture GrContext::createBackendTexture(const SkSurfaceCharacterization& c) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400387 if (!this->asDirectContext() || !c.isValid()) {
388 return GrBackendTexture();
389 }
390
391 if (this->abandoned()) {
392 return GrBackendTexture();
393 }
394
395 if (c.usesGLFBO0()) {
396 // If we are making the surface we will never use FBO0.
397 return GrBackendTexture();
398 }
399
400 if (c.vulkanSecondaryCBCompatible()) {
401 return {};
402 }
403
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400404 const GrBackendFormat format = this->defaultBackendFormat(c.colorType(), GrRenderable::kYes);
Robert Phillips02dc0302019-07-02 17:58:27 -0400405 if (!format.isValid()) {
406 return GrBackendTexture();
407 }
408
Robert Phillips02dc0302019-07-02 17:58:27 -0400409 GrBackendTexture result = this->createBackendTexture(c.width(), c.height(), format,
410 GrMipMapped(c.isMipMapped()),
411 GrRenderable::kYes,
Robert Phillips3cd54322019-07-10 09:28:59 -0400412 c.isProtected());
Robert Phillips02dc0302019-07-02 17:58:27 -0400413 SkASSERT(c.isCompatible(result));
414 return result;
415}
416
417GrBackendTexture GrContext::createBackendTexture(const SkSurfaceCharacterization& c,
418 const SkColor4f& color) {
Robert Phillips02dc0302019-07-02 17:58:27 -0400419 if (!this->asDirectContext() || !c.isValid()) {
420 return GrBackendTexture();
421 }
422
423 if (this->abandoned()) {
424 return GrBackendTexture();
425 }
426
427 if (c.usesGLFBO0()) {
428 // If we are making the surface we will never use FBO0.
429 return GrBackendTexture();
430 }
431
432 if (c.vulkanSecondaryCBCompatible()) {
433 return {};
434 }
435
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400436 const GrBackendFormat format = this->defaultBackendFormat(c.colorType(), GrRenderable::kYes);
Robert Phillips02dc0302019-07-02 17:58:27 -0400437 if (!format.isValid()) {
438 return GrBackendTexture();
439 }
440
Robert Phillips02dc0302019-07-02 17:58:27 -0400441 GrBackendTexture result = this->createBackendTexture(c.width(), c.height(), format, color,
442 GrMipMapped(c.isMipMapped()),
443 GrRenderable::kYes,
Robert Phillips3cd54322019-07-10 09:28:59 -0400444 c.isProtected());
Robert Phillips02dc0302019-07-02 17:58:27 -0400445 SkASSERT(c.isCompatible(result));
446 return result;
447}
448
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400449GrBackendTexture GrContext::createBackendTexture(int width, int height,
Greg Danielf91aeb22019-06-18 09:58:02 -0400450 const GrBackendFormat& backendFormat,
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400451 const SkColor4f& color,
452 GrMipMapped mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400453 GrRenderable renderable,
454 GrProtected isProtected) {
Brian Salomonc42eb662019-06-24 17:13:00 -0400455 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400456 if (!this->asDirectContext()) {
457 return GrBackendTexture();
458 }
459
460 if (this->abandoned()) {
461 return GrBackendTexture();
462 }
463
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400464 return fGpu->createBackendTexture(width, height, backendFormat,
465 mipMapped, renderable,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400466 nullptr, 0, &color, isProtected);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400467}
468
469GrBackendTexture GrContext::createBackendTexture(int width, int height,
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400470 SkColorType skColorType,
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400471 const SkColor4f& color,
472 GrMipMapped mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400473 GrRenderable renderable,
474 GrProtected isProtected) {
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400475 if (!this->asDirectContext()) {
476 return GrBackendTexture();
477 }
478
479 if (this->abandoned()) {
480 return GrBackendTexture();
481 }
482
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400483 GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400484 if (!format.isValid()) {
485 return GrBackendTexture();
486 }
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400487
488 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
489 SkColor4f swizzledColor = this->caps()->getOutputSwizzle(format, grColorType).applyTo(color);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400490
Brian Salomonb450f3b2019-07-09 09:36:51 -0400491 return this->createBackendTexture(width, height, format, swizzledColor, mipMapped, renderable,
492 isProtected);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400493}
494
Robert Phillips66944402019-09-30 13:21:25 -0400495GrBackendTexture GrContext::createBackendTexture(const SkPixmap srcData[], int numLevels,
496 GrRenderable renderable, GrProtected isProtected) {
497 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
498
499 if (!this->asDirectContext()) {
500 return {};
501 }
502
503 if (this->abandoned()) {
504 return {};
505 }
506
507 if (!srcData || !numLevels) {
508 return {};
509 }
510
511 int baseWidth = srcData[0].width();
512 int baseHeight = srcData[0].height();
513 SkColorType colorType = srcData[0].colorType();
514
515 GrBackendFormat backendFormat = this->defaultBackendFormat(colorType, renderable);
516
517 return fGpu->createBackendTexture(baseWidth, baseHeight, backendFormat,
518 numLevels > 1 ? GrMipMapped::kYes : GrMipMapped::kNo,
519 renderable, srcData, numLevels, nullptr, isProtected);
520}
521
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400522void GrContext::deleteBackendTexture(GrBackendTexture backendTex) {
Brian Salomonc42eb662019-06-24 17:13:00 -0400523 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400524 if (this->abandoned() || !backendTex.isValid()) {
525 return;
526 }
527
Robert Phillipsf0313ee2019-05-21 13:51:11 -0400528 fGpu->deleteBackendTexture(backendTex);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400529}
530
Brian Osmaned58e002019-09-06 14:42:43 -0400531bool GrContext::precompileShader(const SkData& key, const SkData& data) {
532 return fGpu->precompileShader(key, data);
533}
534
Brian Salomonec22b1a2019-08-09 09:41:48 -0400535#ifdef SK_ENABLE_DUMP_GPU
536#include "src/utils/SkJSONWriter.h"
537SkString GrContext::dump() const {
538 SkDynamicMemoryWStream stream;
539 SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
540 writer.beginObject();
541
542 writer.appendString("backend", GrBackendApiToStr(this->backend()));
543
544 writer.appendName("caps");
545 this->caps()->dumpJSON(&writer);
546
547 writer.appendName("gpu");
548 this->fGpu->dumpJSON(&writer);
549
550 // Flush JSON to the memory stream
551 writer.endObject();
552 writer.flush();
553
554 // Null terminate the JSON data in the memory stream
555 stream.write8(0);
556
557 // Allocate a string big enough to hold all the data, then copy out of the stream
558 SkString result(stream.bytesWritten());
559 stream.copyToAndReset(result.writable_str());
560 return result;
561}
562#endif