GrGpu.cpp revision a320194e4242ef0e5e758aea896bfd52bcb3dac7
1ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 2b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell/* 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * Copyright 2010 Google Inc. 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * 5b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * Use of this source code is governed by a BSD-style license that can be 6b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell * found in the LICENSE file. 7b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell */ 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell 9ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 10ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "GrGpu.h" 11ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 12ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "GrBufferAllocPool.h" 13ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "GrClipIterator.h" 14ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "GrContext.h" 15ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "GrIndexBuffer.h" 16ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "GrStencilBuffer.h" 17ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#include "GrVertexBuffer.h" 18ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 1980a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner// probably makes no sense for this to be less than a page 207152c237b46a920b29d5605af934766b8f9a07a1Chris Lattnerstatic const size_t VERTEX_POOL_VB_SIZE = 1 << 18; 21ca398dc3989d35e8516489fd163e012133bd41cbChris Lattnerstatic const int VERTEX_POOL_VB_COUNT = 4; 2280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattnerstatic const size_t INDEX_POOL_IB_SIZE = 1 << 16; 2380a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattnerstatic const int INDEX_POOL_IB_COUNT = 4; 2480a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 257152c237b46a920b29d5605af934766b8f9a07a1Chris Lattner//////////////////////////////////////////////////////////////////////////////// 26f7703df4968084c18c248c1feea9961c19a32e6aChris Lattner 27ca398dc3989d35e8516489fd163e012133bd41cbChris Lattnerextern void gr_run_unittests(); 28f7703df4968084c18c248c1feea9961c19a32e6aChris Lattner 29f7703df4968084c18c248c1feea9961c19a32e6aChris Lattner#define DEBUG_INVAL_BUFFER 0xdeadcafe 3080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner#define DEBUG_INVAL_START_IDX -1 31ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 32ca398dc3989d35e8516489fd163e012133bd41cbChris LattnerGrGpu::GrGpu() 33ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner : fClipMaskManager(this) 34ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner , fContext(NULL) 35ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner , fResetTimestamp(kExpiredTimestamp+1) 36ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner , fVertexPool(NULL) 37ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner , fIndexPool(NULL) 38ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner , fVertexPoolUseCnt(0) 39ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner , fIndexPoolUseCnt(0) 40f7703df4968084c18c248c1feea9961c19a32e6aChris Lattner , fQuadIndexBuffer(NULL) 4180a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner , fUnitSquareVertexBuffer(NULL) 4280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner , fContextIsDirty(true) 4380a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner , fResourceHead(NULL) { 44ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 4580a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner#if GR_DEBUG 46ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner //gr_run_unittests(); 47ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#endif 48ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 49ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner fGeomPoolStateStack.push_back(); 5080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner#if GR_DEBUG 51ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GeometryPoolState& poolState = fGeomPoolStateStack.back(); 52ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 5380a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner poolState.fPoolStartVertex = DEBUG_INVAL_START_IDX; 5480a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 5580a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX; 5680a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner#endif 5780a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 5851d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner for (int i = 0; i < kGrPixelConfigCount; ++i) { 5980a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner fConfigRenderSupport[i] = false; 6051d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner }; 6180a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner} 6280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 63ca398dc3989d35e8516489fd163e012133bd41cbChris LattnerGrGpu::~GrGpu() { 64198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner this->releaseResources(); 65198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner} 66198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner 67198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattnervoid GrGpu::abandonResources() { 68198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner 69198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner fClipMaskManager.releaseResources(); 70198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner 71198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner while (NULL != fResourceHead) { 72198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner fResourceHead->abandon(); 7380a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner } 74f98a08490801b8bc6e2006627d34095f5b8567c8Chris Lattner 75f98a08490801b8bc6e2006627d34095f5b8567c8Chris Lattner GrAssert(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid()); 76f98a08490801b8bc6e2006627d34095f5b8567c8Chris Lattner GrAssert(NULL == fUnitSquareVertexBuffer || 77f98a08490801b8bc6e2006627d34095f5b8567c8Chris Lattner !fUnitSquareVertexBuffer->isValid()); 78f98a08490801b8bc6e2006627d34095f5b8567c8Chris Lattner GrSafeSetNull(fQuadIndexBuffer); 79f98a08490801b8bc6e2006627d34095f5b8567c8Chris Lattner GrSafeSetNull(fUnitSquareVertexBuffer); 80f98a08490801b8bc6e2006627d34095f5b8567c8Chris Lattner delete fVertexPool; 8180a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner fVertexPool = NULL; 8280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner delete fIndexPool; 8380a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner fIndexPool = NULL; 8451d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner} 8580a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 8680a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattnervoid GrGpu::releaseResources() { 8780a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 8880a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner fClipMaskManager.releaseResources(); 8980a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 9080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner while (NULL != fResourceHead) { 9180a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner fResourceHead->release(); 9280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner } 9380a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 94ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid()); 95ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(NULL == fUnitSquareVertexBuffer || 96ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner !fUnitSquareVertexBuffer->isValid()); 97ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrSafeSetNull(fQuadIndexBuffer); 98ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrSafeSetNull(fUnitSquareVertexBuffer); 99ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner delete fVertexPool; 10080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner fVertexPool = NULL; 101ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner delete fIndexPool; 102ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner fIndexPool = NULL; 103ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner} 10480a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 10580a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattnervoid GrGpu::insertResource(GrResource* resource) { 106ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(NULL != resource); 107ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(this == resource->getGpu()); 108ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(NULL == resource->fNext); 109ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(NULL == resource->fPrevious); 11080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 111ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner resource->fNext = fResourceHead; 112ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner if (NULL != fResourceHead) { 113ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(NULL == fResourceHead->fPrevious); 114ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner fResourceHead->fPrevious = resource; 115ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner } 116ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner fResourceHead = resource; 117ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner} 118ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 119ca398dc3989d35e8516489fd163e012133bd41cbChris Lattnervoid GrGpu::removeResource(GrResource* resource) { 12080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner GrAssert(NULL != resource); 12180a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner GrAssert(NULL != fResourceHead); 12280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 123ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner if (fResourceHead == resource) { 12480a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner GrAssert(NULL == resource->fPrevious); 125ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner fResourceHead = resource->fNext; 12680a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner } else { 12780a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner GrAssert(NULL != fResourceHead); 128ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner resource->fPrevious->fNext = resource->fNext; 12980a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner } 13080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner if (NULL != resource->fNext) { 131ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner resource->fNext->fPrevious = resource->fPrevious; 132ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner } 133ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner resource->fNext = NULL; 134ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner resource->fPrevious = NULL; 135ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner} 136ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 137ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 138ca398dc3989d35e8516489fd163e012133bd41cbChris Lattnervoid GrGpu::unimpl(const char msg[]) { 139ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#if GR_DEBUG 140ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrPrintf("--- GrGpu unimplemented(\"%s\")\n", msg); 141ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner#endif 142ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner} 143ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 14480a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner//////////////////////////////////////////////////////////////////////////////// 14580a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 146ca398dc3989d35e8516489fd163e012133bd41cbChris LattnerGrTexture* GrGpu::createTexture(const GrTextureDesc& desc, 147ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner const void* srcData, size_t rowBytes) { 148ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner this->handleDirtyContext(); 149ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrTexture* tex = this->onCreateTexture(desc, srcData, rowBytes); 150ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner if (NULL != tex && 151ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner (kRenderTarget_GrTextureFlagBit & desc.fFlags) && 152ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner !(kNoStencil_GrTextureFlagBit & desc.fFlags)) { 153ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(NULL != tex->asRenderTarget()); 154ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner // TODO: defer this and attach dynamically 155ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) { 156ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner tex->unref(); 157ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner return NULL; 158ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner } 159ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner } 160ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner return tex; 161ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner} 162ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 163ca398dc3989d35e8516489fd163e012133bd41cbChris Lattnerbool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) { 164ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(NULL == rt->getStencilBuffer()); 165ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrStencilBuffer* sb = 166ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner this->getContext()->findStencilBuffer(rt->width(), 16780a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner rt->height(), 16880a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner rt->numSamples()); 169ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner if (NULL != sb) { 170ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner rt->setStencilBuffer(sb); 171ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner bool attached = this->attachStencilBufferToRenderTarget(sb, rt); 172ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner if (!attached) { 173ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner rt->setStencilBuffer(NULL); 174ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner } 175ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner return attached; 176ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner } 177ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner if (this->createStencilBufferForRenderTarget(rt, 178ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner rt->width(), rt->height())) { 179ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner rt->getStencilBuffer()->ref(); 18080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner rt->getStencilBuffer()->transferToCacheAndLock(); 18180a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 18280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner // Right now we're clearing the stencil buffer here after it is 18380a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner // attached to an RT for the first time. When we start matching 18480a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner // stencil buffers with smaller color targets this will no longer 18580a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner // be correct because it won't be guaranteed to clear the entire 186f775f95369ba7d88a5cb8b6f1900241699d79351Chris Lattner // sb. 187f775f95369ba7d88a5cb8b6f1900241699d79351Chris Lattner // We used to clear down in the GL subclass using a special purpose 188f775f95369ba7d88a5cb8b6f1900241699d79351Chris Lattner // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported 189f775f95369ba7d88a5cb8b6f1900241699d79351Chris Lattner // FBO status. 190f775f95369ba7d88a5cb8b6f1900241699d79351Chris Lattner GrDrawState::AutoRenderTargetRestore artr(this->drawState(), rt); 19180a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner this->clearStencil(); 19280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner return true; 19380a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner } else { 19480a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner return false; 195ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner } 19651d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner} 197ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner 19880a38d245359cb0a3be8f78f5d7d911232886b9aChris LattnerGrTexture* GrGpu::createPlatformTexture(const GrPlatformTextureDesc& desc) { 19980a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner this->handleDirtyContext(); 20080a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner GrTexture* tex = this->onCreatePlatformTexture(desc); 20180a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner if (NULL == tex) { 202e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner return NULL; 203e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner } 204e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner // TODO: defer this and attach dynamically 205e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner GrRenderTarget* tgt = tex->asRenderTarget(); 206e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner if (NULL != tgt && 207e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner !this->attachStencilBufferToRenderTarget(tgt)) { 208e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner tex->unref(); 209e07007c2bd0dcb775ff3eecabb4c31ce8dc5fab0Chris Lattner return NULL; 210e07007c2bd0dcb775ff3eecabb4c31ce8dc5fab0Chris Lattner } else { 211e07007c2bd0dcb775ff3eecabb4c31ce8dc5fab0Chris Lattner return tex; 212e07007c2bd0dcb775ff3eecabb4c31ce8dc5fab0Chris Lattner } 213e07007c2bd0dcb775ff3eecabb4c31ce8dc5fab0Chris Lattner} 214e07007c2bd0dcb775ff3eecabb4c31ce8dc5fab0Chris Lattner 215e07007c2bd0dcb775ff3eecabb4c31ce8dc5fab0Chris LattnerGrRenderTarget* GrGpu::createPlatformRenderTarget(const GrPlatformRenderTargetDesc& desc) { 216e07007c2bd0dcb775ff3eecabb4c31ce8dc5fab0Chris Lattner this->handleDirtyContext(); 217e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner return this->onCreatePlatformRenderTarget(desc); 218e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner} 219e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner 220e4d90964096c240c9e29ae414792ed1246db4ee8Chris LattnerGrVertexBuffer* GrGpu::createVertexBuffer(uint32_t size, bool dynamic) { 22151d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner this->handleDirtyContext(); 22251d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner return this->onCreateVertexBuffer(size, dynamic); 22351d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner} 22451d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner 22551d6816089a66c171dc23b50d62989ac6bb5c491Chris LattnerGrIndexBuffer* GrGpu::createIndexBuffer(uint32_t size, bool dynamic) { 22651d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner this->handleDirtyContext(); 22751d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner return this->onCreateIndexBuffer(size, dynamic); 228e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner} 229e4d90964096c240c9e29ae414792ed1246db4ee8Chris Lattner 23080a38d245359cb0a3be8f78f5d7d911232886b9aChris LattnerGrPath* GrGpu::createPath(const SkPath& path) { 23180a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner GrAssert(fCaps.fPathStencilingSupport); 23280a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner this->handleDirtyContext(); 23380a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner return this->onCreatePath(path); 234ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner} 235ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner 236ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattnervoid GrGpu::clear(const GrIRect* rect, GrColor color) { 237ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner if (NULL == this->getDrawState().getRenderTarget()) { 238ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner return; 239ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner } 240f8485c643412dbff46fe87ea2867445169a5c28eChris Lattner this->handleDirtyContext(); 241ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner this->onClear(rect, color); 242ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner} 243ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner 244198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattnervoid GrGpu::forceRenderTargetFlush() { 245198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner this->handleDirtyContext(); 246198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner this->onForceRenderTargetFlush(); 247198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner} 248198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner 249198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattnerbool GrGpu::readPixels(GrRenderTarget* target, 250198f4507e2ff934a8ac3aa0a82526fa6a153b70bChris Lattner int left, int top, int width, int height, 251ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner GrPixelConfig config, void* buffer, 252ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner size_t rowBytes, bool invertY) { 253ee5457cbe88b7f691f774de8515d9a94226d1b00Chris Lattner GrAssert(GrPixelConfigIsUnpremultiplied(config) == 25451d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner GrPixelConfigIsUnpremultiplied(target->config())); 25551d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner this->handleDirtyContext(); 25651d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner return this->onReadPixels(target, left, top, width, height, 25751d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner config, buffer, rowBytes, invertY); 25851d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner} 25951d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner 260dd7036d19a3bfd3dff2531c7fdcd7901b2442de9Chris Lattnervoid GrGpu::writeTexturePixels(GrTexture* texture, 26151d6816089a66c171dc23b50d62989ac6bb5c491Chris Lattner int left, int top, int width, int height, 262ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrPixelConfig config, const void* buffer, 263ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner size_t rowBytes) { 264ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrAssert(GrPixelConfigIsUnpremultiplied(config) == 265ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner GrPixelConfigIsUnpremultiplied(texture->config())); 26680a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner this->handleDirtyContext(); 267ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner this->onWriteTexturePixels(texture, left, top, width, height, 268ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner config, buffer, rowBytes); 2697152c237b46a920b29d5605af934766b8f9a07a1Chris Lattner} 2707152c237b46a920b29d5605af934766b8f9a07a1Chris Lattner 2717152c237b46a920b29d5605af934766b8f9a07a1Chris Lattnervoid GrGpu::resolveRenderTarget(GrRenderTarget* target) { 2727152c237b46a920b29d5605af934766b8f9a07a1Chris Lattner GrAssert(target); 2737152c237b46a920b29d5605af934766b8f9a07a1Chris Lattner this->handleDirtyContext(); 2747152c237b46a920b29d5605af934766b8f9a07a1Chris Lattner this->onResolveRenderTarget(target); 2757152c237b46a920b29d5605af934766b8f9a07a1Chris Lattner} 2767152c237b46a920b29d5605af934766b8f9a07a1Chris Lattner 27780a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 27880a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner//////////////////////////////////////////////////////////////////////////////// 27980a38d245359cb0a3be8f78f5d7d911232886b9aChris Lattner 280ca398dc3989d35e8516489fd163e012133bd41cbChris Lattnerstatic const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1; 281ca398dc3989d35e8516489fd163e012133bd41cbChris Lattner 282GR_STATIC_ASSERT(4 * MAX_QUADS <= 65535); 283 284static inline void fill_indices(uint16_t* indices, int quadCount) { 285 for (int i = 0; i < quadCount; ++i) { 286 indices[6 * i + 0] = 4 * i + 0; 287 indices[6 * i + 1] = 4 * i + 1; 288 indices[6 * i + 2] = 4 * i + 2; 289 indices[6 * i + 3] = 4 * i + 0; 290 indices[6 * i + 4] = 4 * i + 2; 291 indices[6 * i + 5] = 4 * i + 3; 292 } 293} 294 295const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const { 296 if (NULL == fQuadIndexBuffer) { 297 static const int SIZE = sizeof(uint16_t) * 6 * MAX_QUADS; 298 GrGpu* me = const_cast<GrGpu*>(this); 299 fQuadIndexBuffer = me->createIndexBuffer(SIZE, false); 300 if (NULL != fQuadIndexBuffer) { 301 uint16_t* indices = (uint16_t*)fQuadIndexBuffer->lock(); 302 if (NULL != indices) { 303 fill_indices(indices, MAX_QUADS); 304 fQuadIndexBuffer->unlock(); 305 } else { 306 indices = (uint16_t*)GrMalloc(SIZE); 307 fill_indices(indices, MAX_QUADS); 308 if (!fQuadIndexBuffer->updateData(indices, SIZE)) { 309 fQuadIndexBuffer->unref(); 310 fQuadIndexBuffer = NULL; 311 GrCrash("Can't get indices into buffer!"); 312 } 313 GrFree(indices); 314 } 315 } 316 } 317 318 return fQuadIndexBuffer; 319} 320 321const GrVertexBuffer* GrGpu::getUnitSquareVertexBuffer() const { 322 if (NULL == fUnitSquareVertexBuffer) { 323 324 static const GrPoint DATA[] = { 325 { 0, 0 }, 326 { GR_Scalar1, 0 }, 327 { GR_Scalar1, GR_Scalar1 }, 328 { 0, GR_Scalar1 } 329#if 0 330 GrPoint(0, 0), 331 GrPoint(GR_Scalar1,0), 332 GrPoint(GR_Scalar1,GR_Scalar1), 333 GrPoint(0, GR_Scalar1) 334#endif 335 }; 336 static const size_t SIZE = sizeof(DATA); 337 338 GrGpu* me = const_cast<GrGpu*>(this); 339 fUnitSquareVertexBuffer = me->createVertexBuffer(SIZE, false); 340 if (NULL != fUnitSquareVertexBuffer) { 341 if (!fUnitSquareVertexBuffer->updateData(DATA, SIZE)) { 342 fUnitSquareVertexBuffer->unref(); 343 fUnitSquareVertexBuffer = NULL; 344 GrCrash("Can't get vertices into buffer!"); 345 } 346 } 347 } 348 349 return fUnitSquareVertexBuffer; 350} 351 352//////////////////////////////////////////////////////////////////////////////// 353 354bool GrGpu::setupClipAndFlushState(DrawType type) { 355 356 if (!fClipMaskManager.setupClipping(fClip)) { 357 return false; 358 } 359 360 if (!this->flushGraphicsState(type)) { 361 return false; 362 } 363 364 return true; 365} 366 367//////////////////////////////////////////////////////////////////////////////// 368 369void GrGpu::geometrySourceWillPush() { 370 const GeometrySrcState& geoSrc = this->getGeomSrc(); 371 if (kArray_GeometrySrcType == geoSrc.fVertexSrc || 372 kReserved_GeometrySrcType == geoSrc.fVertexSrc) { 373 this->finalizeReservedVertices(); 374 } 375 if (kArray_GeometrySrcType == geoSrc.fIndexSrc || 376 kReserved_GeometrySrcType == geoSrc.fIndexSrc) { 377 this->finalizeReservedIndices(); 378 } 379 GeometryPoolState& newState = fGeomPoolStateStack.push_back(); 380#if GR_DEBUG 381 newState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; 382 newState.fPoolStartVertex = DEBUG_INVAL_START_IDX; 383 newState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; 384 newState.fPoolStartIndex = DEBUG_INVAL_START_IDX; 385#endif 386} 387 388void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) { 389 // if popping last entry then pops are unbalanced with pushes 390 GrAssert(fGeomPoolStateStack.count() > 1); 391 fGeomPoolStateStack.pop_back(); 392} 393 394void GrGpu::onDrawIndexed(GrPrimitiveType type, 395 int startVertex, 396 int startIndex, 397 int vertexCount, 398 int indexCount) { 399 400 this->handleDirtyContext(); 401 402 if (!this->setupClipAndFlushState(PrimTypeToDrawType(type))) { 403 return; 404 } 405 406 int sVertex = startVertex; 407 int sIndex = startIndex; 408 setupGeometry(&sVertex, &sIndex, vertexCount, indexCount); 409 410 this->onGpuDrawIndexed(type, sVertex, sIndex, 411 vertexCount, indexCount); 412} 413 414void GrGpu::onDrawNonIndexed(GrPrimitiveType type, 415 int startVertex, 416 int vertexCount) { 417 this->handleDirtyContext(); 418 419 if (!this->setupClipAndFlushState(PrimTypeToDrawType(type))) { 420 return; 421 } 422 423 int sVertex = startVertex; 424 setupGeometry(&sVertex, NULL, vertexCount, 0); 425 426 this->onGpuDrawNonIndexed(type, sVertex, vertexCount); 427} 428 429void GrGpu::onStencilPath(const GrPath& path, GrPathFill fill) { 430 this->handleDirtyContext(); 431 432 if (!this->setupClipAndFlushState(kStencilPath_DrawType)) { 433 return; 434 } 435 436 this->onGpuStencilPath(path, fill); 437} 438 439void GrGpu::finalizeReservedVertices() { 440 GrAssert(NULL != fVertexPool); 441 fVertexPool->unlock(); 442} 443 444void GrGpu::finalizeReservedIndices() { 445 GrAssert(NULL != fIndexPool); 446 fIndexPool->unlock(); 447} 448 449void GrGpu::prepareVertexPool() { 450 if (NULL == fVertexPool) { 451 GrAssert(0 == fVertexPoolUseCnt); 452 fVertexPool = new GrVertexBufferAllocPool(this, true, 453 VERTEX_POOL_VB_SIZE, 454 VERTEX_POOL_VB_COUNT); 455 fVertexPool->releaseGpuRef(); 456 } else if (!fVertexPoolUseCnt) { 457 // the client doesn't have valid data in the pool 458 fVertexPool->reset(); 459 } 460} 461 462void GrGpu::prepareIndexPool() { 463 if (NULL == fIndexPool) { 464 GrAssert(0 == fIndexPoolUseCnt); 465 fIndexPool = new GrIndexBufferAllocPool(this, true, 466 INDEX_POOL_IB_SIZE, 467 INDEX_POOL_IB_COUNT); 468 fIndexPool->releaseGpuRef(); 469 } else if (!fIndexPoolUseCnt) { 470 // the client doesn't have valid data in the pool 471 fIndexPool->reset(); 472 } 473} 474 475bool GrGpu::onReserveVertexSpace(GrVertexLayout vertexLayout, 476 int vertexCount, 477 void** vertices) { 478 GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); 479 480 GrAssert(vertexCount > 0); 481 GrAssert(NULL != vertices); 482 483 this->prepareVertexPool(); 484 485 *vertices = fVertexPool->makeSpace(vertexLayout, 486 vertexCount, 487 &geomPoolState.fPoolVertexBuffer, 488 &geomPoolState.fPoolStartVertex); 489 if (NULL == *vertices) { 490 return false; 491 } 492 ++fVertexPoolUseCnt; 493 return true; 494} 495 496bool GrGpu::onReserveIndexSpace(int indexCount, void** indices) { 497 GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); 498 499 GrAssert(indexCount > 0); 500 GrAssert(NULL != indices); 501 502 this->prepareIndexPool(); 503 504 *indices = fIndexPool->makeSpace(indexCount, 505 &geomPoolState.fPoolIndexBuffer, 506 &geomPoolState.fPoolStartIndex); 507 if (NULL == *indices) { 508 return false; 509 } 510 ++fIndexPoolUseCnt; 511 return true; 512} 513 514void GrGpu::releaseReservedVertexSpace() { 515 const GeometrySrcState& geoSrc = this->getGeomSrc(); 516 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc); 517 size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout); 518 fVertexPool->putBack(bytes); 519 --fVertexPoolUseCnt; 520} 521 522void GrGpu::releaseReservedIndexSpace() { 523 const GeometrySrcState& geoSrc = this->getGeomSrc(); 524 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc); 525 size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t); 526 fIndexPool->putBack(bytes); 527 --fIndexPoolUseCnt; 528} 529 530void GrGpu::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) { 531 this->prepareVertexPool(); 532 GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); 533#if GR_DEBUG 534 bool success = 535#endif 536 fVertexPool->appendVertices(this->getVertexLayout(), 537 vertexCount, 538 vertexArray, 539 &geomPoolState.fPoolVertexBuffer, 540 &geomPoolState.fPoolStartVertex); 541 ++fVertexPoolUseCnt; 542 GR_DEBUGASSERT(success); 543} 544 545void GrGpu::onSetIndexSourceToArray(const void* indexArray, int indexCount) { 546 this->prepareIndexPool(); 547 GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); 548#if GR_DEBUG 549 bool success = 550#endif 551 fIndexPool->appendIndices(indexCount, 552 indexArray, 553 &geomPoolState.fPoolIndexBuffer, 554 &geomPoolState.fPoolStartIndex); 555 ++fIndexPoolUseCnt; 556 GR_DEBUGASSERT(success); 557} 558 559void GrGpu::releaseVertexArray() { 560 // if vertex source was array, we stowed data in the pool 561 const GeometrySrcState& geoSrc = this->getGeomSrc(); 562 GrAssert(kArray_GeometrySrcType == geoSrc.fVertexSrc); 563 size_t bytes = geoSrc.fVertexCount * VertexSize(geoSrc.fVertexLayout); 564 fVertexPool->putBack(bytes); 565 --fVertexPoolUseCnt; 566} 567 568void GrGpu::releaseIndexArray() { 569 // if index source was array, we stowed data in the pool 570 const GeometrySrcState& geoSrc = this->getGeomSrc(); 571 GrAssert(kArray_GeometrySrcType == geoSrc.fIndexSrc); 572 size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t); 573 fIndexPool->putBack(bytes); 574 --fIndexPoolUseCnt; 575} 576 577