blob: 2788aae0d91fa53718df3cf66e95618e015958cd [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
Robert Phillips4e105e22020-07-16 09:18:50 -04008#include "include/gpu/GrDirectContext.h"
Brian Salomon9241a6d2019-10-03 13:26:54 -04009
Robert Phillips4d5594d2020-02-21 14:24:40 -050010#include "include/core/SkDeferredDisplayList.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkTraceMemoryDump.h"
12#include "include/gpu/GrBackendSemaphore.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/private/SkImageInfoPriv.h"
Mike Reed13711eb2020-07-14 17:16:32 -040014#include "src/core/SkMipmap.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/core/SkTaskGroup.h"
Brian Salomon9241a6d2019-10-03 13:26:54 -040016#include "src/gpu/GrClientMappedBufferManager.h"
Greg Daniel7fd7a8a2019-10-10 16:10:31 -040017#include "src/gpu/GrContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "src/gpu/GrDrawingManager.h"
19#include "src/gpu/GrGpu.h"
Adlai Holler302e8fb2020-09-14 11:58:06 -040020#include "src/gpu/GrImageContextPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "src/gpu/GrMemoryPool.h"
22#include "src/gpu/GrPathRendererChain.h"
23#include "src/gpu/GrProxyProvider.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040024#include "src/gpu/GrRenderTargetProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050025#include "src/gpu/GrResourceCache.h"
26#include "src/gpu/GrResourceProvider.h"
27#include "src/gpu/GrSemaphore.h"
28#include "src/gpu/GrSoftwarePathRenderer.h"
Robert Phillipsd464feb2020-10-08 11:00:02 -040029#include "src/gpu/GrThreadSafeCache.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "src/gpu/GrTracing.h"
31#include "src/gpu/SkGr.h"
32#include "src/gpu/ccpr/GrCoverageCountingPathRenderer.h"
33#include "src/gpu/effects/GrSkSLFP.h"
Herb Derbya08bde62020-06-12 15:46:06 -040034#include "src/gpu/text/GrSDFTOptions.h"
Robert Phillips41bd97d2020-04-07 14:19:37 -040035#include "src/gpu/text/GrStrikeCache.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050036#include "src/gpu/text/GrTextBlobCache.h"
Greg Daniel7fd7a8a2019-10-10 16:10:31 -040037#include "src/image/SkImage_GpuBase.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050038#include "src/image/SkSurface_Gpu.h"
Mike Klein0ec1c572018-12-04 11:52:51 -050039#include <atomic>
John Stilesfbd050b2020-08-03 13:21:46 -040040#include <memory>
Greg Danielb76a72a2017-07-13 15:07:54 -040041
Robert Phillipse78b7252017-04-06 07:59:41 -040042#define ASSERT_OWNED_PROXY(P) \
Brian Salomonfd98c2c2018-07-31 17:25:29 -040043 SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == this)
Robert Phillips7ee385e2017-03-30 08:02:11 -040044
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000045#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
Adlai Holler33dbd652020-06-01 12:35:42 -040046#define ASSERT_SINGLE_OWNER GR_ASSERT_SINGLE_OWNER(this->singleOwner())
Robert Phillipsa9162df2019-02-11 14:12:03 -050047#define RETURN_IF_ABANDONED if (this->abandoned()) { return; }
48#define RETURN_FALSE_IF_ABANDONED if (this->abandoned()) { return false; }
49#define RETURN_NULL_IF_ABANDONED if (this->abandoned()) { return nullptr; }
bsalomon@google.combc4b6542011-11-19 13:56:11 +000050
robertphillipsea461502015-05-26 11:38:03 -070051////////////////////////////////////////////////////////////////////////////////
52
Adlai Holler9555f292020-10-09 09:41:14 -040053GrContext::GrContext(sk_sp<GrContextThreadSafeProxy> proxy) : INHERITED(std::move(proxy)) { }
Jim Van Verthe9b9c3b2020-10-08 21:00:25 +000054
Adlai Holler9555f292020-10-09 09:41:14 -040055GrContext::~GrContext() = default;
bsalomon@google.comc0af3172012-06-15 14:10:09 +000056
Brian Salomonc7fe0f72018-05-11 10:14:21 -040057//////////////////////////////////////////////////////////////////////////////
58
bsalomon@google.com8fe72472011-03-30 21:26:44 +000059void GrContext::freeGpuResources() {
joshualitt1de610a2016-01-06 08:26:09 -080060 ASSERT_SINGLE_OWNER
61
Adlai Holler9d8a41c2020-06-25 14:01:58 +000062 if (this->abandoned()) {
63 return;
64 }
65
Robert Phillips2184fb72019-02-21 16:11:41 -050066 // TODO: the glyph cache doesn't hold any GpuResources so this call should not be needed here.
67 // Some slack in the GrTextBlob's implementation requires it though. That could be fixed.
Robert Phillips4d932d12020-04-09 08:58:52 -040068 fStrikeCache->freeAll();
robertphillips68737822015-10-29 12:12:21 -070069
Robert Phillips6a6de562019-02-15 15:19:15 -050070 this->drawingManager()->freeGpuResources();
bsalomon3033b9f2015-04-13 11:09:56 -070071
72 fResourceCache->purgeAllUnlocked();
bsalomon@google.com27847de2011-02-22 20:59:41 +000073}
74
Robert Phillips6eba0632018-03-28 12:25:42 -040075void GrContext::purgeUnlockedResources(bool scratchResourcesOnly) {
76 ASSERT_SINGLE_OWNER
Robert Phillipsddc21482019-10-16 14:30:09 -040077
78 if (this->abandoned()) {
79 return;
80 }
81
Robert Phillips6eba0632018-03-28 12:25:42 -040082 fResourceCache->purgeUnlockedResources(scratchResourcesOnly);
83 fResourceCache->purgeAsNeeded();
Robert Phillips2184fb72019-02-21 16:11:41 -050084
85 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
86 // place to purge stale blobs
87 this->getTextBlobCache()->purgeStaleBlobs();
Robert Phillips6eba0632018-03-28 12:25:42 -040088}
89
Jim Van Verth76d917c2017-12-13 09:26:37 -050090void GrContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed) {
Yuqian Li40aa85f2019-07-02 13:45:00 -070091 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
92
Brian Salomon5e150852017-03-22 14:53:13 -040093 ASSERT_SINGLE_OWNER
Chris Dalton6c3879d2018-11-01 11:13:19 -060094
Brian Salomon9241a6d2019-10-03 13:26:54 -040095 if (this->abandoned()) {
96 return;
97 }
98
Jim Van Verthe0da3792020-08-14 16:50:19 -040099 this->checkAsyncWorkCompletion();
Brian Salomon9241a6d2019-10-03 13:26:54 -0400100 fMappedBufferManager->process();
Chris Dalton6c3879d2018-11-01 11:13:19 -0600101 auto purgeTime = GrStdSteadyClock::now() - msNotUsed;
102
Jim Van Verth76d917c2017-12-13 09:26:37 -0500103 fResourceCache->purgeAsNeeded();
Chris Dalton6c3879d2018-11-01 11:13:19 -0600104 fResourceCache->purgeResourcesNotUsedSince(purgeTime);
105
Robert Phillips6a6de562019-02-15 15:19:15 -0500106 if (auto ccpr = this->drawingManager()->getCoverageCountingPathRenderer()) {
Robert Phillipsa41c6852019-02-07 10:44:10 -0500107 ccpr->purgeCacheEntriesOlderThan(this->proxyProvider(), purgeTime);
Chris Dalton6c3879d2018-11-01 11:13:19 -0600108 }
Jim Van Verth76d917c2017-12-13 09:26:37 -0500109
Robert Phillips2184fb72019-02-21 16:11:41 -0500110 // The textBlob Cache doesn't actually hold any GPU resource but this is a convenient
111 // place to purge stale blobs
112 this->getTextBlobCache()->purgeStaleBlobs();
Brian Salomon5e150852017-03-22 14:53:13 -0400113}
114
Derek Sollenberger5480a182017-05-25 16:43:59 -0400115void GrContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
116 ASSERT_SINGLE_OWNER
Robert Phillipsddc21482019-10-16 14:30:09 -0400117
118 if (this->abandoned()) {
119 return;
120 }
121
Derek Sollenberger5480a182017-05-25 16:43:59 -0400122 fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources);
123}
124
Brian Salomon7e67dca2020-07-21 09:27:25 -0400125size_t GrContext::ComputeImageSize(sk_sp<SkImage> image, GrMipmapped mipMapped, bool useNextPow2) {
Greg Daniel8b666172019-10-09 12:38:22 -0400126 if (!image->isTextureBacked()) {
127 return 0;
128 }
Greg Daniel7fd7a8a2019-10-10 16:10:31 -0400129 SkImage_GpuBase* gpuImage = static_cast<SkImage_GpuBase*>(as_IB(image.get()));
130 GrTextureProxy* proxy = gpuImage->peekProxy();
131 if (!proxy) {
132 return 0;
133 }
134
Greg Daniel8b666172019-10-09 12:38:22 -0400135 int colorSamplesPerPixel = 1;
Greg Daniel0eca74c2020-10-01 13:46:00 -0400136 return GrSurface::ComputeSize(proxy->backendFormat(), image->dimensions(),
Greg Daniel7fd7a8a2019-10-10 16:10:31 -0400137 colorSamplesPerPixel, mipMapped, useNextPow2);
Greg Daniel8b666172019-10-09 12:38:22 -0400138}
139
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000140////////////////////////////////////////////////////////////////////////////////
Greg Daniel414418d2020-07-08 11:44:25 -0400141bool GrContext::wait(int numSemaphores, const GrBackendSemaphore waitSemaphores[],
142 bool deleteSemaphoresAfterWait) {
Brian Salomon9ff5acb2019-05-08 09:04:47 -0400143 if (!fGpu || fGpu->caps()->semaphoreSupport()) {
Greg Daniel06be0792019-04-22 15:53:23 -0400144 return false;
145 }
Greg Daniel414418d2020-07-08 11:44:25 -0400146 GrWrapOwnership ownership =
147 deleteSemaphoresAfterWait ? kAdopt_GrWrapOwnership : kBorrow_GrWrapOwnership;
Greg Daniel06be0792019-04-22 15:53:23 -0400148 for (int i = 0; i < numSemaphores; ++i) {
Greg Daniel301015c2019-11-18 14:06:46 -0500149 std::unique_ptr<GrSemaphore> sema = fResourceProvider->wrapBackendSemaphore(
Greg Daniel414418d2020-07-08 11:44:25 -0400150 waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait, ownership);
Greg Daniel0106fcc2020-07-01 17:40:12 -0400151 // If we failed to wrap the semaphore it means the client didn't give us a valid semaphore
152 // to begin with. Therefore, it is fine to not wait on it.
153 if (sema) {
154 fGpu->waitSemaphore(sema.get());
155 }
Greg Daniel06be0792019-04-22 15:53:23 -0400156 }
157 return true;
158}
159
160////////////////////////////////////////////////////////////////////////////////
161
Greg Daniele8d3cca2020-06-10 10:04:48 -0400162GrSemaphoresSubmitted GrContext::flush(const GrFlushInfo& info) {
Greg Daniel51316782017-08-02 15:10:09 +0000163 ASSERT_SINGLE_OWNER
Robert Phillipsa9162df2019-02-11 14:12:03 -0500164 if (this->abandoned()) {
Greg Daniel55822f12020-05-26 11:26:45 -0400165 if (info.fFinishedProc) {
166 info.fFinishedProc(info.fFinishedContext);
167 }
168 if (info.fSubmittedProc) {
169 info.fSubmittedProc(info.fSubmittedContext, false);
170 }
Robert Phillipsa9162df2019-02-11 14:12:03 -0500171 return GrSemaphoresSubmitted::kNo;
172 }
Greg Daniel51316782017-08-02 15:10:09 +0000173
Greg Daniel04283f32020-05-20 13:16:00 -0400174 bool flushed = this->drawingManager()->flush(
Greg Daniel9efe3862020-06-11 11:51:06 -0400175 nullptr, 0, SkSurface::BackendSurfaceAccess::kNoAccess, info, nullptr);
Greg Danielfe159622020-04-10 17:43:51 +0000176
Greg Daniel04283f32020-05-20 13:16:00 -0400177 if (!flushed || (!this->priv().caps()->semaphoreSupport() && info.fNumSemaphores)) {
Greg Danielfe159622020-04-10 17:43:51 +0000178 return GrSemaphoresSubmitted::kNo;
179 }
180 return GrSemaphoresSubmitted::kYes;
Greg Daniel51316782017-08-02 15:10:09 +0000181}
182
Greg Daniel04283f32020-05-20 13:16:00 -0400183bool GrContext::submit(bool syncCpu) {
184 ASSERT_SINGLE_OWNER
185 if (this->abandoned()) {
186 return false;
187 }
188
189 if (!fGpu) {
190 return false;
191 }
192
193 return fGpu->submitToGpu(syncCpu);
Greg Danielda50cb82020-05-13 14:07:40 -0400194}
195
Greg Daniela870b462019-01-08 15:49:46 -0500196////////////////////////////////////////////////////////////////////////////////
197
Brian Salomonb0d8b762019-05-06 16:58:22 -0400198void GrContext::checkAsyncWorkCompletion() {
199 if (fGpu) {
200 fGpu->checkFinishProcs();
201 }
202}
203
204////////////////////////////////////////////////////////////////////////////////
205
Greg Daniela870b462019-01-08 15:49:46 -0500206void GrContext::storeVkPipelineCacheData() {
207 if (fGpu) {
208 fGpu->storeVkPipelineCacheData();
209 }
210}
211
212////////////////////////////////////////////////////////////////////////////////
213
Khushal3e7548c2018-05-23 15:45:01 -0700214bool GrContext::supportsDistanceFieldText() const {
Robert Phillipsbb606772019-02-04 17:50:57 -0500215 return this->caps()->shaderCaps()->supportsDistanceFieldText();
Khushal3e7548c2018-05-23 15:45:01 -0700216}
217
bsalomon37f9a262015-02-02 13:00:10 -0800218//////////////////////////////////////////////////////////////////////////////
ericrk0a5fa482015-09-15 14:16:10 -0700219void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
joshualitt1de610a2016-01-06 08:26:09 -0800220 ASSERT_SINGLE_OWNER
ericrk0a5fa482015-09-15 14:16:10 -0700221 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
Khushal71652e22018-10-29 13:05:36 -0700222 traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
Robert Phillips2184fb72019-02-21 16:11:41 -0500223 this->getTextBlobCache()->usedBytes());
ericrk0a5fa482015-09-15 14:16:10 -0700224}
Brian Osman71a18892017-08-10 10:23:25 -0400225
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400226//////////////////////////////////////////////////////////////////////////////
227GrBackendTexture GrContext::createBackendTexture(int width, int height,
Greg Danielf91aeb22019-06-18 09:58:02 -0400228 const GrBackendFormat& backendFormat,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400229 GrMipmapped mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400230 GrRenderable renderable,
231 GrProtected isProtected) {
Brian Salomonc42eb662019-06-24 17:13:00 -0400232 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400233 if (!this->asDirectContext()) {
234 return GrBackendTexture();
235 }
236
237 if (this->abandoned()) {
238 return GrBackendTexture();
239 }
240
Robert Phillips4277f012020-01-21 14:28:34 -0500241 return fGpu->createBackendTexture({width, height}, backendFormat, renderable,
Greg Daniel16032b32020-05-06 15:31:10 -0400242 mipMapped, isProtected);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400243}
244
245GrBackendTexture GrContext::createBackendTexture(int width, int height,
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400246 SkColorType skColorType,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400247 GrMipmapped mipMapped,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400248 GrRenderable renderable,
249 GrProtected isProtected) {
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400250 if (!this->asDirectContext()) {
251 return GrBackendTexture();
252 }
253
254 if (this->abandoned()) {
255 return GrBackendTexture();
256 }
257
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400258 const GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400259
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400260 return this->createBackendTexture(width, height, format, mipMapped, renderable, isProtected);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400261}
262
Greg Daniel25597782020-06-11 13:15:08 -0400263static GrBackendTexture create_and_update_backend_texture(
Robert Phillips4e105e22020-07-16 09:18:50 -0400264 GrDirectContext* context,
Greg Daniel25597782020-06-11 13:15:08 -0400265 SkISize dimensions,
266 const GrBackendFormat& backendFormat,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400267 GrMipmapped mipMapped,
Greg Daniel25597782020-06-11 13:15:08 -0400268 GrRenderable renderable,
269 GrProtected isProtected,
270 sk_sp<GrRefCntedCallback> finishedCallback,
271 const GrGpu::BackendTextureData* data) {
Greg Daniel16032b32020-05-06 15:31:10 -0400272 GrGpu* gpu = context->priv().getGpu();
273
274 GrBackendTexture beTex = gpu->createBackendTexture(dimensions, backendFormat, renderable,
275 mipMapped, isProtected);
276 if (!beTex.isValid()) {
277 return {};
278 }
279
Greg Daniel25597782020-06-11 13:15:08 -0400280 if (!context->priv().getGpu()->updateBackendTexture(beTex, std::move(finishedCallback), data)) {
Greg Daniel16032b32020-05-06 15:31:10 -0400281 context->deleteBackendTexture(beTex);
282 return {};
283 }
284 return beTex;
285}
286
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400287GrBackendTexture GrContext::createBackendTexture(int width, int height,
Greg Danielf91aeb22019-06-18 09:58:02 -0400288 const GrBackendFormat& backendFormat,
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400289 const SkColor4f& color,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400290 GrMipmapped mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400291 GrRenderable renderable,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400292 GrProtected isProtected,
293 GrGpuFinishedProc finishedProc,
294 GrGpuFinishedContext finishedContext) {
Greg Daniel25597782020-06-11 13:15:08 -0400295 sk_sp<GrRefCntedCallback> finishedCallback;
296 if (finishedProc) {
297 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
298 }
299
Brian Salomonc42eb662019-06-24 17:13:00 -0400300 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400301 if (!this->asDirectContext()) {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400302 return {};
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400303 }
304
305 if (this->abandoned()) {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400306 return {};
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400307 }
308
Brian Salomon85c3d682019-11-04 15:04:54 -0500309 GrGpu::BackendTextureData data(color);
Robert Phillips4e105e22020-07-16 09:18:50 -0400310 return create_and_update_backend_texture(this->asDirectContext(), {width, height},
311 backendFormat, mipMapped, renderable, isProtected,
312 std::move(finishedCallback), &data);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400313}
314
315GrBackendTexture GrContext::createBackendTexture(int width, int height,
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400316 SkColorType skColorType,
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400317 const SkColor4f& color,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400318 GrMipmapped mipMapped,
Robert Phillipsda2e67a2019-07-01 15:04:06 -0400319 GrRenderable renderable,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400320 GrProtected isProtected,
321 GrGpuFinishedProc finishedProc,
322 GrGpuFinishedContext finishedContext) {
Greg Daniel25597782020-06-11 13:15:08 -0400323 sk_sp<GrRefCntedCallback> finishedCallback;
324 if (finishedProc) {
325 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
326 }
327
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400328 if (!this->asDirectContext()) {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400329 return {};
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400330 }
331
332 if (this->abandoned()) {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400333 return {};
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400334 }
335
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400336 GrBackendFormat format = this->defaultBackendFormat(skColorType, renderable);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400337 if (!format.isValid()) {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400338 return {};
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400339 }
Robert Phillipsd5e80ca2019-07-29 14:11:35 -0400340
341 GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
Brian Salomon982f5462020-03-30 12:52:33 -0400342 SkColor4f swizzledColor = this->caps()->getWriteSwizzle(format, grColorType).applyTo(color);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400343
Greg Daniel25597782020-06-11 13:15:08 -0400344 GrGpu::BackendTextureData data(swizzledColor);
Robert Phillips4e105e22020-07-16 09:18:50 -0400345 return create_and_update_backend_texture(this->asDirectContext(), {width, height}, format,
346 mipMapped, renderable, isProtected,
347 std::move(finishedCallback), &data);
Robert Phillips4bdd36f2019-06-04 11:03:06 -0400348}
349
Robert Phillipsba5c7ad2020-01-24 11:03:33 -0500350GrBackendTexture GrContext::createBackendTexture(const SkPixmap srcData[], int numProvidedLevels,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400351 GrRenderable renderable, GrProtected isProtected,
352 GrGpuFinishedProc finishedProc,
353 GrGpuFinishedContext finishedContext) {
Robert Phillips66944402019-09-30 13:21:25 -0400354 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
355
Greg Daniel25597782020-06-11 13:15:08 -0400356 sk_sp<GrRefCntedCallback> finishedCallback;
357 if (finishedProc) {
358 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
359 }
360
Robert Phillips66944402019-09-30 13:21:25 -0400361 if (!this->asDirectContext()) {
362 return {};
363 }
364
365 if (this->abandoned()) {
366 return {};
367 }
368
Robert Phillipsba5c7ad2020-01-24 11:03:33 -0500369 if (!srcData || numProvidedLevels <= 0) {
Robert Phillips66944402019-09-30 13:21:25 -0400370 return {};
371 }
372
373 int baseWidth = srcData[0].width();
374 int baseHeight = srcData[0].height();
375 SkColorType colorType = srcData[0].colorType();
376
Brian Salomon7e67dca2020-07-21 09:27:25 -0400377 GrMipmapped mipMapped = GrMipmapped::kNo;
Robert Phillipsba5c7ad2020-01-24 11:03:33 -0500378 int numExpectedLevels = 1;
379 if (numProvidedLevels > 1) {
Mike Reed13711eb2020-07-14 17:16:32 -0400380 numExpectedLevels = SkMipmap::ComputeLevelCount(baseWidth, baseHeight) + 1;
Brian Salomon7e67dca2020-07-21 09:27:25 -0400381 mipMapped = GrMipmapped::kYes;
Robert Phillipsba5c7ad2020-01-24 11:03:33 -0500382 }
383
384 if (numProvidedLevels != numExpectedLevels) {
385 return {};
386 }
387
Robert Phillips66944402019-09-30 13:21:25 -0400388 GrBackendFormat backendFormat = this->defaultBackendFormat(colorType, renderable);
389
Brian Salomon85c3d682019-11-04 15:04:54 -0500390 GrGpu::BackendTextureData data(srcData);
Robert Phillips4e105e22020-07-16 09:18:50 -0400391 return create_and_update_backend_texture(this->asDirectContext(), {baseWidth, baseHeight},
392 backendFormat, mipMapped, renderable, isProtected,
Greg Daniel25597782020-06-11 13:15:08 -0400393 std::move(finishedCallback), &data);
Robert Phillips66944402019-09-30 13:21:25 -0400394}
395
Greg Danielb2365d82020-05-13 15:32:04 -0400396bool GrContext::updateBackendTexture(const GrBackendTexture& backendTexture,
397 const SkColor4f& color,
398 GrGpuFinishedProc finishedProc,
399 GrGpuFinishedContext finishedContext) {
Greg Daniel25597782020-06-11 13:15:08 -0400400 sk_sp<GrRefCntedCallback> finishedCallback;
401 if (finishedProc) {
402 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
403 }
404
Greg Danielb2365d82020-05-13 15:32:04 -0400405 if (!this->asDirectContext()) {
Greg Danielb2365d82020-05-13 15:32:04 -0400406 return false;
407 }
408
409 if (this->abandoned()) {
Greg Danielb2365d82020-05-13 15:32:04 -0400410 return false;
411 }
412
413 GrGpu::BackendTextureData data(color);
Greg Daniel25597782020-06-11 13:15:08 -0400414 return fGpu->updateBackendTexture(backendTexture, std::move(finishedCallback), &data);
Greg Danielb2365d82020-05-13 15:32:04 -0400415}
416
417bool GrContext::updateBackendTexture(const GrBackendTexture& backendTexture,
Greg Daniel373d7dd2020-07-21 10:41:50 -0400418 SkColorType skColorType,
419 const SkColor4f& color,
420 GrGpuFinishedProc finishedProc,
421 GrGpuFinishedContext finishedContext) {
422 sk_sp<GrRefCntedCallback> finishedCallback;
423 if (finishedProc) {
424 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
425 }
426
427 if (!this->asDirectContext()) {
428 return false;
429 }
430
431 if (this->abandoned()) {
432 return false;
433 }
434
435 GrBackendFormat format = backendTexture.getBackendFormat();
436 GrColorType grColorType = SkColorTypeAndFormatToGrColorType(this->caps(), skColorType, format);
437
438 if (!this->caps()->areColorTypeAndFormatCompatible(grColorType, format)) {
439 return false;
440 }
441
442 GrSwizzle swizzle = this->caps()->getWriteSwizzle(format, grColorType);
443 GrGpu::BackendTextureData data(swizzle.applyTo(color));
444
445 return fGpu->updateBackendTexture(backendTexture, std::move(finishedCallback), &data);
446}
447
448bool GrContext::updateBackendTexture(const GrBackendTexture& backendTexture,
Greg Danielb2365d82020-05-13 15:32:04 -0400449 const SkPixmap srcData[],
450 int numLevels,
451 GrGpuFinishedProc finishedProc,
452 GrGpuFinishedContext finishedContext) {
Greg Daniel25597782020-06-11 13:15:08 -0400453 sk_sp<GrRefCntedCallback> finishedCallback;
454 if (finishedProc) {
455 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
456 }
457
Greg Danielb2365d82020-05-13 15:32:04 -0400458 if (!this->asDirectContext()) {
Greg Danielb2365d82020-05-13 15:32:04 -0400459 return false;
460 }
461
462 if (this->abandoned()) {
Greg Danielb2365d82020-05-13 15:32:04 -0400463 return false;
464 }
465
466 if (!srcData || numLevels <= 0) {
Greg Danielb2365d82020-05-13 15:32:04 -0400467 return false;
468 }
469
470 int numExpectedLevels = 1;
Brian Salomon40a40622020-07-21 10:32:07 -0400471 if (backendTexture.hasMipmaps()) {
Mike Reed13711eb2020-07-14 17:16:32 -0400472 numExpectedLevels = SkMipmap::ComputeLevelCount(backendTexture.width(),
Greg Danielb2365d82020-05-13 15:32:04 -0400473 backendTexture.height()) + 1;
474 }
475 if (numLevels != numExpectedLevels) {
Greg Danielb2365d82020-05-13 15:32:04 -0400476 return false;
477 }
478
479 GrGpu::BackendTextureData data(srcData);
Greg Daniel25597782020-06-11 13:15:08 -0400480 return fGpu->updateBackendTexture(backendTexture, std::move(finishedCallback), &data);
Greg Danielb2365d82020-05-13 15:32:04 -0400481}
482
Robert Phillipsb915c942019-12-17 14:44:37 -0500483//////////////////////////////////////////////////////////////////////////////
484
Greg Danielaaf738c2020-07-10 09:30:33 -0400485static GrBackendTexture create_and_update_compressed_backend_texture(
Robert Phillips4e105e22020-07-16 09:18:50 -0400486 GrDirectContext* context,
Greg Danielaaf738c2020-07-10 09:30:33 -0400487 SkISize dimensions,
488 const GrBackendFormat& backendFormat,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400489 GrMipmapped mipMapped,
Greg Danielaaf738c2020-07-10 09:30:33 -0400490 GrProtected isProtected,
491 sk_sp<GrRefCntedCallback> finishedCallback,
492 const GrGpu::BackendTextureData* data) {
493 GrGpu* gpu = context->priv().getGpu();
494
495 GrBackendTexture beTex = gpu->createCompressedBackendTexture(dimensions, backendFormat,
496 mipMapped, isProtected);
497 if (!beTex.isValid()) {
498 return {};
499 }
500
501 if (!context->priv().getGpu()->updateCompressedBackendTexture(
502 beTex, std::move(finishedCallback), data)) {
503 context->deleteBackendTexture(beTex);
504 return {};
505 }
506 return beTex;
507}
508
Robert Phillipsb915c942019-12-17 14:44:37 -0500509GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height,
510 const GrBackendFormat& backendFormat,
511 const SkColor4f& color,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400512 GrMipmapped mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400513 GrProtected isProtected,
514 GrGpuFinishedProc finishedProc,
515 GrGpuFinishedContext finishedContext) {
Robert Phillipsb915c942019-12-17 14:44:37 -0500516 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Greg Daniel25597782020-06-11 13:15:08 -0400517 sk_sp<GrRefCntedCallback> finishedCallback;
518 if (finishedProc) {
519 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
520 }
521
Robert Phillipsb915c942019-12-17 14:44:37 -0500522 if (!this->asDirectContext()) {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400523 return {};
Robert Phillipsb915c942019-12-17 14:44:37 -0500524 }
525
526 if (this->abandoned()) {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400527 return {};
Robert Phillipsb915c942019-12-17 14:44:37 -0500528 }
529
530 GrGpu::BackendTextureData data(color);
Robert Phillips4e105e22020-07-16 09:18:50 -0400531 return create_and_update_compressed_backend_texture(this->asDirectContext(), {width, height},
532 backendFormat, mipMapped, isProtected,
Greg Danielaaf738c2020-07-10 09:30:33 -0400533 std::move(finishedCallback), &data);
Robert Phillipsb915c942019-12-17 14:44:37 -0500534}
535
536GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height,
537 SkImage::CompressionType compression,
538 const SkColor4f& color,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400539 GrMipmapped mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400540 GrProtected isProtected,
541 GrGpuFinishedProc finishedProc,
542 GrGpuFinishedContext finishedContext) {
Robert Phillipsb915c942019-12-17 14:44:37 -0500543 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Robert Phillipsb915c942019-12-17 14:44:37 -0500544 GrBackendFormat format = this->compressedBackendFormat(compression);
545 return this->createCompressedBackendTexture(width, height, format, color,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400546 mipMapped, isProtected, finishedProc,
547 finishedContext);
Robert Phillipsb915c942019-12-17 14:44:37 -0500548}
549
550GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height,
551 const GrBackendFormat& backendFormat,
552 const void* compressedData,
553 size_t dataSize,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400554 GrMipmapped mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400555 GrProtected isProtected,
556 GrGpuFinishedProc finishedProc,
557 GrGpuFinishedContext finishedContext) {
Robert Phillipsb915c942019-12-17 14:44:37 -0500558 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Greg Daniel25597782020-06-11 13:15:08 -0400559 sk_sp<GrRefCntedCallback> finishedCallback;
560 if (finishedProc) {
561 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
562 }
563
Robert Phillipsb915c942019-12-17 14:44:37 -0500564 if (!this->asDirectContext()) {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400565 return {};
Robert Phillipsb915c942019-12-17 14:44:37 -0500566 }
567
568 if (this->abandoned()) {
Greg Danielc1ad77c2020-05-06 11:40:03 -0400569 return {};
Robert Phillipsb915c942019-12-17 14:44:37 -0500570 }
571
572 GrGpu::BackendTextureData data(compressedData, dataSize);
Robert Phillips4e105e22020-07-16 09:18:50 -0400573 return create_and_update_compressed_backend_texture(this->asDirectContext(), {width, height},
574 backendFormat, mipMapped, isProtected,
Greg Danielaaf738c2020-07-10 09:30:33 -0400575 std::move(finishedCallback), &data);
Robert Phillipsb915c942019-12-17 14:44:37 -0500576}
577
578GrBackendTexture GrContext::createCompressedBackendTexture(int width, int height,
579 SkImage::CompressionType compression,
580 const void* data, size_t dataSize,
Brian Salomon7e67dca2020-07-21 09:27:25 -0400581 GrMipmapped mipMapped,
Greg Danielc1ad77c2020-05-06 11:40:03 -0400582 GrProtected isProtected,
583 GrGpuFinishedProc finishedProc,
584 GrGpuFinishedContext finishedContext) {
Robert Phillipsb915c942019-12-17 14:44:37 -0500585 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Robert Phillipsb915c942019-12-17 14:44:37 -0500586 GrBackendFormat format = this->compressedBackendFormat(compression);
Greg Daniel25597782020-06-11 13:15:08 -0400587 return this->createCompressedBackendTexture(width, height, format, data, dataSize, mipMapped,
588 isProtected, finishedProc, finishedContext);
Robert Phillipsb915c942019-12-17 14:44:37 -0500589}
590
Greg Daniel1db8e792020-06-09 17:29:32 -0400591bool GrContext::setBackendTextureState(const GrBackendTexture& backendTexture,
592 const GrBackendSurfaceMutableState& state,
Greg Daniel1d3c8c12020-09-23 14:23:36 -0400593 GrBackendSurfaceMutableState* previousState,
Greg Daniel1db8e792020-06-09 17:29:32 -0400594 GrGpuFinishedProc finishedProc,
595 GrGpuFinishedContext finishedContext) {
Greg Daniel1db8e792020-06-09 17:29:32 -0400596 sk_sp<GrRefCntedCallback> callback;
597 if (finishedProc) {
598 callback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
599 }
Greg Daniel25597782020-06-11 13:15:08 -0400600
601 if (!this->asDirectContext()) {
602 return false;
603 }
604
605 if (this->abandoned()) {
606 return false;
607 }
608
Greg Daniel1d3c8c12020-09-23 14:23:36 -0400609 return fGpu->setBackendTextureState(backendTexture, state, previousState, std::move(callback));
Greg Daniel1db8e792020-06-09 17:29:32 -0400610}
611
Greg Daniel95afafb2020-07-22 12:09:26 -0400612bool GrContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
613 const SkColor4f& color,
614 GrGpuFinishedProc finishedProc,
615 GrGpuFinishedContext finishedContext) {
616 sk_sp<GrRefCntedCallback> finishedCallback;
617 if (finishedProc) {
618 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
619 }
620
621 if (!this->asDirectContext()) {
622 return false;
623 }
624
625 if (this->abandoned()) {
626 return false;
627 }
628
629 GrGpu::BackendTextureData data(color);
630 return fGpu->updateCompressedBackendTexture(backendTexture, std::move(finishedCallback), &data);
631}
632
633bool GrContext::updateCompressedBackendTexture(const GrBackendTexture& backendTexture,
634 const void* compressedData,
635 size_t dataSize,
636 GrGpuFinishedProc finishedProc,
637 GrGpuFinishedContext finishedContext) {
638 sk_sp<GrRefCntedCallback> finishedCallback;
639 if (finishedProc) {
640 finishedCallback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
641 }
642
643 if (!this->asDirectContext()) {
644 return false;
645 }
646
647 if (this->abandoned()) {
648 return false;
649 }
650
651 if (!compressedData) {
652 return false;
653 }
654
655 GrGpu::BackendTextureData data(compressedData, dataSize);
656
657 return fGpu->updateCompressedBackendTexture(backendTexture, std::move(finishedCallback), &data);
658}
659
660//////////////////////////////////////////////////////////////////////////////
661
Greg Daniel1db8e792020-06-09 17:29:32 -0400662bool GrContext::setBackendRenderTargetState(const GrBackendRenderTarget& backendRenderTarget,
663 const GrBackendSurfaceMutableState& state,
Greg Daniel1d3c8c12020-09-23 14:23:36 -0400664 GrBackendSurfaceMutableState* previousState,
Greg Daniel1db8e792020-06-09 17:29:32 -0400665 GrGpuFinishedProc finishedProc,
666 GrGpuFinishedContext finishedContext) {
Greg Daniel1db8e792020-06-09 17:29:32 -0400667 sk_sp<GrRefCntedCallback> callback;
668 if (finishedProc) {
669 callback.reset(new GrRefCntedCallback(finishedProc, finishedContext));
670 }
Greg Daniel25597782020-06-11 13:15:08 -0400671
672 if (!this->asDirectContext()) {
673 return false;
674 }
675
676 if (this->abandoned()) {
677 return false;
678 }
679
Greg Daniel1d3c8c12020-09-23 14:23:36 -0400680 return fGpu->setBackendRenderTargetState(backendRenderTarget, state, previousState,
681 std::move(callback));
Greg Daniel1db8e792020-06-09 17:29:32 -0400682}
683
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400684void GrContext::deleteBackendTexture(GrBackendTexture backendTex) {
Brian Salomonc42eb662019-06-24 17:13:00 -0400685 TRACE_EVENT0("skia.gpu", TRACE_FUNC);
Greg Danielf0e04f02019-12-04 15:17:54 -0500686 // For the Vulkan backend we still must destroy the backend texture when the context is
687 // abandoned.
688 if ((this->abandoned() && this->backend() != GrBackendApi::kVulkan) || !backendTex.isValid()) {
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400689 return;
690 }
691
Robert Phillipsf0313ee2019-05-21 13:51:11 -0400692 fGpu->deleteBackendTexture(backendTex);
Robert Phillips5c7a25b2019-05-20 08:38:07 -0400693}
694
Greg Daniel1db8e792020-06-09 17:29:32 -0400695//////////////////////////////////////////////////////////////////////////////
696
Brian Osmaned58e002019-09-06 14:42:43 -0400697bool GrContext::precompileShader(const SkData& key, const SkData& data) {
698 return fGpu->precompileShader(key, data);
699}
700
Brian Salomonec22b1a2019-08-09 09:41:48 -0400701#ifdef SK_ENABLE_DUMP_GPU
Michael Ludwigdd205452020-03-30 17:16:34 -0400702#include "include/core/SkString.h"
Brian Salomonec22b1a2019-08-09 09:41:48 -0400703#include "src/utils/SkJSONWriter.h"
704SkString GrContext::dump() const {
705 SkDynamicMemoryWStream stream;
706 SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
707 writer.beginObject();
708
709 writer.appendString("backend", GrBackendApiToStr(this->backend()));
710
711 writer.appendName("caps");
712 this->caps()->dumpJSON(&writer);
713
714 writer.appendName("gpu");
715 this->fGpu->dumpJSON(&writer);
716
Robert Phillips273f1072020-05-05 13:03:07 -0400717 writer.appendName("context");
718 this->dumpJSON(&writer);
719
Brian Salomonec22b1a2019-08-09 09:41:48 -0400720 // Flush JSON to the memory stream
721 writer.endObject();
722 writer.flush();
723
724 // Null terminate the JSON data in the memory stream
725 stream.write8(0);
726
727 // Allocate a string big enough to hold all the data, then copy out of the stream
728 SkString result(stream.bytesWritten());
729 stream.copyToAndReset(result.writable_str());
730 return result;
731}
732#endif