blob: ba02d60b11ece81231086a890d33214dc03e3601 [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"
joshualitt0823bfa2015-02-27 10:06:15 -080012#include "GrBatch.h"
joshualitt7c3a2f82015-03-31 13:32:05 -070013#include "GrBatchFontCache.h"
joshualitt0823bfa2015-02-27 10:06:15 -080014#include "GrBatchTarget.h"
joshualitte5902662015-05-11 08:18:35 -070015#include "GrBatchTest.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"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000025#include "GrInOrderDrawBuffer.h"
robertphillips@google.come930a072014-04-03 00:34:27 +000026#include "GrLayerCache.h"
commit-bot@chromium.org81312832013-03-22 18:34:09 +000027#include "GrOvalRenderer.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000028#include "GrPathRenderer.h"
tomhudson@google.comd22b6e42011-06-24 15:53:40 +000029#include "GrPathUtils.h"
bsalomon6bc1b5f2015-02-23 09:06:38 -080030#include "GrRenderTargetPriv.h"
bsalomon0ea80f42015-02-11 10:49:59 -080031#include "GrResourceCache.h"
bsalomond309e7a2015-04-30 14:18:54 -070032#include "GrResourceProvider.h"
robertphillips@google.com72176b22012-05-23 13:19:12 +000033#include "GrSoftwarePathRenderer.h"
egdanield58a0ba2014-06-11 10:30:05 -070034#include "GrStrokeInfo.h"
bsalomonafbf2d62014-09-30 12:18:44 -070035#include "GrSurfacePriv.h"
joshualittb7133be2015-04-08 09:08:31 -070036#include "GrTextBlobCache.h"
bsalomonafbf2d62014-09-30 12:18:44 -070037#include "GrTexturePriv.h"
egdanielbbcb38d2014-06-19 10:19:29 -070038#include "GrTraceMarker.h"
commit-bot@chromium.org2a05de02014-03-25 15:17:32 +000039#include "GrTracing.h"
bsalomoncb8979d2015-05-05 09:51:38 -070040#include "GrVertices.h"
egdanield58a0ba2014-06-11 10:30:05 -070041#include "SkDashPathPriv.h"
bsalomon81beccc2014-10-13 12:32:55 -070042#include "SkConfig8888.h"
reed@google.com7111d462014-03-25 16:20:24 +000043#include "SkGr.h"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000044#include "SkRRect.h"
sugoi@google.com5f74cf82012-12-17 21:16:45 +000045#include "SkStrokeRec.h"
robertphillipsfcf78292015-06-19 11:49:52 -070046#include "SkSurfacePriv.h"
commit-bot@chromium.orgdcb8ef92014-03-27 11:26:10 +000047#include "SkTLazy.h"
commit-bot@chromium.org47841822014-03-27 14:19:17 +000048#include "SkTLS.h"
commit-bot@chromium.org933e65d2014-03-20 20:00:24 +000049#include "SkTraceEvent.h"
bsalomon@google.com27847de2011-02-22 20:59:41 +000050
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; }
58#define RETURN_NULL_IF_ABANDONED if (fDrawingMgr.abandoned()) { return NULL; }
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;
65
robertphillipsea461502015-05-26 11:38:03 -070066#ifdef IMMEDIATE_MODE
67 fDrawTarget = SkNEW_ARGS(GrImmediateDrawTarget, (context));
68#else
69 fDrawTarget = SkNEW_ARGS(GrInOrderDrawBuffer, (context));
70#endif
robertphillips2334fb62015-06-17 05:43:33 -070071}
bsalomon781d5822015-06-16 15:03:11 -070072
robertphillips2334fb62015-06-17 05:43:33 -070073void GrContext::DrawingMgr::cleanup() {
74 SkSafeSetNull(fDrawTarget);
75 for (int i = 0; i < kNumPixelGeometries; ++i) {
76 SkSafeSetNull(fDrawContext[i][0]);
77 SkSafeSetNull(fDrawContext[i][1]);
78 }
robertphillipsea461502015-05-26 11:38:03 -070079}
80
81GrContext::DrawingMgr::~DrawingMgr() {
robertphillips2334fb62015-06-17 05:43:33 -070082 this->cleanup();
robertphillipsea461502015-05-26 11:38:03 -070083}
84
85void GrContext::DrawingMgr::abandon() {
86 SkSafeSetNull(fDrawTarget);
robertphillips2334fb62015-06-17 05:43:33 -070087 for (int i = 0; i < kNumPixelGeometries; ++i) {
88 for (int j = 0; j < kNumDFTOptions; ++j) {
89 if (fDrawContext[i][j]) {
90 SkSafeSetNull(fDrawContext[i][j]->fDrawTarget);
91 SkSafeSetNull(fDrawContext[i][j]);
92 }
93 }
94 }
robertphillipsea461502015-05-26 11:38:03 -070095}
96
97void GrContext::DrawingMgr::purgeResources() {
98 if (fDrawTarget) {
99 fDrawTarget->purgeResources();
bsalomonf21dab92014-11-13 13:33:28 -0800100 }
robertphillipsea461502015-05-26 11:38:03 -0700101}
bsalomonf21dab92014-11-13 13:33:28 -0800102
robertphillipsea461502015-05-26 11:38:03 -0700103void GrContext::DrawingMgr::reset() {
104 if (fDrawTarget) {
105 fDrawTarget->reset();
106 }
107}
108
109void GrContext::DrawingMgr::flush() {
110 if (fDrawTarget) {
111 fDrawTarget->flush();
112 }
113}
114
robertphillipsfcf78292015-06-19 11:49:52 -0700115GrDrawContext* GrContext::DrawingMgr::drawContext(const SkSurfaceProps* surfaceProps) {
robertphillipsea461502015-05-26 11:38:03 -0700116 if (this->abandoned()) {
117 return NULL;
118 }
robertphillips2334fb62015-06-17 05:43:33 -0700119
robertphillipsfcf78292015-06-19 11:49:52 -0700120 const SkSurfaceProps props(SkSurfacePropsCopyOrDefault(surfaceProps));
121
122 SkASSERT(props.pixelGeometry() < kNumPixelGeometries);
123 if (!fDrawContext[props.pixelGeometry()][props.isUseDistanceFieldFonts()]) {
124 fDrawContext[props.pixelGeometry()][props.isUseDistanceFieldFonts()] =
125 SkNEW_ARGS(GrDrawContext, (fContext, fDrawTarget, props));
robertphillips2334fb62015-06-17 05:43:33 -0700126 }
127
robertphillipsfcf78292015-06-19 11:49:52 -0700128 return fDrawContext[props.pixelGeometry()][props.isUseDistanceFieldFonts()];
robertphillipsea461502015-05-26 11:38:03 -0700129}
130
131////////////////////////////////////////////////////////////////////////////////
132
bsalomonf21dab92014-11-13 13:33:28 -0800133
bsalomon682c2692015-05-22 14:01:46 -0700134GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext) {
135 GrContextOptions defaultOptions;
136 return Create(backend, backendContext, defaultOptions);
137}
bsalomonf28cff72015-05-22 12:25:41 -0700138
bsalomon682c2692015-05-22 14:01:46 -0700139GrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext,
140 const GrContextOptions& options) {
141 GrContext* context = SkNEW(GrContext);
142
143 if (context->init(backend, backendContext, options)) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000144 return context;
145 } else {
146 context->unref();
147 return NULL;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000148 }
bsalomon@google.com27847de2011-02-22 20:59:41 +0000149}
150
joshualitt0acd0d32015-05-07 08:23:19 -0700151static int32_t gNextID = 1;
152static int32_t next_id() {
153 int32_t id;
154 do {
155 id = sk_atomic_inc(&gNextID);
156 } while (id == SK_InvalidGenID);
157 return id;
158}
159
bsalomon682c2692015-05-22 14:01:46 -0700160GrContext::GrContext() : fUniqueID(next_id()) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000161 fGpu = NULL;
bsalomon76228632015-05-29 08:02:10 -0700162 fCaps = NULL;
bsalomond309e7a2015-04-30 14:18:54 -0700163 fResourceCache = NULL;
164 fResourceProvider = NULL;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000165 fPathRendererChain = NULL;
166 fSoftwarePathRenderer = NULL;
joshualitt7c3a2f82015-03-31 13:32:05 -0700167 fBatchFontCache = NULL;
bsalomonf21dab92014-11-13 13:33:28 -0800168 fFlushToReduceCacheSize = false;
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000169}
170
bsalomon682c2692015-05-22 14:01:46 -0700171bool GrContext::init(GrBackend backend, GrBackendContext backendContext,
172 const GrContextOptions& options) {
robertphillipsea461502015-05-26 11:38:03 -0700173 SkASSERT(!fGpu);
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000174
bsalomon682c2692015-05-22 14:01:46 -0700175 fGpu = GrGpu::Create(backend, backendContext, options, this);
robertphillipsea461502015-05-26 11:38:03 -0700176 if (!fGpu) {
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000177 return false;
178 }
bsalomon33435572014-11-05 14:47:41 -0800179 this->initCommon();
180 return true;
181}
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000182
bsalomon33435572014-11-05 14:47:41 -0800183void GrContext::initCommon() {
bsalomon76228632015-05-29 08:02:10 -0700184 fCaps = SkRef(fGpu->caps());
bsalomon0ea80f42015-02-11 10:49:59 -0800185 fResourceCache = SkNEW(GrResourceCache);
186 fResourceCache->setOverBudgetCallback(OverBudgetCB, this);
bsalomond309e7a2015-04-30 14:18:54 -0700187 fResourceProvider = SkNEW_ARGS(GrResourceProvider, (fGpu, fResourceCache));
commit-bot@chromium.org1836d332013-07-16 22:55:03 +0000188
robertphillips4ec84da2014-06-24 13:10:43 -0700189 fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this)));
robertphillips@google.come930a072014-04-03 00:34:27 +0000190
bsalomon@google.com6e4e6502013-02-25 20:12:45 +0000191 fDidTestPMConversions = false;
192
robertphillipsea461502015-05-26 11:38:03 -0700193 fDrawingMgr.init(this);
joshualitt7c3a2f82015-03-31 13:32:05 -0700194
195 // GrBatchFontCache will eventually replace GrFontCache
joshualitt62db8ba2015-04-09 08:22:37 -0700196 fBatchFontCache = SkNEW_ARGS(GrBatchFontCache, (this));
joshualittb7133be2015-04-08 09:08:31 -0700197
joshualitt0db6dfa2015-04-10 07:01:30 -0700198 fTextBlobCache.reset(SkNEW_ARGS(GrTextBlobCache, (TextBlobCacheOverBudgetCB, this)));
bsalomon@google.comc0af3172012-06-15 14:10:09 +0000199}
200
bsalomon@google.com27847de2011-02-22 20:59:41 +0000201GrContext::~GrContext() {
robertphillipsea461502015-05-26 11:38:03 -0700202 if (!fGpu) {
bsalomon76228632015-05-29 08:02:10 -0700203 SkASSERT(!fCaps);
bsalomon@google.com733c0622013-04-24 17:59:32 +0000204 return;
205 }
206
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000207 this->flush();
robertphillips@google.com5acc0e32012-05-17 12:01:02 +0000208
robertphillips2334fb62015-06-17 05:43:33 -0700209 fDrawingMgr.cleanup();
210
robertphillips@google.com950b1b02013-10-21 17:37:28 +0000211 for (int i = 0; i < fCleanUpData.count(); ++i) {
212 (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
213 }
214
bsalomond309e7a2015-04-30 14:18:54 -0700215 SkDELETE(fResourceProvider);
bsalomon0ea80f42015-02-11 10:49:59 -0800216 SkDELETE(fResourceCache);
joshualitt7c3a2f82015-03-31 13:32:05 -0700217 SkDELETE(fBatchFontCache);
robertphillips@google.comf6747b02012-06-12 00:32:28 +0000218
bsalomon@google.com205d4602011-04-25 12:43:45 +0000219 fGpu->unref();
bsalomon76228632015-05-29 08:02:10 -0700220 fCaps->unref();
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000221 SkSafeUnref(fPathRendererChain);
222 SkSafeUnref(fSoftwarePathRenderer);
bsalomon@google.com27847de2011-02-22 20:59:41 +0000223}
224
bsalomon2354f842014-07-28 13:48:36 -0700225void GrContext::abandonContext() {
bsalomond309e7a2015-04-30 14:18:54 -0700226 fResourceProvider->abandon();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000227 // abandon first to so destructors
228 // don't try to free the resources in the API.
bsalomon0ea80f42015-02-11 10:49:59 -0800229 fResourceCache->abandonAll();
bsalomonc8dc1f72014-08-21 13:02:13 -0700230
robertphillipse3371302014-09-17 06:01:06 -0700231 fGpu->contextAbandoned();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000232
bsalomon@google.com30085192011-08-19 15:42:31 +0000233 // a path renderer may be holding onto resources that
234 // are now unusable
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000235 SkSafeSetNull(fPathRendererChain);
236 SkSafeSetNull(fSoftwarePathRenderer);
bsalomon@google.com30085192011-08-19 15:42:31 +0000237
robertphillipsea461502015-05-26 11:38:03 -0700238 fDrawingMgr.abandon();
bsalomon@google.com205d4602011-04-25 12:43:45 +0000239
joshualitt7c3a2f82015-03-31 13:32:05 -0700240 fBatchFontCache->freeAll();
robertphillips@google.come930a072014-04-03 00:34:27 +0000241 fLayerCache->freeAll();
joshualitt26ffc002015-04-16 11:24:04 -0700242 fTextBlobCache->freeAll();
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000243}
244
bsalomon@google.com0a208a12013-06-28 18:57:35 +0000245void GrContext::resetContext(uint32_t state) {
246 fGpu->markContextDirty(state);
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000247}
248
249void GrContext::freeGpuResources() {
250 this->flush();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000251
robertphillipsea461502015-05-26 11:38:03 -0700252 fDrawingMgr.purgeResources();
robertphillips@google.comff175842012-05-14 19:31:39 +0000253
joshualitt7c3a2f82015-03-31 13:32:05 -0700254 fBatchFontCache->freeAll();
robertphillips@google.come930a072014-04-03 00:34:27 +0000255 fLayerCache->freeAll();
bsalomon@google.com30085192011-08-19 15:42:31 +0000256 // a path renderer may be holding onto resources
commit-bot@chromium.orga4de8c22013-09-09 13:38:37 +0000257 SkSafeSetNull(fPathRendererChain);
258 SkSafeSetNull(fSoftwarePathRenderer);
bsalomon3033b9f2015-04-13 11:09:56 -0700259
260 fResourceCache->purgeAllUnlocked();
bsalomon@google.com27847de2011-02-22 20:59:41 +0000261}
262
commit-bot@chromium.org95c20032014-05-09 14:29:32 +0000263void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
bsalomon71cb0c22014-11-14 12:10:14 -0800264 if (resourceCount) {
bsalomon0ea80f42015-02-11 10:49:59 -0800265 *resourceCount = fResourceCache->getBudgetedResourceCount();
bsalomon71cb0c22014-11-14 12:10:14 -0800266 }
267 if (resourceBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800268 *resourceBytes = fResourceCache->getBudgetedResourceBytes();
bsalomon71cb0c22014-11-14 12:10:14 -0800269 }
commit-bot@chromium.orgd8a57af2014-03-19 21:19:16 +0000270}
271
bsalomon@google.comfea37b52011-04-25 15:51:06 +0000272////////////////////////////////////////////////////////////////////////////////
273
bsalomon71cb0c22014-11-14 12:10:14 -0800274void GrContext::OverBudgetCB(void* data) {
bsalomon66a450f2014-11-13 13:19:10 -0800275 SkASSERT(data);
bsalomonf21dab92014-11-13 13:33:28 -0800276
bsalomon66a450f2014-11-13 13:19:10 -0800277 GrContext* context = reinterpret_cast<GrContext*>(data);
bsalomonf21dab92014-11-13 13:33:28 -0800278
279 // Flush the InOrderDrawBuffer to possibly free up some textures
280 context->fFlushToReduceCacheSize = true;
commit-bot@chromium.orgcae27fe2013-07-10 10:14:35 +0000281}
282
joshualitt0db6dfa2015-04-10 07:01:30 -0700283void GrContext::TextBlobCacheOverBudgetCB(void* data) {
284 SkASSERT(data);
285
286 // Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they
287 // cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush. The solution is to move
288 // drawText calls to below the GrContext level, but this is not trivial because they call
289 // drawPath on SkGpuDevice
290 GrContext* context = reinterpret_cast<GrContext*>(data);
291 context->flush();
292}
293
bsalomon@google.com27847de2011-02-22 20:59:41 +0000294////////////////////////////////////////////////////////////////////////////////
295
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000296void GrContext::flush(int flagsBitfield) {
robertphillipsea461502015-05-26 11:38:03 -0700297 RETURN_IF_ABANDONED
robertphillips@google.come7db8d62013-07-04 11:48:52 +0000298
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000299 if (kDiscard_FlushBit & flagsBitfield) {
robertphillipsea461502015-05-26 11:38:03 -0700300 fDrawingMgr.reset();
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000301 } else {
robertphillipsea461502015-05-26 11:38:03 -0700302 fDrawingMgr.flush();
junov@google.com53a55842011-06-08 22:55:10 +0000303 }
bsalomon3f324322015-04-08 11:01:54 -0700304 fResourceCache->notifyFlushOccurred();
bsalomonf21dab92014-11-13 13:33:28 -0800305 fFlushToReduceCacheSize = false;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000306}
307
bsalomon81beccc2014-10-13 12:32:55 -0700308bool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes,
309 const void* inPixels, size_t outRowBytes, void* outPixels) {
310 SkSrcPixelInfo srcPI;
jvanverthfa1e8a72014-12-22 08:31:49 -0800311 if (!GrPixelConfig2ColorAndProfileType(srcConfig, &srcPI.fColorType, NULL)) {
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000312 return false;
313 }
bsalomon81beccc2014-10-13 12:32:55 -0700314 srcPI.fAlphaType = kUnpremul_SkAlphaType;
315 srcPI.fPixels = inPixels;
316 srcPI.fRowBytes = inRowBytes;
317
318 SkDstPixelInfo dstPI;
319 dstPI.fColorType = srcPI.fColorType;
320 dstPI.fAlphaType = kPremul_SkAlphaType;
321 dstPI.fPixels = outPixels;
322 dstPI.fRowBytes = outRowBytes;
323
324 return srcPI.convertPixelsTo(&dstPI, width, height);
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000325}
326
bsalomon81beccc2014-10-13 12:32:55 -0700327bool GrContext::writeSurfacePixels(GrSurface* surface,
328 int left, int top, int width, int height,
329 GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
330 uint32_t pixelOpsFlags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800331 RETURN_FALSE_IF_ABANDONED
bsalomon81beccc2014-10-13 12:32:55 -0700332 {
333 GrTexture* texture = NULL;
334 if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) &&
joshualitt83bc2292015-06-18 14:18:02 -0700335 fGpu->canWriteTexturePixels(texture, srcConfig) &&
336 (!fCaps->useDrawInsteadOfPartialRenderTargetWrite() || !surface->asRenderTarget() ||
337 (width == texture->width() && height == texture->height()))) {
bsalomon81beccc2014-10-13 12:32:55 -0700338
339 if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) &&
340 surface->surfacePriv().hasPendingIO()) {
341 this->flush();
342 }
343 return fGpu->writeTexturePixels(texture, left, top, width, height,
344 srcConfig, buffer, rowBytes);
345 // Don't need to check kFlushWrites_PixelOp here, we just did a direct write so the
346 // upload is already flushed.
347 }
348 }
349
bsalomone8d21e82015-07-16 08:23:13 -0700350 // Trim the params here so that if we wind up making a temporary surface it can be as small as
351 // necessary.
352 if (!GrSurfacePriv::AdjustWritePixelParams(surface->width(), surface->height(),
353 GrBytesPerPixel(srcConfig), &left, &top, &width,
354 &height, &buffer, &rowBytes)) {
355 return false;
356 }
357
bsalomon81beccc2014-10-13 12:32:55 -0700358 // If we didn't do a direct texture write then we upload the pixels to a texture and draw.
359 GrRenderTarget* renderTarget = surface->asRenderTarget();
robertphillipsea461502015-05-26 11:38:03 -0700360 if (!renderTarget) {
bsalomon81beccc2014-10-13 12:32:55 -0700361 return false;
362 }
363
364 // We ignore the preferred config unless it is a R/B swap of the src config. In that case
365 // we will upload the original src data to a scratch texture but we will spoof it as the swapped
366 // config. This scratch will then have R and B swapped. We correct for this by swapping again
367 // when drawing the scratch to the dst using a conversion effect.
368 bool swapRAndB = false;
369 GrPixelConfig writeConfig = srcConfig;
370 if (GrPixelConfigSwapRAndB(srcConfig) ==
371 fGpu->preferredWritePixelsConfig(srcConfig, renderTarget->config())) {
372 writeConfig = GrPixelConfigSwapRAndB(srcConfig);
373 swapRAndB = true;
374 }
375
bsalomonf2703d82014-10-28 14:33:06 -0700376 GrSurfaceDesc desc;
bsalomon81beccc2014-10-13 12:32:55 -0700377 desc.fWidth = width;
378 desc.fHeight = height;
379 desc.fConfig = writeConfig;
bsalomond309e7a2015-04-30 14:18:54 -0700380 SkAutoTUnref<GrTexture> texture(this->textureProvider()->refScratchTexture(desc,
381 GrTextureProvider::kApprox_ScratchTexMatch));
bsalomone3059732014-10-14 11:47:22 -0700382 if (!texture) {
bsalomon81beccc2014-10-13 12:32:55 -0700383 return false;
384 }
385
386 SkAutoTUnref<const GrFragmentProcessor> fp;
387 SkMatrix textureMatrix;
388 textureMatrix.setIDiv(texture->width(), texture->height());
389
390 // allocate a tmp buffer and sw convert the pixels to premul
391 SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
392
joshualitt5f10b5c2015-07-09 10:24:35 -0700393 GrPaint paint;
bsalomon81beccc2014-10-13 12:32:55 -0700394 if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
395 if (!GrPixelConfigIs8888(srcConfig)) {
396 return false;
397 }
joshualitt5f10b5c2015-07-09 10:24:35 -0700398 fp.reset(this->createUPMToPMEffect(paint.getProcessorDataManager(), texture, swapRAndB,
399 textureMatrix));
bsalomon81beccc2014-10-13 12:32:55 -0700400 // handle the unpremul step on the CPU if we couldn't create an effect to do it.
robertphillipsea461502015-05-26 11:38:03 -0700401 if (!fp) {
bsalomon81beccc2014-10-13 12:32:55 -0700402 size_t tmpRowBytes = 4 * width;
403 tmpPixels.reset(width * height);
404 if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
405 tmpPixels.get())) {
406 return false;
407 }
408 rowBytes = tmpRowBytes;
409 buffer = tmpPixels.get();
410 }
411 }
joshualitt5f10b5c2015-07-09 10:24:35 -0700412
robertphillipsea461502015-05-26 11:38:03 -0700413 if (!fp) {
joshualitt5f10b5c2015-07-09 10:24:35 -0700414 fp.reset(GrConfigConversionEffect::Create(paint.getProcessorDataManager(),
415 texture,
bsalomon81beccc2014-10-13 12:32:55 -0700416 swapRAndB,
417 GrConfigConversionEffect::kNone_PMConversion,
418 textureMatrix));
419 }
420
421 // Even if the client told us not to flush, we still flush here. The client may have known that
422 // writes to the original surface caused no data hazards, but they can't know that the scratch
423 // we just got is safe.
424 if (texture->surfacePriv().hasPendingIO()) {
425 this->flush();
426 }
427 if (!fGpu->writeTexturePixels(texture, 0, 0, width, height,
428 writeConfig, buffer, rowBytes)) {
429 return false;
430 }
431
432 SkMatrix matrix;
433 matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
434
robertphillipsea461502015-05-26 11:38:03 -0700435 GrDrawContext* drawContext = this->drawContext();
436 if (!drawContext) {
437 return false;
bsalomon81beccc2014-10-13 12:32:55 -0700438 }
439
robertphillipsea461502015-05-26 11:38:03 -0700440 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
bsalomone8d21e82015-07-16 08:23:13 -0700453bool GrContext::readSurfacePixels(GrSurface* src,
454 int left, int top, int width, int height,
455 GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
456 uint32_t flags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800457 RETURN_FALSE_IF_ABANDONED
bsalomone8d21e82015-07-16 08:23:13 -0700458 ASSERT_OWNED_RESOURCE(src);
459 SkASSERT(src);
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000460
bsalomone8d21e82015-07-16 08:23:13 -0700461 // Adjust the params so that if we wind up using an intermediate surface we've already done
462 // all the trimming and the temporary can be the min size required.
463 if (!GrSurfacePriv::AdjustReadPixelParams(src->width(), src->height(),
464 GrBytesPerPixel(dstConfig), &left,
465 &top, &width, &height, &buffer, &rowBytes)) {
466 return false;
467 }
468
469 if (!(kDontFlush_PixelOpsFlag & flags) && src->surfacePriv().hasPendingWrite()) {
bsalomon@google.com6f379512011-11-16 20:36:03 +0000470 this->flush();
471 }
bsalomon@google.comc4364992011-11-07 15:54:49 +0000472
bsalomone8d21e82015-07-16 08:23:13 -0700473 bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
bsalomon@google.com9c680582013-02-06 18:17:50 +0000474 if (unpremul && !GrPixelConfigIs8888(dstConfig)) {
bsalomon39826022015-07-23 08:07:21 -0700475 // The unpremul flag is only allowed for 8888 configs.
bsalomon@google.com0a97be22011-11-08 19:20:57 +0000476 return false;
477 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000478
bsalomon39826022015-07-23 08:07:21 -0700479 GrGpu::DrawPreference drawPreference = unpremul ? GrGpu::kCallerPrefersDraw_DrawPreference :
480 GrGpu::kNoDraw_DrawPreference;
481 GrGpu::ReadPixelTempDrawInfo tempDrawInfo;
482 if (!fGpu->getReadPixelsInfo(src, width, height, rowBytes, dstConfig, &drawPreference,
483 &tempDrawInfo)) {
484 return false;
485 }
bsalomon191bcc02014-11-14 11:31:13 -0800486
bsalomon39826022015-07-23 08:07:21 -0700487 GrRenderTarget* rtToRead = src->asRenderTarget();
488 bool didTempDraw = false;
489 if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
bsalomond309e7a2015-04-30 14:18:54 -0700490 GrTextureProvider::ScratchTexMatch match = GrTextureProvider::kApprox_ScratchTexMatch;
bsalomon39826022015-07-23 08:07:21 -0700491 if (tempDrawInfo.fUseExactScratch) {
492 // We only respect this when the entire src is being read. Otherwise we can trigger too
493 // many odd ball texture sizes and trash the cache.
494 if (width == src->width() && height == src->height()) {
495 match = GrTextureProvider::kExact_ScratchTexMatch;
496 }
bsalomon@google.com56d11e02011-11-30 19:59:08 +0000497 }
bsalomon39826022015-07-23 08:07:21 -0700498 SkAutoTUnref<GrTexture> temp;
499 temp.reset(this->textureProvider()->refScratchTexture(tempDrawInfo.fTempSurfaceDesc, match));
500 if (temp) {
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000501 SkMatrix textureMatrix;
bsalomon39826022015-07-23 08:07:21 -0700502 textureMatrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000503 textureMatrix.postIDiv(src->width(), src->height());
joshualitt5f10b5c2015-07-09 10:24:35 -0700504 GrPaint paint;
joshualittb0a8a372014-09-23 09:50:21 -0700505 SkAutoTUnref<const GrFragmentProcessor> fp;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000506 if (unpremul) {
bsalomon39826022015-07-23 08:07:21 -0700507 fp.reset(this->createPMToUPMEffect(
508 paint.getProcessorDataManager(), src->asTexture(), tempDrawInfo.fSwapRAndB,
509 textureMatrix));
joshualittb0a8a372014-09-23 09:50:21 -0700510 if (fp) {
bsalomon@google.com9c680582013-02-06 18:17:50 +0000511 unpremul = false; // we no longer need to do this on CPU after the read back.
bsalomon39826022015-07-23 08:07:21 -0700512 } else if (GrGpu::kCallerPrefersDraw_DrawPreference == drawPreference) {
513 // We only wanted to do the draw in order to perform the unpremul so don't
514 // bother.
515 temp.reset(NULL);
bsalomon@google.comd8b5fac2012-11-01 17:02:46 +0000516 }
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000517 }
bsalomon39826022015-07-23 08:07:21 -0700518 if (!fp && temp) {
519 fp.reset(GrConfigConversionEffect::Create(
520 paint.getProcessorDataManager(), src->asTexture(), tempDrawInfo.fSwapRAndB,
521 GrConfigConversionEffect::kNone_PMConversion, textureMatrix));
522 }
523 if (fp) {
524 paint.addColorProcessor(fp);
525 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
526 GrDrawContext* drawContext = this->drawContext();
527 drawContext->drawRect(temp->asRenderTarget(), GrClip::WideOpen(), paint,
528 SkMatrix::I(), rect, NULL);
529 rtToRead = temp->asRenderTarget();
530 left = 0;
531 top = 0;
532 didTempDraw = true;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000533 }
bsalomon@google.com0342a852012-08-20 19:22:38 +0000534 }
bsalomon@google.comc4364992011-11-07 15:54:49 +0000535 }
joshualitt5c55fef2014-10-31 14:04:35 -0700536
bsalomon39826022015-07-23 08:07:21 -0700537 if (GrGpu::kRequireDraw_DrawPreference == drawPreference && !didTempDraw) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000538 return false;
539 }
bsalomon39826022015-07-23 08:07:21 -0700540 GrPixelConfig configToRead = dstConfig;
541 if (didTempDraw) {
542 this->flushSurfaceWrites(rtToRead);
543 // We swapped R and B while doing the temp draw. Swap back on the read.
544 if (tempDrawInfo.fSwapRAndB) {
545 configToRead = GrPixelConfigSwapRAndB(dstConfig);
546 }
547 }
548 if (!fGpu->readPixels(rtToRead, left, top, width, height, configToRead, buffer, rowBytes)) {
549 return false;
550 }
551
552 // Perform umpremul conversion if we weren't able to perform it as a draw.
553 if (unpremul) {
reed@google.com7111d462014-03-25 16:20:24 +0000554 SkDstPixelInfo dstPI;
jvanverthfa1e8a72014-12-22 08:31:49 -0800555 if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, NULL)) {
reed@google.com7111d462014-03-25 16:20:24 +0000556 return false;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000557 }
reed@google.com7111d462014-03-25 16:20:24 +0000558 dstPI.fAlphaType = kUnpremul_SkAlphaType;
559 dstPI.fPixels = buffer;
560 dstPI.fRowBytes = rowBytes;
561
562 SkSrcPixelInfo srcPI;
bsalomon39826022015-07-23 08:07:21 -0700563 srcPI.fColorType = dstPI.fColorType;
reed@google.com7111d462014-03-25 16:20:24 +0000564 srcPI.fAlphaType = kPremul_SkAlphaType;
565 srcPI.fPixels = buffer;
566 srcPI.fRowBytes = rowBytes;
567
568 return srcPI.convertPixelsTo(&dstPI, width, height);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000569 }
570 return true;
bsalomon@google.com27847de2011-02-22 20:59:41 +0000571}
572
bsalomonc49e8682015-06-30 11:37:35 -0700573void GrContext::prepareSurfaceForExternalIO(GrSurface* surface) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800574 RETURN_IF_ABANDONED
bsalomon87a94eb2014-11-03 14:28:32 -0800575 SkASSERT(surface);
576 ASSERT_OWNED_RESOURCE(surface);
577 if (surface->surfacePriv().hasPendingIO()) {
578 this->flush();
579 }
580 GrRenderTarget* rt = surface->asRenderTarget();
581 if (fGpu && rt) {
582 fGpu->resolveRenderTarget(rt);
bsalomon41ebbdd2014-08-04 08:31:39 -0700583 }
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000584}
585
bsalomonf80bfed2014-10-07 05:56:02 -0700586void GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
587 const SkIPoint& dstPoint, uint32_t pixelOpsFlags) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800588 RETURN_IF_ABANDONED
robertphillipsea461502015-05-26 11:38:03 -0700589 if (!src || !dst) {
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000590 return;
591 }
bsalomone3d4bf22014-09-23 09:15:03 -0700592 ASSERT_OWNED_RESOURCE(src);
junov2bb52102014-09-29 10:18:59 -0700593 ASSERT_OWNED_RESOURCE(dst);
Brian Salomon34a98952014-09-24 11:41:24 -0400594
bsalomonf80bfed2014-10-07 05:56:02 -0700595 // Since we're going to the draw target and not GPU, no need to check kNoFlush
596 // here.
robertphillipsea461502015-05-26 11:38:03 -0700597 if (!dst->asRenderTarget()) {
junov96c118e2014-09-26 13:09:47 -0700598 return;
599 }
robertphillipsea461502015-05-26 11:38:03 -0700600
601 GrDrawContext* drawContext = this->drawContext();
602 if (!drawContext) {
603 return;
604 }
605
606 drawContext->copySurface(dst->asRenderTarget(), src, srcRect, dstPoint);
bsalomonf80bfed2014-10-07 05:56:02 -0700607
608 if (kFlushWrites_PixelOp & pixelOpsFlags) {
609 this->flush();
610 }
senorblanco@chromium.orgef843cd2011-12-02 19:11:17 +0000611}
612
bsalomonf80bfed2014-10-07 05:56:02 -0700613void GrContext::flushSurfaceWrites(GrSurface* surface) {
joshualitt5f5a8d72015-02-25 14:09:45 -0800614 RETURN_IF_ABANDONED
bsalomonf80bfed2014-10-07 05:56:02 -0700615 if (surface->surfacePriv().hasPendingWrite()) {
616 this->flush();
617 }
618}
619
robertphillips@google.com72176b22012-05-23 13:19:12 +0000620/*
621 * This method finds a path renderer that can draw the specified path on
622 * the provided target.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000623 * Due to its expense, the software path renderer has split out so it can
robertphillips@google.com72176b22012-05-23 13:19:12 +0000624 * can be individually allowed/disallowed via the "allowSW" boolean.
625 */
joshualitt9853cce2014-11-17 14:22:48 -0800626GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
egdaniel8dd688b2015-01-22 10:16:09 -0800627 const GrPipelineBuilder* pipelineBuilder,
joshualitt8059eb92014-12-29 15:10:07 -0800628 const SkMatrix& viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800629 const SkPath& path,
kkinnunen18996512015-04-26 23:18:49 -0700630 const GrStrokeInfo& stroke,
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000631 bool allowSW,
632 GrPathRendererChain::DrawType drawType,
633 GrPathRendererChain::StencilSupport* stencilSupport) {
634
robertphillipsea461502015-05-26 11:38:03 -0700635 if (!fPathRendererChain) {
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000636 fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this));
bsalomon@google.com30085192011-08-19 15:42:31 +0000637 }
robertphillips@google.com72176b22012-05-23 13:19:12 +0000638
joshualitt9853cce2014-11-17 14:22:48 -0800639 GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target,
egdaniel8dd688b2015-01-22 10:16:09 -0800640 pipelineBuilder,
joshualitt8059eb92014-12-29 15:10:07 -0800641 viewMatrix,
joshualitt9853cce2014-11-17 14:22:48 -0800642 path,
sugoi@google.com12b4e272012-12-06 20:13:11 +0000643 stroke,
bsalomon@google.com45a15f52012-12-10 19:10:17 +0000644 drawType,
645 stencilSupport);
robertphillips@google.com72176b22012-05-23 13:19:12 +0000646
robertphillipsea461502015-05-26 11:38:03 -0700647 if (!pr && allowSW) {
648 if (!fSoftwarePathRenderer) {
tomhudson@google.comc377baf2012-07-09 20:17:56 +0000649 fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this));
robertphillips@google.com72176b22012-05-23 13:19:12 +0000650 }
robertphillips@google.com72176b22012-05-23 13:19:12 +0000651 pr = fSoftwarePathRenderer;
652 }
653
654 return pr;
bsalomon@google.com30085192011-08-19 15:42:31 +0000655}
656
bsalomon@google.com27847de2011-02-22 20:59:41 +0000657////////////////////////////////////////////////////////////////////////////////
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000658int GrContext::getRecommendedSampleCount(GrPixelConfig config,
659 SkScalar dpi) const {
bsalomon76228632015-05-29 08:02:10 -0700660 if (!this->caps()->isConfigRenderable(config, true)) {
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000661 return 0;
662 }
663 int chosenSampleCount = 0;
jvanverthe9c0fc62015-04-29 11:18:05 -0700664 if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) {
commit-bot@chromium.orgb471a322014-03-10 07:40:03 +0000665 if (dpi >= 250.0f) {
666 chosenSampleCount = 4;
667 } else {
668 chosenSampleCount = 16;
669 }
670 }
671 return chosenSampleCount <= fGpu->caps()->maxSampleCount() ?
672 chosenSampleCount : 0;
673}
674
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000675namespace {
676void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) {
677 GrConfigConversionEffect::PMConversion pmToUPM;
678 GrConfigConversionEffect::PMConversion upmToPM;
679 GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM);
680 *pmToUPMValue = pmToUPM;
681 *upmToPMValue = upmToPM;
682}
683}
684
joshualitt5f10b5c2015-07-09 10:24:35 -0700685const GrFragmentProcessor* GrContext::createPMToUPMEffect(GrProcessorDataManager* procDataManager,
686 GrTexture* texture,
joshualittb0a8a372014-09-23 09:50:21 -0700687 bool swapRAndB,
688 const SkMatrix& matrix) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000689 if (!fDidTestPMConversions) {
690 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
bsalomon@google.comd0f3f682012-08-28 13:08:14 +0000691 fDidTestPMConversions = true;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000692 }
693 GrConfigConversionEffect::PMConversion pmToUPM =
694 static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
695 if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
joshualitt5f10b5c2015-07-09 10:24:35 -0700696 return GrConfigConversionEffect::Create(procDataManager, texture, swapRAndB, pmToUPM,
697 matrix);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000698 } else {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000699 return NULL;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000700 }
701}
702
joshualitt5f10b5c2015-07-09 10:24:35 -0700703const GrFragmentProcessor* GrContext::createUPMToPMEffect(GrProcessorDataManager* procDataManager,
704 GrTexture* texture,
joshualittb0a8a372014-09-23 09:50:21 -0700705 bool swapRAndB,
706 const SkMatrix& matrix) {
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000707 if (!fDidTestPMConversions) {
708 test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
bsalomon@google.comd0f3f682012-08-28 13:08:14 +0000709 fDidTestPMConversions = true;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000710 }
711 GrConfigConversionEffect::PMConversion upmToPM =
712 static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
713 if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
joshualitt5f10b5c2015-07-09 10:24:35 -0700714 return GrConfigConversionEffect::Create(procDataManager, texture, swapRAndB, upmToPM,
715 matrix);
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000716 } else {
bsalomon@google.comadc65362013-01-28 14:26:09 +0000717 return NULL;
bsalomon@google.coma04e8e82012-08-27 12:53:13 +0000718 }
719}
720
bsalomon37f9a262015-02-02 13:00:10 -0800721//////////////////////////////////////////////////////////////////////////////
722
723void GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const {
724 if (maxTextures) {
bsalomon0ea80f42015-02-11 10:49:59 -0800725 *maxTextures = fResourceCache->getMaxResourceCount();
bsalomon37f9a262015-02-02 13:00:10 -0800726 }
727 if (maxTextureBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800728 *maxTextureBytes = fResourceCache->getMaxResourceBytes();
bsalomon37f9a262015-02-02 13:00:10 -0800729 }
730}
731
732void GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
bsalomon0ea80f42015-02-11 10:49:59 -0800733 fResourceCache->setLimits(maxTextures, maxTextureBytes);
bsalomon37f9a262015-02-02 13:00:10 -0800734}
735
bsalomon37f9a262015-02-02 13:00:10 -0800736//////////////////////////////////////////////////////////////////////////////
737
egdanielbbcb38d2014-06-19 10:19:29 -0700738void GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
739 fGpu->addGpuTraceMarker(marker);
egdanielbbcb38d2014-06-19 10:19:29 -0700740}
741
742void GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
743 fGpu->removeGpuTraceMarker(marker);
egdanielbbcb38d2014-06-19 10:19:29 -0700744}
joshualitte5902662015-05-11 08:18:35 -0700745