summaryrefslogtreecommitdiff
path: root/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.h
blob: 1bd8351d8a06125efb12136a9152b19d58f5f4ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// VertexDataManager.h: Defines the VertexDataManager, a class that
// runs the Buffer translation process.

#ifndef LIBGLESV2_VERTEXDATAMANAGER_H_
#define LIBGLESV2_VERTEXDATAMANAGER_H_

#include <vector>
#include <cstddef>

#define GL_APICALL
#include <GLES2/gl2.h>

#include "libGLESv2/Context.h"

namespace gl
{

struct TranslatedAttribute
{
    bool active;

    D3DDECLTYPE type;
    UINT offset;
    UINT stride;   // 0 means not to advance the read pointer at all

    IDirect3DVertexBuffer9 *vertexBuffer;
};

class VertexBuffer
{
  public:
    VertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
    virtual ~VertexBuffer();

    void unmap();

    IDirect3DVertexBuffer9 *getBuffer() const;

  protected:
    IDirect3DDevice9 *const mDevice;
    IDirect3DVertexBuffer9 *mVertexBuffer;

  private:
    DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
};

class ConstantVertexBuffer : public VertexBuffer
{
  public:
    ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w);
    ~ConstantVertexBuffer();
};

class ArrayVertexBuffer : public VertexBuffer
{
  public:
    ArrayVertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
    ~ArrayVertexBuffer();

    UINT size() const { return mBufferSize; }
    virtual void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset) = 0;
    virtual void reserveRequiredSpace() = 0;
    void addRequiredSpace(UINT requiredSpace);
    void addRequiredSpaceFor(ArrayVertexBuffer *buffer);

  protected:
    UINT mBufferSize;
    UINT mWritePosition;
    UINT mRequiredSpace;
};

class StreamingVertexBuffer : public ArrayVertexBuffer
{
  public:
    StreamingVertexBuffer(IDirect3DDevice9 *device, UINT initialSize);
    ~StreamingVertexBuffer();

    void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
    void reserveRequiredSpace();
};

class StaticVertexBuffer : public ArrayVertexBuffer
{
  public:
    explicit StaticVertexBuffer(IDirect3DDevice9 *device);
    ~StaticVertexBuffer();

    void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
    void reserveRequiredSpace();

    UINT lookupAttribute(const VertexAttribute &attribute);   // Returns the offset into the vertex buffer, or -1 if not found

  private:
    struct VertexElement
    {
        GLenum type;
        GLint size;
        bool normalized;
        int attributeOffset;

        UINT streamOffset;
    };

    std::vector<VertexElement> mCache;
};

class VertexDataManager
{
  public:
    VertexDataManager(Context *context, IDirect3DDevice9 *backend);
    virtual ~VertexDataManager();

    void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }

    GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);

  private:
    DISALLOW_COPY_AND_ASSIGN(VertexDataManager);

    UINT spaceRequired(const VertexAttribute &attrib, std::size_t count) const;
    UINT writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);

    Context *const mContext;
    IDirect3DDevice9 *const mDevice;

    StreamingVertexBuffer *mStreamingBuffer;

    bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
    ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];

    // Attribute format conversion
    struct FormatConverter
    {
        bool identity;
        std::size_t outputElementSize;
        void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
        D3DDECLTYPE d3dDeclType;
    };

    enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };

    FormatConverter mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];   // [GL types as enumerated by typeIndex()][normalized][size - 1]

    struct TranslationDescription
    {
        DWORD capsFlag;
        FormatConverter preferredConversion;
        FormatConverter fallbackConversion;
    };

    // This table is used to generate mAttributeTypes.
    static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]

    void checkVertexCaps(DWORD declTypes);

    unsigned int typeIndex(GLenum type) const;
    const FormatConverter &formatConverter(const VertexAttribute &attribute) const;
};

}

#endif   // LIBGLESV2_VERTEXDATAMANAGER_H_