aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGLBuffer.cpp
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2016-03-25 04:55:58 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-25 04:55:59 -0700
commitf8c3ba40cf4f42b2c2ba1b473c28d7733383223e (patch)
tree00c671765311aaa35c8a9d6fa0a6b84907c871b9 /src/gpu/gl/GrGLBuffer.cpp
parentf299e7105435829c47e94f4cf6e408cad675bc77 (diff)
Revert of Consolidate GPU buffer implementations (patchset #10 id:180001 of https://codereview.chromium.org/1825393002/ )
Reason for revert: Lots of Android redness Original issue's description: > Consolidate GPU buffer implementations > > Consolidates all the different buffer implementations into a single > GrBuffer class. This will allow us to add new buffer types, use DSA in > OpenGL, track buffer bindings by unique ID, cache buffers without > respect to the type of data they have been used for previously, etc. > This change is strictly a refactor; it introduces no change in > functionality. > > BUG=skia: > GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1825393002 > > Committed: https://skia.googlesource.com/skia/+/8b1bff29675afd25843439eade634a57f68fe16f TBR=bsalomon@google.com,egdaniel@google.com,jvanverth@google.com,cdalton@nvidia.com # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Review URL: https://codereview.chromium.org/1831133004
Diffstat (limited to 'src/gpu/gl/GrGLBuffer.cpp')
-rw-r--r--src/gpu/gl/GrGLBuffer.cpp336
1 files changed, 0 insertions, 336 deletions
diff --git a/src/gpu/gl/GrGLBuffer.cpp b/src/gpu/gl/GrGLBuffer.cpp
deleted file mode 100644
index ad56ceb729..0000000000
--- a/src/gpu/gl/GrGLBuffer.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrGLBuffer.h"
-#include "GrGLGpu.h"
-#include "SkTraceMemoryDump.h"
-
-#define GL_CALL(X) GR_GL_CALL(this->glGpu()->glInterface(), X)
-#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glGpu()->glInterface(), RET, X)
-
-#if GR_GL_CHECK_ALLOC_WITH_GET_ERROR
- #define CLEAR_ERROR_BEFORE_ALLOC(iface) GrGLClearErr(iface)
- #define GL_ALLOC_CALL(iface, call) GR_GL_CALL_NOERRCHECK(iface, call)
- #define CHECK_ALLOC_ERROR(iface) GR_GL_GET_ERROR(iface)
-#else
- #define CLEAR_ERROR_BEFORE_ALLOC(iface)
- #define GL_ALLOC_CALL(iface, call) GR_GL_CALL(iface, call)
- #define CHECK_ALLOC_ERROR(iface) GR_GL_NO_ERROR
-#endif
-
-#ifdef SK_DEBUG
-#define VALIDATE() this->validate()
-#else
-#define VALIDATE() do {} while(false)
-#endif
-
-GrGLBuffer* GrGLBuffer::Create(GrGLGpu* gpu, GrBufferType type, size_t size,
- GrAccessPattern accessPattern) {
- static const int kIsVertexOrIndex = (1 << kVertex_GrBufferType) | (1 << kIndex_GrBufferType);
- bool cpuBacked = gpu->glCaps().useNonVBOVertexAndIndexDynamicData() &&
- kDynamic_GrAccessPattern == accessPattern &&
- ((kIsVertexOrIndex >> type) & 1);
- SkAutoTUnref<GrGLBuffer> buffer(new GrGLBuffer(gpu, type, size, accessPattern, cpuBacked));
- if (!cpuBacked && 0 == buffer->fBufferID) {
- return nullptr;
- }
- return buffer.release();
-}
-
-// GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a client's vertex buffer
-// objects are implemented as client-side-arrays on tile-deferred architectures.
-#define DYNAMIC_DRAW_PARAM GR_GL_STREAM_DRAW
-
-inline static void get_target_and_usage(GrBufferType type, GrAccessPattern accessPattern,
- const GrGLCaps& caps, GrGLenum* target, GrGLenum* usage) {
- static const GrGLenum nonXferTargets[] = {
- GR_GL_ARRAY_BUFFER,
- GR_GL_ELEMENT_ARRAY_BUFFER
- };
- GR_STATIC_ASSERT(0 == kVertex_GrBufferType);
- GR_STATIC_ASSERT(1 == kIndex_GrBufferType);
-
- static const GrGLenum drawUsages[] = {
- DYNAMIC_DRAW_PARAM, // TODO: Do we really want to use STREAM_DRAW here on non-Chromium?
- GR_GL_STATIC_DRAW,
- GR_GL_STREAM_DRAW
- };
- static const GrGLenum readUsages[] = {
- GR_GL_DYNAMIC_READ,
- GR_GL_STATIC_READ,
- GR_GL_STREAM_READ
- };
- GR_STATIC_ASSERT(0 == kDynamic_GrAccessPattern);
- GR_STATIC_ASSERT(1 == kStatic_GrAccessPattern);
- GR_STATIC_ASSERT(2 == kStream_GrAccessPattern);
- GR_STATIC_ASSERT(SK_ARRAY_COUNT(drawUsages) == 1 + kLast_GrAccessPattern);
- GR_STATIC_ASSERT(SK_ARRAY_COUNT(readUsages) == 1 + kLast_GrAccessPattern);
-
- SkASSERT(accessPattern >= 0 && accessPattern <= kLast_GrAccessPattern);
-
- switch (type) {
- case kVertex_GrBufferType:
- case kIndex_GrBufferType:
- *target = nonXferTargets[type];
- *usage = drawUsages[accessPattern];
- break;
- case kXferCpuToGpu_GrBufferType:
- if (GrGLCaps::kChromium_TransferBufferType == caps.transferBufferType()) {
- *target = GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM;
- } else {
- SkASSERT(GrGLCaps::kPBO_TransferBufferType == caps.transferBufferType());
- *target = GR_GL_PIXEL_UNPACK_BUFFER;
- }
- *usage = drawUsages[accessPattern];
- break;
- case kXferGpuToCpu_GrBufferType:
- if (GrGLCaps::kChromium_TransferBufferType == caps.transferBufferType()) {
- *target = GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM;
- } else {
- SkASSERT(GrGLCaps::kPBO_TransferBufferType == caps.transferBufferType());
- *target = GR_GL_PIXEL_PACK_BUFFER;
- }
- *usage = readUsages[accessPattern];
- break;
- default:
- SkFAIL("Unexpected buffer type.");
- break;
- }
-}
-
-GrGLBuffer::GrGLBuffer(GrGLGpu* gpu, GrBufferType type, size_t size, GrAccessPattern accessPattern,
- bool cpuBacked)
- : INHERITED(gpu, type, size, accessPattern, cpuBacked),
- fCPUData(nullptr),
- fTarget(0),
- fBufferID(0),
- fSizeInBytes(size),
- fUsage(0),
- fGLSizeInBytes(0) {
- if (cpuBacked) {
- if (gpu->caps()->mustClearUploadedBufferData()) {
- fCPUData = sk_calloc_throw(fSizeInBytes);
- } else {
- fCPUData = sk_malloc_flags(fSizeInBytes, SK_MALLOC_THROW);
- }
- } else {
- GL_CALL(GenBuffers(1, &fBufferID));
- fSizeInBytes = size;
- get_target_and_usage(type, accessPattern, gpu->glCaps(), &fTarget, &fUsage);
- if (fBufferID) {
- gpu->bindBuffer(fBufferID, fTarget);
- CLEAR_ERROR_BEFORE_ALLOC(gpu->glInterface());
- // make sure driver can allocate memory for this buffer
- GL_ALLOC_CALL(gpu->glInterface(), BufferData(fTarget,
- (GrGLsizeiptr) fSizeInBytes,
- nullptr, // data ptr
- fUsage));
- if (CHECK_ALLOC_ERROR(gpu->glInterface()) != GR_GL_NO_ERROR) {
- gpu->releaseBuffer(fBufferID, fTarget);
- fBufferID = 0;
- } else {
- fGLSizeInBytes = fSizeInBytes;
- }
- }
- }
- VALIDATE();
- this->registerWithCache();
-}
-
-inline GrGLGpu* GrGLBuffer::glGpu() const {
- SkASSERT(!this->wasDestroyed());
- return static_cast<GrGLGpu*>(this->getGpu());
-}
-
-inline const GrGLCaps& GrGLBuffer::glCaps() const {
- return this->glGpu()->glCaps();
-}
-
-void GrGLBuffer::onRelease() {
- if (!this->wasDestroyed()) {
- VALIDATE();
- // make sure we've not been abandoned or already released
- if (fCPUData) {
- SkASSERT(!fBufferID);
- sk_free(fCPUData);
- fCPUData = nullptr;
- } else if (fBufferID) {
- this->glGpu()->releaseBuffer(fBufferID, fTarget);
- fBufferID = 0;
- fGLSizeInBytes = 0;
- }
- fMapPtr = nullptr;
- VALIDATE();
- }
-
- INHERITED::onRelease();
-}
-
-void GrGLBuffer::onAbandon() {
- fBufferID = 0;
- fGLSizeInBytes = 0;
- fMapPtr = nullptr;
- sk_free(fCPUData);
- fCPUData = nullptr;
- VALIDATE();
- INHERITED::onAbandon();
-}
-
-void GrGLBuffer::onMap() {
- if (this->wasDestroyed()) {
- return;
- }
-
- VALIDATE();
- SkASSERT(!this->isMapped());
-
- if (0 == fBufferID) {
- fMapPtr = fCPUData;
- VALIDATE();
- return;
- }
-
- bool readOnly = (kXferGpuToCpu_GrBufferType == this->type());
-
- // Handling dirty context is done in the bindBuffer call
- switch (this->glCaps().mapBufferType()) {
- case GrGLCaps::kNone_MapBufferType:
- break;
- case GrGLCaps::kMapBuffer_MapBufferType:
- this->glGpu()->bindBuffer(fBufferID, fTarget);
- // Let driver know it can discard the old data
- if (GR_GL_USE_BUFFER_DATA_NULL_HINT || fGLSizeInBytes != fSizeInBytes) {
- GL_CALL(BufferData(fTarget, fSizeInBytes, nullptr, fUsage));
- }
- GL_CALL_RET(fMapPtr, MapBuffer(fTarget, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
- break;
- case GrGLCaps::kMapBufferRange_MapBufferType: {
- this->glGpu()->bindBuffer(fBufferID, fTarget);
- // Make sure the GL buffer size agrees with fDesc before mapping.
- if (fGLSizeInBytes != fSizeInBytes) {
- GL_CALL(BufferData(fTarget, fSizeInBytes, nullptr, fUsage));
- }
- GrGLbitfield writeAccess = GR_GL_MAP_WRITE_BIT;
- // TODO: allow the client to specify invalidation in the transfer buffer case.
- if (kXferCpuToGpu_GrBufferType != this->type()) {
- writeAccess |= GR_GL_MAP_INVALIDATE_BUFFER_BIT;
- }
- GL_CALL_RET(fMapPtr, MapBufferRange(fTarget, 0, fSizeInBytes,
- readOnly ? GR_GL_MAP_READ_BIT : writeAccess));
- break;
- }
- case GrGLCaps::kChromium_MapBufferType:
- this->glGpu()->bindBuffer(fBufferID, fTarget);
- // Make sure the GL buffer size agrees with fDesc before mapping.
- if (fGLSizeInBytes != fSizeInBytes) {
- GL_CALL(BufferData(fTarget, fSizeInBytes, nullptr, fUsage));
- }
- GL_CALL_RET(fMapPtr, MapBufferSubData(fTarget, 0, fSizeInBytes,
- readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
- break;
- }
- fGLSizeInBytes = fSizeInBytes;
- VALIDATE();
-}
-
-void GrGLBuffer::onUnmap() {
- if (this->wasDestroyed()) {
- return;
- }
-
- VALIDATE();
- SkASSERT(this->isMapped());
- if (0 == fBufferID) {
- fMapPtr = nullptr;
- return;
- }
- // 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->glGpu()->bindBuffer(fBufferID, fTarget);
- GL_CALL(UnmapBuffer(fTarget));
- break;
- case GrGLCaps::kChromium_MapBufferType:
- this->glGpu()->bindBuffer(fBufferID, fTarget);
- GL_CALL(UnmapBufferSubData(fMapPtr));
- break;
- }
- fMapPtr = nullptr;
-}
-
-bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
- if (this->wasDestroyed()) {
- return false;
- }
-
- SkASSERT(!this->isMapped());
- SkASSERT(GR_GL_ARRAY_BUFFER == fTarget || GR_GL_ELEMENT_ARRAY_BUFFER == fTarget);
- VALIDATE();
- if (srcSizeInBytes > fSizeInBytes) {
- return false;
- }
- if (0 == fBufferID) {
- memcpy(fCPUData, src, srcSizeInBytes);
- return true;
- }
- SkASSERT(srcSizeInBytes <= fSizeInBytes);
- // bindbuffer handles dirty context
- this->glGpu()->bindBuffer(fBufferID, fTarget);
-
-#if GR_GL_USE_BUFFER_DATA_NULL_HINT
- if (fSizeInBytes == srcSizeInBytes) {
- GL_CALL(BufferData(fTarget, (GrGLsizeiptr) srcSizeInBytes, src, fUsage));
- } 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(fTarget, fSizeInBytes, nullptr, fUsage));
- GL_CALL(BufferSubData(fTarget, 0, (GrGLsizeiptr) srcSizeInBytes, src));
- }
- fGLSizeInBytes = fSizeInBytes;
-#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(fTarget, srcSizeInBytes, src, fUsage));
- fGLSizeInBytes = srcSizeInBytes;
-#endif
- VALIDATE();
- return true;
-}
-
-void GrGLBuffer::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
- const SkString& dumpName) const {
- SkString buffer_id;
- buffer_id.appendU32(this->bufferID());
- traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_buffer",
- buffer_id.c_str());
-}
-
-#ifdef SK_DEBUG
-
-void GrGLBuffer::validate() const {
- SkASSERT(GR_GL_ARRAY_BUFFER == fTarget || GR_GL_ELEMENT_ARRAY_BUFFER == fTarget ||
- GR_GL_PIXEL_PACK_BUFFER == fTarget || GR_GL_PIXEL_UNPACK_BUFFER == fTarget ||
- GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM == fTarget ||
- GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == fTarget);
- // The following assert isn't valid when the buffer has been abandoned:
- // SkASSERT((0 == fDesc.fID) == (fCPUData));
- SkASSERT(0 != fBufferID || 0 == fGLSizeInBytes);
- SkASSERT(nullptr == fMapPtr || fCPUData || fGLSizeInBytes <= fSizeInBytes);
- SkASSERT(nullptr == fCPUData || nullptr == fMapPtr || fCPUData == fMapPtr);
-}
-
-#endif