Commit 2a1c15a1 by Geoff Lang

Update Buffers to return Error objects instead of calling gl::error.

BUG=angle:520 Change-Id: I4b6af8e2d4fae97639518e2acd26e2d4be93c925 Reviewed-on: https://chromium-review.googlesource.com/209881Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 1d743d3d
......@@ -33,35 +33,60 @@ Buffer::~Buffer()
SafeDelete(mBuffer);
}
void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
Error Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
{
gl::Error error = mBuffer->setData(data, size, usage);
if (error.isError())
{
return error;
}
mIndexRangeCache.clear();
mUsage = usage;
mSize = size;
mBuffer->setData(data, size, usage);
return error;
}
void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
Error Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
{
gl::Error error = mBuffer->setSubData(data, size, offset);
if (error.isError())
{
return error;
}
mIndexRangeCache.invalidateRange(offset, size);
mBuffer->setSubData(data, size, offset);
return error;
}
void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
Error Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
{
gl::Error error = mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size);
if (error.isError())
{
return error;
}
mIndexRangeCache.invalidateRange(destOffset, size);
mBuffer->copySubData(source->getImplementation(), sourceOffset, destOffset, size);
return error;
}
GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
{
ASSERT(!mMapped);
ASSERT(offset + length <= mSize);
void *dataPointer = mBuffer->map(offset, length, access);
Error error = mBuffer->map(offset, length, access, &mMapPointer);
if (error.isError())
{
mMapPointer = NULL;
return error;
}
mMapped = GL_TRUE;
mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer));
mMapOffset = static_cast<GLint64>(offset);
mMapLength = static_cast<GLint64>(length);
mAccessFlags = static_cast<GLint>(access);
......@@ -71,20 +96,26 @@ GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
mIndexRangeCache.invalidateRange(offset, length);
}
return mMapPointer;
return error;
}
void Buffer::unmap()
Error Buffer::unmap()
{
ASSERT(mMapped);
mBuffer->unmap();
Error error = mBuffer->unmap();
if (error.isError())
{
return error;
}
mMapped = GL_FALSE;
mMapPointer = NULL;
mMapOffset = 0;
mMapLength = 0;
mAccessFlags = 0;
return error;
}
void Buffer::markTransformFeedbackUsage()
......
......@@ -11,6 +11,8 @@
#ifndef LIBGLESV2_BUFFER_H_
#define LIBGLESV2_BUFFER_H_
#include "libGLESv2/Error.h"
#include "common/angleutils.h"
#include "common/RefCountObject.h"
#include "libGLESv2/renderer/IndexRangeCache.h"
......@@ -31,13 +33,13 @@ class Buffer : public RefCountObject
virtual ~Buffer();
void bufferData(const void *data, GLsizeiptr size, GLenum usage);
void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
void copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
GLvoid *mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
void unmap();
Error bufferData(const void *data, GLsizeiptr size, GLenum usage);
Error bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
Error copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
Error unmap();
GLenum getUsage() const { return mUsage; }
GLenum getUsage() const { return mUsage; }
GLint getAccessFlags() const { return mAccessFlags; }
GLboolean isMapped() const { return mMapped; }
GLvoid *getMapPointer() const { return mMapPointer; }
......
......@@ -542,7 +542,12 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
return;
}
buffer->bufferData(data, size, usage);
gl::Error error = buffer->bufferData(data, size, usage);
if (error.isError())
{
context->recordError(error);
return;
}
}
}
......@@ -598,7 +603,12 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
return;
}
buffer->bufferSubData(data, size, offset);
gl::Error error = buffer->bufferSubData(data, size, offset);
if (error.isError())
{
context->recordError(error);
return;
}
}
}
......@@ -6780,7 +6790,12 @@ void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintp
// if size is zero, the copy is a successful no-op
if (size > 0)
{
writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
gl::Error error = writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size);
if (error.isError())
{
context->recordError(error);
return;
}
}
}
}
......@@ -8379,7 +8394,14 @@ void * __stdcall glMapBufferOES(GLenum target, GLenum access)
return NULL;
}
return buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
gl::Error error = buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
if (error.isError())
{
context->recordError(error);
return NULL;
}
return buffer->getMapPointer();
}
return NULL;
......@@ -8408,7 +8430,12 @@ GLboolean __stdcall glUnmapBufferOES(GLenum target)
// TODO: detect if we had corruption. if so, throw an error and return false.
buffer->unmap();
gl::Error error = buffer->unmap();
if (error.isError())
{
context->recordError(error);
return GL_FALSE;
}
return GL_TRUE;
}
......@@ -8498,7 +8525,14 @@ void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr
return NULL;
}
return buffer->mapRange(offset, length, access);
gl::Error error = buffer->mapRange(offset, length, access);
if (error.isError())
{
context->recordError(error);
return NULL;
}
return buffer->getMapPointer();
}
return NULL;
......
......@@ -20,12 +20,12 @@ class BufferImpl
public:
virtual ~BufferImpl() { }
virtual void setData(const void* data, size_t size, GLenum usage) = 0;
virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 0;
virtual void *getData() = 0;
virtual void setSubData(const void* data, size_t size, size_t offset) = 0;
virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0;
virtual GLvoid* map(size_t offset, size_t length, GLbitfield access) = 0;
virtual void unmap() = 0;
virtual gl::Error setSubData(const void* data, size_t size, size_t offset) = 0;
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) = 0;
virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0;
virtual gl::Error unmap() = 0;
virtual void markTransformFeedbackUsage() = 0;
};
......
......@@ -181,7 +181,7 @@ Buffer11 *Buffer11::makeBuffer11(BufferImpl *buffer)
return static_cast<Buffer11*>(buffer);
}
void Buffer11::setData(const void *data, size_t size, GLenum usage)
gl::Error Buffer11::setData(const void *data, size_t size, GLenum usage)
{
mDynamicUsage = (usage == GL_DYNAMIC_DRAW);
......@@ -189,16 +189,22 @@ void Buffer11::setData(const void *data, size_t size, GLenum usage)
{
if (!mDynamicData.resize(size))
{
return gl::error(GL_OUT_OF_MEMORY);
return gl::Error(GL_OUT_OF_MEMORY);
}
}
setSubData(data, size, 0);
gl::Error error = setSubData(data, size, 0);
if (error.isError())
{
return error;
}
if (usage == GL_STATIC_DRAW)
{
initializeStaticData();
}
return error;
}
void *Buffer11::getData()
......@@ -242,12 +248,9 @@ void *Buffer11::getData()
return mResolvedData.data();
}
void Buffer11::setSubData(const void *data, size_t size, size_t offset)
gl::Error Buffer11::setSubData(const void *data, size_t size, size_t offset)
{
size_t requiredSize = size + offset;
mSize = std::max(mSize, requiredSize);
invalidateStaticData();
if (data && size > 0)
{
......@@ -256,85 +259,96 @@ void Buffer11::setSubData(const void *data, size_t size, size_t offset)
mDynamicDirtyRange.start = std::min(mDynamicDirtyRange.start, offset);
mDynamicDirtyRange.end = std::max(mDynamicDirtyRange.end, size + offset);
memcpy(mDynamicData.data() + offset, data, size);
return;
}
else
{
NativeBuffer11 *stagingBuffer = getStagingBuffer();
NativeBuffer11 *stagingBuffer = getStagingBuffer();
if (!stagingBuffer)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer.");
}
if (!stagingBuffer)
{
// Out-of-memory
return;
}
// Explicitly resize the staging buffer, preserving data if the new data will not
// completely fill the buffer
if (stagingBuffer->getSize() < requiredSize)
{
bool preserveData = (offset > 0);
if (!stagingBuffer->resize(requiredSize, preserveData))
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal staging buffer.");
}
}
// Explicitly resize the staging buffer, preserving data if the new data will not
// completely fill the buffer
if (stagingBuffer->getSize() < requiredSize)
{
bool preserveData = (offset > 0);
if (!stagingBuffer->resize(requiredSize, preserveData))
if (!stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset))
{
// Out-of-memory
return;
return gl::Error(GL_OUT_OF_MEMORY, "Failed to set data on internal staging buffer.");
}
}
stagingBuffer->setData(D3D11_MAP_WRITE, reinterpret_cast<const uint8_t *>(data), size, offset);
stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1);
stagingBuffer->setDataRevision(stagingBuffer->getDataRevision() + 1);
}
}
mSize = std::max(mSize, requiredSize);
invalidateStaticData();
return gl::Error(GL_NO_ERROR);
}
void Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
gl::Error Buffer11::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
{
Buffer11 *sourceBuffer = makeBuffer11(source);
if (sourceBuffer)
ASSERT(sourceBuffer != NULL);
BufferStorage11 *copyDest = getLatestBufferStorage();
if (!copyDest)
{
BufferStorage11 *dest = getLatestBufferStorage();
if (!dest)
{
dest = getStagingBuffer();
}
copyDest = getStagingBuffer();
}
BufferStorage11 *source = sourceBuffer->getLatestBufferStorage();
if (source && dest)
{
// If copying to/from a pixel pack buffer, we must have a staging or
// pack buffer partner, because other native buffers can't be mapped
if (dest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !source->isMappable())
{
source = sourceBuffer->getStagingBuffer();
}
else if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK && !dest->isMappable())
{
dest = getStagingBuffer();
}
BufferStorage11 *copySource = sourceBuffer->getLatestBufferStorage();
// D3D11 does not allow overlapped copies until 11.1, and only if the
// device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap
// Get around this via a different source buffer
if (source == dest)
{
if (source->getUsage() == BUFFER_USAGE_STAGING)
{
source = getBufferStorage(BUFFER_USAGE_VERTEX);
}
else
{
source = getStagingBuffer();
}
}
if (!copySource || !copyDest)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal staging buffer.");
}
dest->copyFromStorage(source, sourceOffset, size, destOffset);
dest->setDataRevision(dest->getDataRevision() + 1);
}
// If copying to/from a pixel pack buffer, we must have a staging or
// pack buffer partner, because other native buffers can't be mapped
if (copyDest->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copySource->isMappable())
{
copySource = sourceBuffer->getStagingBuffer();
}
else if (copySource->getUsage() == BUFFER_USAGE_PIXEL_PACK && !copyDest->isMappable())
{
copyDest = getStagingBuffer();
}
mSize = std::max<size_t>(mSize, destOffset + size);
// D3D11 does not allow overlapped copies until 11.1, and only if the
// device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap
// Get around this via a different source buffer
if (copySource == copyDest)
{
if (copySource->getUsage() == BUFFER_USAGE_STAGING)
{
copySource = getBufferStorage(BUFFER_USAGE_VERTEX);
}
else
{
copySource = getStagingBuffer();
}
}
copyDest->copyFromStorage(copySource, sourceOffset, size, destOffset);
copyDest->setDataRevision(copyDest->getDataRevision() + 1);
mSize = std::max<size_t>(mSize, destOffset + size);
invalidateStaticData();
return gl::Error(GL_NO_ERROR);
}
GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access)
gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
{
ASSERT(!mMappedStorage);
......@@ -355,8 +369,7 @@ GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access)
if (!mMappedStorage)
{
// Out-of-memory
return NULL;
return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate mappable internal buffer.");
}
if ((access & GL_MAP_WRITE_BIT) > 0)
......@@ -365,14 +378,22 @@ GLvoid *Buffer11::map(size_t offset, size_t length, GLbitfield access)
mMappedStorage->setDataRevision(mMappedStorage->getDataRevision() + 1);
}
return mMappedStorage->map(offset, length, access);
void *mappedBuffer = mMappedStorage->map(offset, length, access);
if (!mappedBuffer)
{
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal buffer.");
}
*mapPtr = mappedBuffer;
return gl::Error(GL_NO_ERROR);
}
void Buffer11::unmap()
gl::Error Buffer11::unmap()
{
ASSERT(mMappedStorage);
mMappedStorage->unmap();
mMappedStorage = NULL;
return gl::Error(GL_NO_ERROR);
}
void Buffer11::markTransformFeedbackUsage()
......
......@@ -68,12 +68,12 @@ class Buffer11 : public BufferD3D
virtual Renderer* getRenderer();
// BufferImpl implementation
virtual void setData(const void* data, size_t size, GLenum usage);
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
virtual void *getData();
virtual void setSubData(const void* data, size_t size, size_t offset);
virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
virtual GLvoid* map(size_t offset, size_t length, GLbitfield access);
virtual void unmap();
virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
virtual gl::Error unmap();
virtual void markTransformFeedbackUsage();
private:
......
......@@ -30,13 +30,13 @@ Buffer9 *Buffer9::makeBuffer9(BufferImpl *buffer)
return static_cast<Buffer9*>(buffer);
}
void Buffer9::setData(const void* data, size_t size, GLenum usage)
gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage)
{
if (size > mMemory.size())
{
if (!mMemory.resize(size))
{
return gl::error(GL_OUT_OF_MEMORY);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer.");
}
}
......@@ -52,6 +52,8 @@ void Buffer9::setData(const void* data, size_t size, GLenum usage)
{
initializeStaticData();
}
return gl::Error(GL_NO_ERROR);
}
void *Buffer9::getData()
......@@ -59,13 +61,13 @@ void *Buffer9::getData()
return mMemory.data();
}
void Buffer9::setSubData(const void* data, size_t size, size_t offset)
gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset)
{
if (offset + size > mMemory.size())
{
if (!mMemory.resize(offset + size))
{
return gl::error(GL_OUT_OF_MEMORY);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer.");
}
}
......@@ -76,30 +78,34 @@ void Buffer9::setSubData(const void* data, size_t size, size_t offset)
}
invalidateStaticData();
return gl::Error(GL_NO_ERROR);
}
void Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size)
{
// Note: this method is currently unreachable
Buffer9* sourceBuffer = makeBuffer9(source);
if (sourceBuffer)
{
memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size);
}
ASSERT(sourceBuffer);
memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size);
invalidateStaticData();
return gl::Error(GL_NO_ERROR);
}
// We do not suppot buffer mapping in D3D9
GLvoid* Buffer9::map(size_t offset, size_t length, GLbitfield access)
// We do not support buffer mapping in D3D9
gl::Error Buffer9::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
{
UNREACHABLE();
return NULL;
return gl::Error(GL_INVALID_OPERATION);
}
void Buffer9::unmap()
gl::Error Buffer9::unmap()
{
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
}
void Buffer9::markTransformFeedbackUsage()
......
......@@ -31,12 +31,12 @@ class Buffer9 : public BufferD3D
virtual Renderer* getRenderer();
// BufferImpl implementation
virtual void setData(const void* data, size_t size, GLenum usage);
virtual gl::Error setData(const void* data, size_t size, GLenum usage);
virtual void *getData();
virtual void setSubData(const void* data, size_t size, size_t offset);
virtual void copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
virtual GLvoid* map(size_t offset, size_t length, GLbitfield access);
virtual void unmap();
virtual gl::Error setSubData(const void* data, size_t size, size_t offset);
virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size);
virtual gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
virtual gl::Error unmap();
virtual void markTransformFeedbackUsage();
private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment