VertexBuffer.h revision 9a89bc6524620c87c7a321433470c668e2b95d69
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_HWUI_VERTEX_BUFFER_H
18#define ANDROID_HWUI_VERTEX_BUFFER_H
19
20
21namespace android {
22namespace uirenderer {
23
24class VertexBuffer {
25public:
26    enum Mode {
27        kStandard = 0,
28        kOnePolyRingShadow = 1,
29        kTwoPolyRingShadow = 2
30    };
31
32    VertexBuffer()
33            : mBuffer(0)
34            , mVertexCount(0)
35            , mByteCount(0)
36            , mMode(kStandard)
37            , mCleanupMethod(NULL)
38    {}
39
40    ~VertexBuffer() {
41        if (mCleanupMethod) mCleanupMethod(mBuffer);
42    }
43
44    /**
45       This should be the only method used by the Tessellator. Subsequent calls to
46       alloc will allocate space within the first allocation (useful if you want to
47       eventually allocate multiple regions within a single VertexBuffer, such as
48       with PathTessellator::tessellateLines())
49     */
50    template <class TYPE>
51    TYPE* alloc(int vertexCount) {
52        if (mVertexCount) {
53            TYPE* reallocBuffer = (TYPE*)mReallocBuffer;
54            // already have allocated the buffer, re-allocate space within
55            if (mReallocBuffer != mBuffer) {
56                // not first re-allocation, leave space for degenerate triangles to separate strips
57                reallocBuffer += 2;
58            }
59            mReallocBuffer = reallocBuffer + vertexCount;
60            return reallocBuffer;
61        }
62        mVertexCount = vertexCount;
63        mByteCount = mVertexCount * sizeof(TYPE);
64        mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
65
66        mCleanupMethod = &(cleanup<TYPE>);
67
68        return (TYPE*)mBuffer;
69    }
70
71    template <class TYPE>
72    void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) {
73        int verticesToCopy = srcBuffer.getVertexCount();
74
75        TYPE* dst = alloc<TYPE>(verticesToCopy);
76        TYPE* src = (TYPE*)srcBuffer.getBuffer();
77
78        for (int i = 0; i < verticesToCopy; i++) {
79            TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset);
80        }
81    }
82
83    /**
84     * Brute force bounds computation, used only if the producer of this
85     * vertex buffer can't determine bounds more simply/efficiently
86     */
87    template <class TYPE>
88    void computeBounds(int vertexCount = 0) {
89        if (!mVertexCount) {
90            mBounds.setEmpty();
91            return;
92        }
93
94        // default: compute over every vertex
95        if (vertexCount == 0) vertexCount = mVertexCount;
96
97        TYPE* current = (TYPE*)mBuffer;
98        TYPE* end = current + vertexCount;
99        mBounds.set(current->x, current->y, current->x, current->y);
100        for (; current < end; current++) {
101            mBounds.expandToCoverVertex(current->x, current->y);
102        }
103    }
104
105    const void* getBuffer() const { return mBuffer; }
106    const Rect& getBounds() const { return mBounds; }
107    unsigned int getVertexCount() const { return mVertexCount; }
108    unsigned int getSize() const { return mByteCount; }
109    Mode getMode() const { return mMode; }
110
111    void setBounds(Rect bounds) { mBounds = bounds; }
112    void setMode(Mode mode) { mMode = mode; }
113
114    template <class TYPE>
115    void createDegenerateSeparators(int allocSize) {
116        TYPE* end = (TYPE*)mBuffer + mVertexCount;
117        for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) {
118            memcpy(degen, degen - 1, sizeof(TYPE));
119            memcpy(degen + 1, degen + 2, sizeof(TYPE));
120        }
121    }
122
123private:
124    template <class TYPE>
125    static void cleanup(void* buffer) {
126        delete[] (TYPE*)buffer;
127    }
128
129    Rect mBounds;
130    void* mBuffer;
131    unsigned int mVertexCount;
132    unsigned int mByteCount;
133    Mode mMode;
134
135    void* mReallocBuffer; // used for multi-allocation
136
137    void (*mCleanupMethod)(void*);
138};
139
140}; // namespace uirenderer
141}; // namespace android
142
143#endif // ANDROID_HWUI_VERTEX_BUFFER_H
144