blob: b1959bb9fda3f9ffc599acfaadf823097f5826c6 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
bsalomon@google.com27847de2011-02-22 20:59:41 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
bsalomon@google.com27847de2011-02-22 20:59:41 +00007 */
8
bsalomon@google.com1fadb202011-12-12 16:10:08 +00009#include "GrContext.h"
10
joshualitt7c3a2f82015-03-31 13:32:05 -070011#include "GrBatchFontCache.h"
bsalomon75398562015-08-17 12:55:38 -070012#include "GrBatchFlushState.h"
joshualitte5902662015-05-11 08:18:35 -070013#include "GrBatchTest.h"
bsalomoneb1cb5c2015-05-22 08:01:09 -070014#include "GrCaps.h"
bsalomon682c2692015-05-22 14:01:46 -070015#include "GrContextOptions.h"
joshualitt5478d422014-11-14 16:00:38 -080016#include "GrDefaultGeoProcFactory.h"
robertphillipsea461502015-05-26 11:38:03 -070017#include "GrDrawContext.h"
bsalomon512be532015-09-10 10:42:55 -070018#include "GrDrawTarget.h"
bsalomon453cf402014-11-11 14:15:57 -080019#include "GrGpuResource.h"
bsalomon3582d3e2015-02-13 14:20:05 -080020#include "GrGpuResourcePriv.h"
joshualitt5478d422014-11-14 16:00:38 -080021#include "GrGpu.h"
commit-bot@chromium.orgdcb8ef92014-03-27 11:26:10 +000022#include "GrIndexBuffer.h"
robertphillips@google.come930a072014-04-03 00:34:27 +000023#include "GrLayerCache.h"
commit-bot@chromium.org81312832013-03-22 18:34:09 +000024#include "GrOvalRenderer.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000025#include "GrPathRenderer.h"
tomhudson@google.comd22b6e42011-06-24 15:53:40 +000026#include "GrPathUtils.h"
bsalomon6bc1b5f2015-02-23 09:06:38 -080027#include "GrRenderTargetPriv.h"
bsalomon0ea80f42015-02-11 10:49:59 -080028#include "GrResourceCache.h"
bsalomond309e7a2015-04-30 14:18:54 -070029#include "GrResourceProvider.h"
robertphillips@google.com72176b22012-05-23 13:19:12 +000030#include "GrSoftwarePathRenderer.h"
robertphillips2d70dcb2015-10-06 07:38:23 -070031#include "GrStencilAndCoverTextContext.h"
egdanield58a0ba2014-06-11 10:30:05 -070032#include "GrStrokeInfo.h"
bsalomonafbf2d62014-09-30 12:18:44 -070033#include "GrSurfacePriv.h"
joshualittb7133be2015-04-08 09:08:31 -070034#include "GrTextBlobCache.h"
bsalomonafbf2d62014-09-30 12:18:44 -070035#include "GrTexturePriv.h"
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +000036#include "GrTracing.h"
bsalomoncb8979d2015-05-05 09:51:38 -070037#include "GrVertices.h"
egdanield58a0ba2014-06-11 10:30:05 -070038#include "SkDashPathPriv.h"
bsalomon81beccc2014-10-13 12:32:55 -070039#include "SkConfig8888.h"
reed@google.com7111d462014-03-25 16:20:24 +000040#include "SkGr.h"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000041#include "SkRRect.h"
sugoi@google.com5f74cf82012-12-17 21:16:45 +000042#include "SkStrokeRec.h"
robertphillipsfcf78292015-06-19 11:49:52 -070043#include "SkSurfacePriv.h"
commit-bot@chromium.orgdcb8ef92014-03-27 11:26:10 +000044#include "SkTLazy.h"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000045#include "SkTLS.h"
commit-bot@chromium.org933e65d2014-03-20 20:00:24 +000046#include "SkTraceEvent.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000047
robertphillips2d70dcb2015-10-06 07:38:23 -070048
joshualitt74417822015-08-07 11:42:16 -070049#include "batches/GrBatch.h"
50
joshualitt5478d422014-11-14 16:00:38 -080051#include "effects/GrConfigConversionEffect.h"
52#include "effects/GrDashingEffect.h"
53#include "effects/GrSingleTextureEffect.h"
54
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000055#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
robertphillipsea461502015-05-26 11:38:03 -070056#define RETURN_IF_ABANDONED if (fDrawingMgr.abandoned()) { return; }
57#define RETURN_FALSE_IF_ABANDONED if (fDrawingMgr.abandoned()) { return false; }
halcanary96fcdcc2015-08-27 07:41:13 -070058#define RETURN_NULL_IF_ABANDONED if (fDrawingMgr.abandoned()) { return nullptr; }
bsalomon@google.combc4b6542011-11-19 13:56:11 +000059
bsalomonf21dab92014-11-13 13:33:28 -080060
robertphillipsea461502015-05-26 11:38:03 -070061////////////////////////////////////////////////////////////////////////////////
62
63void GrContext::DrawingMgr::init(GrContext* context) {
robertphillips2334fb62015-06-17 05:43:33 -070064 fContext = context;
bsalomonb3b9aec2015-09-10 11:16:35 -070065 fDrawTarget = new GrDrawTarget(context->getGpu(), context->resourceProvider());
robertphillips2334fb62015-06-17 05:43:33 -070066}
bsalomon781d5822015-06-16 15:03:11 -070067
robertphillips2334fb62015-06-17 05:43:33 -070068void GrContext::DrawingMgr::cleanup() {
69 SkSafeSetNull(fDrawTarget);
robertphillips2d70dcb2015-10-06 07:38:23 -070070 delete fNVPRTextContext;
71 fNVPRTextContext = nullptr;
robertphillips2334fb62015-06-17 05:43:33 -070072 for (int i = 0; i < kNumPixelGeometries; ++i) {
robertphillips2d70dcb2015-10-06 07:38:23 -070073 delete fTextContexts[i][0];
74 fTextContexts[i][0] = nullptr;
75 delete fTextContexts[i][1];
76 fTextContexts[i][1] = nullptr;
robertphillips2334fb62015-06-17 05:43:33 -070077 }
robertphillipsea461502015-05-26 11:38:03 -070078}
79
80GrContext::DrawingMgr::~DrawingMgr() {
robertphillips2334fb62015-06-17 05:43:33 -070081 this->cleanup();
robertphillipsea461502015-05-26 11:38:03 -070082}
83
84void GrContext::DrawingMgr::abandon() {
robertphillips2d70dcb2015-10-06 07:38:23 -070085 this->cleanup();
robertphillipsea461502015-05-26 11:38:03 -070086}
87
robertphillipsea461502015-05-26 11:38:03 -070088void GrContext::DrawingMgr::reset() {
89 if (fDrawTarget) {
90 fDrawTarget->reset();
91 }
92}
93
94void GrContext::DrawingMgr::flush() {
95 if (fDrawTarget) {
96 fDrawTarget->flush();
97 }
98}
99
robertphillips2d70dcb2015-10-06 07:38:23 -0700100GrTextContext* GrContext::DrawingMgr::textContext(const SkSurfaceProps& props,
101 GrRenderTarget* rt) {
102 if (this->abandoned()) {
103 return nullptr;
104 }
105
106 SkASSERT(props.pixelGeometry() < kNumPixelGeometries);
107 bool useDIF = props.isUseDeviceIndependentFonts();
108
109 if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() &&
110 rt->isStencilBufferMultisampled()) {
111 GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt);
112 if (sb) {
113 if (!fNVPRTextContext) {
114 fNVPRTextContext = GrStencilAndCoverTextContext::Create(fContext, props);
115 }
116
117 return fNVPRTextContext;
118 }
119 }
120
121 if (!fTextContexts[props.pixelGeometry()][useDIF]) {
122 fTextContexts[props.pixelGeometry()][useDIF] = GrAtlasTextContext::Create(fContext, props);
123 }
124
125 return fTextContexts[props.pixelGeometry()][useDIF];
126}
127
ericrk0a5fa482015-09-15 14:16:10 -0700128GrDrawContext* GrContext::DrawingMgr::drawContext(const SkSurfaceProps* surfaceProps) {
robertphillipsea461502015-05-26 11:38:03 -0700129 if (this->abandoned()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700130 return nullptr;
robertphillipsea461502015-05-26 11:38:03 -0700131 }
robertphillips2334fb62015-06-17 05:43:33 -0700132
robertphillips2d70dcb2015-10-06 07:38:23 -0700133 return new GrDrawContext(fContext, fDrawTarget, surfaceProps);
robertphillipsea461502015-05-26 11:38:03 -0700134}
135
136////////////////////////////////////////////////////////////////////////////////
137
bsalomonf21dab92014-11-13 13:33:28 -0800138
bsalomon682c2692015-05-22 14:01:46 -0700139GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) {
140 GrContextOptions defaultOptions;
141 return Create(backend, backendContext, defaultOptions);
142}
bsalomonf28cff72015-05-22 12:25:41 -0700143
bsalomon682c2692015-05-22 14:01:46 -0700144GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext,
145 const GrContextOptions& options) {
halcanary385fe4d2015-08-26 13:07:48 -0700146 GrContext* context = new GrContext;
bsalomon682c2692015-05-22 14:01:46 -0700147
148 if (context->init(backend, backendContext, options)) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000149 return context;
150 } else {
151 context->unref();
halcanary96fcdcc2015-08-27 07:41:13 -0700152 return nullptr;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000153 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000154}
155
joshualitt0acd0d32015-05-07 08:23:19 -0700156static int32_t gNextID = 1;
157static int32_t next_id() {
158 int32_t id;
159 do {
160 id = sk_atomic_inc(&gNextID);
161 } while (id == SK_InvalidGenID);
162 return id;
163}
164
bsalomon682c2692015-05-22 14:01:46 -0700165GrContext::GrContext() : fUniqueID(next_id()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700166 fGpu = nullptr;
167 fCaps = nullptr;
168 fResourceCache = nullptr;
169 fResourceProvider = nullptr;
170 fPathRendererChain = nullptr;
171 fSoftwarePathRenderer = nullptr;
172 fBatchFontCache = nullptr;
bsalomonf21dab92014-11-13 13:33:28 -0800173 fFlushToReduceCacheSize = false;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000174}
175
bsalomon682c2692015-05-22 14:01:46 -0700176bool GrContext::init(GrBackend backend, GrBackendContext backendContext,
177 const GrContextOptions& options) {
robertphillipsea461502015-05-26 11:38:03 -0700178 SkASSERT(!fGpu);
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000179
bsalomon682c2692015-05-22 14:01:46 -0700180 fGpu = GrGpu::Create(backend, backendContext, options, this);
robertphillipsea461502015-05-26 11:38:03 -0700181 if (!fGpu) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000182 return false;
183 }
bsalomon33435572014-11-05 14:47:41 -0800184 this->initCommon();
185 return true;
186}
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000187
bsalomon33435572014-11-05 14:47:41 -0800188void GrContext::initCommon() {
bsalomon76228632015-05-29 08:02:10 -0700189 fCaps = SkRef(fGpu->caps());
halcanary385fe4d2015-08-26 13:07:48 -0700190 fResourceCache = new GrResourceCache(fCaps);
bsalomon0ea80f42015-02-11 10:49:59 -0800191 fResourceCache->setOverBudgetCallback(OverBudgetCB, this);
halcanary385fe4d2015-08-26 13:07:48 -0700192 fResourceProvider = new GrResourceProvider(fGpu, fResourceCache);
commit-bot@chromium.org1836d332013-07-16 22:55:03 +0000193
halcanary385fe4d2015-08-26 13:07:48 -0700194 fLayerCache.reset(new GrLayerCache(this));
robertphillips@google.come930a072014-04-03 00:34:27 +0000195
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000196 fDidTestPMConversions = false;
197
robertphillipsea461502015-05-26 11:38:03 -0700198 fDrawingMgr.init(this);
joshualitt7c3a2f82015-03-31 13:32:05 -0700199
200 // GrBatchFontCache will eventually replace GrFontCache
halcanary385fe4d2015-08-26 13:07:48 -0700201 fBatchFontCache = new GrBatchFontCache(this);
joshualittb7133be2015-04-08 09:08:31 -0700202
halcanary385fe4d2015-08-26 13:07:48 -0700203 fTextBlobCache.reset(new GrTextBlobCache(TextBlobCacheOverBudgetCB, this));
bsalomon@google.comc0af3172012-06-15 14:10:09 +0000204}
205
bsalomon@google.com27847de2011-02-22 20:59:41 +0000206GrContext::~GrContext() {
robertphillipsea461502015-05-26 11:38:03 -0700207 if (!fGpu) {
bsalomon76228632015-05-29 08:02:10 -0700208 SkASSERT(!fCaps);
bsalomon@google.com733c0622013-04-24 17:59:32 +0000209 return;
210 }
211
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000212 this->flush();
robertphillips@google.com5acc0e32012-05-17 12:01:02 +0000213
robertphillips2334fb62015-06-17 05:43:33 -0700214 fDrawingMgr.cleanup();
215
robertphillips@google.com950b1b02013-10-21 17:37:28 +0000216 for (int i = 0; i < fCleanUpData.count(); ++i) {
217 (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
218 }
219
halcanary385fe4d2015-08-26 13:07:48 -0700220 delete fResourceProvider;
221 delete fResourceCache;
222 delete fBatchFontCache;
robertphillips@google.comf6747b02012-06-12 00:32:28 +0000223
bsalomon@google.com205d4602011-04-25 12:43:45 +0000224 fGpu->unref();
bsalomon76228632015-05-29 08:02:10 -0700225 fCaps->unref();
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000226 SkSafeUnref(fPathRendererChain);
227 SkSafeUnref(fSoftwarePathRenderer);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000228}
229
bsalomon2354f842014-07-28 13:48:36 -0700230void GrContext::abandonContext() {
bsalomond309e7a2015-04-30 14:18:54 -0700231 fResourceProvider->abandon();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000232 // abandon first to so destructors
233 // don't try to free the resources in the API.
bsalomon0ea80f42015-02-11 10:49:59 -0800234 fResourceCache->abandonAll();
bsalomonc8dc1f72014-08-21 13:02:13 -0700235
robertphillipse3371302014-09-17 06:01:06 -0700236 fGpu->contextAbandoned();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000237
bsalomon@google.com30085192011-08-19 15:42:31 +0000238 // a path renderer may be holding onto resources that
239 // are now unusable
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000240 SkSafeSetNull(fPathRendererChain);
241 SkSafeSetNull(fSoftwarePathRenderer);
bsalomon@google.com30085192011-08-19 15:42:31 +0000242
robertphillipsea461502015-05-26 11:38:03 -0700243 fDrawingMgr.abandon();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000244
joshualitt7c3a2f82015-03-31 13:32:05 -0700245 fBatchFontCache->freeAll();
robertphillips@google.come930a072014-04-03 00:34:27 +0000246 fLayerCache->freeAll();
joshualitt26ffc002015-04-16 11:24:04 -0700247 fTextBlobCache->freeAll();
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000248}
249
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000250void GrContext::resetContext(uint32_t state) {
251 fGpu->markContextDirty(state);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000252}
253
254void GrContext::freeGpuResources() {
255 this->flush();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000256
joshualitt7c3a2f82015-03-31 13:32:05 -0700257 fBatchFontCache->freeAll();
robertphillips@google.come930a072014-04-03 00:34:27 +0000258 fLayerCache->freeAll();
bsalomon@google.com30085192011-08-19 15:42:31 +0000259 // a path renderer may be holding onto resources
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000260 SkSafeSetNull(fPathRendererChain);
261 SkSafeSetNull(fSoftwarePathRenderer);
bsalomon3033b9f2015-04-13 11:09:56 -0700262
263 fResourceCache->purgeAllUnlocked();
bsalomon@google.com27847de2011-02-22 20:59:41 +0000264}
265
commit-bot@chromium.org95c20032014-05-09 14:29:32 +0000266void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
bsalomon71cb0c22014-11-14 12:10:14 -0800267 if (resourceCount) {
bsalomon0ea80f42015-02-11 10:49:59 -0800268 *resourceCount = fResourceCache->getBudgetedResourceCount();
bsalomon71cb0c22014-11-14 12:10:14 -0800269 }
270 if (resourceBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800271 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
bsalomon71cb0c22014-11-14 12:10:14 -0800272 }
commit-bot@chromium.orgd8a57af2014-03-19 21:19:16 +0000273}
274
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000275////////////////////////////////////////////////////////////////////////////////
276
bsalomon71cb0c22014-11-14 12:10:14 -0800277void GrContext::OverBudgetCB(void* data) {
bsalomon66a450f2014-11-13 13:19:10 -0800278 SkASSERT(data);
bsalomonf21dab92014-11-13 13:33:28 -0800279
bsalomon66a450f2014-11-13 13:19:10 -0800280 GrContext* context = reinterpret_cast<GrContext*>(data);
bsalomonf21dab92014-11-13 13:33:28 -0800281
joshualittb542bae2015-07-28 09:58:39 -0700282 // Flush the GrBufferedDrawTarget to possibly free up some textures
bsalomonf21dab92014-11-13 13:33:28 -0800283 context->fFlushToReduceCacheSize = true;
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000284}
285
joshualitt0db6dfa2015-04-10 07:01:30 -0700286void GrContext::TextBlobCacheOverBudgetCB(void* data) {
287 SkASSERT(data);
288
289 // Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they
290 // cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush. The solution is to move
291 // drawText calls to below the GrContext level, but this is not trivial because they call
292 // drawPath on SkGpuDevice
293 GrContext* context = reinterpret_cast<GrContext*>(data);
294 context->flush();
295}
296
bsalomon@google.com27847de2011-02-22 20:59:41 +0000297////////////////////////////////////////////////////////////////////////////////
298
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000299void GrContext::flush(int flagsBitfield) {
robertphillipsea461502015-05-26 11:38:03 -0700300 RETURN_IF_ABANDONED
robertphillips@google.come7db8d62013-07-04 11:48:52 +0000301
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000302 if (kDiscard_FlushBit & flagsBitfield) {
robertphillipsea461502015-05-26 11:38:03 -0700303 fDrawingMgr.reset();
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000304 } else {
robertphillipsea461502015-05-26 11:38:03 -0700305 fDrawingMgr.flush();
junov@google.com53a55842011-06-08 22:55:10 +0000306 }
bsalomon3f324322015-04-08 11:01:54 -0700307 fResourceCache->notifyFlushOccurred();
bsalomonf21dab92014-11-13 13:33:28 -0800308 fFlushToReduceCacheSize = false;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000309}
310
bsalomon81beccc2014-10-13 12:32:55 -0700311bool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes,
312 const void* inPixels, size_t outRowBytes, void* outPixels) {
313 SkSrcPixelInfo srcPI;
halcanary96fcdcc2015-08-27 07:41:13 -0700314 if (!GrPixelConfig2ColorAndProfileType(srcConfig, &srcPI.fColorType, nullptr)) {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000315 return false;
316 }
bsalomon81beccc2014-10-13 12:32:55 -0700317 srcPI.fAlphaType = kUnpremul_SkAlphaType;
318 srcPI.fPixels = inPixels;
319 srcPI.fRowBytes = inRowBytes;
320
321 SkDstPixelInfo dstPI;
322 dstPI.fColorType = srcPI.fColorType;
323 dstPI.fAlphaType = kPremul_SkAlphaType;
324 dstPI.fPixels = outPixels;
325 dstPI.fRowBytes = outRowBytes;
326
327 return srcPI.convertPixelsTo(&dstPI, width, height);
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000328}
329
bsalomon81beccc2014-10-13 12:32:55 -0700330bool GrContext::writeSurfacePixels(GrSurface* surface,
331 int left, int top, int width, int height,
332 GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
333 uint32_t pixelOpsFlags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800334 RETURN_FALSE_IF_ABANDONED
bsalomon6c6f6582015-09-10 08:12:46 -0700335 ASSERT_OWNED_RESOURCE(surface);
336 SkASSERT(surface);
337
338 this->testPMConversionsIfNecessary(pixelOpsFlags);
bsalomon81beccc2014-10-13 12:32:55 -0700339
bsalomone8d21e82015-07-16 08:23:13 -0700340 // Trim the params here so that if we wind up making a temporary surface it can be as small as
bsalomonf0674512015-07-28 13:26:15 -0700341 // necessary and because GrGpu::getWritePixelsInfo requires it.
bsalomone8d21e82015-07-16 08:23:13 -0700342 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(),
343 GrBytesPerPixel(srcConfig), &left, &top, &width,
344 &height, &buffer, &rowBytes)) {
345 return false;
346 }
347
bsalomonf0674512015-07-28 13:26:15 -0700348 bool applyPremulToSrc = false;
bsalomon81beccc2014-10-13 12:32:55 -0700349 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
350 if (!GrPixelConfigIs8888(srcConfig)) {
351 return false;
352 }
bsalomonf0674512015-07-28 13:26:15 -0700353 applyPremulToSrc = true;
354 }
bsalomon636e8022015-07-29 06:08:46 -0700355
356 GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
357 // Don't prefer to draw for the conversion (and thereby access a texture from the cache) when
358 // we've already determined that there isn't a roundtrip preserving conversion processor pair.
359 if (applyPremulToSrc && !this->didFailPMUPMConversionTest()) {
360 drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference;
361 }
362
bsalomonf0674512015-07-28 13:26:15 -0700363 GrGpu::WritePixelTempDrawInfo tempDrawInfo;
364 if (!fGpu->getWritePixelsInfo(surface, width, height, rowBytes, srcConfig, &drawPreference,
365 &tempDrawInfo)) {
366 return false;
367 }
368
369 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().hasPendingIO()) {
370 this->flush();
371 }
372
373 SkAutoTUnref<GrTexture> tempTexture;
374 if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
bsalomoneae62002015-07-31 13:59:30 -0700375 tempTexture.reset(
376 this->textureProvider()->createApproxTexture(tempDrawInfo.fTempSurfaceDesc));
bsalomonf0674512015-07-28 13:26:15 -0700377 if (!tempTexture && GrGpu::kRequireDraw_DrawPreference == drawPreference) {
378 return false;
379 }
380 }
381
382 // temp buffer for doing sw premul conversion, if needed.
383 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
384 if (tempTexture) {
385 SkAutoTUnref<const GrFragmentProcessor> fp;
386 SkMatrix textureMatrix;
387 textureMatrix.setIDiv(tempTexture->width(), tempTexture->height());
388 GrPaint paint;
389 if (applyPremulToSrc) {
390 fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), tempTexture,
391 tempDrawInfo.fSwapRAndB, textureMatrix));
392 // If premultiplying was the only reason for the draw, fall back to a straight write.
393 if (!fp) {
394 if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
halcanary96fcdcc2015-08-27 07:41:13 -0700395 tempTexture.reset(nullptr);
bsalomonf0674512015-07-28 13:26:15 -0700396 }
397 } else {
398 applyPremulToSrc = false;
399 }
400 }
401 if (tempTexture) {
402 if (!fp) {
403 fp.reset(GrConfigConversionEffect::Create(
404 paint.getProcessorDataManager(), tempTexture, tempDrawInfo.fSwapRAndB,
405 GrConfigConversionEffect::kNone_PMConversion, textureMatrix));
406 if (!fp) {
407 return false;
408 }
409 }
410 GrRenderTarget* renderTarget = surface->asRenderTarget();
411 SkASSERT(renderTarget);
412 if (tempTexture->surfacePriv().hasPendingIO()) {
413 this->flush();
414 }
415 if (applyPremulToSrc) {
416 size_t tmpRowBytes = 4 * width;
417 tmpPixels.reset(width * height);
418 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
419 tmpPixels.get())) {
420 return false;
421 }
422 rowBytes = tmpRowBytes;
423 buffer = tmpPixels.get();
424 applyPremulToSrc = false;
425 }
bsalomon6cb3cbe2015-07-30 07:34:27 -0700426 if (!fGpu->writePixels(tempTexture, 0, 0, width, height,
427 tempDrawInfo.fTempSurfaceDesc.fConfig, buffer,
428 rowBytes)) {
bsalomonf0674512015-07-28 13:26:15 -0700429 return false;
430 }
431 SkMatrix matrix;
432 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
robertphillipsc9a37062015-09-01 08:34:28 -0700433 SkAutoTUnref<GrDrawContext> drawContext(this->drawContext());
bsalomonf0674512015-07-28 13:26:15 -0700434 if (!drawContext) {
435 return false;
436 }
bsalomonac856c92015-08-27 06:30:17 -0700437 paint.addColorFragmentProcessor(fp);
bsalomonf0674512015-07-28 13:26:15 -0700438 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
halcanary96fcdcc2015-08-27 07:41:13 -0700439 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matrix, rect, nullptr);
bsalomonf0674512015-07-28 13:26:15 -0700440
441 if (kFlushWrites_PixelOp & pixelOpsFlags) {
442 this->flushSurfaceWrites(surface);
443 }
444 }
445 }
446 if (!tempTexture) {
bsalomonf0674512015-07-28 13:26:15 -0700447 if (applyPremulToSrc) {
bsalomon81beccc2014-10-13 12:32:55 -0700448 size_t tmpRowBytes = 4 * width;
449 tmpPixels.reset(width * height);
450 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
451 tmpPixels.get())) {
452 return false;
453 }
454 rowBytes = tmpRowBytes;
455 buffer = tmpPixels.get();
bsalomonf0674512015-07-28 13:26:15 -0700456 applyPremulToSrc = false;
bsalomon81beccc2014-10-13 12:32:55 -0700457 }
bsalomon6cb3cbe2015-07-30 07:34:27 -0700458 return fGpu->writePixels(surface, left, top, width, height, srcConfig, buffer, rowBytes);
bsalomon81beccc2014-10-13 12:32:55 -0700459 }
bsalomon81beccc2014-10-13 12:32:55 -0700460 return true;
461}
bsalomon@google.coma91e9232012-02-23 15:39:54 +0000462
bsalomone8d21e82015-07-16 08:23:13 -0700463bool GrContext::readSurfacePixels(GrSurface* src,
464 int left, int top, int width, int height,
465 GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
466 uint32_t flags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800467 RETURN_FALSE_IF_ABANDONED
bsalomone8d21e82015-07-16 08:23:13 -0700468 ASSERT_OWNED_RESOURCE(src);
469 SkASSERT(src);
bsalomon32ab2602015-09-09 18:57:49 -0700470
bsalomon6c6f6582015-09-10 08:12:46 -0700471 this->testPMConversionsIfNecessary(flags);
472 SkAutoMutexAcquire ama(fReadPixelsMutex);
473
bsalomone8d21e82015-07-16 08:23:13 -0700474 // Adjust the params so that if we wind up using an intermediate surface we've already done
475 // all the trimming and the temporary can be the min size required.
476 if (!GrSurfacePriv::AdjustReadPixelParams(src->width(), src->height(),
477 GrBytesPerPixel(dstConfig), &left,
478 &top, &width, &height, &buffer, &rowBytes)) {
479 return false;
480 }
481
482 if (!(kDontFlush_PixelOpsFlag & flags) && src->surfacePriv().hasPendingWrite()) {
bsalomon@google.com6f379512011-11-16 20:36:03 +0000483 this->flush();
484 }
bsalomon@google.comc4364992011-11-07 15:54:49 +0000485
bsalomone8d21e82015-07-16 08:23:13 -0700486 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
bsalomon@google.com9c680582013-02-06 18:17:50 +0000487 if (unpremul && !GrPixelConfigIs8888(dstConfig)) {
bsalomon39826022015-07-23 08:07:21 -0700488 // The unpremul flag is only allowed for 8888 configs.
bsalomon@google.com0a97be22011-11-08 19:20:57 +0000489 return false;
490 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000491
bsalomon636e8022015-07-29 06:08:46 -0700492 GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
493 // Don't prefer to draw for the conversion (and thereby access a texture from the cache) when
494 // we've already determined that there isn't a roundtrip preserving conversion processor pair.
495 if (unpremul && !this->didFailPMUPMConversionTest()) {
496 drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference;
497 }
498
bsalomon39826022015-07-23 08:07:21 -0700499 GrGpu::ReadPixelTempDrawInfo tempDrawInfo;
500 if (!fGpu->getReadPixelsInfo(src, width, height, rowBytes, dstConfig, &drawPreference,
501 &tempDrawInfo)) {
502 return false;
503 }
bsalomon191bcc02014-11-14 11:31:13 -0800504
bsalomon6cb3cbe2015-07-30 07:34:27 -0700505 SkAutoTUnref<GrSurface> surfaceToRead(SkRef(src));
bsalomon39826022015-07-23 08:07:21 -0700506 bool didTempDraw = false;
507 if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
bsalomon39826022015-07-23 08:07:21 -0700508 if (tempDrawInfo.fUseExactScratch) {
509 // We only respect this when the entire src is being read. Otherwise we can trigger too
510 // many odd ball texture sizes and trash the cache.
bsalomoneae62002015-07-31 13:59:30 -0700511 if (width != src->width() || height != src->height()) {
512 tempDrawInfo.fUseExactScratch = false;
bsalomon39826022015-07-23 08:07:21 -0700513 }
bsalomon@google.com56d11e02011-11-30 19:59:08 +0000514 }
bsalomon39826022015-07-23 08:07:21 -0700515 SkAutoTUnref<GrTexture> temp;
bsalomoneae62002015-07-31 13:59:30 -0700516 if (tempDrawInfo.fUseExactScratch) {
517 temp.reset(this->textureProvider()->createTexture(tempDrawInfo.fTempSurfaceDesc, true));
518 } else {
519 temp.reset(this->textureProvider()->createApproxTexture(tempDrawInfo.fTempSurfaceDesc));
520 }
bsalomon39826022015-07-23 08:07:21 -0700521 if (temp) {
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000522 SkMatrix textureMatrix;
bsalomon39826022015-07-23 08:07:21 -0700523 textureMatrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000524 textureMatrix.postIDiv(src->width(), src->height());
joshualitt5f10b5c2015-07-09 10:24:35 -0700525 GrPaint paint;
joshualittb0a8a372014-09-23 09:50:21 -0700526 SkAutoTUnref<const GrFragmentProcessor> fp;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000527 if (unpremul) {
bsalomon39826022015-07-23 08:07:21 -0700528 fp.reset(this->createPMToUPMEffect(
529 paint.getProcessorDataManager(), src->asTexture(), tempDrawInfo.fSwapRAndB,
530 textureMatrix));
joshualittb0a8a372014-09-23 09:50:21 -0700531 if (fp) {
bsalomon@google.com9c680582013-02-06 18:17:50 +0000532 unpremul = false; // we no longer need to do this on CPU after the read back.
bsalomon39826022015-07-23 08:07:21 -0700533 } else if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
534 // We only wanted to do the draw in order to perform the unpremul so don't
535 // bother.
halcanary96fcdcc2015-08-27 07:41:13 -0700536 temp.reset(nullptr);
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000537 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000538 }
bsalomon39826022015-07-23 08:07:21 -0700539 if (!fp && temp) {
540 fp.reset(GrConfigConversionEffect::Create(
541 paint.getProcessorDataManager(), src->asTexture(), tempDrawInfo.fSwapRAndB,
542 GrConfigConversionEffect::kNone_PMConversion, textureMatrix));
543 }
544 if (fp) {
bsalomonac856c92015-08-27 06:30:17 -0700545 paint.addColorFragmentProcessor(fp);
bsalomon39826022015-07-23 08:07:21 -0700546 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
robertphillipsc9a37062015-09-01 08:34:28 -0700547 SkAutoTUnref<GrDrawContext> drawContext(this->drawContext());
bsalomon39826022015-07-23 08:07:21 -0700548 drawContext->drawRect(temp->asRenderTarget(), GrClip::WideOpen(), paint,
halcanary96fcdcc2015-08-27 07:41:13 -0700549 SkMatrix::I(), rect, nullptr);
bsalomon6cb3cbe2015-07-30 07:34:27 -0700550 surfaceToRead.reset(SkRef(temp.get()));
bsalomon39826022015-07-23 08:07:21 -0700551 left = 0;
552 top = 0;
553 didTempDraw = true;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000554 }
bsalomon@google.com0342a852012-08-20 19:22:38 +0000555 }
bsalomon@google.comc4364992011-11-07 15:54:49 +0000556 }
joshualitt5c55fef2014-10-31 14:04:35 -0700557
bsalomon39826022015-07-23 08:07:21 -0700558 if (GrGpu::kRequireDraw_DrawPreference == drawPreference && !didTempDraw) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000559 return false;
560 }
bsalomon39826022015-07-23 08:07:21 -0700561 GrPixelConfig configToRead = dstConfig;
562 if (didTempDraw) {
bsalomon6cb3cbe2015-07-30 07:34:27 -0700563 this->flushSurfaceWrites(surfaceToRead);
bsalomon39826022015-07-23 08:07:21 -0700564 // We swapped R and B while doing the temp draw. Swap back on the read.
565 if (tempDrawInfo.fSwapRAndB) {
566 configToRead = GrPixelConfigSwapRAndB(dstConfig);
567 }
568 }
bsalomon6cb3cbe2015-07-30 07:34:27 -0700569 if (!fGpu->readPixels(surfaceToRead, left, top, width, height, configToRead, buffer,
570 rowBytes)) {
bsalomon39826022015-07-23 08:07:21 -0700571 return false;
572 }
573
574 // Perform umpremul conversion if we weren't able to perform it as a draw.
575 if (unpremul) {
reed@google.com7111d462014-03-25 16:20:24 +0000576 SkDstPixelInfo dstPI;
halcanary96fcdcc2015-08-27 07:41:13 -0700577 if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, nullptr)) {
reed@google.com7111d462014-03-25 16:20:24 +0000578 return false;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000579 }
reed@google.com7111d462014-03-25 16:20:24 +0000580 dstPI.fAlphaType = kUnpremul_SkAlphaType;
581 dstPI.fPixels = buffer;
582 dstPI.fRowBytes = rowBytes;
583
584 SkSrcPixelInfo srcPI;
bsalomon39826022015-07-23 08:07:21 -0700585 srcPI.fColorType = dstPI.fColorType;
reed@google.com7111d462014-03-25 16:20:24 +0000586 srcPI.fAlphaType = kPremul_SkAlphaType;
587 srcPI.fPixels = buffer;
588 srcPI.fRowBytes = rowBytes;
589
590 return srcPI.convertPixelsTo(&dstPI, width, height);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000591 }
592 return true;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000593}
594
bsalomonc49e8682015-06-30 11:37:35 -0700595void GrContext::prepareSurfaceForExternalIO(GrSurface* surface) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800596 RETURN_IF_ABANDONED
bsalomon87a94eb2014-11-03 14:28:32 -0800597 SkASSERT(surface);
598 ASSERT_OWNED_RESOURCE(surface);
599 if (surface->surfacePriv().hasPendingIO()) {
600 this->flush();
601 }
602 GrRenderTarget* rt = surface->asRenderTarget();
603 if (fGpu && rt) {
604 fGpu->resolveRenderTarget(rt);
bsalomon41ebbdd2014-08-04 08:31:39 -0700605 }
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000606}
607
bsalomonf80bfed2014-10-07 05:56:02 -0700608void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
609 const SkIPoint& dstPoint, uint32_t pixelOpsFlags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800610 RETURN_IF_ABANDONED
robertphillipsea461502015-05-26 11:38:03 -0700611 if (!src || !dst) {
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000612 return;
613 }
bsalomone3d4bf22014-09-23 09:15:03 -0700614 ASSERT_OWNED_RESOURCE(src);
junov2bb52102014-09-29 10:18:59 -0700615 ASSERT_OWNED_RESOURCE(dst);
Brian Salomon34a98952014-09-24 11:41:24 -0400616
bsalomonf80bfed2014-10-07 05:56:02 -0700617 // Since we're going to the draw target and not GPU, no need to check kNoFlush
618 // here.
robertphillipsea461502015-05-26 11:38:03 -0700619 if (!dst->asRenderTarget()) {
junov96c118e2014-09-26 13:09:47 -0700620 return;
621 }
robertphillipsea461502015-05-26 11:38:03 -0700622
robertphillipsc9a37062015-09-01 08:34:28 -0700623 SkAutoTUnref<GrDrawContext> drawContext(this->drawContext());
robertphillipsea461502015-05-26 11:38:03 -0700624 if (!drawContext) {
625 return;
626 }
627
628 drawContext->copySurface(dst->asRenderTarget(), src, srcRect, dstPoint);
bsalomonf80bfed2014-10-07 05:56:02 -0700629
630 if (kFlushWrites_PixelOp & pixelOpsFlags) {
631 this->flush();
632 }
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000633}
634
bsalomonf80bfed2014-10-07 05:56:02 -0700635void GrContext::flushSurfaceWrites(GrSurface* surface) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800636 RETURN_IF_ABANDONED
bsalomonf80bfed2014-10-07 05:56:02 -0700637 if (surface->surfacePriv().hasPendingWrite()) {
638 this->flush();
639 }
640}
641
robertphillips@google.com72176b22012-05-23 13:19:12 +0000642/*
643 * This method finds a path renderer that can draw the specified path on
644 * the provided target.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000645 * Due to its expense, the software path renderer has split out so it can
robertphillips@google.com72176b22012-05-23 13:19:12 +0000646 * can be individually allowed/disallowed via the "allowSW" boolean.
647 */
joshualitt9853cce2014-11-17 14:22:48 -0800648GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
egdaniel8dd688b2015-01-22 10:16:09 -0800649 const GrPipelineBuilder* pipelineBuilder,
joshualitt8059eb92014-12-29 15:10:07 -0800650 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800651 const SkPath& path,
kkinnunen18996512015-04-26 23:18:49 -0700652 const GrStrokeInfo& stroke,
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000653 bool allowSW,
654 GrPathRendererChain::DrawType drawType,
655 GrPathRendererChain::StencilSupport* stencilSupport) {
656
robertphillipsea461502015-05-26 11:38:03 -0700657 if (!fPathRendererChain) {
halcanary385fe4d2015-08-26 13:07:48 -0700658 fPathRendererChain = new GrPathRendererChain(this);
bsalomon@google.com30085192011-08-19 15:42:31 +0000659 }
robertphillips@google.com72176b22012-05-23 13:19:12 +0000660
joshualitt9853cce2014-11-17 14:22:48 -0800661 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target,
egdaniel8dd688b2015-01-22 10:16:09 -0800662 pipelineBuilder,
joshualitt8059eb92014-12-29 15:10:07 -0800663 viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800664 path,
sugoi@google.com12b4e272012-12-06 20:13:11 +0000665 stroke,
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000666 drawType,
667 stencilSupport);
robertphillips@google.com72176b22012-05-23 13:19:12 +0000668
robertphillipsea461502015-05-26 11:38:03 -0700669 if (!pr && allowSW) {
670 if (!fSoftwarePathRenderer) {
halcanary385fe4d2015-08-26 13:07:48 -0700671 fSoftwarePathRenderer = new GrSoftwarePathRenderer(this);
robertphillips@google.com72176b22012-05-23 13:19:12 +0000672 }
robertphillips@google.com72176b22012-05-23 13:19:12 +0000673 pr = fSoftwarePathRenderer;
674 }
675
676 return pr;
bsalomon@google.com30085192011-08-19 15:42:31 +0000677}
678
bsalomon@google.com27847de2011-02-22 20:59:41 +0000679////////////////////////////////////////////////////////////////////////////////
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000680int GrContext::getRecommendedSampleCount(GrPixelConfig config,
681 SkScalar dpi) const {
bsalomon76228632015-05-29 08:02:10 -0700682 if (!this->caps()->isConfigRenderable(config, true)) {
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000683 return 0;
684 }
685 int chosenSampleCount = 0;
jvanverthe9c0fc62015-04-29 11:18:05 -0700686 if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) {
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000687 if (dpi >= 250.0f) {
688 chosenSampleCount = 4;
689 } else {
690 chosenSampleCount = 16;
691 }
692 }
693 return chosenSampleCount <= fGpu->caps()->maxSampleCount() ?
694 chosenSampleCount : 0;
695}
696
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000697namespace {
698void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) {
699 GrConfigConversionEffect::PMConversion pmToUPM;
700 GrConfigConversionEffect::PMConversion upmToPM;
701 GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM);
702 *pmToUPMValue = pmToUPM;
703 *upmToPMValue = upmToPM;
704}
705}
706
bsalomon6c6f6582015-09-10 08:12:46 -0700707void GrContext::testPMConversionsIfNecessary(uint32_t flags) {
708 if (SkToBool(kUnpremul_PixelOpsFlag & flags)) {
709 SkAutoMutexAcquire ama(fTestPMConversionsMutex);
710 if (!fDidTestPMConversions) {
711 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
712 fDidTestPMConversions = true;
713 }
714 }
715}
716
joshualitt5f10b5c2015-07-09 10:24:35 -0700717const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrProcessorDataManager* procDataManager,
718 GrTexture* texture,
joshualittb0a8a372014-09-23 09:50:21 -0700719 bool swapRAndB,
bsalomon6c6f6582015-09-10 08:12:46 -0700720 const SkMatrix& matrix) const {
721 // We should have already called this->testPMConversionsIfNecessary().
722 SkASSERT(fDidTestPMConversions);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000723 GrConfigConversionEffect::PMConversion pmToUPM =
724 static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
725 if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
joshualitt5f10b5c2015-07-09 10:24:35 -0700726 return GrConfigConversionEffect::Create(procDataManager, texture, swapRAndB, pmToUPM,
727 matrix);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000728 } else {
halcanary96fcdcc2015-08-27 07:41:13 -0700729 return nullptr;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000730 }
731}
732
joshualitt5f10b5c2015-07-09 10:24:35 -0700733const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrProcessorDataManager* procDataManager,
734 GrTexture* texture,
joshualittb0a8a372014-09-23 09:50:21 -0700735 bool swapRAndB,
bsalomon6c6f6582015-09-10 08:12:46 -0700736 const SkMatrix& matrix) const {
737 // We should have already called this->testPMConversionsIfNecessary().
738 SkASSERT(fDidTestPMConversions);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000739 GrConfigConversionEffect::PMConversion upmToPM =
740 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
741 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
joshualitt5f10b5c2015-07-09 10:24:35 -0700742 return GrConfigConversionEffect::Create(procDataManager, texture, swapRAndB, upmToPM,
743 matrix);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000744 } else {
halcanary96fcdcc2015-08-27 07:41:13 -0700745 return nullptr;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000746 }
747}
748
bsalomon636e8022015-07-29 06:08:46 -0700749bool GrContext::didFailPMUPMConversionTest() const {
bsalomon6c6f6582015-09-10 08:12:46 -0700750 // We should have already called this->testPMConversionsIfNecessary().
751 SkASSERT(fDidTestPMConversions);
bsalomon636e8022015-07-29 06:08:46 -0700752 // The PM<->UPM tests fail or succeed together so we only need to check one.
bsalomon6c6f6582015-09-10 08:12:46 -0700753 return GrConfigConversionEffect::kNone_PMConversion == fPMToUPMConversion;
bsalomon636e8022015-07-29 06:08:46 -0700754}
755
bsalomon37f9a262015-02-02 13:00:10 -0800756//////////////////////////////////////////////////////////////////////////////
757
758void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const {
759 if (maxTextures) {
bsalomon0ea80f42015-02-11 10:49:59 -0800760 *maxTextures = fResourceCache->getMaxResourceCount();
bsalomon37f9a262015-02-02 13:00:10 -0800761 }
762 if (maxTextureBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800763 *maxTextureBytes = fResourceCache->getMaxResourceBytes();
bsalomon37f9a262015-02-02 13:00:10 -0800764 }
765}
766
767void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800768 fResourceCache->setLimits(maxTextures, maxTextureBytes);
bsalomon37f9a262015-02-02 13:00:10 -0800769}
770
ericrk0a5fa482015-09-15 14:16:10 -0700771//////////////////////////////////////////////////////////////////////////////
772
773void GrContext::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
774 fResourceCache->dumpMemoryStatistics(traceMemoryDump);
775}