GrInOrderDrawBuffer.cpp revision c26d94fd7dc0b00cd6d0e42d28285f4a38aff021
1ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */ 8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 9ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrInOrderDrawBuffer.h" 111c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#include "GrBufferAllocPool.h" 12c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com#include "GrDrawTargetCaps.h" 13ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrGpu.h" 1486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrIndexBuffer.h" 15ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrPath.h" 16ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrRenderTarget.h" 176e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com#include "GrTemplates.h" 18ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com#include "GrTexture.h" 1986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com#include "GrVertexBuffer.h" 20ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 216e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.comGrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, 22471d471dcd7422e5dd9c822c1092b2ba4721dcfebsalomon@google.com GrVertexBufferAllocPool* vertexPool, 2325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrIndexBufferAllocPool* indexPool) 246e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com : GrDrawTarget(gpu->getContext()) 256e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com , fDstGpu(gpu) 2697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com , fClipSet(true) 27d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com , fClipProxyState(kUnknown_ClipProxyState) 286970557055acaed619d7bb89451868e1570249b2robertphillips@google.com , fVertexPool(*vertexPool) 296970557055acaed619d7bb89451868e1570249b2robertphillips@google.com , fIndexPool(*indexPool) 30c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com , fFlushing(false) { 3118c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com 326e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->ref(); 33bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com fCaps.reset(SkRef(fDstGpu->caps())); 3418c9c198f571997463d9a7134dbd88298e592ec2bsalomon@google.com 351c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com GrAssert(NULL != vertexPool); 361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com GrAssert(NULL != indexPool); 3725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com 3825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); 3925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fUsedPoolVertexBytes = 0; 4025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fUsedPoolIndexBytes = 0; 4125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG 4225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; 4325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fPoolStartVertex = ~0; 4425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; 4525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fPoolStartIndex = ~0; 4625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif 47a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com this->reset(); 48ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 49ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 50ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrInOrderDrawBuffer::~GrInOrderDrawBuffer() { 5186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com this->reset(); 524a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com // This must be called by before the GrDrawTarget destructor 534a018bb20bf969a38ec11d9506843f06366dfa7cbsalomon@google.com this->releaseGeometry(); 546e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->unref(); 55ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 56ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 57934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 58934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 59d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comnamespace { 60d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid get_vertex_bounds(const void* vertices, 61d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com size_t vertexSize, 62d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com int vertexCount, 63d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com SkRect* bounds) { 64d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com GrAssert(vertexSize >= sizeof(GrPoint)); 65d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com GrAssert(vertexCount > 0); 66d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com const GrPoint* point = static_cast<const GrPoint*>(vertices); 67d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com bounds->fLeft = bounds->fRight = point->fX; 68d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com bounds->fTop = bounds->fBottom = point->fY; 69d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com for (int i = 1; i < vertexCount; ++i) { 70d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com point = reinterpret_cast<GrPoint*>(reinterpret_cast<intptr_t>(point) + vertexSize); 71d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com bounds->growToInclude(point->fX, point->fY); 72d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 73d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com} 74934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com} 75934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 76d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.comvoid GrInOrderDrawBuffer::drawRect(const GrRect& rect, 77b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com const SkMatrix* matrix, 78c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com const GrRect* localRect, 79c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com const SkMatrix* localMatrix) { 80d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 819b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com GrAttribBindings bindings = GrDrawState::kDefault_AttribBindings; 82d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com GrDrawState::AutoColorRestore acr; 839b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com 849b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com GrDrawState* drawState = this->drawState(); 859b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com 869b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com GrColor color = drawState->getColor(); 879b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com GrVertexAttribArray<3> attribs; 889b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com size_t currentOffset = 0; 89c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com int colorOffset = -1, localOffset = -1; 909b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com 919b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com // set position attrib 929b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, attribs.count()); 933b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com GrVertexAttrib currAttrib = {kVec2f_GrVertexAttribType, currentOffset}; 943b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com attribs.push_back(currAttrib); 959b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com currentOffset += sizeof(GrPoint); 96d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com 97d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // Using per-vertex colors allows batching across colors. (A lot of rects in a row differing 98d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // only in color is a common occurrence in tables). However, having per-vertex colors disables 99d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // blending optimizations because we don't know if the color will be solid or not. These 100d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // optimizations help determine whether coverage and color can be blended correctly when 101d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // dual-source blending isn't available. This comes into play when there is coverage. If colors 102d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // were a stage it could take a hint that every vertex's color will be opaque. 103bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com if (this->caps()->dualSourceBlendingSupport() || 1049b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com drawState->hasSolidCoverage(drawState->getAttribBindings())) { 1059b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com bindings |= GrDrawState::kColor_AttribBindingsBit; 1069b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com drawState->setAttribIndex(GrDrawState::kColor_AttribIndex, attribs.count()); 1073b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com currAttrib.set(kVec4ub_GrVertexAttribType, currentOffset); 1083b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com attribs.push_back(currAttrib); 1099b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com colorOffset = currentOffset; 1109b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com currentOffset += sizeof(GrColor); 111d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // We set the draw state's color to white here. This is done so that any batching performed 112d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // in our subclass's onDraw() won't get a false from GrDrawState::op== due to a color 113d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // mismatch. TODO: Once vertex layout is owned by GrDrawState it should skip comparing the 114d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // constant color in its op== when the kColor layout bit is set and then we can remove this. 1159b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com acr.set(drawState, 0xFFFFFFFF); 116d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 117d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com 118c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com if (NULL != localRect) { 119c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com bindings |= GrDrawState::kLocalCoords_AttribBindingsBit; 120c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com drawState->setAttribIndex(GrDrawState::kLocalCoords_AttribIndex, attribs.count()); 1213b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com currAttrib.set(kVec2f_GrVertexAttribType, currentOffset); 1223b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com attribs.push_back(currAttrib); 123c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com localOffset = currentOffset; 1249b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com currentOffset += sizeof(GrPoint); 125d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 126f04c40ef1e60e21f3e1b2a03b910211bf895b339robertphillips@google.com 1279b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com drawState->setVertexAttribs(attribs.begin(), attribs.count()); 1289b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com drawState->setAttribBindings(bindings); 129b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com AutoReleaseGeometry geo(this, 4, 0); 130d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (!geo.succeeded()) { 131d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com GrPrintf("Failed to get space for vertices!\n"); 132d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return; 133d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 1348b129aa3379ece6c43d9ce2ad0cdeafb089b7eb5robertphillips@google.com 135d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // Go to device coords to allow batching across matrix changes 136d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com SkMatrix combinedMatrix; 137d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (NULL != matrix) { 138d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com combinedMatrix = *matrix; 139d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } else { 140d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com combinedMatrix.reset(); 141d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 1429b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com combinedMatrix.postConcat(drawState->getViewMatrix()); 1433976825a21532e254311b90b4a9046e25717e335jvanverth@google.com // When the caller has provided an explicit source rect for a stage then we don't want to 144d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // modify that stage's matrix. Otherwise if the effect is generating its source rect from 145d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // the vertex positions then we have to account for the view matrix change. 146c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com GrDrawState::AutoDeviceCoordDraw adcd(drawState); 147d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (!adcd.succeeded()) { 148d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return; 149d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 150d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com 1519b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com size_t vsize = drawState->getVertexSize(); 1529b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com GrAssert(vsize == currentOffset); 153d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com 154d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize); 155d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com combinedMatrix.mapPointsWithStride(geo.positions(), vsize, 4); 156d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com 157d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com SkRect devBounds; 158d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // since we already computed the dev verts, set the bounds hint. This will help us avoid 159d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // unnecessary clipping in our onDraw(). 160d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com get_vertex_bounds(geo.vertices(), vsize, 4, &devBounds); 161d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com 162c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com if (localOffset >= 0) { 163c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) + localOffset); 164c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com coords->setRectFan(localRect->fLeft, localRect->fTop, 165c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com localRect->fRight, localRect->fBottom, 1669b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com vsize); 167c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com if (NULL != localMatrix) { 168c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com localMatrix->mapPointsWithStride(coords, vsize, 4); 169e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com } 170d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 17186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com 172d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (colorOffset >= 0) { 173d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com GrColor* vertColor = GrTCast<GrColor*>(GrTCast<intptr_t>(geo.vertices()) + colorOffset); 174d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com for (int i = 0; i < 4; ++i) { 175d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com *vertColor = color; 176d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com vertColor = (GrColor*) ((intptr_t) vertColor + vsize); 177d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 178d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 179d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 1806e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer()); 181d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds); 1829b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com 1839b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com // to ensure that stashing the drawState ptr is valid 1849b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com GrAssert(this->drawState() == drawState); 185d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com} 186fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 187d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.combool GrInOrderDrawBuffer::quickInsideClip(const SkRect& devBounds) { 188d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (!this->getDrawState().isClipState()) { 189d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return true; 190d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 191d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (kUnknown_ClipProxyState == fClipProxyState) { 192d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com SkIRect rect; 193d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com bool iior; 194d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com this->getClip()->getConservativeBounds(this->getDrawState().getRenderTarget(), &rect, &iior); 195d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (iior) { 196d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // The clip is a rect. We will remember that in fProxyClip. It is common for an edge (or 197d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // all edges) of the clip to be at the edge of the RT. However, we get that clipping for 198d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // free via the viewport. We don't want to think that clipping must be enabled in this 199d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // case. So we extend the clip outward from the edge to avoid these false negatives. 200d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fClipProxyState = kValid_ClipProxyState; 201d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fClipProxy = SkRect::MakeFromIRect(rect); 202d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com 203d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (fClipProxy.fLeft <= 0) { 204d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fClipProxy.fLeft = SK_ScalarMin; 20586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com } 206d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (fClipProxy.fTop <= 0) { 207d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fClipProxy.fTop = SK_ScalarMin; 20886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com } 209d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (fClipProxy.fRight >= this->getDrawState().getRenderTarget()->width()) { 210d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fClipProxy.fRight = SK_ScalarMax; 211d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 212d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (fClipProxy.fBottom >= this->getDrawState().getRenderTarget()->height()) { 213d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fClipProxy.fBottom = SK_ScalarMax; 214d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 215d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } else { 216d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fClipProxyState = kInvalid_ClipProxyState; 21786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com } 21886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com } 219d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (kValid_ClipProxyState == fClipProxyState) { 220d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return fClipProxy.contains(devBounds); 221d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 222d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX), 223d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com SkIntToScalar(this->getClip()->fOrigin.fY)}; 224d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com SkRect clipSpaceBounds = devBounds; 225d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com clipSpaceBounds.offset(originOffset); 226d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return this->getClip()->fClipStack->quickContains(clipSpaceBounds); 22786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com} 22886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com 229d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comint GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { 230d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com GrAssert(info.isInstanced()); 231934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 232934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com const GeometrySrcState& geomSrc = this->getGeomSrc(); 233b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com const GrDrawState& drawState = this->getDrawState(); 234934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 235d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // we only attempt to concat the case when reserved verts are used with a client-specified index 236d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // buffer. To make this work with client-specified VBs we'd need to know if the VB was updated 237d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // between draws. 238d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || 239d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { 240d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return 0; 241d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 242d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // Check if there is a draw info that is compatible that uses the same VB from the pool and 243d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // the same IB 244d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (kDraw_Cmd != fCmds.back()) { 245d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return 0; 246d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 247934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 248d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com DrawRecord* draw = &fDraws.back(); 249d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.back(); 250d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; 251d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com 252d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (!draw->isInstanced() || 253d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com draw->verticesPerInstance() != info.verticesPerInstance() || 254d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com draw->indicesPerInstance() != info.indicesPerInstance() || 255d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com draw->fVertexBuffer != vertexBuffer || 256b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com draw->fIndexBuffer != geomSrc.fIndexBuffer) { 257d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return 0; 258d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 259d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // info does not yet account for the offset from the start of the pool's VB while the previous 260d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // draw record does. 261d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com int adjustedStartVertex = poolState.fPoolStartVertex + info.startVertex(); 262d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (draw->startVertex() + draw->vertexCount() != adjustedStartVertex) { 263d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return 0; 264d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 265a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com 266d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com GrAssert(poolState.fPoolStartVertex == draw->startVertex() + draw->vertexCount()); 267934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 268d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // how many instances can be concat'ed onto draw given the size of the index buffer 269d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com int instancesToConcat = this->indexCountInCurrentSource() / info.indicesPerInstance(); 270d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com instancesToConcat -= draw->instanceCount(); 271d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com instancesToConcat = GrMin(instancesToConcat, info.instanceCount()); 272934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 273d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com // update the amount of reserved vertex data actually referenced in draws 274ae683921ffda9108147a29da7319c7eee4dc9245skia.committer@gmail.com size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * 275b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com drawState.getVertexSize(); 276d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com poolState.fUsedPoolVertexBytes = GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); 277934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 278d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com draw->adjustInstanceCount(instancesToConcat); 279d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return instancesToConcat; 280d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com} 281934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 282d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comclass AutoClipReenable { 283d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.compublic: 284d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com AutoClipReenable() : fDrawState(NULL) {} 285d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com ~AutoClipReenable() { 286d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (NULL != fDrawState) { 287d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fDrawState->enableState(GrDrawState::kClip_StateBit); 288d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 289934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com } 290d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com void set(GrDrawState* drawState) { 291d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (drawState->isClipState()) { 292d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fDrawState = drawState; 293d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com drawState->disableState(GrDrawState::kClip_StateBit); 294d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 295d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 296d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comprivate: 297d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com GrDrawState* fDrawState; 298d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com}; 299934c570297c1b1f99cb4ca8d012d468a7eddf73fbsalomon@google.com 30074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.comvoid GrInOrderDrawBuffer::onDraw(const DrawInfo& info) { 301ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 30225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.back(); 303b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com const GrDrawState& drawState = this->getDrawState(); 304d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com AutoClipReenable acr; 305d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com 306b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com if (drawState.isClipState() && 307d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com NULL != info.getDevBounds() && 308d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com this->quickInsideClip(*info.getDevBounds())) { 309d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com acr.set(this->drawState()); 310d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 31125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com 312a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com if (this->needsNewClip()) { 313a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com this->recordClip(); 31486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com } 315a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com if (this->needsNewState()) { 316a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com this->recordState(); 31786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com } 318ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 319d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com DrawRecord* draw; 320d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (info.isInstanced()) { 321d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com int instancesConcated = this->concatInstancedDraw(info); 322d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (info.instanceCount() > instancesConcated) { 323d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com draw = this->recordDraw(info); 324d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com draw->adjustInstanceCount(-instancesConcated); 325d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } else { 326d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return; 327d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 328d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } else { 329d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com draw = this->recordDraw(info); 330d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com } 33174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com 33225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com switch (this->getGeomSrc().fVertexSrc) { 33374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com case kBuffer_GeometrySrcType: 33474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com draw->fVertexBuffer = this->getGeomSrc().fVertexBuffer; 33574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com break; 33674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com case kReserved_GeometrySrcType: // fallthrough 33774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com case kArray_GeometrySrcType: { 338ae683921ffda9108147a29da7319c7eee4dc9245skia.committer@gmail.com size_t vertexBytes = (info.vertexCount() + info.startVertex()) * 339b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com drawState.getVertexSize(); 34074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com poolState.fUsedPoolVertexBytes = GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); 34174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com draw->fVertexBuffer = poolState.fPoolVertexBuffer; 342d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com draw->adjustStartVertex(poolState.fPoolStartVertex); 34374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com break; 34474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com } 34574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com default: 34674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com GrCrash("unknown geom src type"); 347ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 348a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com draw->fVertexBuffer->ref(); 349ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 35074749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com if (info.isIndexed()) { 35174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com switch (this->getGeomSrc().fIndexSrc) { 35274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com case kBuffer_GeometrySrcType: 35374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com draw->fIndexBuffer = this->getGeomSrc().fIndexBuffer; 35474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com break; 35574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com case kReserved_GeometrySrcType: // fallthrough 35674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com case kArray_GeometrySrcType: { 35774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com size_t indexBytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t); 35874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com poolState.fUsedPoolIndexBytes = GrMax(poolState.fUsedPoolIndexBytes, indexBytes); 35974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com draw->fIndexBuffer = poolState.fPoolIndexBuffer; 360d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com draw->adjustStartIndex(poolState.fPoolStartIndex); 36174749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com break; 36274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com } 36374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com default: 36474749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com GrCrash("unknown geom src type"); 36574749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com } 36674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com draw->fIndexBuffer->ref(); 36774749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com } else { 36874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com draw->fIndexBuffer = NULL; 369ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 370ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 371ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 3725f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comGrInOrderDrawBuffer::StencilPath::StencilPath() : fStroke(SkStrokeRec::kFill_InitStyle) {} 3735f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com 3745f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.comvoid GrInOrderDrawBuffer::onStencilPath(const GrPath* path, const SkStrokeRec& stroke, 37512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com SkPath::FillType fill) { 376ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com if (this->needsNewClip()) { 377ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com this->recordClip(); 378ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com } 379ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com // Only compare the subset of GrDrawState relevant to path stenciling? 380ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com if (this->needsNewState()) { 381ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com this->recordState(); 382ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com } 383ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com StencilPath* sp = this->recordStencilPath(); 384ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com sp->fPath.reset(path); 385ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com path->ref(); 386ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com sp->fFill = fill; 38712b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com sp->fStroke = stroke; 38864aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com} 38964aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com 390d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.comvoid GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color, GrRenderTarget* renderTarget) { 3916aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com GrIRect r; 3921b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com if (NULL == renderTarget) { 3931b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com renderTarget = this->drawState()->getRenderTarget(); 3941b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com GrAssert(NULL != renderTarget); 3951b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com } 3966aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com if (NULL == rect) { 3976aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com // We could do something smart and remove previous draws and clears to 3986aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com // the current render target. If we get that smart we have to make sure 3996aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com // those draws aren't read before this clear (render-to-texture). 4001b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); 4016aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com rect = &r; 4026aa25c3f555dc2a6711365d14279db3ec909e064bsalomon@google.com } 403a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com Clear* clr = this->recordClear(); 404a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com clr->fColor = color; 405a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com clr->fRect = *rect; 406a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com clr->fRenderTarget = renderTarget; 4071b3ce47c7b6c14c84d7aaee249b33f9d3b473050bsalomon@google.com renderTarget->ref(); 4080b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com} 4090b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com 410ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrInOrderDrawBuffer::reset() { 41125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(1 == fGeoPoolStateStack.count()); 41225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com this->resetVertexSource(); 41325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com this->resetIndexSource(); 41486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com int numDraws = fDraws.count(); 41586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com for (int d = 0; d < numDraws; ++d) { 41686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com // we always have a VB, but not always an IB 41786afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com GrAssert(NULL != fDraws[d].fVertexBuffer); 41886afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com fDraws[d].fVertexBuffer->unref(); 41986afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com GrSafeUnref(fDraws[d].fIndexBuffer); 42086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com } 421a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com fCmds.reset(); 422ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fDraws.reset(); 423ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com fStencilPaths.reset(); 424ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fStates.reset(); 4250b335c1ac100aeacf79a4c98a052286fd46661e7bsalomon@google.com fClears.reset(); 4261c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com fVertexPool.reset(); 4271c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com fIndexPool.reset(); 428ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com fClips.reset(); 429beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com fClipOrigins.reset(); 430a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com fClipSet = true; 431ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 432ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 4336e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.combool GrInOrderDrawBuffer::flush() { 43425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); 43525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); 4363f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com 437a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com int numCmds = fCmds.count(); 438358e427763f0971af436f07170c641f747b94595bsalomon@google.com if (0 == numCmds) { 439a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com return false; 440ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 4416e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com GrAssert(!fFlushing); 4426e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 4436e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com GrAutoTRestore<bool> flushRestore(&fFlushing); 4446e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fFlushing = true; 445ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 4461c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com fVertexPool.unlock(); 4471c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com fIndexPool.unlock(); 448ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 4496e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com GrDrawTarget::AutoClipRestore acr(fDstGpu); 4506e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit); 451ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com 452ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com GrDrawState playbackState; 4536e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com GrDrawState* prevDrawState = fDstGpu->drawState(); 454a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com prevDrawState->ref(); 4556e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->setDrawState(&playbackState); 456ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 457beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com GrClipData clipData; 458beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com 459ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com int currState = 0; 460ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com int currClip = 0; 461ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com int currClear = 0; 462ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com int currDraw = 0; 463ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com int currStencilPath = 0; 464a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com 465a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com for (int c = 0; c < numCmds; ++c) { 466a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com switch (fCmds[c]) { 467a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com case kDraw_Cmd: { 46874749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com const DrawRecord& draw = fDraws[currDraw]; 4696e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->setVertexSourceToBuffer(draw.fVertexBuffer); 470d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com if (draw.isIndexed()) { 4716e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->setIndexSourceToBuffer(draw.fIndexBuffer); 472a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com } 4736e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->executeDraw(draw); 474ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 475a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com ++currDraw; 476a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com break; 477a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com } 478ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com case kStencilPath_Cmd: { 479ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com const StencilPath& sp = fStencilPaths[currStencilPath]; 4806e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->stencilPath(sp.fPath.get(), sp.fStroke, sp.fFill); 481ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com ++currStencilPath; 482ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com break; 483ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com } 484a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com case kSetState_Cmd: 485ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fStates[currState].restoreTo(&playbackState); 486a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com ++currState; 487a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com break; 488a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com case kSetClip_Cmd: 489beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com clipData.fClipStack = &fClips[currClip]; 490beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com clipData.fOrigin = fClipOrigins[currClip]; 4916e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->setClip(&clipData); 492a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com ++currClip; 493a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com break; 494a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com case kClear_Cmd: 4956e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->clear(&fClears[currClear].fRect, 4966e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fClears[currClear].fColor, 4976e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fClears[currClear].fRenderTarget); 498a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com ++currClear; 499a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com break; 500ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 501ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 502a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com // we should have consumed all the states, clips, etc. 503a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com GrAssert(fStates.count() == currState); 504a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com GrAssert(fClips.count() == currClip); 505beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com GrAssert(fClipOrigins.count() == currClip); 506a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com GrAssert(fClears.count() == currClear); 507a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com GrAssert(fDraws.count() == currDraw); 508a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com 5096e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com fDstGpu->setDrawState(prevDrawState); 510a5d056ae0b04021dfb44c2c7a3d6a34e060261b8bsalomon@google.com prevDrawState->unref(); 51155e4a2005eae1e4f677ec145c577c615a63cf05dbsalomon@google.com this->reset(); 512a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com return true; 513ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 514ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 51597805382d89b717de3355312a79a957ea4a864c9bsalomon@google.comvoid GrInOrderDrawBuffer::willReserveVertexAndIndexSpace( 51697805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com int vertexCount, 51797805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com int indexCount) { 5186e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com // We use geometryHints() to know whether to flush the draw buffer. We 5196e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com // can't flush if we are inside an unbalanced pushGeometrySource. 5206e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com // Moreover, flushing blows away vertex and index data that was 5216e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com // previously reserved. So if the vertex or index data is pulled from 5226e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com // reserved space and won't be released by this request then we can't 5236e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com // flush. 5246e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com bool insideGeoPush = fGeoPoolStateStack.count() > 1; 5256e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 5266e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com bool unreleasedVertexSpace = 5276e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com !vertexCount && 5286e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc; 5296e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 5306e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com bool unreleasedIndexSpace = 5316e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com !indexCount && 5326e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; 5336e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 5346e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com // we don't want to finalize any reserved geom on the target since 5356e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com // we don't know that the client has finished writing to it. 5366e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com bool targetHasReservedGeom = fDstGpu->hasReservedVerticesOrIndices(); 5376e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 5386e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com int vcount = vertexCount; 5396e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com int icount = indexCount; 5406e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 5416e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com if (!insideGeoPush && 5426e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com !unreleasedVertexSpace && 5436e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com !unreleasedIndexSpace && 5446e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com !targetHasReservedGeom && 5456e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com this->geometryHints(&vcount, &icount)) { 5466e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com 5476e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com this->flush(); 54897805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com } 54997805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com} 55097805382d89b717de3355312a79a957ea4a864c9bsalomon@google.com 551b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.combool GrInOrderDrawBuffer::geometryHints(int* vertexCount, 5521c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com int* indexCount) const { 5531c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com // we will recommend a flush if the data could fit in a single 5541c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com // preallocated buffer but none are left and it can't fit 5551c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com // in the current buffer (which may not be prealloced). 556ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com bool flush = false; 557ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (NULL != indexCount) { 5581c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com int32_t currIndices = fIndexPool.currentBufferIndices(); 5591c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com if (*indexCount > currIndices && 5601c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com (!fIndexPool.preallocatedBuffersRemaining() && 5611c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com *indexCount <= fIndexPool.preallocatedBufferIndices())) { 5621c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 5631c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com flush = true; 5641c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com } 5651c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com *indexCount = currIndices; 566ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 567ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com if (NULL != vertexCount) { 568b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com size_t vertexSize = this->getDrawState().getVertexSize(); 569a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.com int32_t currVertices = fVertexPool.currentBufferVertices(vertexSize); 5701c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com if (*vertexCount > currVertices && 5711c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com (!fVertexPool.preallocatedBuffersRemaining() && 572a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.com *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexSize))) { 5731c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 5741c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com flush = true; 575ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 5761c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com *vertexCount = currVertices; 577ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 578ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return flush; 579ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 580ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 581a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.combool GrInOrderDrawBuffer::onReserveVertexSpace(size_t vertexSize, 58225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com int vertexCount, 58325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com void** vertices) { 58425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.back(); 58525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(vertexCount > 0); 58625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(NULL != vertices); 58725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(0 == poolState.fUsedPoolVertexBytes); 588fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 589a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.com *vertices = fVertexPool.makeSpace(vertexSize, 59025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com vertexCount, 59125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com &poolState.fPoolVertexBuffer, 59225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com &poolState.fPoolStartVertex); 59325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com return NULL != *vertices; 59425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com} 595fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 59625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) { 59725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.back(); 59825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(indexCount > 0); 59925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(NULL != indices); 60025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(0 == poolState.fUsedPoolIndexBytes); 60125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com 60225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com *indices = fIndexPool.makeSpace(indexCount, 60325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com &poolState.fPoolIndexBuffer, 60425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com &poolState.fPoolStartIndex); 60525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com return NULL != *indices; 606ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 607ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 60825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedVertexSpace() { 60925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.back(); 610fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com const GeometrySrcState& geoSrc = this->getGeomSrc(); 611d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com 612d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com // If we get a release vertex space call then our current source should either be reserved 613d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com // or array (which we copied into reserved space). 614d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc || 615d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com kArray_GeometrySrcType == geoSrc.fVertexSrc); 6163f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com 6173f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // When the caller reserved vertex buffer space we gave it back a pointer 6183f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // provided by the vertex buffer pool. At each draw we tracked the largest 6193f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // offset into the pool's pointer that was referenced. Now we return to the 6203f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // pool any portion at the tail of the allocation that no draw referenced. 621b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com size_t reservedVertexBytes = geoSrc.fVertexSize * geoSrc.fVertexCount; 622fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com fVertexPool.putBack(reservedVertexBytes - 62325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fUsedPoolVertexBytes); 62425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fUsedPoolVertexBytes = 0; 6253f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com poolState.fPoolVertexBuffer = NULL; 6263f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com poolState.fPoolStartVertex = 0; 62725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com} 628ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 62925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::releaseReservedIndexSpace() { 63025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.back(); 631fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com const GeometrySrcState& geoSrc = this->getGeomSrc(); 6321c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 633d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com // If we get a release index space call then our current source should either be reserved 634d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com // or array (which we copied into reserved space). 635d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc || 636d57d71a5b857c273d9cf834856e10e663c1ccb91bsalomon@google.com kArray_GeometrySrcType == geoSrc.fIndexSrc); 6373f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com 6383f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // Similar to releaseReservedVertexSpace we return any unused portion at 6393f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // the tail 64025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount; 64125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes); 64225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fUsedPoolIndexBytes = 0; 6433f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com poolState.fPoolIndexBuffer = NULL; 6443f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com poolState.fPoolStartIndex = 0; 6451c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com} 646fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 647bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray, 648bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com int vertexCount) { 64925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com 65025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.back(); 65125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(0 == poolState.fUsedPoolVertexBytes); 6521c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG 6531c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com bool success = 6541c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif 655b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com fVertexPool.appendVertices(this->getVertexSize(), 6561c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com vertexCount, 6571c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com vertexArray, 65825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com &poolState.fPoolVertexBuffer, 65925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com &poolState.fPoolStartVertex); 6601c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com GR_DEBUGASSERT(success); 6611c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com} 6621c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com 663bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray, 664bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com int indexCount) { 66525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.back(); 66625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(0 == poolState.fUsedPoolIndexBytes); 6671c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#if GR_DEBUG 6681c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com bool success = 6691c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif 6701c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com fIndexPool.appendIndices(indexCount, 6711c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com indexArray, 67225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com &poolState.fPoolIndexBuffer, 67325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com &poolState.fPoolStartIndex); 6741c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com GR_DEBUGASSERT(success); 675ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 676ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 6773f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.comvoid GrInOrderDrawBuffer::releaseVertexArray() { 6783f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // When the client provides an array as the vertex source we handled it 6793f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // by copying their array into reserved space. 6803f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com this->GrInOrderDrawBuffer::releaseReservedVertexSpace(); 6813f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com} 6823f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com 6833f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.comvoid GrInOrderDrawBuffer::releaseIndexArray() { 6843f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // When the client provides an array as the index source we handled it 6853f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com // by copying their array into reserved space. 6863f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com this->GrInOrderDrawBuffer::releaseReservedIndexSpace(); 6873f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com} 6883f5a95e9745c5ea1f960d1454cf7df5942fa5dedbsalomon@google.com 68925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPush() { 69025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); 69125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fUsedPoolVertexBytes = 0; 69225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fUsedPoolIndexBytes = 0; 69325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#if GR_DEBUG 69425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; 69525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fPoolStartVertex = ~0; 69625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; 69725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com poolState.fPoolStartIndex = ~0; 69825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif 69925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com} 70025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com 70125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrInOrderDrawBuffer::geometrySourceWillPop( 70225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com const GeometrySrcState& restoredState) { 70325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GrAssert(fGeoPoolStateStack.count() > 1); 70425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com fGeoPoolStateStack.pop_back(); 70525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com GeometryPoolState& poolState = fGeoPoolStateStack.back(); 70625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com // we have to assume that any slack we had in our vertex/index data 70725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com // is now unreleasable because data may have been appended later in the 70825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com // pool. 70925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com if (kReserved_GeometrySrcType == restoredState.fVertexSrc || 71025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com kArray_GeometrySrcType == restoredState.fVertexSrc) { 711b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredState.fVertexCount; 71225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com } 71325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com if (kReserved_GeometrySrcType == restoredState.fIndexSrc || 71425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com kArray_GeometrySrcType == restoredState.fIndexSrc) { 715fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * 71625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com restoredState.fIndexCount; 71725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com } 71825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com} 71925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com 72086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewState() const { 721ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com return fStates.empty() || !fStates.back().isEqual(this->getDrawState()); 722ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 723ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com 72486afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.combool GrInOrderDrawBuffer::needsNewClip() const { 725358e427763f0971af436f07170c641f747b94595bsalomon@google.com GrAssert(fClips.count() == fClipOrigins.count()); 726358e427763f0971af436f07170c641f747b94595bsalomon@google.com if (this->getDrawState().isClipState()) { 727fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com if (fClipSet && 728358e427763f0971af436f07170c641f747b94595bsalomon@google.com (fClips.empty() || 72902ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com fClips.back() != *this->getClip()->fClipStack || 73002ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com fClipOrigins.back() != this->getClip()->fOrigin)) { 73186afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com return true; 73286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com } 733ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com } 734ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com return false; 735ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 736d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 737a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordClip() { 73802ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com fClips.push_back() = *this->getClip()->fClipStack; 73902ddc8b85ace91b15feb329a6a1d5d62b2b846c6bsalomon@google.com fClipOrigins.push_back() = this->getClip()->fOrigin; 74086afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com fClipSet = false; 741a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com fCmds.push_back(kSetClip_Cmd); 742a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com} 743a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com 744a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comvoid GrInOrderDrawBuffer::recordState() { 745ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com fStates.push_back().saveFrom(this->getDrawState()); 746a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com fCmds.push_back(kSetState_Cmd); 747a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com} 748a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com 74974749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.comGrInOrderDrawBuffer::DrawRecord* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info) { 750d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fCmds.push_back(kDraw_Cmd); 751d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com return &fDraws.push_back(info); 75274749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com} 75374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com 754ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.comGrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath() { 755ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com fCmds.push_back(kStencilPath_Cmd); 756ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com return &fStencilPaths.push_back(); 757ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com} 758ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com 759a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.comGrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear() { 760a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com fCmds.push_back(kClear_Cmd); 761a4f6b10818819a16bc94738e2eda42dfec332c43bsalomon@google.com return &fClears.push_back(); 76286afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com} 763d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com 764beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.comvoid GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) { 765beb1af78d016d2700c350487a383c6bcfa7e2e20robertphillips@google.com INHERITED::clipWillBeSet(newClipData); 76686afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.com fClipSet = true; 767d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com fClipProxyState = kUnknown_ClipProxyState; 768ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com} 769