blob: 8410b407d279b6edabc4935353c28779a37ce25b [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"
Khushal71652e22018-10-29 13:05:36 -070036#include "SkTraceMemoryDump.h"
joshualitt5478d422014-11-14 16:00:38 -080037#include "effects/GrConfigConversionEffect.h"
Ethan Nicholas00543112018-07-31 09:44:36 -040038#include "effects/GrSkSLFP.h"
Chris Dalton6c3879d2018-11-01 11:13:19 -060039#include "ccpr/GrCoverageCountingPathRenderer.h"
Brian Salomon5f33a8c2018-02-26 14:32:39 -050040#include "text/GrTextBlobCache.h"
Mike Klein0ec1c572018-12-04 11:52:51 -050041#include <atomic>
42#include <unordered_map>
Greg Danielb76a72a2017-07-13 15:07:54 -040043
Robert Phillipse78b7252017-04-06 07:59:41 -040044#define ASSERT_OWNED_PROXY(P) \
Brian Salomonfd98c2c2018-07-31 17:25:29 -040045 SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == this)
Robert Phillips7ee385e2017-03-30 08:02:11 -040046#define ASSERT_OWNED_PROXY_PRIV(P) \
Brian Salomonfd98c2c2018-07-31 17:25:29 -040047 SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == fContext)
Robert Phillips7ee385e2017-03-30 08:02:11 -040048
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000049#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
joshualitt1de610a2016-01-06 08:26:09 -080050#define ASSERT_SINGLE_OWNER \
51 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fSingleOwner);)
robertphillips4fd74ae2016-08-03 14:26:53 -070052#define ASSERT_SINGLE_OWNER_PRIV \
53 SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fContext->fSingleOwner);)
robertphillips7761d612016-05-16 09:14:53 -070054#define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; }
Robert Phillips7ee385e2017-03-30 08:02:11 -040055#define RETURN_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return; }
robertphillips7761d612016-05-16 09:14:53 -070056#define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; }
Robert Phillipse78b7252017-04-06 07:59:41 -040057#define RETURN_FALSE_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return false; }
robertphillips7761d612016-05-16 09:14:53 -070058#define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; }
bsalomon@google.combc4b6542011-11-19 13:56:11 +000059
robertphillipsea461502015-05-26 11:38:03 -070060////////////////////////////////////////////////////////////////////////////////
61
Robert Phillipsc1541ae2019-02-04 12:05:37 -050062GrContext::GrContext(GrBackendApi backend, const GrContextOptions& options, int32_t id)
63 : INHERITED(backend, options, id) {
halcanary96fcdcc2015-08-27 07:41:13 -070064 fResourceCache = nullptr;
65 fResourceProvider = nullptr;
Robert Phillips1afd4cd2018-01-08 13:40:32 -050066 fProxyProvider = nullptr;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050067 fGlyphCache = nullptr;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000068}
69
Robert Phillipsc1541ae2019-02-04 12:05:37 -050070bool GrContext::initCommon() {
Greg Danielb76a72a2017-07-13 15:07:54 -040071 ASSERT_SINGLE_OWNER
Robert Phillipsfde6fa02018-03-02 08:53:14 -050072 SkASSERT(fCaps); // needs to have been initialized by derived classes
73 SkASSERT(fThreadSafeProxy); // needs to have been initialized by derived classes
Robert Phillips88260b52018-01-19 12:56:09 -050074
75 if (fGpu) {
76 fCaps = fGpu->refCaps();
Robert Phillipsfd0d9702019-02-01 10:19:42 -050077 fResourceCache = new GrResourceCache(fCaps.get(), &fSingleOwner, this->contextID());
Robert Phillips4150eea2018-02-07 17:08:21 -050078 fResourceProvider = new GrResourceProvider(fGpu.get(), fResourceCache, &fSingleOwner,
Robert Phillipsc1541ae2019-02-04 12:05:37 -050079 this->options().fExplicitlyAllocateGPUResources);
Brian Salomon238069b2018-07-11 15:58:57 -040080 fProxyProvider =
81 new GrProxyProvider(fResourceProvider, fResourceCache, fCaps, &fSingleOwner);
82 } else {
Robert Phillipsfd0d9702019-02-01 10:19:42 -050083 fProxyProvider = new GrProxyProvider(this->contextID(), fCaps, &fSingleOwner);
Robert Phillips88260b52018-01-19 12:56:09 -050084 }
85
Robert Phillips88260b52018-01-19 12:56:09 -050086 if (fResourceCache) {
87 fResourceCache->setProxyProvider(fProxyProvider);
88 }
Robert Phillips1afd4cd2018-01-08 13:40:32 -050089
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000090 fDidTestPMConversions = false;
91
bsalomon6b2552f2016-09-15 13:50:26 -070092 GrPathRendererChain::Options prcOptions;
Robert Phillipsc1541ae2019-02-04 12:05:37 -050093 prcOptions.fAllowPathMaskCaching = this->options().fAllowPathMaskCaching;
Brian Osman195c05b2017-08-30 15:14:04 -040094#if GR_TEST_UTILS
Robert Phillipsc1541ae2019-02-04 12:05:37 -050095 prcOptions.fGpuPathRenderers = this->options().fGpuPathRenderers;
Brian Osman195c05b2017-08-30 15:14:04 -040096#endif
Robert Phillipsc1541ae2019-02-04 12:05:37 -050097 if (this->options().fDisableCoverageCountingPaths) {
Chris Daltonef125092018-06-26 18:16:47 -060098 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
99 }
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500100 if (this->options().fDisableDistanceFieldPaths) {
Brian Osman195c05b2017-08-30 15:14:04 -0400101 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
Brian Osmanb350ae22017-08-29 16:15:39 -0400102 }
Brian Salomonaf597482017-11-07 16:23:34 -0500103
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500104 if (!fResourceCache) {
105 // DDL TODO: remove this crippling of the path renderer chain
106 // Disable the small path renderer bc of the proxies in the atlas. They need to be
107 // unified when the opLists are added back to the destination drawing manager.
108 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kSmall;
Robert Phillips5ffcb4d2018-07-03 16:39:40 -0400109 prcOptions.fGpuPathRenderers &= ~GpuPathRenderers::kStencilAndCover;
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500110 }
111
Herb Derby26cbe512018-05-24 14:39:01 -0400112 GrTextContext::Options textContextOptions;
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500113 textContextOptions.fMaxDistanceFieldFontSize = this->options().fGlyphsAsPathsFontSize;
114 textContextOptions.fMinDistanceFieldFontSize = this->options().fMinDistanceFieldFontSize;
Herb Derby26cbe512018-05-24 14:39:01 -0400115 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = false;
Brian Salomonb5086962017-12-13 10:59:33 -0500116#if SK_SUPPORT_ATLAS_TEXT
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500117 if (GrContextOptions::Enable::kYes == this->options().fDistanceFieldGlyphVerticesAlwaysHaveW) {
Herb Derby26cbe512018-05-24 14:39:01 -0400118 textContextOptions.fDistanceFieldVerticesAlwaysHaveW = true;
Brian Salomonb5086962017-12-13 10:59:33 -0500119 }
120#endif
Brian Salomonaf597482017-11-07 16:23:34 -0500121
Robert Phillips64ecdce2018-04-02 10:26:39 -0400122 bool explicitlyAllocatingResources = fResourceProvider
123 ? fResourceProvider->explicitlyAllocateGPUResources()
124 : false;
Herb Derby26cbe512018-05-24 14:39:01 -0400125 fDrawingManager.reset(new GrDrawingManager(this, prcOptions, textContextOptions,
Robert Phillips64ecdce2018-04-02 10:26:39 -0400126 &fSingleOwner, explicitlyAllocatingResources,
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500127 this->options().fSortRenderTargets,
128 this->options().fReduceOpListSplitting));
joshualitt7c3a2f82015-03-31 13:32:05 -0700129
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500130 fGlyphCache = new GrStrikeCache(fCaps.get(), this->options().fGlyphCacheTextureMaximumBytes);
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500131
Robert Phillipsfd0d9702019-02-01 10:19:42 -0500132 fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this, this->contextID()));
Brian Salomon91a3e522017-06-23 10:58:19 -0400133
Robert Phillipsfde6fa02018-03-02 08:53:14 -0500134 // DDL TODO: we need to think through how the task group & persistent cache
135 // get passed on to/shared between all the DDLRecorders created with this context.
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500136 if (this->options().fExecutor) {
137 fTaskGroup = skstd::make_unique<SkTaskGroup>(*this->options().fExecutor);
Brian Osman51279982017-08-23 10:12:00 -0400138 }
139
Robert Phillipsc1541ae2019-02-04 12:05:37 -0500140 fPersistentCache = this->options().fPersistentCache;
Ethan Nicholasd1b2eec2017-11-01 15:45:43 -0400141
Brian Salomon91a3e522017-06-23 10:58:19 -0400142 return true;
bsalomon@google.comc0af3172012-06-15 14:10:09 +0000143}
144
bsalomon@google.com27847de2011-02-22 20:59:41 +0000145GrContext::~GrContext() {
joshualitt1de610a2016-01-06 08:26:09 -0800146 ASSERT_SINGLE_OWNER
147
Robert Phillips2e6feed2018-01-22 15:27:20 -0500148 if (fDrawingManager) {
149 fDrawingManager->cleanup();
150 }
halcanary385fe4d2015-08-26 13:07:48 -0700151 delete fResourceProvider;
152 delete fResourceCache;
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500153 delete fProxyProvider;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500154 delete fGlyphCache;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000155}
156
Robert Phillips4217ea72019-01-30 13:08:28 -0500157sk_sp<GrContextThreadSafeProxy> GrContext::threadSafeProxy() {
158 return fThreadSafeProxy;
159}
160
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400161//////////////////////////////////////////////////////////////////////////////
162
bsalomon2354f842014-07-28 13:48:36 -0700163void GrContext::abandonContext() {
joshualitt1de610a2016-01-06 08:26:09 -0800164 ASSERT_SINGLE_OWNER
165
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500166 fProxyProvider->abandon();
bsalomond309e7a2015-04-30 14:18:54 -0700167 fResourceProvider->abandon();
robertphillips0dfa62c2015-11-16 06:23:31 -0800168
169 // Need to abandon the drawing manager first so all the render targets
170 // will be released/forgotten before they too are abandoned.
171 fDrawingManager->abandon();
172
bsalomon@google.com205d4602011-04-25 12:43:45 +0000173 // abandon first to so destructors
174 // don't try to free the resources in the API.
bsalomon0ea80f42015-02-11 10:49:59 -0800175 fResourceCache->abandonAll();
bsalomonc8dc1f72014-08-21 13:02:13 -0700176
bsalomon6e2aad42016-04-01 11:54:31 -0700177 fGpu->disconnect(GrGpu::DisconnectType::kAbandon);
178
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500179 fGlyphCache->freeAll();
bsalomon6e2aad42016-04-01 11:54:31 -0700180 fTextBlobCache->freeAll();
181}
182
Khushalc421ca12018-06-26 14:38:34 -0700183bool GrContext::abandoned() const {
184 ASSERT_SINGLE_OWNER
Brian Salomon9bc76d92019-01-24 12:18:33 -0500185 // If called from ~GrContext(), the drawing manager may already be gone.
186 return !fDrawingManager || fDrawingManager->wasAbandoned();
Khushalc421ca12018-06-26 14:38:34 -0700187}
188
bsalomon6e2aad42016-04-01 11:54:31 -0700189void GrContext::releaseResourcesAndAbandonContext() {
190 ASSERT_SINGLE_OWNER
191
Brian Salomon614c1a82018-12-19 15:42:06 -0500192 if (this->abandoned()) {
193 return;
194 }
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500195 fProxyProvider->abandon();
bsalomon6e2aad42016-04-01 11:54:31 -0700196 fResourceProvider->abandon();
197
198 // Need to abandon the drawing manager first so all the render targets
199 // will be released/forgotten before they too are abandoned.
200 fDrawingManager->abandon();
201
202 // Release all resources in the backend 3D API.
203 fResourceCache->releaseAll();
204
205 fGpu->disconnect(GrGpu::DisconnectType::kCleanup);
bsalomon@google.com205d4602011-04-25 12:43:45 +0000206
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500207 fGlyphCache->freeAll();
joshualitt26ffc002015-04-16 11:24:04 -0700208 fTextBlobCache->freeAll();
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000209}
210
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000211void GrContext::resetContext(uint32_t state) {
joshualitt1de610a2016-01-06 08:26:09 -0800212 ASSERT_SINGLE_OWNER
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000213 fGpu->markContextDirty(state);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000214}
215
216void GrContext::freeGpuResources() {
joshualitt1de610a2016-01-06 08:26:09 -0800217 ASSERT_SINGLE_OWNER
218
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500219 fGlyphCache->freeAll();
robertphillips68737822015-10-29 12:12:21 -0700220
221 fDrawingManager->freeGpuResources();
bsalomon3033b9f2015-04-13 11:09:56 -0700222
223 fResourceCache->purgeAllUnlocked();
bsalomon@google.com27847de2011-02-22 20:59:41 +0000224}
225
Robert Phillips6eba0632018-03-28 12:25:42 -0400226void GrContext::purgeUnlockedResources(bool scratchResourcesOnly) {
227 ASSERT_SINGLE_OWNER
228 fResourceCache->purgeUnlockedResources(scratchResourcesOnly);
229 fResourceCache->purgeAsNeeded();
230 fTextBlobCache->purgeStaleBlobs();
231}
232
Jim Van Verth76d917c2017-12-13 09:26:37 -0500233void GrContext::performDeferredCleanup(std::chrono::milliseconds msNotUsed) {
Brian Salomon5e150852017-03-22 14:53:13 -0400234 ASSERT_SINGLE_OWNER
Chris Dalton6c3879d2018-11-01 11:13:19 -0600235
236 auto purgeTime = GrStdSteadyClock::now() - msNotUsed;
237
Jim Van Verth76d917c2017-12-13 09:26:37 -0500238 fResourceCache->purgeAsNeeded();
Chris Dalton6c3879d2018-11-01 11:13:19 -0600239 fResourceCache->purgeResourcesNotUsedSince(purgeTime);
240
241 if (auto ccpr = fDrawingManager->getCoverageCountingPathRenderer()) {
Chris Dalton351e80c2019-01-06 22:51:00 -0700242 ccpr->purgeCacheEntriesOlderThan(fProxyProvider, purgeTime);
Chris Dalton6c3879d2018-11-01 11:13:19 -0600243 }
Jim Van Verth76d917c2017-12-13 09:26:37 -0500244
245 fTextBlobCache->purgeStaleBlobs();
Brian Salomon5e150852017-03-22 14:53:13 -0400246}
247
Derek Sollenberger5480a182017-05-25 16:43:59 -0400248void GrContext::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) {
249 ASSERT_SINGLE_OWNER
250 fResourceCache->purgeUnlockedResources(bytesToPurge, preferScratchResources);
251}
252
commit-bot@chromium.org95c20032014-05-09 14:29:32 +0000253void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
joshualitt1de610a2016-01-06 08:26:09 -0800254 ASSERT_SINGLE_OWNER
255
bsalomon71cb0c22014-11-14 12:10:14 -0800256 if (resourceCount) {
bsalomon0ea80f42015-02-11 10:49:59 -0800257 *resourceCount = fResourceCache->getBudgetedResourceCount();
bsalomon71cb0c22014-11-14 12:10:14 -0800258 }
259 if (resourceBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800260 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
bsalomon71cb0c22014-11-14 12:10:14 -0800261 }
commit-bot@chromium.orgd8a57af2014-03-19 21:19:16 +0000262}
263
Derek Sollenbergeree479142017-05-24 11:41:33 -0400264size_t GrContext::getResourceCachePurgeableBytes() const {
265 ASSERT_SINGLE_OWNER
266 return fResourceCache->getPurgeableBytes();
267}
268
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000269////////////////////////////////////////////////////////////////////////////////
270
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400271int GrContext::maxTextureSize() const { return fCaps->maxTextureSize(); }
Brian Salomonf932a632018-04-05 12:46:09 -0400272
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400273int GrContext::maxRenderTargetSize() const { return fCaps->maxRenderTargetSize(); }
Brian Salomonf932a632018-04-05 12:46:09 -0400274
Brian Salomonbdecacf2018-02-02 20:32:49 -0500275bool GrContext::colorTypeSupportedAsImage(SkColorType colorType) const {
Brian Osman2b23c4b2018-06-01 12:25:08 -0400276 GrPixelConfig config = SkColorType2GrPixelConfig(colorType);
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400277 return fCaps->isConfigTexturable(config);
Brian Salomonbdecacf2018-02-02 20:32:49 -0500278}
279
280int GrContext::maxSurfaceSampleCountForColorType(SkColorType colorType) const {
Brian Osman2b23c4b2018-06-01 12:25:08 -0400281 GrPixelConfig config = SkColorType2GrPixelConfig(colorType);
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400282 return fCaps->maxRenderTargetSampleCount(config);
Brian Salomonbdecacf2018-02-02 20:32:49 -0500283}
284
285////////////////////////////////////////////////////////////////////////////////
286
joshualitt0db6dfa2015-04-10 07:01:30 -0700287void GrContext::TextBlobCacheOverBudgetCB(void* data) {
288 SkASSERT(data);
Brian Osman11052242016-10-27 14:47:55 -0400289 // TextBlobs are drawn at the SkGpuDevice level, therefore they cannot rely on
290 // GrRenderTargetContext to perform a necessary flush. The solution is to move drawText calls
291 // to below the GrContext level, but this is not trivial because they call drawPath on
292 // SkGpuDevice.
joshualitt0db6dfa2015-04-10 07:01:30 -0700293 GrContext* context = reinterpret_cast<GrContext*>(data);
294 context->flush();
295}
296
bsalomon@google.com27847de2011-02-22 20:59:41 +0000297////////////////////////////////////////////////////////////////////////////////
298
bsalomonb77a9072016-09-07 10:02:04 -0700299void GrContext::flush() {
joshualitt1de610a2016-01-06 08:26:09 -0800300 ASSERT_SINGLE_OWNER
robertphillipsea461502015-05-26 11:38:03 -0700301 RETURN_IF_ABANDONED
Robert Phillips7ee385e2017-03-30 08:02:11 -0400302
303 fDrawingManager->flush(nullptr);
304}
305
Greg Daniel51316782017-08-02 15:10:09 +0000306GrSemaphoresSubmitted GrContext::flushAndSignalSemaphores(int numSemaphores,
307 GrBackendSemaphore signalSemaphores[]) {
308 ASSERT_SINGLE_OWNER
309 if (fDrawingManager->wasAbandoned()) { return GrSemaphoresSubmitted::kNo; }
310
311 return fDrawingManager->flush(nullptr, numSemaphores, signalSemaphores);
312}
313
Robert Phillips7ee385e2017-03-30 08:02:11 -0400314void GrContextPriv::flush(GrSurfaceProxy* proxy) {
315 ASSERT_SINGLE_OWNER_PRIV
316 RETURN_IF_ABANDONED_PRIV
317 ASSERT_OWNED_PROXY_PRIV(proxy);
318
319 fContext->fDrawingManager->flush(proxy);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000320}
321
Greg Daniela870b462019-01-08 15:49:46 -0500322////////////////////////////////////////////////////////////////////////////////
323
324void GrContext::storeVkPipelineCacheData() {
325 if (fGpu) {
326 fGpu->storeVkPipelineCacheData();
327 }
328}
329
330////////////////////////////////////////////////////////////////////////////////
331
Brian Salomonc320b152018-02-20 14:05:36 -0500332// TODO: This will be removed when GrSurfaceContexts are aware of their color types.
333// (skbug.com/6718)
Brian Osmand2ca59a2017-04-13 14:03:57 -0400334static bool valid_premul_config(GrPixelConfig config) {
Brian Salomonc320b152018-02-20 14:05:36 -0500335 switch (config) {
336 case kUnknown_GrPixelConfig: return false;
337 case kAlpha_8_GrPixelConfig: return false;
338 case kGray_8_GrPixelConfig: return false;
339 case kRGB_565_GrPixelConfig: return false;
340 case kRGBA_4444_GrPixelConfig: return true;
341 case kRGBA_8888_GrPixelConfig: return true;
Brian Salomon5fba7ad2018-03-22 10:01:16 -0400342 case kRGB_888_GrPixelConfig: return false;
Jim Van Verth69e57852018-12-05 13:38:59 -0500343 case kRG_88_GrPixelConfig: return false;
Brian Salomonc320b152018-02-20 14:05:36 -0500344 case kBGRA_8888_GrPixelConfig: return true;
345 case kSRGBA_8888_GrPixelConfig: return true;
346 case kSBGRA_8888_GrPixelConfig: return true;
Brian Osman10fc6fd2018-03-02 11:01:10 -0500347 case kRGBA_1010102_GrPixelConfig: return true;
Brian Salomonc320b152018-02-20 14:05:36 -0500348 case kRGBA_float_GrPixelConfig: return true;
349 case kRG_float_GrPixelConfig: return false;
350 case kAlpha_half_GrPixelConfig: return false;
351 case kRGBA_half_GrPixelConfig: return true;
Jim Van Verth1676cb92019-01-15 13:24:45 -0500352 case kRGB_ETC1_GrPixelConfig: return false;
Brian Salomonc320b152018-02-20 14:05:36 -0500353 case kAlpha_8_as_Alpha_GrPixelConfig: return false;
354 case kAlpha_8_as_Red_GrPixelConfig: return false;
355 case kAlpha_half_as_Red_GrPixelConfig: return false;
356 case kGray_8_as_Lum_GrPixelConfig: return false;
357 case kGray_8_as_Red_GrPixelConfig: return false;
358 }
359 SK_ABORT("Invalid GrPixelConfig");
360 return false;
Brian Osmance425512017-03-22 14:37:50 -0400361}
362
Brian Salomonc320b152018-02-20 14:05:36 -0500363static bool valid_premul_color_type(GrColorType ct) {
364 switch (ct) {
Brian Osman10fc6fd2018-03-02 11:01:10 -0500365 case GrColorType::kUnknown: return false;
366 case GrColorType::kAlpha_8: return false;
367 case GrColorType::kRGB_565: return false;
368 case GrColorType::kABGR_4444: return true;
369 case GrColorType::kRGBA_8888: return true;
Brian Salomon5fba7ad2018-03-22 10:01:16 -0400370 case GrColorType::kRGB_888x: return false;
Jim Van Verth69e57852018-12-05 13:38:59 -0500371 case GrColorType::kRG_88: return false;
Brian Osman10fc6fd2018-03-02 11:01:10 -0500372 case GrColorType::kBGRA_8888: return true;
373 case GrColorType::kRGBA_1010102: return true;
374 case GrColorType::kGray_8: return false;
375 case GrColorType::kAlpha_F16: return false;
376 case GrColorType::kRGBA_F16: return true;
377 case GrColorType::kRG_F32: return false;
378 case GrColorType::kRGBA_F32: return true;
Jim Van Verth1676cb92019-01-15 13:24:45 -0500379 case GrColorType::kRGB_ETC1: return false;
Brian Salomonc320b152018-02-20 14:05:36 -0500380 }
381 SK_ABORT("Invalid GrColorType");
382 return false;
383}
384
385static bool valid_pixel_conversion(GrColorType cpuColorType, GrPixelConfig gpuConfig,
Brian Osmand2ca59a2017-04-13 14:03:57 -0400386 bool premulConversion) {
Brian Osmand2ca59a2017-04-13 14:03:57 -0400387 // We only allow premul <-> unpremul conversions for some formats
Brian Salomonc320b152018-02-20 14:05:36 -0500388 if (premulConversion &&
389 (!valid_premul_color_type(cpuColorType) || !valid_premul_config(gpuConfig))) {
Brian Osmand2ca59a2017-04-13 14:03:57 -0400390 return false;
391 }
Brian Osmand2ca59a2017-04-13 14:03:57 -0400392 return true;
393}
394
Brian Salomonc320b152018-02-20 14:05:36 -0500395bool GrContextPriv::writeSurfacePixels(GrSurfaceContext* dst, int left, int top, int width,
396 int height, GrColorType srcColorType,
397 SkColorSpace* srcColorSpace, const void* buffer,
398 size_t rowBytes, uint32_t pixelOpsFlags) {
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500399 ASSERT_SINGLE_OWNER_PRIV
400 RETURN_FALSE_IF_ABANDONED_PRIV
401 SkASSERT(dst);
402 SkASSERT(buffer);
403 ASSERT_OWNED_PROXY_PRIV(dst->asSurfaceProxy());
Brian Salomond494f6e2018-06-01 14:13:43 -0400404 GR_CREATE_TRACE_MARKER_CONTEXT("GrContextPriv", "writeSurfacePixels", fContext);
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500405
406 if (GrColorType::kUnknown == srcColorType) {
407 return false;
408 }
409
410 if (!dst->asSurfaceProxy()->instantiate(this->resourceProvider())) {
411 return false;
412 }
413
414 GrSurfaceProxy* dstProxy = dst->asSurfaceProxy();
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400415 GrSurface* dstSurface = dstProxy->peekSurface();
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500416
417 if (!GrSurfacePriv::AdjustWritePixelParams(dstSurface->width(), dstSurface->height(),
418 GrColorTypeBytesPerPixel(srcColorType), &left, &top,
419 &width, &height, &buffer, &rowBytes)) {
420 return false;
421 }
422
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400423 // TODO: Make GrSurfaceContext know its alpha type and pass src buffer's alpha type.
424 bool premul = SkToBool(kUnpremul_PixelOpsFlag & pixelOpsFlags);
425
426 // For canvas2D putImageData performance we have a special code path for unpremul RGBA_8888 srcs
427 // that are premultiplied on the GPU. This is kept as narrow as possible for now.
Brian Salomon817847c2018-05-07 13:33:50 -0400428 bool canvas2DFastPath =
Greg Daniel4374e962018-09-28 15:09:47 -0400429 !fContext->contextPriv().caps()->avoidWritePixelsFastPath() &&
Brian Salomon817847c2018-05-07 13:33:50 -0400430 premul &&
Brian Osman34ec3742018-07-03 10:40:57 -0400431 !dst->colorSpaceInfo().colorSpace() &&
Brian Salomon817847c2018-05-07 13:33:50 -0400432 (srcColorType == GrColorType::kRGBA_8888 || srcColorType == GrColorType::kBGRA_8888) &&
433 SkToBool(dst->asRenderTargetContext()) &&
434 (dstProxy->config() == kRGBA_8888_GrPixelConfig ||
435 dstProxy->config() == kBGRA_8888_GrPixelConfig) &&
436 !(pixelOpsFlags & kDontFlush_PixelOpsFlag) &&
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400437 fContext->contextPriv().caps()->isConfigTexturable(kRGBA_8888_GrPixelConfig) &&
Brian Salomon817847c2018-05-07 13:33:50 -0400438 fContext->validPMUPMConversionExists();
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400439
Greg Daniel4065d452018-11-16 15:43:41 -0500440 const GrCaps* caps = this->caps();
441 if (!caps->surfaceSupportsWritePixels(dstSurface) ||
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400442 canvas2DFastPath) {
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400443 // We don't expect callers that are skipping flushes to require an intermediate draw.
444 SkASSERT(!(pixelOpsFlags & kDontFlush_PixelOpsFlag));
445 if (pixelOpsFlags & kDontFlush_PixelOpsFlag) {
446 return false;
447 }
448
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500449 GrSurfaceDesc desc;
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500450 desc.fWidth = width;
451 desc.fHeight = height;
452 desc.fSampleCnt = 1;
Greg Daniel4065d452018-11-16 15:43:41 -0500453
454 GrBackendFormat format;
455 if (canvas2DFastPath) {
456 desc.fConfig = kRGBA_8888_GrPixelConfig;
457 format =
458 fContext->contextPriv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
459 } else {
460 desc.fConfig = dstProxy->config();
461 format = dstProxy->backendFormat().makeTexture2D();
462 if (!format.isValid()) {
463 return false;
464 }
465 }
466
Brian Salomon2a4f9832018-03-03 22:43:43 -0500467 auto tempProxy = this->proxyProvider()->createProxy(
Greg Daniel4065d452018-11-16 15:43:41 -0500468 format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500469 if (!tempProxy) {
470 return false;
471 }
472 auto tempCtx = this->drawingManager()->makeTextureContext(
473 tempProxy, dst->colorSpaceInfo().refColorSpace());
474 if (!tempCtx) {
475 return false;
476 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400477 uint32_t flags = canvas2DFastPath ? 0 : pixelOpsFlags;
Brian Salomon817847c2018-05-07 13:33:50 -0400478 // In the fast path we always write the srcData to the temp context as though it were RGBA.
479 // When the data is really BGRA the write will cause the R and B channels to be swapped in
480 // the intermediate surface which gets corrected by a swizzle effect when drawing to the
481 // dst.
482 auto tmpColorType = canvas2DFastPath ? GrColorType::kRGBA_8888 : srcColorType;
Brian Salomond494f6e2018-06-01 14:13:43 -0400483 if (!this->writeSurfacePixels(tempCtx.get(), 0, 0, width, height, tmpColorType,
484 srcColorSpace, buffer, rowBytes, flags)) {
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500485 return false;
486 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400487 if (canvas2DFastPath) {
488 GrPaint paint;
489 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
Brian Salomon817847c2018-05-07 13:33:50 -0400490 auto fp = fContext->createUPMToPMEffect(
Brian Osman5ea96bf2018-10-02 14:58:05 -0400491 GrSimpleTextureEffect::Make(std::move(tempProxy), SkMatrix::I()));
Brian Salomon817847c2018-05-07 13:33:50 -0400492 if (srcColorType == GrColorType::kBGRA_8888) {
493 fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
494 }
495 if (!fp) {
496 return false;
497 }
498 paint.addColorFragmentProcessor(std::move(fp));
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400499 dst->asRenderTargetContext()->fillRectToRect(
500 GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
501 SkRect::MakeXYWH(left, top, width, height), SkRect::MakeWH(width, height));
502 return true;
503 } else {
504 return dst->copy(tempProxy.get(), SkIRect::MakeWH(width, height), {left, top});
505 }
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500506 }
507
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500508 bool convert = premul;
509
510 if (!valid_pixel_conversion(srcColorType, dstProxy->config(), premul)) {
511 return false;
512 }
513
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400514 GrColorType allowedColorType = fContext->contextPriv().caps()->supportedWritePixelsColorType(
515 dstProxy->config(), srcColorType);
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500516 convert = convert || (srcColorType != allowedColorType);
517
518 if (!dst->colorSpaceInfo().colorSpace()) {
519 // "Legacy" mode - no color space conversions.
520 srcColorSpace = nullptr;
521 }
522 convert = convert || !SkColorSpace::Equals(srcColorSpace, dst->colorSpaceInfo().colorSpace());
523
524 std::unique_ptr<char[]> tempBuffer;
525 if (convert) {
526 auto srcSkColorType = GrColorTypeToSkColorType(srcColorType);
527 auto dstSkColorType = GrColorTypeToSkColorType(allowedColorType);
528 if (kUnknown_SkColorType == srcSkColorType || kUnknown_SkColorType == dstSkColorType) {
529 return false;
530 }
Brian Osman2091fbb2018-10-11 11:05:37 -0400531 auto srcAlphaType = SkColorTypeIsAlwaysOpaque(srcSkColorType)
532 ? kOpaque_SkAlphaType
533 : (premul ? kUnpremul_SkAlphaType : kPremul_SkAlphaType);
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500534 SkPixmap src(SkImageInfo::Make(width, height, srcSkColorType, srcAlphaType,
535 sk_ref_sp(srcColorSpace)),
536 buffer, rowBytes);
537 auto tempSrcII = SkImageInfo::Make(width, height, dstSkColorType, kPremul_SkAlphaType,
538 dst->colorSpaceInfo().refColorSpace());
539 auto size = tempSrcII.computeMinByteSize();
540 if (!size) {
541 return false;
542 }
543 tempBuffer.reset(new char[size]);
544 SkPixmap tempSrc(tempSrcII, tempBuffer.get(), tempSrcII.minRowBytes());
545 if (!src.readPixels(tempSrc)) {
546 return false;
547 }
548 srcColorType = allowedColorType;
549 buffer = tempSrc.addr();
550 rowBytes = tempSrc.rowBytes();
551 if (dstProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
552 std::unique_ptr<char[]> row(new char[rowBytes]);
553 for (int y = 0; y < height / 2; ++y) {
554 memcpy(row.get(), tempSrc.addr(0, y), rowBytes);
555 memcpy(tempSrc.writable_addr(0, y), tempSrc.addr(0, height - 1 - y), rowBytes);
556 memcpy(tempSrc.writable_addr(0, height - 1 - y), row.get(), rowBytes);
557 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400558 top = dstSurface->height() - top - height;
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500559 }
560 } else if (dstProxy->origin() == kBottomLeft_GrSurfaceOrigin) {
561 size_t trimRowBytes = GrColorTypeBytesPerPixel(srcColorType) * width;
562 tempBuffer.reset(new char[trimRowBytes * height]);
563 char* dst = reinterpret_cast<char*>(tempBuffer.get()) + trimRowBytes * (height - 1);
564 const char* src = reinterpret_cast<const char*>(buffer);
565 for (int i = 0; i < height; ++i, src += rowBytes, dst -= trimRowBytes) {
566 memcpy(dst, src, trimRowBytes);
567 }
568 buffer = tempBuffer.get();
569 rowBytes = trimRowBytes;
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400570 top = dstSurface->height() - top - height;
Brian Salomon5f33a8c2018-02-26 14:32:39 -0500571 }
572
573 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && dstSurface->surfacePriv().hasPendingIO()) {
574 this->flush(nullptr); // MDB TODO: tighten this
575 }
576
577 return this->getGpu()->writePixels(dstSurface, left, top, width, height, srcColorType, buffer,
578 rowBytes);
579}
580
Brian Salomond494f6e2018-06-01 14:13:43 -0400581bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src, int left, int top, int width,
582 int height, GrColorType dstColorType,
583 SkColorSpace* dstColorSpace, void* buffer, size_t rowBytes,
584 uint32_t pixelOpsFlags) {
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400585 ASSERT_SINGLE_OWNER_PRIV
586 RETURN_FALSE_IF_ABANDONED_PRIV
587 SkASSERT(src);
588 SkASSERT(buffer);
589 ASSERT_OWNED_PROXY_PRIV(src->asSurfaceProxy());
Brian Salomond494f6e2018-06-01 14:13:43 -0400590 GR_CREATE_TRACE_MARKER_CONTEXT("GrContextPriv", "readSurfacePixels", fContext);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400591
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400592 SkASSERT(!(pixelOpsFlags & kDontFlush_PixelOpsFlag));
593 if (pixelOpsFlags & kDontFlush_PixelOpsFlag) {
Brian Salomon5fba7ad2018-03-22 10:01:16 -0400594 return false;
595 }
596
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400597 // MDB TODO: delay this instantiation until later in the method
598 if (!src->asSurfaceProxy()->instantiate(this->resourceProvider())) {
599 return false;
600 }
601
602 GrSurfaceProxy* srcProxy = src->asSurfaceProxy();
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400603 GrSurface* srcSurface = srcProxy->peekSurface();
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400604
605 if (!GrSurfacePriv::AdjustReadPixelParams(srcSurface->width(), srcSurface->height(),
606 GrColorTypeBytesPerPixel(dstColorType), &left, &top,
607 &width, &height, &buffer, &rowBytes)) {
608 return false;
609 }
610
611 // TODO: Make GrSurfaceContext know its alpha type and pass dst buffer's alpha type.
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400612 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & pixelOpsFlags);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400613
614 if (!valid_pixel_conversion(dstColorType, srcProxy->config(), unpremul)) {
615 return false;
616 }
617
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400618 // This is the getImageData equivalent to the canvas2D putImageData fast path. We probably don't
619 // care so much about getImageData performance. However, in order to ensure putImageData/
620 // getImageData in "legacy" mode are round-trippable we use the GPU to do the complementary
Brian Salomond494f6e2018-06-01 14:13:43 -0400621 // unpremul step to writeSurfacePixels's premul step (which is determined empirically in
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400622 // fContext->vaildaPMUPMConversionExists()).
Brian Salomon817847c2018-05-07 13:33:50 -0400623 bool canvas2DFastPath =
624 unpremul &&
Brian Osman34ec3742018-07-03 10:40:57 -0400625 !src->colorSpaceInfo().colorSpace() &&
Brian Salomon817847c2018-05-07 13:33:50 -0400626 (GrColorType::kRGBA_8888 == dstColorType || GrColorType::kBGRA_8888 == dstColorType) &&
627 SkToBool(srcProxy->asTextureProxy()) &&
628 (srcProxy->config() == kRGBA_8888_GrPixelConfig ||
629 srcProxy->config() == kBGRA_8888_GrPixelConfig) &&
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400630 fContext->contextPriv().caps()->isConfigRenderable(kRGBA_8888_GrPixelConfig) &&
Brian Salomon817847c2018-05-07 13:33:50 -0400631 fContext->validPMUPMConversionExists();
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400632
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400633 if (!fContext->contextPriv().caps()->surfaceSupportsReadPixels(srcSurface) ||
634 canvas2DFastPath) {
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400635 GrSurfaceDesc desc;
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400636 desc.fFlags = canvas2DFastPath ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
637 desc.fConfig = canvas2DFastPath ? kRGBA_8888_GrPixelConfig : srcProxy->config();
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400638 desc.fWidth = width;
639 desc.fHeight = height;
640 desc.fSampleCnt = 1;
Greg Daniel4065d452018-11-16 15:43:41 -0500641
642 GrBackendFormat format;
643 if (canvas2DFastPath) {
644 desc.fFlags = kRenderTarget_GrSurfaceFlag;
645 desc.fConfig = kRGBA_8888_GrPixelConfig;
646 format = this->caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
647 } else {
648 desc.fFlags = kNone_GrSurfaceFlags;
649 desc.fConfig = srcProxy->config();
650 format = srcProxy->backendFormat().makeTexture2D();
651 if (!format.isValid()) {
652 return false;
653 }
654 }
655
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400656 auto tempProxy = this->proxyProvider()->createProxy(
Greg Daniel4065d452018-11-16 15:43:41 -0500657 format, desc, kTopLeft_GrSurfaceOrigin, SkBackingFit::kApprox, SkBudgeted::kYes);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400658 if (!tempProxy) {
659 return false;
660 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400661 sk_sp<GrSurfaceContext> tempCtx;
662 if (canvas2DFastPath) {
663 tempCtx = this->drawingManager()->makeRenderTargetContext(std::move(tempProxy), nullptr,
664 nullptr);
Greg Daniel42314012018-04-23 10:57:37 -0400665 SkASSERT(tempCtx->asRenderTargetContext());
666 tempCtx->asRenderTargetContext()->discard();
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400667 } else {
668 tempCtx = this->drawingManager()->makeTextureContext(
669 std::move(tempProxy), src->colorSpaceInfo().refColorSpace());
670 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400671 if (!tempCtx) {
672 return false;
673 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400674 if (canvas2DFastPath) {
675 GrPaint paint;
676 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
Brian Salomon817847c2018-05-07 13:33:50 -0400677 auto fp = fContext->createPMToUPMEffect(
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400678 GrSimpleTextureEffect::Make(sk_ref_sp(srcProxy->asTextureProxy()),
Brian Osman5ea96bf2018-10-02 14:58:05 -0400679 SkMatrix::I()));
Brian Salomon817847c2018-05-07 13:33:50 -0400680 if (dstColorType == GrColorType::kBGRA_8888) {
681 fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
682 dstColorType = GrColorType::kRGBA_8888;
683 }
684 if (!fp) {
685 return false;
686 }
687 paint.addColorFragmentProcessor(std::move(fp));
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400688 tempCtx->asRenderTargetContext()->fillRectToRect(
689 GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(),
690 SkRect::MakeWH(width, height), SkRect::MakeXYWH(left, top, width, height));
691 } else if (!tempCtx->copy(srcProxy, SkIRect::MakeXYWH(left, top, width, height), {0, 0})) {
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400692 return false;
693 }
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400694 uint32_t flags = canvas2DFastPath ? 0 : pixelOpsFlags;
Brian Salomond494f6e2018-06-01 14:13:43 -0400695 return this->readSurfacePixels(tempCtx.get(), 0, 0, width, height, dstColorType,
696 dstColorSpace, buffer, rowBytes, flags);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400697 }
698
Brian Salomonf3c4e0c2018-04-06 20:32:06 -0400699 bool convert = unpremul;
700
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400701 bool flip = srcProxy->origin() == kBottomLeft_GrSurfaceOrigin;
702 if (flip) {
703 top = srcSurface->height() - top - height;
704 }
705
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400706 GrColorType allowedColorType = fContext->contextPriv().caps()->supportedReadPixelsColorType(
707 srcProxy->config(), dstColorType);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400708 convert = convert || (dstColorType != allowedColorType);
709
710 if (!src->colorSpaceInfo().colorSpace()) {
711 // "Legacy" mode - no color space conversions.
712 dstColorSpace = nullptr;
713 }
714 convert = convert || !SkColorSpace::Equals(dstColorSpace, src->colorSpaceInfo().colorSpace());
715
716 SkAutoPixmapStorage tempPixmap;
717 SkPixmap finalPixmap;
718 if (convert) {
719 SkColorType srcSkColorType = GrColorTypeToSkColorType(allowedColorType);
720 SkColorType dstSkColorType = GrColorTypeToSkColorType(dstColorType);
Brian Osman2091fbb2018-10-11 11:05:37 -0400721 bool srcAlwaysOpaque = SkColorTypeIsAlwaysOpaque(srcSkColorType);
722 bool dstAlwaysOpaque = SkColorTypeIsAlwaysOpaque(dstSkColorType);
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400723 if (kUnknown_SkColorType == srcSkColorType || kUnknown_SkColorType == dstSkColorType) {
724 return false;
725 }
Brian Osman2091fbb2018-10-11 11:05:37 -0400726 auto tempAT = srcAlwaysOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400727 auto tempII = SkImageInfo::Make(width, height, srcSkColorType, tempAT,
728 src->colorSpaceInfo().refColorSpace());
Brian Osman2091fbb2018-10-11 11:05:37 -0400729 SkASSERT(!unpremul || !dstAlwaysOpaque);
730 auto finalAT = (srcAlwaysOpaque || dstAlwaysOpaque)
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400731 ? kOpaque_SkAlphaType
732 : unpremul ? kUnpremul_SkAlphaType : kPremul_SkAlphaType;
733 auto finalII =
734 SkImageInfo::Make(width, height, dstSkColorType, finalAT, sk_ref_sp(dstColorSpace));
735 if (!SkImageInfoValidConversion(finalII, tempII)) {
736 return false;
737 }
Brian Salomon6196fc12018-07-12 16:39:23 -0400738 if (!tempPixmap.tryAlloc(tempII)) {
739 return false;
740 }
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400741 finalPixmap.reset(finalII, buffer, rowBytes);
742 buffer = tempPixmap.writable_addr();
743 rowBytes = tempPixmap.rowBytes();
Brian Salomon3d945e82018-05-14 14:54:06 -0400744 // Chrome msan bots require this.
745 sk_bzero(buffer, tempPixmap.computeByteSize());
Brian Salomon19eaf2d2018-03-19 16:06:44 -0400746 }
747
748 if (srcSurface->surfacePriv().hasPendingWrite()) {
749 this->flush(nullptr); // MDB TODO: tighten this
750 }
751
752 if (!fContext->fGpu->readPixels(srcSurface, left, top, width, height, allowedColorType, buffer,
753 rowBytes)) {
754 return false;
755 }
756
757 if (flip) {
758 size_t trimRowBytes = GrColorTypeBytesPerPixel(allowedColorType) * width;
759 std::unique_ptr<char[]> row(new char[trimRowBytes]);
760 char* upper = reinterpret_cast<char*>(buffer);
761 char* lower = reinterpret_cast<char*>(buffer) + (height - 1) * rowBytes;
762 for (int y = 0; y < height / 2; ++y, upper += rowBytes, lower -= rowBytes) {
763 memcpy(row.get(), upper, trimRowBytes);
764 memcpy(upper, lower, trimRowBytes);
765 memcpy(lower, row.get(), trimRowBytes);
766 }
767 }
768 if (convert) {
769 if (!tempPixmap.readPixels(finalPixmap)) {
770 return false;
771 }
772 }
773 return true;
774}
775
Robert Phillips7ee385e2017-03-30 08:02:11 -0400776void GrContextPriv::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) {
777 ASSERT_SINGLE_OWNER_PRIV
778 RETURN_IF_ABANDONED_PRIV
779 SkASSERT(proxy);
780 ASSERT_OWNED_PROXY_PRIV(proxy);
Greg Daniel51316782017-08-02 15:10:09 +0000781 fContext->fDrawingManager->prepareSurfaceForExternalIO(proxy, 0, nullptr);
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000782}
783
Robert Phillips7ee385e2017-03-30 08:02:11 -0400784void GrContextPriv::flushSurfaceWrites(GrSurfaceProxy* proxy) {
785 ASSERT_SINGLE_OWNER_PRIV
786 RETURN_IF_ABANDONED_PRIV
787 SkASSERT(proxy);
788 ASSERT_OWNED_PROXY_PRIV(proxy);
789 if (proxy->priv().hasPendingWrite()) {
790 this->flush(proxy);
bsalomonf80bfed2014-10-07 05:56:02 -0700791 }
792}
793
Robert Phillips7ee385e2017-03-30 08:02:11 -0400794void GrContextPriv::flushSurfaceIO(GrSurfaceProxy* proxy) {
795 ASSERT_SINGLE_OWNER_PRIV
796 RETURN_IF_ABANDONED_PRIV
797 SkASSERT(proxy);
798 ASSERT_OWNED_PROXY_PRIV(proxy);
799 if (proxy->priv().hasPendingIO()) {
800 this->flush(proxy);
ajuma95243eb2016-08-24 08:19:02 -0700801 }
802}
803
bsalomon@google.com27847de2011-02-22 20:59:41 +0000804////////////////////////////////////////////////////////////////////////////////
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000805
Robert Phillipsc994a932018-06-19 13:09:54 -0400806sk_sp<GrOpMemoryPool> GrContextPriv::refOpMemoryPool() {
807 if (!fContext->fOpMemoryPool) {
808 // DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory
809 // consumed in DDL mode vs. normal mode for a single skp might be a good metric of wasted
810 // memory.
811 fContext->fOpMemoryPool = sk_sp<GrOpMemoryPool>(new GrOpMemoryPool(16384, 16384));
812 }
813
814 SkASSERT(fContext->fOpMemoryPool);
815 return fContext->fOpMemoryPool;
816}
817
818GrOpMemoryPool* GrContextPriv::opMemoryPool() {
819 return this->refOpMemoryPool().get();
820}
821
Robert Phillips2c862492017-01-18 10:08:39 -0500822sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy,
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500823 sk_sp<SkColorSpace> colorSpace,
824 const SkSurfaceProps* props) {
Brian Osman45580d32016-11-23 09:37:01 -0500825 ASSERT_SINGLE_OWNER_PRIV
826
Brian Osman45580d32016-11-23 09:37:01 -0500827 if (proxy->asRenderTargetProxy()) {
Robert Phillips2c862492017-01-18 10:08:39 -0500828 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500829 std::move(colorSpace), props);
Brian Osman45580d32016-11-23 09:37:01 -0500830 } else {
831 SkASSERT(proxy->asTextureProxy());
Robert Phillipsd5f9cdd2018-01-31 09:29:48 -0500832 SkASSERT(!props);
Robert Phillips2c862492017-01-18 10:08:39 -0500833 return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
Brian Osman45580d32016-11-23 09:37:01 -0500834 }
835}
836
Greg Daniel4065d452018-11-16 15:43:41 -0500837sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrBackendFormat& format,
838 const GrSurfaceDesc& dstDesc,
Brian Salomon2a4f9832018-03-03 22:43:43 -0500839 GrSurfaceOrigin origin,
Greg Daniel65c7f662017-10-30 13:39:09 -0400840 GrMipMapped mipMapped,
Robert Phillipse2f7d182016-12-15 09:23:05 -0500841 SkBackingFit fit,
Brian Salomon366093f2018-02-13 09:25:22 -0500842 SkBudgeted isDstBudgeted,
843 sk_sp<SkColorSpace> colorSpace,
844 const SkSurfaceProps* props) {
Greg Daniel65c7f662017-10-30 13:39:09 -0400845 sk_sp<GrTextureProxy> proxy;
846 if (GrMipMapped::kNo == mipMapped) {
Greg Daniel4065d452018-11-16 15:43:41 -0500847 proxy = this->proxyProvider()->createProxy(format, dstDesc, origin, fit, isDstBudgeted);
Greg Daniel65c7f662017-10-30 13:39:09 -0400848 } else {
849 SkASSERT(SkBackingFit::kExact == fit);
Greg Daniel4065d452018-11-16 15:43:41 -0500850 proxy = this->proxyProvider()->createMipMapProxy(format, dstDesc, origin, isDstBudgeted);
Greg Daniel65c7f662017-10-30 13:39:09 -0400851 }
Robert Phillips77b3f322017-01-31 18:24:12 -0500852 if (!proxy) {
853 return nullptr;
854 }
Robert Phillipse2f7d182016-12-15 09:23:05 -0500855
Greg Daniel55fa6472018-03-16 16:13:10 -0400856 sk_sp<GrSurfaceContext> sContext = this->makeWrappedSurfaceContext(std::move(proxy),
857 std::move(colorSpace),
858 props);
859 if (sContext && sContext->asRenderTargetContext()) {
860 sContext->asRenderTargetContext()->discard();
861 }
862
863 return sContext;
Robert Phillipse2f7d182016-12-15 09:23:05 -0500864}
865
Brian Salomond17f6582017-07-19 18:28:58 -0400866sk_sp<GrTextureContext> GrContextPriv::makeBackendTextureContext(const GrBackendTexture& tex,
Greg Daniel7ef28f32017-04-20 16:41:55 +0000867 GrSurfaceOrigin origin,
Brian Osmanc1e37052017-03-09 14:19:20 -0500868 sk_sp<SkColorSpace> colorSpace) {
Robert Phillips26caf892017-01-27 10:58:31 -0500869 ASSERT_SINGLE_OWNER_PRIV
870
Brian Salomonc67c31c2018-12-06 10:00:03 -0500871 sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendTexture(
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500872 tex, origin, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType);
Robert Phillips77b3f322017-01-31 18:24:12 -0500873 if (!proxy) {
874 return nullptr;
875 }
Robert Phillips26caf892017-01-27 10:58:31 -0500876
Brian Salomond17f6582017-07-19 18:28:58 -0400877 return this->drawingManager()->makeTextureContext(std::move(proxy), std::move(colorSpace));
Robert Phillips26caf892017-01-27 10:58:31 -0500878}
879
Brian Osman11052242016-10-27 14:47:55 -0400880sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureRenderTargetContext(
Greg Daniel7ef28f32017-04-20 16:41:55 +0000881 const GrBackendTexture& tex,
882 GrSurfaceOrigin origin,
883 int sampleCnt,
Brian Osman11052242016-10-27 14:47:55 -0400884 sk_sp<SkColorSpace> colorSpace,
Brian Osmanc1e37052017-03-09 14:19:20 -0500885 const SkSurfaceProps* props) {
robertphillips4fd74ae2016-08-03 14:26:53 -0700886 ASSERT_SINGLE_OWNER_PRIV
Brian Salomonbdecacf2018-02-02 20:32:49 -0500887 SkASSERT(sampleCnt > 0);
robertphillips4fd74ae2016-08-03 14:26:53 -0700888
Brian Salomonaa6ca0a2019-01-24 16:03:07 -0500889 sk_sp<GrTextureProxy> proxy(this->proxyProvider()->wrapRenderableBackendTexture(
890 tex, origin, sampleCnt, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo));
Robert Phillips77b3f322017-01-31 18:24:12 -0500891 if (!proxy) {
892 return nullptr;
893 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400894
Robert Phillips37430132016-11-09 06:50:43 -0500895 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
Brian Osman11052242016-10-27 14:47:55 -0400896 std::move(colorSpace), props);
robertphillips4fd74ae2016-08-03 14:26:53 -0700897}
898
Brian Osman11052242016-10-27 14:47:55 -0400899sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendRenderTargetRenderTargetContext(
Greg Danielbcf612b2017-05-01 13:50:58 +0000900 const GrBackendRenderTarget& backendRT,
901 GrSurfaceOrigin origin,
robertphillips4fd74ae2016-08-03 14:26:53 -0700902 sk_sp<SkColorSpace> colorSpace,
903 const SkSurfaceProps* surfaceProps) {
904 ASSERT_SINGLE_OWNER_PRIV
905
Brian Salomon7578f3e2018-03-07 14:39:54 -0500906 sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->wrapBackendRenderTarget(backendRT, origin);
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),
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400912 std::move(colorSpace),
Brian Osman11052242016-10-27 14:47:55 -0400913 surfaceProps);
robertphillips4fd74ae2016-08-03 14:26:53 -0700914}
915
Brian Osman11052242016-10-27 14:47:55 -0400916sk_sp<GrRenderTargetContext> GrContextPriv::makeBackendTextureAsRenderTargetRenderTargetContext(
Greg Daniel7ef28f32017-04-20 16:41:55 +0000917 const GrBackendTexture& tex,
918 GrSurfaceOrigin origin,
919 int sampleCnt,
robertphillips4fd74ae2016-08-03 14:26:53 -0700920 sk_sp<SkColorSpace> colorSpace,
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500921 const SkSurfaceProps* props) {
robertphillips4fd74ae2016-08-03 14:26:53 -0700922 ASSERT_SINGLE_OWNER_PRIV
Brian Salomonbdecacf2018-02-02 20:32:49 -0500923 SkASSERT(sampleCnt > 0);
Brian Salomon7578f3e2018-03-07 14:39:54 -0500924 sk_sp<GrSurfaceProxy> proxy(
925 this->proxyProvider()->wrapBackendTextureAsRenderTarget(tex, origin, sampleCnt));
Robert Phillips77b3f322017-01-31 18:24:12 -0500926 if (!proxy) {
927 return nullptr;
928 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400929
Robert Phillips37430132016-11-09 06:50:43 -0500930 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
Robert Phillipsc7635fa2016-10-28 13:25:24 -0400931 std::move(colorSpace),
Robert Phillips0bd24dc2018-01-16 08:06:32 -0500932 props);
robertphillips77a2e522015-10-17 07:43:27 -0700933}
934
Greg Danielb46add82019-01-02 14:51:29 -0500935sk_sp<GrRenderTargetContext> GrContextPriv::makeVulkanSecondaryCBRenderTargetContext(
936 const SkImageInfo& imageInfo, const GrVkDrawableInfo& vkInfo, const SkSurfaceProps* props) {
937 ASSERT_SINGLE_OWNER_PRIV
938 sk_sp<GrSurfaceProxy> proxy(
939 this->proxyProvider()->wrapVulkanSecondaryCBAsRenderTarget(imageInfo, vkInfo));
940 if (!proxy) {
941 return nullptr;
942 }
943
944 return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
945 imageInfo.refColorSpace(),
946 props);
947}
948
Chris Daltonfe199b72017-05-05 11:26:15 -0400949void GrContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
950 fContext->fDrawingManager->addOnFlushCallbackObject(onFlushCBObject);
Robert Phillipseb35f4d2017-03-21 07:56:47 -0400951}
952
Robert Phillips62000362018-02-01 09:10:04 -0500953void GrContextPriv::moveOpListsToDDL(SkDeferredDisplayList* ddl) {
954 fContext->fDrawingManager->moveOpListsToDDL(ddl);
955}
956
957void GrContextPriv::copyOpListsFromDDL(const SkDeferredDisplayList* ddl,
958 GrRenderTargetProxy* newDest) {
959 fContext->fDrawingManager->copyOpListsFromDDL(ddl, newDest);
960}
961
robertphillips48fde9c2016-09-06 05:20:20 -0700962static inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) {
Brian Osman78f20e02017-01-12 10:28:01 -0500963 switch (config) {
964 case kAlpha_8_GrPixelConfig:
Greg Daniel93b4ddd2018-04-16 16:16:47 -0400965 case kAlpha_8_as_Alpha_GrPixelConfig:
966 case kAlpha_8_as_Red_GrPixelConfig:
Brian Osman78f20e02017-01-12 10:28:01 -0500967 case kRGB_565_GrPixelConfig:
968 case kRGBA_4444_GrPixelConfig:
969 case kBGRA_8888_GrPixelConfig:
Brian Osman10fc6fd2018-03-02 11:01:10 -0500970 case kRGBA_1010102_GrPixelConfig:
Brian Osman9c111352018-10-16 10:18:26 -0400971 case kRGBA_half_GrPixelConfig:
Brian Osman78f20e02017-01-12 10:28:01 -0500972 return kRGBA_8888_GrPixelConfig;
973 case kSBGRA_8888_GrPixelConfig:
974 return kSRGBA_8888_GrPixelConfig;
975 case kAlpha_half_GrPixelConfig:
Greg Daniel93b4ddd2018-04-16 16:16:47 -0400976 case kAlpha_half_as_Red_GrPixelConfig:
Brian Osman78f20e02017-01-12 10:28:01 -0500977 return kRGBA_half_GrPixelConfig;
Greg Daniel93b4ddd2018-04-16 16:16:47 -0400978 case kGray_8_GrPixelConfig:
979 case kGray_8_as_Lum_GrPixelConfig:
980 case kGray_8_as_Red_GrPixelConfig:
981 return kRGB_888_GrPixelConfig;
Brian Osman78f20e02017-01-12 10:28:01 -0500982 default:
983 return kUnknown_GrPixelConfig;
984 }
robertphillips48fde9c2016-09-06 05:20:20 -0700985}
986
Robert Phillips0c4b7b12018-03-06 08:20:37 -0500987sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContextWithFallback(
Greg Daniel4065d452018-11-16 15:43:41 -0500988 const GrBackendFormat& format,
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) {
Greg Daniel4065d452018-11-16 15:43:41 -0500998 GrBackendFormat localFormat = format;
Brian Salomonbdecacf2018-02-02 20:32:49 -0500999 SkASSERT(sampleCnt > 0);
Brian Salomonc7fe0f72018-05-11 10:14:21 -04001000 if (0 == fContext->contextPriv().caps()->getRenderTargetSampleCount(sampleCnt, config)) {
robertphillipsd728f0c2016-11-21 11:05:03 -08001001 config = GrPixelConfigFallback(config);
Greg Daniel4065d452018-11-16 15:43:41 -05001002 // TODO: First we should be checking the getRenderTargetSampleCount from the GrBackendFormat
1003 // and not GrPixelConfig. Besides that, we should implement the fallback in the caps, but
1004 // for now we just convert the fallback pixel config to an SkColorType and then get the
1005 // GrBackendFormat from that.
1006 SkColorType colorType;
1007 if (!GrPixelConfigToColorType(config, &colorType)) {
1008 return nullptr;
1009 }
1010 localFormat = fContext->fCaps->getBackendFormatFromColorType(colorType);
robertphillipsd728f0c2016-11-21 11:05:03 -08001011 }
1012
Greg Daniel4065d452018-11-16 15:43:41 -05001013 return this->makeDeferredRenderTargetContext(localFormat, fit, width, height, config,
1014 std::move(colorSpace), sampleCnt, mipMapped,
1015 origin, surfaceProps, budgeted);
robertphillipsd728f0c2016-11-21 11:05:03 -08001016}
1017
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001018sk_sp<GrRenderTargetContext> GrContextPriv::makeDeferredRenderTargetContext(
Greg Daniel4065d452018-11-16 15:43:41 -05001019 const GrBackendFormat& format,
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001020 SkBackingFit fit,
1021 int width, int height,
1022 GrPixelConfig config,
1023 sk_sp<SkColorSpace> colorSpace,
1024 int sampleCnt,
Greg Daniel45d63032017-10-30 13:41:26 -04001025 GrMipMapped mipMapped,
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001026 GrSurfaceOrigin origin,
1027 const SkSurfaceProps* surfaceProps,
1028 SkBudgeted budgeted) {
Brian Salomonbdecacf2018-02-02 20:32:49 -05001029 SkASSERT(sampleCnt > 0);
Khushalc421ca12018-06-26 14:38:34 -07001030 if (fContext->abandoned()) {
Brian Salomon79e4d1b2017-07-13 11:17:11 -04001031 return nullptr;
1032 }
1033
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001034 GrSurfaceDesc desc;
1035 desc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001036 desc.fWidth = width;
1037 desc.fHeight = height;
1038 desc.fConfig = config;
1039 desc.fSampleCnt = sampleCnt;
1040
Greg Daniele1da1d92017-10-06 15:59:27 -04001041 sk_sp<GrTextureProxy> rtp;
Greg Daniel45d63032017-10-30 13:41:26 -04001042 if (GrMipMapped::kNo == mipMapped) {
Greg Daniel4065d452018-11-16 15:43:41 -05001043 rtp = fContext->fProxyProvider->createProxy(format, desc, origin, fit, budgeted);
Greg Daniele1da1d92017-10-06 15:59:27 -04001044 } else {
Greg Daniel4065d452018-11-16 15:43:41 -05001045 rtp = fContext->fProxyProvider->createMipMapProxy(format, desc, origin, budgeted);
Greg Daniele1da1d92017-10-06 15:59:27 -04001046 }
Robert Phillips08c5ec72017-01-30 12:26:47 -05001047 if (!rtp) {
1048 return nullptr;
1049 }
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001050
Robert Phillips1119dc32017-04-11 12:54:57 -04001051 sk_sp<GrRenderTargetContext> renderTargetContext(
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001052 fContext->fDrawingManager->makeRenderTargetContext(std::move(rtp),
1053 std::move(colorSpace),
1054 surfaceProps));
Robert Phillips1119dc32017-04-11 12:54:57 -04001055 if (!renderTargetContext) {
1056 return nullptr;
1057 }
1058
1059 renderTargetContext->discard();
1060
1061 return renderTargetContext;
Robert Phillipsc7635fa2016-10-28 13:25:24 -04001062}
1063
Robert Phillipsa0bc39d2019-01-29 13:14:47 -05001064sk_sp<GrSkSLFPFactoryCache> GrContextPriv::getFPFactoryCache() { return fContext->fFPFactoryCache; }
1065
Brian Salomonaff329b2017-08-11 09:40:37 -04001066std::unique_ptr<GrFragmentProcessor> GrContext::createPMToUPMEffect(
Brian Osman5ea96bf2018-10-02 14:58:05 -04001067 std::unique_ptr<GrFragmentProcessor> fp) {
Robert Phillips757914d2017-01-25 15:48:30 -05001068 ASSERT_SINGLE_OWNER
Brian Osman5ea96bf2018-10-02 14:58:05 -04001069 // We should have already called this->validPMUPMConversionExists() in this case
1070 SkASSERT(fDidTestPMConversions);
1071 // ...and it should have succeeded
1072 SkASSERT(this->validPMUPMConversionExists());
Brian Osman409e74f2017-04-17 11:48:28 -04001073
Brian Osman5ea96bf2018-10-02 14:58:05 -04001074 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToUnpremul);
Robert Phillips757914d2017-01-25 15:48:30 -05001075}
1076
Brian Salomonaff329b2017-08-11 09:40:37 -04001077std::unique_ptr<GrFragmentProcessor> GrContext::createUPMToPMEffect(
Brian Osman5ea96bf2018-10-02 14:58:05 -04001078 std::unique_ptr<GrFragmentProcessor> fp) {
joshualitt1de610a2016-01-06 08:26:09 -08001079 ASSERT_SINGLE_OWNER
Brian Osman5ea96bf2018-10-02 14:58:05 -04001080 // We should have already called this->validPMUPMConversionExists() in this case
1081 SkASSERT(fDidTestPMConversions);
1082 // ...and it should have succeeded
1083 SkASSERT(this->validPMUPMConversionExists());
Brian Osman409e74f2017-04-17 11:48:28 -04001084
Brian Osman5ea96bf2018-10-02 14:58:05 -04001085 return GrConfigConversionEffect::Make(std::move(fp), PMConversion::kToPremul);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +00001086}
1087
Brian Osman409e74f2017-04-17 11:48:28 -04001088bool GrContext::validPMUPMConversionExists() {
joshualitt1de610a2016-01-06 08:26:09 -08001089 ASSERT_SINGLE_OWNER
Brian Osman409e74f2017-04-17 11:48:28 -04001090 if (!fDidTestPMConversions) {
Brian Osman28804f32017-04-20 10:24:36 -04001091 fPMUPMConversionsRoundTrip = GrConfigConversionEffect::TestForPreservingPMConversions(this);
Brian Osman409e74f2017-04-17 11:48:28 -04001092 fDidTestPMConversions = true;
1093 }
1094
bsalomon636e8022015-07-29 06:08:46 -07001095 // The PM<->UPM tests fail or succeed together so we only need to check one.
Brian Osman28804f32017-04-20 10:24:36 -04001096 return fPMUPMConversionsRoundTrip;
bsalomon636e8022015-07-29 06:08:46 -07001097}
1098
Khushal3e7548c2018-05-23 15:45:01 -07001099bool GrContext::supportsDistanceFieldText() const {
1100 return fCaps->shaderCaps()->supportsDistanceFieldText();
1101}
1102
bsalomon37f9a262015-02-02 13:00:10 -08001103//////////////////////////////////////////////////////////////////////////////
1104
Robert Phillipsfc711a22018-02-13 17:03:00 -05001105// DDL TODO: remove 'maxResources'
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001106void GrContext::getResourceCacheLimits(int* maxResources, size_t* maxResourceBytes) const {
joshualitt1de610a2016-01-06 08:26:09 -08001107 ASSERT_SINGLE_OWNER
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001108 if (maxResources) {
1109 *maxResources = fResourceCache->getMaxResourceCount();
bsalomon37f9a262015-02-02 13:00:10 -08001110 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001111 if (maxResourceBytes) {
1112 *maxResourceBytes = fResourceCache->getMaxResourceBytes();
bsalomon37f9a262015-02-02 13:00:10 -08001113 }
1114}
1115
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001116void GrContext::setResourceCacheLimits(int maxResources, size_t maxResourceBytes) {
joshualitt1de610a2016-01-06 08:26:09 -08001117 ASSERT_SINGLE_OWNER
Robert Phillips8d1e67e2017-12-04 13:48:14 -05001118 fResourceCache->setLimits(maxResources, maxResourceBytes);
bsalomon37f9a262015-02-02 13:00:10 -08001119}
1120
ericrk0a5fa482015-09-15 14:16:10 -07001121//////////////////////////////////////////////////////////////////////////////
ericrk0a5fa482015-09-15 14:16:10 -07001122void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
joshualitt1de610a2016-01-06 08:26:09 -08001123 ASSERT_SINGLE_OWNER
ericrk0a5fa482015-09-15 14:16:10 -07001124 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
Khushal71652e22018-10-29 13:05:36 -07001125 traceMemoryDump->dumpNumericValue("skia/gr_text_blob_cache", "size", "bytes",
1126 fTextBlobCache->usedBytes());
ericrk0a5fa482015-09-15 14:16:10 -07001127}
Brian Osman71a18892017-08-10 10:23:25 -04001128
1129//////////////////////////////////////////////////////////////////////////////
Kevin Lubickf4def342018-10-04 12:52:50 -04001130#ifdef SK_ENABLE_DUMP_GPU
1131#include "SkJSONWriter.h"
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001132SkString GrContextPriv::dump() const {
Brian Osman71a18892017-08-10 10:23:25 -04001133 SkDynamicMemoryWStream stream;
1134 SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
1135 writer.beginObject();
1136
1137 static const char* kBackendStr[] = {
1138 "Metal",
1139 "OpenGL",
1140 "Vulkan",
1141 "Mock",
1142 };
Greg Danielbdf12ad2018-10-12 09:31:11 -04001143 GR_STATIC_ASSERT(0 == (unsigned)GrBackendApi::kMetal);
1144 GR_STATIC_ASSERT(1 == (unsigned)GrBackendApi::kOpenGL);
1145 GR_STATIC_ASSERT(2 == (unsigned)GrBackendApi::kVulkan);
1146 GR_STATIC_ASSERT(3 == (unsigned)GrBackendApi::kMock);
Robert Phillips4217ea72019-01-30 13:08:28 -05001147 writer.appendString("backend", kBackendStr[(unsigned)fContext->backend()]);
Brian Osman71a18892017-08-10 10:23:25 -04001148
1149 writer.appendName("caps");
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001150 fContext->fCaps->dumpJSON(&writer);
Brian Osman71a18892017-08-10 10:23:25 -04001151
1152 writer.appendName("gpu");
Robert Phillips0c4b7b12018-03-06 08:20:37 -05001153 fContext->fGpu->dumpJSON(&writer);
Brian Osman71a18892017-08-10 10:23:25 -04001154
1155 // Flush JSON to the memory stream
1156 writer.endObject();
1157 writer.flush();
1158
1159 // Null terminate the JSON data in the memory stream
1160 stream.write8(0);
1161
1162 // Allocate a string big enough to hold all the data, then copy out of the stream
1163 SkString result(stream.bytesWritten());
1164 stream.copyToAndReset(result.writable_str());
1165 return result;
1166}
Kevin Lubickf4def342018-10-04 12:52:50 -04001167#endif