GrInOrderDrawBuffer.cpp revision 18c9c198f571997463d9a7134dbd88298e592ec2
1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright 2011 Google Inc. 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license that can be 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * found in the LICENSE file. 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 113f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include "GrInOrderDrawBuffer.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "GrTexture.h" 13bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org#include "GrBufferAllocPool.h" 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "GrIndexBuffer.h" 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "GrVertexBuffer.h" 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "GrGpu.h" 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgGrInOrderDrawBuffer::GrInOrderDrawBuffer(const GrGpu* gpu, 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrVertexBufferAllocPool* vertexPool, 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrIndexBufferAllocPool* indexPool) 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : fDraws(&fDrawStorage) 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fStates(&fStateStorage) 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fClears(&fClearStorage) 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fClips(&fClipStorage) 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fClipSet(true) 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fLastRectVertexLayout(0) 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fQuadIndexBuffer(NULL) 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fMaxQuads(0) 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fCurrQuad(0) 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fVertexPool(*vertexPool) 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fIndexPool(*indexPool) 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org , fGeoPoolStateStack(&fGeoStackStorage) { 3564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fCaps = gpu->getCaps(); 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrAssert(NULL != vertexPool); 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrAssert(NULL != indexPool); 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); 4264a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org poolState.fUsedPoolVertexBytes = 0; 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poolState.fUsedPoolIndexBytes = 0; 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if GR_DEBUG 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poolState.fPoolStartVertex = ~0; 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org poolState.fPoolStartIndex = ~0; 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgGrInOrderDrawBuffer::~GrInOrderDrawBuffer() { 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org this->reset(); 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrSafeUnref(fQuadIndexBuffer); 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 56bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org 57bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.orgvoid GrInOrderDrawBuffer::initializeDrawStateAndClip(const GrDrawTarget& target) { 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org this->copyDrawState(target); 59bc669ace8f09d73e95f923253ecdadd366f9b7f1pbos@webrtc.org this->setClip(target.getClip()); 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid GrInOrderDrawBuffer::setQuadIndexBuffer(const GrIndexBuffer* indexBuffer) { 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool newIdxBuffer = fQuadIndexBuffer != indexBuffer; 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (newIdxBuffer) { 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrSafeUnref(fQuadIndexBuffer); 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fQuadIndexBuffer = indexBuffer; 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrSafeRef(fQuadIndexBuffer); 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fCurrQuad = 0; 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fMaxQuads = (NULL == indexBuffer) ? 0 : indexBuffer->maxQuads(); 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else { 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrAssert((NULL == indexBuffer && 0 == fMaxQuads) || 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (indexBuffer->maxQuads() == fMaxQuads)); 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid GrInOrderDrawBuffer::drawRect(const GrRect& rect, 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const GrMatrix* matrix, 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StageBitfield stageEnableBitfield, 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const GrRect* srcRects[], 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const GrMatrix* srcMatrices[]) { 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad)); 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrAssert(!(fDraws.empty() && fCurrQuad)); 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer)); 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // if we have a quad IB then either append to the previous run of 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // rects or start a new run 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (fMaxQuads) { 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool appendToPreviousDraw = false; 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrVertexLayout layout = GetRectVertexLayout(stageEnableBitfield, srcRects); 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org AutoReleaseGeometry geo(this, layout, 4, 0); 9364a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org if (!geo.succeeded()) { 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrPrintf("Failed to get space for vertices!\n"); 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 9764a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org AutoViewMatrixRestore avmr(this); 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrMatrix combinedMatrix = this->getViewMatrix(); 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org this->setViewMatrix(GrMatrix::I()); 10064a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org if (NULL != matrix) { 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org combinedMatrix.preConcat(*matrix); 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices, layout, geo.vertices()); 10564a144ff1bf67bc85942721aab04c98757b83e3bpbos@webrtc.org 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // we don't want to miss an opportunity to batch rects together 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // simply because the clip has changed if the clip doesn't affect 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // the rect. 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool disabledClip = false; 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (this->isClipState() && fClip.isRect()) { 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GrRect clipRect = fClip.getRect(0); 113 // If the clip rect touches the edge of the viewport, extended it 114 // out (close) to infinity to avoid bogus intersections. 115 // We might consider a more exact clip to viewport if this 116 // conservative test fails. 117 const GrRenderTarget* target = this->getRenderTarget(); 118 if (0 >= clipRect.fLeft) { 119 clipRect.fLeft = GR_ScalarMin; 120 } 121 if (target->width() <= clipRect.fRight) { 122 clipRect.fRight = GR_ScalarMax; 123 } 124 if (0 >= clipRect.top()) { 125 clipRect.fTop = GR_ScalarMin; 126 } 127 if (target->height() <= clipRect.fBottom) { 128 clipRect.fBottom = GR_ScalarMax; 129 } 130 int stride = VertexSize(layout); 131 bool insideClip = true; 132 for (int v = 0; v < 4; ++v) { 133 const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride); 134 if (!clipRect.contains(p)) { 135 insideClip = false; 136 break; 137 } 138 } 139 if (insideClip) { 140 this->disableState(kClip_StateBit); 141 disabledClip = true; 142 } 143 } 144 if (!needsNewClip() && !needsNewState() && fCurrQuad > 0 && 145 fCurrQuad < fMaxQuads && layout == fLastRectVertexLayout) { 146 147 int vsize = VertexSize(layout); 148 149 Draw& lastDraw = fDraws.back(); 150 151 GrAssert(lastDraw.fIndexBuffer == fQuadIndexBuffer); 152 GrAssert(kTriangles_PrimitiveType == lastDraw.fPrimitiveType); 153 GrAssert(0 == lastDraw.fVertexCount % 4); 154 GrAssert(0 == lastDraw.fIndexCount % 6); 155 GrAssert(0 == lastDraw.fStartIndex); 156 157 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 158 bool clearSinceLastDraw = 159 fClears.count() && 160 fClears.back().fBeforeDrawIdx == fDraws.count(); 161 162 appendToPreviousDraw = 163 !clearSinceLastDraw && 164 lastDraw.fVertexBuffer == poolState.fPoolVertexBuffer && 165 (fCurrQuad * 4 + lastDraw.fStartVertex) == poolState.fPoolStartVertex; 166 167 if (appendToPreviousDraw) { 168 lastDraw.fVertexCount += 4; 169 lastDraw.fIndexCount += 6; 170 fCurrQuad += 1; 171 // we reserved above, so we should be the first 172 // use of this vertex reserveation. 173 GrAssert(0 == poolState.fUsedPoolVertexBytes); 174 poolState.fUsedPoolVertexBytes = 4 * vsize; 175 } 176 } 177 if (!appendToPreviousDraw) { 178 this->setIndexSourceToBuffer(fQuadIndexBuffer); 179 drawIndexed(kTriangles_PrimitiveType, 0, 0, 4, 6); 180 fCurrQuad = 1; 181 fLastRectVertexLayout = layout; 182 } 183 if (disabledClip) { 184 this->enableState(kClip_StateBit); 185 } 186 } else { 187 INHERITED::drawRect(rect, matrix, stageEnableBitfield, srcRects, srcMatrices); 188 } 189} 190 191void GrInOrderDrawBuffer::onDrawIndexed(GrPrimitiveType primitiveType, 192 int startVertex, 193 int startIndex, 194 int vertexCount, 195 int indexCount) { 196 197 if (!vertexCount || !indexCount) { 198 return; 199 } 200 201 fCurrQuad = 0; 202 203 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 204 205 Draw& draw = fDraws.push_back(); 206 draw.fPrimitiveType = primitiveType; 207 draw.fStartVertex = startVertex; 208 draw.fStartIndex = startIndex; 209 draw.fVertexCount = vertexCount; 210 draw.fIndexCount = indexCount; 211 212 draw.fClipChanged = this->needsNewClip(); 213 if (draw.fClipChanged) { 214 this->pushClip(); 215 } 216 217 draw.fStateChanged = this->needsNewState(); 218 if (draw.fStateChanged) { 219 this->pushState(); 220 } 221 222 draw.fVertexLayout = this->getGeomSrc().fVertexLayout; 223 switch (this->getGeomSrc().fVertexSrc) { 224 case kBuffer_GeometrySrcType: 225 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer; 226 break; 227 case kReserved_GeometrySrcType: // fallthrough 228 case kArray_GeometrySrcType: { 229 size_t vertexBytes = (vertexCount + startVertex) * 230 VertexSize(this->getGeomSrc().fVertexLayout); 231 poolState.fUsedPoolVertexBytes = 232 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); 233 draw.fVertexBuffer = poolState.fPoolVertexBuffer; 234 draw.fStartVertex += poolState.fPoolStartVertex; 235 break; 236 } 237 default: 238 GrCrash("unknown geom src type"); 239 } 240 draw.fVertexBuffer->ref(); 241 242 switch (this->getGeomSrc().fIndexSrc) { 243 case kBuffer_GeometrySrcType: 244 draw.fIndexBuffer = this->getGeomSrc().fIndexBuffer; 245 break; 246 case kReserved_GeometrySrcType: // fallthrough 247 case kArray_GeometrySrcType: { 248 size_t indexBytes = (indexCount + startIndex) * sizeof(uint16_t); 249 poolState.fUsedPoolIndexBytes = 250 GrMax(poolState.fUsedPoolIndexBytes, indexBytes); 251 draw.fIndexBuffer = poolState.fPoolIndexBuffer; 252 draw.fStartIndex += poolState.fPoolStartVertex; 253 break; 254 } 255 default: 256 GrCrash("unknown geom src type"); 257 } 258 draw.fIndexBuffer->ref(); 259} 260 261void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType, 262 int startVertex, 263 int vertexCount) { 264 if (!vertexCount) { 265 return; 266 } 267 268 fCurrQuad = 0; 269 270 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 271 272 Draw& draw = fDraws.push_back(); 273 draw.fPrimitiveType = primitiveType; 274 draw.fStartVertex = startVertex; 275 draw.fStartIndex = 0; 276 draw.fVertexCount = vertexCount; 277 draw.fIndexCount = 0; 278 279 draw.fClipChanged = this->needsNewClip(); 280 if (draw.fClipChanged) { 281 this->pushClip(); 282 } 283 284 draw.fStateChanged = this->needsNewState(); 285 if (draw.fStateChanged) { 286 this->pushState(); 287 } 288 289 draw.fVertexLayout = this->getGeomSrc().fVertexLayout; 290 switch (this->getGeomSrc().fVertexSrc) { 291 case kBuffer_GeometrySrcType: 292 draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer; 293 break; 294 case kReserved_GeometrySrcType: // fallthrough 295 case kArray_GeometrySrcType: { 296 size_t vertexBytes = (vertexCount + startVertex) * 297 VertexSize(this->getGeomSrc().fVertexLayout); 298 poolState.fUsedPoolVertexBytes = 299 GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); 300 draw.fVertexBuffer = poolState.fPoolVertexBuffer; 301 draw.fStartVertex += poolState.fPoolStartVertex; 302 break; 303 } 304 default: 305 GrCrash("unknown geom src type"); 306 } 307 draw.fVertexBuffer->ref(); 308 draw.fIndexBuffer = NULL; 309} 310 311void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) { 312 GrIRect r; 313 if (NULL == rect) { 314 // We could do something smart and remove previous draws and clears to 315 // the current render target. If we get that smart we have to make sure 316 // those draws aren't read before this clear (render-to-texture). 317 r.setLTRB(0, 0, 318 this->getRenderTarget()->width(), 319 this->getRenderTarget()->height()); 320 rect = &r; 321 } 322 Clear& clr = fClears.push_back(); 323 clr.fColor = color; 324 clr.fBeforeDrawIdx = fDraws.count(); 325 clr.fRect = *rect; 326} 327 328void GrInOrderDrawBuffer::reset() { 329 GrAssert(1 == fGeoPoolStateStack.count()); 330 this->resetVertexSource(); 331 this->resetIndexSource(); 332 uint32_t numStates = fStates.count(); 333 for (uint32_t i = 0; i < numStates; ++i) { 334 const DrState& dstate = this->accessSavedDrawState(fStates[i]); 335 for (int s = 0; s < kNumStages; ++s) { 336 GrSafeUnref(dstate.fTextures[s]); 337 } 338 GrSafeUnref(dstate.fRenderTarget); 339 } 340 int numDraws = fDraws.count(); 341 for (int d = 0; d < numDraws; ++d) { 342 // we always have a VB, but not always an IB 343 GrAssert(NULL != fDraws[d].fVertexBuffer); 344 fDraws[d].fVertexBuffer->unref(); 345 GrSafeUnref(fDraws[d].fIndexBuffer); 346 } 347 fDraws.reset(); 348 fStates.reset(); 349 350 fClears.reset(); 351 352 fVertexPool.reset(); 353 fIndexPool.reset(); 354 355 fClips.reset(); 356 357 fCurrQuad = 0; 358} 359 360void GrInOrderDrawBuffer::playback(GrDrawTarget* target) { 361 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); 362 GrAssert(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); 363 GrAssert(NULL != target); 364 GrAssert(target != this); // not considered and why? 365 366 int numDraws = fDraws.count(); 367 if (!numDraws) { 368 return; 369 } 370 371 fVertexPool.unlock(); 372 fIndexPool.unlock(); 373 374 GrDrawTarget::AutoStateRestore asr(target); 375 GrDrawTarget::AutoClipRestore acr(target); 376 AutoGeometryPush agp(target); 377 378 int currState = ~0; 379 int currClip = ~0; 380 int currClear = 0; 381 382 for (int i = 0; i < numDraws; ++i) { 383 while (currClear < fClears.count() && 384 i == fClears[currClear].fBeforeDrawIdx) { 385 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor); 386 ++currClear; 387 } 388 389 const Draw& draw = fDraws[i]; 390 if (draw.fStateChanged) { 391 ++currState; 392 target->restoreDrawState(fStates[currState]); 393 } 394 if (draw.fClipChanged) { 395 ++currClip; 396 target->setClip(fClips[currClip]); 397 } 398 399 target->setVertexSourceToBuffer(draw.fVertexLayout, draw.fVertexBuffer); 400 401 if (draw.fIndexCount) { 402 target->setIndexSourceToBuffer(draw.fIndexBuffer); 403 } 404 405 if (draw.fIndexCount) { 406 target->drawIndexed(draw.fPrimitiveType, 407 draw.fStartVertex, 408 draw.fStartIndex, 409 draw.fVertexCount, 410 draw.fIndexCount); 411 } else { 412 target->drawNonIndexed(draw.fPrimitiveType, 413 draw.fStartVertex, 414 draw.fVertexCount); 415 } 416 } 417 while (currClear < fClears.count()) { 418 GrAssert(fDraws.count() == fClears[currClear].fBeforeDrawIdx); 419 target->clear(&fClears[currClear].fRect, fClears[currClear].fColor); 420 ++currClear; 421 } 422} 423 424bool GrInOrderDrawBuffer::geometryHints(GrVertexLayout vertexLayout, 425 int* vertexCount, 426 int* indexCount) const { 427 // we will recommend a flush if the data could fit in a single 428 // preallocated buffer but none are left and it can't fit 429 // in the current buffer (which may not be prealloced). 430 bool flush = false; 431 if (NULL != indexCount) { 432 int32_t currIndices = fIndexPool.currentBufferIndices(); 433 if (*indexCount > currIndices && 434 (!fIndexPool.preallocatedBuffersRemaining() && 435 *indexCount <= fIndexPool.preallocatedBufferIndices())) { 436 437 flush = true; 438 } 439 *indexCount = currIndices; 440 } 441 if (NULL != vertexCount) { 442 int32_t currVertices = fVertexPool.currentBufferVertices(vertexLayout); 443 if (*vertexCount > currVertices && 444 (!fVertexPool.preallocatedBuffersRemaining() && 445 *vertexCount <= fVertexPool.preallocatedBufferVertices(vertexLayout))) { 446 447 flush = true; 448 } 449 *vertexCount = currVertices; 450 } 451 return flush; 452} 453 454bool GrInOrderDrawBuffer::onReserveVertexSpace(GrVertexLayout vertexLayout, 455 int vertexCount, 456 void** vertices) { 457 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 458 GrAssert(vertexCount > 0); 459 GrAssert(NULL != vertices); 460 GrAssert(0 == poolState.fUsedPoolVertexBytes); 461 462 *vertices = fVertexPool.makeSpace(vertexLayout, 463 vertexCount, 464 &poolState.fPoolVertexBuffer, 465 &poolState.fPoolStartVertex); 466 return NULL != *vertices; 467} 468 469bool GrInOrderDrawBuffer::onReserveIndexSpace(int indexCount, void** indices) { 470 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 471 GrAssert(indexCount > 0); 472 GrAssert(NULL != indices); 473 GrAssert(0 == poolState.fUsedPoolIndexBytes); 474 475 *indices = fIndexPool.makeSpace(indexCount, 476 &poolState.fPoolIndexBuffer, 477 &poolState.fPoolStartIndex); 478 return NULL != *indices; 479} 480 481void GrInOrderDrawBuffer::releaseReservedVertexSpace() { 482 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 483 const GeometrySrcState& geoSrc = this->getGeomSrc(); 484 485 GrAssert(kReserved_GeometrySrcType == geoSrc.fVertexSrc); 486 487 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) * 488 geoSrc.fVertexCount; 489 fVertexPool.putBack(reservedVertexBytes - 490 poolState.fUsedPoolVertexBytes); 491 poolState.fUsedPoolVertexBytes = 0; 492 poolState.fPoolVertexBuffer = 0; 493} 494 495void GrInOrderDrawBuffer::releaseReservedIndexSpace() { 496 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 497 const GeometrySrcState& geoSrc = this->getGeomSrc(); 498 499 GrAssert(kReserved_GeometrySrcType == geoSrc.fIndexSrc); 500 501 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount; 502 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes); 503 poolState.fUsedPoolIndexBytes = 0; 504 poolState.fPoolStartVertex = 0; 505} 506 507void GrInOrderDrawBuffer::onSetVertexSourceToArray(const void* vertexArray, 508 int vertexCount) { 509 510 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 511 GrAssert(0 == poolState.fUsedPoolVertexBytes); 512#if GR_DEBUG 513 bool success = 514#endif 515 fVertexPool.appendVertices(this->getGeomSrc().fVertexLayout, 516 vertexCount, 517 vertexArray, 518 &poolState.fPoolVertexBuffer, 519 &poolState.fPoolStartVertex); 520 GR_DEBUGASSERT(success); 521} 522 523void GrInOrderDrawBuffer::onSetIndexSourceToArray(const void* indexArray, 524 int indexCount) { 525 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 526 GrAssert(0 == poolState.fUsedPoolIndexBytes); 527#if GR_DEBUG 528 bool success = 529#endif 530 fIndexPool.appendIndices(indexCount, 531 indexArray, 532 &poolState.fPoolIndexBuffer, 533 &poolState.fPoolStartIndex); 534 GR_DEBUGASSERT(success); 535} 536 537void GrInOrderDrawBuffer::geometrySourceWillPush() { 538 GeometryPoolState& poolState = fGeoPoolStateStack.push_back(); 539 poolState.fUsedPoolVertexBytes = 0; 540 poolState.fUsedPoolIndexBytes = 0; 541#if GR_DEBUG 542 poolState.fPoolVertexBuffer = (GrVertexBuffer*)~0; 543 poolState.fPoolStartVertex = ~0; 544 poolState.fPoolIndexBuffer = (GrIndexBuffer*)~0; 545 poolState.fPoolStartIndex = ~0; 546#endif 547} 548 549void GrInOrderDrawBuffer::releaseVertexArray() { 550 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 551 const GeometrySrcState& geoSrc = this->getGeomSrc(); 552 553 size_t reservedVertexBytes = VertexSize(geoSrc.fVertexLayout) * 554 geoSrc.fVertexCount; 555 fVertexPool.putBack(reservedVertexBytes - poolState.fUsedPoolVertexBytes); 556 557 poolState.fUsedPoolVertexBytes = 0; 558} 559 560void GrInOrderDrawBuffer::releaseIndexArray() { 561 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 562 const GeometrySrcState& geoSrc = this->getGeomSrc(); 563 564 size_t reservedIndexBytes = sizeof(uint16_t) * geoSrc.fIndexCount; 565 fIndexPool.putBack(reservedIndexBytes - poolState.fUsedPoolIndexBytes); 566 567 poolState.fUsedPoolIndexBytes = 0; 568} 569 570void GrInOrderDrawBuffer::geometrySourceWillPop( 571 const GeometrySrcState& restoredState) { 572 GrAssert(fGeoPoolStateStack.count() > 1); 573 fGeoPoolStateStack.pop_back(); 574 GeometryPoolState& poolState = fGeoPoolStateStack.back(); 575 // we have to assume that any slack we had in our vertex/index data 576 // is now unreleasable because data may have been appended later in the 577 // pool. 578 if (kReserved_GeometrySrcType == restoredState.fVertexSrc || 579 kArray_GeometrySrcType == restoredState.fVertexSrc) { 580 poolState.fUsedPoolVertexBytes = 581 VertexSize(restoredState.fVertexLayout) * 582 restoredState.fVertexCount; 583 } 584 if (kReserved_GeometrySrcType == restoredState.fIndexSrc || 585 kArray_GeometrySrcType == restoredState.fIndexSrc) { 586 poolState.fUsedPoolVertexBytes = sizeof(uint16_t) * 587 restoredState.fIndexCount; 588 } 589} 590 591bool GrInOrderDrawBuffer::needsNewState() const { 592 if (fStates.empty()) { 593 return true; 594 } else { 595 const DrState& old = this->accessSavedDrawState(fStates.back()); 596 return old != fCurrDrawState; 597 } 598} 599 600void GrInOrderDrawBuffer::pushState() { 601 for (int s = 0; s < kNumStages; ++s) { 602 GrSafeRef(fCurrDrawState.fTextures[s]); 603 } 604 GrSafeRef(fCurrDrawState.fRenderTarget); 605 this->saveCurrentDrawState(&fStates.push_back()); 606 } 607 608bool GrInOrderDrawBuffer::needsNewClip() const { 609 if (fCurrDrawState.fFlagBits & kClip_StateBit) { 610 if (fClips.empty() || (fClipSet && fClips.back() != fClip)) { 611 return true; 612 } 613 } 614 return false; 615} 616 617void GrInOrderDrawBuffer::pushClip() { 618 fClips.push_back() = fClip; 619 fClipSet = false; 620} 621 622void GrInOrderDrawBuffer::clipWillBeSet(const GrClip& newClip) { 623 INHERITED::clipWillBeSet(newClip); 624 fClipSet = true; 625} 626 627bool GrInOrderDrawBuffer::willUseHWAALines() const { 628 return this->getCaps().fHWAALineSupport && 629 CanUseHWAALines(this->getGeomSrc().fVertexLayout, fCurrDrawState); 630} 631 632