1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker 7*8975f5c5SAndroid Build Coastguard Worker // Buffer.h: Defines the gl::Buffer class, representing storage of vertex and/or 8*8975f5c5SAndroid Build Coastguard Worker // index data. Implements GL buffer objects and related functionality. 9*8975f5c5SAndroid Build Coastguard Worker // [OpenGL ES 2.0.24] section 2.9 page 21. 10*8975f5c5SAndroid Build Coastguard Worker 11*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_BUFFER_H_ 12*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_BUFFER_H_ 13*8975f5c5SAndroid Build Coastguard Worker 14*8975f5c5SAndroid Build Coastguard Worker #include "common/PackedEnums.h" 15*8975f5c5SAndroid Build Coastguard Worker #include "common/angleutils.h" 16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Debug.h" 17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Error.h" 18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/IndexRangeCache.h" 19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Observer.h" 20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/RefCountObject.h" 21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/angletypes.h" 22*8975f5c5SAndroid Build Coastguard Worker 23*8975f5c5SAndroid Build Coastguard Worker namespace rx 24*8975f5c5SAndroid Build Coastguard Worker { 25*8975f5c5SAndroid Build Coastguard Worker class BufferImpl; 26*8975f5c5SAndroid Build Coastguard Worker class GLImplFactory; 27*8975f5c5SAndroid Build Coastguard Worker } // namespace rx 28*8975f5c5SAndroid Build Coastguard Worker 29*8975f5c5SAndroid Build Coastguard Worker namespace gl 30*8975f5c5SAndroid Build Coastguard Worker { 31*8975f5c5SAndroid Build Coastguard Worker class Buffer; 32*8975f5c5SAndroid Build Coastguard Worker class Context; 33*8975f5c5SAndroid Build Coastguard Worker 34*8975f5c5SAndroid Build Coastguard Worker enum class WebGLBufferType 35*8975f5c5SAndroid Build Coastguard Worker { 36*8975f5c5SAndroid Build Coastguard Worker Undefined, 37*8975f5c5SAndroid Build Coastguard Worker ElementArray, 38*8975f5c5SAndroid Build Coastguard Worker OtherData, 39*8975f5c5SAndroid Build Coastguard Worker }; 40*8975f5c5SAndroid Build Coastguard Worker 41*8975f5c5SAndroid Build Coastguard Worker class BufferState final : angle::NonCopyable 42*8975f5c5SAndroid Build Coastguard Worker { 43*8975f5c5SAndroid Build Coastguard Worker public: 44*8975f5c5SAndroid Build Coastguard Worker BufferState(); 45*8975f5c5SAndroid Build Coastguard Worker ~BufferState(); 46*8975f5c5SAndroid Build Coastguard Worker getUsage()47*8975f5c5SAndroid Build Coastguard Worker BufferUsage getUsage() const { return mUsage; } getAccessFlags()48*8975f5c5SAndroid Build Coastguard Worker GLbitfield getAccessFlags() const { return mAccessFlags; } getAccess()49*8975f5c5SAndroid Build Coastguard Worker GLenum getAccess() const { return mAccess; } isMapped()50*8975f5c5SAndroid Build Coastguard Worker GLboolean isMapped() const { return mMapped; } getMapPointer()51*8975f5c5SAndroid Build Coastguard Worker void *getMapPointer() const { return mMapPointer; } getMapOffset()52*8975f5c5SAndroid Build Coastguard Worker GLint64 getMapOffset() const { return mMapOffset; } getMapLength()53*8975f5c5SAndroid Build Coastguard Worker GLint64 getMapLength() const { return mMapLength; } getSize()54*8975f5c5SAndroid Build Coastguard Worker GLint64 getSize() const { return mSize; } isBoundForTransformFeedback()55*8975f5c5SAndroid Build Coastguard Worker bool isBoundForTransformFeedback() const { return mTransformFeedbackIndexedBindingCount != 0; } getLabel()56*8975f5c5SAndroid Build Coastguard Worker std::string getLabel() const { return mLabel; } getWebGLType()57*8975f5c5SAndroid Build Coastguard Worker WebGLBufferType getWebGLType() const { return mWebGLType; } 58*8975f5c5SAndroid Build Coastguard Worker 59*8975f5c5SAndroid Build Coastguard Worker private: 60*8975f5c5SAndroid Build Coastguard Worker friend class Buffer; 61*8975f5c5SAndroid Build Coastguard Worker 62*8975f5c5SAndroid Build Coastguard Worker std::string mLabel; 63*8975f5c5SAndroid Build Coastguard Worker 64*8975f5c5SAndroid Build Coastguard Worker BufferUsage mUsage; 65*8975f5c5SAndroid Build Coastguard Worker GLint64 mSize; 66*8975f5c5SAndroid Build Coastguard Worker GLbitfield mAccessFlags; 67*8975f5c5SAndroid Build Coastguard Worker GLenum mAccess; 68*8975f5c5SAndroid Build Coastguard Worker GLboolean mMapped; 69*8975f5c5SAndroid Build Coastguard Worker void *mMapPointer; 70*8975f5c5SAndroid Build Coastguard Worker GLint64 mMapOffset; 71*8975f5c5SAndroid Build Coastguard Worker GLint64 mMapLength; 72*8975f5c5SAndroid Build Coastguard Worker int mBindingCount; 73*8975f5c5SAndroid Build Coastguard Worker int mTransformFeedbackIndexedBindingCount; 74*8975f5c5SAndroid Build Coastguard Worker int mTransformFeedbackGenericBindingCount; 75*8975f5c5SAndroid Build Coastguard Worker GLboolean mImmutable; 76*8975f5c5SAndroid Build Coastguard Worker GLbitfield mStorageExtUsageFlags; 77*8975f5c5SAndroid Build Coastguard Worker GLboolean mExternal; 78*8975f5c5SAndroid Build Coastguard Worker WebGLBufferType mWebGLType; 79*8975f5c5SAndroid Build Coastguard Worker }; 80*8975f5c5SAndroid Build Coastguard Worker 81*8975f5c5SAndroid Build Coastguard Worker // Vertex Array and Texture track buffer data updates. 82*8975f5c5SAndroid Build Coastguard Worker struct ContentsObserver 83*8975f5c5SAndroid Build Coastguard Worker { 84*8975f5c5SAndroid Build Coastguard Worker static constexpr uint32_t kBufferTextureIndex = std::numeric_limits<uint32_t>::max(); 85*8975f5c5SAndroid Build Coastguard Worker uint32_t bufferIndex = 0; 86*8975f5c5SAndroid Build Coastguard Worker 87*8975f5c5SAndroid Build Coastguard Worker // VertexArray* (bufferIndex != kBufferTextureIndex) or Texture* 88*8975f5c5SAndroid Build Coastguard Worker void *observer = nullptr; 89*8975f5c5SAndroid Build Coastguard Worker }; 90*8975f5c5SAndroid Build Coastguard Worker 91*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE bool operator==(const ContentsObserver &lhs, const ContentsObserver &rhs) 92*8975f5c5SAndroid Build Coastguard Worker { 93*8975f5c5SAndroid Build Coastguard Worker return lhs.bufferIndex == rhs.bufferIndex && lhs.observer == rhs.observer; 94*8975f5c5SAndroid Build Coastguard Worker } 95*8975f5c5SAndroid Build Coastguard Worker 96*8975f5c5SAndroid Build Coastguard Worker class Buffer final : public ThreadSafeRefCountObject<BufferID>, 97*8975f5c5SAndroid Build Coastguard Worker public LabeledObject, 98*8975f5c5SAndroid Build Coastguard Worker public angle::ObserverInterface, 99*8975f5c5SAndroid Build Coastguard Worker public angle::Subject 100*8975f5c5SAndroid Build Coastguard Worker { 101*8975f5c5SAndroid Build Coastguard Worker public: 102*8975f5c5SAndroid Build Coastguard Worker Buffer(rx::GLImplFactory *factory, BufferID id); 103*8975f5c5SAndroid Build Coastguard Worker ~Buffer() override; 104*8975f5c5SAndroid Build Coastguard Worker void onDestroy(const Context *context) override; 105*8975f5c5SAndroid Build Coastguard Worker 106*8975f5c5SAndroid Build Coastguard Worker void onBind(const Context *context, BufferBinding target); 107*8975f5c5SAndroid Build Coastguard Worker 108*8975f5c5SAndroid Build Coastguard Worker angle::Result setLabel(const Context *context, const std::string &label) override; 109*8975f5c5SAndroid Build Coastguard Worker const std::string &getLabel() const override; 110*8975f5c5SAndroid Build Coastguard Worker 111*8975f5c5SAndroid Build Coastguard Worker angle::Result bufferStorageExternal(Context *context, 112*8975f5c5SAndroid Build Coastguard Worker BufferBinding target, 113*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size, 114*8975f5c5SAndroid Build Coastguard Worker GLeglClientBufferEXT clientBuffer, 115*8975f5c5SAndroid Build Coastguard Worker GLbitfield flags); 116*8975f5c5SAndroid Build Coastguard Worker angle::Result bufferStorage(Context *context, 117*8975f5c5SAndroid Build Coastguard Worker BufferBinding target, 118*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size, 119*8975f5c5SAndroid Build Coastguard Worker const void *data, 120*8975f5c5SAndroid Build Coastguard Worker GLbitfield flags); 121*8975f5c5SAndroid Build Coastguard Worker angle::Result bufferData(Context *context, 122*8975f5c5SAndroid Build Coastguard Worker BufferBinding target, 123*8975f5c5SAndroid Build Coastguard Worker const void *data, 124*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size, 125*8975f5c5SAndroid Build Coastguard Worker BufferUsage usage); 126*8975f5c5SAndroid Build Coastguard Worker angle::Result bufferSubData(const Context *context, 127*8975f5c5SAndroid Build Coastguard Worker BufferBinding target, 128*8975f5c5SAndroid Build Coastguard Worker const void *data, 129*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size, 130*8975f5c5SAndroid Build Coastguard Worker GLintptr offset); 131*8975f5c5SAndroid Build Coastguard Worker angle::Result copyBufferSubData(const Context *context, 132*8975f5c5SAndroid Build Coastguard Worker Buffer *source, 133*8975f5c5SAndroid Build Coastguard Worker GLintptr sourceOffset, 134*8975f5c5SAndroid Build Coastguard Worker GLintptr destOffset, 135*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size); 136*8975f5c5SAndroid Build Coastguard Worker angle::Result map(const Context *context, GLenum access); 137*8975f5c5SAndroid Build Coastguard Worker angle::Result mapRange(const Context *context, 138*8975f5c5SAndroid Build Coastguard Worker GLintptr offset, 139*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr length, 140*8975f5c5SAndroid Build Coastguard Worker GLbitfield access); 141*8975f5c5SAndroid Build Coastguard Worker angle::Result unmap(const Context *context, GLboolean *result); 142*8975f5c5SAndroid Build Coastguard Worker 143*8975f5c5SAndroid Build Coastguard Worker // These are called when another operation changes Buffer data. 144*8975f5c5SAndroid Build Coastguard Worker void onDataChanged(); 145*8975f5c5SAndroid Build Coastguard Worker 146*8975f5c5SAndroid Build Coastguard Worker angle::Result getIndexRange(const gl::Context *context, 147*8975f5c5SAndroid Build Coastguard Worker DrawElementsType type, 148*8975f5c5SAndroid Build Coastguard Worker size_t offset, 149*8975f5c5SAndroid Build Coastguard Worker size_t count, 150*8975f5c5SAndroid Build Coastguard Worker bool primitiveRestartEnabled, 151*8975f5c5SAndroid Build Coastguard Worker IndexRange *outRange) const; getState()152*8975f5c5SAndroid Build Coastguard Worker const BufferState &getState() const { return mState; } getUsage()153*8975f5c5SAndroid Build Coastguard Worker BufferUsage getUsage() const { return mState.mUsage; } getAccessFlags()154*8975f5c5SAndroid Build Coastguard Worker GLbitfield getAccessFlags() const { return mState.mAccessFlags; } getAccess()155*8975f5c5SAndroid Build Coastguard Worker GLenum getAccess() const { return mState.mAccess; } isMapped()156*8975f5c5SAndroid Build Coastguard Worker GLboolean isMapped() const { return mState.mMapped; } isPersistentlyMapped()157*8975f5c5SAndroid Build Coastguard Worker bool isPersistentlyMapped() const 158*8975f5c5SAndroid Build Coastguard Worker { 159*8975f5c5SAndroid Build Coastguard Worker return (mState.mStorageExtUsageFlags & GL_MAP_PERSISTENT_BIT_EXT) != 0; 160*8975f5c5SAndroid Build Coastguard Worker } getMapPointer()161*8975f5c5SAndroid Build Coastguard Worker void *getMapPointer() const { return mState.mMapPointer; } getMapOffset()162*8975f5c5SAndroid Build Coastguard Worker GLint64 getMapOffset() const { return mState.mMapOffset; } getMapLength()163*8975f5c5SAndroid Build Coastguard Worker GLint64 getMapLength() const { return mState.mMapLength; } getSize()164*8975f5c5SAndroid Build Coastguard Worker GLint64 getSize() const { return mState.mSize; } 165*8975f5c5SAndroid Build Coastguard Worker GLint64 getMemorySize() const; isImmutable()166*8975f5c5SAndroid Build Coastguard Worker GLboolean isImmutable() const { return mState.mImmutable; } getStorageExtUsageFlags()167*8975f5c5SAndroid Build Coastguard Worker GLbitfield getStorageExtUsageFlags() const { return mState.mStorageExtUsageFlags; } 168*8975f5c5SAndroid Build Coastguard Worker 169*8975f5c5SAndroid Build Coastguard Worker // Buffers are always initialized immediately when allocated initState()170*8975f5c5SAndroid Build Coastguard Worker InitState initState() const { return InitState::Initialized; } 171*8975f5c5SAndroid Build Coastguard Worker getImplementation()172*8975f5c5SAndroid Build Coastguard Worker rx::BufferImpl *getImplementation() const { return mImpl; } 173*8975f5c5SAndroid Build Coastguard Worker 174*8975f5c5SAndroid Build Coastguard Worker // Note: we pass "isWebGL" to this function to clarify it's only valid if WebGL is enabled. 175*8975f5c5SAndroid Build Coastguard Worker // We pass the boolean flag instead of the pointer because this header can't read Context.h. hasWebGLXFBBindingConflict(bool isWebGL)176*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE bool hasWebGLXFBBindingConflict(bool isWebGL) const 177*8975f5c5SAndroid Build Coastguard Worker { 178*8975f5c5SAndroid Build Coastguard Worker if (!isWebGL) 179*8975f5c5SAndroid Build Coastguard Worker { 180*8975f5c5SAndroid Build Coastguard Worker return false; 181*8975f5c5SAndroid Build Coastguard Worker } 182*8975f5c5SAndroid Build Coastguard Worker 183*8975f5c5SAndroid Build Coastguard Worker // The transform feedback generic binding point is not an indexed binding point but it also 184*8975f5c5SAndroid Build Coastguard Worker // does not count as a non-transform-feedback use of the buffer, so we subtract it from the 185*8975f5c5SAndroid Build Coastguard Worker // binding count when checking if the buffer is bound to a non-transform-feedback location. 186*8975f5c5SAndroid Build Coastguard Worker // See https://crbug.com/853978 187*8975f5c5SAndroid Build Coastguard Worker return mState.mTransformFeedbackIndexedBindingCount > 0 && 188*8975f5c5SAndroid Build Coastguard Worker mState.mTransformFeedbackIndexedBindingCount != 189*8975f5c5SAndroid Build Coastguard Worker mState.mBindingCount - mState.mTransformFeedbackGenericBindingCount; 190*8975f5c5SAndroid Build Coastguard Worker } 191*8975f5c5SAndroid Build Coastguard Worker 192*8975f5c5SAndroid Build Coastguard Worker bool isDoubleBoundForTransformFeedback() const; 193*8975f5c5SAndroid Build Coastguard Worker void onTFBindingChanged(const Context *context, bool bound, bool indexed); onNonTFBindingChanged(int incr)194*8975f5c5SAndroid Build Coastguard Worker void onNonTFBindingChanged(int incr) { mState.mBindingCount += incr; } 195*8975f5c5SAndroid Build Coastguard Worker angle::Result getSubData(const gl::Context *context, 196*8975f5c5SAndroid Build Coastguard Worker GLintptr offset, 197*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size, 198*8975f5c5SAndroid Build Coastguard Worker void *outData); 199*8975f5c5SAndroid Build Coastguard Worker 200*8975f5c5SAndroid Build Coastguard Worker // angle::ObserverInterface implementation. 201*8975f5c5SAndroid Build Coastguard Worker void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 202*8975f5c5SAndroid Build Coastguard Worker 203*8975f5c5SAndroid Build Coastguard Worker void addContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex); 204*8975f5c5SAndroid Build Coastguard Worker void removeContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex); 205*8975f5c5SAndroid Build Coastguard Worker void addContentsObserver(Texture *texture); 206*8975f5c5SAndroid Build Coastguard Worker void removeContentsObserver(Texture *texture); 207*8975f5c5SAndroid Build Coastguard Worker bool hasContentsObserver(Texture *texture) const; 208*8975f5c5SAndroid Build Coastguard Worker 209*8975f5c5SAndroid Build Coastguard Worker private: 210*8975f5c5SAndroid Build Coastguard Worker angle::Result bufferDataImpl(Context *context, 211*8975f5c5SAndroid Build Coastguard Worker BufferBinding target, 212*8975f5c5SAndroid Build Coastguard Worker const void *data, 213*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size, 214*8975f5c5SAndroid Build Coastguard Worker BufferUsage usage, 215*8975f5c5SAndroid Build Coastguard Worker GLbitfield flags); 216*8975f5c5SAndroid Build Coastguard Worker angle::Result bufferExternalDataImpl(Context *context, 217*8975f5c5SAndroid Build Coastguard Worker BufferBinding target, 218*8975f5c5SAndroid Build Coastguard Worker GLeglClientBufferEXT clientBuffer, 219*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr size, 220*8975f5c5SAndroid Build Coastguard Worker GLbitfield flags); 221*8975f5c5SAndroid Build Coastguard Worker 222*8975f5c5SAndroid Build Coastguard Worker void onContentsChange(); 223*8975f5c5SAndroid Build Coastguard Worker size_t getContentsObserverIndex(void *observer, uint32_t bufferIndex) const; 224*8975f5c5SAndroid Build Coastguard Worker void removeContentsObserverImpl(void *observer, uint32_t bufferIndex); 225*8975f5c5SAndroid Build Coastguard Worker 226*8975f5c5SAndroid Build Coastguard Worker BufferState mState; 227*8975f5c5SAndroid Build Coastguard Worker rx::BufferImpl *mImpl; 228*8975f5c5SAndroid Build Coastguard Worker angle::ObserverBinding mImplObserver; 229*8975f5c5SAndroid Build Coastguard Worker 230*8975f5c5SAndroid Build Coastguard Worker angle::FastVector<ContentsObserver, angle::kMaxFixedObservers> mContentsObservers; 231*8975f5c5SAndroid Build Coastguard Worker mutable IndexRangeCache mIndexRangeCache; 232*8975f5c5SAndroid Build Coastguard Worker }; 233*8975f5c5SAndroid Build Coastguard Worker 234*8975f5c5SAndroid Build Coastguard Worker } // namespace gl 235*8975f5c5SAndroid Build Coastguard Worker 236*8975f5c5SAndroid Build Coastguard Worker #endif // LIBANGLE_BUFFER_H_ 237