| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "GrGpu.h" | 10 #include "GrGpu.h" |
| 11 | 11 |
| 12 #include "GrBufferAllocPool.h" | 12 #include "GrBufferAllocPool.h" |
| 13 #include "GrContext.h" | 13 #include "GrContext.h" |
| 14 #include "GrDrawTargetCaps.h" | 14 #include "GrDrawTargetCaps.h" |
| 15 #include "GrIndexBuffer.h" | 15 #include "GrIndexBuffer.h" |
| 16 #include "GrStencilBuffer.h" | 16 #include "GrStencilBuffer.h" |
| 17 #include "GrVertexBuffer.h" | 17 #include "GrVertexBuffer.h" |
| 18 | 18 |
| 19 // probably makes no sense for this to be less than a page | |
| 20 static const size_t VERTEX_POOL_VB_SIZE = 1 << 18; | |
| 21 static const int VERTEX_POOL_VB_COUNT = 4; | |
| 22 static const size_t INDEX_POOL_IB_SIZE = 1 << 16; | |
| 23 static const int INDEX_POOL_IB_COUNT = 4; | |
| 24 | |
| 25 //////////////////////////////////////////////////////////////////////////////// | 19 //////////////////////////////////////////////////////////////////////////////// |
| 26 | 20 |
| 27 #define DEBUG_INVAL_BUFFER 0xdeadcafe | 21 #define DEBUG_INVAL_BUFFER 0xdeadcafe |
| 28 #define DEBUG_INVAL_START_IDX -1 | 22 #define DEBUG_INVAL_START_IDX -1 |
| 29 | 23 |
| 30 GrGpu::GrGpu(GrContext* context) | 24 GrGpu::GrGpu(GrContext* context) |
| 31 : fResetTimestamp(kExpiredTimestamp+1) | 25 : fResetTimestamp(kExpiredTimestamp+1) |
| 32 , fResetBits(kAll_GrBackendState) | 26 , fResetBits(kAll_GrBackendState) |
| 33 , fVertexPool(NULL) | |
| 34 , fIndexPool(NULL) | |
| 35 , fVertexPoolUseCnt(0) | |
| 36 , fIndexPoolUseCnt(0) | |
| 37 , fQuadIndexBuffer(NULL) | 27 , fQuadIndexBuffer(NULL) |
| 38 , fContext(context) { | 28 , fContext(context) { |
| 39 fGeomPoolStateStack.push_back(); | |
| 40 fDrawState = &fDefaultDrawState; | 29 fDrawState = &fDefaultDrawState; |
| 41 // We assume that fDrawState always owns a ref to the object it points at. | 30 // We assume that fDrawState always owns a ref to the object it points at. |
| 42 fDefaultDrawState.ref(); | 31 fDefaultDrawState.ref(); |
| 43 #ifdef SK_DEBUG | |
| 44 GeometryPoolState& poolState = fGeomPoolStateStack.back(); | |
| 45 poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; | |
| 46 poolState.fPoolStartVertex = DEBUG_INVAL_START_IDX; | |
| 47 poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; | |
| 48 poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX; | |
| 49 #endif | |
| 50 | |
| 51 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back(); | |
| 52 #ifdef SK_DEBUG | |
| 53 geoSrc.fVertexCount = DEBUG_INVAL_START_IDX; | |
| 54 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; | |
| 55 geoSrc.fIndexCount = DEBUG_INVAL_START_IDX; | |
| 56 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; | |
| 57 #endif | |
| 58 geoSrc.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType; | |
| 59 geoSrc.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType; | |
| 60 } | 32 } |
| 61 | 33 |
| 62 GrGpu::~GrGpu() { | 34 GrGpu::~GrGpu() { |
| 63 SkSafeSetNull(fQuadIndexBuffer); | 35 SkSafeSetNull(fQuadIndexBuffer); |
| 64 delete fVertexPool; | |
| 65 fVertexPool = NULL; | |
| 66 delete fIndexPool; | |
| 67 fIndexPool = NULL; | |
| 68 SkASSERT(1 == fGeoSrcStateStack.count()); | |
| 69 SkDEBUGCODE(GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back(
)); | |
| 70 SkASSERT(GrDrawTarget::kNone_GeometrySrcType == geoSrc.fIndexSrc); | |
| 71 SkASSERT(GrDrawTarget::kNone_GeometrySrcType == geoSrc.fVertexSrc); | |
| 72 SkSafeUnref(fDrawState); | 36 SkSafeUnref(fDrawState); |
| 37 SkSafeUnref(fGeoSrcState.fVertexBuffer); |
| 38 SkSafeUnref(fGeoSrcState.fIndexBuffer); |
| 73 } | 39 } |
| 74 | 40 |
| 75 void GrGpu::contextAbandoned() {} | 41 void GrGpu::contextAbandoned() {} |
| 76 | 42 |
| 77 //////////////////////////////////////////////////////////////////////////////// | 43 //////////////////////////////////////////////////////////////////////////////// |
| 78 | 44 |
| 79 GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, | 45 GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, |
| 80 const void* srcData, size_t rowBytes) { | 46 const void* srcData, size_t rowBytes) { |
| 81 if (!this->caps()->isConfigTexturable(desc.fConfig)) { | 47 if (!this->caps()->isConfigTexturable(desc.fConfig)) { |
| 82 return NULL; | 48 return NULL; |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 void GrGpu::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { | 267 void GrGpu::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { |
| 302 if (this->caps()->gpuTracingSupport()) { | 268 if (this->caps()->gpuTracingSupport()) { |
| 303 SkASSERT(fGpuTraceMarkerCount >= 1); | 269 SkASSERT(fGpuTraceMarkerCount >= 1); |
| 304 this->fActiveTraceMarkers.remove(*marker); | 270 this->fActiveTraceMarkers.remove(*marker); |
| 305 this->didRemoveGpuTraceMarker(); | 271 this->didRemoveGpuTraceMarker(); |
| 306 --fGpuTraceMarkerCount; | 272 --fGpuTraceMarkerCount; |
| 307 } | 273 } |
| 308 } | 274 } |
| 309 | 275 |
| 310 void GrGpu::setVertexSourceToBuffer(const GrVertexBuffer* buffer) { | 276 void GrGpu::setVertexSourceToBuffer(const GrVertexBuffer* buffer) { |
| 311 this->releasePreviousVertexSource(); | 277 SkSafeUnref(fGeoSrcState.fVertexBuffer); |
| 312 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | 278 fGeoSrcState.fVertexBuffer = buffer; |
| 313 geoSrc.fVertexSrc = GrDrawTarget::kBuffer_GeometrySrcType; | |
| 314 geoSrc.fVertexBuffer = buffer; | |
| 315 buffer->ref(); | 279 buffer->ref(); |
| 316 geoSrc.fVertexSize = this->drawState()->getVertexStride(); | 280 fGeoSrcState.fVertexSize = this->drawState()->getVertexStride(); |
| 317 } | 281 } |
| 318 | 282 |
| 319 void GrGpu::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { | 283 void GrGpu::setIndexSourceToBuffer(const GrIndexBuffer* buffer) { |
| 320 this->releasePreviousIndexSource(); | 284 SkSafeUnref(fGeoSrcState.fIndexBuffer); |
| 321 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | 285 fGeoSrcState.fIndexBuffer = buffer; |
| 322 geoSrc.fIndexSrc = GrDrawTarget::kBuffer_GeometrySrcType; | |
| 323 geoSrc.fIndexBuffer = buffer; | |
| 324 buffer->ref(); | 286 buffer->ref(); |
| 325 } | 287 } |
| 326 | 288 |
| 327 void GrGpu::setDrawState(GrDrawState* drawState) { | 289 void GrGpu::setDrawState(GrDrawState* drawState) { |
| 328 SkASSERT(fDrawState); | 290 SkASSERT(fDrawState); |
| 329 if (NULL == drawState) { | 291 if (NULL == drawState) { |
| 330 drawState = &fDefaultDrawState; | 292 drawState = &fDefaultDrawState; |
| 331 } | 293 } |
| 332 if (fDrawState != drawState) { | 294 if (fDrawState != drawState) { |
| 333 fDrawState->unref(); | 295 fDrawState->unref(); |
| 334 drawState->ref(); | 296 drawState->ref(); |
| 335 fDrawState = drawState; | 297 fDrawState = drawState; |
| 336 } | 298 } |
| 337 } | 299 } |
| 338 | 300 |
| 339 void GrGpu::resetVertexSource() { | |
| 340 this->releasePreviousVertexSource(); | |
| 341 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 342 geoSrc.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType; | |
| 343 } | |
| 344 | |
| 345 void GrGpu::resetIndexSource() { | |
| 346 this->releasePreviousIndexSource(); | |
| 347 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 348 geoSrc.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType; | |
| 349 } | |
| 350 | |
| 351 void GrGpu::pushGeometrySource() { | |
| 352 this->geometrySourceWillPush(); | |
| 353 GrDrawTarget::GeometrySrcState& newState = fGeoSrcStateStack.push_back(); | |
| 354 newState.fIndexSrc = GrDrawTarget::kNone_GeometrySrcType; | |
| 355 newState.fVertexSrc = GrDrawTarget::kNone_GeometrySrcType; | |
| 356 #ifdef SK_DEBUG | |
| 357 newState.fVertexCount = ~0; | |
| 358 newState.fVertexBuffer = (GrVertexBuffer*)~0; | |
| 359 newState.fIndexCount = ~0; | |
| 360 newState.fIndexBuffer = (GrIndexBuffer*)~0; | |
| 361 #endif | |
| 362 } | |
| 363 | |
| 364 void GrGpu::popGeometrySource() { | |
| 365 // if popping last element then pops are unbalanced with pushes | |
| 366 SkASSERT(fGeoSrcStateStack.count() > 1); | |
| 367 | |
| 368 this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1)); | |
| 369 this->releasePreviousVertexSource(); | |
| 370 this->releasePreviousIndexSource(); | |
| 371 fGeoSrcStateStack.pop_back(); | |
| 372 } | |
| 373 | |
| 374 //////////////////////////////////////////////////////////////////////////////// | 301 //////////////////////////////////////////////////////////////////////////////// |
| 375 | 302 |
| 376 static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1; | 303 static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1; |
| 377 | 304 |
| 378 GR_STATIC_ASSERT(4 * MAX_QUADS <= 65535); | 305 GR_STATIC_ASSERT(4 * MAX_QUADS <= 65535); |
| 379 | 306 |
| 380 static const uint16_t gQuadIndexPattern[] = { | 307 static const uint16_t gQuadIndexPattern[] = { |
| 381 0, 1, 2, 0, 2, 3 | 308 0, 1, 2, 0, 2, 3 |
| 382 }; | 309 }; |
| 383 | 310 |
| 384 const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const { | 311 const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const { |
| 385 if (NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed()) { | 312 if (NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed()) { |
| 386 SkSafeUnref(fQuadIndexBuffer); | 313 SkSafeUnref(fQuadIndexBuffer); |
| 387 GrGpu* me = const_cast<GrGpu*>(this); | 314 GrGpu* me = const_cast<GrGpu*>(this); |
| 388 fQuadIndexBuffer = me->createInstancedIndexBuffer(gQuadIndexPattern, | 315 fQuadIndexBuffer = me->createInstancedIndexBuffer(gQuadIndexPattern, |
| 389 6, | 316 6, |
| 390 MAX_QUADS, | 317 MAX_QUADS, |
| 391 4); | 318 4); |
| 392 } | 319 } |
| 393 | 320 |
| 394 return fQuadIndexBuffer; | 321 return fQuadIndexBuffer; |
| 395 } | 322 } |
| 396 | 323 |
| 397 //////////////////////////////////////////////////////////////////////////////// | 324 //////////////////////////////////////////////////////////////////////////////// |
| 398 | 325 |
| 399 void GrGpu::geometrySourceWillPush() { | |
| 400 const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc(); | |
| 401 if (GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fVertexSrc) { | |
| 402 this->finalizeReservedVertices(); | |
| 403 } | |
| 404 if (GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fIndexSrc) { | |
| 405 this->finalizeReservedIndices(); | |
| 406 } | |
| 407 GeometryPoolState& newState = fGeomPoolStateStack.push_back(); | |
| 408 #ifdef SK_DEBUG | |
| 409 newState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; | |
| 410 newState.fPoolStartVertex = DEBUG_INVAL_START_IDX; | |
| 411 newState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; | |
| 412 newState.fPoolStartIndex = DEBUG_INVAL_START_IDX; | |
| 413 #else | |
| 414 (void) newState; // silence compiler warning | |
| 415 #endif | |
| 416 } | |
| 417 | |
| 418 void GrGpu::geometrySourceWillPop(const GrDrawTarget::GeometrySrcState& restored
State) { | |
| 419 // if popping last entry then pops are unbalanced with pushes | |
| 420 SkASSERT(fGeomPoolStateStack.count() > 1); | |
| 421 fGeomPoolStateStack.pop_back(); | |
| 422 } | |
| 423 | |
| 424 void GrGpu::onDraw(const GrDrawTarget::DrawInfo& info, | 326 void GrGpu::onDraw(const GrDrawTarget::DrawInfo& info, |
| 425 const GrClipMaskManager::ScissorState& scissorState) { | 327 const GrClipMaskManager::ScissorState& scissorState) { |
| 426 this->handleDirtyContext(); | 328 this->handleDirtyContext(); |
| 427 if (!this->flushGraphicsState(PrimTypeToDrawType(info.primitiveType()), | 329 if (!this->flushGraphicsState(PrimTypeToDrawType(info.primitiveType()), |
| 428 scissorState, | 330 scissorState, |
| 429 info.getDstCopy())) { | 331 info.getDstCopy())) { |
| 430 return; | 332 return; |
| 431 } | 333 } |
| 432 this->onGpuDraw(info); | 334 this->onGpuDraw(info); |
| 433 } | 335 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 this->handleDirtyContext(); | 371 this->handleDirtyContext(); |
| 470 | 372 |
| 471 if (!this->flushGraphicsState(kDrawPaths_DrawType, scissorState, dstCopy)) { | 373 if (!this->flushGraphicsState(kDrawPaths_DrawType, scissorState, dstCopy)) { |
| 472 return; | 374 return; |
| 473 } | 375 } |
| 474 | 376 |
| 475 pathRange->willDrawPaths(indices, count); | 377 pathRange->willDrawPaths(indices, count); |
| 476 this->pathRendering()->drawPaths(pathRange, indices, count, transforms, tran
sformsType, | 378 this->pathRendering()->drawPaths(pathRange, indices, count, transforms, tran
sformsType, |
| 477 stencilSettings); | 379 stencilSettings); |
| 478 } | 380 } |
| 479 | |
| 480 void GrGpu::finalizeReservedVertices() { | |
| 481 SkASSERT(fVertexPool); | |
| 482 fVertexPool->unmap(); | |
| 483 } | |
| 484 | |
| 485 void GrGpu::finalizeReservedIndices() { | |
| 486 SkASSERT(fIndexPool); | |
| 487 fIndexPool->unmap(); | |
| 488 } | |
| 489 | |
| 490 void GrGpu::prepareVertexPool() { | |
| 491 if (NULL == fVertexPool) { | |
| 492 SkASSERT(0 == fVertexPoolUseCnt); | |
| 493 fVertexPool = SkNEW_ARGS(GrVertexBufferAllocPool, (this, true, | |
| 494 VERTEX_POOL_VB_SIZE, | |
| 495 VERTEX_POOL_VB_COUNT)); | |
| 496 fVertexPool->releaseGpuRef(); | |
| 497 } else if (!fVertexPoolUseCnt) { | |
| 498 // the client doesn't have valid data in the pool | |
| 499 fVertexPool->reset(); | |
| 500 } | |
| 501 } | |
| 502 | |
| 503 void GrGpu::prepareIndexPool() { | |
| 504 if (NULL == fIndexPool) { | |
| 505 SkASSERT(0 == fIndexPoolUseCnt); | |
| 506 fIndexPool = SkNEW_ARGS(GrIndexBufferAllocPool, (this, true, | |
| 507 INDEX_POOL_IB_SIZE, | |
| 508 INDEX_POOL_IB_COUNT)); | |
| 509 fIndexPool->releaseGpuRef(); | |
| 510 } else if (!fIndexPoolUseCnt) { | |
| 511 // the client doesn't have valid data in the pool | |
| 512 fIndexPool->reset(); | |
| 513 } | |
| 514 } | |
| 515 | |
| 516 bool GrGpu::onReserveVertexSpace(size_t vertexSize, | |
| 517 int vertexCount, | |
| 518 void** vertices) { | |
| 519 GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); | |
| 520 | |
| 521 SkASSERT(vertexCount > 0); | |
| 522 SkASSERT(vertices); | |
| 523 | |
| 524 this->prepareVertexPool(); | |
| 525 | |
| 526 *vertices = fVertexPool->makeSpace(vertexSize, | |
| 527 vertexCount, | |
| 528 &geomPoolState.fPoolVertexBuffer, | |
| 529 &geomPoolState.fPoolStartVertex); | |
| 530 if (NULL == *vertices) { | |
| 531 return false; | |
| 532 } | |
| 533 ++fVertexPoolUseCnt; | |
| 534 return true; | |
| 535 } | |
| 536 | |
| 537 bool GrGpu::onReserveIndexSpace(int indexCount, void** indices) { | |
| 538 GeometryPoolState& geomPoolState = fGeomPoolStateStack.back(); | |
| 539 | |
| 540 SkASSERT(indexCount > 0); | |
| 541 SkASSERT(indices); | |
| 542 | |
| 543 this->prepareIndexPool(); | |
| 544 | |
| 545 *indices = fIndexPool->makeSpace(indexCount, | |
| 546 &geomPoolState.fPoolIndexBuffer, | |
| 547 &geomPoolState.fPoolStartIndex); | |
| 548 if (NULL == *indices) { | |
| 549 return false; | |
| 550 } | |
| 551 ++fIndexPoolUseCnt; | |
| 552 return true; | |
| 553 } | |
| 554 | |
| 555 void GrGpu::releaseReservedVertexSpace() { | |
| 556 const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc(); | |
| 557 SkASSERT(GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fVertexSrc); | |
| 558 size_t bytes = geoSrc.fVertexCount * geoSrc.fVertexSize; | |
| 559 fVertexPool->putBack(bytes); | |
| 560 --fVertexPoolUseCnt; | |
| 561 } | |
| 562 | |
| 563 void GrGpu::releaseReservedIndexSpace() { | |
| 564 const GrDrawTarget::GeometrySrcState& geoSrc = this->getGeomSrc(); | |
| 565 SkASSERT(GrDrawTarget::kReserved_GeometrySrcType == geoSrc.fIndexSrc); | |
| 566 size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t); | |
| 567 fIndexPool->putBack(bytes); | |
| 568 --fIndexPoolUseCnt; | |
| 569 } | |
| 570 | |
| 571 void GrGpu::releasePreviousVertexSource() { | |
| 572 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 573 switch (geoSrc.fVertexSrc) { | |
| 574 case GrDrawTarget::kNone_GeometrySrcType: | |
| 575 break; | |
| 576 case GrDrawTarget::kReserved_GeometrySrcType: | |
| 577 this->releaseReservedVertexSpace(); | |
| 578 break; | |
| 579 case GrDrawTarget::kBuffer_GeometrySrcType: | |
| 580 geoSrc.fVertexBuffer->unref(); | |
| 581 #ifdef SK_DEBUG | |
| 582 geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER; | |
| 583 #endif | |
| 584 break; | |
| 585 default: | |
| 586 SkFAIL("Unknown Vertex Source Type."); | |
| 587 break; | |
| 588 } | |
| 589 } | |
| 590 | |
| 591 void GrGpu::releasePreviousIndexSource() { | |
| 592 GrDrawTarget::GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); | |
| 593 switch (geoSrc.fIndexSrc) { | |
| 594 case GrDrawTarget::kNone_GeometrySrcType: // these two don't require | |
| 595 break; | |
| 596 case GrDrawTarget::kReserved_GeometrySrcType: | |
| 597 this->releaseReservedIndexSpace(); | |
| 598 break; | |
| 599 case GrDrawTarget::kBuffer_GeometrySrcType: | |
| 600 geoSrc.fIndexBuffer->unref(); | |
| 601 #ifdef SK_DEBUG | |
| 602 geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER; | |
| 603 #endif | |
| 604 break; | |
| 605 default: | |
| 606 SkFAIL("Unknown Index Source Type."); | |
| 607 break; | |
| 608 } | |
| 609 } | |
| 610 | |
| 611 void GrGpu::releaseGeometry() { | |
| 612 int popCnt = fGeoSrcStateStack.count() - 1; | |
| 613 while (popCnt) { | |
| 614 this->popGeometrySource(); | |
| 615 --popCnt; | |
| 616 } | |
| 617 this->resetVertexSource(); | |
| 618 this->resetIndexSource(); | |
| 619 } | |
| OLD | NEW |