1//
2// Copyright (c) 2002-2010 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// geometry/VertexDataManager.h: Defines the VertexDataManager, a class that
8// runs the Buffer translation process.
9
10#ifndef LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
11#define LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
12
13#include <vector>
14#include <cstddef>
15
16#define GL_APICALL
17#include <GLES2/gl2.h>
18
19#include "libGLESv2/Context.h"
20
21namespace gl
22{
23
24struct TranslatedAttribute
25{
26    bool active;
27
28    D3DDECLTYPE type;
29    UINT offset;
30    UINT stride;   // 0 means not to advance the read pointer at all
31    UINT semanticIndex;
32
33    IDirect3DVertexBuffer9 *vertexBuffer;
34};
35
36class VertexBuffer
37{
38  public:
39    VertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
40    virtual ~VertexBuffer();
41
42    void unmap();
43
44    IDirect3DVertexBuffer9 *getBuffer() const;
45
46  protected:
47    IDirect3DDevice9 *const mDevice;
48    IDirect3DVertexBuffer9 *mVertexBuffer;
49
50  private:
51    DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
52};
53
54class ConstantVertexBuffer : public VertexBuffer
55{
56  public:
57    ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w);
58    ~ConstantVertexBuffer();
59};
60
61class ArrayVertexBuffer : public VertexBuffer
62{
63  public:
64    ArrayVertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
65    ~ArrayVertexBuffer();
66
67    UINT size() const { return mBufferSize; }
68    virtual void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset) = 0;
69    virtual void reserveRequiredSpace() = 0;
70    void addRequiredSpace(UINT requiredSpace);
71    void addRequiredSpaceFor(ArrayVertexBuffer *buffer);
72
73  protected:
74    UINT mBufferSize;
75    UINT mWritePosition;
76    UINT mRequiredSpace;
77};
78
79class StreamingVertexBuffer : public ArrayVertexBuffer
80{
81  public:
82    StreamingVertexBuffer(IDirect3DDevice9 *device, UINT initialSize);
83    ~StreamingVertexBuffer();
84
85    void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
86    void reserveRequiredSpace();
87};
88
89class StaticVertexBuffer : public ArrayVertexBuffer
90{
91  public:
92    explicit StaticVertexBuffer(IDirect3DDevice9 *device);
93    ~StaticVertexBuffer();
94
95    void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
96    void reserveRequiredSpace();
97
98    UINT lookupAttribute(const VertexAttribute &attribute);   // Returns the offset into the vertex buffer, or -1 if not found
99
100  private:
101    struct VertexElement
102    {
103        GLenum type;
104        GLint size;
105        bool normalized;
106        int attributeOffset;
107
108        UINT streamOffset;
109    };
110
111    std::vector<VertexElement> mCache;
112};
113
114class VertexDataManager
115{
116  public:
117    VertexDataManager(Context *context, IDirect3DDevice9 *backend);
118    virtual ~VertexDataManager();
119
120    void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
121
122    void setupAttributes(const TranslatedAttribute *attributes);
123    GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
124
125  private:
126    DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
127
128    UINT spaceRequired(const VertexAttribute &attrib, std::size_t count) const;
129    UINT writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
130
131    Context *const mContext;
132    IDirect3DDevice9 *const mDevice;
133
134    StreamingVertexBuffer *mStreamingBuffer;
135
136    bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
137    ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
138
139    // Attribute format conversion
140    struct FormatConverter
141    {
142        bool identity;
143        std::size_t outputElementSize;
144        void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
145        D3DDECLTYPE d3dDeclType;
146    };
147
148    enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
149
150    FormatConverter mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];   // [GL types as enumerated by typeIndex()][normalized][size - 1]
151
152    struct TranslationDescription
153    {
154        DWORD capsFlag;
155        FormatConverter preferredConversion;
156        FormatConverter fallbackConversion;
157    };
158
159    // This table is used to generate mAttributeTypes.
160    static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
161
162    void checkVertexCaps(DWORD declTypes);
163
164    unsigned int typeIndex(GLenum type) const;
165    const FormatConverter &formatConverter(const VertexAttribute &attribute) const;
166};
167
168}
169
170#endif   // LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
171