1 //
2 // Copyright (c) 2002-2012 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 // VertexDataManager.h: Defines the VertexDataManager, a class that
8 // runs the Buffer translation process.
9 
10 #ifndef LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
11 #define LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
12 
13 #include "common/angleutils.h"
14 #include "libANGLE/angletypes.h"
15 #include "libANGLE/Constants.h"
16 #include "libANGLE/VertexAttribute.h"
17 
18 namespace gl
19 {
20 class State;
21 struct VertexAttribute;
22 class VertexBinding;
23 struct VertexAttribCurrentValueData;
24 }
25 
26 namespace rx
27 {
28 class BufferD3D;
29 class BufferFactoryD3D;
30 class StreamingVertexBufferInterface;
31 class VertexBuffer;
32 
33 class VertexBufferBinding final
34 {
35   public:
36     VertexBufferBinding();
37     VertexBufferBinding(const VertexBufferBinding &other);
38     ~VertexBufferBinding();
39 
40     void set(VertexBuffer *vertexBuffer);
41     VertexBuffer *get() const;
42     VertexBufferBinding &operator=(const VertexBufferBinding &other);
43 
44   private:
45     VertexBuffer *mBoundVertexBuffer;
46 };
47 
48 struct TranslatedAttribute
49 {
50     TranslatedAttribute();
51     TranslatedAttribute(const TranslatedAttribute &other);
52 
53     // Computes the correct offset from baseOffset, usesFirstVertexOffset, stride and startVertex.
54     // Can throw an error on integer overflow.
55     gl::ErrorOrResult<unsigned int> computeOffset(GLint startVertex) const;
56 
57     bool active;
58 
59     const gl::VertexAttribute *attribute;
60     const gl::VertexBinding *binding;
61     GLenum currentValueType;
62     unsigned int baseOffset;
63     bool usesFirstVertexOffset;
64     unsigned int stride;   // 0 means not to advance the read pointer at all
65 
66     VertexBufferBinding vertexBuffer;
67     BufferD3D *storage;
68     unsigned int serial;
69     unsigned int divisor;
70 };
71 
72 enum class VertexStorageType
73 {
74     UNKNOWN,
75     STATIC,         // Translate the vertex data once and re-use it.
76     DYNAMIC,        // Translate the data every frame into a ring buffer.
77     DIRECT,         // Bind a D3D buffer directly without any translation.
78     CURRENT_VALUE,  // Use a single value for the attribute.
79 };
80 
81 // Given a vertex attribute, return the type of storage it will use.
82 VertexStorageType ClassifyAttributeStorage(const gl::VertexAttribute &attrib,
83                                            const gl::VertexBinding &binding);
84 
85 class VertexDataManager : angle::NonCopyable
86 {
87   public:
88     VertexDataManager(BufferFactoryD3D *factory);
89     virtual ~VertexDataManager();
90 
91     gl::Error initialize();
92     void deinitialize();
93 
94     gl::Error prepareVertexData(const gl::Context *context,
95                                 GLint start,
96                                 GLsizei count,
97                                 std::vector<TranslatedAttribute> *translatedAttribs,
98                                 GLsizei instances);
99 
100     static void StoreDirectAttrib(TranslatedAttribute *directAttrib);
101 
102     static gl::Error StoreStaticAttrib(const gl::Context *context, TranslatedAttribute *translated);
103 
104     gl::Error storeDynamicAttribs(const gl::Context *context,
105                                   std::vector<TranslatedAttribute> *translatedAttribs,
106                                   const gl::AttributesMask &dynamicAttribsMask,
107                                   GLint start,
108                                   GLsizei count,
109                                   GLsizei instances);
110 
111     // Promote static usage of dynamic buffers.
112     static void PromoteDynamicAttribs(const gl::Context *context,
113                                       const std::vector<TranslatedAttribute> &translatedAttribs,
114                                       const gl::AttributesMask &dynamicAttribsMask,
115                                       GLsizei count);
116 
117     gl::Error storeCurrentValue(const gl::VertexAttribCurrentValueData &currentValue,
118                                 TranslatedAttribute *translated,
119                                 size_t attribIndex);
120 
121   private:
122     struct CurrentValueState
123     {
124         CurrentValueState();
125         ~CurrentValueState();
126 
127         std::unique_ptr<StreamingVertexBufferInterface> buffer;
128         gl::VertexAttribCurrentValueData data;
129         size_t offset;
130     };
131 
132     gl::Error reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib,
133                                     GLsizei count,
134                                     GLint start,
135                                     GLsizei instances) const;
136 
137     gl::Error storeDynamicAttrib(const gl::Context *context,
138                                  TranslatedAttribute *translated,
139                                  GLint start,
140                                  GLsizei count,
141                                  GLsizei instances);
142 
143     BufferFactoryD3D *const mFactory;
144 
145     std::unique_ptr<StreamingVertexBufferInterface> mStreamingBuffer;
146     std::vector<CurrentValueState> mCurrentValueCache;
147     gl::AttributesMask mDynamicAttribsMaskCache;
148 };
149 
150 }  // namespace rx
151 
152 #endif   // LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
153