Commit 6d3d381e by Geoff Lang Committed by Commit Bot

GL: Update BufferGL to use ANGLE_GL_TRY.

Refactor the check for keeping shadow data into a feature so it's only initialized once. Bug: angleproject:3020 Change-Id: I45575c246afa7cd54e3a07d7a8464f4d4f45b3be Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1769064 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 556d812a
...@@ -492,6 +492,13 @@ struct FeaturesGL : FeatureSetBase ...@@ -492,6 +492,13 @@ struct FeaturesGL : FeatureSetBase
"Speculative fix for issues on Linux/Wayland where exposing GLX_OML_sync_control renders " "Speculative fix for issues on Linux/Wayland where exposing GLX_OML_sync_control renders "
"Chrome unusable", "Chrome unusable",
&members, "https://crbug.com/1137851"}; &members, "https://crbug.com/1137851"};
// Buffers need to maintain a shadow copy of data when buffer data readback is not possible
// through the GL API
Feature keepBufferShadowCopy = {
"keep_buffer_shadow_copy", FeatureCategory::OpenGLWorkarounds,
"Maintain a shadow copy of buffer data when the GL API does not permit reading data back.",
&members};
}; };
inline FeaturesGL::FeaturesGL() = default; inline FeaturesGL::FeaturesGL() = default;
......
...@@ -31,29 +31,25 @@ static constexpr gl::BufferBinding SourceBufferOperationTarget = gl::BufferBindi ...@@ -31,29 +31,25 @@ static constexpr gl::BufferBinding SourceBufferOperationTarget = gl::BufferBindi
// supported GL versions and doesn't affect any current state when it changes. // supported GL versions and doesn't affect any current state when it changes.
static constexpr gl::BufferBinding DestBufferOperationTarget = gl::BufferBinding::Array; static constexpr gl::BufferBinding DestBufferOperationTarget = gl::BufferBinding::Array;
BufferGL::BufferGL(const gl::BufferState &state, BufferGL::BufferGL(const gl::BufferState &state, GLuint buffer)
const FunctionsGL *functions,
StateManagerGL *stateManager)
: BufferImpl(state), : BufferImpl(state),
mIsMapped(false), mIsMapped(false),
mMapOffset(0), mMapOffset(0),
mMapSize(0), mMapSize(0),
mShadowBufferData(!CanMapBufferForRead(functions)),
mShadowCopy(), mShadowCopy(),
mBufferSize(0), mBufferSize(0),
mFunctions(functions), mBufferID(buffer)
mStateManager(stateManager), {}
mBufferID(0)
{
ASSERT(mFunctions);
ASSERT(mStateManager);
mFunctions->genBuffers(1, &mBufferID); BufferGL::~BufferGL()
{
ASSERT(mBufferID == 0);
} }
BufferGL::~BufferGL() void BufferGL::destroy(const gl::Context *context)
{ {
mStateManager->deleteBuffer(mBufferID); StateManagerGL *stateManager = GetStateManagerGL(context);
stateManager->deleteBuffer(mBufferID);
mBufferID = 0; mBufferID = 0;
} }
...@@ -63,12 +59,18 @@ angle::Result BufferGL::setData(const gl::Context *context, ...@@ -63,12 +59,18 @@ angle::Result BufferGL::setData(const gl::Context *context,
size_t size, size_t size,
gl::BufferUsage usage) gl::BufferUsage usage)
{ {
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); ContextGL *contextGL = GetImplAs<ContextGL>(context);
mFunctions->bufferData(gl::ToGLenum(DestBufferOperationTarget), size, data, ToGLenum(usage)); const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);
stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
ANGLE_GL_TRY(context, functions->bufferData(gl::ToGLenum(DestBufferOperationTarget), size, data,
ToGLenum(usage)));
if (mShadowBufferData) if (features.keepBufferShadowCopy.enabled)
{ {
ANGLE_CHECK_GL_ALLOC(GetImplAs<ContextGL>(context), mShadowCopy.resize(size)); ANGLE_CHECK_GL_ALLOC(contextGL, mShadowCopy.resize(size));
if (size > 0 && data != nullptr) if (size > 0 && data != nullptr)
{ {
...@@ -87,10 +89,15 @@ angle::Result BufferGL::setSubData(const gl::Context *context, ...@@ -87,10 +89,15 @@ angle::Result BufferGL::setSubData(const gl::Context *context,
size_t size, size_t size,
size_t offset) size_t offset)
{ {
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); const FunctionsGL *functions = GetFunctionsGL(context);
mFunctions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), offset, size, data); StateManagerGL *stateManager = GetStateManagerGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);
stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
ANGLE_GL_TRY(context, functions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), offset,
size, data));
if (mShadowBufferData && size > 0) if (features.keepBufferShadowCopy.enabled && size > 0)
{ {
memcpy(mShadowCopy.data() + offset, data, size); memcpy(mShadowCopy.data() + offset, data, size);
} }
...@@ -104,18 +111,22 @@ angle::Result BufferGL::copySubData(const gl::Context *context, ...@@ -104,18 +111,22 @@ angle::Result BufferGL::copySubData(const gl::Context *context,
GLintptr destOffset, GLintptr destOffset,
GLsizeiptr size) GLsizeiptr size)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);
BufferGL *sourceGL = GetAs<BufferGL>(source); BufferGL *sourceGL = GetAs<BufferGL>(source);
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
mStateManager->bindBuffer(SourceBufferOperationTarget, sourceGL->getBufferID()); stateManager->bindBuffer(SourceBufferOperationTarget, sourceGL->getBufferID());
mFunctions->copyBufferSubData(gl::ToGLenum(SourceBufferOperationTarget), ANGLE_GL_TRY(context, functions->copyBufferSubData(gl::ToGLenum(SourceBufferOperationTarget),
gl::ToGLenum(DestBufferOperationTarget), sourceOffset, destOffset, gl::ToGLenum(DestBufferOperationTarget),
size); sourceOffset, destOffset, size));
if (mShadowBufferData && size > 0) if (features.keepBufferShadowCopy.enabled && size > 0)
{ {
ASSERT(sourceGL->mShadowBufferData); ASSERT(sourceGL->mShadowCopy.size() >= static_cast<size_t>(sourceOffset + size));
memcpy(mShadowCopy.data() + destOffset, sourceGL->mShadowCopy.data() + sourceOffset, size); memcpy(mShadowCopy.data() + destOffset, sourceGL->mShadowCopy.data() + sourceOffset, size);
} }
...@@ -124,21 +135,27 @@ angle::Result BufferGL::copySubData(const gl::Context *context, ...@@ -124,21 +135,27 @@ angle::Result BufferGL::copySubData(const gl::Context *context,
angle::Result BufferGL::map(const gl::Context *context, GLenum access, void **mapPtr) angle::Result BufferGL::map(const gl::Context *context, GLenum access, void **mapPtr)
{ {
if (mShadowBufferData) const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);
if (features.keepBufferShadowCopy.enabled)
{ {
*mapPtr = mShadowCopy.data(); *mapPtr = mShadowCopy.data();
} }
else if (mFunctions->mapBuffer) else if (functions->mapBuffer)
{ {
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
*mapPtr = mFunctions->mapBuffer(gl::ToGLenum(DestBufferOperationTarget), access); *mapPtr = ANGLE_GL_TRY(
context, functions->mapBuffer(gl::ToGLenum(DestBufferOperationTarget), access));
} }
else else
{ {
ASSERT(mFunctions->mapBufferRange && access == GL_WRITE_ONLY_OES); ASSERT(functions->mapBufferRange && access == GL_WRITE_ONLY_OES);
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
*mapPtr = mFunctions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget), 0, *mapPtr =
mBufferSize, GL_MAP_WRITE_BIT); ANGLE_GL_TRY(context, functions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget),
0, mBufferSize, GL_MAP_WRITE_BIT));
} }
mIsMapped = true; mIsMapped = true;
...@@ -154,15 +171,20 @@ angle::Result BufferGL::mapRange(const gl::Context *context, ...@@ -154,15 +171,20 @@ angle::Result BufferGL::mapRange(const gl::Context *context,
GLbitfield access, GLbitfield access,
void **mapPtr) void **mapPtr)
{ {
if (mShadowBufferData) const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);
if (features.keepBufferShadowCopy.enabled)
{ {
*mapPtr = mShadowCopy.data() + offset; *mapPtr = mShadowCopy.data() + offset;
} }
else else
{ {
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
*mapPtr = mFunctions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget), offset, *mapPtr =
length, access); ANGLE_GL_TRY(context, functions->mapBufferRange(gl::ToGLenum(DestBufferOperationTarget),
offset, length, access));
} }
mIsMapped = true; mIsMapped = true;
...@@ -174,20 +196,26 @@ angle::Result BufferGL::mapRange(const gl::Context *context, ...@@ -174,20 +196,26 @@ angle::Result BufferGL::mapRange(const gl::Context *context,
angle::Result BufferGL::unmap(const gl::Context *context, GLboolean *result) angle::Result BufferGL::unmap(const gl::Context *context, GLboolean *result)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);
ASSERT(result); ASSERT(result);
ASSERT(mIsMapped); ASSERT(mIsMapped);
if (mShadowBufferData) if (features.keepBufferShadowCopy.enabled)
{ {
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
mFunctions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), mMapOffset, mMapSize, ANGLE_GL_TRY(context,
mShadowCopy.data() + mMapOffset); functions->bufferSubData(gl::ToGLenum(DestBufferOperationTarget), mMapOffset,
mMapSize, mShadowCopy.data() + mMapOffset));
*result = GL_TRUE; *result = GL_TRUE;
} }
else else
{ {
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
*result = mFunctions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget)); *result =
ANGLE_GL_TRY(context, functions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget)));
} }
mIsMapped = false; mIsMapped = false;
...@@ -201,25 +229,29 @@ angle::Result BufferGL::getIndexRange(const gl::Context *context, ...@@ -201,25 +229,29 @@ angle::Result BufferGL::getIndexRange(const gl::Context *context,
bool primitiveRestartEnabled, bool primitiveRestartEnabled,
gl::IndexRange *outRange) gl::IndexRange *outRange)
{ {
const FunctionsGL *functions = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);
ASSERT(!mIsMapped); ASSERT(!mIsMapped);
if (mShadowBufferData) if (features.keepBufferShadowCopy.enabled)
{ {
*outRange = gl::ComputeIndexRange(type, mShadowCopy.data() + offset, count, *outRange = gl::ComputeIndexRange(type, mShadowCopy.data() + offset, count,
primitiveRestartEnabled); primitiveRestartEnabled);
} }
else else
{ {
mStateManager->bindBuffer(DestBufferOperationTarget, mBufferID); stateManager->bindBuffer(DestBufferOperationTarget, mBufferID);
const GLuint typeBytes = gl::GetDrawElementsTypeSize(type); const GLuint typeBytes = gl::GetDrawElementsTypeSize(type);
const uint8_t *bufferData = const uint8_t *bufferData =
MapBufferRangeWithFallback(mFunctions, gl::ToGLenum(DestBufferOperationTarget), offset, MapBufferRangeWithFallback(functions, gl::ToGLenum(DestBufferOperationTarget), offset,
count * typeBytes, GL_MAP_READ_BIT); count * typeBytes, GL_MAP_READ_BIT);
if (bufferData) if (bufferData)
{ {
*outRange = gl::ComputeIndexRange(type, bufferData, count, primitiveRestartEnabled); *outRange = gl::ComputeIndexRange(type, bufferData, count, primitiveRestartEnabled);
mFunctions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget)); ANGLE_GL_TRY(context, functions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget)));
} }
else else
{ {
......
...@@ -21,11 +21,11 @@ class StateManagerGL; ...@@ -21,11 +21,11 @@ class StateManagerGL;
class BufferGL : public BufferImpl class BufferGL : public BufferImpl
{ {
public: public:
BufferGL(const gl::BufferState &state, BufferGL(const gl::BufferState &state, GLuint buffer);
const FunctionsGL *functions,
StateManagerGL *stateManager);
~BufferGL() override; ~BufferGL() override;
void destroy(const gl::Context *context) override;
angle::Result setData(const gl::Context *context, angle::Result setData(const gl::Context *context,
gl::BufferBinding target, gl::BufferBinding target,
const void *data, const void *data,
...@@ -63,14 +63,10 @@ class BufferGL : public BufferImpl ...@@ -63,14 +63,10 @@ class BufferGL : public BufferImpl
size_t mMapOffset; size_t mMapOffset;
size_t mMapSize; size_t mMapSize;
bool mShadowBufferData;
angle::MemoryBuffer mShadowCopy; angle::MemoryBuffer mShadowCopy;
size_t mBufferSize; size_t mBufferSize;
const FunctionsGL *mFunctions;
StateManagerGL *mStateManager;
GLuint mBufferID; GLuint mBufferID;
}; };
......
...@@ -105,7 +105,12 @@ RenderbufferImpl *ContextGL::createRenderbuffer(const gl::RenderbufferState &sta ...@@ -105,7 +105,12 @@ RenderbufferImpl *ContextGL::createRenderbuffer(const gl::RenderbufferState &sta
BufferImpl *ContextGL::createBuffer(const gl::BufferState &state) BufferImpl *ContextGL::createBuffer(const gl::BufferState &state)
{ {
return new BufferGL(state, getFunctions(), getStateManager()); const FunctionsGL *functions = getFunctions();
GLuint buffer = 0;
functions->genBuffers(1, &buffer);
return new BufferGL(state, buffer);
} }
VertexArrayImpl *ContextGL::createVertexArray(const gl::VertexArrayState &data) VertexArrayImpl *ContextGL::createVertexArray(const gl::VertexArrayState &data)
......
...@@ -1834,6 +1834,8 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature ...@@ -1834,6 +1834,8 @@ void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *feature
// http://crbug.com/1137851 // http://crbug.com/1137851
// Speculative fix for now, leave disabled so users can enable it via flags. // Speculative fix for now, leave disabled so users can enable it via flags.
ANGLE_FEATURE_CONDITION(features, disableSyncControlSupport, false); ANGLE_FEATURE_CONDITION(features, disableSyncControlSupport, false);
ANGLE_FEATURE_CONDITION(features, keepBufferShadowCopy, !CanMapBufferForRead(functions));
} }
void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features) void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
......
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