aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar jvanverth <jvanverth@google.com>2015-12-03 09:15:47 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-12-03 09:15:47 -0800
commit73063dc517f424ad5660db0fbc5fe6fcc13f77f7 (patch)
tree96360627441f666f6632336afdbb5bd6c90fbf4d
parentc2e0ac4fce5bfe5bac9f2cb1ebd3aea3a8900fb1 (diff)
Add transfer buffer support.
-rw-r--r--gyp/gpu.gypi3
-rw-r--r--src/gpu/GrGpu.cpp7
-rw-r--r--src/gpu/GrGpu.h18
-rw-r--r--src/gpu/GrTest.cpp2
-rwxr-xr-xsrc/gpu/GrTransferBuffer.h76
-rw-r--r--src/gpu/gl/GrGLBufferImpl.cpp8
-rw-r--r--src/gpu/gl/GrGLBufferImpl.h12
-rw-r--r--src/gpu/gl/GrGLDefines.h3
-rw-r--r--src/gpu/gl/GrGLGpu.cpp91
-rw-r--r--src/gpu/gl/GrGLGpu.h6
-rw-r--r--src/gpu/gl/GrGLIndexBuffer.cpp3
-rwxr-xr-xsrc/gpu/gl/GrGLTransferBuffer.cpp51
-rwxr-xr-xsrc/gpu/gl/GrGLTransferBuffer.h47
-rw-r--r--src/gpu/gl/GrGLVertexBuffer.cpp3
-rw-r--r--src/gpu/gl/SkNullGLContext.cpp46
15 files changed, 341 insertions, 35 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 91a9fa98da..cd6600af85 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -188,6 +188,7 @@
'<(skia_src_path)/gpu/GrTextureProvider.cpp',
'<(skia_src_path)/gpu/GrTexturePriv.h',
'<(skia_src_path)/gpu/GrTextureAccess.cpp',
+ '<(skia_src_path)/gpu/GrTransferBuffer.h',
'<(skia_src_path)/gpu/GrTRecorder.h',
'<(skia_src_path)/gpu/GrVertexBuffer.h',
'<(skia_src_path)/gpu/GrVertices.h',
@@ -335,6 +336,8 @@
'<(skia_src_path)/gpu/gl/GrGLTexture.h',
'<(skia_src_path)/gpu/gl/GrGLTextureRenderTarget.cpp',
'<(skia_src_path)/gpu/gl/GrGLTextureRenderTarget.h',
+ '<(skia_src_path)/gpu/gl/GrGLTransferBuffer.cpp',
+ '<(skia_src_path)/gpu/gl/GrGLTransferBuffer.h',
'<(skia_src_path)/gpu/gl/GrGLUtil.cpp',
'<(skia_src_path)/gpu/gl/GrGLUtil.h',
'<(skia_src_path)/gpu/gl/GrGLVaryingHandler.cpp',
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 439fe1b70f..a9b283f3ce 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -20,6 +20,7 @@
#include "GrRenderTargetPriv.h"
#include "GrStencilAttachment.h"
#include "GrSurfacePriv.h"
+#include "GrTransferBuffer.h"
#include "GrVertexBuffer.h"
#include "GrVertices.h"
@@ -197,6 +198,12 @@ GrIndexBuffer* GrGpu::createIndexBuffer(size_t size, bool dynamic) {
return ib;
}
+GrTransferBuffer* GrGpu::createTransferBuffer(size_t size, TransferType type) {
+ this->handleDirtyContext();
+ GrTransferBuffer* tb = this->onCreateTransferBuffer(size, type);
+ return tb;
+}
+
void GrGpu::clear(const SkIRect& rect,
GrColor color,
GrRenderTarget* renderTarget) {
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index aeaa595f8b..9c36d0555f 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -31,6 +31,7 @@ class GrRenderTarget;
class GrStencilAttachment;
class GrSurface;
class GrTexture;
+class GrTransferBuffer;
class GrVertexBuffer;
class GrVertices;
@@ -128,6 +129,22 @@ public:
*/
GrIndexBuffer* createIndexBuffer(size_t size, bool dynamic);
+ enum TransferType {
+ kCpuToGpu_TransferType,
+ kGpuToCpu_TransferType
+ };
+
+ /**
+ * Creates a transfer buffer.
+ *
+ * @param size size in bytes of the index buffer
+ * @param toGpu true if used to transfer from the cpu to the gpu
+ * otherwise to be used to transfer from the gpu to the cpu
+ *
+ * @return The transfer buffer if successful, otherwise nullptr.
+ */
+ GrTransferBuffer* createTransferBuffer(size_t size, TransferType type);
+
/**
* Resolves MSAA.
*/
@@ -455,6 +472,7 @@ private:
GrWrapOwnership) = 0;
virtual GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) = 0;
virtual GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) = 0;
+ virtual GrTransferBuffer* onCreateTransferBuffer(size_t size, TransferType type) = 0;
// overridden by backend-specific derived class to perform the clear.
virtual void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) = 0;
diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp
index b1c135474d..a3823dd8a2 100644
--- a/src/gpu/GrTest.cpp
+++ b/src/gpu/GrTest.cpp
@@ -311,6 +311,8 @@ private:
GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override { return nullptr; }
+ GrTransferBuffer* onCreateTransferBuffer(size_t, TransferType) override { return nullptr; }
+
void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override {}
void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override {}
diff --git a/src/gpu/GrTransferBuffer.h b/src/gpu/GrTransferBuffer.h
new file mode 100755
index 0000000000..bd80666fd6
--- /dev/null
+++ b/src/gpu/GrTransferBuffer.h
@@ -0,0 +1,76 @@
+
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef GrTransferBuffer_DEFINED
+#define GrTransferBuffer_DEFINED
+
+#include "GrGpuResource.h"
+
+class GrTransferBuffer : public GrGpuResource {
+public:
+ /**
+ * Maps the buffer to be written by the CPU.
+ *
+ * The previous content of the buffer is invalidated. It is an error
+ * to transfer to or from the buffer while it is mapped. It is an error to
+ * call map on an already mapped buffer. Must be matched by an unmap() call.
+ * Currently only one map at a time is supported (no nesting of map/unmap).
+ *
+ * Note that buffer mapping does not go through GrContext and therefore is
+ * not serialized with other operations.
+ *
+ * @return a pointer to the data or nullptr if the map fails.
+ */
+ void* map() { return (fMapPtr = this->onMap()); }
+
+ /**
+ * Unmaps the buffer.
+ *
+ * The pointer returned by the previous map call will no longer be valid.
+ */
+ void unmap() {
+ SkASSERT(fMapPtr);
+ this->onUnmap();
+ fMapPtr = nullptr;
+ }
+
+ /**
+ * Returns the same ptr that map() returned at time of map or nullptr if the
+ * is not mapped.
+ *
+ * @return ptr to mapped buffer data or nullptr if buffer is not mapped.
+ */
+ void* mapPtr() const { return fMapPtr; }
+
+ /**
+ Queries whether the buffer has been mapped.
+
+ @return true if the buffer is mapped, false otherwise.
+ */
+ bool isMapped() const { return SkToBool(fMapPtr); }
+
+protected:
+ GrTransferBuffer(GrGpu* gpu, size_t gpuMemorySize)
+ : INHERITED(gpu, kUncached_LifeCycle)
+ , fGpuMemorySize(gpuMemorySize) {
+ }
+
+private:
+ virtual size_t onGpuMemorySize() const { return fGpuMemorySize; }
+
+ virtual void* onMap() = 0;
+ virtual void onUnmap() = 0;
+
+ void* fMapPtr;
+ size_t fGpuMemorySize;
+
+ typedef GrGpuResource INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLBufferImpl.cpp b/src/gpu/gl/GrGLBufferImpl.cpp
index 6cbf4e0d0e..07fc7a1584 100644
--- a/src/gpu/gl/GrGLBufferImpl.cpp
+++ b/src/gpu/gl/GrGLBufferImpl.cpp
@@ -65,7 +65,7 @@ void* GrGLBufferImpl::map(GrGLGpu* gpu) {
if (0 == fDesc.fID) {
fMapPtr = fCPUData;
} else {
- fMapPtr = gpu->mapBuffer(fDesc.fID, fBufferType, fDesc.fDynamic, fGLSizeInBytes,
+ fMapPtr = gpu->mapBuffer(fDesc.fID, fBufferType, fDesc.fUsage, fGLSizeInBytes,
fDesc.fSizeInBytes);
fGLSizeInBytes = fDesc.fSizeInBytes;
}
@@ -89,6 +89,7 @@ bool GrGLBufferImpl::isMapped() const {
bool GrGLBufferImpl::updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInBytes) {
SkASSERT(!this->isMapped());
+ SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType);
VALIDATE();
if (srcSizeInBytes > fDesc.fSizeInBytes) {
return false;
@@ -97,7 +98,7 @@ bool GrGLBufferImpl::updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInB
memcpy(fCPUData, src, srcSizeInBytes);
return true;
}
- gpu->bufferData(fDesc.fID, fBufferType, fDesc.fDynamic, fDesc.fSizeInBytes, src,
+ gpu->bufferData(fDesc.fID, fBufferType, fDesc.fUsage, fDesc.fSizeInBytes, src,
srcSizeInBytes);
#if GR_GL_USE_BUFFER_DATA_NULL_HINT
fGLSizeInBytes = fDesc.fSizeInBytes;
@@ -109,7 +110,8 @@ bool GrGLBufferImpl::updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInB
}
void GrGLBufferImpl::validate() const {
- SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType);
+ SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType ||
+ GR_GL_PIXEL_PACK_BUFFER == fBufferType || GR_GL_PIXEL_UNPACK_BUFFER == fBufferType);
// The following assert isn't valid when the buffer has been abandoned:
// SkASSERT((0 == fDesc.fID) == (fCPUData));
SkASSERT(nullptr == fCPUData || 0 == fGLSizeInBytes);
diff --git a/src/gpu/gl/GrGLBufferImpl.h b/src/gpu/gl/GrGLBufferImpl.h
index 15d2f48efe..ef7ce95541 100644
--- a/src/gpu/gl/GrGLBufferImpl.h
+++ b/src/gpu/gl/GrGLBufferImpl.h
@@ -19,10 +19,20 @@ class GrGLGpu;
*/
class GrGLBufferImpl : SkNoncopyable {
public:
+ enum Usage {
+ kStaticDraw_Usage = 0,
+ kDynamicDraw_Usage,
+ kStreamDraw_Usage,
+ kStreamRead_Usage,
+
+ kLast_Usage = kStreamRead_Usage
+ };
+ static const int kUsageCount = kLast_Usage + 1;
+
struct Desc {
GrGLuint fID; // set to 0 to indicate buffer is CPU-backed and not a VBO.
size_t fSizeInBytes;
- bool fDynamic;
+ Usage fUsage;
};
GrGLBufferImpl(GrGLGpu*, const Desc&, GrGLenum bufferType);
diff --git a/src/gpu/gl/GrGLDefines.h b/src/gpu/gl/GrGLDefines.h
index dfab5e7e13..4570f4c94b 100644
--- a/src/gpu/gl/GrGLDefines.h
+++ b/src/gpu/gl/GrGLDefines.h
@@ -110,8 +110,11 @@
#define GR_GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GR_GL_ARRAY_BUFFER_BINDING 0x8894
#define GR_GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GR_GL_PIXEL_PACK_BUFFER 0x88EB
+#define GR_GL_PIXEL_UNPACK_BUFFER 0x88EC
#define GR_GL_STREAM_DRAW 0x88E0
+#define GR_GL_STREAM_READ 0x88E1
#define GR_GL_STATIC_DRAW 0x88E4
#define GR_GL_DYNAMIC_DRAW 0x88E8
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index a136496ef5..918bee8f89 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1399,12 +1399,16 @@ GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRen
////////////////////////////////////////////////////////////////////////////////
+// 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_USAGE_PARAM GR_GL_STREAM_DRAW
+
GrVertexBuffer* GrGLGpu::onCreateVertexBuffer(size_t size, bool dynamic) {
GrGLVertexBuffer::Desc desc;
- desc.fDynamic = dynamic;
+ desc.fUsage = dynamic ? GrGLBufferImpl::kDynamicDraw_Usage : GrGLBufferImpl::kStaticDraw_Usage;
desc.fSizeInBytes = size;
- if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) {
+ if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && dynamic) {
desc.fID = 0;
GrGLVertexBuffer* vertexBuffer = new GrGLVertexBuffer(this, desc);
return vertexBuffer;
@@ -1418,7 +1422,7 @@ GrVertexBuffer* GrGLGpu::onCreateVertexBuffer(size_t size, bool dynamic) {
BufferData(GR_GL_ARRAY_BUFFER,
(GrGLsizeiptr) desc.fSizeInBytes,
nullptr, // data ptr
- desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
+ 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);
@@ -1433,10 +1437,10 @@ GrVertexBuffer* GrGLGpu::onCreateVertexBuffer(size_t size, bool dynamic) {
GrIndexBuffer* GrGLGpu::onCreateIndexBuffer(size_t size, bool dynamic) {
GrGLIndexBuffer::Desc desc;
- desc.fDynamic = dynamic;
+ desc.fUsage = dynamic ? GrGLBufferImpl::kDynamicDraw_Usage : GrGLBufferImpl::kStaticDraw_Usage;
desc.fSizeInBytes = size;
- if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && desc.fDynamic) {
+ if (this->glCaps().useNonVBOVertexAndIndexDynamicData() && dynamic) {
desc.fID = 0;
GrIndexBuffer* indexBuffer = new GrGLIndexBuffer(this, desc);
return indexBuffer;
@@ -1450,7 +1454,7 @@ GrIndexBuffer* GrGLGpu::onCreateIndexBuffer(size_t size, bool dynamic) {
BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
(GrGLsizeiptr) desc.fSizeInBytes,
nullptr, // data ptr
- desc.fDynamic ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
+ 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);
@@ -1463,6 +1467,35 @@ GrIndexBuffer* GrGLGpu::onCreateIndexBuffer(size_t size, bool dynamic) {
}
}
+GrTransferBuffer* GrGLGpu::onCreateTransferBuffer(size_t size, TransferType type) {
+ GrGLTransferBuffer::Desc desc;
+ bool toGpu = (kCpuToGpu_TransferType == type);
+ desc.fUsage = toGpu ? GrGLBufferImpl::kStreamDraw_Usage : GrGLBufferImpl::kStreamRead_Usage;
+
+ desc.fSizeInBytes = size;
+
+ // TODO: check caps to see if we can create a PBO, and which kind
+ GL_CALL(GenBuffers(1, &desc.fID));
+ if (desc.fID) {
+ CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
+ // make sure driver can allocate memory for this buffer
+ GrGLenum type = toGpu ? GR_GL_PIXEL_UNPACK_BUFFER : GR_GL_PIXEL_PACK_BUFFER;
+ GL_ALLOC_CALL(this->glInterface(),
+ BufferData(type,
+ (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, type);
+ return transferBuffer;
+ }
+
+ return nullptr;
+}
+
void GrGLGpu::flushScissor(const GrScissorState& scissorState,
const GrGLIRect& rtViewport,
GrSurfaceOrigin rtOrigin) {
@@ -1603,8 +1636,7 @@ void GrGLGpu::bindBuffer(GrGLuint id, GrGLenum type) {
this->handleDirtyContext();
if (GR_GL_ARRAY_BUFFER == type) {
this->bindVertexBuffer(id);
- } else {
- SkASSERT(GR_GL_ELEMENT_ARRAY_BUFFER == type);
+ } else if (GR_GL_ELEMENT_ARRAY_BUFFER == type) {
this->bindIndexBufferAndDefaultVertexArray(id);
}
}
@@ -1614,19 +1646,27 @@ void GrGLGpu::releaseBuffer(GrGLuint id, GrGLenum type) {
GL_CALL(DeleteBuffers(1, &id));
if (GR_GL_ARRAY_BUFFER == type) {
this->notifyVertexBufferDelete(id);
- } else {
- SkASSERT(GR_GL_ELEMENT_ARRAY_BUFFER == type);
+ } else if (GR_GL_ELEMENT_ARRAY_BUFFER == type) {
this->notifyIndexBufferDelete(id);
}
}
-// 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_USAGE_PARAM GR_GL_STREAM_DRAW
+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, bool dynamic, size_t currentSize,
- size_t requestedSize) {
+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);
// Handling dirty context is done in the bindBuffer call
switch (this->glCaps().mapBufferType()) {
case GrGLCaps::kNone_MapBufferType:
@@ -1635,8 +1675,7 @@ void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, bool dynamic, size_t curren
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,
- dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW));
+ GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
}
GL_CALL_RET(mapPtr, MapBuffer(type, GR_GL_WRITE_ONLY));
break;
@@ -1644,8 +1683,7 @@ void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, bool dynamic, size_t curren
this->bindBuffer(id, type);
// Make sure the GL buffer size agrees with fDesc before mapping.
if (currentSize != requestedSize) {
- GL_CALL(BufferData(type, requestedSize, nullptr,
- dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW));
+ GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
}
static const GrGLbitfield kAccess = GR_GL_MAP_INVALIDATE_BUFFER_BIT |
GR_GL_MAP_WRITE_BIT;
@@ -1656,8 +1694,7 @@ void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, bool dynamic, size_t curren
this->bindBuffer(id, type);
// Make sure the GL buffer size agrees with fDesc before mapping.
if (currentSize != requestedSize) {
- GL_CALL(BufferData(type, requestedSize, nullptr,
- dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW));
+ GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
}
GL_CALL_RET(mapPtr, MapBufferSubData(type, 0, requestedSize, GR_GL_WRITE_ONLY));
break;
@@ -1665,16 +1702,16 @@ void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, bool dynamic, size_t curren
return mapPtr;
}
-void GrGLGpu::bufferData(GrGLuint id, GrGLenum type, bool dynamic, size_t currentSize,
- const void* src, size_t srcSizeInBytes) {
+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 usage = dynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW;
+ GrGLenum glUsage = get_gl_usage(usage);
#if GR_GL_USE_BUFFER_DATA_NULL_HINT
if (currentSize == srcSizeInBytes) {
- GL_CALL(BufferData(type, (GrGLsizeiptr) srcSizeInBytes, src, usage));
+ 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
@@ -1683,14 +1720,14 @@ void GrGLGpu::bufferData(GrGLuint id, GrGLenum type, bool dynamic, size_t curren
// 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, usage));
+ 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, usage));
+ GL_CALL(BufferData(type, srcSizeInBytes, src, glUsage));
#endif
}
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 2d05396f87..6ec3881b89 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -16,6 +16,7 @@
#include "GrGLRenderTarget.h"
#include "GrGLStencilAttachment.h"
#include "GrGLTexture.h"
+#include "GrGLTransferBuffer.h"
#include "GrGLVertexArray.h"
#include "GrGLVertexBuffer.h"
#include "GrGpu.h"
@@ -101,12 +102,12 @@ public:
void releaseBuffer(GrGLuint id, GrGLenum type);
// sizes are in bytes
- void* mapBuffer(GrGLuint id, GrGLenum type, bool dynamic, size_t currentSize,
+ void* mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage, size_t currentSize,
size_t requestedSize);
void unmapBuffer(GrGLuint id, GrGLenum type, void* mapPtr);
- void bufferData(GrGLuint id, GrGLenum type, bool dynamic, size_t currentSize,
+ void bufferData(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage, size_t currentSize,
const void* src, size_t srcSizeInBytes);
const GrGLContext* glContextForTesting() const override {
@@ -145,6 +146,7 @@ private:
const void* srcData) override;
GrVertexBuffer* onCreateVertexBuffer(size_t size, bool dynamic) override;
GrIndexBuffer* onCreateIndexBuffer(size_t size, bool dynamic) override;
+ GrTransferBuffer* onCreateTransferBuffer(size_t size, TransferType type) override;
GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;
GrRenderTarget* onWrapBackendRenderTarget(const GrBackendRenderTargetDesc&,
GrWrapOwnership) override;
diff --git a/src/gpu/gl/GrGLIndexBuffer.cpp b/src/gpu/gl/GrGLIndexBuffer.cpp
index 230d9a4693..5a794ad824 100644
--- a/src/gpu/gl/GrGLIndexBuffer.cpp
+++ b/src/gpu/gl/GrGLIndexBuffer.cpp
@@ -10,7 +10,8 @@
#include "SkTraceMemoryDump.h"
GrGLIndexBuffer::GrGLIndexBuffer(GrGLGpu* gpu, const Desc& desc)
- : INHERITED(gpu, desc.fSizeInBytes, desc.fDynamic, 0 == desc.fID)
+ : INHERITED(gpu, desc.fSizeInBytes, GrGLBufferImpl::kDynamicDraw_Usage == desc.fUsage,
+ 0 == desc.fID)
, fImpl(gpu, desc, GR_GL_ELEMENT_ARRAY_BUFFER) {
this->registerWithCache();
}
diff --git a/src/gpu/gl/GrGLTransferBuffer.cpp b/src/gpu/gl/GrGLTransferBuffer.cpp
new file mode 100755
index 0000000000..b7ee766d92
--- /dev/null
+++ b/src/gpu/gl/GrGLTransferBuffer.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLTransferBuffer.h"
+#include "GrGLGpu.h"
+#include "SkTraceMemoryDump.h"
+
+GrGLTransferBuffer::GrGLTransferBuffer(GrGLGpu* gpu, const Desc& desc, GrGLenum type)
+ : INHERITED(gpu, desc.fSizeInBytes)
+ , fImpl(gpu, desc, type) {
+ this->registerWithCache();
+}
+
+void GrGLTransferBuffer::onRelease() {
+ if (!this->wasDestroyed()) {
+ fImpl.release(this->getGpuGL());
+ }
+
+ INHERITED::onRelease();
+}
+
+void GrGLTransferBuffer::onAbandon() {
+ fImpl.abandon();
+ INHERITED::onAbandon();
+}
+
+void* GrGLTransferBuffer::onMap() {
+ if (!this->wasDestroyed()) {
+ return fImpl.map(this->getGpuGL());
+ } else {
+ return nullptr;
+ }
+}
+
+void GrGLTransferBuffer::onUnmap() {
+ if (!this->wasDestroyed()) {
+ fImpl.unmap(this->getGpuGL());
+ }
+}
+
+void GrGLTransferBuffer::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());
+}
diff --git a/src/gpu/gl/GrGLTransferBuffer.h b/src/gpu/gl/GrGLTransferBuffer.h
new file mode 100755
index 0000000000..ff9caeea74
--- /dev/null
+++ b/src/gpu/gl/GrGLTransferBuffer.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLTransferBuffer_DEFINED
+#define GrGLTransferBuffer_DEFINED
+
+#include "GrTransferBuffer.h"
+#include "GrGLBufferImpl.h"
+#include "gl/GrGLInterface.h"
+
+class GrGLGpu;
+
+class GrGLTransferBuffer : public GrTransferBuffer {
+
+public:
+ typedef GrGLBufferImpl::Desc Desc;
+
+ GrGLTransferBuffer(GrGLGpu* gpu, const Desc& desc, GrGLenum type);
+
+ GrGLuint bufferID() const { return fImpl.bufferID(); }
+ size_t baseOffset() const { return fImpl.baseOffset(); }
+
+protected:
+ void onAbandon() override;
+ void onRelease() override;
+ void setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
+ const SkString& dumpName) const override;
+
+private:
+ void* onMap() override;
+ void onUnmap() override;
+
+ GrGLGpu* getGpuGL() const {
+ SkASSERT(!this->wasDestroyed());
+ return (GrGLGpu*)(this->getGpu());
+ }
+
+ GrGLBufferImpl fImpl;
+
+ typedef GrTransferBuffer INHERITED;
+};
+
+#endif
diff --git a/src/gpu/gl/GrGLVertexBuffer.cpp b/src/gpu/gl/GrGLVertexBuffer.cpp
index 1f8951654f..2294844fc4 100644
--- a/src/gpu/gl/GrGLVertexBuffer.cpp
+++ b/src/gpu/gl/GrGLVertexBuffer.cpp
@@ -10,7 +10,8 @@
#include "SkTraceMemoryDump.h"
GrGLVertexBuffer::GrGLVertexBuffer(GrGLGpu* gpu, const Desc& desc)
- : INHERITED(gpu, desc.fSizeInBytes, desc.fDynamic, 0 == desc.fID)
+ : INHERITED(gpu, desc.fSizeInBytes, GrGLBufferImpl::kDynamicDraw_Usage == desc.fUsage,
+ 0 == desc.fID)
, fImpl(gpu, desc, GR_GL_ARRAY_BUFFER) {
this->registerWithCache();
}
diff --git a/src/gpu/gl/SkNullGLContext.cpp b/src/gpu/gl/SkNullGLContext.cpp
index e2a80ce2b3..e7270c32c4 100644
--- a/src/gpu/gl/SkNullGLContext.cpp
+++ b/src/gpu/gl/SkNullGLContext.cpp
@@ -122,6 +122,8 @@ public:
BufferManager fBufferManager;
GrGLuint fCurrArrayBuffer;
GrGLuint fCurrElementArrayBuffer;
+ GrGLuint fCurrPixelPackBuffer;
+ GrGLuint fCurrPixelUnpackBuffer;
GrGLuint fCurrProgramID;
GrGLuint fCurrShaderID;
@@ -129,6 +131,8 @@ public:
ContextState()
: fCurrArrayBuffer(0)
, fCurrElementArrayBuffer(0)
+ , fCurrPixelPackBuffer(0)
+ , fCurrPixelUnpackBuffer(0)
, fCurrProgramID(0)
, fCurrShaderID(0) {}
@@ -172,6 +176,12 @@ GrGLvoid GR_GL_FUNCTION_TYPE nullGLBufferData(GrGLenum target,
case GR_GL_ELEMENT_ARRAY_BUFFER:
id = state->fCurrElementArrayBuffer;
break;
+ case GR_GL_PIXEL_PACK_BUFFER:
+ id = state->fCurrPixelPackBuffer;
+ break;
+ case GR_GL_PIXEL_UNPACK_BUFFER:
+ id = state->fCurrPixelUnpackBuffer;
+ break;
default:
SkFAIL("Unexpected target to nullGLBufferData");
break;
@@ -215,6 +225,12 @@ GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindBuffer(GrGLenum target, GrGLuint buffer)
case GR_GL_ELEMENT_ARRAY_BUFFER:
state->fCurrElementArrayBuffer = buffer;
break;
+ case GR_GL_PIXEL_PACK_BUFFER:
+ state->fCurrPixelPackBuffer = buffer;
+ break;
+ case GR_GL_PIXEL_UNPACK_BUFFER:
+ state->fCurrPixelUnpackBuffer = buffer;
+ break;
}
}
@@ -228,6 +244,12 @@ GrGLvoid GR_GL_FUNCTION_TYPE nullGLDeleteBuffers(GrGLsizei n, const GrGLuint* id
if (ids[i] == state->fCurrElementArrayBuffer) {
state->fCurrElementArrayBuffer = 0;
}
+ if (ids[i] == state->fCurrPixelPackBuffer) {
+ state->fCurrPixelPackBuffer = 0;
+ }
+ if (ids[i] == state->fCurrPixelUnpackBuffer) {
+ state->fCurrPixelUnpackBuffer = 0;
+ }
BufferObj* buffer = state->fBufferManager.lookUp(ids[i]);
state->fBufferManager.free(buffer);
@@ -245,6 +267,12 @@ GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBufferRange(GrGLenum target, GrGLintptr o
case GR_GL_ELEMENT_ARRAY_BUFFER:
id = state->fCurrElementArrayBuffer;
break;
+ case GR_GL_PIXEL_PACK_BUFFER:
+ id = state->fCurrPixelPackBuffer;
+ break;
+ case GR_GL_PIXEL_UNPACK_BUFFER:
+ id = state->fCurrPixelUnpackBuffer;
+ break;
}
if (id > 0) {
@@ -267,6 +295,12 @@ GrGLvoid* GR_GL_FUNCTION_TYPE nullGLMapBuffer(GrGLenum target, GrGLenum access)
case GR_GL_ELEMENT_ARRAY_BUFFER:
id = state->fCurrElementArrayBuffer;
break;
+ case GR_GL_PIXEL_PACK_BUFFER:
+ id = state->fCurrPixelPackBuffer;
+ break;
+ case GR_GL_PIXEL_UNPACK_BUFFER:
+ id = state->fCurrPixelUnpackBuffer;
+ break;
}
if (id > 0) {
@@ -295,6 +329,12 @@ GrGLboolean GR_GL_FUNCTION_TYPE nullGLUnmapBuffer(GrGLenum target) {
case GR_GL_ELEMENT_ARRAY_BUFFER:
id = state->fCurrElementArrayBuffer;
break;
+ case GR_GL_PIXEL_PACK_BUFFER:
+ id = state->fCurrPixelPackBuffer;
+ break;
+ case GR_GL_PIXEL_UNPACK_BUFFER:
+ id = state->fCurrPixelUnpackBuffer;
+ break;
}
if (id > 0) {
BufferObj* buffer = state->fBufferManager.lookUp(id);
@@ -320,6 +360,12 @@ GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenu
case GR_GL_ELEMENT_ARRAY_BUFFER:
id = state->fCurrElementArrayBuffer;
break;
+ case GR_GL_PIXEL_PACK_BUFFER:
+ id = state->fCurrPixelPackBuffer;
+ break;
+ case GR_GL_PIXEL_UNPACK_BUFFER:
+ id = state->fCurrPixelUnpackBuffer;
+ break;
}
if (id > 0) {
BufferObj* buffer = state->fBufferManager.lookUp(id);