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 |