1 // 2 // Copyright 2002 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // Buffer.h: Defines the gl::Buffer class, representing storage of vertex and/or 8 // index data. Implements GL buffer objects and related functionality. 9 // [OpenGL ES 2.0.24] section 2.9 page 21. 10 11 #ifndef LIBANGLE_BUFFER_H_ 12 #define LIBANGLE_BUFFER_H_ 13 14 #include "common/PackedEnums.h" 15 #include "common/angleutils.h" 16 #include "libANGLE/Debug.h" 17 #include "libANGLE/Error.h" 18 #include "libANGLE/IndexRangeCache.h" 19 #include "libANGLE/Observer.h" 20 #include "libANGLE/RefCountObject.h" 21 22 namespace rx 23 { 24 class BufferImpl; 25 class GLImplFactory; 26 } // namespace rx 27 28 namespace gl 29 { 30 class Buffer; 31 class Context; 32 33 class BufferState final : angle::NonCopyable 34 { 35 public: 36 BufferState(); 37 ~BufferState(); 38 getUsage()39 BufferUsage getUsage() const { return mUsage; } getAccessFlags()40 GLbitfield getAccessFlags() const { return mAccessFlags; } getAccess()41 GLenum getAccess() const { return mAccess; } isMapped()42 GLboolean isMapped() const { return mMapped; } getMapPointer()43 void *getMapPointer() const { return mMapPointer; } getMapOffset()44 GLint64 getMapOffset() const { return mMapOffset; } getMapLength()45 GLint64 getMapLength() const { return mMapLength; } getSize()46 GLint64 getSize() const { return mSize; } isBoundForTransformFeedback()47 bool isBoundForTransformFeedback() const { return mTransformFeedbackIndexedBindingCount != 0; } 48 49 private: 50 friend class Buffer; 51 52 std::string mLabel; 53 54 BufferUsage mUsage; 55 GLint64 mSize; 56 GLbitfield mAccessFlags; 57 GLenum mAccess; 58 GLboolean mMapped; 59 void *mMapPointer; 60 GLint64 mMapOffset; 61 GLint64 mMapLength; 62 int mBindingCount; 63 int mTransformFeedbackIndexedBindingCount; 64 int mTransformFeedbackGenericBindingCount; 65 }; 66 67 class Buffer final : public RefCountObject<BufferID>, 68 public LabeledObject, 69 public angle::ObserverInterface, 70 public angle::Subject 71 { 72 public: 73 Buffer(rx::GLImplFactory *factory, BufferID id); 74 ~Buffer() override; 75 void onDestroy(const Context *context) override; 76 77 void setLabel(const Context *context, const std::string &label) override; 78 const std::string &getLabel() const override; 79 80 angle::Result bufferData(Context *context, 81 BufferBinding target, 82 const void *data, 83 GLsizeiptr size, 84 BufferUsage usage); 85 angle::Result bufferSubData(const Context *context, 86 BufferBinding target, 87 const void *data, 88 GLsizeiptr size, 89 GLintptr offset); 90 angle::Result copyBufferSubData(const Context *context, 91 Buffer *source, 92 GLintptr sourceOffset, 93 GLintptr destOffset, 94 GLsizeiptr size); 95 angle::Result map(const Context *context, GLenum access); 96 angle::Result mapRange(const Context *context, 97 GLintptr offset, 98 GLsizeiptr length, 99 GLbitfield access); 100 angle::Result unmap(const Context *context, GLboolean *result); 101 102 // These are called when another operation changes Buffer data. 103 void onDataChanged(); 104 105 angle::Result getIndexRange(const gl::Context *context, 106 DrawElementsType type, 107 size_t offset, 108 size_t count, 109 bool primitiveRestartEnabled, 110 IndexRange *outRange) const; 111 getUsage()112 BufferUsage getUsage() const { return mState.mUsage; } getAccessFlags()113 GLbitfield getAccessFlags() const { return mState.mAccessFlags; } getAccess()114 GLenum getAccess() const { return mState.mAccess; } isMapped()115 GLboolean isMapped() const { return mState.mMapped; } getMapPointer()116 void *getMapPointer() const { return mState.mMapPointer; } getMapOffset()117 GLint64 getMapOffset() const { return mState.mMapOffset; } getMapLength()118 GLint64 getMapLength() const { return mState.mMapLength; } getSize()119 GLint64 getSize() const { return mState.mSize; } 120 GLint64 getMemorySize() const; 121 getImplementation()122 rx::BufferImpl *getImplementation() const { return mImpl; } 123 isBound()124 ANGLE_INLINE bool isBound() const { return mState.mBindingCount > 0; } 125 isBoundForTransformFeedbackAndOtherUse()126 ANGLE_INLINE bool isBoundForTransformFeedbackAndOtherUse() const 127 { 128 // The transform feedback generic binding point is not an indexed binding point but it also 129 // does not count as a non-transform-feedback use of the buffer, so we subtract it from the 130 // binding count when checking if the buffer is bound to a non-transform-feedback location. 131 // See https://crbug.com/853978 132 return mState.mTransformFeedbackIndexedBindingCount > 0 && 133 mState.mTransformFeedbackIndexedBindingCount != 134 mState.mBindingCount - mState.mTransformFeedbackGenericBindingCount; 135 } 136 137 bool isDoubleBoundForTransformFeedback() const; 138 void onTFBindingChanged(const Context *context, bool bound, bool indexed); onNonTFBindingChanged(int incr)139 void onNonTFBindingChanged(int incr) { mState.mBindingCount += incr; } 140 141 // angle::ObserverInterface implementation. 142 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 143 144 private: 145 BufferState mState; 146 rx::BufferImpl *mImpl; 147 angle::ObserverBinding mImplObserver; 148 149 mutable IndexRangeCache mIndexRangeCache; 150 }; 151 152 } // namespace gl 153 154 #endif // LIBANGLE_BUFFER_H_ 155