blob: 9337a955333fa3cb5c780ae73761600e696d2ddc [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"
joshualitt7c3a2f82015-03-31 13:32:05 -070012#include "GrBatchFontCache.h"
joshualitt0823bfa2015-02-27 10:06:15 -080013#include "GrBatchTarget.h"
joshualitte5902662015-05-11 08:18:35 -070014#include "GrBatchTest.h"
joshualittb542bae2015-07-28 09:58:39 -070015#include "GrBufferedDrawTarget.h"
bsalomoneb1cb5c2015-05-22 08:01:09 -070016#include "GrCaps.h"
bsalomon682c2692015-05-22 14:01:46 -070017#include "GrContextOptions.h"
joshualitt5478d422014-11-14 16:00:38 -080018#include "GrDefaultGeoProcFactory.h"
robertphillipsea461502015-05-26 11:38:03 -070019#include "GrDrawContext.h"
bsalomon453cf402014-11-11 14:15:57 -080020#include "GrGpuResource.h"
bsalomon3582d3e2015-02-13 14:20:05 -080021#include "GrGpuResourcePriv.h"
joshualitt5478d422014-11-14 16:00:38 -080022#include "GrGpu.h"
joshualittbb87b212015-05-19 14:28:04 -070023#include "GrImmediateDrawTarget.h"
commit-bot@chromium.orgdcb8ef92014-03-27 11:26:10 +000024#include "GrIndexBuffer.h"
robertphillips@google.come930a072014-04-03 00:34:27 +000025#include "GrLayerCache.h"
commit-bot@chromium.org81312832013-03-22 18:34:09 +000026#include "GrOvalRenderer.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000027#include "GrPathRenderer.h"
tomhudson@google.comd22b6e42011-06-24 15:53:40 +000028#include "GrPathUtils.h"
bsalomon6bc1b5f2015-02-23 09:06:38 -080029#include "GrRenderTargetPriv.h"
bsalomon0ea80f42015-02-11 10:49:59 -080030#include "GrResourceCache.h"
bsalomond309e7a2015-04-30 14:18:54 -070031#include "GrResourceProvider.h"
robertphillips@google.com72176b22012-05-23 13:19:12 +000032#include "GrSoftwarePathRenderer.h"
egdanield58a0ba2014-06-11 10:30:05 -070033#include "GrStrokeInfo.h"
bsalomonafbf2d62014-09-30 12:18:44 -070034#include "GrSurfacePriv.h"
joshualittb7133be2015-04-08 09:08:31 -070035#include "GrTextBlobCache.h"
bsalomonafbf2d62014-09-30 12:18:44 -070036#include "GrTexturePriv.h"
egdanielbbcb38d2014-06-19 10:19:29 -070037#include "GrTraceMarker.h"
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +000038#include "GrTracing.h"
bsalomoncb8979d2015-05-05 09:51:38 -070039#include "GrVertices.h"
egdanield58a0ba2014-06-11 10:30:05 -070040#include "SkDashPathPriv.h"
bsalomon81beccc2014-10-13 12:32:55 -070041#include "SkConfig8888.h"
reed@google.com7111d462014-03-25 16:20:24 +000042#include "SkGr.h"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000043#include "SkRRect.h"
sugoi@google.com5f74cf82012-12-17 21:16:45 +000044#include "SkStrokeRec.h"
robertphillipsfcf78292015-06-19 11:49:52 -070045#include "SkSurfacePriv.h"
commit-bot@chromium.orgdcb8ef92014-03-27 11:26:10 +000046#include "SkTLazy.h"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000047#include "SkTLS.h"
commit-bot@chromium.org933e65d2014-03-20 20:00:24 +000048#include "SkTraceEvent.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000049
joshualitt74417822015-08-07 11:42:16 -070050#include "batches/GrBatch.h"
51
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) {
robertphillips2334fb62015-06-17 05:43:33 -070065 fContext = context;
66
robertphillipsea461502015-05-26 11:38:03 -070067#ifdef IMMEDIATE_MODE
68 fDrawTarget = SkNEW_ARGS(GrImmediateDrawTarget, (context));
69#else
joshualittb542bae2015-07-28 09:58:39 -070070 fDrawTarget = SkNEW_ARGS(GrBufferedDrawTarget, (context));
robertphillipsea461502015-05-26 11:38:03 -070071#endif
robertphillips2334fb62015-06-17 05:43:33 -070072}
bsalomon781d5822015-06-16 15:03:11 -070073
robertphillips2334fb62015-06-17 05:43:33 -070074void GrContext::DrawingMgr::cleanup() {
75 SkSafeSetNull(fDrawTarget);
76 for (int i = 0; i < kNumPixelGeometries; ++i) {
77 SkSafeSetNull(fDrawContext[i][0]);
78 SkSafeSetNull(fDrawContext[i][1]);
79 }
robertphillipsea461502015-05-26 11:38:03 -070080}
81
82GrContext::DrawingMgr::~DrawingMgr() {
robertphillips2334fb62015-06-17 05:43:33 -070083 this->cleanup();
robertphillipsea461502015-05-26 11:38:03 -070084}
85
86void GrContext::DrawingMgr::abandon() {
87 SkSafeSetNull(fDrawTarget);
robertphillips2334fb62015-06-17 05:43:33 -070088 for (int i = 0; i < kNumPixelGeometries; ++i) {
89 for (int j = 0; j < kNumDFTOptions; ++j) {
90 if (fDrawContext[i][j]) {
91 SkSafeSetNull(fDrawContext[i][j]->fDrawTarget);
92 SkSafeSetNull(fDrawContext[i][j]);
93 }
94 }
95 }
robertphillipsea461502015-05-26 11:38:03 -070096}
97
98void GrContext::DrawingMgr::purgeResources() {
99 if (fDrawTarget) {
100 fDrawTarget->purgeResources();
bsalomonf21dab92014-11-13 13:33:28 -0800101 }
robertphillipsea461502015-05-26 11:38:03 -0700102}
bsalomonf21dab92014-11-13 13:33:28 -0800103
robertphillipsea461502015-05-26 11:38:03 -0700104void GrContext::DrawingMgr::reset() {
105 if (fDrawTarget) {
106 fDrawTarget->reset();
107 }
108}
109
110void GrContext::DrawingMgr::flush() {
111 if (fDrawTarget) {
112 fDrawTarget->flush();
113 }
114}
115
robertphillipsfcf78292015-06-19 11:49:52 -0700116GrDrawContext* GrContext::DrawingMgr::drawContext(const SkSurfaceProps* surfaceProps) {
robertphillipsea461502015-05-26 11:38:03 -0700117 if (this->abandoned()) {
118 return NULL;
119 }
robertphillips2334fb62015-06-17 05:43:33 -0700120
robertphillipsfcf78292015-06-19 11:49:52 -0700121 const SkSurfaceProps props(SkSurfacePropsCopyOrDefault(surfaceProps));
122
123 SkASSERT(props.pixelGeometry() < kNumPixelGeometries);
124 if (!fDrawContext[props.pixelGeometry()][props.isUseDistanceFieldFonts()]) {
125 fDrawContext[props.pixelGeometry()][props.isUseDistanceFieldFonts()] =
126 SkNEW_ARGS(GrDrawContext, (fContext, fDrawTarget, props));
robertphillips2334fb62015-06-17 05:43:33 -0700127 }
128
robertphillipsfcf78292015-06-19 11:49:52 -0700129 return fDrawContext[props.pixelGeometry()][props.isUseDistanceFieldFonts()];
robertphillipsea461502015-05-26 11:38:03 -0700130}
131
132////////////////////////////////////////////////////////////////////////////////
133
bsalomonf21dab92014-11-13 13:33:28 -0800134
bsalomon682c2692015-05-22 14:01:46 -0700135GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) {
136 GrContextOptions defaultOptions;
137 return Create(backend, backendContext, defaultOptions);
138}
bsalomonf28cff72015-05-22 12:25:41 -0700139
bsalomon682c2692015-05-22 14:01:46 -0700140GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext,
141 const GrContextOptions& options) {
142 GrContext* context = SkNEW(GrContext);
143
144 if (context->init(backend, backendContext, options)) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000145 return context;
146 } else {
147 context->unref();
148 return NULL;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000149 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000150}
151
joshualitt0acd0d32015-05-07 08:23:19 -0700152static int32_t gNextID = 1;
153static int32_t next_id() {
154 int32_t id;
155 do {
156 id = sk_atomic_inc(&gNextID);
157 } while (id == SK_InvalidGenID);
158 return id;
159}
160
bsalomon682c2692015-05-22 14:01:46 -0700161GrContext::GrContext() : fUniqueID(next_id()) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000162 fGpu = NULL;
bsalomon76228632015-05-29 08:02:10 -0700163 fCaps = NULL;
bsalomond309e7a2015-04-30 14:18:54 -0700164 fResourceCache = NULL;
165 fResourceProvider = NULL;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000166 fPathRendererChain = NULL;
167 fSoftwarePathRenderer = NULL;
joshualitt7c3a2f82015-03-31 13:32:05 -0700168 fBatchFontCache = NULL;
bsalomonf21dab92014-11-13 13:33:28 -0800169 fFlushToReduceCacheSize = false;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000170}
171
bsalomon682c2692015-05-22 14:01:46 -0700172bool GrContext::init(GrBackend backend, GrBackendContext backendContext,
173 const GrContextOptions& options) {
robertphillipsea461502015-05-26 11:38:03 -0700174 SkASSERT(!fGpu);
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000175
bsalomon682c2692015-05-22 14:01:46 -0700176 fGpu = GrGpu::Create(backend, backendContext, options, this);
robertphillipsea461502015-05-26 11:38:03 -0700177 if (!fGpu) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000178 return false;
179 }
bsalomon33435572014-11-05 14:47:41 -0800180 this->initCommon();
181 return true;
182}
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000183
bsalomon33435572014-11-05 14:47:41 -0800184void GrContext::initCommon() {
bsalomon76228632015-05-29 08:02:10 -0700185 fCaps = SkRef(fGpu->caps());
bsalomon0ea80f42015-02-11 10:49:59 -0800186 fResourceCache = SkNEW(GrResourceCache);
187 fResourceCache->setOverBudgetCallback(OverBudgetCB, this);
bsalomond309e7a2015-04-30 14:18:54 -0700188 fResourceProvider = SkNEW_ARGS(GrResourceProvider, (fGpu, fResourceCache));
commit-bot@chromium.org1836d332013-07-16 22:55:03 +0000189
robertphillips4ec84da2014-06-24 13:10:43 -0700190 fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this)));
robertphillips@google.come930a072014-04-03 00:34:27 +0000191
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000192 fDidTestPMConversions = false;
193
robertphillipsea461502015-05-26 11:38:03 -0700194 fDrawingMgr.init(this);
joshualitt7c3a2f82015-03-31 13:32:05 -0700195
196 // GrBatchFontCache will eventually replace GrFontCache
joshualitt62db8ba2015-04-09 08:22:37 -0700197 fBatchFontCache = SkNEW_ARGS(GrBatchFontCache, (this));
joshualittb7133be2015-04-08 09:08:31 -0700198
joshualitt0db6dfa2015-04-10 07:01:30 -0700199 fTextBlobCache.reset(SkNEW_ARGS(GrTextBlobCache, (TextBlobCacheOverBudgetCB, this)));
bsalomon@google.comc0af3172012-06-15 14:10:09 +0000200}
201
bsalomon@google.com27847de2011-02-22 20:59:41 +0000202GrContext::~GrContext() {
robertphillipsea461502015-05-26 11:38:03 -0700203 if (!fGpu) {
bsalomon76228632015-05-29 08:02:10 -0700204 SkASSERT(!fCaps);
bsalomon@google.com733c0622013-04-24 17:59:32 +0000205 return;
206 }
207
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000208 this->flush();
robertphillips@google.com5acc0e32012-05-17 12:01:02 +0000209
robertphillips2334fb62015-06-17 05:43:33 -0700210 fDrawingMgr.cleanup();
211
robertphillips@google.com950b1b02013-10-21 17:37:28 +0000212 for (int i = 0; i < fCleanUpData.count(); ++i) {
213 (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
214 }
215
bsalomond309e7a2015-04-30 14:18:54 -0700216 SkDELETE(fResourceProvider);
bsalomon0ea80f42015-02-11 10:49:59 -0800217 SkDELETE(fResourceCache);
joshualitt7c3a2f82015-03-31 13:32:05 -0700218 SkDELETE(fBatchFontCache);
robertphillips@google.comf6747b02012-06-12 00:32:28 +0000219
bsalomon@google.com205d4602011-04-25 12:43:45 +0000220 fGpu->unref();
bsalomon76228632015-05-29 08:02:10 -0700221 fCaps->unref();
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000222 SkSafeUnref(fPathRendererChain);
223 SkSafeUnref(fSoftwarePathRenderer);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000224}
225
bsalomon2354f842014-07-28 13:48:36 -0700226void GrContext::abandonContext() {
bsalomond309e7a2015-04-30 14:18:54 -0700227 fResourceProvider->abandon();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000228 // abandon first to so destructors
229 // don't try to free the resources in the API.
bsalomon0ea80f42015-02-11 10:49:59 -0800230 fResourceCache->abandonAll();
bsalomonc8dc1f72014-08-21 13:02:13 -0700231
robertphillipse3371302014-09-17 06:01:06 -0700232 fGpu->contextAbandoned();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000233
bsalomon@google.com30085192011-08-19 15:42:31 +0000234 // a path renderer may be holding onto resources that
235 // are now unusable
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000236 SkSafeSetNull(fPathRendererChain);
237 SkSafeSetNull(fSoftwarePathRenderer);
bsalomon@google.com30085192011-08-19 15:42:31 +0000238
robertphillipsea461502015-05-26 11:38:03 -0700239 fDrawingMgr.abandon();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000240
joshualitt7c3a2f82015-03-31 13:32:05 -0700241 fBatchFontCache->freeAll();
robertphillips@google.come930a072014-04-03 00:34:27 +0000242 fLayerCache->freeAll();
joshualitt26ffc002015-04-16 11:24:04 -0700243 fTextBlobCache->freeAll();
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000244}
245
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000246void GrContext::resetContext(uint32_t state) {
247 fGpu->markContextDirty(state);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000248}
249
250void GrContext::freeGpuResources() {
251 this->flush();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000252
robertphillipsea461502015-05-26 11:38:03 -0700253 fDrawingMgr.purgeResources();
robertphillips@google.comff175842012-05-14 19:31:39 +0000254
joshualitt7c3a2f82015-03-31 13:32:05 -0700255 fBatchFontCache->freeAll();
robertphillips@google.come930a072014-04-03 00:34:27 +0000256 fLayerCache->freeAll();
bsalomon@google.com30085192011-08-19 15:42:31 +0000257 // a path renderer may be holding onto resources
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000258 SkSafeSetNull(fPathRendererChain);
259 SkSafeSetNull(fSoftwarePathRenderer);
bsalomon3033b9f2015-04-13 11:09:56 -0700260
261 fResourceCache->purgeAllUnlocked();
bsalomon@google.com27847de2011-02-22 20:59:41 +0000262}
263
commit-bot@chromium.org95c20032014-05-09 14:29:32 +0000264void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
bsalomon71cb0c22014-11-14 12:10:14 -0800265 if (resourceCount) {
bsalomon0ea80f42015-02-11 10:49:59 -0800266 *resourceCount = fResourceCache->getBudgetedResourceCount();
bsalomon71cb0c22014-11-14 12:10:14 -0800267 }
268 if (resourceBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800269 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
bsalomon71cb0c22014-11-14 12:10:14 -0800270 }
commit-bot@chromium.orgd8a57af2014-03-19 21:19:16 +0000271}
272
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000273////////////////////////////////////////////////////////////////////////////////
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
joshualittb542bae2015-07-28 09:58:39 -0700280 // Flush the GrBufferedDrawTarget to possibly free up some textures
bsalomonf21dab92014-11-13 13:33:28 -0800281 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.com27847de2011-02-22 20:59:41 +0000295////////////////////////////////////////////////////////////////////////////////
296
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000297void GrContext::flush(int flagsBitfield) {
robertphillipsea461502015-05-26 11:38:03 -0700298 RETURN_IF_ABANDONED
robertphillips@google.come7db8d62013-07-04 11:48:52 +0000299
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000300 if (kDiscard_FlushBit & flagsBitfield) {
robertphillipsea461502015-05-26 11:38:03 -0700301 fDrawingMgr.reset();
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000302 } else {
robertphillipsea461502015-05-26 11:38:03 -0700303 fDrawingMgr.flush();
junov@google.com53a55842011-06-08 22:55:10 +0000304 }
bsalomon3f324322015-04-08 11:01:54 -0700305 fResourceCache->notifyFlushOccurred();
bsalomonf21dab92014-11-13 13:33:28 -0800306 fFlushToReduceCacheSize = false;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000307}
308
bsalomon81beccc2014-10-13 12:32:55 -0700309bool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes,
310 const void* inPixels, size_t outRowBytes, void* outPixels) {
311 SkSrcPixelInfo srcPI;
jvanverthfa1e8a72014-12-22 08:31:49 -0800312 if (!GrPixelConfig2ColorAndProfileType(srcConfig, &srcPI.fColorType, NULL)) {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000313 return false;
314 }
bsalomon81beccc2014-10-13 12:32:55 -0700315 srcPI.fAlphaType = kUnpremul_SkAlphaType;
316 srcPI.fPixels = inPixels;
317 srcPI.fRowBytes = inRowBytes;
318
319 SkDstPixelInfo dstPI;
320 dstPI.fColorType = srcPI.fColorType;
321 dstPI.fAlphaType = kPremul_SkAlphaType;
322 dstPI.fPixels = outPixels;
323 dstPI.fRowBytes = outRowBytes;
324
325 return srcPI.convertPixelsTo(&dstPI, width, height);
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000326}
327
bsalomon81beccc2014-10-13 12:32:55 -0700328bool GrContext::writeSurfacePixels(GrSurface* surface,
329 int left, int top, int width, int height,
330 GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
331 uint32_t pixelOpsFlags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800332 RETURN_FALSE_IF_ABANDONED
bsalomon81beccc2014-10-13 12:32:55 -0700333
bsalomone8d21e82015-07-16 08:23:13 -0700334 // 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 -0700335 // necessary and because GrGpu::getWritePixelsInfo requires it.
bsalomone8d21e82015-07-16 08:23:13 -0700336 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(),
337 GrBytesPerPixel(srcConfig), &left, &top, &width,
338 &height, &buffer, &rowBytes)) {
339 return false;
340 }
341
bsalomonf0674512015-07-28 13:26:15 -0700342 bool applyPremulToSrc = false;
bsalomon81beccc2014-10-13 12:32:55 -0700343 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
344 if (!GrPixelConfigIs8888(srcConfig)) {
345 return false;
346 }
bsalomonf0674512015-07-28 13:26:15 -0700347 applyPremulToSrc = true;
348 }
bsalomon636e8022015-07-29 06:08:46 -0700349
350 GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
351 // Don't prefer to draw for the conversion (and thereby access a texture from the cache) when
352 // we've already determined that there isn't a roundtrip preserving conversion processor pair.
353 if (applyPremulToSrc && !this->didFailPMUPMConversionTest()) {
354 drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference;
355 }
356
bsalomonf0674512015-07-28 13:26:15 -0700357 GrGpu::WritePixelTempDrawInfo tempDrawInfo;
358 if (!fGpu->getWritePixelsInfo(surface, width, height, rowBytes, srcConfig, &drawPreference,
359 &tempDrawInfo)) {
360 return false;
361 }
362
363 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) && surface->surfacePriv().hasPendingIO()) {
364 this->flush();
365 }
366
367 SkAutoTUnref<GrTexture> tempTexture;
368 if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
bsalomoneae62002015-07-31 13:59:30 -0700369 tempTexture.reset(
370 this->textureProvider()->createApproxTexture(tempDrawInfo.fTempSurfaceDesc));
bsalomonf0674512015-07-28 13:26:15 -0700371 if (!tempTexture && GrGpu::kRequireDraw_DrawPreference == drawPreference) {
372 return false;
373 }
374 }
375
376 // temp buffer for doing sw premul conversion, if needed.
377 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
378 if (tempTexture) {
379 SkAutoTUnref<const GrFragmentProcessor> fp;
380 SkMatrix textureMatrix;
381 textureMatrix.setIDiv(tempTexture->width(), tempTexture->height());
382 GrPaint paint;
383 if (applyPremulToSrc) {
384 fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), tempTexture,
385 tempDrawInfo.fSwapRAndB, textureMatrix));
386 // If premultiplying was the only reason for the draw, fall back to a straight write.
387 if (!fp) {
388 if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
389 tempTexture.reset(NULL);
390 }
391 } else {
392 applyPremulToSrc = false;
393 }
394 }
395 if (tempTexture) {
396 if (!fp) {
397 fp.reset(GrConfigConversionEffect::Create(
398 paint.getProcessorDataManager(), tempTexture, tempDrawInfo.fSwapRAndB,
399 GrConfigConversionEffect::kNone_PMConversion, textureMatrix));
400 if (!fp) {
401 return false;
402 }
403 }
404 GrRenderTarget* renderTarget = surface->asRenderTarget();
405 SkASSERT(renderTarget);
406 if (tempTexture->surfacePriv().hasPendingIO()) {
407 this->flush();
408 }
409 if (applyPremulToSrc) {
410 size_t tmpRowBytes = 4 * width;
411 tmpPixels.reset(width * height);
412 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
413 tmpPixels.get())) {
414 return false;
415 }
416 rowBytes = tmpRowBytes;
417 buffer = tmpPixels.get();
418 applyPremulToSrc = false;
419 }
bsalomon6cb3cbe2015-07-30 07:34:27 -0700420 if (!fGpu->writePixels(tempTexture, 0, 0, width, height,
421 tempDrawInfo.fTempSurfaceDesc.fConfig, buffer,
422 rowBytes)) {
bsalomonf0674512015-07-28 13:26:15 -0700423 return false;
424 }
425 SkMatrix matrix;
426 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
427 GrDrawContext* drawContext = this->drawContext();
428 if (!drawContext) {
429 return false;
430 }
431 paint.addColorProcessor(fp);
432 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
433 drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, matrix, rect, NULL);
434
435 if (kFlushWrites_PixelOp & pixelOpsFlags) {
436 this->flushSurfaceWrites(surface);
437 }
438 }
439 }
440 if (!tempTexture) {
bsalomonf0674512015-07-28 13:26:15 -0700441 if (applyPremulToSrc) {
bsalomon81beccc2014-10-13 12:32:55 -0700442 size_t tmpRowBytes = 4 * width;
443 tmpPixels.reset(width * height);
444 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
445 tmpPixels.get())) {
446 return false;
447 }
448 rowBytes = tmpRowBytes;
449 buffer = tmpPixels.get();
bsalomonf0674512015-07-28 13:26:15 -0700450 applyPremulToSrc = false;
bsalomon81beccc2014-10-13 12:32:55 -0700451 }
bsalomon6cb3cbe2015-07-30 07:34:27 -0700452 return fGpu->writePixels(surface, left, top, width, height, srcConfig, buffer, rowBytes);
bsalomon81beccc2014-10-13 12:32:55 -0700453 }
bsalomon81beccc2014-10-13 12:32:55 -0700454 return true;
455}
bsalomon@google.coma91e9232012-02-23 15:39:54 +0000456
bsalomone8d21e82015-07-16 08:23:13 -0700457bool GrContext::readSurfacePixels(GrSurface* src,
458 int left, int top, int width, int height,
459 GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
460 uint32_t flags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800461 RETURN_FALSE_IF_ABANDONED
bsalomone8d21e82015-07-16 08:23:13 -0700462 ASSERT_OWNED_RESOURCE(src);
463 SkASSERT(src);
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000464
bsalomone8d21e82015-07-16 08:23:13 -0700465 // Adjust the params so that if we wind up using an intermediate surface we've already done
466 // all the trimming and the temporary can be the min size required.
467 if (!GrSurfacePriv::AdjustReadPixelParams(src->width(), src->height(),
468 GrBytesPerPixel(dstConfig), &left,
469 &top, &width, &height, &buffer, &rowBytes)) {
470 return false;
471 }
472
473 if (!(kDontFlush_PixelOpsFlag & flags) && src->surfacePriv().hasPendingWrite()) {
bsalomon@google.com6f379512011-11-16 20:36:03 +0000474 this->flush();
475 }
bsalomon@google.comc4364992011-11-07 15:54:49 +0000476
bsalomone8d21e82015-07-16 08:23:13 -0700477 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
bsalomon@google.com9c680582013-02-06 18:17:50 +0000478 if (unpremul && !GrPixelConfigIs8888(dstConfig)) {
bsalomon39826022015-07-23 08:07:21 -0700479 // The unpremul flag is only allowed for 8888 configs.
bsalomon@google.com0a97be22011-11-08 19:20:57 +0000480 return false;
481 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000482
bsalomon636e8022015-07-29 06:08:46 -0700483 GrGpu::DrawPreference drawPreference = GrGpu::kNoDraw_DrawPreference;
484 // Don't prefer to draw for the conversion (and thereby access a texture from the cache) when
485 // we've already determined that there isn't a roundtrip preserving conversion processor pair.
486 if (unpremul && !this->didFailPMUPMConversionTest()) {
487 drawPreference = GrGpu::kCallerPrefersDraw_DrawPreference;
488 }
489
bsalomon39826022015-07-23 08:07:21 -0700490 GrGpu::ReadPixelTempDrawInfo tempDrawInfo;
491 if (!fGpu->getReadPixelsInfo(src, width, height, rowBytes, dstConfig, &drawPreference,
492 &tempDrawInfo)) {
493 return false;
494 }
bsalomon191bcc02014-11-14 11:31:13 -0800495
bsalomon6cb3cbe2015-07-30 07:34:27 -0700496 SkAutoTUnref<GrSurface> surfaceToRead(SkRef(src));
bsalomon39826022015-07-23 08:07:21 -0700497 bool didTempDraw = false;
498 if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
bsalomon39826022015-07-23 08:07:21 -0700499 if (tempDrawInfo.fUseExactScratch) {
500 // We only respect this when the entire src is being read. Otherwise we can trigger too
501 // many odd ball texture sizes and trash the cache.
bsalomoneae62002015-07-31 13:59:30 -0700502 if (width != src->width() || height != src->height()) {
503 tempDrawInfo.fUseExactScratch = false;
bsalomon39826022015-07-23 08:07:21 -0700504 }
bsalomon@google.com56d11e02011-11-30 19:59:08 +0000505 }
bsalomon39826022015-07-23 08:07:21 -0700506 SkAutoTUnref<GrTexture> temp;
bsalomoneae62002015-07-31 13:59:30 -0700507 if (tempDrawInfo.fUseExactScratch) {
508 temp.reset(this->textureProvider()->createTexture(tempDrawInfo.fTempSurfaceDesc, true));
509 } else {
510 temp.reset(this->textureProvider()->createApproxTexture(tempDrawInfo.fTempSurfaceDesc));
511 }
bsalomon39826022015-07-23 08:07:21 -0700512 if (temp) {
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000513 SkMatrix textureMatrix;
bsalomon39826022015-07-23 08:07:21 -0700514 textureMatrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000515 textureMatrix.postIDiv(src->width(), src->height());
joshualitt5f10b5c2015-07-09 10:24:35 -0700516 GrPaint paint;
joshualittb0a8a372014-09-23 09:50:21 -0700517 SkAutoTUnref<const GrFragmentProcessor> fp;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000518 if (unpremul) {
bsalomon39826022015-07-23 08:07:21 -0700519 fp.reset(this->createPMToUPMEffect(
520 paint.getProcessorDataManager(), src->asTexture(), tempDrawInfo.fSwapRAndB,
521 textureMatrix));
joshualittb0a8a372014-09-23 09:50:21 -0700522 if (fp) {
bsalomon@google.com9c680582013-02-06 18:17:50 +0000523 unpremul = false; // we no longer need to do this on CPU after the read back.
bsalomon39826022015-07-23 08:07:21 -0700524 } else if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
525 // We only wanted to do the draw in order to perform the unpremul so don't
526 // bother.
527 temp.reset(NULL);
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000528 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000529 }
bsalomon39826022015-07-23 08:07:21 -0700530 if (!fp && temp) {
531 fp.reset(GrConfigConversionEffect::Create(
532 paint.getProcessorDataManager(), src->asTexture(), tempDrawInfo.fSwapRAndB,
533 GrConfigConversionEffect::kNone_PMConversion, textureMatrix));
534 }
535 if (fp) {
536 paint.addColorProcessor(fp);
537 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
538 GrDrawContext* drawContext = this->drawContext();
539 drawContext->drawRect(temp->asRenderTarget(), GrClip::WideOpen(), paint,
540 SkMatrix::I(), rect, NULL);
bsalomon6cb3cbe2015-07-30 07:34:27 -0700541 surfaceToRead.reset(SkRef(temp.get()));
bsalomon39826022015-07-23 08:07:21 -0700542 left = 0;
543 top = 0;
544 didTempDraw = true;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000545 }
bsalomon@google.com0342a852012-08-20 19:22:38 +0000546 }
bsalomon@google.comc4364992011-11-07 15:54:49 +0000547 }
joshualitt5c55fef2014-10-31 14:04:35 -0700548
bsalomon39826022015-07-23 08:07:21 -0700549 if (GrGpu::kRequireDraw_DrawPreference == drawPreference && !didTempDraw) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000550 return false;
551 }
bsalomon39826022015-07-23 08:07:21 -0700552 GrPixelConfig configToRead = dstConfig;
553 if (didTempDraw) {
bsalomon6cb3cbe2015-07-30 07:34:27 -0700554 this->flushSurfaceWrites(surfaceToRead);
bsalomon39826022015-07-23 08:07:21 -0700555 // We swapped R and B while doing the temp draw. Swap back on the read.
556 if (tempDrawInfo.fSwapRAndB) {
557 configToRead = GrPixelConfigSwapRAndB(dstConfig);
558 }
559 }
bsalomon6cb3cbe2015-07-30 07:34:27 -0700560 if (!fGpu->readPixels(surfaceToRead, left, top, width, height, configToRead, buffer,
561 rowBytes)) {
bsalomon39826022015-07-23 08:07:21 -0700562 return false;
563 }
564
565 // Perform umpremul conversion if we weren't able to perform it as a draw.
566 if (unpremul) {
reed@google.com7111d462014-03-25 16:20:24 +0000567 SkDstPixelInfo dstPI;
jvanverthfa1e8a72014-12-22 08:31:49 -0800568 if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, NULL)) {
reed@google.com7111d462014-03-25 16:20:24 +0000569 return false;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000570 }
reed@google.com7111d462014-03-25 16:20:24 +0000571 dstPI.fAlphaType = kUnpremul_SkAlphaType;
572 dstPI.fPixels = buffer;
573 dstPI.fRowBytes = rowBytes;
574
575 SkSrcPixelInfo srcPI;
bsalomon39826022015-07-23 08:07:21 -0700576 srcPI.fColorType = dstPI.fColorType;
reed@google.com7111d462014-03-25 16:20:24 +0000577 srcPI.fAlphaType = kPremul_SkAlphaType;
578 srcPI.fPixels = buffer;
579 srcPI.fRowBytes = rowBytes;
580
581 return srcPI.convertPixelsTo(&dstPI, width, height);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000582 }
583 return true;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000584}
585
bsalomonc49e8682015-06-30 11:37:35 -0700586void GrContext::prepareSurfaceForExternalIO(GrSurface* surface) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800587 RETURN_IF_ABANDONED
bsalomon87a94eb2014-11-03 14:28:32 -0800588 SkASSERT(surface);
589 ASSERT_OWNED_RESOURCE(surface);
590 if (surface->surfacePriv().hasPendingIO()) {
591 this->flush();
592 }
593 GrRenderTarget* rt = surface->asRenderTarget();
594 if (fGpu && rt) {
595 fGpu->resolveRenderTarget(rt);
bsalomon41ebbdd2014-08-04 08:31:39 -0700596 }
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000597}
598
bsalomonf80bfed2014-10-07 05:56:02 -0700599void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
600 const SkIPoint& dstPoint, uint32_t pixelOpsFlags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800601 RETURN_IF_ABANDONED
robertphillipsea461502015-05-26 11:38:03 -0700602 if (!src || !dst) {
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000603 return;
604 }
bsalomone3d4bf22014-09-23 09:15:03 -0700605 ASSERT_OWNED_RESOURCE(src);
junov2bb52102014-09-29 10:18:59 -0700606 ASSERT_OWNED_RESOURCE(dst);
Brian Salomon34a98952014-09-24 11:41:24 -0400607
bsalomonf80bfed2014-10-07 05:56:02 -0700608 // Since we're going to the draw target and not GPU, no need to check kNoFlush
609 // here.
robertphillipsea461502015-05-26 11:38:03 -0700610 if (!dst->asRenderTarget()) {
junov96c118e2014-09-26 13:09:47 -0700611 return;
612 }
robertphillipsea461502015-05-26 11:38:03 -0700613
614 GrDrawContext* drawContext = this->drawContext();
615 if (!drawContext) {
616 return;
617 }
618
619 drawContext->copySurface(dst->asRenderTarget(), src, srcRect, dstPoint);
bsalomonf80bfed2014-10-07 05:56:02 -0700620
621 if (kFlushWrites_PixelOp & pixelOpsFlags) {
622 this->flush();
623 }
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000624}
625
bsalomonf80bfed2014-10-07 05:56:02 -0700626void GrContext::flushSurfaceWrites(GrSurface* surface) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800627 RETURN_IF_ABANDONED
bsalomonf80bfed2014-10-07 05:56:02 -0700628 if (surface->surfacePriv().hasPendingWrite()) {
629 this->flush();
630 }
631}
632
robertphillips@google.com72176b22012-05-23 13:19:12 +0000633/*
634 * This method finds a path renderer that can draw the specified path on
635 * the provided target.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000636 * Due to its expense, the software path renderer has split out so it can
robertphillips@google.com72176b22012-05-23 13:19:12 +0000637 * can be individually allowed/disallowed via the "allowSW" boolean.
638 */
joshualitt9853cce2014-11-17 14:22:48 -0800639GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
egdaniel8dd688b2015-01-22 10:16:09 -0800640 const GrPipelineBuilder* pipelineBuilder,
joshualitt8059eb92014-12-29 15:10:07 -0800641 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800642 const SkPath& path,
kkinnunen18996512015-04-26 23:18:49 -0700643 const GrStrokeInfo& stroke,
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000644 bool allowSW,
645 GrPathRendererChain::DrawType drawType,
646 GrPathRendererChain::StencilSupport* stencilSupport) {
647
robertphillipsea461502015-05-26 11:38:03 -0700648 if (!fPathRendererChain) {
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000649 fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this));
bsalomon@google.com30085192011-08-19 15:42:31 +0000650 }
robertphillips@google.com72176b22012-05-23 13:19:12 +0000651
joshualitt9853cce2014-11-17 14:22:48 -0800652 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target,
egdaniel8dd688b2015-01-22 10:16:09 -0800653 pipelineBuilder,
joshualitt8059eb92014-12-29 15:10:07 -0800654 viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800655 path,
sugoi@google.com12b4e272012-12-06 20:13:11 +0000656 stroke,
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000657 drawType,
658 stencilSupport);
robertphillips@google.com72176b22012-05-23 13:19:12 +0000659
robertphillipsea461502015-05-26 11:38:03 -0700660 if (!pr && allowSW) {
661 if (!fSoftwarePathRenderer) {
tomhudson@google.comc377baf2012-07-09 20:17:56 +0000662 fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this));
robertphillips@google.com72176b22012-05-23 13:19:12 +0000663 }
robertphillips@google.com72176b22012-05-23 13:19:12 +0000664 pr = fSoftwarePathRenderer;
665 }
666
667 return pr;
bsalomon@google.com30085192011-08-19 15:42:31 +0000668}
669
bsalomon@google.com27847de2011-02-22 20:59:41 +0000670////////////////////////////////////////////////////////////////////////////////
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000671int GrContext::getRecommendedSampleCount(GrPixelConfig config,
672 SkScalar dpi) const {
bsalomon76228632015-05-29 08:02:10 -0700673 if (!this->caps()->isConfigRenderable(config, true)) {
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000674 return 0;
675 }
676 int chosenSampleCount = 0;
jvanverthe9c0fc62015-04-29 11:18:05 -0700677 if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) {
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000678 if (dpi >= 250.0f) {
679 chosenSampleCount = 4;
680 } else {
681 chosenSampleCount = 16;
682 }
683 }
684 return chosenSampleCount <= fGpu->caps()->maxSampleCount() ?
685 chosenSampleCount : 0;
686}
687
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000688namespace {
689void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) {
690 GrConfigConversionEffect::PMConversion pmToUPM;
691 GrConfigConversionEffect::PMConversion upmToPM;
692 GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM);
693 *pmToUPMValue = pmToUPM;
694 *upmToPMValue = upmToPM;
695}
696}
697
joshualitt5f10b5c2015-07-09 10:24:35 -0700698const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrProcessorDataManager* procDataManager,
699 GrTexture* texture,
joshualittb0a8a372014-09-23 09:50:21 -0700700 bool swapRAndB,
701 const SkMatrix& matrix) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000702 if (!fDidTestPMConversions) {
703 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
bsalomon@google.comd0f3f682012-08-28 13:08:14 +0000704 fDidTestPMConversions = true;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000705 }
706 GrConfigConversionEffect::PMConversion pmToUPM =
707 static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
708 if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
joshualitt5f10b5c2015-07-09 10:24:35 -0700709 return GrConfigConversionEffect::Create(procDataManager, texture, swapRAndB, pmToUPM,
710 matrix);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000711 } else {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000712 return NULL;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000713 }
714}
715
joshualitt5f10b5c2015-07-09 10:24:35 -0700716const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrProcessorDataManager* procDataManager,
717 GrTexture* texture,
joshualittb0a8a372014-09-23 09:50:21 -0700718 bool swapRAndB,
719 const SkMatrix& matrix) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000720 if (!fDidTestPMConversions) {
721 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
bsalomon@google.comd0f3f682012-08-28 13:08:14 +0000722 fDidTestPMConversions = true;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000723 }
724 GrConfigConversionEffect::PMConversion upmToPM =
725 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
726 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
joshualitt5f10b5c2015-07-09 10:24:35 -0700727 return GrConfigConversionEffect::Create(procDataManager, texture, swapRAndB, upmToPM,
728 matrix);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000729 } else {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000730 return NULL;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000731 }
732}
733
bsalomon636e8022015-07-29 06:08:46 -0700734bool GrContext::didFailPMUPMConversionTest() const {
735 // The PM<->UPM tests fail or succeed together so we only need to check one.
736 return fDidTestPMConversions &&
737 GrConfigConversionEffect::kNone_PMConversion == fPMToUPMConversion;
738}
739
bsalomon37f9a262015-02-02 13:00:10 -0800740//////////////////////////////////////////////////////////////////////////////
741
742void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const {
743 if (maxTextures) {
bsalomon0ea80f42015-02-11 10:49:59 -0800744 *maxTextures = fResourceCache->getMaxResourceCount();
bsalomon37f9a262015-02-02 13:00:10 -0800745 }
746 if (maxTextureBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800747 *maxTextureBytes = fResourceCache->getMaxResourceBytes();
bsalomon37f9a262015-02-02 13:00:10 -0800748 }
749}
750
751void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800752 fResourceCache->setLimits(maxTextures, maxTextureBytes);
bsalomon37f9a262015-02-02 13:00:10 -0800753}
754
bsalomon37f9a262015-02-02 13:00:10 -0800755//////////////////////////////////////////////////////////////////////////////
756
egdanielbbcb38d2014-06-19 10:19:29 -0700757void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
758 fGpu->addGpuTraceMarker(marker);
egdanielbbcb38d2014-06-19 10:19:29 -0700759}
760
761void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
762 fGpu->removeGpuTraceMarker(marker);
egdanielbbcb38d2014-06-19 10:19:29 -0700763}
joshualitte5902662015-05-11 08:18:35 -0700764