blob: 47863bb6fcf56848248b56f8e8816a00eceecd57 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@google.comac10a2d2010-12-22 21:39:39 +000010#include "GrGpu.h"
bsalomon@google.com558a75b2011-08-08 17:01:14 +000011
bsalomon@google.com81c3f8d2011-08-03 15:18:33 +000012#include "GrBufferAllocPool.h"
bsalomon@google.com558a75b2011-08-08 17:01:14 +000013#include "GrContext.h"
bsalomon@google.comc26d94f2013-03-25 18:19:00 +000014#include "GrDrawTargetCaps.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000015#include "GrIndexBuffer.h"
tomhudson@google.comdd182cb2012-02-10 21:01:00 +000016#include "GrStencilBuffer.h"
bsalomon@google.com81c3f8d2011-08-03 15:18:33 +000017#include "GrVertexBuffer.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000018
19// probably makes no sense for this to be less than a page
bsalomon@google.comee435122011-07-01 14:57:55 +000020static const size_t VERTEX_POOL_VB_SIZE = 1 << 18;
21static const int VERTEX_POOL_VB_COUNT = 4;
bsalomon@google.com25fd36c2011-07-06 17:41:08 +000022static const size_t INDEX_POOL_IB_SIZE = 1 << 16;
23static const int INDEX_POOL_IB_COUNT = 4;
reed@google.comac10a2d2010-12-22 21:39:39 +000024
bsalomon@google.comd302f142011-03-03 13:54:13 +000025////////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +000026
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000027#define DEBUG_INVAL_BUFFER 0xdeadcafe
28#define DEBUG_INVAL_START_IDX -1
29
bsalomon@google.com6e4e6502013-02-25 20:12:45 +000030GrGpu::GrGpu(GrContext* context)
joshualitt3322fa42014-11-07 08:48:51 -080031 : fResetTimestamp(kExpiredTimestamp+1)
bsalomon@google.com0a208a12013-06-28 18:57:35 +000032 , fResetBits(kAll_GrBackendState)
bsalomon@google.com8fe72472011-03-30 21:26:44 +000033 , fVertexPool(NULL)
34 , fIndexPool(NULL)
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000035 , fVertexPoolUseCnt(0)
36 , fIndexPoolUseCnt(0)
joshualitt3322fa42014-11-07 08:48:51 -080037 , fQuadIndexBuffer(NULL)
38 , fContext(context) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000039 fGeomPoolStateStack.push_back();
joshualitt3322fa42014-11-07 08:48:51 -080040 fDrawState = &fDefaultDrawState;
41 // We assume that fDrawState always owns a ref to the object it points at.
42 fDefaultDrawState.ref();
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000043#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +000044 GeometryPoolState& poolState = fGeomPoolStateStack.back();
45 poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
46 poolState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
47 poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
48 poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
49#endif
joshualitt3322fa42014-11-07 08:48:51 -080050
51 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
52#ifdef SK_DEBUG
53 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
54 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
55 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
56 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
57#endif
58 geoSrc.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType;
59 geoSrc.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType;
reed@google.comac10a2d2010-12-22 21:39:39 +000060}
61
bsalomon1d89ddc2014-08-19 14:20:58 -070062GrGpu::~GrGpu() {
bsalomon1d89ddc2014-08-19 14:20:58 -070063 SkSafeSetNull(fQuadIndexBuffer);
64 delete fVertexPool;
65 fVertexPool = NULL;
66 delete fIndexPool;
67 fIndexPool = NULL;
joshualitt3322fa42014-11-07 08:48:51 -080068 SkASSERT(1 == fGeoSrcStateStack.count());
69 SkDEBUGCODE(GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
70 SkASSERT(GrDrawTarget::kNone_GeometrySrcType == geoSrc.fIndexSrc);
71 SkASSERT(GrDrawTarget::kNone_GeometrySrcType == geoSrc.fVertexSrc);
72 SkSafeUnref(fDrawState);
bsalomon1d89ddc2014-08-19 14:20:58 -070073}
74
robertphillipse3371302014-09-17 06:01:06 -070075void GrGpu::contextAbandoned() {}
reed@google.comac10a2d2010-12-22 21:39:39 +000076
bsalomon@google.comd302f142011-03-03 13:54:13 +000077////////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +000078
bsalomonf2703d82014-10-28 14:33:06 -070079GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc,
bsalomon@google.coma7f84e12011-03-10 14:13:19 +000080 const void* srcData, size_t rowBytes) {
krajcevski9c0e6292014-06-02 07:38:14 -070081 if (!this->caps()->isConfigTexturable(desc.fConfig)) {
robertphillips@google.comd3eb3362012-10-31 13:56:35 +000082 return NULL;
83 }
krajcevski9c0e6292014-06-02 07:38:14 -070084
bsalomonf2703d82014-10-28 14:33:06 -070085 if ((desc.fFlags & kRenderTarget_GrSurfaceFlag) &&
commit-bot@chromium.org6b7938f2013-10-15 14:18:16 +000086 !this->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
87 return NULL;
88 }
robertphillips@google.comd3eb3362012-10-31 13:56:35 +000089
krajcevski9c0e6292014-06-02 07:38:14 -070090 GrTexture *tex = NULL;
91 if (GrPixelConfigIsCompressed(desc.fConfig)) {
92 // We shouldn't be rendering into this
bsalomonf2703d82014-10-28 14:33:06 -070093 SkASSERT((desc.fFlags & kRenderTarget_GrSurfaceFlag) == 0);
krajcevski9c0e6292014-06-02 07:38:14 -070094
95 if (!this->caps()->npotTextureTileSupport() &&
tfarinaf9dae782014-06-06 06:35:28 -070096 (!SkIsPow2(desc.fWidth) || !SkIsPow2(desc.fHeight))) {
bsalomon@google.com81c3f8d2011-08-03 15:18:33 +000097 return NULL;
98 }
tfarinaf9dae782014-06-06 06:35:28 -070099
krajcevski9c0e6292014-06-02 07:38:14 -0700100 this->handleDirtyContext();
101 tex = this->onCreateCompressedTexture(desc, srcData);
102 } else {
103 this->handleDirtyContext();
104 tex = this->onCreateTexture(desc, srcData, rowBytes);
bsalomon49f085d2014-09-05 13:34:00 -0700105 if (tex &&
bsalomonf2703d82014-10-28 14:33:06 -0700106 (kRenderTarget_GrSurfaceFlag & desc.fFlags) &&
107 !(kNoStencil_GrSurfaceFlag & desc.fFlags)) {
bsalomon49f085d2014-09-05 13:34:00 -0700108 SkASSERT(tex->asRenderTarget());
krajcevski9c0e6292014-06-02 07:38:14 -0700109 // TODO: defer this and attach dynamically
110 if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) {
111 tex->unref();
112 return NULL;
113 }
114 }
bsalomon@google.com81c3f8d2011-08-03 15:18:33 +0000115 }
116 return tex;
117}
118
119bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000120 SkASSERT(NULL == rt->getStencilBuffer());
rmistry@google.comd6176b02012-08-23 18:14:13 +0000121 GrStencilBuffer* sb =
robertphillips@google.com9fbcad02012-09-09 14:44:15 +0000122 this->getContext()->findStencilBuffer(rt->width(),
123 rt->height(),
124 rt->numSamples());
bsalomon49f085d2014-09-05 13:34:00 -0700125 if (sb) {
bsalomon@google.com558a75b2011-08-08 17:01:14 +0000126 rt->setStencilBuffer(sb);
127 bool attached = this->attachStencilBufferToRenderTarget(sb, rt);
128 if (!attached) {
129 rt->setStencilBuffer(NULL);
130 }
131 return attached;
132 }
bsalomon@google.com99621082011-11-15 16:47:16 +0000133 if (this->createStencilBufferForRenderTarget(rt,
134 rt->width(), rt->height())) {
bsalomon@google.comedc177d2011-08-05 15:46:40 +0000135 // Right now we're clearing the stencil buffer here after it is
136 // attached to an RT for the first time. When we start matching
137 // stencil buffers with smaller color targets this will no longer
138 // be correct because it won't be guaranteed to clear the entire
139 // sb.
140 // We used to clear down in the GL subclass using a special purpose
141 // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
142 // FBO status.
bsalomonb0bd4f62014-09-03 07:19:50 -0700143 this->clearStencil(rt);
bsalomon@google.com558a75b2011-08-08 17:01:14 +0000144 return true;
145 } else {
146 return false;
bsalomon@google.comedc177d2011-08-05 15:46:40 +0000147 }
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000148}
149
bsalomon@google.com16e3dde2012-10-25 18:43:28 +0000150GrTexture* GrGpu::wrapBackendTexture(const GrBackendTextureDesc& desc) {
bsalomon@google.come269f212011-11-07 13:29:52 +0000151 this->handleDirtyContext();
bsalomon@google.com16e3dde2012-10-25 18:43:28 +0000152 GrTexture* tex = this->onWrapBackendTexture(desc);
bsalomon@google.coma14dd6d2012-01-03 21:08:12 +0000153 if (NULL == tex) {
154 return NULL;
155 }
bsalomon@google.come269f212011-11-07 13:29:52 +0000156 // TODO: defer this and attach dynamically
157 GrRenderTarget* tgt = tex->asRenderTarget();
bsalomon49f085d2014-09-05 13:34:00 -0700158 if (tgt &&
bsalomon@google.come269f212011-11-07 13:29:52 +0000159 !this->attachStencilBufferToRenderTarget(tgt)) {
160 tex->unref();
161 return NULL;
162 } else {
163 return tex;
164 }
165}
166
bsalomon@google.com16e3dde2012-10-25 18:43:28 +0000167GrRenderTarget* GrGpu::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) {
bsalomon@google.come269f212011-11-07 13:29:52 +0000168 this->handleDirtyContext();
bsalomon@google.com16e3dde2012-10-25 18:43:28 +0000169 return this->onWrapBackendRenderTarget(desc);
bsalomon@google.come269f212011-11-07 13:29:52 +0000170}
171
robertphillips@google.comadacc702013-10-14 21:53:24 +0000172GrVertexBuffer* GrGpu::createVertexBuffer(size_t size, bool dynamic) {
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000173 this->handleDirtyContext();
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000174 return this->onCreateVertexBuffer(size, dynamic);
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000175}
176
robertphillips@google.comadacc702013-10-14 21:53:24 +0000177GrIndexBuffer* GrGpu::createIndexBuffer(size_t size, bool dynamic) {
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000178 this->handleDirtyContext();
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000179 return this->onCreateIndexBuffer(size, dynamic);
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000180}
181
joshualitt5ead6da2014-10-22 16:00:29 -0700182GrIndexBuffer* GrGpu::createInstancedIndexBuffer(const uint16_t* pattern,
183 int patternSize,
184 int reps,
185 int vertCount,
186 bool isDynamic) {
187 size_t bufferSize = patternSize * reps * sizeof(uint16_t);
188 GrGpu* me = const_cast<GrGpu*>(this);
189 GrIndexBuffer* buffer = me->createIndexBuffer(bufferSize, isDynamic);
190 if (buffer) {
191 uint16_t* data = (uint16_t*) buffer->map();
192 bool useTempData = (NULL == data);
193 if (useTempData) {
194 data = SkNEW_ARRAY(uint16_t, reps * patternSize);
195 }
196 for (int i = 0; i < reps; ++i) {
197 int baseIdx = i * patternSize;
198 uint16_t baseVert = (uint16_t)(i * vertCount);
199 for (int j = 0; j < patternSize; ++j) {
200 data[baseIdx+j] = baseVert + pattern[j];
201 }
202 }
203 if (useTempData) {
204 if (!buffer->updateData(data, bufferSize)) {
205 SkFAIL("Can't get indices into buffer!");
206 }
207 SkDELETE_ARRAY(data);
208 } else {
209 buffer->unmap();
210 }
211 }
212 return buffer;
213}
214
joshualitt3322fa42014-11-07 08:48:51 -0800215void GrGpu::clear(const SkIRect* rect,
216 GrColor color,
217 bool canIgnoreRect,
218 GrRenderTarget* renderTarget) {
bsalomon89c62982014-11-03 12:08:42 -0800219 SkASSERT(renderTarget);
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000220 this->handleDirtyContext();
bsalomon63b21962014-11-05 07:05:34 -0800221 this->onGpuClear(renderTarget, rect, color, canIgnoreRect);
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000222}
223
joshualitt6db519c2014-10-29 08:48:18 -0700224void GrGpu::clearStencilClip(const SkIRect& rect,
225 bool insideClip,
226 GrRenderTarget* renderTarget) {
227 if (NULL == renderTarget) {
228 renderTarget = this->getDrawState().getRenderTarget();
229 }
230 if (NULL == renderTarget) {
231 SkASSERT(0);
232 return;
233 }
234 this->handleDirtyContext();
235 this->onClearStencilClip(renderTarget, rect, insideClip);
236}
237
bsalomon@google.com669fdc42011-04-05 17:08:27 +0000238bool GrGpu::readPixels(GrRenderTarget* target,
239 int left, int top, int width, int height,
bsalomon@google.comc6980972011-11-02 19:57:21 +0000240 GrPixelConfig config, void* buffer,
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000241 size_t rowBytes) {
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000242 this->handleDirtyContext();
bsalomon@google.comc6980972011-11-02 19:57:21 +0000243 return this->onReadPixels(target, left, top, width, height,
senorblanco@chromium.org3cb406b2013-02-05 19:50:46 +0000244 config, buffer, rowBytes);
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000245}
246
bsalomon@google.com9c680582013-02-06 18:17:50 +0000247bool GrGpu::writeTexturePixels(GrTexture* texture,
bsalomon@google.com6f379512011-11-16 20:36:03 +0000248 int left, int top, int width, int height,
249 GrPixelConfig config, const void* buffer,
250 size_t rowBytes) {
bsalomon@google.com6f379512011-11-16 20:36:03 +0000251 this->handleDirtyContext();
bsalomon@google.com9c680582013-02-06 18:17:50 +0000252 return this->onWriteTexturePixels(texture, left, top, width, height,
253 config, buffer, rowBytes);
bsalomon@google.com6f379512011-11-16 20:36:03 +0000254}
255
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000256void GrGpu::resolveRenderTarget(GrRenderTarget* target) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000257 SkASSERT(target);
bsalomon@google.com75f9f252012-01-31 13:35:56 +0000258 this->handleDirtyContext();
259 this->onResolveRenderTarget(target);
260}
261
joshualitt3322fa42014-11-07 08:48:51 -0800262void GrGpu::initCopySurfaceDstDesc(const GrSurface* src, GrSurfaceDesc* desc) {
263 // Make the dst of the copy be a render target because the default copySurface draws to the dst.
264 desc->fOrigin = kDefault_GrSurfaceOrigin;
265 desc->fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
266 desc->fConfig = src->config();
267}
268
269typedef GrTraceMarkerSet::Iter TMIter;
270void GrGpu::saveActiveTraceMarkers() {
271 if (this->caps()->gpuTracingSupport()) {
272 SkASSERT(0 == fStoredTraceMarkers.count());
273 fStoredTraceMarkers.addSet(fActiveTraceMarkers);
274 for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
275 this->removeGpuTraceMarker(&(*iter));
276 }
277 }
278}
279
280void GrGpu::restoreActiveTraceMarkers() {
281 if (this->caps()->gpuTracingSupport()) {
282 SkASSERT(0 == fActiveTraceMarkers.count());
283 for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
284 this->addGpuTraceMarker(&(*iter));
285 }
286 for (TMIter iter = fActiveTraceMarkers.begin(); iter != fActiveTraceMarkers.end(); ++iter) {
287 this->fStoredTraceMarkers.remove(*iter);
288 }
289 }
290}
291
292void GrGpu::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
293 if (this->caps()->gpuTracingSupport()) {
294 SkASSERT(fGpuTraceMarkerCount >= 0);
295 this->fActiveTraceMarkers.add(*marker);
296 this->didAddGpuTraceMarker();
297 ++fGpuTraceMarkerCount;
298 }
299}
300
301void GrGpu::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
302 if (this->caps()->gpuTracingSupport()) {
303 SkASSERT(fGpuTraceMarkerCount >= 1);
304 this->fActiveTraceMarkers.remove(*marker);
305 this->didRemoveGpuTraceMarker();
306 --fGpuTraceMarkerCount;
307 }
308}
309
310void GrGpu::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
311 this->releasePreviousVertexSource();
312 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
313 geoSrc.fVertexSrc = GrDrawTarget::kBuffer_GeometrySrcType;
314 geoSrc.fVertexBuffer = buffer;
315 buffer->ref();
316 geoSrc.fVertexSize = this->drawState()->getVertexStride();
317}
318
319void GrGpu::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
320 this->releasePreviousIndexSource();
321 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
322 geoSrc.fIndexSrc = GrDrawTarget::kBuffer_GeometrySrcType;
323 geoSrc.fIndexBuffer = buffer;
324 buffer->ref();
325}
326
327void GrGpu::setDrawState(GrDrawState* drawState) {
328 SkASSERT(fDrawState);
329 if (NULL == drawState) {
330 drawState = &fDefaultDrawState;
331 }
332 if (fDrawState != drawState) {
333 fDrawState->unref();
334 drawState->ref();
335 fDrawState = drawState;
336 }
337}
338
339void GrGpu::resetVertexSource() {
340 this->releasePreviousVertexSource();
341 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
342 geoSrc.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType;
343}
344
345void GrGpu::resetIndexSource() {
346 this->releasePreviousIndexSource();
347 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
348 geoSrc.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType;
349}
350
351void GrGpu::pushGeometrySource() {
352 this->geometrySourceWillPush();
353 GrDrawTarget::GeometrySrcState& newState = fGeoSrcStateStack.push_back();
354 newState.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType;
355 newState.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType;
356#ifdef SK_DEBUG
357 newState.fVertexCount = ~0;
358 newState.fVertexBuffer = (GrVertexBuffer*)~0;
359 newState.fIndexCount = ~0;
360 newState.fIndexBuffer = (GrIndexBuffer*)~0;
361#endif
362}
363
364void GrGpu::popGeometrySource() {
365 // if popping last element then pops are unbalanced with pushes
366 SkASSERT(fGeoSrcStateStack.count() > 1);
367
368 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
369 this->releasePreviousVertexSource();
370 this->releasePreviousIndexSource();
371 fGeoSrcStateStack.pop_back();
372}
373
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000374////////////////////////////////////////////////////////////////////////////////
375
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000376static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
reed@google.comac10a2d2010-12-22 21:39:39 +0000377
reed@google.com8195f672011-01-12 18:14:28 +0000378GR_STATIC_ASSERT(4 * MAX_QUADS <= 65535);
reed@google.comac10a2d2010-12-22 21:39:39 +0000379
joshualitt5ead6da2014-10-22 16:00:29 -0700380static const uint16_t gQuadIndexPattern[] = {
381 0, 1, 2, 0, 2, 3
382};
reed@google.comac10a2d2010-12-22 21:39:39 +0000383
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000384const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
bsalomonc8dc1f72014-08-21 13:02:13 -0700385 if (NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed()) {
386 SkSafeUnref(fQuadIndexBuffer);
reed@google.comac10a2d2010-12-22 21:39:39 +0000387 GrGpu* me = const_cast<GrGpu*>(this);
joshualitt5ead6da2014-10-22 16:00:29 -0700388 fQuadIndexBuffer = me->createInstancedIndexBuffer(gQuadIndexPattern,
389 6,
390 MAX_QUADS,
391 4);
reed@google.comac10a2d2010-12-22 21:39:39 +0000392 }
393
394 return fQuadIndexBuffer;
395}
396
bsalomon@google.comd302f142011-03-03 13:54:13 +0000397////////////////////////////////////////////////////////////////////////////////
reed@google.comac10a2d2010-12-22 21:39:39 +0000398
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000399void GrGpu::geometrySourceWillPush() {
joshualitt3322fa42014-11-07 08:48:51 -0800400 const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc();
401 if (GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fVertexSrc) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000402 this->finalizeReservedVertices();
403 }
joshualitt3322fa42014-11-07 08:48:51 -0800404 if (GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fIndexSrc) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000405 this->finalizeReservedIndices();
406 }
407 GeometryPoolState& newState = fGeomPoolStateStack.push_back();
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000408#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000409 newState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
410 newState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
411 newState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
412 newState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
humper@google.com0e515772013-01-07 19:54:40 +0000413#else
414 (void) newState; // silence compiler warning
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000415#endif
416}
417
joshualitt3322fa42014-11-07 08:48:51 -0800418void GrGpu::geometrySourceWillPop(const GrDrawTarget::GeometrySrcState& restoredState) {
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000419 // if popping last entry then pops are unbalanced with pushes
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000420 SkASSERT(fGeomPoolStateStack.count() > 1);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000421 fGeomPoolStateStack.pop_back();
422}
423
joshualitt3322fa42014-11-07 08:48:51 -0800424void GrGpu::onDraw(const GrDrawTarget::DrawInfo& info,
425 const GrClipMaskManager::ScissorState& scissorState) {
bsalomon@google.coma7f84e12011-03-10 14:13:19 +0000426 this->handleDirtyContext();
joshualitt2c93efe2014-11-06 12:57:13 -0800427 if (!this->flushGraphicsState(PrimTypeToDrawType(info.primitiveType()),
428 scissorState,
429 info.getDstCopy())) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000430 return;
431 }
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000432 this->onGpuDraw(info);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000433}
434
joshualitt2c93efe2014-11-06 12:57:13 -0800435void GrGpu::onStencilPath(const GrPath* path,
436 const GrClipMaskManager::ScissorState& scissorState,
437 const GrStencilSettings& stencilSettings) {
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000438 this->handleDirtyContext();
439
joshualitt2c93efe2014-11-06 12:57:13 -0800440 if (!this->flushGraphicsState(kStencilPath_DrawType, scissorState, NULL)) {
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000441 return;
442 }
443
joshualitt92e496f2014-10-31 13:56:50 -0700444 this->pathRendering()->stencilPath(path, stencilSettings);
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000445}
446
commit-bot@chromium.org32184d82013-10-09 15:14:18 +0000447
joshualitt2c93efe2014-11-06 12:57:13 -0800448void GrGpu::onDrawPath(const GrPath* path,
449 const GrClipMaskManager::ScissorState& scissorState,
450 const GrStencilSettings& stencilSettings,
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000451 const GrDeviceCoordTexture* dstCopy) {
452 this->handleDirtyContext();
453
joshualitt2c93efe2014-11-06 12:57:13 -0800454 if (!this->flushGraphicsState(kDrawPath_DrawType, scissorState, dstCopy)) {
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000455 return;
456 }
457
joshualitt92e496f2014-10-31 13:56:50 -0700458 this->pathRendering()->drawPath(path, stencilSettings);
commit-bot@chromium.orgc4dc0ad2013-10-09 14:11:33 +0000459}
460
cdaltonb85a0aa2014-07-21 15:32:44 -0700461void GrGpu::onDrawPaths(const GrPathRange* pathRange,
joshualitt2c93efe2014-11-06 12:57:13 -0800462 const uint32_t indices[],
463 int count,
464 const float transforms[],
joshualitt3322fa42014-11-07 08:48:51 -0800465 GrDrawTarget::PathTransformType transformsType,
joshualitt2c93efe2014-11-06 12:57:13 -0800466 const GrClipMaskManager::ScissorState& scissorState,
467 const GrStencilSettings& stencilSettings,
468 const GrDeviceCoordTexture* dstCopy) {
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000469 this->handleDirtyContext();
470
joshualitt2c93efe2014-11-06 12:57:13 -0800471 if (!this->flushGraphicsState(kDrawPaths_DrawType, scissorState, dstCopy)) {
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000472 return;
473 }
474
cdalton855d83f2014-09-18 13:51:53 -0700475 pathRange->willDrawPaths(indices, count);
joshualitt92e496f2014-10-31 13:56:50 -0700476 this->pathRendering()->drawPaths(pathRange, indices, count, transforms, transformsType,
477 stencilSettings);
commit-bot@chromium.org9b62aa12014-03-25 11:59:40 +0000478}
479
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000480void GrGpu::finalizeReservedVertices() {
bsalomon49f085d2014-09-05 13:34:00 -0700481 SkASSERT(fVertexPool);
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000482 fVertexPool->unmap();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000483}
484
485void GrGpu::finalizeReservedIndices() {
bsalomon49f085d2014-09-05 13:34:00 -0700486 SkASSERT(fIndexPool);
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000487 fIndexPool->unmap();
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000488}
489
490void GrGpu::prepareVertexPool() {
491 if (NULL == fVertexPool) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000492 SkASSERT(0 == fVertexPoolUseCnt);
tomhudson@google.comc377baf2012-07-09 20:17:56 +0000493 fVertexPool = SkNEW_ARGS(GrVertexBufferAllocPool, (this, true,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000494 VERTEX_POOL_VB_SIZE,
tomhudson@google.comc377baf2012-07-09 20:17:56 +0000495 VERTEX_POOL_VB_COUNT));
bsalomon@google.com11f0b512011-03-29 20:52:23 +0000496 fVertexPool->releaseGpuRef();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000497 } else if (!fVertexPoolUseCnt) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000498 // the client doesn't have valid data in the pool
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000499 fVertexPool->reset();
500 }
501}
502
503void GrGpu::prepareIndexPool() {
senorblanco@chromium.org9d18b782011-03-28 20:47:09 +0000504 if (NULL == fIndexPool) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000505 SkASSERT(0 == fIndexPoolUseCnt);
tomhudson@google.comc377baf2012-07-09 20:17:56 +0000506 fIndexPool = SkNEW_ARGS(GrIndexBufferAllocPool, (this, true,
bsalomon@google.com25fd36c2011-07-06 17:41:08 +0000507 INDEX_POOL_IB_SIZE,
tomhudson@google.comc377baf2012-07-09 20:17:56 +0000508 INDEX_POOL_IB_COUNT));
bsalomon@google.com11f0b512011-03-29 20:52:23 +0000509 fIndexPool->releaseGpuRef();
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000510 } else if (!fIndexPoolUseCnt) {
bsalomon@google.comd302f142011-03-03 13:54:13 +0000511 // the client doesn't have valid data in the pool
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000512 fIndexPool->reset();
513 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000514}
515
jvanverth@google.coma6338982013-01-31 21:34:25 +0000516bool GrGpu::onReserveVertexSpace(size_t vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000517 int vertexCount,
518 void** vertices) {
519 GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000520
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000521 SkASSERT(vertexCount > 0);
bsalomon49f085d2014-09-05 13:34:00 -0700522 SkASSERT(vertices);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000523
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000524 this->prepareVertexPool();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000525
jvanverth@google.coma6338982013-01-31 21:34:25 +0000526 *vertices = fVertexPool->makeSpace(vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000527 vertexCount,
528 &geomPoolState.fPoolVertexBuffer,
529 &geomPoolState.fPoolStartVertex);
530 if (NULL == *vertices) {
531 return false;
reed@google.comac10a2d2010-12-22 21:39:39 +0000532 }
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000533 ++fVertexPoolUseCnt;
reed@google.comac10a2d2010-12-22 21:39:39 +0000534 return true;
535}
536
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000537bool GrGpu::onReserveIndexSpace(int indexCount, void** indices) {
538 GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000539
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000540 SkASSERT(indexCount > 0);
bsalomon49f085d2014-09-05 13:34:00 -0700541 SkASSERT(indices);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000542
543 this->prepareIndexPool();
544
545 *indices = fIndexPool->makeSpace(indexCount,
546 &geomPoolState.fPoolIndexBuffer,
547 &geomPoolState.fPoolStartIndex);
548 if (NULL == *indices) {
549 return false;
550 }
551 ++fIndexPoolUseCnt;
552 return true;
553}
554
555void GrGpu::releaseReservedVertexSpace() {
joshualitt3322fa42014-11-07 08:48:51 -0800556 const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc();
557 SkASSERT(GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fVertexSrc);
jvanverth@google.comb75b0a02013-02-05 20:33:30 +0000558 size_t bytes = geoSrc.fVertexCount * geoSrc.fVertexSize;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000559 fVertexPool->putBack(bytes);
560 --fVertexPoolUseCnt;
561}
562
563void GrGpu::releaseReservedIndexSpace() {
joshualitt3322fa42014-11-07 08:48:51 -0800564 const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc();
565 SkASSERT(GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fIndexSrc);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000566 size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
567 fIndexPool->putBack(bytes);
568 --fIndexPoolUseCnt;
569}
joshualitt3322fa42014-11-07 08:48:51 -0800570
571void GrGpu::releasePreviousVertexSource() {
572 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
573 switch (geoSrc.fVertexSrc) {
574 case GrDrawTarget::kNone_GeometrySrcType:
575 break;
576 case GrDrawTarget::kReserved_GeometrySrcType:
577 this->releaseReservedVertexSpace();
578 break;
579 case GrDrawTarget::kBuffer_GeometrySrcType:
580 geoSrc.fVertexBuffer->unref();
581#ifdef SK_DEBUG
582 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
583#endif
584 break;
585 default:
586 SkFAIL("Unknown Vertex Source Type.");
587 break;
588 }
589}
590
591void GrGpu::releasePreviousIndexSource() {
592 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
593 switch (geoSrc.fIndexSrc) {
594 case GrDrawTarget::kNone_GeometrySrcType: // these two don't require
595 break;
596 case GrDrawTarget::kReserved_GeometrySrcType:
597 this->releaseReservedIndexSpace();
598 break;
599 case GrDrawTarget::kBuffer_GeometrySrcType:
600 geoSrc.fIndexBuffer->unref();
601#ifdef SK_DEBUG
602 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
603#endif
604 break;
605 default:
606 SkFAIL("Unknown Index Source Type.");
607 break;
608 }
609}
610
611void GrGpu::releaseGeometry() {
612 int popCnt = fGeoSrcStateStack.count() - 1;
613 while (popCnt) {
614 this->popGeometrySource();
615 --popCnt;
616 }
617 this->resetVertexSource();
618 this->resetIndexSource();
619}