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

Unified Diff: src/gpu/gl/GrGLGpu.cpp

Issue 1831133004: Revert of Consolidate GPU buffer implementations (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 9 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/gl/GrGLGpu.h ('k') | src/gpu/gl/GrGLIndexBuffer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGLGpu.cpp
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 6b591494b992e13a88c5656f26c5b2b8a5cdc6cc..3a293610f2f8e34fcc79c41462822274207c1bae 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -6,7 +6,6 @@
*/
#include "GrGLGpu.h"
-#include "GrGLBuffer.h"
#include "GrGLGLSL.h"
#include "GrGLStencilAttachment.h"
#include "GrGLTextureRenderTarget.h"
@@ -844,7 +843,7 @@
bool GrGLGpu::onTransferPixels(GrSurface* surface,
int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
+ GrPixelConfig config, GrTransferBuffer* buffer,
size_t offset, size_t rowBytes) {
GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
@@ -860,14 +859,16 @@
this->setScratchTextureUnit();
GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
- SkASSERT(kXferCpuToGpu_GrBufferType == transferBuffer->type());
- SkASSERT(!transferBuffer->isMapped());
- const GrGLBuffer* glBuffer = reinterpret_cast<const GrGLBuffer*>(transferBuffer);
- this->bindBuffer(glBuffer->bufferID(), glBuffer->target());
+ SkASSERT(!buffer->isMapped());
+ GrGLTransferBuffer* glBuffer = reinterpret_cast<GrGLTransferBuffer*>(buffer);
+ // bind the transfer buffer
+ SkASSERT(GR_GL_PIXEL_UNPACK_BUFFER == glBuffer->bufferType() ||
+ GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == glBuffer->bufferType());
+ GL_CALL(BindBuffer(glBuffer->bufferType(), glBuffer->bufferID()));
bool success = false;
GrMipLevel mipLevel;
- mipLevel.fPixels = transferBuffer;
+ mipLevel.fPixels = buffer;
mipLevel.fRowBytes = rowBytes;
SkSTArray<1, GrMipLevel> texels;
texels.push_back(mipLevel);
@@ -1932,8 +1933,111 @@
// objects are implemented as client-side-arrays on tile-deferred architectures.
#define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW
-GrBuffer* GrGLGpu::onCreateBuffer(GrBufferType type, size_t size, GrAccessPattern accessPattern) {
- return GrGLBuffer::Create(this, type, size, accessPattern);
+GrVertexBuffer* GrGLGpu::onCreateVertexBuffer(size_t size, bool dynamic) {
+ GrGLVertexBuffer::Desc desc;
+ desc.fUsage = dynamic ? GrGLBufferImpl::kDynamicDraw_Usage : GrGLBufferImpl::kStaticDraw_Usage;
+ desc.fSizeInBytes = size;
+
+ if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && dynamic) {
+ desc.fID = 0;
+ GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, desc);
+ return vertexBuffer;
+ } else {
+ desc.fID = 0;
+ GL_CALL(GenBuffers(1, &desc.fID));
+ if (desc.fID) {
+ fHWGeometryState.setVertexBufferID(this, desc.fID);
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
+ // make sure driver can allocate memory for this buffer
+ GL_ALLOC_CALL(this->glInterface(),
+ BufferData(GR_GL_ARRAY_BUFFER,
+ (GrGLsizeiptr) desc.fSizeInBytes,
+ nullptr, // data ptr
+ dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_CALL(DeleteBuffers(1, &desc.fID));
+ this->notifyVertexBufferDelete(desc.fID);
+ return nullptr;
+ }
+ GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, desc);
+ return vertexBuffer;
+ }
+ return nullptr;
+ }
+}
+
+GrIndexBuffer* GrGLGpu::onCreateIndexBuffer(size_t size, bool dynamic) {
+ GrGLIndexBuffer::Desc desc;
+ desc.fUsage = dynamic ? GrGLBufferImpl::kDynamicDraw_Usage : GrGLBufferImpl::kStaticDraw_Usage;
+ desc.fSizeInBytes = size;
+
+ if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && dynamic) {
+ desc.fID = 0;
+ GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, desc);
+ return indexBuffer;
+ } else {
+ desc.fID = 0;
+ GL_CALL(GenBuffers(1, &desc.fID));
+ if (desc.fID) {
+ fHWGeometryState.setIndexBufferIDOnDefaultVertexArray(this, desc.fID);
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
+ // make sure driver can allocate memory for this buffer
+ GL_ALLOC_CALL(this->glInterface(),
+ BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
+ (GrGLsizeiptr) desc.fSizeInBytes,
+ nullptr, // data ptr
+ dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_CALL(DeleteBuffers(1, &desc.fID));
+ this->notifyIndexBufferDelete(desc.fID);
+ return nullptr;
+ }
+ GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, desc);
+ return indexBuffer;
+ }
+ return nullptr;
+ }
+}
+
+GrTransferBuffer* GrGLGpu::onCreateTransferBuffer(size_t size, TransferType xferType) {
+ GrGLCaps::TransferBufferType xferBufferType = this->ctxInfo().caps()->transferBufferType();
+ if (GrGLCaps::kNone_TransferBufferType == xferBufferType) {
+ return nullptr;
+ }
+
+ GrGLTransferBuffer::Desc desc;
+ bool toGpu = (kCpuToGpu_TransferType == xferType);
+ desc.fUsage = toGpu ? GrGLBufferImpl::kStreamDraw_Usage : GrGLBufferImpl::kStreamRead_Usage;
+
+ desc.fSizeInBytes = size;
+ desc.fID = 0;
+ GL_CALL(GenBuffers(1, &desc.fID));
+ if (desc.fID) {
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
+ // make sure driver can allocate memory for this bmapuffer
+ GrGLenum target;
+ if (GrGLCaps::kChromium_TransferBufferType == xferBufferType) {
+ target = toGpu ? GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM
+ : GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM;
+ } else {
+ SkASSERT(GrGLCaps::kPBO_TransferBufferType == xferBufferType);
+ target = toGpu ? GR_GL_PIXEL_UNPACK_BUFFER : GR_GL_PIXEL_PACK_BUFFER;
+ }
+ GL_CALL(BindBuffer(target, desc.fID));
+ GL_ALLOC_CALL(this->glInterface(),
+ BufferData(target,
+ (GrGLsizeiptr) desc.fSizeInBytes,
+ nullptr, // data ptr
+ (toGpu ? GR_GL_STREAM_DRAW : GR_GL_STREAM_READ)));
+ if (CHECK_ALLOC_ERROR(this->glInterface()) != GR_GL_NO_ERROR) {
+ GL_CALL(DeleteBuffers(1, &desc.fID));
+ return nullptr;
+ }
+ GrTransferBuffer* transferBuffer = new GrGLTransferBuffer(this, desc, target);
+ return transferBuffer;
+ }
+
+ return nullptr;
}
void GrGLGpu::flushScissor(const GrScissorState& scissorState,
@@ -2018,18 +2122,18 @@
void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
const GrNonInstancedMesh& mesh,
size_t* indexOffsetInBytes) {
- const GrGLBuffer* vbuf;
- vbuf = static_cast<const GrGLBuffer*>(mesh.vertexBuffer());
+ GrGLVertexBuffer* vbuf;
+ vbuf = (GrGLVertexBuffer*) mesh.vertexBuffer();
SkASSERT(vbuf);
SkASSERT(!vbuf->isMapped());
- const GrGLBuffer* ibuf = nullptr;
+ GrGLIndexBuffer* ibuf = nullptr;
if (mesh.isIndexed()) {
SkASSERT(indexOffsetInBytes);
*indexOffsetInBytes = 0;
- ibuf = static_cast<const GrGLBuffer*>(mesh.indexBuffer());
+ ibuf = (GrGLIndexBuffer*)mesh.indexBuffer();
SkASSERT(ibuf);
SkASSERT(!ibuf->isMapped());
@@ -2115,6 +2219,113 @@
if (fHWBoundDrawIndirectBufferIDIsValid && id == fHWBoundDrawIndirectBufferID) {
fHWBoundDrawIndirectBufferID = 0;
}
+ break;
+ }
+}
+
+static GrGLenum get_gl_usage(GrGLBufferImpl::Usage usage) {
+ static const GrGLenum grToGL[] = {
+ GR_GL_STATIC_DRAW, // GrGLBufferImpl::kStaticDraw_Usage
+ DYNAMIC_USAGE_PARAM, // GrGLBufferImpl::kDynamicDraw_Usage
+ GR_GL_STREAM_DRAW, // GrGLBufferImpl::kStreamDraw_Usage
+ GR_GL_STREAM_READ, // GrGLBufferImpl::kStreamRead_Usage
+ };
+ static_assert(SK_ARRAY_COUNT(grToGL) == GrGLBufferImpl::kUsageCount, "array_size_mismatch");
+
+ return grToGL[usage];
+}
+
+void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage,
+ size_t currentSize, size_t requestedSize) {
+ void* mapPtr = nullptr;
+ GrGLenum glUsage = get_gl_usage(usage);
+ bool readOnly = (GrGLBufferImpl::kStreamRead_Usage == usage);
+
+ // Handling dirty context is done in the bindBuffer call
+ switch (this->glCaps().mapBufferType()) {
+ case GrGLCaps::kNone_MapBufferType:
+ break;
+ case GrGLCaps::kMapBuffer_MapBufferType:
+ this->bindBuffer(id, type);
+ // Let driver know it can discard the old data
+ if (GR_GL_USE_BUFFER_DATA_NULL_HINT || currentSize != requestedSize) {
+ GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
+ }
+ GL_CALL_RET(mapPtr, MapBuffer(type, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
+ break;
+ case GrGLCaps::kMapBufferRange_MapBufferType: {
+ this->bindBuffer(id, type);
+ // Make sure the GL buffer size agrees with fDesc before mapping.
+ if (currentSize != requestedSize) {
+ GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
+ }
+ GrGLbitfield writeAccess = GR_GL_MAP_WRITE_BIT;
+ // TODO: allow the client to specify invalidation in the stream draw case
+ if (GrGLBufferImpl::kStreamDraw_Usage != usage) {
+ writeAccess |= GR_GL_MAP_INVALIDATE_BUFFER_BIT;
+ }
+ GL_CALL_RET(mapPtr, MapBufferRange(type, 0, requestedSize, readOnly ?
+ GR_GL_MAP_READ_BIT :
+ writeAccess));
+ break;
+ }
+ case GrGLCaps::kChromium_MapBufferType:
+ this->bindBuffer(id, type);
+ // Make sure the GL buffer size agrees with fDesc before mapping.
+ if (currentSize != requestedSize) {
+ GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
+ }
+ GL_CALL_RET(mapPtr, MapBufferSubData(type, 0, requestedSize, readOnly ?
+ GR_GL_READ_ONLY :
+ GR_GL_WRITE_ONLY));
+ break;
+ }
+ return mapPtr;
+}
+
+void GrGLGpu::bufferData(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage,
+ size_t currentSize, const void* src, size_t srcSizeInBytes) {
+ SkASSERT(srcSizeInBytes <= currentSize);
+ // bindbuffer handles dirty context
+ this->bindBuffer(id, type);
+ GrGLenum glUsage = get_gl_usage(usage);
+
+#if GR_GL_USE_BUFFER_DATA_NULL_HINT
+ if (currentSize == srcSizeInBytes) {
+ GL_CALL(BufferData(type, (GrGLsizeiptr) srcSizeInBytes, src, glUsage));
+ } else {
+ // Before we call glBufferSubData we give the driver a hint using
+ // glBufferData with nullptr. This makes the old buffer contents
+ // inaccessible to future draws. The GPU may still be processing
+ // draws that reference the old contents. With this hint it can
+ // assign a different allocation for the new contents to avoid
+ // flushing the gpu past draws consuming the old contents.
+ // TODO I think we actually want to try calling bufferData here
+ GL_CALL(BufferData(type, currentSize, nullptr, glUsage));
+ GL_CALL(BufferSubData(type, 0, (GrGLsizeiptr) srcSizeInBytes, src));
+ }
+#else
+ // Note that we're cheating on the size here. Currently no methods
+ // allow a partial update that preserves contents of non-updated
+ // portions of the buffer (map() does a glBufferData(..size, nullptr..))
+ GL_CALL(BufferData(type, srcSizeInBytes, src, glUsage));
+#endif
+}
+
+void GrGLGpu::unmapBuffer(GrGLuint id, GrGLenum type, void* mapPtr) {
+ // bind buffer handles the dirty context
+ switch (this->glCaps().mapBufferType()) {
+ case GrGLCaps::kNone_MapBufferType:
+ SkDEBUGFAIL("Shouldn't get here.");
+ return;
+ case GrGLCaps::kMapBuffer_MapBufferType: // fall through
+ case GrGLCaps::kMapBufferRange_MapBufferType:
+ this->bindBuffer(id, type);
+ GL_CALL(UnmapBuffer(type));
+ break;
+ case GrGLCaps::kChromium_MapBufferType:
+ this->bindBuffer(id, type);
+ GL_CALL(UnmapBufferSubData(mapPtr));
break;
}
}
@@ -4140,8 +4351,8 @@
///////////////////////////////////////////////////////////////////////////////
GrGLAttribArrayState* GrGLGpu::HWGeometryState::bindArrayAndBuffersToDraw(
GrGLGpu* gpu,
- const GrGLBuffer* vbuffer,
- const GrGLBuffer* ibuffer) {
+ const GrGLVertexBuffer* vbuffer,
+ const GrGLIndexBuffer* ibuffer) {
SkASSERT(vbuffer);
GrGLuint vbufferID = vbuffer->bufferID();
GrGLuint* ibufferIDPtr = nullptr;
« no previous file with comments | « src/gpu/gl/GrGLGpu.h ('k') | src/gpu/gl/GrGLIndexBuffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698