blob: 550d7ff7c19a4f4c7d9a65cb66c1abe1250c7f03 [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
jvanverth@google.combfe2b9d2013-09-06 16:57:29 +000011#include "GrAARectRenderer.h"
joshualitt1d89e8d2015-04-01 12:40:54 -070012#include "GrAtlasTextContext.h"
joshualitt0823bfa2015-02-27 10:06:15 -080013#include "GrBatch.h"
joshualitt7c3a2f82015-03-31 13:32:05 -070014#include "GrBatchFontCache.h"
joshualitt0823bfa2015-02-27 10:06:15 -080015#include "GrBatchTarget.h"
joshualitte5902662015-05-11 08:18:35 -070016#include "GrBatchTest.h"
bsalomoneb1cb5c2015-05-22 08:01:09 -070017#include "GrCaps.h"
bsalomon682c2692015-05-22 14:01:46 -070018#include "GrContextOptions.h"
joshualitt5478d422014-11-14 16:00:38 -080019#include "GrDefaultGeoProcFactory.h"
robertphillipsea461502015-05-26 11:38:03 -070020#include "GrDrawContext.h"
bsalomon453cf402014-11-11 14:15:57 -080021#include "GrGpuResource.h"
bsalomon3582d3e2015-02-13 14:20:05 -080022#include "GrGpuResourcePriv.h"
joshualitt5478d422014-11-14 16:00:38 -080023#include "GrGpu.h"
joshualittbb87b212015-05-19 14:28:04 -070024#include "GrImmediateDrawTarget.h"
commit-bot@chromium.orgdcb8ef92014-03-27 11:26:10 +000025#include "GrIndexBuffer.h"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000026#include "GrInOrderDrawBuffer.h"
robertphillips@google.come930a072014-04-03 00:34:27 +000027#include "GrLayerCache.h"
commit-bot@chromium.org81312832013-03-22 18:34:09 +000028#include "GrOvalRenderer.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000029#include "GrPathRenderer.h"
tomhudson@google.comd22b6e42011-06-24 15:53:40 +000030#include "GrPathUtils.h"
bsalomon6bc1b5f2015-02-23 09:06:38 -080031#include "GrRenderTargetPriv.h"
bsalomon0ea80f42015-02-11 10:49:59 -080032#include "GrResourceCache.h"
bsalomond309e7a2015-04-30 14:18:54 -070033#include "GrResourceProvider.h"
robertphillips@google.com72176b22012-05-23 13:19:12 +000034#include "GrSoftwarePathRenderer.h"
kkinnunenc6cb56f2014-06-24 00:12:27 -070035#include "GrStencilAndCoverTextContext.h"
egdanield58a0ba2014-06-11 10:30:05 -070036#include "GrStrokeInfo.h"
bsalomonafbf2d62014-09-30 12:18:44 -070037#include "GrSurfacePriv.h"
joshualittb7133be2015-04-08 09:08:31 -070038#include "GrTextBlobCache.h"
bsalomonafbf2d62014-09-30 12:18:44 -070039#include "GrTexturePriv.h"
egdanielbbcb38d2014-06-19 10:19:29 -070040#include "GrTraceMarker.h"
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +000041#include "GrTracing.h"
bsalomoncb8979d2015-05-05 09:51:38 -070042#include "GrVertices.h"
egdanield58a0ba2014-06-11 10:30:05 -070043#include "SkDashPathPriv.h"
bsalomon81beccc2014-10-13 12:32:55 -070044#include "SkConfig8888.h"
reed@google.com7111d462014-03-25 16:20:24 +000045#include "SkGr.h"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000046#include "SkRRect.h"
sugoi@google.com5f74cf82012-12-17 21:16:45 +000047#include "SkStrokeRec.h"
commit-bot@chromium.orgdcb8ef92014-03-27 11:26:10 +000048#include "SkTLazy.h"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000049#include "SkTLS.h"
commit-bot@chromium.org933e65d2014-03-20 20:00:24 +000050#include "SkTraceEvent.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000051
joshualitt5478d422014-11-14 16:00:38 -080052#include "effects/GrConfigConversionEffect.h"
53#include "effects/GrDashingEffect.h"
54#include "effects/GrSingleTextureEffect.h"
55
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000056#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
robertphillipsea461502015-05-26 11:38:03 -070057#define RETURN_IF_ABANDONED if (fDrawingMgr.abandoned()) { return; }
58#define RETURN_FALSE_IF_ABANDONED if (fDrawingMgr.abandoned()) { return false; }
59#define RETURN_NULL_IF_ABANDONED if (fDrawingMgr.abandoned()) { return NULL; }
bsalomon@google.combc4b6542011-11-19 13:56:11 +000060
bsalomonf21dab92014-11-13 13:33:28 -080061
robertphillipsea461502015-05-26 11:38:03 -070062////////////////////////////////////////////////////////////////////////////////
63
64void GrContext::DrawingMgr::init(GrContext* context) {
65#ifdef IMMEDIATE_MODE
66 fDrawTarget = SkNEW_ARGS(GrImmediateDrawTarget, (context));
67#else
68 fDrawTarget = SkNEW_ARGS(GrInOrderDrawBuffer, (context));
69#endif
70
71 fDrawContext = SkNEW_ARGS(GrDrawContext, (context, fDrawTarget));
72}
73
74GrContext::DrawingMgr::~DrawingMgr() {
75 SkSafeUnref(fDrawTarget);
76 SkSafeUnref(fDrawContext);
77}
78
79void GrContext::DrawingMgr::abandon() {
80 SkSafeSetNull(fDrawTarget);
81 fDrawContext->fDrawTarget.reset(NULL);
82 SkSafeSetNull(fDrawContext);
83}
84
85void GrContext::DrawingMgr::purgeResources() {
86 if (fDrawTarget) {
87 fDrawTarget->purgeResources();
bsalomonf21dab92014-11-13 13:33:28 -080088 }
robertphillipsea461502015-05-26 11:38:03 -070089}
bsalomonf21dab92014-11-13 13:33:28 -080090
robertphillipsea461502015-05-26 11:38:03 -070091void GrContext::DrawingMgr::reset() {
92 if (fDrawTarget) {
93 fDrawTarget->reset();
94 }
95}
96
97void GrContext::DrawingMgr::flush() {
98 if (fDrawTarget) {
99 fDrawTarget->flush();
100 }
101}
102
103GrDrawContext* GrContext::DrawingMgr::drawContext() {
104 if (this->abandoned()) {
105 return NULL;
106 }
107 return fDrawContext;
108}
109
110////////////////////////////////////////////////////////////////////////////////
111
bsalomonf21dab92014-11-13 13:33:28 -0800112
bsalomon682c2692015-05-22 14:01:46 -0700113GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) {
114 GrContextOptions defaultOptions;
115 return Create(backend, backendContext, defaultOptions);
116}
bsalomonf28cff72015-05-22 12:25:41 -0700117
bsalomon682c2692015-05-22 14:01:46 -0700118GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext,
119 const GrContextOptions& options) {
120 GrContext* context = SkNEW(GrContext);
121
122 if (context->init(backend, backendContext, options)) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000123 return context;
124 } else {
125 context->unref();
126 return NULL;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000127 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000128}
129
joshualitt0acd0d32015-05-07 08:23:19 -0700130static int32_t gNextID = 1;
131static int32_t next_id() {
132 int32_t id;
133 do {
134 id = sk_atomic_inc(&gNextID);
135 } while (id == SK_InvalidGenID);
136 return id;
137}
138
bsalomon682c2692015-05-22 14:01:46 -0700139GrContext::GrContext() : fUniqueID(next_id()) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000140 fGpu = NULL;
bsalomond309e7a2015-04-30 14:18:54 -0700141 fResourceCache = NULL;
142 fResourceProvider = NULL;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000143 fPathRendererChain = NULL;
144 fSoftwarePathRenderer = NULL;
joshualitt7c3a2f82015-03-31 13:32:05 -0700145 fBatchFontCache = NULL;
bsalomonf21dab92014-11-13 13:33:28 -0800146 fFlushToReduceCacheSize = false;
robertphillips@google.com44a91dc2013-07-25 15:32:06 +0000147 fMaxTextureSizeOverride = 1 << 20;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000148}
149
bsalomon682c2692015-05-22 14:01:46 -0700150bool GrContext::init(GrBackend backend, GrBackendContext backendContext,
151 const GrContextOptions& options) {
robertphillipsea461502015-05-26 11:38:03 -0700152 SkASSERT(!fGpu);
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000153
bsalomon682c2692015-05-22 14:01:46 -0700154 fGpu = GrGpu::Create(backend, backendContext, options, this);
robertphillipsea461502015-05-26 11:38:03 -0700155 if (!fGpu) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000156 return false;
157 }
bsalomon33435572014-11-05 14:47:41 -0800158 this->initCommon();
159 return true;
160}
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000161
bsalomon33435572014-11-05 14:47:41 -0800162void GrContext::initCommon() {
bsalomon0ea80f42015-02-11 10:49:59 -0800163 fResourceCache = SkNEW(GrResourceCache);
164 fResourceCache->setOverBudgetCallback(OverBudgetCB, this);
bsalomond309e7a2015-04-30 14:18:54 -0700165 fResourceProvider = SkNEW_ARGS(GrResourceProvider, (fGpu, fResourceCache));
commit-bot@chromium.org1836d332013-07-16 22:55:03 +0000166
robertphillips4ec84da2014-06-24 13:10:43 -0700167 fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this)));
robertphillips@google.come930a072014-04-03 00:34:27 +0000168
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000169 fDidTestPMConversions = false;
170
robertphillipsea461502015-05-26 11:38:03 -0700171 fDrawingMgr.init(this);
joshualitt7c3a2f82015-03-31 13:32:05 -0700172
173 // GrBatchFontCache will eventually replace GrFontCache
joshualitt62db8ba2015-04-09 08:22:37 -0700174 fBatchFontCache = SkNEW_ARGS(GrBatchFontCache, (this));
joshualittb7133be2015-04-08 09:08:31 -0700175
joshualitt0db6dfa2015-04-10 07:01:30 -0700176 fTextBlobCache.reset(SkNEW_ARGS(GrTextBlobCache, (TextBlobCacheOverBudgetCB, this)));
bsalomon@google.comc0af3172012-06-15 14:10:09 +0000177}
178
bsalomon@google.com27847de2011-02-22 20:59:41 +0000179GrContext::~GrContext() {
robertphillipsea461502015-05-26 11:38:03 -0700180 if (!fGpu) {
bsalomon@google.com733c0622013-04-24 17:59:32 +0000181 return;
182 }
183
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000184 this->flush();
robertphillips@google.com5acc0e32012-05-17 12:01:02 +0000185
robertphillips@google.com950b1b02013-10-21 17:37:28 +0000186 for (int i = 0; i < fCleanUpData.count(); ++i) {
187 (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
188 }
189
bsalomond309e7a2015-04-30 14:18:54 -0700190 SkDELETE(fResourceProvider);
bsalomon0ea80f42015-02-11 10:49:59 -0800191 SkDELETE(fResourceCache);
joshualitt7c3a2f82015-03-31 13:32:05 -0700192 SkDELETE(fBatchFontCache);
robertphillips@google.comf6747b02012-06-12 00:32:28 +0000193
bsalomon@google.com205d4602011-04-25 12:43:45 +0000194 fGpu->unref();
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000195 SkSafeUnref(fPathRendererChain);
196 SkSafeUnref(fSoftwarePathRenderer);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000197}
198
bsalomon2354f842014-07-28 13:48:36 -0700199void GrContext::abandonContext() {
bsalomond309e7a2015-04-30 14:18:54 -0700200 fResourceProvider->abandon();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000201 // abandon first to so destructors
202 // don't try to free the resources in the API.
bsalomon0ea80f42015-02-11 10:49:59 -0800203 fResourceCache->abandonAll();
bsalomonc8dc1f72014-08-21 13:02:13 -0700204
robertphillipse3371302014-09-17 06:01:06 -0700205 fGpu->contextAbandoned();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000206
bsalomon@google.com30085192011-08-19 15:42:31 +0000207 // a path renderer may be holding onto resources that
208 // are now unusable
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000209 SkSafeSetNull(fPathRendererChain);
210 SkSafeSetNull(fSoftwarePathRenderer);
bsalomon@google.com30085192011-08-19 15:42:31 +0000211
robertphillipsea461502015-05-26 11:38:03 -0700212 fDrawingMgr.abandon();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000213
joshualitt7c3a2f82015-03-31 13:32:05 -0700214 fBatchFontCache->freeAll();
robertphillips@google.come930a072014-04-03 00:34:27 +0000215 fLayerCache->freeAll();
joshualitt26ffc002015-04-16 11:24:04 -0700216 fTextBlobCache->freeAll();
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000217}
218
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000219void GrContext::resetContext(uint32_t state) {
220 fGpu->markContextDirty(state);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000221}
222
223void GrContext::freeGpuResources() {
224 this->flush();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000225
robertphillipsea461502015-05-26 11:38:03 -0700226 fDrawingMgr.purgeResources();
robertphillips@google.comff175842012-05-14 19:31:39 +0000227
joshualitt7c3a2f82015-03-31 13:32:05 -0700228 fBatchFontCache->freeAll();
robertphillips@google.come930a072014-04-03 00:34:27 +0000229 fLayerCache->freeAll();
bsalomon@google.com30085192011-08-19 15:42:31 +0000230 // a path renderer may be holding onto resources
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000231 SkSafeSetNull(fPathRendererChain);
232 SkSafeSetNull(fSoftwarePathRenderer);
bsalomon3033b9f2015-04-13 11:09:56 -0700233
234 fResourceCache->purgeAllUnlocked();
bsalomon@google.com27847de2011-02-22 20:59:41 +0000235}
236
commit-bot@chromium.org95c20032014-05-09 14:29:32 +0000237void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
bsalomon71cb0c22014-11-14 12:10:14 -0800238 if (resourceCount) {
bsalomon0ea80f42015-02-11 10:49:59 -0800239 *resourceCount = fResourceCache->getBudgetedResourceCount();
bsalomon71cb0c22014-11-14 12:10:14 -0800240 }
241 if (resourceBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800242 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
bsalomon71cb0c22014-11-14 12:10:14 -0800243 }
commit-bot@chromium.orgd8a57af2014-03-19 21:19:16 +0000244}
245
kkinnunenc6cb56f2014-06-24 00:12:27 -0700246GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget,
joshualitt6e8cd962015-03-20 10:30:14 -0700247 SkGpuDevice* gpuDevice,
kkinnunenc6cb56f2014-06-24 00:12:27 -0700248 const SkDeviceProperties&
249 leakyProperties,
250 bool enableDistanceFieldFonts) {
jvanverthe9c0fc62015-04-29 11:18:05 -0700251 if (fGpu->caps()->shaderCaps()->pathRenderingSupport() && renderTarget->isMultisampled()) {
egdaniel8dc7c3a2015-04-16 11:22:42 -0700252 GrStencilAttachment* sb = renderTarget->renderTargetPriv().attachStencilAttachment();
bsalomon6bc1b5f2015-02-23 09:06:38 -0800253 if (sb) {
joshualitt6e8cd962015-03-20 10:30:14 -0700254 return GrStencilAndCoverTextContext::Create(this, gpuDevice, leakyProperties);
bsalomon6bc1b5f2015-02-23 09:06:38 -0800255 }
jvanverth8c27a182014-10-14 08:45:50 -0700256 }
257
joshualitt9bd2daf2015-04-17 09:30:06 -0700258 return GrAtlasTextContext::Create(this, gpuDevice, leakyProperties, enableDistanceFieldFonts);
kkinnunenc6cb56f2014-06-24 00:12:27 -0700259}
260
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000261////////////////////////////////////////////////////////////////////////////////
262
robertphillipsea461502015-05-26 11:38:03 -0700263bool GrContext::shaderDerivativeSupport() const {
264 return fGpu->caps()->shaderCaps()->shaderDerivativeSupport();
265}
266
bsalomond2a6f4e2015-02-04 10:55:54 -0800267bool GrContext::isConfigTexturable(GrPixelConfig config) const {
268 return fGpu->caps()->isConfigTexturable(config);
269}
270
271bool GrContext::npotTextureTileSupport() const {
272 return fGpu->caps()->npotTextureTileSupport();
273}
274
bsalomon71cb0c22014-11-14 12:10:14 -0800275void GrContext::OverBudgetCB(void* data) {
bsalomon66a450f2014-11-13 13:19:10 -0800276 SkASSERT(data);
bsalomonf21dab92014-11-13 13:33:28 -0800277
bsalomon66a450f2014-11-13 13:19:10 -0800278 GrContext* context = reinterpret_cast<GrContext*>(data);
bsalomonf21dab92014-11-13 13:33:28 -0800279
280 // Flush the InOrderDrawBuffer to possibly free up some textures
281 context->fFlushToReduceCacheSize = true;
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000282}
283
joshualitt0db6dfa2015-04-10 07:01:30 -0700284void GrContext::TextBlobCacheOverBudgetCB(void* data) {
285 SkASSERT(data);
286
287 // Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they
288 // cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush. The solution is to move
289 // drawText calls to below the GrContext level, but this is not trivial because they call
290 // drawPath on SkGpuDevice
291 GrContext* context = reinterpret_cast<GrContext*>(data);
292 context->flush();
293}
294
bsalomon@google.com91958362011-06-13 17:58:13 +0000295int GrContext::getMaxTextureSize() const {
commit-bot@chromium.org972f9cd2014-03-28 17:58:28 +0000296 return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride);
bsalomon@google.com91958362011-06-13 17:58:13 +0000297}
298
299int GrContext::getMaxRenderTargetSize() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000300 return fGpu->caps()->maxRenderTargetSize();
bsalomon@google.com27847de2011-02-22 20:59:41 +0000301}
302
bsalomon@google.com8a70eef2013-03-19 13:58:55 +0000303int GrContext::getMaxSampleCount() const {
bsalomon@google.combcce8922013-03-25 15:38:39 +0000304 return fGpu->caps()->maxSampleCount();
bsalomon@google.com8a70eef2013-03-19 13:58:55 +0000305}
306
bsalomon@google.com27847de2011-02-22 20:59:41 +0000307////////////////////////////////////////////////////////////////////////////////
308
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000309void GrContext::flush(int flagsBitfield) {
robertphillipsea461502015-05-26 11:38:03 -0700310 RETURN_IF_ABANDONED
robertphillips@google.come7db8d62013-07-04 11:48:52 +0000311
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000312 if (kDiscard_FlushBit & flagsBitfield) {
robertphillipsea461502015-05-26 11:38:03 -0700313 fDrawingMgr.reset();
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000314 } else {
robertphillipsea461502015-05-26 11:38:03 -0700315 fDrawingMgr.flush();
junov@google.com53a55842011-06-08 22:55:10 +0000316 }
bsalomon3f324322015-04-08 11:01:54 -0700317 fResourceCache->notifyFlushOccurred();
bsalomonf21dab92014-11-13 13:33:28 -0800318 fFlushToReduceCacheSize = false;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000319}
320
bsalomon81beccc2014-10-13 12:32:55 -0700321bool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes,
322 const void* inPixels, size_t outRowBytes, void* outPixels) {
323 SkSrcPixelInfo srcPI;
jvanverthfa1e8a72014-12-22 08:31:49 -0800324 if (!GrPixelConfig2ColorAndProfileType(srcConfig, &srcPI.fColorType, NULL)) {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000325 return false;
326 }
bsalomon81beccc2014-10-13 12:32:55 -0700327 srcPI.fAlphaType = kUnpremul_SkAlphaType;
328 srcPI.fPixels = inPixels;
329 srcPI.fRowBytes = inRowBytes;
330
331 SkDstPixelInfo dstPI;
332 dstPI.fColorType = srcPI.fColorType;
333 dstPI.fAlphaType = kPremul_SkAlphaType;
334 dstPI.fPixels = outPixels;
335 dstPI.fRowBytes = outRowBytes;
336
337 return srcPI.convertPixelsTo(&dstPI, width, height);
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000338}
339
bsalomon81beccc2014-10-13 12:32:55 -0700340bool GrContext::writeSurfacePixels(GrSurface* surface,
341 int left, int top, int width, int height,
342 GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
343 uint32_t pixelOpsFlags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800344 RETURN_FALSE_IF_ABANDONED
bsalomon81beccc2014-10-13 12:32:55 -0700345 {
346 GrTexture* texture = NULL;
347 if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) &&
348 fGpu->canWriteTexturePixels(texture, srcConfig)) {
349
350 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) &&
351 surface->surfacePriv().hasPendingIO()) {
352 this->flush();
353 }
354 return fGpu->writeTexturePixels(texture, left, top, width, height,
355 srcConfig, buffer, rowBytes);
356 // Don't need to check kFlushWrites_PixelOp here, we just did a direct write so the
357 // upload is already flushed.
358 }
359 }
360
361 // If we didn't do a direct texture write then we upload the pixels to a texture and draw.
362 GrRenderTarget* renderTarget = surface->asRenderTarget();
robertphillipsea461502015-05-26 11:38:03 -0700363 if (!renderTarget) {
bsalomon81beccc2014-10-13 12:32:55 -0700364 return false;
365 }
366
367 // We ignore the preferred config unless it is a R/B swap of the src config. In that case
368 // we will upload the original src data to a scratch texture but we will spoof it as the swapped
369 // config. This scratch will then have R and B swapped. We correct for this by swapping again
370 // when drawing the scratch to the dst using a conversion effect.
371 bool swapRAndB = false;
372 GrPixelConfig writeConfig = srcConfig;
373 if (GrPixelConfigSwapRAndB(srcConfig) ==
374 fGpu->preferredWritePixelsConfig(srcConfig, renderTarget->config())) {
375 writeConfig = GrPixelConfigSwapRAndB(srcConfig);
376 swapRAndB = true;
377 }
378
bsalomonf2703d82014-10-28 14:33:06 -0700379 GrSurfaceDesc desc;
bsalomon81beccc2014-10-13 12:32:55 -0700380 desc.fWidth = width;
381 desc.fHeight = height;
382 desc.fConfig = writeConfig;
bsalomond309e7a2015-04-30 14:18:54 -0700383 SkAutoTUnref<GrTexture> texture(this->textureProvider()->refScratchTexture(desc,
384 GrTextureProvider::kApprox_ScratchTexMatch));
bsalomone3059732014-10-14 11:47:22 -0700385 if (!texture) {
bsalomon81beccc2014-10-13 12:32:55 -0700386 return false;
387 }
388
389 SkAutoTUnref<const GrFragmentProcessor> fp;
390 SkMatrix textureMatrix;
391 textureMatrix.setIDiv(texture->width(), texture->height());
392
393 // allocate a tmp buffer and sw convert the pixels to premul
394 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
395
396 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
397 if (!GrPixelConfigIs8888(srcConfig)) {
398 return false;
399 }
400 fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix));
401 // handle the unpremul step on the CPU if we couldn't create an effect to do it.
robertphillipsea461502015-05-26 11:38:03 -0700402 if (!fp) {
bsalomon81beccc2014-10-13 12:32:55 -0700403 size_t tmpRowBytes = 4 * width;
404 tmpPixels.reset(width * height);
405 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
406 tmpPixels.get())) {
407 return false;
408 }
409 rowBytes = tmpRowBytes;
410 buffer = tmpPixels.get();
411 }
412 }
robertphillipsea461502015-05-26 11:38:03 -0700413 if (!fp) {
bsalomon81beccc2014-10-13 12:32:55 -0700414 fp.reset(GrConfigConversionEffect::Create(texture,
415 swapRAndB,
416 GrConfigConversionEffect::kNone_PMConversion,
417 textureMatrix));
418 }
419
420 // Even if the client told us not to flush, we still flush here. The client may have known that
421 // writes to the original surface caused no data hazards, but they can't know that the scratch
422 // we just got is safe.
423 if (texture->surfacePriv().hasPendingIO()) {
424 this->flush();
425 }
426 if (!fGpu->writeTexturePixels(texture, 0, 0, width, height,
427 writeConfig, buffer, rowBytes)) {
428 return false;
429 }
430
431 SkMatrix matrix;
432 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
433
robertphillipsea461502015-05-26 11:38:03 -0700434 GrDrawContext* drawContext = this->drawContext();
435 if (!drawContext) {
436 return false;
bsalomon81beccc2014-10-13 12:32:55 -0700437 }
438
robertphillipsea461502015-05-26 11:38:03 -0700439 GrPaint paint;
440 paint.addColorProcessor(fp);
441
442 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
443
444 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matrix, rect, NULL);
445
bsalomon81beccc2014-10-13 12:32:55 -0700446 if (kFlushWrites_PixelOp & pixelOpsFlags) {
447 this->flushSurfaceWrites(surface);
448 }
449
450 return true;
451}
bsalomon@google.coma91e9232012-02-23 15:39:54 +0000452
reed@google.com7111d462014-03-25 16:20:24 +0000453// toggles between RGBA and BGRA
454static SkColorType toggle_colortype32(SkColorType ct) {
455 if (kRGBA_8888_SkColorType == ct) {
456 return kBGRA_8888_SkColorType;
457 } else {
458 SkASSERT(kBGRA_8888_SkColorType == ct);
459 return kRGBA_8888_SkColorType;
bsalomon@google.coma91e9232012-02-23 15:39:54 +0000460 }
461}
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000462
bsalomon@google.com0342a852012-08-20 19:22:38 +0000463bool GrContext::readRenderTargetPixels(GrRenderTarget* target,
464 int left, int top, int width, int height,
bsalomon@google.com9c680582013-02-06 18:17:50 +0000465 GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
bsalomon@google.com0342a852012-08-20 19:22:38 +0000466 uint32_t flags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800467 RETURN_FALSE_IF_ABANDONED
bsalomon@google.combc4b6542011-11-19 13:56:11 +0000468 ASSERT_OWNED_RESOURCE(target);
bsalomon89c62982014-11-03 12:08:42 -0800469 SkASSERT(target);
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000470
bsalomonafbf2d62014-09-30 12:18:44 -0700471 if (!(kDontFlush_PixelOpsFlag & flags) && target->surfacePriv().hasPendingWrite()) {
bsalomon@google.com6f379512011-11-16 20:36:03 +0000472 this->flush();
473 }
bsalomon@google.comc4364992011-11-07 15:54:49 +0000474
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000475 // Determine which conversions have to be applied: flipY, swapRAnd, and/or unpremul.
bsalomon@google.com0342a852012-08-20 19:22:38 +0000476
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000477 // If fGpu->readPixels would incur a y-flip cost then we will read the pixels upside down. We'll
478 // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read.
479 bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top,
bsalomon@google.com9c680582013-02-06 18:17:50 +0000480 width, height, dstConfig,
bsalomon@google.comc4364992011-11-07 15:54:49 +0000481 rowBytes);
bsalomon@google.com9c680582013-02-06 18:17:50 +0000482 // We ignore the preferred config if it is different than our config unless it is an R/B swap.
483 // In that case we'll perform an R and B swap while drawing to a scratch texture of the swapped
484 // config. Then we will call readPixels on the scratch with the swapped config. The swaps during
485 // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from
486 // dstConfig.
487 GrPixelConfig readConfig = dstConfig;
488 bool swapRAndB = false;
commit-bot@chromium.org5d1d79a2013-05-24 18:52:52 +0000489 if (GrPixelConfigSwapRAndB(dstConfig) ==
490 fGpu->preferredReadPixelsConfig(dstConfig, target->config())) {
bsalomon@google.com9c680582013-02-06 18:17:50 +0000491 readConfig = GrPixelConfigSwapRAndB(readConfig);
492 swapRAndB = true;
493 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000494
bsalomon@google.com0342a852012-08-20 19:22:38 +0000495 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
bsalomon@google.comc4364992011-11-07 15:54:49 +0000496
bsalomon@google.com9c680582013-02-06 18:17:50 +0000497 if (unpremul && !GrPixelConfigIs8888(dstConfig)) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000498 // The unpremul flag is only allowed for these two configs.
bsalomon@google.com0a97be22011-11-08 19:20:57 +0000499 return false;
500 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000501
bsalomon191bcc02014-11-14 11:31:13 -0800502 SkAutoTUnref<GrTexture> tempTexture;
503
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000504 // If the src is a texture and we would have to do conversions after read pixels, we instead
505 // do the conversions by drawing the src to a scratch texture. If we handle any of the
506 // conversions in the draw we set the corresponding bool to false so that we don't reapply it
507 // on the read back pixels.
508 GrTexture* src = target->asTexture();
bsalomon49f085d2014-09-05 13:34:00 -0700509 if (src && (swapRAndB || unpremul || flipY)) {
bsalomon81beccc2014-10-13 12:32:55 -0700510 // Make the scratch a render so we can read its pixels.
bsalomonf2703d82014-10-28 14:33:06 -0700511 GrSurfaceDesc desc;
512 desc.fFlags = kRenderTarget_GrSurfaceFlag;
robertphillips@google.com75b3c962012-06-07 12:08:45 +0000513 desc.fWidth = width;
514 desc.fHeight = height;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000515 desc.fConfig = readConfig;
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000516 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
bsalomon@google.comc4ff22a2011-11-10 21:56:21 +0000517
bsalomon@google.com9c680582013-02-06 18:17:50 +0000518 // When a full read back is faster than a partial we could always make the scratch exactly
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000519 // match the passed rect. However, if we see many different size rectangles we will trash
520 // our texture cache and pay the cost of creating and destroying many textures. So, we only
521 // request an exact match when the caller is reading an entire RT.
bsalomond309e7a2015-04-30 14:18:54 -0700522 GrTextureProvider::ScratchTexMatch match = GrTextureProvider::kApprox_ScratchTexMatch;
bsalomon@google.com56d11e02011-11-30 19:59:08 +0000523 if (0 == left &&
524 0 == top &&
525 target->width() == width &&
526 target->height() == height &&
527 fGpu->fullReadPixelsIsFasterThanPartial()) {
bsalomond309e7a2015-04-30 14:18:54 -0700528 match = GrTextureProvider::kExact_ScratchTexMatch;
bsalomon@google.com56d11e02011-11-30 19:59:08 +0000529 }
bsalomond309e7a2015-04-30 14:18:54 -0700530 tempTexture.reset(this->textureProvider()->refScratchTexture(desc, match));
bsalomon191bcc02014-11-14 11:31:13 -0800531 if (tempTexture) {
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000532 // compute a matrix to perform the draw
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000533 SkMatrix textureMatrix;
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000534 textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top);
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000535 textureMatrix.postIDiv(src->width(), src->height());
536
joshualittb0a8a372014-09-23 09:50:21 -0700537 SkAutoTUnref<const GrFragmentProcessor> fp;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000538 if (unpremul) {
joshualittb0a8a372014-09-23 09:50:21 -0700539 fp.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix));
540 if (fp) {
bsalomon@google.com9c680582013-02-06 18:17:50 +0000541 unpremul = false; // we no longer need to do this on CPU after the read back.
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000542 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000543 }
544 // If we failed to create a PM->UPM effect and have no other conversions to perform then
545 // there is no longer any point to using the scratch.
joshualittb0a8a372014-09-23 09:50:21 -0700546 if (fp || flipY || swapRAndB) {
547 if (!fp) {
548 fp.reset(GrConfigConversionEffect::Create(
549 src, swapRAndB, GrConfigConversionEffect::kNone_PMConversion,
550 textureMatrix));
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000551 }
552 swapRAndB = false; // we will handle the swap in the draw.
bsalomon@google.comc4364992011-11-07 15:54:49 +0000553
robertphillips@google.com13f181f2013-03-02 12:02:08 +0000554 // We protect the existing geometry here since it may not be
555 // clear to the caller that a draw operation (i.e., drawSimpleRect)
556 // can be invoked in this method
joshualitt5c55fef2014-10-31 14:04:35 -0700557 {
robertphillipsea461502015-05-26 11:38:03 -0700558 GrDrawContext* drawContext = this->drawContext();
559 if (!drawContext) {
560 return false;
561 }
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000562
robertphillipsea461502015-05-26 11:38:03 -0700563 GrPaint paint;
564 paint.addColorProcessor(fp);
565
joshualitt5c55fef2014-10-31 14:04:35 -0700566 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
robertphillipsea461502015-05-26 11:38:03 -0700567
568 drawContext->drawRect(tempTexture->asRenderTarget(), GrClip::WideOpen(), paint,
569 SkMatrix::I(), rect, NULL);
570
joshualitt5c55fef2014-10-31 14:04:35 -0700571 // we want to read back from the scratch's origin
572 left = 0;
573 top = 0;
bsalomon191bcc02014-11-14 11:31:13 -0800574 target = tempTexture->asRenderTarget();
joshualitt5c55fef2014-10-31 14:04:35 -0700575 }
576 this->flushSurfaceWrites(target);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000577 }
bsalomon@google.com0342a852012-08-20 19:22:38 +0000578 }
bsalomon@google.comc4364992011-11-07 15:54:49 +0000579 }
joshualitt5c55fef2014-10-31 14:04:35 -0700580
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000581 if (!fGpu->readPixels(target,
582 left, top, width, height,
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000583 readConfig, buffer, rowBytes)) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000584 return false;
585 }
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000586 // Perform any conversions we weren't able to perform using a scratch texture.
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000587 if (unpremul || swapRAndB) {
reed@google.com7111d462014-03-25 16:20:24 +0000588 SkDstPixelInfo dstPI;
jvanverthfa1e8a72014-12-22 08:31:49 -0800589 if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, NULL)) {
reed@google.com7111d462014-03-25 16:20:24 +0000590 return false;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000591 }
reed@google.com7111d462014-03-25 16:20:24 +0000592 dstPI.fAlphaType = kUnpremul_SkAlphaType;
593 dstPI.fPixels = buffer;
594 dstPI.fRowBytes = rowBytes;
595
596 SkSrcPixelInfo srcPI;
597 srcPI.fColorType = swapRAndB ? toggle_colortype32(dstPI.fColorType) : dstPI.fColorType;
598 srcPI.fAlphaType = kPremul_SkAlphaType;
599 srcPI.fPixels = buffer;
600 srcPI.fRowBytes = rowBytes;
601
602 return srcPI.convertPixelsTo(&dstPI, width, height);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000603 }
604 return true;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000605}
606
bsalomon87a94eb2014-11-03 14:28:32 -0800607void GrContext::prepareSurfaceForExternalRead(GrSurface* surface) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800608 RETURN_IF_ABANDONED
bsalomon87a94eb2014-11-03 14:28:32 -0800609 SkASSERT(surface);
610 ASSERT_OWNED_RESOURCE(surface);
611 if (surface->surfacePriv().hasPendingIO()) {
612 this->flush();
613 }
614 GrRenderTarget* rt = surface->asRenderTarget();
615 if (fGpu && rt) {
616 fGpu->resolveRenderTarget(rt);
bsalomon41ebbdd2014-08-04 08:31:39 -0700617 }
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000618}
619
bsalomonf80bfed2014-10-07 05:56:02 -0700620void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
621 const SkIPoint& dstPoint, uint32_t pixelOpsFlags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800622 RETURN_IF_ABANDONED
robertphillipsea461502015-05-26 11:38:03 -0700623 if (!src || !dst) {
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000624 return;
625 }
bsalomone3d4bf22014-09-23 09:15:03 -0700626 ASSERT_OWNED_RESOURCE(src);
junov2bb52102014-09-29 10:18:59 -0700627 ASSERT_OWNED_RESOURCE(dst);
Brian Salomon34a98952014-09-24 11:41:24 -0400628
bsalomonf80bfed2014-10-07 05:56:02 -0700629 // Since we're going to the draw target and not GPU, no need to check kNoFlush
630 // here.
robertphillipsea461502015-05-26 11:38:03 -0700631 if (!dst->asRenderTarget()) {
junov96c118e2014-09-26 13:09:47 -0700632 return;
633 }
robertphillipsea461502015-05-26 11:38:03 -0700634
635 GrDrawContext* drawContext = this->drawContext();
636 if (!drawContext) {
637 return;
638 }
639
640 drawContext->copySurface(dst->asRenderTarget(), src, srcRect, dstPoint);
bsalomonf80bfed2014-10-07 05:56:02 -0700641
642 if (kFlushWrites_PixelOp & pixelOpsFlags) {
643 this->flush();
644 }
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000645}
646
bsalomonf80bfed2014-10-07 05:56:02 -0700647void GrContext::flushSurfaceWrites(GrSurface* surface) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800648 RETURN_IF_ABANDONED
bsalomonf80bfed2014-10-07 05:56:02 -0700649 if (surface->surfacePriv().hasPendingWrite()) {
650 this->flush();
651 }
652}
653
robertphillips@google.com72176b22012-05-23 13:19:12 +0000654/*
655 * This method finds a path renderer that can draw the specified path on
656 * the provided target.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000657 * Due to its expense, the software path renderer has split out so it can
robertphillips@google.com72176b22012-05-23 13:19:12 +0000658 * can be individually allowed/disallowed via the "allowSW" boolean.
659 */
joshualitt9853cce2014-11-17 14:22:48 -0800660GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
egdaniel8dd688b2015-01-22 10:16:09 -0800661 const GrPipelineBuilder* pipelineBuilder,
joshualitt8059eb92014-12-29 15:10:07 -0800662 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800663 const SkPath& path,
kkinnunen18996512015-04-26 23:18:49 -0700664 const GrStrokeInfo& stroke,
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000665 bool allowSW,
666 GrPathRendererChain::DrawType drawType,
667 GrPathRendererChain::StencilSupport* stencilSupport) {
668
robertphillipsea461502015-05-26 11:38:03 -0700669 if (!fPathRendererChain) {
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000670 fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this));
bsalomon@google.com30085192011-08-19 15:42:31 +0000671 }
robertphillips@google.com72176b22012-05-23 13:19:12 +0000672
joshualitt9853cce2014-11-17 14:22:48 -0800673 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target,
egdaniel8dd688b2015-01-22 10:16:09 -0800674 pipelineBuilder,
joshualitt8059eb92014-12-29 15:10:07 -0800675 viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800676 path,
sugoi@google.com12b4e272012-12-06 20:13:11 +0000677 stroke,
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000678 drawType,
679 stencilSupport);
robertphillips@google.com72176b22012-05-23 13:19:12 +0000680
robertphillipsea461502015-05-26 11:38:03 -0700681 if (!pr && allowSW) {
682 if (!fSoftwarePathRenderer) {
tomhudson@google.comc377baf2012-07-09 20:17:56 +0000683 fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this));
robertphillips@google.com72176b22012-05-23 13:19:12 +0000684 }
robertphillips@google.com72176b22012-05-23 13:19:12 +0000685 pr = fSoftwarePathRenderer;
686 }
687
688 return pr;
bsalomon@google.com30085192011-08-19 15:42:31 +0000689}
690
bsalomon@google.com27847de2011-02-22 20:59:41 +0000691////////////////////////////////////////////////////////////////////////////////
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +0000692bool GrContext::isConfigRenderable(GrPixelConfig config, bool withMSAA) const {
693 return fGpu->caps()->isConfigRenderable(config, withMSAA);
robertphillips@google.com99a5ac02012-04-10 19:26:38 +0000694}
695
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000696int GrContext::getRecommendedSampleCount(GrPixelConfig config,
697 SkScalar dpi) const {
698 if (!this->isConfigRenderable(config, true)) {
699 return 0;
700 }
701 int chosenSampleCount = 0;
jvanverthe9c0fc62015-04-29 11:18:05 -0700702 if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) {
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000703 if (dpi >= 250.0f) {
704 chosenSampleCount = 4;
705 } else {
706 chosenSampleCount = 16;
707 }
708 }
709 return chosenSampleCount <= fGpu->caps()->maxSampleCount() ?
710 chosenSampleCount : 0;
711}
712
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000713namespace {
714void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) {
715 GrConfigConversionEffect::PMConversion pmToUPM;
716 GrConfigConversionEffect::PMConversion upmToPM;
717 GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM);
718 *pmToUPMValue = pmToUPM;
719 *upmToPMValue = upmToPM;
720}
721}
722
joshualittb0a8a372014-09-23 09:50:21 -0700723const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture,
724 bool swapRAndB,
725 const SkMatrix& matrix) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000726 if (!fDidTestPMConversions) {
727 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
bsalomon@google.comd0f3f682012-08-28 13:08:14 +0000728 fDidTestPMConversions = true;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000729 }
730 GrConfigConversionEffect::PMConversion pmToUPM =
731 static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
732 if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000733 return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000734 } else {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000735 return NULL;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000736 }
737}
738
joshualittb0a8a372014-09-23 09:50:21 -0700739const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture,
740 bool swapRAndB,
741 const SkMatrix& matrix) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000742 if (!fDidTestPMConversions) {
743 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
bsalomon@google.comd0f3f682012-08-28 13:08:14 +0000744 fDidTestPMConversions = true;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000745 }
746 GrConfigConversionEffect::PMConversion upmToPM =
747 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
748 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000749 return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000750 } else {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000751 return NULL;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000752 }
753}
754
bsalomon37f9a262015-02-02 13:00:10 -0800755//////////////////////////////////////////////////////////////////////////////
756
757void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const {
758 if (maxTextures) {
bsalomon0ea80f42015-02-11 10:49:59 -0800759 *maxTextures = fResourceCache->getMaxResourceCount();
bsalomon37f9a262015-02-02 13:00:10 -0800760 }
761 if (maxTextureBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800762 *maxTextureBytes = fResourceCache->getMaxResourceBytes();
bsalomon37f9a262015-02-02 13:00:10 -0800763 }
764}
765
766void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800767 fResourceCache->setLimits(maxTextures, maxTextureBytes);
bsalomon37f9a262015-02-02 13:00:10 -0800768}
769
bsalomon37f9a262015-02-02 13:00:10 -0800770//////////////////////////////////////////////////////////////////////////////
771
egdanielbbcb38d2014-06-19 10:19:29 -0700772void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
773 fGpu->addGpuTraceMarker(marker);
egdanielbbcb38d2014-06-19 10:19:29 -0700774}
775
776void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
777 fGpu->removeGpuTraceMarker(marker);
egdanielbbcb38d2014-06-19 10:19:29 -0700778}
joshualitte5902662015-05-11 08:18:35 -0700779