VertexBuffer.h revision 55bfb4e728fe1db619af5d2c287f4abe711b3343
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    VertexBuffer():
27        mBuffer(0),
28        mVertexCount(0),
29        mCleanupMethod(NULL)
30    {}
31
32    ~VertexBuffer() {
33        if (mCleanupMethod) mCleanupMethod(mBuffer);
34    }
35
36    /**
37       This should be the only method used by the Tessellator. Subsequent calls to
38       alloc will allocate space within the first allocation (useful if you want to
39       eventually allocate multiple regions within a single VertexBuffer, such as
40       with PathTessellator::tesselateLines())
41     */
42    template <class TYPE>
43    TYPE* alloc(int vertexCount) {
44        if (mVertexCount) {
45            TYPE* reallocBuffer = (TYPE*)mReallocBuffer;
46            // already have allocated the buffer, re-allocate space within
47            if (mReallocBuffer != mBuffer) {
48                // not first re-allocation, leave space for degenerate triangles to separate strips
49                reallocBuffer += 2;
50            }
51            mReallocBuffer = reallocBuffer + vertexCount;
52            return reallocBuffer;
53        }
54        mVertexCount = vertexCount;
55        mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
56        mCleanupMethod = &(cleanup<TYPE>);
57
58        return (TYPE*)mBuffer;
59    }
60
61    template <class TYPE>
62    void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) {
63        int verticesToCopy = srcBuffer.getVertexCount();
64
65        TYPE* dst = alloc<TYPE>(verticesToCopy);
66        TYPE* src = (TYPE*)srcBuffer.getBuffer();
67
68        for (int i = 0; i < verticesToCopy; i++) {
69            TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset);
70        }
71    }
72
73    const void* getBuffer() const { return mBuffer; }
74    unsigned int getVertexCount() const { return mVertexCount; }
75
76    template <class TYPE>
77    void createDegenerateSeparators(int allocSize) {
78        TYPE* end = (TYPE*)mBuffer + mVertexCount;
79        for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) {
80            memcpy(degen, degen - 1, sizeof(TYPE));
81            memcpy(degen + 1, degen + 2, sizeof(TYPE));
82        }
83    }
84
85private:
86    template <class TYPE>
87    static void cleanup(void* buffer) {
88        delete[] (TYPE*)buffer;
89    }
90
91    void* mBuffer;
92    unsigned int mVertexCount;
93
94    void* mReallocBuffer; // used for multi-allocation
95
96    void (*mCleanupMethod)(void*);
97};
98
99}; // namespace uirenderer
100}; // namespace android
101
102#endif // ANDROID_HWUI_VERTEX_BUFFER_H
103