1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/GrGpu.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,548 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2010 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "GrGpu.h" 1.14 + 1.15 +#include "GrBufferAllocPool.h" 1.16 +#include "GrContext.h" 1.17 +#include "GrDrawTargetCaps.h" 1.18 +#include "GrIndexBuffer.h" 1.19 +#include "GrStencilBuffer.h" 1.20 +#include "GrVertexBuffer.h" 1.21 + 1.22 +// probably makes no sense for this to be less than a page 1.23 +static const size_t VERTEX_POOL_VB_SIZE = 1 << 18; 1.24 +static const int VERTEX_POOL_VB_COUNT = 4; 1.25 +static const size_t INDEX_POOL_IB_SIZE = 1 << 16; 1.26 +static const int INDEX_POOL_IB_COUNT = 4; 1.27 + 1.28 +//////////////////////////////////////////////////////////////////////////////// 1.29 + 1.30 +#define DEBUG_INVAL_BUFFER 0xdeadcafe 1.31 +#define DEBUG_INVAL_START_IDX -1 1.32 + 1.33 +GrGpu::GrGpu(GrContext* context) 1.34 + : GrDrawTarget(context) 1.35 + , fResetTimestamp(kExpiredTimestamp+1) 1.36 + , fResetBits(kAll_GrBackendState) 1.37 + , fVertexPool(NULL) 1.38 + , fIndexPool(NULL) 1.39 + , fVertexPoolUseCnt(0) 1.40 + , fIndexPoolUseCnt(0) 1.41 + , fQuadIndexBuffer(NULL) { 1.42 + 1.43 + fClipMaskManager.setGpu(this); 1.44 + 1.45 + fGeomPoolStateStack.push_back(); 1.46 +#ifdef SK_DEBUG 1.47 + GeometryPoolState& poolState = fGeomPoolStateStack.back(); 1.48 + poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 1.49 + poolState.fPoolStartVertex = DEBUG_INVAL_START_IDX; 1.50 + poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 1.51 + poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX; 1.52 +#endif 1.53 +} 1.54 + 1.55 +GrGpu::~GrGpu() { 1.56 + this->releaseResources(); 1.57 +} 1.58 + 1.59 +void GrGpu::abandonResources() { 1.60 + 1.61 + fClipMaskManager.releaseResources(); 1.62 + 1.63 + while (NULL != fResourceList.head()) { 1.64 + fResourceList.head()->abandon(); 1.65 + } 1.66 + 1.67 + SkASSERT(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid()); 1.68 + SkSafeSetNull(fQuadIndexBuffer); 1.69 + delete fVertexPool; 1.70 + fVertexPool = NULL; 1.71 + delete fIndexPool; 1.72 + fIndexPool = NULL; 1.73 +} 1.74 + 1.75 +void GrGpu::releaseResources() { 1.76 + 1.77 + fClipMaskManager.releaseResources(); 1.78 + 1.79 + while (NULL != fResourceList.head()) { 1.80 + fResourceList.head()->release(); 1.81 + } 1.82 + 1.83 + SkASSERT(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid()); 1.84 + SkSafeSetNull(fQuadIndexBuffer); 1.85 + delete fVertexPool; 1.86 + fVertexPool = NULL; 1.87 + delete fIndexPool; 1.88 + fIndexPool = NULL; 1.89 +} 1.90 + 1.91 +void GrGpu::insertResource(GrResource* resource) { 1.92 + SkASSERT(NULL != resource); 1.93 + SkASSERT(this == resource->getGpu()); 1.94 + 1.95 + fResourceList.addToHead(resource); 1.96 +} 1.97 + 1.98 +void GrGpu::removeResource(GrResource* resource) { 1.99 + SkASSERT(NULL != resource); 1.100 + SkASSERT(this == resource->getGpu()); 1.101 + 1.102 + fResourceList.remove(resource); 1.103 +} 1.104 + 1.105 + 1.106 +void GrGpu::unimpl(const char msg[]) { 1.107 +#ifdef SK_DEBUG 1.108 + GrPrintf("--- GrGpu unimplemented(\"%s\")\n", msg); 1.109 +#endif 1.110 +} 1.111 + 1.112 +//////////////////////////////////////////////////////////////////////////////// 1.113 + 1.114 +GrTexture* GrGpu::createTexture(const GrTextureDesc& desc, 1.115 + const void* srcData, size_t rowBytes) { 1.116 + if (kUnknown_GrPixelConfig == desc.fConfig) { 1.117 + return NULL; 1.118 + } 1.119 + if ((desc.fFlags & kRenderTarget_GrTextureFlagBit) && 1.120 + !this->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) { 1.121 + return NULL; 1.122 + } 1.123 + 1.124 + this->handleDirtyContext(); 1.125 + GrTexture* tex = this->onCreateTexture(desc, srcData, rowBytes); 1.126 + if (NULL != tex && 1.127 + (kRenderTarget_GrTextureFlagBit & desc.fFlags) && 1.128 + !(kNoStencil_GrTextureFlagBit & desc.fFlags)) { 1.129 + SkASSERT(NULL != tex->asRenderTarget()); 1.130 + // TODO: defer this and attach dynamically 1.131 + if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) { 1.132 + tex->unref(); 1.133 + return NULL; 1.134 + } 1.135 + } 1.136 + return tex; 1.137 +} 1.138 + 1.139 +bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) { 1.140 + SkASSERT(NULL == rt->getStencilBuffer()); 1.141 + GrStencilBuffer* sb = 1.142 + this->getContext()->findStencilBuffer(rt->width(), 1.143 + rt->height(), 1.144 + rt->numSamples()); 1.145 + if (NULL != sb) { 1.146 + rt->setStencilBuffer(sb); 1.147 + bool attached = this->attachStencilBufferToRenderTarget(sb, rt); 1.148 + if (!attached) { 1.149 + rt->setStencilBuffer(NULL); 1.150 + } 1.151 + return attached; 1.152 + } 1.153 + if (this->createStencilBufferForRenderTarget(rt, 1.154 + rt->width(), rt->height())) { 1.155 + // Right now we're clearing the stencil buffer here after it is 1.156 + // attached to an RT for the first time. When we start matching 1.157 + // stencil buffers with smaller color targets this will no longer 1.158 + // be correct because it won't be guaranteed to clear the entire 1.159 + // sb. 1.160 + // We used to clear down in the GL subclass using a special purpose 1.161 + // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported 1.162 + // FBO status. 1.163 + GrDrawState::AutoRenderTargetRestore artr(this->drawState(), rt); 1.164 + this->clearStencil(); 1.165 + return true; 1.166 + } else { 1.167 + return false; 1.168 + } 1.169 +} 1.170 + 1.171 +GrTexture* GrGpu::wrapBackendTexture(const GrBackendTextureDesc& desc) { 1.172 + this->handleDirtyContext(); 1.173 + GrTexture* tex = this->onWrapBackendTexture(desc); 1.174 + if (NULL == tex) { 1.175 + return NULL; 1.176 + } 1.177 + // TODO: defer this and attach dynamically 1.178 + GrRenderTarget* tgt = tex->asRenderTarget(); 1.179 + if (NULL != tgt && 1.180 + !this->attachStencilBufferToRenderTarget(tgt)) { 1.181 + tex->unref(); 1.182 + return NULL; 1.183 + } else { 1.184 + return tex; 1.185 + } 1.186 +} 1.187 + 1.188 +GrRenderTarget* GrGpu::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) { 1.189 + this->handleDirtyContext(); 1.190 + return this->onWrapBackendRenderTarget(desc); 1.191 +} 1.192 + 1.193 +GrVertexBuffer* GrGpu::createVertexBuffer(size_t size, bool dynamic) { 1.194 + this->handleDirtyContext(); 1.195 + return this->onCreateVertexBuffer(size, dynamic); 1.196 +} 1.197 + 1.198 +GrIndexBuffer* GrGpu::createIndexBuffer(size_t size, bool dynamic) { 1.199 + this->handleDirtyContext(); 1.200 + return this->onCreateIndexBuffer(size, dynamic); 1.201 +} 1.202 + 1.203 +GrPath* GrGpu::createPath(const SkPath& path, const SkStrokeRec& stroke) { 1.204 + SkASSERT(this->caps()->pathRenderingSupport()); 1.205 + this->handleDirtyContext(); 1.206 + return this->onCreatePath(path, stroke); 1.207 +} 1.208 + 1.209 +void GrGpu::clear(const SkIRect* rect, 1.210 + GrColor color, 1.211 + bool canIgnoreRect, 1.212 + GrRenderTarget* renderTarget) { 1.213 + GrDrawState::AutoRenderTargetRestore art; 1.214 + if (NULL != renderTarget) { 1.215 + art.set(this->drawState(), renderTarget); 1.216 + } 1.217 + if (NULL == this->getDrawState().getRenderTarget()) { 1.218 + SkASSERT(0); 1.219 + return; 1.220 + } 1.221 + this->handleDirtyContext(); 1.222 + this->onClear(rect, color, canIgnoreRect); 1.223 +} 1.224 + 1.225 +void GrGpu::forceRenderTargetFlush() { 1.226 + this->handleDirtyContext(); 1.227 + this->onForceRenderTargetFlush(); 1.228 +} 1.229 + 1.230 +bool GrGpu::readPixels(GrRenderTarget* target, 1.231 + int left, int top, int width, int height, 1.232 + GrPixelConfig config, void* buffer, 1.233 + size_t rowBytes) { 1.234 + this->handleDirtyContext(); 1.235 + return this->onReadPixels(target, left, top, width, height, 1.236 + config, buffer, rowBytes); 1.237 +} 1.238 + 1.239 +bool GrGpu::writeTexturePixels(GrTexture* texture, 1.240 + int left, int top, int width, int height, 1.241 + GrPixelConfig config, const void* buffer, 1.242 + size_t rowBytes) { 1.243 + this->handleDirtyContext(); 1.244 + return this->onWriteTexturePixels(texture, left, top, width, height, 1.245 + config, buffer, rowBytes); 1.246 +} 1.247 + 1.248 +void GrGpu::resolveRenderTarget(GrRenderTarget* target) { 1.249 + SkASSERT(target); 1.250 + this->handleDirtyContext(); 1.251 + this->onResolveRenderTarget(target); 1.252 +} 1.253 + 1.254 +static const GrStencilSettings& winding_path_stencil_settings() { 1.255 + GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, 1.256 + kIncClamp_StencilOp, 1.257 + kIncClamp_StencilOp, 1.258 + kAlwaysIfInClip_StencilFunc, 1.259 + 0xFFFF, 0xFFFF, 0xFFFF); 1.260 + return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 1.261 +} 1.262 + 1.263 +static const GrStencilSettings& even_odd_path_stencil_settings() { 1.264 + GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings, 1.265 + kInvert_StencilOp, 1.266 + kInvert_StencilOp, 1.267 + kAlwaysIfInClip_StencilFunc, 1.268 + 0xFFFF, 0xFFFF, 0xFFFF); 1.269 + return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 1.270 +} 1.271 + 1.272 +void GrGpu::getPathStencilSettingsForFillType(SkPath::FillType fill, GrStencilSettings* outStencilSettings) { 1.273 + 1.274 + switch (fill) { 1.275 + default: 1.276 + GrCrash("Unexpected path fill."); 1.277 + /* fallthrough */; 1.278 + case SkPath::kWinding_FillType: 1.279 + case SkPath::kInverseWinding_FillType: 1.280 + *outStencilSettings = winding_path_stencil_settings(); 1.281 + break; 1.282 + case SkPath::kEvenOdd_FillType: 1.283 + case SkPath::kInverseEvenOdd_FillType: 1.284 + *outStencilSettings = even_odd_path_stencil_settings(); 1.285 + break; 1.286 + } 1.287 + fClipMaskManager.adjustPathStencilParams(outStencilSettings); 1.288 +} 1.289 + 1.290 + 1.291 +//////////////////////////////////////////////////////////////////////////////// 1.292 + 1.293 +static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1; 1.294 + 1.295 +GR_STATIC_ASSERT(4 * MAX_QUADS <= 65535); 1.296 + 1.297 +static inline void fill_indices(uint16_t* indices, int quadCount) { 1.298 + for (int i = 0; i < quadCount; ++i) { 1.299 + indices[6 * i + 0] = 4 * i + 0; 1.300 + indices[6 * i + 1] = 4 * i + 1; 1.301 + indices[6 * i + 2] = 4 * i + 2; 1.302 + indices[6 * i + 3] = 4 * i + 0; 1.303 + indices[6 * i + 4] = 4 * i + 2; 1.304 + indices[6 * i + 5] = 4 * i + 3; 1.305 + } 1.306 +} 1.307 + 1.308 +const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const { 1.309 + if (NULL == fQuadIndexBuffer) { 1.310 + static const int SIZE = sizeof(uint16_t) * 6 * MAX_QUADS; 1.311 + GrGpu* me = const_cast<GrGpu*>(this); 1.312 + fQuadIndexBuffer = me->createIndexBuffer(SIZE, false); 1.313 + if (NULL != fQuadIndexBuffer) { 1.314 + uint16_t* indices = (uint16_t*)fQuadIndexBuffer->lock(); 1.315 + if (NULL != indices) { 1.316 + fill_indices(indices, MAX_QUADS); 1.317 + fQuadIndexBuffer->unlock(); 1.318 + } else { 1.319 + indices = (uint16_t*)sk_malloc_throw(SIZE); 1.320 + fill_indices(indices, MAX_QUADS); 1.321 + if (!fQuadIndexBuffer->updateData(indices, SIZE)) { 1.322 + fQuadIndexBuffer->unref(); 1.323 + fQuadIndexBuffer = NULL; 1.324 + GrCrash("Can't get indices into buffer!"); 1.325 + } 1.326 + sk_free(indices); 1.327 + } 1.328 + } 1.329 + } 1.330 + 1.331 + return fQuadIndexBuffer; 1.332 +} 1.333 + 1.334 +//////////////////////////////////////////////////////////////////////////////// 1.335 + 1.336 +bool GrGpu::setupClipAndFlushState(DrawType type, const GrDeviceCoordTexture* dstCopy, 1.337 + GrDrawState::AutoRestoreEffects* are, 1.338 + const SkRect* devBounds) { 1.339 + if (!fClipMaskManager.setupClipping(this->getClip(), are, devBounds)) { 1.340 + return false; 1.341 + } 1.342 + 1.343 + if (!this->flushGraphicsState(type, dstCopy)) { 1.344 + return false; 1.345 + } 1.346 + 1.347 + return true; 1.348 +} 1.349 + 1.350 +//////////////////////////////////////////////////////////////////////////////// 1.351 + 1.352 +void GrGpu::geometrySourceWillPush() { 1.353 + const GeometrySrcState& geoSrc = this->getGeomSrc(); 1.354 + if (kArray_GeometrySrcType == geoSrc.fVertexSrc || 1.355 + kReserved_GeometrySrcType == geoSrc.fVertexSrc) { 1.356 + this->finalizeReservedVertices(); 1.357 + } 1.358 + if (kArray_GeometrySrcType == geoSrc.fIndexSrc || 1.359 + kReserved_GeometrySrcType == geoSrc.fIndexSrc) { 1.360 + this->finalizeReservedIndices(); 1.361 + } 1.362 + GeometryPoolState& newState = fGeomPoolStateStack.push_back(); 1.363 +#ifdef SK_DEBUG 1.364 + newState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 1.365 + newState.fPoolStartVertex = DEBUG_INVAL_START_IDX; 1.366 + newState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 1.367 + newState.fPoolStartIndex = DEBUG_INVAL_START_IDX; 1.368 +#else 1.369 + (void) newState; // silence compiler warning 1.370 +#endif 1.371 +} 1.372 + 1.373 +void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) { 1.374 + // if popping last entry then pops are unbalanced with pushes 1.375 + SkASSERT(fGeomPoolStateStack.count() > 1); 1.376 + fGeomPoolStateStack.pop_back(); 1.377 +} 1.378 + 1.379 +void GrGpu::onDraw(const DrawInfo& info) { 1.380 + this->handleDirtyContext(); 1.381 + GrDrawState::AutoRestoreEffects are; 1.382 + if (!this->setupClipAndFlushState(PrimTypeToDrawType(info.primitiveType()), 1.383 + info.getDstCopy(), &are, info.getDevBounds())) { 1.384 + return; 1.385 + } 1.386 + this->onGpuDraw(info); 1.387 +} 1.388 + 1.389 +void GrGpu::onStencilPath(const GrPath* path, SkPath::FillType fill) { 1.390 + this->handleDirtyContext(); 1.391 + 1.392 + GrDrawState::AutoRestoreEffects are; 1.393 + if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, &are, NULL)) { 1.394 + return; 1.395 + } 1.396 + 1.397 + this->onGpuStencilPath(path, fill); 1.398 +} 1.399 + 1.400 + 1.401 +void GrGpu::onDrawPath(const GrPath* path, SkPath::FillType fill, 1.402 + const GrDeviceCoordTexture* dstCopy) { 1.403 + this->handleDirtyContext(); 1.404 + 1.405 + drawState()->setDefaultVertexAttribs(); 1.406 + 1.407 + GrDrawState::AutoRestoreEffects are; 1.408 + if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, &are, NULL)) { 1.409 + return; 1.410 + } 1.411 + 1.412 + this->onGpuDrawPath(path, fill); 1.413 +} 1.414 + 1.415 +void GrGpu::finalizeReservedVertices() { 1.416 + SkASSERT(NULL != fVertexPool); 1.417 + fVertexPool->unlock(); 1.418 +} 1.419 + 1.420 +void GrGpu::finalizeReservedIndices() { 1.421 + SkASSERT(NULL != fIndexPool); 1.422 + fIndexPool->unlock(); 1.423 +} 1.424 + 1.425 +void GrGpu::prepareVertexPool() { 1.426 + if (NULL == fVertexPool) { 1.427 + SkASSERT(0 == fVertexPoolUseCnt); 1.428 + fVertexPool = SkNEW_ARGS(GrVertexBufferAllocPool, (this, true, 1.429 + VERTEX_POOL_VB_SIZE, 1.430 + VERTEX_POOL_VB_COUNT)); 1.431 + fVertexPool->releaseGpuRef(); 1.432 + } else if (!fVertexPoolUseCnt) { 1.433 + // the client doesn't have valid data in the pool 1.434 + fVertexPool->reset(); 1.435 + } 1.436 +} 1.437 + 1.438 +void GrGpu::prepareIndexPool() { 1.439 + if (NULL == fIndexPool) { 1.440 + SkASSERT(0 == fIndexPoolUseCnt); 1.441 + fIndexPool = SkNEW_ARGS(GrIndexBufferAllocPool, (this, true, 1.442 + INDEX_POOL_IB_SIZE, 1.443 + INDEX_POOL_IB_COUNT)); 1.444 + fIndexPool->releaseGpuRef(); 1.445 + } else if (!fIndexPoolUseCnt) { 1.446 + // the client doesn't have valid data in the pool 1.447 + fIndexPool->reset(); 1.448 + } 1.449 +} 1.450 + 1.451 +bool GrGpu::onReserveVertexSpace(size_t vertexSize, 1.452 + int vertexCount, 1.453 + void** vertices) { 1.454 + GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); 1.455 + 1.456 + SkASSERT(vertexCount > 0); 1.457 + SkASSERT(NULL != vertices); 1.458 + 1.459 + this->prepareVertexPool(); 1.460 + 1.461 + *vertices = fVertexPool->makeSpace(vertexSize, 1.462 + vertexCount, 1.463 + &geomPoolState.fPoolVertexBuffer, 1.464 + &geomPoolState.fPoolStartVertex); 1.465 + if (NULL == *vertices) { 1.466 + return false; 1.467 + } 1.468 + ++fVertexPoolUseCnt; 1.469 + return true; 1.470 +} 1.471 + 1.472 +bool GrGpu::onReserveIndexSpace(int indexCount, void** indices) { 1.473 + GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); 1.474 + 1.475 + SkASSERT(indexCount > 0); 1.476 + SkASSERT(NULL != indices); 1.477 + 1.478 + this->prepareIndexPool(); 1.479 + 1.480 + *indices = fIndexPool->makeSpace(indexCount, 1.481 + &geomPoolState.fPoolIndexBuffer, 1.482 + &geomPoolState.fPoolStartIndex); 1.483 + if (NULL == *indices) { 1.484 + return false; 1.485 + } 1.486 + ++fIndexPoolUseCnt; 1.487 + return true; 1.488 +} 1.489 + 1.490 +void GrGpu::releaseReservedVertexSpace() { 1.491 + const GeometrySrcState& geoSrc = this->getGeomSrc(); 1.492 + SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc); 1.493 + size_t bytes = geoSrc.fVertexCount * geoSrc.fVertexSize; 1.494 + fVertexPool->putBack(bytes); 1.495 + --fVertexPoolUseCnt; 1.496 +} 1.497 + 1.498 +void GrGpu::releaseReservedIndexSpace() { 1.499 + const GeometrySrcState& geoSrc = this->getGeomSrc(); 1.500 + SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc); 1.501 + size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t); 1.502 + fIndexPool->putBack(bytes); 1.503 + --fIndexPoolUseCnt; 1.504 +} 1.505 + 1.506 +void GrGpu::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) { 1.507 + this->prepareVertexPool(); 1.508 + GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); 1.509 +#ifdef SK_DEBUG 1.510 + bool success = 1.511 +#endif 1.512 + fVertexPool->appendVertices(this->getVertexSize(), 1.513 + vertexCount, 1.514 + vertexArray, 1.515 + &geomPoolState.fPoolVertexBuffer, 1.516 + &geomPoolState.fPoolStartVertex); 1.517 + ++fVertexPoolUseCnt; 1.518 + GR_DEBUGASSERT(success); 1.519 +} 1.520 + 1.521 +void GrGpu::onSetIndexSourceToArray(const void* indexArray, int indexCount) { 1.522 + this->prepareIndexPool(); 1.523 + GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); 1.524 +#ifdef SK_DEBUG 1.525 + bool success = 1.526 +#endif 1.527 + fIndexPool->appendIndices(indexCount, 1.528 + indexArray, 1.529 + &geomPoolState.fPoolIndexBuffer, 1.530 + &geomPoolState.fPoolStartIndex); 1.531 + ++fIndexPoolUseCnt; 1.532 + GR_DEBUGASSERT(success); 1.533 +} 1.534 + 1.535 +void GrGpu::releaseVertexArray() { 1.536 + // if vertex source was array, we stowed data in the pool 1.537 + const GeometrySrcState& geoSrc = this->getGeomSrc(); 1.538 + SkASSERT(kArray_GeometrySrcType == geoSrc.fVertexSrc); 1.539 + size_t bytes = geoSrc.fVertexCount * geoSrc.fVertexSize; 1.540 + fVertexPool->putBack(bytes); 1.541 + --fVertexPoolUseCnt; 1.542 +} 1.543 + 1.544 +void GrGpu::releaseIndexArray() { 1.545 + // if index source was array, we stowed data in the pool 1.546 + const GeometrySrcState& geoSrc = this->getGeomSrc(); 1.547 + SkASSERT(kArray_GeometrySrcType == geoSrc.fIndexSrc); 1.548 + size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t); 1.549 + fIndexPool->putBack(bytes); 1.550 + --fIndexPoolUseCnt; 1.551 +}