Split Buffer::map into map and mapRange to match the API.
BUG=angleproject:681
Change-Id: Ia4bf2b81134a922265ca762f33ac85d9ddbf1a7c
Reviewed-on: https://chromium-review.googlesource.com/261890
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Brandon Jones <bajones@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Buffer.cpp b/src/libANGLE/Buffer.cpp
index f394a6b..621d8d2 100644
--- a/src/libANGLE/Buffer.cpp
+++ b/src/libANGLE/Buffer.cpp
@@ -21,6 +21,7 @@
mUsage(GL_DYNAMIC_DRAW),
mSize(0),
mAccessFlags(0),
+ mAccess(GL_WRITE_ONLY_OES),
mMapped(GL_FALSE),
mMapPointer(NULL),
mMapOffset(0),
@@ -74,12 +75,36 @@
return error;
}
+Error Buffer::map(GLenum access)
+{
+ ASSERT(!mMapped);
+
+ Error error = mBuffer->map(access, &mMapPointer);
+ if (error.isError())
+ {
+ mMapPointer = NULL;
+ return error;
+ }
+
+ ASSERT(access == GL_WRITE_ONLY_OES);
+
+ mMapped = GL_TRUE;
+ mMapOffset = 0;
+ mMapLength = mSize;
+ mAccess = access;
+ mAccessFlags = GL_MAP_WRITE_BIT;
+
+ mIndexRangeCache.invalidateRange(0, mMapLength);
+
+ return error;
+}
+
Error Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access)
{
ASSERT(!mMapped);
ASSERT(offset + length <= mSize);
- Error error = mBuffer->map(offset, length, access, &mMapPointer);
+ Error error = mBuffer->mapRange(offset, length, access, &mMapPointer);
if (error.isError())
{
mMapPointer = NULL;
@@ -89,7 +114,13 @@
mMapped = GL_TRUE;
mMapOffset = static_cast<GLint64>(offset);
mMapLength = static_cast<GLint64>(length);
- mAccessFlags = static_cast<GLint>(access);
+ mAccess = GL_WRITE_ONLY_OES;
+ mAccessFlags = access;
+
+ // The OES_mapbuffer extension states that GL_WRITE_ONLY_OES is the only valid
+ // value for GL_BUFFER_ACCESS_OES because it was written against ES2. Since there is
+ // no update for ES3 and the GL_READ_ONLY and GL_READ_WRITE enums don't exist for ES,
+ // we cannot properly set GL_BUFFER_ACCESS_OES when glMapBufferRange is called.
if ((access & GL_MAP_WRITE_BIT) > 0)
{
@@ -99,13 +130,14 @@
return error;
}
-Error Buffer::unmap()
+Error Buffer::unmap(GLboolean *result)
{
ASSERT(mMapped);
- Error error = mBuffer->unmap();
+ Error error = mBuffer->unmap(result);
if (error.isError())
{
+ *result = GL_FALSE;
return error;
}
@@ -113,6 +145,7 @@
mMapPointer = NULL;
mMapOffset = 0;
mMapLength = 0;
+ mAccess = GL_WRITE_ONLY_OES;
mAccessFlags = 0;
return error;
diff --git a/src/libANGLE/Buffer.h b/src/libANGLE/Buffer.h
index 6793028..029aff8 100644
--- a/src/libANGLE/Buffer.h
+++ b/src/libANGLE/Buffer.h
@@ -35,11 +35,13 @@
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 map(GLenum access);
Error mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access);
- Error unmap();
+ Error unmap(GLboolean *result);
GLenum getUsage() const { return mUsage; }
- GLint getAccessFlags() const { return mAccessFlags; }
+ GLbitfield getAccessFlags() const { return mAccessFlags; }
+ GLenum getAccess() const { return mAccess; }
GLboolean isMapped() const { return mMapped; }
GLvoid *getMapPointer() const { return mMapPointer; }
GLint64 getMapOffset() const { return mMapOffset; }
@@ -56,7 +58,8 @@
GLenum mUsage;
GLint64 mSize;
- GLint mAccessFlags;
+ GLbitfield mAccessFlags;
+ GLenum mAccess;
GLboolean mMapped;
GLvoid *mMapPointer;
GLint64 mMapOffset;
diff --git a/src/libANGLE/renderer/BufferImpl.h b/src/libANGLE/renderer/BufferImpl.h
index 9bc5eaf..755e793 100644
--- a/src/libANGLE/renderer/BufferImpl.h
+++ b/src/libANGLE/renderer/BufferImpl.h
@@ -25,8 +25,9 @@
virtual gl::Error setData(const void* data, size_t size, GLenum usage) = 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 gl::Error map(GLenum access, GLvoid **mapPtr) = 0;
+ virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) = 0;
+ virtual gl::Error unmap(GLboolean *result) = 0;
// This method may not have a corresponding GL-backed function. It is necessary
// for validation, for certain indexed draw calls.
diff --git a/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
index 575ee15..72cf277 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
@@ -356,7 +356,15 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Buffer11::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
+gl::Error Buffer11::map(GLenum access, GLvoid **mapPtr)
+{
+ // GL_OES_mapbuffer uses an enum instead of a bitfield for it's access, convert to a bitfield
+ // and call mapRange.
+ ASSERT(access == GL_WRITE_ONLY_OES);
+ return mapRange(0, mSize, GL_MAP_WRITE_BIT, mapPtr);
+}
+
+gl::Error Buffer11::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
{
ASSERT(!mMappedStorage);
@@ -396,11 +404,15 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error Buffer11::unmap()
+gl::Error Buffer11::unmap(GLboolean *result)
{
ASSERT(mMappedStorage);
mMappedStorage->unmap();
mMappedStorage = NULL;
+
+ // TODO: detect if we had corruption. if so, return false.
+ *result = GL_TRUE;
+
return gl::Error(GL_NO_ERROR);
}
diff --git a/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
index 5591458..5ccabf3 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
@@ -64,8 +64,9 @@
gl::Error getData(const uint8_t **outData) override;
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 gl::Error map(GLenum access, GLvoid **mapPtr);
+ virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
+ virtual gl::Error unmap(GLboolean *result);
virtual void markTransformFeedbackUsage();
private:
diff --git a/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
index 199c404..c067aa1 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
@@ -90,13 +90,19 @@
}
// We do not support buffer mapping in D3D9
-gl::Error Buffer9::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
+gl::Error Buffer9::map(GLenum access, GLvoid **mapPtr)
{
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
}
-gl::Error Buffer9::unmap()
+gl::Error Buffer9::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
+{
+ UNREACHABLE();
+ return gl::Error(GL_INVALID_OPERATION);
+}
+
+gl::Error Buffer9::unmap(GLboolean *result)
{
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
diff --git a/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
index dc1aff6..f40b660 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
@@ -32,8 +32,9 @@
gl::Error getData(const uint8_t **outData) override;
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 gl::Error map(GLenum access, GLvoid **mapPtr);
+ virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr);
+ virtual gl::Error unmap(GLboolean *result);
virtual void markTransformFeedbackUsage();
private:
diff --git a/src/libANGLE/renderer/gl/BufferGL.cpp b/src/libANGLE/renderer/gl/BufferGL.cpp
index c63a9e7..1ce91de 100644
--- a/src/libANGLE/renderer/gl/BufferGL.cpp
+++ b/src/libANGLE/renderer/gl/BufferGL.cpp
@@ -73,20 +73,26 @@
return gl::Error(GL_NO_ERROR);
}
-gl::Error BufferGL::map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
+gl::Error BufferGL::map(GLenum access, GLvoid **mapPtr)
{
- // TODO: look into splitting this into two functions, glMapBuffer is available in 1.5, but
- // glMapBufferRange requires 3.0
+ mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
+ *mapPtr = mFunctions->mapBuffer(DestBufferOperationTarget, access);
+ return gl::Error(GL_NO_ERROR);
+}
+gl::Error BufferGL::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr)
+{
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
*mapPtr = mFunctions->mapBufferRange(DestBufferOperationTarget, offset, length, access);
return gl::Error(GL_NO_ERROR);
}
-gl::Error BufferGL::unmap()
+gl::Error BufferGL::unmap(GLboolean *result)
{
+ ASSERT(*result);
+
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
- mFunctions->unmapBuffer(DestBufferOperationTarget);
+ *result = mFunctions->unmapBuffer(DestBufferOperationTarget);
return gl::Error(GL_NO_ERROR);
}
diff --git a/src/libANGLE/renderer/gl/BufferGL.h b/src/libANGLE/renderer/gl/BufferGL.h
index 398c748..2fe7525 100644
--- a/src/libANGLE/renderer/gl/BufferGL.h
+++ b/src/libANGLE/renderer/gl/BufferGL.h
@@ -26,8 +26,9 @@
gl::Error setData(const void* data, size_t size, GLenum usage) override;
gl::Error setSubData(const void* data, size_t size, size_t offset) override;
gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) override;
- gl::Error map(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override;
- gl::Error unmap() override;
+ gl::Error map(GLenum access, GLvoid **mapPtr) override;
+ gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) override;
+ gl::Error unmap(GLboolean *result) override;
// This method may not have a corresponding GL-backed function. It is necessary
// for validation, for certain indexed draw calls.
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 2e2ca84..7dea88e 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -129,19 +129,27 @@
bool ValidBufferParameter(const Context *context, GLenum pname)
{
+ const Extensions &extensions = context->getExtensions();
+
switch (pname)
{
case GL_BUFFER_USAGE:
case GL_BUFFER_SIZE:
return true;
+ case GL_BUFFER_ACCESS_OES:
+ return extensions.mapBuffer;
+
+ case GL_BUFFER_MAPPED:
+ static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
+ return (context->getClientVersion() >= 3) || extensions.mapBuffer || extensions.mapBufferRange;
+
// GL_BUFFER_MAP_POINTER is a special case, and may only be
// queried with GetBufferPointerv
case GL_BUFFER_ACCESS_FLAGS:
- case GL_BUFFER_MAPPED:
case GL_BUFFER_MAP_OFFSET:
case GL_BUFFER_MAP_LENGTH:
- return (context->getClientVersion() >= 3);
+ return (context->getClientVersion() >= 3) || extensions.mapBufferRange;
default:
return false;
diff --git a/src/libGLESv2/entry_points_gles_2_0.cpp b/src/libGLESv2/entry_points_gles_2_0.cpp
index 6d3089b..8c45d55 100644
--- a/src/libGLESv2/entry_points_gles_2_0.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0.cpp
@@ -1784,7 +1784,11 @@
case GL_BUFFER_ACCESS_FLAGS:
*params = buffer->getAccessFlags();
break;
+ case GL_BUFFER_ACCESS_OES:
+ *params = buffer->getAccess();
+ break;
case GL_BUFFER_MAPPED:
+ static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
*params = static_cast<GLint>(buffer->isMapped());
break;
case GL_BUFFER_MAP_OFFSET:
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
index 8be6ae7..6f85b2f 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -863,7 +863,7 @@
return NULL;
}
- Error error = buffer->mapRange(0, buffer->getSize(), GL_MAP_WRITE_BIT);
+ Error error = buffer->map(access);
if (error.isError())
{
context->recordError(error);
@@ -897,16 +897,15 @@
return GL_FALSE;
}
- // TODO: detect if we had corruption. if so, throw an error and return false.
-
- Error error = buffer->unmap();
+ GLboolean result;
+ Error error = buffer->unmap(&result);
if (error.isError())
{
context->recordError(error);
return GL_FALSE;
}
- return GL_TRUE;
+ return result;
}
return GL_FALSE;