| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrInOrderDrawBuffer.h" | 8 #include "GrInOrderDrawBuffer.h" |
| 9 | 9 |
| 10 #include "GrBufferAllocPool.h" | 10 #include "GrBufferAllocPool.h" |
| 11 #include "GrDrawTargetCaps.h" | 11 #include "GrDrawTargetCaps.h" |
| 12 #include "GrTextStrike.h" | 12 #include "GrTextStrike.h" |
| 13 #include "GrGpu.h" | 13 #include "GrGpu.h" |
| 14 #include "GrTemplates.h" | 14 #include "GrTemplates.h" |
| 15 #include "GrTexture.h" | 15 #include "GrTexture.h" |
| 16 | 16 |
| 17 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, | 17 GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu, |
| 18 GrVertexBufferAllocPool* vertexPool, | 18 GrVertexBufferAllocPool* vertexPool, |
| 19 GrIndexBufferAllocPool* indexPool) | 19 GrIndexBufferAllocPool* indexPool) |
| 20 : GrDrawTarget(gpu->getContext()) | 20 : GrDrawTarget(gpu->getContext()) |
| 21 , fCmdBuffer(kCmdBufferInitialSizeInBytes) |
| 22 , fLastState(NULL) |
| 23 , fLastClip(NULL) |
| 21 , fDstGpu(gpu) | 24 , fDstGpu(gpu) |
| 22 , fClipSet(true) | 25 , fClipSet(true) |
| 23 , fClipProxyState(kUnknown_ClipProxyState) | 26 , fClipProxyState(kUnknown_ClipProxyState) |
| 24 , fVertexPool(*vertexPool) | 27 , fVertexPool(*vertexPool) |
| 25 , fIndexPool(*indexPool) | 28 , fIndexPool(*indexPool) |
| 26 , fFlushing(false) | 29 , fFlushing(false) |
| 27 , fDrawID(0) { | 30 , fDrawID(0) { |
| 28 | 31 |
| 29 fDstGpu->ref(); | 32 fDstGpu->ref(); |
| 30 fCaps.reset(SkRef(fDstGpu->caps())); | 33 fCaps.reset(SkRef(fDstGpu->caps())); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 return fClipProxy.contains(devBounds); | 212 return fClipProxy.contains(devBounds); |
| 210 } | 213 } |
| 211 SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX), | 214 SkPoint originOffset = {SkIntToScalar(this->getClip()->fOrigin.fX), |
| 212 SkIntToScalar(this->getClip()->fOrigin.fY)}; | 215 SkIntToScalar(this->getClip()->fOrigin.fY)}; |
| 213 SkRect clipSpaceBounds = devBounds; | 216 SkRect clipSpaceBounds = devBounds; |
| 214 clipSpaceBounds.offset(originOffset); | 217 clipSpaceBounds.offset(originOffset); |
| 215 return this->getClip()->fClipStack->quickContains(clipSpaceBounds); | 218 return this->getClip()->fClipStack->quickContains(clipSpaceBounds); |
| 216 } | 219 } |
| 217 | 220 |
| 218 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { | 221 int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info) { |
| 222 SkASSERT(!fCmdBuffer.empty()); |
| 219 SkASSERT(info.isInstanced()); | 223 SkASSERT(info.isInstanced()); |
| 220 | 224 |
| 221 const GeometrySrcState& geomSrc = this->getGeomSrc(); | 225 const GeometrySrcState& geomSrc = this->getGeomSrc(); |
| 222 const GrDrawState& drawState = this->getDrawState(); | 226 const GrDrawState& drawState = this->getDrawState(); |
| 223 | 227 |
| 224 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index | 228 // we only attempt to concat the case when reserved verts are used with a cl
ient-specified index |
| 225 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated | 229 // buffer. To make this work with client-specified VBs we'd need to know if
the VB was updated |
| 226 // between draws. | 230 // between draws. |
| 227 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || | 231 if (kReserved_GeometrySrcType != geomSrc.fVertexSrc || |
| 228 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { | 232 kBuffer_GeometrySrcType != geomSrc.fIndexSrc) { |
| 229 return 0; | 233 return 0; |
| 230 } | 234 } |
| 231 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and | 235 // Check if there is a draw info that is compatible that uses the same VB fr
om the pool and |
| 232 // the same IB | 236 // the same IB |
| 233 if (kDraw_Cmd != strip_trace_bit(fCmds.back())) { | 237 if (kDraw_Cmd != strip_trace_bit(fCmdBuffer.back().type())) { |
| 234 return 0; | 238 return 0; |
| 235 } | 239 } |
| 236 | 240 |
| 237 Draw* draw = &fDraws.back(); | 241 Draw* draw = static_cast<Draw*>(&fCmdBuffer.back()); |
| 238 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 242 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
| 239 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; | 243 const GrVertexBuffer* vertexBuffer = poolState.fPoolVertexBuffer; |
| 240 | 244 |
| 241 if (!draw->isInstanced() || | 245 if (!draw->isInstanced() || |
| 242 draw->verticesPerInstance() != info.verticesPerInstance() || | 246 draw->verticesPerInstance() != info.verticesPerInstance() || |
| 243 draw->indicesPerInstance() != info.indicesPerInstance() || | 247 draw->indicesPerInstance() != info.indicesPerInstance() || |
| 244 draw->vertexBuffer() != vertexBuffer || | 248 draw->vertexBuffer() != vertexBuffer || |
| 245 draw->indexBuffer() != geomSrc.fIndexBuffer) { | 249 draw->indexBuffer() != geomSrc.fIndexBuffer) { |
| 246 return 0; | 250 return 0; |
| 247 } | 251 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 261 | 265 |
| 262 // update the amount of reserved vertex data actually referenced in draws | 266 // update the amount of reserved vertex data actually referenced in draws |
| 263 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * | 267 size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * |
| 264 drawState.getVertexStride(); | 268 drawState.getVertexStride(); |
| 265 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); | 269 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vert
exBytes); |
| 266 | 270 |
| 267 draw->adjustInstanceCount(instancesToConcat); | 271 draw->adjustInstanceCount(instancesToConcat); |
| 268 | 272 |
| 269 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added | 273 // update last fGpuCmdMarkers to include any additional trace markers that h
ave been added |
| 270 if (this->getActiveTraceMarkers().count() > 0) { | 274 if (this->getActiveTraceMarkers().count() > 0) { |
| 271 if (cmd_has_trace_marker(fCmds.back())) { | 275 if (cmd_has_trace_marker(draw->type())) { |
| 272 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); | 276 fGpuCmdMarkers.back().addSet(this->getActiveTraceMarkers()); |
| 273 } else { | 277 } else { |
| 274 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); | 278 fGpuCmdMarkers.push_back(this->getActiveTraceMarkers()); |
| 275 fCmds.back() = add_trace_bit(fCmds.back()); | 279 draw->resetType(add_trace_bit(draw->type())); |
| 276 } | 280 } |
| 277 } | 281 } |
| 278 | 282 |
| 279 return instancesToConcat; | 283 return instancesToConcat; |
| 280 } | 284 } |
| 281 | 285 |
| 282 class AutoClipReenable { | 286 class AutoClipReenable { |
| 283 public: | 287 public: |
| 284 AutoClipReenable() : fDrawState(NULL) {} | 288 AutoClipReenable() : fDrawState(NULL) {} |
| 285 ~AutoClipReenable() { | 289 ~AutoClipReenable() { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 302 GeometryPoolState& poolState = fGeoPoolStateStack.back(); | 306 GeometryPoolState& poolState = fGeoPoolStateStack.back(); |
| 303 const GrDrawState& drawState = this->getDrawState(); | 307 const GrDrawState& drawState = this->getDrawState(); |
| 304 AutoClipReenable acr; | 308 AutoClipReenable acr; |
| 305 | 309 |
| 306 if (drawState.isClipState() && | 310 if (drawState.isClipState() && |
| 307 info.getDevBounds() && | 311 info.getDevBounds() && |
| 308 this->quickInsideClip(*info.getDevBounds())) { | 312 this->quickInsideClip(*info.getDevBounds())) { |
| 309 acr.set(this->drawState()); | 313 acr.set(this->drawState()); |
| 310 } | 314 } |
| 311 | 315 |
| 312 if (this->needsNewClip()) { | 316 this->recordClipIfNecessary(); |
| 313 this->recordClip(); | |
| 314 } | |
| 315 this->recordStateIfNecessary(); | 317 this->recordStateIfNecessary(); |
| 316 | 318 |
| 317 const GrVertexBuffer* vb; | 319 const GrVertexBuffer* vb; |
| 318 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { | 320 if (kBuffer_GeometrySrcType == this->getGeomSrc().fVertexSrc) { |
| 319 vb = this->getGeomSrc().fVertexBuffer; | 321 vb = this->getGeomSrc().fVertexBuffer; |
| 320 } else { | 322 } else { |
| 321 vb = poolState.fPoolVertexBuffer; | 323 vb = poolState.fPoolVertexBuffer; |
| 322 } | 324 } |
| 323 | 325 |
| 324 const GrIndexBuffer* ib = NULL; | 326 const GrIndexBuffer* ib = NULL; |
| 325 if (info.isIndexed()) { | 327 if (info.isIndexed()) { |
| 326 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { | 328 if (kBuffer_GeometrySrcType == this->getGeomSrc().fIndexSrc) { |
| 327 ib = this->getGeomSrc().fIndexBuffer; | 329 ib = this->getGeomSrc().fIndexBuffer; |
| 328 } else { | 330 } else { |
| 329 ib = poolState.fPoolIndexBuffer; | 331 ib = poolState.fPoolIndexBuffer; |
| 330 } | 332 } |
| 331 } | 333 } |
| 332 | 334 |
| 333 Draw* draw; | 335 Draw* draw; |
| 334 if (info.isInstanced()) { | 336 if (info.isInstanced()) { |
| 335 int instancesConcated = this->concatInstancedDraw(info); | 337 int instancesConcated = this->concatInstancedDraw(info); |
| 336 if (info.instanceCount() > instancesConcated) { | 338 if (info.instanceCount() > instancesConcated) { |
| 337 draw = this->recordDraw(info, vb, ib); | 339 draw = &fCmdBuffer.push_back<Draw>(info, vb, ib); |
| 338 draw->adjustInstanceCount(-instancesConcated); | 340 draw->adjustInstanceCount(-instancesConcated); |
| 339 } else { | 341 } else { |
| 340 return; | 342 return; |
| 341 } | 343 } |
| 342 } else { | 344 } else { |
| 343 draw = this->recordDraw(info, vb, ib); | 345 draw = &fCmdBuffer.push_back<Draw>(info, vb, ib); |
| 344 } | 346 } |
| 347 this->recordTraceMarkersIfNecessary(); |
| 345 | 348 |
| 346 // Adjust the starting vertex and index when we are using reserved or array
sources to | 349 // Adjust the starting vertex and index when we are using reserved or array
sources to |
| 347 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. | 350 // compensate for the fact that the data was inserted into a larger vb/ib ow
ned by the pool. |
| 348 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { | 351 if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) { |
| 349 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get
VertexStride(); | 352 size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.get
VertexStride(); |
| 350 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); | 353 poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes,
bytes); |
| 351 draw->adjustStartVertex(poolState.fPoolStartVertex); | 354 draw->adjustStartVertex(poolState.fPoolStartVertex); |
| 352 } | 355 } |
| 353 | 356 |
| 354 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { | 357 if (info.isIndexed() && kBuffer_GeometrySrcType != this->getGeomSrc().fIndex
Src) { |
| 355 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); | 358 size_t bytes = (info.indexCount() + info.startIndex()) * sizeof(uint16_t
); |
| 356 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); | 359 poolState.fUsedPoolIndexBytes = SkTMax(poolState.fUsedPoolIndexBytes, by
tes); |
| 357 draw->adjustStartIndex(poolState.fPoolStartIndex); | 360 draw->adjustStartIndex(poolState.fPoolStartIndex); |
| 358 } | 361 } |
| 359 } | 362 } |
| 360 | 363 |
| 361 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil
l) { | 364 void GrInOrderDrawBuffer::onStencilPath(const GrPath* path, SkPath::FillType fil
l) { |
| 362 if (this->needsNewClip()) { | 365 this->recordClipIfNecessary(); |
| 363 this->recordClip(); | |
| 364 } | |
| 365 // Only compare the subset of GrDrawState relevant to path stenciling? | 366 // Only compare the subset of GrDrawState relevant to path stenciling? |
| 366 this->recordStateIfNecessary(); | 367 this->recordStateIfNecessary(); |
| 367 StencilPath* sp = this->recordStencilPath(path); | 368 StencilPath& sp = fCmdBuffer.push_back<StencilPath>(path); |
| 368 sp->fFill = fill; | 369 sp.fFill = fill; |
| 370 this->recordTraceMarkersIfNecessary(); |
| 369 } | 371 } |
| 370 | 372 |
| 371 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, | 373 void GrInOrderDrawBuffer::onDrawPath(const GrPath* path, |
| 372 SkPath::FillType fill, const GrDeviceCoordT
exture* dstCopy) { | 374 SkPath::FillType fill, const GrDeviceCoordT
exture* dstCopy) { |
| 373 if (this->needsNewClip()) { | 375 this->recordClipIfNecessary(); |
| 374 this->recordClip(); | |
| 375 } | |
| 376 // TODO: Only compare the subset of GrDrawState relevant to path covering? | 376 // TODO: Only compare the subset of GrDrawState relevant to path covering? |
| 377 this->recordStateIfNecessary(); | 377 this->recordStateIfNecessary(); |
| 378 DrawPath* cp = this->recordDrawPath(path); | 378 DrawPath& dp = fCmdBuffer.push_back<DrawPath>(path); |
| 379 cp->fFill = fill; | 379 dp.fFill = fill; |
| 380 if (dstCopy) { | 380 if (dstCopy) { |
| 381 cp->fDstCopy = *dstCopy; | 381 dp.fDstCopy = *dstCopy; |
| 382 } | 382 } |
| 383 this->recordTraceMarkersIfNecessary(); |
| 383 } | 384 } |
| 384 | 385 |
| 385 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, | 386 void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange, |
| 386 const uint32_t indices[], int count, | 387 const uint32_t indices[], int count, |
| 387 const float transforms[], PathTransformTyp
e transformsType, | 388 const float transforms[], PathTransformTyp
e transformsType, |
| 388 SkPath::FillType fill, const GrDeviceCoord
Texture* dstCopy) { | 389 SkPath::FillType fill, const GrDeviceCoord
Texture* dstCopy) { |
| 389 SkASSERT(pathRange); | 390 SkASSERT(pathRange); |
| 390 SkASSERT(indices); | 391 SkASSERT(indices); |
| 391 SkASSERT(transforms); | 392 SkASSERT(transforms); |
| 392 | 393 |
| 393 if (this->needsNewClip()) { | 394 this->recordClipIfNecessary(); |
| 394 this->recordClip(); | 395 this->recordStateIfNecessary(); |
| 396 |
| 397 int indicesSize = count * sizeof(uint32_t); |
| 398 int transformsSize = count * GrPathRendering::PathTransformSize(transformsTy
pe) * sizeof(float); |
| 399 int sizeInBytes = sizeof(DrawPaths) + indicesSize + transformsSize; |
| 400 |
| 401 DrawPaths& dp = fCmdBuffer.push_back_size<DrawPaths>(sizeInBytes, pathRange)
; |
| 402 memcpy(dp.indices(), indices, indicesSize); |
| 403 dp.fCount = count; |
| 404 memcpy(dp.transforms(), transforms, transformsSize); |
| 405 dp.fTransformsType = transformsType; |
| 406 dp.fFill = fill; |
| 407 if (NULL != dstCopy) { |
| 408 dp.fDstCopy = *dstCopy; |
| 395 } | 409 } |
| 396 this->recordStateIfNecessary(); | |
| 397 DrawPaths* dp = this->recordDrawPaths(pathRange); | |
| 398 dp->fIndices = SkNEW_ARRAY(uint32_t, count); // TODO: Accomplish this withou
t a malloc | |
| 399 memcpy(dp->fIndices, indices, sizeof(uint32_t) * count); | |
| 400 dp->fCount = count; | |
| 401 | 410 |
| 402 const int transformsLength = GrPathRendering::PathTransformSize(transformsTy
pe) * count; | 411 this->recordTraceMarkersIfNecessary(); |
| 403 dp->fTransforms = SkNEW_ARRAY(float, transformsLength); | |
| 404 memcpy(dp->fTransforms, transforms, sizeof(float) * transformsLength); | |
| 405 dp->fTransformsType = transformsType; | |
| 406 | |
| 407 dp->fFill = fill; | |
| 408 | |
| 409 if (dstCopy) { | |
| 410 dp->fDstCopy = *dstCopy; | |
| 411 } | |
| 412 } | 412 } |
| 413 | 413 |
| 414 void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, | 414 void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, |
| 415 bool canIgnoreRect, GrRenderTarget* renderTarget
) { | 415 bool canIgnoreRect, GrRenderTarget* renderTarget
) { |
| 416 SkIRect r; | 416 SkIRect r; |
| 417 if (NULL == renderTarget) { | 417 if (NULL == renderTarget) { |
| 418 renderTarget = this->drawState()->getRenderTarget(); | 418 renderTarget = this->drawState()->getRenderTarget(); |
| 419 SkASSERT(renderTarget); | 419 SkASSERT(renderTarget); |
| 420 } | 420 } |
| 421 if (NULL == rect) { | 421 if (NULL == rect) { |
| 422 // We could do something smart and remove previous draws and clears to | 422 // We could do something smart and remove previous draws and clears to |
| 423 // the current render target. If we get that smart we have to make sure | 423 // the current render target. If we get that smart we have to make sure |
| 424 // those draws aren't read before this clear (render-to-texture). | 424 // those draws aren't read before this clear (render-to-texture). |
| 425 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); | 425 r.setLTRB(0, 0, renderTarget->width(), renderTarget->height()); |
| 426 rect = &r; | 426 rect = &r; |
| 427 } | 427 } |
| 428 Clear* clr = this->recordClear(renderTarget); | 428 Clear& clr = fCmdBuffer.push_back<Clear>(renderTarget); |
| 429 GrColorIsPMAssert(color); | 429 GrColorIsPMAssert(color); |
| 430 clr->fColor = color; | 430 clr.fColor = color; |
| 431 clr->fRect = *rect; | 431 clr.fRect = *rect; |
| 432 clr->fCanIgnoreRect = canIgnoreRect; | 432 clr.fCanIgnoreRect = canIgnoreRect; |
| 433 this->recordTraceMarkersIfNecessary(); |
| 433 } | 434 } |
| 434 | 435 |
| 435 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { | 436 void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) { |
| 436 if (!this->caps()->discardRenderTargetSupport()) { | 437 if (!this->caps()->discardRenderTargetSupport()) { |
| 437 return; | 438 return; |
| 438 } | 439 } |
| 439 if (NULL == renderTarget) { | 440 if (NULL == renderTarget) { |
| 440 renderTarget = this->drawState()->getRenderTarget(); | 441 renderTarget = this->drawState()->getRenderTarget(); |
| 441 SkASSERT(renderTarget); | 442 SkASSERT(renderTarget); |
| 442 } | 443 } |
| 443 Clear* clr = this->recordClear(renderTarget); | 444 Clear& clr = fCmdBuffer.push_back<Clear>(renderTarget); |
| 444 clr->fColor = GrColor_ILLEGAL; | 445 clr.fColor = GrColor_ILLEGAL; |
| 446 this->recordTraceMarkersIfNecessary(); |
| 445 } | 447 } |
| 446 | 448 |
| 447 void GrInOrderDrawBuffer::reset() { | 449 void GrInOrderDrawBuffer::reset() { |
| 448 SkASSERT(1 == fGeoPoolStateStack.count()); | 450 SkASSERT(1 == fGeoPoolStateStack.count()); |
| 449 this->resetVertexSource(); | 451 this->resetVertexSource(); |
| 450 this->resetIndexSource(); | 452 this->resetIndexSource(); |
| 451 | 453 |
| 452 fCmds.reset(); | 454 fCmdBuffer.reset(); |
| 453 fDraws.reset(); | 455 fLastState = NULL; |
| 454 fStencilPaths.reset(); | 456 fLastClip = NULL; |
| 455 fDrawPath.reset(); | |
| 456 fDrawPaths.reset(); | |
| 457 fStates.reset(); | |
| 458 fClears.reset(); | |
| 459 fVertexPool.reset(); | 457 fVertexPool.reset(); |
| 460 fIndexPool.reset(); | 458 fIndexPool.reset(); |
| 461 fClips.reset(); | |
| 462 fCopySurfaces.reset(); | |
| 463 fGpuCmdMarkers.reset(); | 459 fGpuCmdMarkers.reset(); |
| 464 fClipSet = true; | 460 fClipSet = true; |
| 465 } | 461 } |
| 466 | 462 |
| 467 void GrInOrderDrawBuffer::flush() { | 463 void GrInOrderDrawBuffer::flush() { |
| 468 if (fFlushing) { | 464 if (fFlushing) { |
| 469 return; | 465 return; |
| 470 } | 466 } |
| 471 | 467 |
| 472 this->getContext()->getFontCache()->updateTextures(); | 468 this->getContext()->getFontCache()->updateTextures(); |
| 473 | 469 |
| 474 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); | 470 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fVertexSrc); |
| 475 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); | 471 SkASSERT(kReserved_GeometrySrcType != this->getGeomSrc().fIndexSrc); |
| 476 | 472 |
| 477 int numCmds = fCmds.count(); | 473 if (fCmdBuffer.empty()) { |
| 478 if (0 == numCmds) { | |
| 479 return; | 474 return; |
| 480 } | 475 } |
| 481 | 476 |
| 482 GrAutoTRestore<bool> flushRestore(&fFlushing); | 477 GrAutoTRestore<bool> flushRestore(&fFlushing); |
| 483 fFlushing = true; | 478 fFlushing = true; |
| 484 | 479 |
| 485 fVertexPool.unmap(); | 480 fVertexPool.unmap(); |
| 486 fIndexPool.unmap(); | 481 fIndexPool.unmap(); |
| 487 | 482 |
| 488 GrDrawTarget::AutoClipRestore acr(fDstGpu); | 483 GrDrawTarget::AutoClipRestore acr(fDstGpu); |
| 489 AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit); | 484 AutoGeometryAndStatePush agasp(fDstGpu, kPreserve_ASRInit); |
| 490 | 485 |
| 491 GrDrawState* prevDrawState = SkRef(fDstGpu->drawState()); | 486 GrDrawState* prevDrawState = SkRef(fDstGpu->drawState()); |
| 492 | 487 |
| 493 GrClipData clipData; | 488 CmdBuffer::Iter iter(fCmdBuffer); |
| 494 | 489 |
| 495 StateAllocator::Iter stateIter(&fStates); | 490 int currCmdMarker = 0; |
| 496 ClipAllocator::Iter clipIter(&fClips); | 491 fDstGpu->saveActiveTraceMarkers(); |
| 497 ClearAllocator::Iter clearIter(&fClears); | |
| 498 DrawAllocator::Iter drawIter(&fDraws); | |
| 499 StencilPathAllocator::Iter stencilPathIter(&fStencilPaths); | |
| 500 DrawPathAllocator::Iter drawPathIter(&fDrawPath); | |
| 501 DrawPathsAllocator::Iter drawPathsIter(&fDrawPaths); | |
| 502 CopySurfaceAllocator::Iter copySurfaceIter(&fCopySurfaces); | |
| 503 | 492 |
| 504 int currCmdMarker = 0; | 493 while (iter.next()) { |
| 505 | |
| 506 fDstGpu->saveActiveTraceMarkers(); | |
| 507 for (int c = 0; c < numCmds; ++c) { | |
| 508 GrGpuTraceMarker newMarker("", -1); | 494 GrGpuTraceMarker newMarker("", -1); |
| 509 SkString traceString; | 495 SkString traceString; |
| 510 if (cmd_has_trace_marker(fCmds[c])) { | 496 if (cmd_has_trace_marker(iter->type())) { |
| 511 traceString = fGpuCmdMarkers[currCmdMarker].toString(); | 497 traceString = fGpuCmdMarkers[currCmdMarker].toString(); |
| 512 newMarker.fMarker = traceString.c_str(); | 498 newMarker.fMarker = traceString.c_str(); |
| 513 fDstGpu->addGpuTraceMarker(&newMarker); | 499 fDstGpu->addGpuTraceMarker(&newMarker); |
| 514 ++currCmdMarker; | 500 ++currCmdMarker; |
| 515 } | 501 } |
| 516 switch (strip_trace_bit(fCmds[c])) { | 502 |
| 517 case kDraw_Cmd: { | 503 SkDEBUGCODE(bool isDraw = kDraw_Cmd == strip_trace_bit(iter->type()) || |
| 518 SkASSERT(fDstGpu->drawState() != prevDrawState); | 504 kStencilPath_Cmd == strip_trace_bit(iter->type
()) || |
| 519 SkAssertResult(drawIter.next()); | 505 kDrawPath_Cmd == strip_trace_bit(iter->type())
|| |
| 520 fDstGpu->setVertexSourceToBuffer(drawIter->vertexBuffer()); | 506 kDrawPaths_Cmd == strip_trace_bit(iter->type()
)); |
| 521 if (drawIter->isIndexed()) { | 507 SkASSERT(!isDraw || fDstGpu->drawState() != prevDrawState); |
| 522 fDstGpu->setIndexSourceToBuffer(drawIter->indexBuffer()); | 508 |
| 523 } | 509 iter->execute(fDstGpu); |
| 524 fDstGpu->executeDraw(*drawIter); | 510 |
| 525 break; | 511 if (cmd_has_trace_marker(iter->type())) { |
| 526 } | |
| 527 case kStencilPath_Cmd: { | |
| 528 SkASSERT(fDstGpu->drawState() != prevDrawState); | |
| 529 SkAssertResult(stencilPathIter.next()); | |
| 530 fDstGpu->stencilPath(stencilPathIter->path(), stencilPathIter->f
Fill); | |
| 531 break; | |
| 532 } | |
| 533 case kDrawPath_Cmd: { | |
| 534 SkASSERT(fDstGpu->drawState() != prevDrawState); | |
| 535 SkAssertResult(drawPathIter.next()); | |
| 536 fDstGpu->executeDrawPath(drawPathIter->path(), drawPathIter->fFi
ll, | |
| 537 drawPathIter->fDstCopy.texture() ? | |
| 538 &drawPathIter->fDstCopy : | |
| 539 NULL); | |
| 540 break; | |
| 541 } | |
| 542 case kDrawPaths_Cmd: { | |
| 543 SkASSERT(fDstGpu->drawState() != prevDrawState); | |
| 544 SkAssertResult(drawPathsIter.next()); | |
| 545 const GrDeviceCoordTexture* dstCopy = | |
| 546 drawPathsIter->fDstCopy.texture() ? &drawPathsIter->fDstCopy
: NULL; | |
| 547 fDstGpu->executeDrawPaths(drawPathsIter->pathRange(), | |
| 548 drawPathsIter->fIndices, | |
| 549 drawPathsIter->fCount, | |
| 550 drawPathsIter->fTransforms, | |
| 551 drawPathsIter->fTransformsType, | |
| 552 drawPathsIter->fFill, | |
| 553 dstCopy); | |
| 554 break; | |
| 555 } | |
| 556 case kSetState_Cmd: | |
| 557 SkAssertResult(stateIter.next()); | |
| 558 fDstGpu->setDrawState(stateIter.get()); | |
| 559 break; | |
| 560 case kSetClip_Cmd: | |
| 561 SkAssertResult(clipIter.next()); | |
| 562 clipData.fClipStack = &clipIter->fStack; | |
| 563 clipData.fOrigin = clipIter->fOrigin; | |
| 564 fDstGpu->setClip(&clipData); | |
| 565 break; | |
| 566 case kClear_Cmd: | |
| 567 SkAssertResult(clearIter.next()); | |
| 568 if (GrColor_ILLEGAL == clearIter->fColor) { | |
| 569 fDstGpu->discard(clearIter->renderTarget()); | |
| 570 } else { | |
| 571 fDstGpu->clear(&clearIter->fRect, | |
| 572 clearIter->fColor, | |
| 573 clearIter->fCanIgnoreRect, | |
| 574 clearIter->renderTarget()); | |
| 575 } | |
| 576 break; | |
| 577 case kCopySurface_Cmd: | |
| 578 SkAssertResult(copySurfaceIter.next()); | |
| 579 fDstGpu->copySurface(copySurfaceIter->dst(), | |
| 580 copySurfaceIter->src(), | |
| 581 copySurfaceIter->fSrcRect, | |
| 582 copySurfaceIter->fDstPoint); | |
| 583 break; | |
| 584 } | |
| 585 if (cmd_has_trace_marker(fCmds[c])) { | |
| 586 fDstGpu->removeGpuTraceMarker(&newMarker); | 512 fDstGpu->removeGpuTraceMarker(&newMarker); |
| 587 } | 513 } |
| 588 } | 514 } |
| 515 |
| 589 fDstGpu->restoreActiveTraceMarkers(); | 516 fDstGpu->restoreActiveTraceMarkers(); |
| 590 // we should have consumed all the states, clips, etc. | |
| 591 SkASSERT(!stateIter.next()); | |
| 592 SkASSERT(!clipIter.next()); | |
| 593 SkASSERT(!clearIter.next()); | |
| 594 SkASSERT(!drawIter.next()); | |
| 595 SkASSERT(!copySurfaceIter.next()); | |
| 596 SkASSERT(!stencilPathIter.next()); | |
| 597 SkASSERT(!drawPathIter.next()); | |
| 598 SkASSERT(!drawPathsIter.next()); | |
| 599 | |
| 600 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); | 517 SkASSERT(fGpuCmdMarkers.count() == currCmdMarker); |
| 601 | 518 |
| 602 fDstGpu->setDrawState(prevDrawState); | 519 fDstGpu->setDrawState(prevDrawState); |
| 603 prevDrawState->unref(); | 520 prevDrawState->unref(); |
| 604 this->reset(); | 521 this->reset(); |
| 605 ++fDrawID; | 522 ++fDrawID; |
| 606 } | 523 } |
| 607 | 524 |
| 525 void GrInOrderDrawBuffer::Draw::execute(GrDrawTarget* gpu) { |
| 526 gpu->setVertexSourceToBuffer(this->vertexBuffer()); |
| 527 if (this->isIndexed()) { |
| 528 gpu->setIndexSourceToBuffer(this->indexBuffer()); |
| 529 } |
| 530 gpu->executeDraw(*this); |
| 531 } |
| 532 |
| 533 void GrInOrderDrawBuffer::StencilPath::execute(GrDrawTarget* gpu) { |
| 534 gpu->stencilPath(this->path(), fFill); |
| 535 } |
| 536 |
| 537 void GrInOrderDrawBuffer::DrawPath::execute(GrDrawTarget* gpu) { |
| 538 gpu->executeDrawPath(this->path(), fFill, fDstCopy.texture() ? &fDstCopy : N
ULL); |
| 539 } |
| 540 |
| 541 void GrInOrderDrawBuffer::DrawPaths::execute(GrDrawTarget* gpu) { |
| 542 gpu->executeDrawPaths(this->pathRange(), this->indices(), fCount, this->tran
sforms(), |
| 543 fTransformsType, fFill, fDstCopy.texture() ? &fDstCopy
: NULL); |
| 544 } |
| 545 |
| 546 void GrInOrderDrawBuffer::SetState::execute(GrDrawTarget* gpu) { |
| 547 gpu->setDrawState(&fState); |
| 548 } |
| 549 |
| 550 void GrInOrderDrawBuffer::SetClip::execute(GrDrawTarget* gpu) { |
| 551 // Our fClipData is referenced directly, so we must remain alive for the ent
ire |
| 552 // duration of the flush (after which the gpu's previous clip is restored). |
| 553 gpu->setClip(&fClipData); |
| 554 } |
| 555 |
| 556 void GrInOrderDrawBuffer::Clear::execute(GrDrawTarget* gpu) { |
| 557 if (GrColor_ILLEGAL == fColor) { |
| 558 gpu->discard(this->renderTarget()); |
| 559 } else { |
| 560 gpu->clear(&fRect, fColor, fCanIgnoreRect, this->renderTarget()); |
| 561 } |
| 562 } |
| 563 |
| 564 void GrInOrderDrawBuffer::CopySurface::execute(GrDrawTarget* gpu) { |
| 565 gpu->copySurface(this->dst(), this->src(), fSrcRect, fDstPoint); |
| 566 } |
| 567 |
| 608 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, | 568 bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, |
| 609 GrSurface* src, | 569 GrSurface* src, |
| 610 const SkIRect& srcRect, | 570 const SkIRect& srcRect, |
| 611 const SkIPoint& dstPoint) { | 571 const SkIPoint& dstPoint) { |
| 612 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { | 572 if (fDstGpu->canCopySurface(dst, src, srcRect, dstPoint)) { |
| 613 CopySurface* cs = this->recordCopySurface(dst, src); | 573 CopySurface& cs = fCmdBuffer.push_back<CopySurface>(dst, src); |
| 614 cs->fSrcRect = srcRect; | 574 cs.fSrcRect = srcRect; |
| 615 cs->fDstPoint = dstPoint; | 575 cs.fDstPoint = dstPoint; |
| 576 this->recordTraceMarkersIfNecessary(); |
| 616 return true; | 577 return true; |
| 617 } else { | 578 } else { |
| 618 return false; | 579 return false; |
| 619 } | 580 } |
| 620 } | 581 } |
| 621 | 582 |
| 622 bool GrInOrderDrawBuffer::onCanCopySurface(GrSurface* dst, | 583 bool GrInOrderDrawBuffer::onCanCopySurface(GrSurface* dst, |
| 623 GrSurface* src, | 584 GrSurface* src, |
| 624 const SkIRect& srcRect, | 585 const SkIRect& srcRect, |
| 625 const SkIPoint& dstPoint) { | 586 const SkIPoint& dstPoint) { |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 if (kReserved_GeometrySrcType == restoredState.fVertexSrc || | 784 if (kReserved_GeometrySrcType == restoredState.fVertexSrc || |
| 824 kArray_GeometrySrcType == restoredState.fVertexSrc) { | 785 kArray_GeometrySrcType == restoredState.fVertexSrc) { |
| 825 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; | 786 poolState.fUsedPoolVertexBytes = restoredState.fVertexSize * restoredSta
te.fVertexCount; |
| 826 } | 787 } |
| 827 if (kReserved_GeometrySrcType == restoredState.fIndexSrc || | 788 if (kReserved_GeometrySrcType == restoredState.fIndexSrc || |
| 828 kArray_GeometrySrcType == restoredState.fIndexSrc) { | 789 kArray_GeometrySrcType == restoredState.fIndexSrc) { |
| 829 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * | 790 poolState.fUsedPoolIndexBytes = sizeof(uint16_t) * |
| 830 restoredState.fIndexCount; | 791 restoredState.fIndexCount; |
| 831 } | 792 } |
| 832 } | 793 } |
| 833 | 794 #include <stdio.h> |
| 834 void GrInOrderDrawBuffer::recordStateIfNecessary() { | 795 void GrInOrderDrawBuffer::recordStateIfNecessary() { |
| 835 if (fStates.empty()) { | 796 if (NULL == fLastState) { |
| 836 this->convertDrawStateToPendingExec(&fStates.push_back(this->getDrawStat
e())); | 797 fLastState = &fCmdBuffer.push_back<SetState>(this->getDrawState()).fStat
e; |
| 837 this->addToCmdBuffer(kSetState_Cmd); | 798 this->convertDrawStateToPendingExec(fLastState); |
| 799 this->recordTraceMarkersIfNecessary(); |
| 838 return; | 800 return; |
| 839 } | 801 } |
| 840 const GrDrawState& curr = this->getDrawState(); | 802 const GrDrawState& curr = this->getDrawState(); |
| 841 GrDrawState& prev = fStates.back(); | 803 switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) { |
| 842 switch (GrDrawState::CombineIfPossible(prev, curr, *this->caps())) { | |
| 843 case GrDrawState::kIncompatible_CombinedState: | 804 case GrDrawState::kIncompatible_CombinedState: |
| 844 this->convertDrawStateToPendingExec(&fStates.push_back(curr)); | 805 fLastState = &fCmdBuffer.push_back<SetState>(curr).fState; |
| 845 this->addToCmdBuffer(kSetState_Cmd); | 806 this->convertDrawStateToPendingExec(fLastState); |
| 807 this->recordTraceMarkersIfNecessary(); |
| 846 break; | 808 break; |
| 847 case GrDrawState::kA_CombinedState: | 809 case GrDrawState::kA_CombinedState: |
| 848 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. | 810 case GrDrawState::kAOrB_CombinedState: // Treat the same as kA. |
| 849 break; | 811 break; |
| 850 case GrDrawState::kB_CombinedState: | 812 case GrDrawState::kB_CombinedState: |
| 851 // prev has already been converted to pending execution. That is a o
ne-way ticket. | 813 // prev has already been converted to pending execution. That is a o
ne-way ticket. |
| 852 // So here we just delete prev and push back a new copy of curr. Not
e that this | 814 // So here we just destruct the previous state and reinit with a new
copy of curr. |
| 853 // goes away when we move GrIODB over to taking optimized snapshots
of draw states. | 815 // Note that this goes away when we move GrIODB over to taking optim
ized snapshots |
| 854 fStates.pop_back(); | 816 // of draw states. |
| 855 this->convertDrawStateToPendingExec(&fStates.push_back(curr)); | 817 fLastState->~GrDrawState(); |
| 818 SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr)); |
| 819 this->convertDrawStateToPendingExec(fLastState); |
| 856 break; | 820 break; |
| 857 } | 821 } |
| 858 } | 822 } |
| 859 | 823 |
| 860 bool GrInOrderDrawBuffer::needsNewClip() const { | 824 void GrInOrderDrawBuffer::recordClipIfNecessary() { |
| 861 if (this->getDrawState().isClipState()) { | 825 if (this->getDrawState().isClipState() && |
| 862 if (fClipSet && | 826 fClipSet && |
| 863 (fClips.empty() || | 827 (NULL == fLastClip || *fLastClip != *this->getClip())) { |
| 864 fClips.back().fStack != *this->getClip()->fClipStack || | 828 fLastClip = &fCmdBuffer.push_back<SetClip>(this->getClip()).fClipData; |
| 865 fClips.back().fOrigin != this->getClip()->fOrigin)) { | 829 this->recordTraceMarkersIfNecessary(); |
| 866 return true; | 830 fClipSet = false; |
| 867 } | |
| 868 } | |
| 869 return false; | |
| 870 } | |
| 871 | |
| 872 void GrInOrderDrawBuffer::addToCmdBuffer(uint8_t cmd) { | |
| 873 SkASSERT(!cmd_has_trace_marker(cmd)); | |
| 874 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); | |
| 875 if (activeTraceMarkers.count() > 0) { | |
| 876 fCmds.push_back(add_trace_bit(cmd)); | |
| 877 fGpuCmdMarkers.push_back(activeTraceMarkers); | |
| 878 } else { | |
| 879 fCmds.push_back(cmd); | |
| 880 } | 831 } |
| 881 } | 832 } |
| 882 | 833 |
| 883 void GrInOrderDrawBuffer::recordClip() { | 834 void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary() { |
| 884 fClips.push_back().fStack = *this->getClip()->fClipStack; | 835 SkASSERT(!fCmdBuffer.empty()); |
| 885 fClips.back().fOrigin = this->getClip()->fOrigin; | 836 SkASSERT(!cmd_has_trace_marker(fCmdBuffer.back().type())); |
| 886 fClipSet = false; | 837 const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers(); |
| 887 this->addToCmdBuffer(kSetClip_Cmd); | 838 if (activeTraceMarkers.count() > 0) { |
| 888 } | 839 fCmdBuffer.back().resetType(add_trace_bit(fCmdBuffer.back().type())); |
| 889 | 840 fGpuCmdMarkers.push_back(activeTraceMarkers); |
| 890 GrInOrderDrawBuffer::Draw* GrInOrderDrawBuffer::recordDraw(const DrawInfo& info, | 841 } |
| 891 const GrVertexBuffer*
vb, | |
| 892 const GrIndexBuffer*
ib) { | |
| 893 this->addToCmdBuffer(kDraw_Cmd); | |
| 894 return GrNEW_APPEND_TO_ALLOCATOR(&fDraws, Draw, (info, vb, ib)); | |
| 895 } | |
| 896 | |
| 897 GrInOrderDrawBuffer::StencilPath* GrInOrderDrawBuffer::recordStencilPath(const G
rPath* path) { | |
| 898 this->addToCmdBuffer(kStencilPath_Cmd); | |
| 899 return GrNEW_APPEND_TO_ALLOCATOR(&fStencilPaths, StencilPath, (path)); | |
| 900 } | |
| 901 | |
| 902 GrInOrderDrawBuffer::DrawPath* GrInOrderDrawBuffer::recordDrawPath(const GrPath*
path) { | |
| 903 this->addToCmdBuffer(kDrawPath_Cmd); | |
| 904 return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPath, DrawPath, (path)); | |
| 905 } | |
| 906 | |
| 907 GrInOrderDrawBuffer::DrawPaths* GrInOrderDrawBuffer::recordDrawPaths(const GrPat
hRange* pathRange) { | |
| 908 this->addToCmdBuffer(kDrawPaths_Cmd); | |
| 909 return GrNEW_APPEND_TO_ALLOCATOR(&fDrawPaths, DrawPaths, (pathRange)); | |
| 910 } | |
| 911 | |
| 912 GrInOrderDrawBuffer::Clear* GrInOrderDrawBuffer::recordClear(GrRenderTarget* rt)
{ | |
| 913 this->addToCmdBuffer(kClear_Cmd); | |
| 914 return GrNEW_APPEND_TO_ALLOCATOR(&fClears, Clear, (rt)); | |
| 915 } | |
| 916 | |
| 917 GrInOrderDrawBuffer::CopySurface* GrInOrderDrawBuffer::recordCopySurface(GrSurfa
ce* dst, | |
| 918 GrSurfa
ce* src) { | |
| 919 this->addToCmdBuffer(kCopySurface_Cmd); | |
| 920 return GrNEW_APPEND_TO_ALLOCATOR(&fCopySurfaces, CopySurface, (dst, src)); | |
| 921 } | 842 } |
| 922 | 843 |
| 923 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) { | 844 void GrInOrderDrawBuffer::clipWillBeSet(const GrClipData* newClipData) { |
| 924 INHERITED::clipWillBeSet(newClipData); | 845 INHERITED::clipWillBeSet(newClipData); |
| 925 fClipSet = true; | 846 fClipSet = true; |
| 926 fClipProxyState = kUnknown_ClipProxyState; | 847 fClipProxyState = kUnknown_ClipProxyState; |
| 927 } | 848 } |
| OLD | NEW |