Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: src/gpu/gl/GrGLGpu.cpp

Issue 1490473003: Add transfer buffer support. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Some clean up Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 8
9 #include "GrGLGpu.h" 9 #include "GrGLGpu.h"
10 #include "GrGLGLSL.h" 10 #include "GrGLGLSL.h"
(...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 height, 1394 height,
1395 samples, 1395 samples,
1396 format); 1396 format);
1397 return stencil; 1397 return stencil;
1398 } 1398 }
1399 1399
1400 //////////////////////////////////////////////////////////////////////////////// 1400 ////////////////////////////////////////////////////////////////////////////////
1401 1401
1402 GrVertexBuffer* GrGLGpu::onCreateVertexBuffer(size_t size, bool dynamic) { 1402 GrVertexBuffer* GrGLGpu::onCreateVertexBuffer(size_t size, bool dynamic) {
1403 GrGLVertexBuffer::Desc desc; 1403 GrGLVertexBuffer::Desc desc;
1404 desc.fDynamic = dynamic; 1404 desc.fUsage = dynamic ? GrGLBufferImpl::kDynamicDraw_Usage : GrGLBufferImpl: :kStaticDraw_Usage;
1405 desc.fSizeInBytes = size; 1405 desc.fSizeInBytes = size;
1406 1406
1407 if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) { 1407 if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && dynamic) {
1408 desc.fID = 0; 1408 desc.fID = 0;
1409 GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, desc); 1409 GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, desc);
1410 return vertexBuffer; 1410 return vertexBuffer;
1411 } else { 1411 } else {
1412 GL_CALL(GenBuffers(1, &desc.fID)); 1412 GL_CALL(GenBuffers(1, &desc.fID));
1413 if (desc.fID) { 1413 if (desc.fID) {
1414 fHWGeometryState.setVertexBufferID(this, desc.fID); 1414 fHWGeometryState.setVertexBufferID(this, desc.fID);
1415 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1415 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1416 // make sure driver can allocate memory for this buffer 1416 // make sure driver can allocate memory for this buffer
1417 GL_ALLOC_CALL(this->glInterface(), 1417 GL_ALLOC_CALL(this->glInterface(),
1418 BufferData(GR_GL_ARRAY_BUFFER, 1418 BufferData(GR_GL_ARRAY_BUFFER,
1419 (GrGLsizeiptr) desc.fSizeInBytes, 1419 (GrGLsizeiptr) desc.fSizeInBytes,
1420 nullptr, // data ptr 1420 nullptr, // data ptr
1421 desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_ STATIC_DRAW)); 1421 /* Why DYNAMIC_DRAW here and STREAM_DRAW el sewhere? */
bsalomon 2015/12/02 16:38:31 Probably no good reason... we should be consistent
jvanverth1 2015/12/02 18:05:07 It looks like it's always stream_draw -- I've chan
bsalomon 2015/12/02 18:39:22 Looks the same as before. I remember the history h
jvanverth1 2015/12/02 18:41:59 I apparently hadn't saved that file when I uploade
1422 dynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC _DRAW));
1422 if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) { 1423 if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
1423 GL_CALL(DeleteBuffers(1, &desc.fID)); 1424 GL_CALL(DeleteBuffers(1, &desc.fID));
1424 this->notifyVertexBufferDelete(desc.fID); 1425 this->notifyVertexBufferDelete(desc.fID);
1425 return nullptr; 1426 return nullptr;
1426 } 1427 }
1427 GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, desc); 1428 GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, desc);
1428 return vertexBuffer; 1429 return vertexBuffer;
1429 } 1430 }
1430 return nullptr; 1431 return nullptr;
1431 } 1432 }
1432 } 1433 }
1433 1434
1434 GrIndexBuffer* GrGLGpu::onCreateIndexBuffer(size_t size, bool dynamic) { 1435 GrIndexBuffer* GrGLGpu::onCreateIndexBuffer(size_t size, bool dynamic) {
1435 GrGLIndexBuffer::Desc desc; 1436 GrGLIndexBuffer::Desc desc;
1436 desc.fDynamic = dynamic; 1437 desc.fUsage = dynamic ? GrGLBufferImpl::kDynamicDraw_Usage : GrGLBufferImpl: :kStaticDraw_Usage;
1437 desc.fSizeInBytes = size; 1438 desc.fSizeInBytes = size;
1438 1439
1439 if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) { 1440 if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && dynamic) {
1440 desc.fID = 0; 1441 desc.fID = 0;
1441 GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, desc); 1442 GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, desc);
1442 return indexBuffer; 1443 return indexBuffer;
1443 } else { 1444 } else {
1444 GL_CALL(GenBuffers(1, &desc.fID)); 1445 GL_CALL(GenBuffers(1, &desc.fID));
1445 if (desc.fID) { 1446 if (desc.fID) {
1446 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, desc.fID ); 1447 fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, desc.fID );
1447 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface()); 1448 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1448 // make sure driver can allocate memory for this buffer 1449 // make sure driver can allocate memory for this buffer
1449 GL_ALLOC_CALL(this->glInterface(), 1450 GL_ALLOC_CALL(this->glInterface(),
1450 BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, 1451 BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
1451 (GrGLsizeiptr) desc.fSizeInBytes, 1452 (GrGLsizeiptr) desc.fSizeInBytes,
1452 nullptr, // data ptr 1453 nullptr, // data ptr
1453 desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_ STATIC_DRAW)); 1454 dynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC _DRAW));
1454 if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) { 1455 if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
1455 GL_CALL(DeleteBuffers(1, &desc.fID)); 1456 GL_CALL(DeleteBuffers(1, &desc.fID));
1456 this->notifyIndexBufferDelete(desc.fID); 1457 this->notifyIndexBufferDelete(desc.fID);
1457 return nullptr; 1458 return nullptr;
1458 } 1459 }
1459 GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, desc); 1460 GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, desc);
1460 return indexBuffer; 1461 return indexBuffer;
1461 } 1462 }
1462 return nullptr; 1463 return nullptr;
1463 } 1464 }
1464 } 1465 }
1465 1466
1467 GrTransferBuffer* GrGLGpu::onCreateTransferBuffer(size_t size, bool toGpu) {
1468 GrGLTransferBuffer::Desc desc;
1469 desc.fUsage = toGpu ? GrGLBufferImpl::kStreamDraw_Usage : GrGLBufferImpl::kS treamRead_Usage;
1470
1471 desc.fSizeInBytes = size;
1472
1473 // TODO: check caps to see if we can create a PBO, and which kind
1474 GL_CALL(GenBuffers(1, &desc.fID));
1475 if (desc.fID) {
1476 CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
1477 // make sure driver can allocate memory for this buffer
1478 GrGLenum type = toGpu ? GR_GL_PIXEL_UNPACK_BUFFER : GR_GL_PIXEL_PACK_BUF FER;
1479 GL_ALLOC_CALL(this->glInterface(),
1480 BufferData(type,
1481 (GrGLsizeiptr) desc.fSizeInBytes,
1482 nullptr, // data ptr
1483 (toGpu ? GR_GL_STREAM_DRAW : GR_GL_STREAM_READ) ));
1484 if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
1485 GL_CALL(DeleteBuffers(1, &desc.fID));
1486 return nullptr;
1487 }
1488 GrTransferBuffer* transferBuffer = new GrGLTransferBuffer(this, desc, ty pe);
1489 return transferBuffer;
1490 }
1491
1492 return nullptr;
1493 }
1494
1466 void GrGLGpu::flushScissor(const GrScissorState& scissorState, 1495 void GrGLGpu::flushScissor(const GrScissorState& scissorState,
1467 const GrGLIRect& rtViewport, 1496 const GrGLIRect& rtViewport,
1468 GrSurfaceOrigin rtOrigin) { 1497 GrSurfaceOrigin rtOrigin) {
1469 if (scissorState.enabled()) { 1498 if (scissorState.enabled()) {
1470 GrGLIRect scissor; 1499 GrGLIRect scissor;
1471 scissor.setRelativeTo(rtViewport, 1500 scissor.setRelativeTo(rtViewport,
1472 scissorState.rect().fLeft, 1501 scissorState.rect().fLeft,
1473 scissorState.rect().fTop, 1502 scissorState.rect().fTop,
1474 scissorState.rect().width(), 1503 scissorState.rect().width(),
1475 scissorState.rect().height(), 1504 scissorState.rect().height(),
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1596 const GrPipeline& pipeline) const { 1625 const GrPipeline& pipeline) const {
1597 if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, this)) { 1626 if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, this)) {
1598 SkDEBUGFAIL("Failed to generate GL program descriptor"); 1627 SkDEBUGFAIL("Failed to generate GL program descriptor");
1599 } 1628 }
1600 } 1629 }
1601 1630
1602 void GrGLGpu::bindBuffer(GrGLuint id, GrGLenum type) { 1631 void GrGLGpu::bindBuffer(GrGLuint id, GrGLenum type) {
1603 this->handleDirtyContext(); 1632 this->handleDirtyContext();
1604 if (GR_GL_ARRAY_BUFFER == type) { 1633 if (GR_GL_ARRAY_BUFFER == type) {
1605 this->bindVertexBuffer(id); 1634 this->bindVertexBuffer(id);
1606 } else { 1635 } else if (GR_GL_ELEMENT_ARRAY_BUFFER == type) {
1607 SkASSERT(GR_GL_ELEMENT_ARRAY_BUFFER == type);
1608 this->bindIndexBufferAndDefaultVertexArray(id); 1636 this->bindIndexBufferAndDefaultVertexArray(id);
1609 } 1637 }
1610 } 1638 }
1611 1639
1612 void GrGLGpu::releaseBuffer(GrGLuint id, GrGLenum type) { 1640 void GrGLGpu::releaseBuffer(GrGLuint id, GrGLenum type) {
1613 this->handleDirtyContext(); 1641 this->handleDirtyContext();
1614 GL_CALL(DeleteBuffers(1, &id)); 1642 GL_CALL(DeleteBuffers(1, &id));
1615 if (GR_GL_ARRAY_BUFFER == type) { 1643 if (GR_GL_ARRAY_BUFFER == type) {
1616 this->notifyVertexBufferDelete(id); 1644 this->notifyVertexBufferDelete(id);
1617 } else { 1645 } else if (GR_GL_ELEMENT_ARRAY_BUFFER == type) {
bsalomon 2015/12/02 16:38:31 you don't need equivalent here for pbo?
jvanverth1 2015/12/02 18:05:07 It's used to update the geometry state, which I do
1618 SkASSERT(GR_GL_ELEMENT_ARRAY_BUFFER == type);
1619 this->notifyIndexBufferDelete(id); 1646 this->notifyIndexBufferDelete(id);
1620 } 1647 }
1621 } 1648 }
1622 1649
1623 // GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a cli ent's vertex buffer 1650 // GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a cli ent's vertex buffer
1624 // objects are implemented as client-side-arrays on tile-deferred architectures. 1651 // objects are implemented as client-side-arrays on tile-deferred architectures.
1625 #define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW 1652 #define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW
1626 1653
1627 void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, bool dynamic, size_t curren tSize, 1654 static GrGLenum get_gl_usage(GrGLBufferImpl::Usage usage) {
1628 size_t requestedSize) { 1655 static const GrGLenum grToGL[] = {
1656 GR_GL_STATIC_DRAW, // GrGLBufferImpl::kStaticDraw_Usage
1657 DYNAMIC_USAGE_PARAM, // GrGLBufferImpl::kDynamicDraw_Usage
1658 GR_GL_STREAM_DRAW, // GrGLBufferImpl::kStreamDraw_Usage
1659 GR_GL_STREAM_READ, // GrGLBufferImpl::kStreamRead_Usage
1660 };
1661 static_assert(SK_ARRAY_COUNT(grToGL) == GrGLBufferImpl::kUsageCount, "array_ size_mismatch");
1662 SkASSERT(usage < GrGLBufferImpl::kUsageCount);
1663
1664 return grToGL[usage];
1665 }
1666
1667 void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage ,
1668 size_t currentSize, size_t requestedSize) {
1629 void* mapPtr = nullptr; 1669 void* mapPtr = nullptr;
1670 GrGLenum glUsage = get_gl_usage(usage);
1630 // Handling dirty context is done in the bindBuffer call 1671 // Handling dirty context is done in the bindBuffer call
1631 switch (this->glCaps().mapBufferType()) { 1672 switch (this->glCaps().mapBufferType()) {
1632 case GrGLCaps::kNone_MapBufferType: 1673 case GrGLCaps::kNone_MapBufferType:
1633 break; 1674 break;
1634 case GrGLCaps::kMapBuffer_MapBufferType: 1675 case GrGLCaps::kMapBuffer_MapBufferType:
1635 this->bindBuffer(id, type); 1676 this->bindBuffer(id, type);
1636 // Let driver know it can discard the old data 1677 // Let driver know it can discard the old data
1637 if (GR_GL_USE_BUFFER_DATA_NULL_HINT || currentSize != requestedSize) { 1678 if (GR_GL_USE_BUFFER_DATA_NULL_HINT || currentSize != requestedSize) {
1638 GL_CALL(BufferData(type, requestedSize, nullptr, 1679 GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
1639 dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_ DRAW));
1640 } 1680 }
1641 GL_CALL_RET(mapPtr, MapBuffer(type, GR_GL_WRITE_ONLY)); 1681 GL_CALL_RET(mapPtr, MapBuffer(type, GR_GL_WRITE_ONLY));
1642 break; 1682 break;
1643 case GrGLCaps::kMapBufferRange_MapBufferType: { 1683 case GrGLCaps::kMapBufferRange_MapBufferType: {
1644 this->bindBuffer(id, type); 1684 this->bindBuffer(id, type);
1645 // Make sure the GL buffer size agrees with fDesc before mapping. 1685 // Make sure the GL buffer size agrees with fDesc before mapping.
1646 if (currentSize != requestedSize) { 1686 if (currentSize != requestedSize) {
1647 GL_CALL(BufferData(type, requestedSize, nullptr, 1687 GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
1648 dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_ DRAW));
1649 } 1688 }
1650 static const GrGLbitfield kAccess = GR_GL_MAP_INVALIDATE_BUFFER_BIT | 1689 static const GrGLbitfield kAccess = GR_GL_MAP_INVALIDATE_BUFFER_BIT |
1651 GR_GL_MAP_WRITE_BIT; 1690 GR_GL_MAP_WRITE_BIT;
1652 GL_CALL_RET(mapPtr, MapBufferRange(type, 0, requestedSize, kAccess)) ; 1691 GL_CALL_RET(mapPtr, MapBufferRange(type, 0, requestedSize, kAccess)) ;
1653 break; 1692 break;
1654 } 1693 }
1655 case GrGLCaps::kChromium_MapBufferType: 1694 case GrGLCaps::kChromium_MapBufferType:
1656 this->bindBuffer(id, type); 1695 this->bindBuffer(id, type);
1657 // Make sure the GL buffer size agrees with fDesc before mapping. 1696 // Make sure the GL buffer size agrees with fDesc before mapping.
1658 if (currentSize != requestedSize) { 1697 if (currentSize != requestedSize) {
1659 GL_CALL(BufferData(type, requestedSize, nullptr, 1698 GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
1660 dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_ DRAW));
1661 } 1699 }
1662 GL_CALL_RET(mapPtr, MapBufferSubData(type, 0, requestedSize, GR_GL_W RITE_ONLY)); 1700 GL_CALL_RET(mapPtr, MapBufferSubData(type, 0, requestedSize, GR_GL_W RITE_ONLY));
1663 break; 1701 break;
1664 } 1702 }
1665 return mapPtr; 1703 return mapPtr;
1666 } 1704 }
1667 1705
1668 void GrGLGpu::bufferData(GrGLuint id, GrGLenum type, bool dynamic, size_t curren tSize, 1706 void GrGLGpu::bufferData(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage ,
1669 const void* src, size_t srcSizeInBytes) { 1707 size_t currentSize, const void* src, size_t srcSizeInBy tes) {
1670 SkASSERT(srcSizeInBytes <= currentSize); 1708 SkASSERT(srcSizeInBytes <= currentSize);
1671 // bindbuffer handles dirty context 1709 // bindbuffer handles dirty context
1672 this->bindBuffer(id, type); 1710 this->bindBuffer(id, type);
1673 GrGLenum usage = dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW; 1711 GrGLenum glUsage = get_gl_usage(usage);
1674 1712
1675 #if GR_GL_USE_BUFFER_DATA_NULL_HINT 1713 #if GR_GL_USE_BUFFER_DATA_NULL_HINT
1676 if (currentSize == srcSizeInBytes) { 1714 if (currentSize == srcSizeInBytes) {
1677 GL_CALL(BufferData(type, (GrGLsizeiptr) srcSizeInBytes, src, usage)); 1715 GL_CALL(BufferData(type, (GrGLsizeiptr) srcSizeInBytes, src, glUsage));
1678 } else { 1716 } else {
1679 // Before we call glBufferSubData we give the driver a hint using 1717 // Before we call glBufferSubData we give the driver a hint using
1680 // glBufferData with nullptr. This makes the old buffer contents 1718 // glBufferData with nullptr. This makes the old buffer contents
1681 // inaccessible to future draws. The GPU may still be processing 1719 // inaccessible to future draws. The GPU may still be processing
1682 // draws that reference the old contents. With this hint it can 1720 // draws that reference the old contents. With this hint it can
1683 // assign a different allocation for the new contents to avoid 1721 // assign a different allocation for the new contents to avoid
1684 // flushing the gpu past draws consuming the old contents. 1722 // flushing the gpu past draws consuming the old contents.
1685 // TODO I think we actually want to try calling bufferData here 1723 // TODO I think we actually want to try calling bufferData here
1686 GL_CALL(BufferData(type, currentSize, nullptr, usage)); 1724 GL_CALL(BufferData(type, currentSize, nullptr, glUsage));
1687 GL_CALL(BufferSubData(type, 0, (GrGLsizeiptr) srcSizeInBytes, src)); 1725 GL_CALL(BufferSubData(type, 0, (GrGLsizeiptr) srcSizeInBytes, src));
1688 } 1726 }
1689 #else 1727 #else
1690 // Note that we're cheating on the size here. Currently no methods 1728 // Note that we're cheating on the size here. Currently no methods
1691 // allow a partial update that preserves contents of non-updated 1729 // allow a partial update that preserves contents of non-updated
1692 // portions of the buffer (map() does a glBufferData(..size, nullptr..)) 1730 // portions of the buffer (map() does a glBufferData(..size, nullptr..))
1693 GL_CALL(BufferData(type, srcSizeInBytes, src, usage)); 1731 GL_CALL(BufferData(type, srcSizeInBytes, src, usage));
1694 #endif 1732 #endif
1695 } 1733 }
1696 1734
(...skipping 1701 matching lines...) Expand 10 before | Expand all | Expand 10 after
3398 this->setVertexArrayID(gpu, 0); 3436 this->setVertexArrayID(gpu, 0);
3399 } 3437 }
3400 int attrCount = gpu->glCaps().maxVertexAttributes(); 3438 int attrCount = gpu->glCaps().maxVertexAttributes();
3401 if (fDefaultVertexArrayAttribState.count() != attrCount) { 3439 if (fDefaultVertexArrayAttribState.count() != attrCount) {
3402 fDefaultVertexArrayAttribState.resize(attrCount); 3440 fDefaultVertexArrayAttribState.resize(attrCount);
3403 } 3441 }
3404 attribState = &fDefaultVertexArrayAttribState; 3442 attribState = &fDefaultVertexArrayAttribState;
3405 } 3443 }
3406 return attribState; 3444 return attribState;
3407 } 3445 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698