diff options
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/Buffer.h')
-rw-r--r-- | gfx/angle/checkout/src/libANGLE/Buffer.h | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/Buffer.h b/gfx/angle/checkout/src/libANGLE/Buffer.h new file mode 100644 index 0000000000..b71f6af89b --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Buffer.h @@ -0,0 +1,218 @@ +// +// Copyright 2002 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Buffer.h: Defines the gl::Buffer class, representing storage of vertex and/or +// index data. Implements GL buffer objects and related functionality. +// [OpenGL ES 2.0.24] section 2.9 page 21. + +#ifndef LIBANGLE_BUFFER_H_ +#define LIBANGLE_BUFFER_H_ + +#include "common/PackedEnums.h" +#include "common/angleutils.h" +#include "libANGLE/Debug.h" +#include "libANGLE/Error.h" +#include "libANGLE/IndexRangeCache.h" +#include "libANGLE/Observer.h" +#include "libANGLE/RefCountObject.h" +#include "libANGLE/angletypes.h" + +namespace rx +{ +class BufferImpl; +class GLImplFactory; +} // namespace rx + +namespace gl +{ +class Buffer; +class Context; + +class BufferState final : angle::NonCopyable +{ + public: + BufferState(); + ~BufferState(); + + BufferUsage getUsage() const { return mUsage; } + GLbitfield getAccessFlags() const { return mAccessFlags; } + GLenum getAccess() const { return mAccess; } + GLboolean isMapped() const { return mMapped; } + void *getMapPointer() const { return mMapPointer; } + GLint64 getMapOffset() const { return mMapOffset; } + GLint64 getMapLength() const { return mMapLength; } + GLint64 getSize() const { return mSize; } + bool isBoundForTransformFeedback() const { return mTransformFeedbackIndexedBindingCount != 0; } + std::string getLabel() const { return mLabel; } + + private: + friend class Buffer; + + std::string mLabel; + + BufferUsage mUsage; + GLint64 mSize; + GLbitfield mAccessFlags; + GLenum mAccess; + GLboolean mMapped; + void *mMapPointer; + GLint64 mMapOffset; + GLint64 mMapLength; + int mBindingCount; + int mTransformFeedbackIndexedBindingCount; + int mTransformFeedbackGenericBindingCount; + GLboolean mImmutable; + GLbitfield mStorageExtUsageFlags; + GLboolean mExternal; +}; + +// Some Vertex Array Objects track buffer data updates. +struct ContentsObserver +{ + VertexArray *vertexArray = nullptr; + uint32_t bufferIndex = 0; +}; + +ANGLE_INLINE bool operator==(const ContentsObserver &lhs, const ContentsObserver &rhs) +{ + return lhs.vertexArray == rhs.vertexArray && lhs.bufferIndex == rhs.bufferIndex; +} + +class Buffer final : public RefCountObject<BufferID>, + public LabeledObject, + public angle::ObserverInterface, + public angle::Subject +{ + public: + Buffer(rx::GLImplFactory *factory, BufferID id); + ~Buffer() override; + void onDestroy(const Context *context) override; + + angle::Result setLabel(const Context *context, const std::string &label) override; + const std::string &getLabel() const override; + + angle::Result bufferStorageExternal(Context *context, + BufferBinding target, + GLsizeiptr size, + GLeglClientBufferEXT clientBuffer, + GLbitfield flags); + angle::Result bufferStorage(Context *context, + BufferBinding target, + GLsizeiptr size, + const void *data, + GLbitfield flags); + angle::Result bufferData(Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + BufferUsage usage); + angle::Result bufferSubData(const Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + GLintptr offset); + angle::Result copyBufferSubData(const Context *context, + Buffer *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size); + angle::Result map(const Context *context, GLenum access); + angle::Result mapRange(const Context *context, + GLintptr offset, + GLsizeiptr length, + GLbitfield access); + angle::Result unmap(const Context *context, GLboolean *result); + + // These are called when another operation changes Buffer data. + void onDataChanged(); + + angle::Result getIndexRange(const gl::Context *context, + DrawElementsType type, + size_t offset, + size_t count, + bool primitiveRestartEnabled, + IndexRange *outRange) const; + const BufferState &getState() const { return mState; } + BufferUsage getUsage() const { return mState.mUsage; } + GLbitfield getAccessFlags() const { return mState.mAccessFlags; } + GLenum getAccess() const { return mState.mAccess; } + GLboolean isMapped() const { return mState.mMapped; } + bool isPersistentlyMapped() const + { + return (mState.mStorageExtUsageFlags & GL_MAP_PERSISTENT_BIT_EXT) != 0; + } + void *getMapPointer() const { return mState.mMapPointer; } + GLint64 getMapOffset() const { return mState.mMapOffset; } + GLint64 getMapLength() const { return mState.mMapLength; } + GLint64 getSize() const { return mState.mSize; } + GLint64 getMemorySize() const; + GLboolean isImmutable() const { return mState.mImmutable; } + GLbitfield getStorageExtUsageFlags() const { return mState.mStorageExtUsageFlags; } + + // Buffers are always initialized immediately when allocated + InitState initState() const { return InitState::Initialized; } + + rx::BufferImpl *getImplementation() const { return mImpl; } + + // Note: we pass "isWebGL" to this function to clarify it's only valid if WebGL is enabled. + // We pass the boolean flag instead of the pointer because this header can't read Context.h. + ANGLE_INLINE bool hasWebGLXFBBindingConflict(bool isWebGL) const + { + if (!isWebGL) + { + return false; + } + + // The transform feedback generic binding point is not an indexed binding point but it also + // does not count as a non-transform-feedback use of the buffer, so we subtract it from the + // binding count when checking if the buffer is bound to a non-transform-feedback location. + // See https://crbug.com/853978 + return mState.mTransformFeedbackIndexedBindingCount > 0 && + mState.mTransformFeedbackIndexedBindingCount != + mState.mBindingCount - mState.mTransformFeedbackGenericBindingCount; + } + + bool isDoubleBoundForTransformFeedback() const; + void onTFBindingChanged(const Context *context, bool bound, bool indexed); + void onNonTFBindingChanged(int incr) { mState.mBindingCount += incr; } + angle::Result getSubData(const gl::Context *context, + GLintptr offset, + GLsizeiptr size, + void *outData); + + // angle::ObserverInterface implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + void addContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex); + void removeContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex); + + private: + angle::Result bufferDataImpl(Context *context, + BufferBinding target, + const void *data, + GLsizeiptr size, + BufferUsage usage, + GLbitfield flags); + angle::Result bufferExternalDataImpl(Context *context, + BufferBinding target, + GLeglClientBufferEXT clientBuffer, + GLsizeiptr size, + GLbitfield flags); + + void onContentsChange(); + size_t getContentsObserverIndex(VertexArray *vertexArray, uint32_t bufferIndex) const; + + BufferState mState; + rx::BufferImpl *mImpl; + angle::ObserverBinding mImplObserver; + + angle::FastVector<ContentsObserver, angle::kMaxFixedObservers> mContentsObservers; + mutable IndexRangeCache mIndexRangeCache; +}; + +} // namespace gl + +#endif // LIBANGLE_BUFFER_H_ |