diff options
author | 2016-03-25 04:55:58 -0700 | |
---|---|---|
committer | 2016-03-25 04:55:59 -0700 | |
commit | f8c3ba40cf4f42b2c2ba1b473c28d7733383223e (patch) | |
tree | 00c671765311aaa35c8a9d6fa0a6b84907c871b9 /src/gpu/gl/GrGLBuffer.cpp | |
parent | f299e7105435829c47e94f4cf6e408cad675bc77 (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.cpp | 336 |
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 |