• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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