diff options
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLBuffer.cpp | 104 | ||||
-rw-r--r-- | src/gpu/gl/GrGLBuffer.h | 6 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 27 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 22 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.h | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGLVertexArray.cpp | 12 | ||||
-rw-r--r-- | src/gpu/gl/GrGLVertexArray.h | 6 |
7 files changed, 72 insertions, 109 deletions
diff --git a/src/gpu/gl/GrGLBuffer.cpp b/src/gpu/gl/GrGLBuffer.cpp index 37ce273d1f..96226b9121 100644 --- a/src/gpu/gl/GrGLBuffer.cpp +++ b/src/gpu/gl/GrGLBuffer.cpp @@ -30,12 +30,8 @@ GrGLBuffer* GrGLBuffer::Create(GrGLGpu* gpu, size_t size, GrBufferType intendedType, GrAccessPattern accessPattern, const void* data) { - bool cpuBacked = gpu->glCaps().useNonVBOVertexAndIndexDynamicData() && - GrBufferTypeIsVertexOrIndex(intendedType) && - kDynamic_GrAccessPattern == accessPattern; - SkAutoTUnref<GrGLBuffer> buffer(new GrGLBuffer(gpu, size, intendedType, accessPattern, - cpuBacked, data)); - if (!cpuBacked && 0 == buffer->bufferID()) { + SkAutoTUnref<GrGLBuffer> buffer(new GrGLBuffer(gpu, size, intendedType, accessPattern, data)); + if (0 == buffer->bufferID()) { return nullptr; } return buffer.release(); @@ -89,42 +85,27 @@ inline static GrGLenum gr_to_gl_access_pattern(GrBufferType bufferType, } GrGLBuffer::GrGLBuffer(GrGLGpu* gpu, size_t size, GrBufferType intendedType, - GrAccessPattern accessPattern, bool cpuBacked, const void* data) - : INHERITED(gpu, size, intendedType, accessPattern, cpuBacked), - fCPUData(nullptr), + GrAccessPattern accessPattern, const void* data) + : INHERITED(gpu, size, intendedType, accessPattern), fIntendedType(intendedType), fBufferID(0), - fSizeInBytes(size), fUsage(gr_to_gl_access_pattern(intendedType, accessPattern)), fGLSizeInBytes(0), fHasAttachedToTexture(false) { - if (this->isCPUBacked()) { - // Core profile uses vertex array objects, which disallow client side arrays. - SkASSERT(!gpu->glCaps().isCoreProfile()); - if (gpu->caps()->mustClearUploadedBufferData()) { - fCPUData = sk_calloc_throw(fSizeInBytes); + GL_CALL(GenBuffers(1, &fBufferID)); + if (fBufferID) { + GrGLenum target = gpu->bindBuffer(fIntendedType, this); + CLEAR_ERROR_BEFORE_ALLOC(gpu->glInterface()); + // make sure driver can allocate memory for this buffer + GL_ALLOC_CALL(gpu->glInterface(), BufferData(target, + (GrGLsizeiptr) size, + data, + fUsage)); + if (CHECK_ALLOC_ERROR(gpu->glInterface()) != GR_GL_NO_ERROR) { + GL_CALL(DeleteBuffers(1, &fBufferID)); + fBufferID = 0; } else { - fCPUData = sk_malloc_flags(fSizeInBytes, SK_MALLOC_THROW); - } - if (data) { - memcpy(fCPUData, data, fSizeInBytes); - } - } else { - GL_CALL(GenBuffers(1, &fBufferID)); - if (fBufferID) { - GrGLenum target = gpu->bindBuffer(fIntendedType, this); - CLEAR_ERROR_BEFORE_ALLOC(gpu->glInterface()); - // make sure driver can allocate memory for this buffer - GL_ALLOC_CALL(gpu->glInterface(), BufferData(target, - (GrGLsizeiptr) fSizeInBytes, - data, - fUsage)); - if (CHECK_ALLOC_ERROR(gpu->glInterface()) != GR_GL_NO_ERROR) { - GL_CALL(DeleteBuffers(1, &fBufferID)); - fBufferID = 0; - } else { - fGLSizeInBytes = fSizeInBytes; - } + fGLSizeInBytes = size; } } VALIDATE(); @@ -144,11 +125,7 @@ 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) { + if (fBufferID) { GL_CALL(DeleteBuffers(1, &fBufferID)); fBufferID = 0; fGLSizeInBytes = 0; @@ -165,8 +142,6 @@ void GrGLBuffer::onAbandon() { fBufferID = 0; fGLSizeInBytes = 0; fMapPtr = nullptr; - sk_free(fCPUData); - fCPUData = nullptr; VALIDATE(); INHERITED::onAbandon(); } @@ -179,12 +154,6 @@ void GrGLBuffer::onMap() { VALIDATE(); SkASSERT(!this->isMapped()); - if (0 == fBufferID) { - fMapPtr = fCPUData; - VALIDATE(); - return; - } - // TODO: Make this a function parameter. bool readOnly = (kXferGpuToCpu_GrBufferType == fIntendedType); @@ -195,8 +164,8 @@ void GrGLBuffer::onMap() { case GrGLCaps::kMapBuffer_MapBufferType: { GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this); // Let driver know it can discard the old data - if (GR_GL_USE_BUFFER_DATA_NULL_HINT || fGLSizeInBytes != fSizeInBytes) { - GL_CALL(BufferData(target, fSizeInBytes, nullptr, fUsage)); + if (GR_GL_USE_BUFFER_DATA_NULL_HINT || fGLSizeInBytes != this->sizeInBytes()) { + GL_CALL(BufferData(target, this->sizeInBytes(), nullptr, fUsage)); } GL_CALL_RET(fMapPtr, MapBuffer(target, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY)); break; @@ -204,30 +173,30 @@ void GrGLBuffer::onMap() { case GrGLCaps::kMapBufferRange_MapBufferType: { GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this); // Make sure the GL buffer size agrees with fDesc before mapping. - if (fGLSizeInBytes != fSizeInBytes) { - GL_CALL(BufferData(target, fSizeInBytes, nullptr, fUsage)); + if (fGLSizeInBytes != this->sizeInBytes()) { + GL_CALL(BufferData(target, this->sizeInBytes(), nullptr, fUsage)); } GrGLbitfield writeAccess = GR_GL_MAP_WRITE_BIT; if (kXferCpuToGpu_GrBufferType != fIntendedType) { // TODO: Make this a function parameter. writeAccess |= GR_GL_MAP_INVALIDATE_BUFFER_BIT; } - GL_CALL_RET(fMapPtr, MapBufferRange(target, 0, fSizeInBytes, + GL_CALL_RET(fMapPtr, MapBufferRange(target, 0, this->sizeInBytes(), readOnly ? GR_GL_MAP_READ_BIT : writeAccess)); break; } case GrGLCaps::kChromium_MapBufferType: { GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this); // Make sure the GL buffer size agrees with fDesc before mapping. - if (fGLSizeInBytes != fSizeInBytes) { - GL_CALL(BufferData(target, fSizeInBytes, nullptr, fUsage)); + if (fGLSizeInBytes != this->sizeInBytes()) { + GL_CALL(BufferData(target, this->sizeInBytes(), nullptr, fUsage)); } - GL_CALL_RET(fMapPtr, MapBufferSubData(target, 0, fSizeInBytes, + GL_CALL_RET(fMapPtr, MapBufferSubData(target, 0, this->sizeInBytes(), readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY)); break; } } - fGLSizeInBytes = fSizeInBytes; + fGLSizeInBytes = this->sizeInBytes(); VALIDATE(); } @@ -268,19 +237,15 @@ bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) { SkASSERT(!this->isMapped()); VALIDATE(); - if (srcSizeInBytes > fSizeInBytes) { + if (srcSizeInBytes > this->sizeInBytes()) { return false; } - if (0 == fBufferID) { - memcpy(fCPUData, src, srcSizeInBytes); - return true; - } - SkASSERT(srcSizeInBytes <= fSizeInBytes); + SkASSERT(srcSizeInBytes <= this->sizeInBytes()); // bindbuffer handles dirty context GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this); #if GR_GL_USE_BUFFER_DATA_NULL_HINT - if (fSizeInBytes == srcSizeInBytes) { + if (this->sizeInBytes() == srcSizeInBytes) { GL_CALL(BufferData(target, (GrGLsizeiptr) srcSizeInBytes, src, fUsage)); } else { // Before we call glBufferSubData we give the driver a hint using @@ -290,10 +255,10 @@ bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) { // 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(target, fSizeInBytes, nullptr, fUsage)); + GL_CALL(BufferData(target, this->sizeInBytes(), nullptr, fUsage)); GL_CALL(BufferSubData(target, 0, (GrGLsizeiptr) srcSizeInBytes, src)); } - fGLSizeInBytes = fSizeInBytes; + fGLSizeInBytes = this->sizeInBytes(); #else // Note that we're cheating on the size here. Currently no methods // allow a partial update that preserves contents of non-updated @@ -316,11 +281,8 @@ void GrGLBuffer::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump, #ifdef SK_DEBUG void GrGLBuffer::validate() const { - // 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); + SkASSERT(nullptr == fMapPtr || fGLSizeInBytes <= this->sizeInBytes()); } #endif diff --git a/src/gpu/gl/GrGLBuffer.h b/src/gpu/gl/GrGLBuffer.h index 84d05be382..6a90d0334c 100644 --- a/src/gpu/gl/GrGLBuffer.h +++ b/src/gpu/gl/GrGLBuffer.h @@ -25,7 +25,6 @@ public: } GrGLuint bufferID() const { return fBufferID; } - size_t baseOffset() const { return reinterpret_cast<size_t>(fCPUData); } /** * Returns the actual size of the underlying GL buffer object. In certain cases we may make this @@ -37,8 +36,7 @@ public: bool hasAttachedToTexture() const { return fHasAttachedToTexture; } protected: - GrGLBuffer(GrGLGpu*, size_t size, GrBufferType intendedType, GrAccessPattern, bool cpuBacked, - const void* data); + GrGLBuffer(GrGLGpu*, size_t size, GrBufferType intendedType, GrAccessPattern, const void* data); void onAbandon() override; void onRelease() override; @@ -57,10 +55,8 @@ private: void validate() const; #endif - void* fCPUData; GrBufferType fIntendedType; GrGLuint fBufferID; - size_t fSizeInBytes; GrGLenum fUsage; size_t fGLSizeInBytes; bool fHasAttachedToTexture; diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 431390697b..6a34a30771 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -41,7 +41,6 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions, fMultiDrawIndirectSupport = false; fBaseInstanceSupport = false; fCanDrawIndirectToFloat = false; - fUseNonVBOVertexAndIndexDynamicData = false; fIsCoreProfile = false; fBindFragDataLocationSupport = false; fRectangleTextureSupport = false; @@ -132,18 +131,6 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, fImagingSupport = kGL_GrGLStandard == standard && ctxInfo.hasExtension("GL_ARB_imaging"); - // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with - // frequently changing VBOs. We've measured a performance increase using non-VBO vertex - // data for dynamic content on these GPUs. Perhaps we should read the renderer string and - // limit this decision to specific GPU families rather than basing it on the vendor alone. - if (!GR_GL_MUST_USE_VBO && - !fIsCoreProfile && - (kARM_GrGLVendor == ctxInfo.vendor() || - kImagination_GrGLVendor == ctxInfo.vendor() || - kQualcomm_GrGLVendor == ctxInfo.vendor())) { - fUseNonVBOVertexAndIndexDynamicData = true; - } - // A driver but on the nexus 6 causes incorrect dst copies when invalidate is called beforehand. // Thus we are blacklisting this extension for now on Adreno4xx devices. if (kAdreno4xx_GrGLRenderer != ctxInfo.renderer() && @@ -344,6 +331,18 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, } } + // SGX and Mali GPUs that are based on a tiled-deferred architecture that have trouble with + // frequently changing VBOs. We've measured a performance increase using non-VBO vertex + // data for dynamic content on these GPUs. Perhaps we should read the renderer string and + // limit this decision to specific GPU families rather than basing it on the vendor alone. + if (!GR_GL_MUST_USE_VBO && + !fIsCoreProfile && + (kARM_GrGLVendor == ctxInfo.vendor() || + kImagination_GrGLVendor == ctxInfo.vendor() || + kQualcomm_GrGLVendor == ctxInfo.vendor())) { + fPreferClientSideDynamicBuffers = true; + } + // fUsesMixedSamples must be set before calling initFSAASupport. this->initFSAASupport(ctxInfo, gli); this->initBlendEqationSupport(ctxInfo); @@ -1122,8 +1121,6 @@ SkString GrGLCaps::dump() const { r.appendf("Multi draw indirect support: %s\n", (fMultiDrawIndirectSupport ? "YES" : "NO")); r.appendf("Base instance support: %s\n", (fBaseInstanceSupport ? "YES" : "NO")); r.appendf("Can draw indirect to float: %s\n", (fCanDrawIndirectToFloat ? "YES" : "NO")); - r.appendf("Use non-VBO for dynamic data: %s\n", - (fUseNonVBOVertexAndIndexDynamicData ? "YES" : "NO")); r.appendf("RGBA 8888 pixel ops are slow: %s\n", (fRGBA8888PixelsOpsAreSlow ? "YES" : "NO")); r.appendf("Partial FBO read is slow: %s\n", (fPartialFBOReadIsSlow ? "YES" : "NO")); r.appendf("Bind uniform location support: %s\n", (fBindUniformLocationSupport ? "YES" : "NO")); diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 9972690487..885e182c55 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -2053,9 +2053,7 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, const GrNonInstancedMesh& mesh, size_t* indexOffsetInBytes) { - const GrGLBuffer* vbuf; - vbuf = static_cast<const GrGLBuffer*>(mesh.vertexBuffer()); - + const GrBuffer* vbuf = mesh.vertexBuffer(); SkASSERT(vbuf); SkASSERT(!vbuf->isMapped()); @@ -2064,8 +2062,7 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, SkASSERT(indexOffsetInBytes); *indexOffsetInBytes = 0; - const GrGLBuffer* ibuf = static_cast<const GrGLBuffer*>(mesh.indexBuffer()); - + const GrBuffer* ibuf = mesh.indexBuffer(); SkASSERT(ibuf); SkASSERT(!ibuf->isMapped()); *indexOffsetInBytes += ibuf->baseOffset(); @@ -2102,7 +2099,7 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, } } -GrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrGLBuffer* buffer) { +GrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrBuffer* buffer) { this->handleDirtyContext(); // Index buffer state is tied to the vertex array. @@ -2114,10 +2111,15 @@ GrGLenum GrGLGpu::bindBuffer(GrBufferType type, const GrGLBuffer* buffer) { auto& bufferState = fHWBufferState[type]; if (buffer->getUniqueID() != bufferState.fBoundBufferUniqueID) { - if (!buffer->isCPUBacked() || !bufferState.fBufferZeroKnownBound) { - GL_CALL(BindBuffer(bufferState.fGLTarget, buffer->bufferID())); - bufferState.fBufferZeroKnownBound = buffer->isCPUBacked(); + if (buffer->isCPUBacked()) { + if (!bufferState.fBufferZeroKnownBound) { + GL_CALL(BindBuffer(bufferState.fGLTarget, 0)); + } + } else { + const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(buffer); + GL_CALL(BindBuffer(bufferState.fGLTarget, glBuffer->bufferID())); } + bufferState.fBufferZeroKnownBound = buffer->isCPUBacked(); bufferState.fBoundBufferUniqueID = buffer->getUniqueID(); } @@ -4568,7 +4570,7 @@ void GrGLGpu::resetShaderCacheForTesting() const { /////////////////////////////////////////////////////////////////////////////// GrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLGpu* gpu, - const GrGLBuffer* ibuf) { + const GrBuffer* ibuf) { GrGLAttribArrayState* attribState; if (gpu->glCaps().isCoreProfile()) { diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h index 5cc0facea6..02a9c1d54b 100644 --- a/src/gpu/gl/GrGLGpu.h +++ b/src/gpu/gl/GrGLGpu.h @@ -92,7 +92,7 @@ public: // returns the GL target the buffer was bound to. // When 'type' is kIndex_GrBufferType, this function will also implicitly bind the default VAO. // If the caller wishes to bind an index buffer to a specific VAO, it can call glBind directly. - GrGLenum bindBuffer(GrBufferType type, const GrGLBuffer*); + GrGLenum bindBuffer(GrBufferType type, const GrBuffer*); // Called by GrGLBuffer after its buffer object has been destroyed. void notifyBufferReleased(const GrGLBuffer*); @@ -467,7 +467,7 @@ private: * * The returned GrGLAttribArrayState should be used to set vertex attribute arrays. */ - GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrGLBuffer* ibuff = nullptr); + GrGLAttribArrayState* bindInternalVertexArray(GrGLGpu*, const GrBuffer* ibuff = nullptr); private: GrGLuint fBoundVertexArrayID; diff --git a/src/gpu/gl/GrGLVertexArray.cpp b/src/gpu/gl/GrGLVertexArray.cpp index d131ff2186..abf6502bed 100644 --- a/src/gpu/gl/GrGLVertexArray.cpp +++ b/src/gpu/gl/GrGLVertexArray.cpp @@ -39,7 +39,7 @@ GR_STATIC_ASSERT(8 == kUint_GrVertexAttribType); void GrGLAttribArrayState::set(GrGLGpu* gpu, int index, - const GrGLBuffer* vertexBuffer, + const GrBuffer* vertexBuffer, GrVertexAttribType type, GrGLsizei stride, GrGLvoid* offset) { @@ -112,10 +112,16 @@ GrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) { return &fAttribArrays; } -GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, const GrGLBuffer* ibuff) { +GrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* ibuff) { GrGLAttribArrayState* state = this->bind(gpu); if (state && fIndexBufferUniqueID != ibuff->getUniqueID()) { - GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, ibuff->bufferID())); + if (ibuff->isCPUBacked()) { + GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0)); + } else { + const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(ibuff); + GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, + glBuffer->bufferID())); + } fIndexBufferUniqueID = ibuff->getUniqueID(); } return state; diff --git a/src/gpu/gl/GrGLVertexArray.h b/src/gpu/gl/GrGLVertexArray.h index 6b865bd621..639892690f 100644 --- a/src/gpu/gl/GrGLVertexArray.h +++ b/src/gpu/gl/GrGLVertexArray.h @@ -13,7 +13,7 @@ #include "gl/GrGLTypes.h" #include "SkTArray.h" -class GrGLBuffer; +class GrBuffer; class GrGLGpu; /** @@ -40,7 +40,7 @@ public: */ void set(GrGLGpu*, int attribIndex, - const GrGLBuffer* vertexBuffer, + const GrBuffer* vertexBuffer, GrVertexAttribType type, GrGLsizei stride, GrGLvoid* offset); @@ -103,7 +103,7 @@ public: * This is a version of the above function that also binds an index buffer to the vertex * array object. */ - GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, const GrGLBuffer* indexBuffer); + GrGLAttribArrayState* bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* indexBuffer); GrGLuint arrayID() const { return fID; } |