blob: c0d3886317fd8aae4cd563ec2ecc2a22b239009d [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
bsalomon@google.com1fadb202011-12-12 16:10:08 +00008#include "GrContext.h"
Brian Salomon5f33a8c2018-02-26 14:32:39 -05009#include "GrBackendSemaphore.h"
Brian Salomonc65aec92017-03-09 09:03:58 -050010#include "GrClip.h"
bsalomon682c2692015-05-22 14:01:46 -070011#include "GrContextOptions.h"
Brian Salomonc65aec92017-03-09 09:03:58 -050012#include "GrContextPriv.h"
robertphillips77a2e522015-10-17 07:43:27 -070013#include "GrDrawingManager.h"
Robert Phillips646e4292017-06-13 12:44:56 -040014#include "GrGpu.h"
Robert Phillipsc994a932018-06-19 13:09:54 -040015#include "GrMemoryPool.h"
Robert Phillips1afd4cd2018-01-08 13:40:32 -050016#include "GrProxyProvider.h"
Brian Osman11052242016-10-27 14:47:55 -040017#include "GrRenderTargetContext.h"
Brian Salomonc65aec92017-03-09 09:03:58 -050018#include "GrRenderTargetProxy.h"
bsalomon0ea80f42015-02-11 10:49:59 -080019#include "GrResourceCache.h"
bsalomond309e7a2015-04-30 14:18:54 -070020#include "GrResourceProvider.h"
Greg Danield85f97d2017-03-07 13:37:21 -050021#include "GrSemaphore.h"
robertphillips@google.com72176b22012-05-23 13:19:12 +000022#include "GrSoftwarePathRenderer.h"
Brian Osman45580d32016-11-23 09:37:01 -050023#include "GrSurfaceContext.h"
bsalomonafbf2d62014-09-30 12:18:44 -070024#include "GrSurfacePriv.h"
Robert Phillips757914d2017-01-25 15:48:30 -050025#include "GrSurfaceProxyPriv.h"
Robert Phillips646e4292017-06-13 12:44:56 -040026#include "GrTexture.h"
Brian Osman45580d32016-11-23 09:37:01 -050027#include "GrTextureContext.h"
Brian Salomondcbb9d92017-07-19 10:53:20 -040028#include "GrTracing.h"
Brian Salomon19eaf2d2018-03-19 16:06:44 -040029#include "SkAutoPixmapStorage.h"
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -050030#include "SkDeferredDisplayList.h"
Brian Osman3b655982017-03-07 16:58:08 -050031#include "SkGr.h"
Mike Reed7fcfb622018-02-09 13:26:46 -050032#include "SkImageInfoPriv.h"
Brian Osman51279982017-08-23 10:12:00 -040033#include "SkMakeUnique.h"
Robert Phillips6b6fcc72018-03-30 13:57:00 -040034#include "SkSurface_Gpu.h"
Brian Osman51279982017-08-23 10:12:00 -040035#include "SkTaskGroup.h"
Matt Sarettc7b29082017-02-09 16:22:39 -050036#include "SkUnPreMultiplyPriv.h"
joshualitt5478d422014-11-14 16:00:38 -080037#include "effects/GrConfigConversionEffect.h"
Ethan Nicholas00543112018-07-31 09:44:36 -040038#include "effects/GrSkSLFP.h"
Brian Salomon5f33a8c2018-02-26 14:32:39 -050039#include "text/GrTextBlobCache.h"
Ethan Nicholas00543112018-07-31 09:44:36 -040040#include <unordered_map>
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#define ASSERT_OWNED_PROXY_PRIV(P) \
Brian Salomonfd98c2c2018-07-31 17:25:29 -040045 SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == fContext)
Robert Phillips7ee385e2017-03-30 08:02:11 -040046
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000047#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
joshualitt1de610a2016-01-06 08:26:09 -080048#define ASSERT_SINGLE_OWNER \
49 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fSingleOwner);)
robertphillips4fd74ae2016-08-03 14:26:53 -070050#define ASSERT_SINGLE_OWNER_PRIV \
51 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fContext->fSingleOwner);)
robertphillips7761d612016-05-16 09:14:53 -070052#define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; }
Robert Phillips7ee385e2017-03-30 08:02:11 -040053#define RETURN_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return; }
robertphillips7761d612016-05-16 09:14:53 -070054#define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; }
Robert Phillipse78b7252017-04-06 07:59:41 -040055#define RETURN_FALSE_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return false; }
robertphillips7761d612016-05-16 09:14:53 -070056#define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; }
bsalomon@google.combc4b6542011-11-19 13:56:11 +000057
robertphillipsea461502015-05-26 11:38:03 -070058////////////////////////////////////////////////////////////////////////////////
59
joshualitt0acd0d32015-05-07 08:23:19 -070060static int32_t gNextID = 1;
61static int32_t next_id() {
62 int32_t id;
63 do {
64 id = sk_atomic_inc(&gNextID);
65 } while (id == SK_InvalidGenID);
66 return id;
67}
68
Robert Phillipsfde6fa02018-03-02 08:53:14 -050069GrContext::GrContext(GrBackend backend, int32_t id)
70 : fBackend(backend)
71 , fUniqueID(SK_InvalidGenID == id ? next_id() : id) {
halcanary96fcdcc2015-08-27 07:41:13 -070072 fResourceCache = nullptr;
73 fResourceProvider = nullptr;
Robert Phillips1afd4cd2018-01-08 13:40:32 -050074 fProxyProvider = nullptr;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050075 fGlyphCache = nullptr;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000076}
77
Robert Phillipsfde6fa02018-03-02 08:53:14 -050078bool GrContext::initCommon(const GrContextOptions& options) {
Greg Danielb76a72a2017-07-13 15:07:54 -040079 ASSERT_SINGLE_OWNER
Robert Phillipsfde6fa02018-03-02 08:53:14 -050080 SkASSERT(fCaps); // needs to have been initialized by derived classes
81 SkASSERT(fThreadSafeProxy); // needs to have been initialized by derived classes
Robert Phillips88260b52018-01-19 12:56:09 -050082
83 if (fGpu) {
84 fCaps = fGpu->refCaps();
85 fResourceCache = new GrResourceCache(fCaps.get(), fUniqueID);
Robert Phillips4150eea2018-02-07 17:08:21 -050086 fResourceProvider = new GrResourceProvider(fGpu.get(), fResourceCache, &fSingleOwner,
87 options.fExplicitlyAllocateGPUResources);
Brian Salomon238069b2018-07-11 15:58:57 -040088 fProxyProvider =
89 new GrProxyProvider(fResourceProvider, fResourceCache, fCaps, &fSingleOwner);
90 } else {
91 fProxyProvider = new GrProxyProvider(this->uniqueID(), fCaps, &fSingleOwner);
Robert Phillips88260b52018-01-19 12:56:09 -050092 }
93
Robert Phillips88260b52018-01-19 12:56:09 -050094 if (fResourceCache) {
95 fResourceCache->setProxyProvider(fProxyProvider);
96 }
Robert Phillips1afd4cd2018-01-08 13:40:32 -050097
Brian Osman46da1cc2017-02-14 14:15:48 -050098 fDisableGpuYUVConversion = options.fDisableGpuYUVConversion;
Brian Osman8a83ca42018-02-12 14:32:17 -050099 fSharpenMipmappedTextures = options.fSharpenMipmappedTextures;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000100 fDidTestPMConversions = false;
101
bsalomon6b2552f2016-09-15 13:50:26 -0700102 GrPathRendererChain::Options prcOptions;
bsalomon39ef7fb2016-09-21 11:16:05 -0700103 prcOptions.fAllowPathMaskCaching = options.fAllowPathMaskCaching;
Brian Osman195c05b2017-08-30 15:14:04 -0400104#if GR_TEST_UTILS
csmartdalton008b9d82017-02-22 12:00:42 -0700105 prcOptions.fGpuPathRenderers = options.fGpuPathRenderers;
Brian Osman195c05b2017-08-30 15:14:04 -0400106#endif
Chris Daltonef125092018-06-26 18:16:47 -0600107 if (options.fDisableCoverageCountingPaths) {
108 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
109 }
Brian Osmanb350ae22017-08-29 16:15:39 -0400110 if (options.fDisableDistanceFieldPaths) {
Brian Osman195c05b2017-08-30 15:14:04 -0400111 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
Brian Osmanb350ae22017-08-29 16:15:39 -0400112 }
Brian Salomonaf597482017-11-07 16:23:34 -0500113
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500114 if (!fResourceCache) {
115 // DDL TODO: remove this crippling of the path renderer chain
116 // Disable the small path renderer bc of the proxies in the atlas. They need to be
117 // unified when the opLists are added back to the destination drawing manager.
118 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
Robert Phillips5ffcb4d2018-07-03 16:39:40 -0400119 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kStencilAndCover;
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500120 }
121
Herb Derby26cbe512018-05-24 14:39:01 -0400122 GrTextContext::Options textContextOptions;
123 textContextOptions.fMaxDistanceFieldFontSize = options.fGlyphsAsPathsFontSize;
124 textContextOptions.fMinDistanceFieldFontSize = options.fMinDistanceFieldFontSize;
125 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = false;
Brian Salomonb5086962017-12-13 10:59:33 -0500126#if SK_SUPPORT_ATLAS_TEXT
127 if (GrContextOptions::Enable::kYes == options.fDistanceFieldGlyphVerticesAlwaysHaveW) {
Herb Derby26cbe512018-05-24 14:39:01 -0400128 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = true;
Brian Salomonb5086962017-12-13 10:59:33 -0500129 }
130#endif
Brian Salomonaf597482017-11-07 16:23:34 -0500131
Robert Phillips64ecdce2018-04-02 10:26:39 -0400132 bool explicitlyAllocatingResources = fResourceProvider
133 ? fResourceProvider->explicitlyAllocateGPUResources()
134 : false;
Herb Derby26cbe512018-05-24 14:39:01 -0400135 fDrawingManager.reset(new GrDrawingManager(this, prcOptions, textContextOptions,
Robert Phillips64ecdce2018-04-02 10:26:39 -0400136 &fSingleOwner, explicitlyAllocatingResources,
137 options.fSortRenderTargets));
joshualitt7c3a2f82015-03-31 13:32:05 -0700138
Robert Phillipsaf4adef2018-03-07 11:59:37 -0500139 fGlyphCache = new GrGlyphCache(fCaps.get(), options.fGlyphCacheTextureMaximumBytes);
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500140
Robert Phillips303cd582018-02-14 18:54:01 -0500141 fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB,
Herb Derbyb12175f2018-05-23 16:38:09 -0400142 this, this->uniqueID()));
Brian Salomon91a3e522017-06-23 10:58:19 -0400143
Robert Phillipsfde6fa02018-03-02 08:53:14 -0500144 // DDL TODO: we need to think through how the task group & persistent cache
145 // get passed on to/shared between all the DDLRecorders created with this context.
Brian Osman51279982017-08-23 10:12:00 -0400146 if (options.fExecutor) {
147 fTaskGroup = skstd::make_unique<SkTaskGroup>(*options.fExecutor);
148 }
149
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400150 fPersistentCache = options.fPersistentCache;
151
Brian Salomon91a3e522017-06-23 10:58:19 -0400152 return true;
bsalomon@google.comc0af3172012-06-15 14:10:09 +0000153}
154
bsalomon@google.com27847de2011-02-22 20:59:41 +0000155GrContext::~GrContext() {
joshualitt1de610a2016-01-06 08:26:09 -0800156 ASSERT_SINGLE_OWNER
157
Robert Phillips2e6feed2018-01-22 15:27:20 -0500158 if (fDrawingManager) {
159 fDrawingManager->cleanup();
160 }
halcanary385fe4d2015-08-26 13:07:48 -0700161 delete fResourceProvider;
162 delete fResourceCache;
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500163 delete fProxyProvider;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500164 delete fGlyphCache;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000165}
166
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400167//////////////////////////////////////////////////////////////////////////////
168
169GrContextThreadSafeProxy::GrContextThreadSafeProxy(sk_sp<const GrCaps> caps, uint32_t uniqueID,
170 GrBackend backend,
Ethan Nicholas00543112018-07-31 09:44:36 -0400171 const GrContextOptions& options,
172 sk_sp<GrSkSLFPFactoryCache> cache)
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400173 : fCaps(std::move(caps))
174 , fContextUniqueID(uniqueID)
175 , fBackend(backend)
Ethan Nicholas00543112018-07-31 09:44:36 -0400176 , fOptions(options)
177 , fFPFactoryCache(std::move(cache)) {}
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400178
Brian Salomon103d6f62018-05-11 11:19:22 -0400179GrContextThreadSafeProxy::~GrContextThreadSafeProxy() = default;
180
bungeman6bd52842016-10-27 09:30:08 -0700181sk_sp<GrContextThreadSafeProxy> GrContext::threadSafeProxy() {
bungeman6bd52842016-10-27 09:30:08 -0700182 return fThreadSafeProxy;
bsalomon41b952c2016-03-11 06:46:33 -0800183}
184
Robert Phillipsfc711a22018-02-13 17:03:00 -0500185SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization(
186 size_t cacheMaxResourceBytes,
187 const SkImageInfo& ii, const GrBackendFormat& backendFormat,
188 int sampleCnt, GrSurfaceOrigin origin,
189 const SkSurfaceProps& surfaceProps,
Greg Daniela070ed72018-04-26 16:31:38 -0400190 bool isMipMapped, bool willUseGLFBO0) {
Robert Phillipsfc711a22018-02-13 17:03:00 -0500191 if (!backendFormat.isValid()) {
192 return SkSurfaceCharacterization(); // return an invalid characterization
193 }
194
Greg Daniela070ed72018-04-26 16:31:38 -0400195 if (kOpenGL_GrBackend != backendFormat.backend() && willUseGLFBO0) {
196 // The willUseGLFBO0 flags can only be used for a GL backend.
197 return SkSurfaceCharacterization(); // return an invalid characterization
198 }
199
Robert Phillipsfc711a22018-02-13 17:03:00 -0500200 if (!fCaps->mipMapSupport()) {
201 isMipMapped = false;
202 }
203
204 GrPixelConfig config = kUnknown_GrPixelConfig;
205 if (!fCaps->getConfigFromBackendFormat(backendFormat, ii.colorType(), &config)) {
206 return SkSurfaceCharacterization(); // return an invalid characterization
207 }
208
Robert Phillipsbe77a022018-04-03 17:17:05 -0400209 if (!SkSurface_Gpu::Valid(fCaps.get(), config, ii.colorSpace())) {
210 return SkSurfaceCharacterization(); // return an invalid characterization
211 }
212
Robert Phillips6b6fcc72018-03-30 13:57:00 -0400213 sampleCnt = fCaps->getRenderTargetSampleCount(sampleCnt, config);
214 if (!sampleCnt) {
215 return SkSurfaceCharacterization(); // return an invalid characterization
216 }
217
218 GrFSAAType FSAAType = GrFSAAType::kNone;
219 if (sampleCnt > 1) {
220 FSAAType = fCaps->usesMixedSamples() ? GrFSAAType::kMixedSamples : GrFSAAType::kUnifiedMSAA;
221 }
222
Robert Phillipsfc711a22018-02-13 17:03:00 -0500223 // This surface characterization factory assumes that the resulting characterization is
224 // textureable.
225 if (!fCaps->isConfigTexturable(config)) {
226 return SkSurfaceCharacterization(); // return an invalid characterization
227 }
228
229 return SkSurfaceCharacterization(sk_ref_sp<GrContextThreadSafeProxy>(this),
Robert Phillipsbe77a022018-04-03 17:17:05 -0400230 cacheMaxResourceBytes, ii,
231 origin, config, FSAAType, sampleCnt,
Robert Phillipsfc711a22018-02-13 17:03:00 -0500232 SkSurfaceCharacterization::Textureable(true),
233 SkSurfaceCharacterization::MipMapped(isMipMapped),
Greg Daniela070ed72018-04-26 16:31:38 -0400234 SkSurfaceCharacterization::UsesGLFBO0(willUseGLFBO0),
Robert Phillipsbe77a022018-04-03 17:17:05 -0400235 surfaceProps);
Robert Phillipsfc711a22018-02-13 17:03:00 -0500236}
237
bsalomon2354f842014-07-28 13:48:36 -0700238void GrContext::abandonContext() {
joshualitt1de610a2016-01-06 08:26:09 -0800239 ASSERT_SINGLE_OWNER
240
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500241 fProxyProvider->abandon();
bsalomond309e7a2015-04-30 14:18:54 -0700242 fResourceProvider->abandon();
robertphillips0dfa62c2015-11-16 06:23:31 -0800243
244 // Need to abandon the drawing manager first so all the render targets
245 // will be released/forgotten before they too are abandoned.
246 fDrawingManager->abandon();
247
bsalomon@google.com205d4602011-04-25 12:43:45 +0000248 // abandon first to so destructors
249 // don't try to free the resources in the API.
bsalomon0ea80f42015-02-11 10:49:59 -0800250 fResourceCache->abandonAll();
bsalomonc8dc1f72014-08-21 13:02:13 -0700251
bsalomon6e2aad42016-04-01 11:54:31 -0700252 fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
253
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500254 fGlyphCache->freeAll();
bsalomon6e2aad42016-04-01 11:54:31 -0700255 fTextBlobCache->freeAll();
256}
257
Khushalc421ca12018-06-26 14:38:34 -0700258bool GrContext::abandoned() const {
259 ASSERT_SINGLE_OWNER
260 return fDrawingManager->wasAbandoned();
261}
262
bsalomon6e2aad42016-04-01 11:54:31 -0700263void GrContext::releaseResourcesAndAbandonContext() {
264 ASSERT_SINGLE_OWNER
265
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500266 fProxyProvider->abandon();
bsalomon6e2aad42016-04-01 11:54:31 -0700267 fResourceProvider->abandon();
268
269 // Need to abandon the drawing manager first so all the render targets
270 // will be released/forgotten before they too are abandoned.
271 fDrawingManager->abandon();
272
273 // Release all resources in the backend 3D API.
274 fResourceCache->releaseAll();
275
276 fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
bsalomon@google.com205d4602011-04-25 12:43:45 +0000277
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500278 fGlyphCache->freeAll();
joshualitt26ffc002015-04-16 11:24:04 -0700279 fTextBlobCache->freeAll();
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000280}
281
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000282void GrContext::resetContext(uint32_t state) {
joshualitt1de610a2016-01-06 08:26:09 -0800283 ASSERT_SINGLE_OWNER
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000284 fGpu->markContextDirty(state);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000285}
286
287void GrContext::freeGpuResources() {
joshualitt1de610a2016-01-06 08:26:09 -0800288 ASSERT_SINGLE_OWNER
289
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500290 fGlyphCache->freeAll();
robertphillips68737822015-10-29 12:12:21 -0700291
292 fDrawingManager->freeGpuResources();
bsalomon3033b9f2015-04-13 11:09:56 -0700293
294 fResourceCache->purgeAllUnlocked();
bsalomon@google.com27847de2011-02-22 20:59:41 +0000295}
296
Robert Phillips6eba0632018-03-28 12:25:42 -0400297void GrContext::purgeUnlockedResources(bool scratchResourcesOnly) {
298 ASSERT_SINGLE_OWNER
299 fResourceCache->purgeUnlockedResources(scratchResourcesOnly);
300 fResourceCache->purgeAsNeeded();
301 fTextBlobCache->purgeStaleBlobs();
302}
303
Jim Van Verth76d917c2017-12-13 09:26:37 -0500304void GrContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed) {
Brian Salomon5e150852017-03-22 14:53:13 -0400305 ASSERT_SINGLE_OWNER
Jim Van Verth76d917c2017-12-13 09:26:37 -0500306 fResourceCache->purgeAsNeeded();
307 fResourceCache->purgeResourcesNotUsedSince(GrStdSteadyClock::now() - msNotUsed);
308
309 fTextBlobCache->purgeStaleBlobs();
Brian Salomon5e150852017-03-22 14:53:13 -0400310}
311
Derek Sollenberger5480a182017-05-25 16:43:59 -0400312void GrContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
313 ASSERT_SINGLE_OWNER
314 fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources);
315}
316
commit-bot@chromium.org95c20032014-05-09 14:29:32 +0000317void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
joshualitt1de610a2016-01-06 08:26:09 -0800318 ASSERT_SINGLE_OWNER
319
bsalomon71cb0c22014-11-14 12:10:14 -0800320 if (resourceCount) {
bsalomon0ea80f42015-02-11 10:49:59 -0800321 *resourceCount = fResourceCache->getBudgetedResourceCount();
bsalomon71cb0c22014-11-14 12:10:14 -0800322 }
323 if (resourceBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800324 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
bsalomon71cb0c22014-11-14 12:10:14 -0800325 }
commit-bot@chromium.orgd8a57af2014-03-19 21:19:16 +0000326}
327
Derek Sollenbergeree479142017-05-24 11:41:33 -0400328size_t GrContext::getResourceCachePurgeableBytes() const {
329 ASSERT_SINGLE_OWNER
330 return fResourceCache->getPurgeableBytes();
331}
332
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000333////////////////////////////////////////////////////////////////////////////////
334
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400335int GrContext::maxTextureSize() const { return fCaps->maxTextureSize(); }
Brian Salomonf932a632018-04-05 12:46:09 -0400336
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400337int GrContext::maxRenderTargetSize() const { return fCaps->maxRenderTargetSize(); }
Brian Salomonf932a632018-04-05 12:46:09 -0400338
Brian Salomonbdecacf2018-02-02 20:32:49 -0500339bool GrContext::colorTypeSupportedAsImage(SkColorType colorType) const {
Brian Osman2b23c4b2018-06-01 12:25:08 -0400340 GrPixelConfig config = SkColorType2GrPixelConfig(colorType);
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400341 return fCaps->isConfigTexturable(config);
Brian Salomonbdecacf2018-02-02 20:32:49 -0500342}
343
344int GrContext::maxSurfaceSampleCountForColorType(SkColorType colorType) const {
Brian Osman2b23c4b2018-06-01 12:25:08 -0400345 GrPixelConfig config = SkColorType2GrPixelConfig(colorType);
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400346 return fCaps->maxRenderTargetSampleCount(config);
Brian Salomonbdecacf2018-02-02 20:32:49 -0500347}
348
349////////////////////////////////////////////////////////////////////////////////
350
joshualitt0db6dfa2015-04-10 07:01:30 -0700351void GrContext::TextBlobCacheOverBudgetCB(void* data) {
352 SkASSERT(data);
Brian Osman11052242016-10-27 14:47:55 -0400353 // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
354 // GrRenderTargetContext to perform a necessary flush. The solution is to move drawText calls
355 // to below the GrContext level, but this is not trivial because they call drawPath on
356 // SkGpuDevice.
joshualitt0db6dfa2015-04-10 07:01:30 -0700357 GrContext* context = reinterpret_cast<GrContext*>(data);
358 context->flush();
359}
360
bsalomon@google.com27847de2011-02-22 20:59:41 +0000361////////////////////////////////////////////////////////////////////////////////
362
bsalomonb77a9072016-09-07 10:02:04 -0700363void GrContext::flush() {
joshualitt1de610a2016-01-06 08:26:09 -0800364 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700365 RETURN_IF_ABANDONED
Robert Phillips7ee385e2017-03-30 08:02:11 -0400366
367 fDrawingManager->flush(nullptr);
368}
369
Greg Daniel51316782017-08-02 15:10:09 +0000370GrSemaphoresSubmitted GrContext::flushAndSignalSemaphores(int numSemaphores,
371 GrBackendSemaphore signalSemaphores[]) {
372 ASSERT_SINGLE_OWNER
373 if (fDrawingManager->wasAbandoned()) { return GrSemaphoresSubmitted::kNo; }
374
375 return fDrawingManager->flush(nullptr, numSemaphores, signalSemaphores);
376}
377
Robert Phillips7ee385e2017-03-30 08:02:11 -0400378void GrContextPriv::flush(GrSurfaceProxy* proxy) {
379 ASSERT_SINGLE_OWNER_PRIV
380 RETURN_IF_ABANDONED_PRIV
381 ASSERT_OWNED_PROXY_PRIV(proxy);
382
383 fContext->fDrawingManager->flush(proxy);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000384}
385
Brian Salomonc320b152018-02-20 14:05:36 -0500386// TODO: This will be removed when GrSurfaceContexts are aware of their color types.
387// (skbug.com/6718)
Brian Osmand2ca59a2017-04-13 14:03:57 -0400388static bool valid_premul_config(GrPixelConfig config) {
Brian Salomonc320b152018-02-20 14:05:36 -0500389 switch (config) {
390 case kUnknown_GrPixelConfig: return false;
391 case kAlpha_8_GrPixelConfig: return false;
392 case kGray_8_GrPixelConfig: return false;
393 case kRGB_565_GrPixelConfig: return false;
394 case kRGBA_4444_GrPixelConfig: return true;
395 case kRGBA_8888_GrPixelConfig: return true;
Brian Salomon5fba7ad2018-03-22 10:01:16 -0400396 case kRGB_888_GrPixelConfig: return false;
Brian Salomonc320b152018-02-20 14:05:36 -0500397 case kBGRA_8888_GrPixelConfig: return true;
398 case kSRGBA_8888_GrPixelConfig: return true;
399 case kSBGRA_8888_GrPixelConfig: return true;
Brian Osman10fc6fd2018-03-02 11:01:10 -0500400 case kRGBA_1010102_GrPixelConfig: return true;
Brian Salomonc320b152018-02-20 14:05:36 -0500401 case kRGBA_float_GrPixelConfig: return true;
402 case kRG_float_GrPixelConfig: return false;
403 case kAlpha_half_GrPixelConfig: return false;
404 case kRGBA_half_GrPixelConfig: return true;
405 case kAlpha_8_as_Alpha_GrPixelConfig: return false;
406 case kAlpha_8_as_Red_GrPixelConfig: return false;
407 case kAlpha_half_as_Red_GrPixelConfig: return false;
408 case kGray_8_as_Lum_GrPixelConfig: return false;
409 case kGray_8_as_Red_GrPixelConfig: return false;
410 }
411 SK_ABORT("Invalid GrPixelConfig");
412 return false;
Brian Osmance425512017-03-22 14:37:50 -0400413}
414
Brian Salomonc320b152018-02-20 14:05:36 -0500415static bool valid_premul_color_type(GrColorType ct) {
416 switch (ct) {
Brian Osman10fc6fd2018-03-02 11:01:10 -0500417 case GrColorType::kUnknown: return false;
418 case GrColorType::kAlpha_8: return false;
419 case GrColorType::kRGB_565: return false;
420 case GrColorType::kABGR_4444: return true;
421 case GrColorType::kRGBA_8888: return true;
Brian Salomon5fba7ad2018-03-22 10:01:16 -0400422 case GrColorType::kRGB_888x: return false;
Brian Osman10fc6fd2018-03-02 11:01:10 -0500423 case GrColorType::kBGRA_8888: return true;
424 case GrColorType::kRGBA_1010102: return true;
425 case GrColorType::kGray_8: return false;
426 case GrColorType::kAlpha_F16: return false;
427 case GrColorType::kRGBA_F16: return true;
428 case GrColorType::kRG_F32: return false;
429 case GrColorType::kRGBA_F32: return true;
Brian Salomonc320b152018-02-20 14:05:36 -0500430 }
431 SK_ABORT("Invalid GrColorType");
432 return false;
433}
434
435static bool valid_pixel_conversion(GrColorType cpuColorType, GrPixelConfig gpuConfig,
Brian Osmand2ca59a2017-04-13 14:03:57 -0400436 bool premulConversion) {
Brian Osmand2ca59a2017-04-13 14:03:57 -0400437 // We only allow premul <-> unpremul conversions for some formats
Brian Salomonc320b152018-02-20 14:05:36 -0500438 if (premulConversion &&
439 (!valid_premul_color_type(cpuColorType) || !valid_premul_config(gpuConfig))) {
Brian Osmand2ca59a2017-04-13 14:03:57 -0400440 return false;
441 }
Brian Osmand2ca59a2017-04-13 14:03:57 -0400442 return true;
443}
444
Brian Salomonc320b152018-02-20 14:05:36 -0500445bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst, int left, int top, int width,
446 int height, GrColorType srcColorType,
447 SkColorSpace* srcColorSpace, const void* buffer,
448 size_t rowBytes, uint32_t pixelOpsFlags) {
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500449 ASSERT_SINGLE_OWNER_PRIV
450 RETURN_FALSE_IF_ABANDONED_PRIV
451 SkASSERT(dst);
452 SkASSERT(buffer);
453 ASSERT_OWNED_PROXY_PRIV(dst->asSurfaceProxy());
Brian Salomond494f6e2018-06-01 14:13:43 -0400454 GR_CREATE_TRACE_MARKER_CONTEXT("GrContextPriv", "writeSurfacePixels", fContext);
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500455
456 if (GrColorType::kUnknown == srcColorType) {
457 return false;
458 }
459
460 if (!dst->asSurfaceProxy()->instantiate(this->resourceProvider())) {
461 return false;
462 }
463
464 GrSurfaceProxy* dstProxy = dst->asSurfaceProxy();
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400465 GrSurface* dstSurface = dstProxy->peekSurface();
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500466
467 if (!GrSurfacePriv::AdjustWritePixelParams(dstSurface->width(), dstSurface->height(),
468 GrColorTypeBytesPerPixel(srcColorType), &left, &top,
469 &width, &height, &buffer, &rowBytes)) {
470 return false;
471 }
472
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400473 // TODO: Make GrSurfaceContext know its alpha type and pass src buffer's alpha type.
474 bool premul = SkToBool(kUnpremul_PixelOpsFlag & pixelOpsFlags);
475
476 // For canvas2D putImageData performance we have a special code path for unpremul RGBA_8888 srcs
477 // that are premultiplied on the GPU. This is kept as narrow as possible for now.
Brian Salomon817847c2018-05-07 13:33:50 -0400478 bool canvas2DFastPath =
Greg Daniel4374e962018-09-28 15:09:47 -0400479 !fContext->contextPriv().caps()->avoidWritePixelsFastPath() &&
Brian Salomon817847c2018-05-07 13:33:50 -0400480 premul &&
Brian Osman34ec3742018-07-03 10:40:57 -0400481 !dst->colorSpaceInfo().colorSpace() &&
Brian Salomon817847c2018-05-07 13:33:50 -0400482 (srcColorType == GrColorType::kRGBA_8888 || srcColorType == GrColorType::kBGRA_8888) &&
483 SkToBool(dst->asRenderTargetContext()) &&
484 (dstProxy->config() == kRGBA_8888_GrPixelConfig ||
485 dstProxy->config() == kBGRA_8888_GrPixelConfig) &&
486 !(pixelOpsFlags & kDontFlush_PixelOpsFlag) &&
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400487 fContext->contextPriv().caps()->isConfigTexturable(kRGBA_8888_GrPixelConfig) &&
Brian Salomon817847c2018-05-07 13:33:50 -0400488 fContext->validPMUPMConversionExists();
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400489
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400490 if (!fContext->contextPriv().caps()->surfaceSupportsWritePixels(dstSurface) ||
491 canvas2DFastPath) {
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400492 // We don't expect callers that are skipping flushes to require an intermediate draw.
493 SkASSERT(!(pixelOpsFlags & kDontFlush_PixelOpsFlag));
494 if (pixelOpsFlags & kDontFlush_PixelOpsFlag) {
495 return false;
496 }
497
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500498 GrSurfaceDesc desc;
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400499 desc.fConfig = canvas2DFastPath ? kRGBA_8888_GrPixelConfig : dstProxy->config();
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500500 desc.fWidth = width;
501 desc.fHeight = height;
502 desc.fSampleCnt = 1;
Brian Salomon2a4f9832018-03-03 22:43:43 -0500503 auto tempProxy = this->proxyProvider()->createProxy(
504 desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500505 if (!tempProxy) {
506 return false;
507 }
508 auto tempCtx = this->drawingManager()->makeTextureContext(
509 tempProxy, dst->colorSpaceInfo().refColorSpace());
510 if (!tempCtx) {
511 return false;
512 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400513 uint32_t flags = canvas2DFastPath ? 0 : pixelOpsFlags;
Brian Salomon817847c2018-05-07 13:33:50 -0400514 // In the fast path we always write the srcData to the temp context as though it were RGBA.
515 // When the data is really BGRA the write will cause the R and B channels to be swapped in
516 // the intermediate surface which gets corrected by a swizzle effect when drawing to the
517 // dst.
518 auto tmpColorType = canvas2DFastPath ? GrColorType::kRGBA_8888 : srcColorType;
Brian Salomond494f6e2018-06-01 14:13:43 -0400519 if (!this->writeSurfacePixels(tempCtx.get(), 0, 0, width, height, tmpColorType,
520 srcColorSpace, buffer, rowBytes, flags)) {
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500521 return false;
522 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400523 if (canvas2DFastPath) {
524 GrPaint paint;
525 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
Brian Salomon817847c2018-05-07 13:33:50 -0400526 auto fp = fContext->createUPMToPMEffect(
Brian Osman5ea96bf2018-10-02 14:58:05 -0400527 GrSimpleTextureEffect::Make(std::move(tempProxy), SkMatrix::I()));
Brian Salomon817847c2018-05-07 13:33:50 -0400528 if (srcColorType == GrColorType::kBGRA_8888) {
529 fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
530 }
531 if (!fp) {
532 return false;
533 }
534 paint.addColorFragmentProcessor(std::move(fp));
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400535 dst->asRenderTargetContext()->fillRectToRect(
536 GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
537 SkRect::MakeXYWH(left, top, width, height), SkRect::MakeWH(width, height));
538 return true;
539 } else {
540 return dst->copy(tempProxy.get(), SkIRect::MakeWH(width, height), {left, top});
541 }
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500542 }
543
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500544 bool convert = premul;
545
546 if (!valid_pixel_conversion(srcColorType, dstProxy->config(), premul)) {
547 return false;
548 }
549
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400550 GrColorType allowedColorType = fContext->contextPriv().caps()->supportedWritePixelsColorType(
551 dstProxy->config(), srcColorType);
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500552 convert = convert || (srcColorType != allowedColorType);
553
554 if (!dst->colorSpaceInfo().colorSpace()) {
555 // "Legacy" mode - no color space conversions.
556 srcColorSpace = nullptr;
557 }
558 convert = convert || !SkColorSpace::Equals(srcColorSpace, dst->colorSpaceInfo().colorSpace());
559
560 std::unique_ptr<char[]> tempBuffer;
561 if (convert) {
562 auto srcSkColorType = GrColorTypeToSkColorType(srcColorType);
563 auto dstSkColorType = GrColorTypeToSkColorType(allowedColorType);
564 if (kUnknown_SkColorType == srcSkColorType || kUnknown_SkColorType == dstSkColorType) {
565 return false;
566 }
567 auto srcAlphaType = premul ? kUnpremul_SkAlphaType : kPremul_SkAlphaType;
568 SkPixmap src(SkImageInfo::Make(width, height, srcSkColorType, srcAlphaType,
569 sk_ref_sp(srcColorSpace)),
570 buffer, rowBytes);
571 auto tempSrcII = SkImageInfo::Make(width, height, dstSkColorType, kPremul_SkAlphaType,
572 dst->colorSpaceInfo().refColorSpace());
573 auto size = tempSrcII.computeMinByteSize();
574 if (!size) {
575 return false;
576 }
577 tempBuffer.reset(new char[size]);
578 SkPixmap tempSrc(tempSrcII, tempBuffer.get(), tempSrcII.minRowBytes());
579 if (!src.readPixels(tempSrc)) {
580 return false;
581 }
582 srcColorType = allowedColorType;
583 buffer = tempSrc.addr();
584 rowBytes = tempSrc.rowBytes();
585 if (dstProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
586 std::unique_ptr<char[]> row(new char[rowBytes]);
587 for (int y = 0; y < height / 2; ++y) {
588 memcpy(row.get(), tempSrc.addr(0, y), rowBytes);
589 memcpy(tempSrc.writable_addr(0, y), tempSrc.addr(0, height - 1 - y), rowBytes);
590 memcpy(tempSrc.writable_addr(0, height - 1 - y), row.get(), rowBytes);
591 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400592 top = dstSurface->height() - top - height;
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500593 }
594 } else if (dstProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
595 size_t trimRowBytes = GrColorTypeBytesPerPixel(srcColorType) * width;
596 tempBuffer.reset(new char[trimRowBytes * height]);
597 char* dst = reinterpret_cast<char*>(tempBuffer.get()) + trimRowBytes * (height - 1);
598 const char* src = reinterpret_cast<const char*>(buffer);
599 for (int i = 0; i < height; ++i, src += rowBytes, dst -= trimRowBytes) {
600 memcpy(dst, src, trimRowBytes);
601 }
602 buffer = tempBuffer.get();
603 rowBytes = trimRowBytes;
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400604 top = dstSurface->height() - top - height;
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500605 }
606
607 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && dstSurface->surfacePriv().hasPendingIO()) {
608 this->flush(nullptr); // MDB TODO: tighten this
609 }
610
611 return this->getGpu()->writePixels(dstSurface, left, top, width, height, srcColorType, buffer,
612 rowBytes);
613}
614
Brian Salomond494f6e2018-06-01 14:13:43 -0400615bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src, int left, int top, int width,
616 int height, GrColorType dstColorType,
617 SkColorSpace* dstColorSpace, void* buffer, size_t rowBytes,
618 uint32_t pixelOpsFlags) {
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400619 ASSERT_SINGLE_OWNER_PRIV
620 RETURN_FALSE_IF_ABANDONED_PRIV
621 SkASSERT(src);
622 SkASSERT(buffer);
623 ASSERT_OWNED_PROXY_PRIV(src->asSurfaceProxy());
Brian Salomond494f6e2018-06-01 14:13:43 -0400624 GR_CREATE_TRACE_MARKER_CONTEXT("GrContextPriv", "readSurfacePixels", fContext);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400625
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400626 SkASSERT(!(pixelOpsFlags & kDontFlush_PixelOpsFlag));
627 if (pixelOpsFlags & kDontFlush_PixelOpsFlag) {
Brian Salomon5fba7ad2018-03-22 10:01:16 -0400628 return false;
629 }
630
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400631 // MDB TODO: delay this instantiation until later in the method
632 if (!src->asSurfaceProxy()->instantiate(this->resourceProvider())) {
633 return false;
634 }
635
636 GrSurfaceProxy* srcProxy = src->asSurfaceProxy();
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400637 GrSurface* srcSurface = srcProxy->peekSurface();
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400638
639 if (!GrSurfacePriv::AdjustReadPixelParams(srcSurface->width(), srcSurface->height(),
640 GrColorTypeBytesPerPixel(dstColorType), &left, &top,
641 &width, &height, &buffer, &rowBytes)) {
642 return false;
643 }
644
645 // TODO: Make GrSurfaceContext know its alpha type and pass dst buffer's alpha type.
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400646 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & pixelOpsFlags);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400647
648 if (!valid_pixel_conversion(dstColorType, srcProxy->config(), unpremul)) {
649 return false;
650 }
651
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400652 // This is the getImageData equivalent to the canvas2D putImageData fast path. We probably don't
653 // care so much about getImageData performance. However, in order to ensure putImageData/
654 // getImageData in "legacy" mode are round-trippable we use the GPU to do the complementary
Brian Salomond494f6e2018-06-01 14:13:43 -0400655 // unpremul step to writeSurfacePixels's premul step (which is determined empirically in
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400656 // fContext->vaildaPMUPMConversionExists()).
Brian Salomon817847c2018-05-07 13:33:50 -0400657 bool canvas2DFastPath =
658 unpremul &&
Brian Osman34ec3742018-07-03 10:40:57 -0400659 !src->colorSpaceInfo().colorSpace() &&
Brian Salomon817847c2018-05-07 13:33:50 -0400660 (GrColorType::kRGBA_8888 == dstColorType || GrColorType::kBGRA_8888 == dstColorType) &&
661 SkToBool(srcProxy->asTextureProxy()) &&
662 (srcProxy->config() == kRGBA_8888_GrPixelConfig ||
663 srcProxy->config() == kBGRA_8888_GrPixelConfig) &&
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400664 fContext->contextPriv().caps()->isConfigRenderable(kRGBA_8888_GrPixelConfig) &&
Brian Salomon817847c2018-05-07 13:33:50 -0400665 fContext->validPMUPMConversionExists();
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400666
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400667 if (!fContext->contextPriv().caps()->surfaceSupportsReadPixels(srcSurface) ||
668 canvas2DFastPath) {
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400669 GrSurfaceDesc desc;
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400670 desc.fFlags = canvas2DFastPath ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
671 desc.fConfig = canvas2DFastPath ? kRGBA_8888_GrPixelConfig : srcProxy->config();
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400672 desc.fWidth = width;
673 desc.fHeight = height;
674 desc.fSampleCnt = 1;
675 auto tempProxy = this->proxyProvider()->createProxy(
676 desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
677 if (!tempProxy) {
678 return false;
679 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400680 sk_sp<GrSurfaceContext> tempCtx;
681 if (canvas2DFastPath) {
682 tempCtx = this->drawingManager()->makeRenderTargetContext(std::move(tempProxy), nullptr,
683 nullptr);
Greg Daniel42314012018-04-23 10:57:37 -0400684 SkASSERT(tempCtx->asRenderTargetContext());
685 tempCtx->asRenderTargetContext()->discard();
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400686 } else {
687 tempCtx = this->drawingManager()->makeTextureContext(
688 std::move(tempProxy), src->colorSpaceInfo().refColorSpace());
689 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400690 if (!tempCtx) {
691 return false;
692 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400693 if (canvas2DFastPath) {
694 GrPaint paint;
695 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
Brian Salomon817847c2018-05-07 13:33:50 -0400696 auto fp = fContext->createPMToUPMEffect(
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400697 GrSimpleTextureEffect::Make(sk_ref_sp(srcProxy->asTextureProxy()),
Brian Osman5ea96bf2018-10-02 14:58:05 -0400698 SkMatrix::I()));
Brian Salomon817847c2018-05-07 13:33:50 -0400699 if (dstColorType == GrColorType::kBGRA_8888) {
700 fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
701 dstColorType = GrColorType::kRGBA_8888;
702 }
703 if (!fp) {
704 return false;
705 }
706 paint.addColorFragmentProcessor(std::move(fp));
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400707 tempCtx->asRenderTargetContext()->fillRectToRect(
708 GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
709 SkRect::MakeWH(width, height), SkRect::MakeXYWH(left, top, width, height));
710 } else if (!tempCtx->copy(srcProxy, SkIRect::MakeXYWH(left, top, width, height), {0, 0})) {
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400711 return false;
712 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400713 uint32_t flags = canvas2DFastPath ? 0 : pixelOpsFlags;
Brian Salomond494f6e2018-06-01 14:13:43 -0400714 return this->readSurfacePixels(tempCtx.get(), 0, 0, width, height, dstColorType,
715 dstColorSpace, buffer, rowBytes, flags);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400716 }
717
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400718 bool convert = unpremul;
719
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400720 bool flip = srcProxy->origin() == kBottomLeft_GrSurfaceOrigin;
721 if (flip) {
722 top = srcSurface->height() - top - height;
723 }
724
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400725 GrColorType allowedColorType = fContext->contextPriv().caps()->supportedReadPixelsColorType(
726 srcProxy->config(), dstColorType);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400727 convert = convert || (dstColorType != allowedColorType);
728
729 if (!src->colorSpaceInfo().colorSpace()) {
730 // "Legacy" mode - no color space conversions.
731 dstColorSpace = nullptr;
732 }
733 convert = convert || !SkColorSpace::Equals(dstColorSpace, src->colorSpaceInfo().colorSpace());
734
735 SkAutoPixmapStorage tempPixmap;
736 SkPixmap finalPixmap;
737 if (convert) {
738 SkColorType srcSkColorType = GrColorTypeToSkColorType(allowedColorType);
739 SkColorType dstSkColorType = GrColorTypeToSkColorType(dstColorType);
740 if (kUnknown_SkColorType == srcSkColorType || kUnknown_SkColorType == dstSkColorType) {
741 return false;
742 }
743 auto tempAT = SkColorTypeIsAlwaysOpaque(srcSkColorType) ? kOpaque_SkAlphaType
744 : kPremul_SkAlphaType;
745 auto tempII = SkImageInfo::Make(width, height, srcSkColorType, tempAT,
746 src->colorSpaceInfo().refColorSpace());
747 SkASSERT(!unpremul || !SkColorTypeIsAlwaysOpaque(dstSkColorType));
748 auto finalAT = SkColorTypeIsAlwaysOpaque(srcSkColorType)
749 ? kOpaque_SkAlphaType
750 : unpremul ? kUnpremul_SkAlphaType : kPremul_SkAlphaType;
751 auto finalII =
752 SkImageInfo::Make(width, height, dstSkColorType, finalAT, sk_ref_sp(dstColorSpace));
753 if (!SkImageInfoValidConversion(finalII, tempII)) {
754 return false;
755 }
Brian Salomon6196fc12018-07-12 16:39:23 -0400756 if (!tempPixmap.tryAlloc(tempII)) {
757 return false;
758 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400759 finalPixmap.reset(finalII, buffer, rowBytes);
760 buffer = tempPixmap.writable_addr();
761 rowBytes = tempPixmap.rowBytes();
Brian Salomon3d945e82018-05-14 14:54:06 -0400762 // Chrome msan bots require this.
763 sk_bzero(buffer, tempPixmap.computeByteSize());
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400764 }
765
766 if (srcSurface->surfacePriv().hasPendingWrite()) {
767 this->flush(nullptr); // MDB TODO: tighten this
768 }
769
770 if (!fContext->fGpu->readPixels(srcSurface, left, top, width, height, allowedColorType, buffer,
771 rowBytes)) {
772 return false;
773 }
774
775 if (flip) {
776 size_t trimRowBytes = GrColorTypeBytesPerPixel(allowedColorType) * width;
777 std::unique_ptr<char[]> row(new char[trimRowBytes]);
778 char* upper = reinterpret_cast<char*>(buffer);
779 char* lower = reinterpret_cast<char*>(buffer) + (height - 1) * rowBytes;
780 for (int y = 0; y < height / 2; ++y, upper += rowBytes, lower -= rowBytes) {
781 memcpy(row.get(), upper, trimRowBytes);
782 memcpy(upper, lower, trimRowBytes);
783 memcpy(lower, row.get(), trimRowBytes);
784 }
785 }
786 if (convert) {
787 if (!tempPixmap.readPixels(finalPixmap)) {
788 return false;
789 }
790 }
791 return true;
792}
793
Robert Phillips7ee385e2017-03-30 08:02:11 -0400794void GrContextPriv::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) {
795 ASSERT_SINGLE_OWNER_PRIV
796 RETURN_IF_ABANDONED_PRIV
797 SkASSERT(proxy);
798 ASSERT_OWNED_PROXY_PRIV(proxy);
Greg Daniel51316782017-08-02 15:10:09 +0000799 fContext->fDrawingManager->prepareSurfaceForExternalIO(proxy, 0, nullptr);
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000800}
801
Robert Phillips7ee385e2017-03-30 08:02:11 -0400802void GrContextPriv::flushSurfaceWrites(GrSurfaceProxy* proxy) {
803 ASSERT_SINGLE_OWNER_PRIV
804 RETURN_IF_ABANDONED_PRIV
805 SkASSERT(proxy);
806 ASSERT_OWNED_PROXY_PRIV(proxy);
807 if (proxy->priv().hasPendingWrite()) {
808 this->flush(proxy);
bsalomonf80bfed2014-10-07 05:56:02 -0700809 }
810}
811
Robert Phillips7ee385e2017-03-30 08:02:11 -0400812void GrContextPriv::flushSurfaceIO(GrSurfaceProxy* proxy) {
813 ASSERT_SINGLE_OWNER_PRIV
814 RETURN_IF_ABANDONED_PRIV
815 SkASSERT(proxy);
816 ASSERT_OWNED_PROXY_PRIV(proxy);
817 if (proxy->priv().hasPendingIO()) {
818 this->flush(proxy);
ajuma95243eb2016-08-24 08:19:02 -0700819 }
820}
821
bsalomon@google.com27847de2011-02-22 20:59:41 +0000822////////////////////////////////////////////////////////////////////////////////
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000823
Robert Phillipsc994a932018-06-19 13:09:54 -0400824sk_sp<GrOpMemoryPool> GrContextPriv::refOpMemoryPool() {
825 if (!fContext->fOpMemoryPool) {
826 // DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory
827 // consumed in DDL mode vs. normal mode for a single skp might be a good metric of wasted
828 // memory.
829 fContext->fOpMemoryPool = sk_sp<GrOpMemoryPool>(new GrOpMemoryPool(16384, 16384));
830 }
831
832 SkASSERT(fContext->fOpMemoryPool);
833 return fContext->fOpMemoryPool;
834}
835
836GrOpMemoryPool* GrContextPriv::opMemoryPool() {
837 return this->refOpMemoryPool().get();
838}
839
Robert Phillips2c862492017-01-18 10:08:39 -0500840sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500841 sk_sp<SkColorSpace> colorSpace,
842 const SkSurfaceProps* props) {
Brian Osman45580d32016-11-23 09:37:01 -0500843 ASSERT_SINGLE_OWNER_PRIV
844
Brian Osman45580d32016-11-23 09:37:01 -0500845 if (proxy->asRenderTargetProxy()) {
Robert Phillips2c862492017-01-18 10:08:39 -0500846 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500847 std::move(colorSpace), props);
Brian Osman45580d32016-11-23 09:37:01 -0500848 } else {
849 SkASSERT(proxy->asTextureProxy());
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500850 SkASSERT(!props);
Robert Phillips2c862492017-01-18 10:08:39 -0500851 return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
Brian Osman45580d32016-11-23 09:37:01 -0500852 }
853}
854
Robert Phillipse2f7d182016-12-15 09:23:05 -0500855sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
Brian Salomon2a4f9832018-03-03 22:43:43 -0500856 GrSurfaceOrigin origin,
Greg Daniel65c7f662017-10-30 13:39:09 -0400857 GrMipMapped mipMapped,
Robert Phillipse2f7d182016-12-15 09:23:05 -0500858 SkBackingFit fit,
Brian Salomon366093f2018-02-13 09:25:22 -0500859 SkBudgeted isDstBudgeted,
860 sk_sp<SkColorSpace> colorSpace,
861 const SkSurfaceProps* props) {
Greg Daniel65c7f662017-10-30 13:39:09 -0400862 sk_sp<GrTextureProxy> proxy;
863 if (GrMipMapped::kNo == mipMapped) {
Brian Salomon2a4f9832018-03-03 22:43:43 -0500864 proxy = this->proxyProvider()->createProxy(dstDesc, origin, fit, isDstBudgeted);
Greg Daniel65c7f662017-10-30 13:39:09 -0400865 } else {
866 SkASSERT(SkBackingFit::kExact == fit);
Brian Salomon2a4f9832018-03-03 22:43:43 -0500867 proxy = this->proxyProvider()->createMipMapProxy(dstDesc, origin, isDstBudgeted);
Greg Daniel65c7f662017-10-30 13:39:09 -0400868 }
Robert Phillips77b3f322017-01-31 18:24:12 -0500869 if (!proxy) {
870 return nullptr;
871 }
Robert Phillipse2f7d182016-12-15 09:23:05 -0500872
Greg Daniel55fa6472018-03-16 16:13:10 -0400873 sk_sp<GrSurfaceContext> sContext = this->makeWrappedSurfaceContext(std::move(proxy),
874 std::move(colorSpace),
875 props);
876 if (sContext && sContext->asRenderTargetContext()) {
877 sContext->asRenderTargetContext()->discard();
878 }
879
880 return sContext;
Robert Phillipse2f7d182016-12-15 09:23:05 -0500881}
882
Brian Salomond17f6582017-07-19 18:28:58 -0400883sk_sp<GrTextureContext> GrContextPriv::makeBackendTextureContext(const GrBackendTexture& tex,
Greg Daniel7ef28f32017-04-20 16:41:55 +0000884 GrSurfaceOrigin origin,
Brian Osmanc1e37052017-03-09 14:19:20 -0500885 sk_sp<SkColorSpace> colorSpace) {
Robert Phillips26caf892017-01-27 10:58:31 -0500886 ASSERT_SINGLE_OWNER_PRIV
887
Brian Salomon7578f3e2018-03-07 14:39:54 -0500888 sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendTexture(tex, origin);
Robert Phillips77b3f322017-01-31 18:24:12 -0500889 if (!proxy) {
890 return nullptr;
891 }
Robert Phillips26caf892017-01-27 10:58:31 -0500892
Brian Salomond17f6582017-07-19 18:28:58 -0400893 return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
Robert Phillips26caf892017-01-27 10:58:31 -0500894}
895
Brian Osman11052242016-10-27 14:47:55 -0400896sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
Greg Daniel7ef28f32017-04-20 16:41:55 +0000897 const GrBackendTexture& tex,
898 GrSurfaceOrigin origin,
899 int sampleCnt,
Brian Osman11052242016-10-27 14:47:55 -0400900 sk_sp<SkColorSpace> colorSpace,
Brian Osmanc1e37052017-03-09 14:19:20 -0500901 const SkSurfaceProps* props) {
robertphillips4fd74ae2016-08-03 14:26:53 -0700902 ASSERT_SINGLE_OWNER_PRIV
Brian Salomonbdecacf2018-02-02 20:32:49 -0500903 SkASSERT(sampleCnt > 0);
robertphillips4fd74ae2016-08-03 14:26:53 -0700904
Brian Salomon7578f3e2018-03-07 14:39:54 -0500905 sk_sp<GrTextureProxy> proxy(
906 this->proxyProvider()->wrapRenderableBackendTexture(tex, origin, sampleCnt));
Robert Phillips77b3f322017-01-31 18:24:12 -0500907 if (!proxy) {
908 return nullptr;
909 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400910
Robert Phillips37430132016-11-09 06:50:43 -0500911 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
Brian Osman11052242016-10-27 14:47:55 -0400912 std::move(colorSpace), props);
robertphillips4fd74ae2016-08-03 14:26:53 -0700913}
914
Brian Osman11052242016-10-27 14:47:55 -0400915sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendRenderTargetRenderTargetContext(
Greg Danielbcf612b2017-05-01 13:50:58 +0000916 const GrBackendRenderTarget& backendRT,
917 GrSurfaceOrigin origin,
robertphillips4fd74ae2016-08-03 14:26:53 -0700918 sk_sp<SkColorSpace> colorSpace,
919 const SkSurfaceProps* surfaceProps) {
920 ASSERT_SINGLE_OWNER_PRIV
921
Brian Salomon7578f3e2018-03-07 14:39:54 -0500922 sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendRenderTarget(backendRT, origin);
Robert Phillips77b3f322017-01-31 18:24:12 -0500923 if (!proxy) {
924 return nullptr;
925 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400926
Robert Phillips37430132016-11-09 06:50:43 -0500927 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400928 std::move(colorSpace),
Brian Osman11052242016-10-27 14:47:55 -0400929 surfaceProps);
robertphillips4fd74ae2016-08-03 14:26:53 -0700930}
931
Brian Osman11052242016-10-27 14:47:55 -0400932sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureAsRenderTargetRenderTargetContext(
Greg Daniel7ef28f32017-04-20 16:41:55 +0000933 const GrBackendTexture& tex,
934 GrSurfaceOrigin origin,
935 int sampleCnt,
robertphillips4fd74ae2016-08-03 14:26:53 -0700936 sk_sp<SkColorSpace> colorSpace,
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500937 const SkSurfaceProps* props) {
robertphillips4fd74ae2016-08-03 14:26:53 -0700938 ASSERT_SINGLE_OWNER_PRIV
Brian Salomonbdecacf2018-02-02 20:32:49 -0500939 SkASSERT(sampleCnt > 0);
Brian Salomon7578f3e2018-03-07 14:39:54 -0500940 sk_sp<GrSurfaceProxy> proxy(
941 this->proxyProvider()->wrapBackendTextureAsRenderTarget(tex, origin, sampleCnt));
Robert Phillips77b3f322017-01-31 18:24:12 -0500942 if (!proxy) {
943 return nullptr;
944 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400945
Robert Phillips37430132016-11-09 06:50:43 -0500946 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400947 std::move(colorSpace),
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500948 props);
robertphillips77a2e522015-10-17 07:43:27 -0700949}
950
Chris Daltonfe199b72017-05-05 11:26:15 -0400951void GrContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
952 fContext->fDrawingManager->addOnFlushCallbackObject(onFlushCBObject);
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400953}
954
Robert Phillips62000362018-02-01 09:10:04 -0500955void GrContextPriv::moveOpListsToDDL(SkDeferredDisplayList* ddl) {
956 fContext->fDrawingManager->moveOpListsToDDL(ddl);
957}
958
959void GrContextPriv::copyOpListsFromDDL(const SkDeferredDisplayList* ddl,
960 GrRenderTargetProxy* newDest) {
961 fContext->fDrawingManager->copyOpListsFromDDL(ddl, newDest);
962}
963
robertphillips48fde9c2016-09-06 05:20:20 -0700964static inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) {
Brian Osman78f20e02017-01-12 10:28:01 -0500965 switch (config) {
966 case kAlpha_8_GrPixelConfig:
Greg Daniel93b4ddd2018-04-16 16:16:47 -0400967 case kAlpha_8_as_Alpha_GrPixelConfig:
968 case kAlpha_8_as_Red_GrPixelConfig:
Brian Osman78f20e02017-01-12 10:28:01 -0500969 case kRGB_565_GrPixelConfig:
970 case kRGBA_4444_GrPixelConfig:
971 case kBGRA_8888_GrPixelConfig:
Brian Osman10fc6fd2018-03-02 11:01:10 -0500972 case kRGBA_1010102_GrPixelConfig:
Brian Osman78f20e02017-01-12 10:28:01 -0500973 return kRGBA_8888_GrPixelConfig;
974 case kSBGRA_8888_GrPixelConfig:
975 return kSRGBA_8888_GrPixelConfig;
976 case kAlpha_half_GrPixelConfig:
Greg Daniel93b4ddd2018-04-16 16:16:47 -0400977 case kAlpha_half_as_Red_GrPixelConfig:
Brian Osman78f20e02017-01-12 10:28:01 -0500978 return kRGBA_half_GrPixelConfig;
Greg Daniel93b4ddd2018-04-16 16:16:47 -0400979 case kGray_8_GrPixelConfig:
980 case kGray_8_as_Lum_GrPixelConfig:
981 case kGray_8_as_Red_GrPixelConfig:
982 return kRGB_888_GrPixelConfig;
Brian Osman78f20e02017-01-12 10:28:01 -0500983 default:
984 return kUnknown_GrPixelConfig;
985 }
robertphillips48fde9c2016-09-06 05:20:20 -0700986}
987
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500988sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContextWithFallback(
robertphillipsd728f0c2016-11-21 11:05:03 -0800989 SkBackingFit fit,
990 int width, int height,
991 GrPixelConfig config,
992 sk_sp<SkColorSpace> colorSpace,
993 int sampleCnt,
Greg Daniel45d63032017-10-30 13:41:26 -0400994 GrMipMapped mipMapped,
robertphillipsd728f0c2016-11-21 11:05:03 -0800995 GrSurfaceOrigin origin,
996 const SkSurfaceProps* surfaceProps,
997 SkBudgeted budgeted) {
Brian Salomonbdecacf2018-02-02 20:32:49 -0500998 SkASSERT(sampleCnt > 0);
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400999 if (0 == fContext->contextPriv().caps()->getRenderTargetSampleCount(sampleCnt, config)) {
robertphillipsd728f0c2016-11-21 11:05:03 -08001000 config = GrPixelConfigFallback(config);
1001 }
1002
1003 return this->makeDeferredRenderTargetContext(fit, width, height, config, std::move(colorSpace),
Greg Daniel45d63032017-10-30 13:41:26 -04001004 sampleCnt, mipMapped, origin, surfaceProps,
Greg Daniele1da1d92017-10-06 15:59:27 -04001005 budgeted);
robertphillipsd728f0c2016-11-21 11:05:03 -08001006}
1007
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001008sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContext(
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001009 SkBackingFit fit,
1010 int width, int height,
1011 GrPixelConfig config,
1012 sk_sp<SkColorSpace> colorSpace,
1013 int sampleCnt,
Greg Daniel45d63032017-10-30 13:41:26 -04001014 GrMipMapped mipMapped,
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001015 GrSurfaceOrigin origin,
1016 const SkSurfaceProps* surfaceProps,
1017 SkBudgeted budgeted) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001018 SkASSERT(sampleCnt > 0);
Khushalc421ca12018-06-26 14:38:34 -07001019 if (fContext->abandoned()) {
Brian Salomon79e4d1b2017-07-13 11:17:11 -04001020 return nullptr;
1021 }
1022
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001023 GrSurfaceDesc desc;
1024 desc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001025 desc.fWidth = width;
1026 desc.fHeight = height;
1027 desc.fConfig = config;
1028 desc.fSampleCnt = sampleCnt;
1029
Greg Daniele1da1d92017-10-06 15:59:27 -04001030 sk_sp<GrTextureProxy> rtp;
Greg Daniel45d63032017-10-30 13:41:26 -04001031 if (GrMipMapped::kNo == mipMapped) {
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001032 rtp = fContext->fProxyProvider->createProxy(desc, origin, fit, budgeted);
Greg Daniele1da1d92017-10-06 15:59:27 -04001033 } else {
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001034 rtp = fContext->fProxyProvider->createMipMapProxy(desc, origin, budgeted);
Greg Daniele1da1d92017-10-06 15:59:27 -04001035 }
Robert Phillips08c5ec72017-01-30 12:26:47 -05001036 if (!rtp) {
1037 return nullptr;
1038 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001039
Robert Phillips1119dc32017-04-11 12:54:57 -04001040 sk_sp<GrRenderTargetContext> renderTargetContext(
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001041 fContext->fDrawingManager->makeRenderTargetContext(std::move(rtp),
1042 std::move(colorSpace),
1043 surfaceProps));
Robert Phillips1119dc32017-04-11 12:54:57 -04001044 if (!renderTargetContext) {
1045 return nullptr;
1046 }
1047
1048 renderTargetContext->discard();
1049
1050 return renderTargetContext;
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001051}
1052
Brian Salomonaff329b2017-08-11 09:40:37 -04001053std::unique_ptr<GrFragmentProcessor> GrContext::createPMToUPMEffect(
Brian Osman5ea96bf2018-10-02 14:58:05 -04001054 std::unique_ptr<GrFragmentProcessor> fp) {
Robert Phillips757914d2017-01-25 15:48:30 -05001055 ASSERT_SINGLE_OWNER
Brian Osman5ea96bf2018-10-02 14:58:05 -04001056 // We should have already called this->validPMUPMConversionExists() in this case
1057 SkASSERT(fDidTestPMConversions);
1058 // ...and it should have succeeded
1059 SkASSERT(this->validPMUPMConversionExists());
Brian Osman409e74f2017-04-17 11:48:28 -04001060
Brian Osman5ea96bf2018-10-02 14:58:05 -04001061 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToUnpremul);
Robert Phillips757914d2017-01-25 15:48:30 -05001062}
1063
Brian Salomonaff329b2017-08-11 09:40:37 -04001064std::unique_ptr<GrFragmentProcessor> GrContext::createUPMToPMEffect(
Brian Osman5ea96bf2018-10-02 14:58:05 -04001065 std::unique_ptr<GrFragmentProcessor> fp) {
joshualitt1de610a2016-01-06 08:26:09 -08001066 ASSERT_SINGLE_OWNER
Brian Osman5ea96bf2018-10-02 14:58:05 -04001067 // We should have already called this->validPMUPMConversionExists() in this case
1068 SkASSERT(fDidTestPMConversions);
1069 // ...and it should have succeeded
1070 SkASSERT(this->validPMUPMConversionExists());
Brian Osman409e74f2017-04-17 11:48:28 -04001071
Brian Osman5ea96bf2018-10-02 14:58:05 -04001072 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToPremul);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +00001073}
1074
Brian Osman409e74f2017-04-17 11:48:28 -04001075bool GrContext::validPMUPMConversionExists() {
joshualitt1de610a2016-01-06 08:26:09 -08001076 ASSERT_SINGLE_OWNER
Brian Osman409e74f2017-04-17 11:48:28 -04001077 if (!fDidTestPMConversions) {
Brian Osman28804f32017-04-20 10:24:36 -04001078 fPMUPMConversionsRoundTrip = GrConfigConversionEffect::TestForPreservingPMConversions(this);
Brian Osman409e74f2017-04-17 11:48:28 -04001079 fDidTestPMConversions = true;
1080 }
1081
bsalomon636e8022015-07-29 06:08:46 -07001082 // The PM<->UPM tests fail or succeed together so we only need to check one.
Brian Osman28804f32017-04-20 10:24:36 -04001083 return fPMUPMConversionsRoundTrip;
bsalomon636e8022015-07-29 06:08:46 -07001084}
1085
Khushal3e7548c2018-05-23 15:45:01 -07001086bool GrContext::supportsDistanceFieldText() const {
1087 return fCaps->shaderCaps()->supportsDistanceFieldText();
1088}
1089
bsalomon37f9a262015-02-02 13:00:10 -08001090//////////////////////////////////////////////////////////////////////////////
1091
Robert Phillipsfc711a22018-02-13 17:03:00 -05001092// DDL TODO: remove 'maxResources'
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001093void GrContext::getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const {
joshualitt1de610a2016-01-06 08:26:09 -08001094 ASSERT_SINGLE_OWNER
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001095 if (maxResources) {
1096 *maxResources = fResourceCache->getMaxResourceCount();
bsalomon37f9a262015-02-02 13:00:10 -08001097 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001098 if (maxResourceBytes) {
1099 *maxResourceBytes = fResourceCache->getMaxResourceBytes();
bsalomon37f9a262015-02-02 13:00:10 -08001100 }
1101}
1102
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001103void GrContext::setResourceCacheLimits(int maxResources, size_t maxResourceBytes) {
joshualitt1de610a2016-01-06 08:26:09 -08001104 ASSERT_SINGLE_OWNER
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001105 fResourceCache->setLimits(maxResources, maxResourceBytes);
bsalomon37f9a262015-02-02 13:00:10 -08001106}
1107
ericrk0a5fa482015-09-15 14:16:10 -07001108//////////////////////////////////////////////////////////////////////////////
ericrk0a5fa482015-09-15 14:16:10 -07001109void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
joshualitt1de610a2016-01-06 08:26:09 -08001110 ASSERT_SINGLE_OWNER
ericrk0a5fa482015-09-15 14:16:10 -07001111 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
1112}
Brian Osman71a18892017-08-10 10:23:25 -04001113
1114//////////////////////////////////////////////////////////////////////////////
Kevin Lubickf4def342018-10-04 12:52:50 -04001115#ifdef SK_ENABLE_DUMP_GPU
1116#include "SkJSONWriter.h"
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001117SkString GrContextPriv::dump() const {
Brian Osman71a18892017-08-10 10:23:25 -04001118 SkDynamicMemoryWStream stream;
1119 SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
1120 writer.beginObject();
1121
1122 static const char* kBackendStr[] = {
1123 "Metal",
1124 "OpenGL",
1125 "Vulkan",
1126 "Mock",
1127 };
1128 GR_STATIC_ASSERT(0 == kMetal_GrBackend);
1129 GR_STATIC_ASSERT(1 == kOpenGL_GrBackend);
1130 GR_STATIC_ASSERT(2 == kVulkan_GrBackend);
1131 GR_STATIC_ASSERT(3 == kMock_GrBackend);
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001132 writer.appendString("backend", kBackendStr[fContext->fBackend]);
Brian Osman71a18892017-08-10 10:23:25 -04001133
1134 writer.appendName("caps");
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001135 fContext->fCaps->dumpJSON(&writer);
Brian Osman71a18892017-08-10 10:23:25 -04001136
1137 writer.appendName("gpu");
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001138 fContext->fGpu->dumpJSON(&writer);
Brian Osman71a18892017-08-10 10:23:25 -04001139
1140 // Flush JSON to the memory stream
1141 writer.endObject();
1142 writer.flush();
1143
1144 // Null terminate the JSON data in the memory stream
1145 stream.write8(0);
1146
1147 // Allocate a string big enough to hold all the data, then copy out of the stream
1148 SkString result(stream.bytesWritten());
1149 stream.copyToAndReset(result.writable_str());
1150 return result;
1151}
Kevin Lubickf4def342018-10-04 12:52:50 -04001152#endif