• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "utils/MathUtils.h"
21 
22 namespace android {
23 namespace uirenderer {
24 
25 class VertexBuffer {
26 public:
27     enum Mode {
28         kStandard = 0,
29         kOnePolyRingShadow = 1,
30         kTwoPolyRingShadow = 2,
31         kIndices = 3
32     };
33 
VertexBuffer()34     VertexBuffer()
35             : mBuffer(0)
36             , mIndices(0)
37             , mVertexCount(0)
38             , mIndexCount(0)
39             , mAllocatedVertexCount(0)
40             , mAllocatedIndexCount(0)
41             , mByteCount(0)
42             , mMode(kStandard)
43             , mReallocBuffer(0)
44             , mCleanupMethod(NULL)
45             , mCleanupIndexMethod(NULL)
46     {}
47 
~VertexBuffer()48     ~VertexBuffer() {
49         if (mCleanupMethod) mCleanupMethod(mBuffer);
50         if (mCleanupIndexMethod) mCleanupIndexMethod(mIndices);
51     }
52 
53     /**
54        This should be the only method used by the Tessellator. Subsequent calls to
55        alloc will allocate space within the first allocation (useful if you want to
56        eventually allocate multiple regions within a single VertexBuffer, such as
57        with PathTessellator::tessellateLines())
58      */
59     template <class TYPE>
alloc(int vertexCount)60     TYPE* alloc(int vertexCount) {
61         if (mVertexCount) {
62             TYPE* reallocBuffer = (TYPE*)mReallocBuffer;
63             // already have allocated the buffer, re-allocate space within
64             if (mReallocBuffer != mBuffer) {
65                 // not first re-allocation, leave space for degenerate triangles to separate strips
66                 reallocBuffer += 2;
67             }
68             mReallocBuffer = reallocBuffer + vertexCount;
69             return reallocBuffer;
70         }
71         mAllocatedVertexCount = vertexCount;
72         mVertexCount = vertexCount;
73         mByteCount = mVertexCount * sizeof(TYPE);
74         mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
75 
76         mCleanupMethod = &(cleanup<TYPE>);
77 
78         return (TYPE*)mBuffer;
79     }
80 
81     template <class TYPE>
allocIndices(int indexCount)82     TYPE* allocIndices(int indexCount) {
83         mAllocatedIndexCount = indexCount;
84         mIndexCount = indexCount;
85         mIndices = (void*)new TYPE[indexCount];
86 
87         mCleanupIndexMethod = &(cleanup<TYPE>);
88 
89         return (TYPE*)mIndices;
90     }
91 
92     template <class TYPE>
copyInto(const VertexBuffer & srcBuffer,float xOffset,float yOffset)93     void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) {
94         int verticesToCopy = srcBuffer.getVertexCount();
95 
96         TYPE* dst = alloc<TYPE>(verticesToCopy);
97         TYPE* src = (TYPE*)srcBuffer.getBuffer();
98 
99         for (int i = 0; i < verticesToCopy; i++) {
100             TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset);
101         }
102     }
103 
104     /**
105      * Brute force bounds computation, used only if the producer of this
106      * vertex buffer can't determine bounds more simply/efficiently
107      */
108     template <class TYPE>
109     void computeBounds(int vertexCount = 0) {
110         if (!mVertexCount) {
111             mBounds.setEmpty();
112             return;
113         }
114 
115         // default: compute over every vertex
116         if (vertexCount == 0) vertexCount = mVertexCount;
117 
118         TYPE* current = (TYPE*)mBuffer;
119         TYPE* end = current + vertexCount;
120         mBounds.set(current->x, current->y, current->x, current->y);
121         for (; current < end; current++) {
122             mBounds.expandToCoverVertex(current->x, current->y);
123         }
124     }
125 
getBuffer()126     const void* getBuffer() const { return mBuffer; }
getIndices()127     const void* getIndices() const { return mIndices; }
getBounds()128     const Rect& getBounds() const { return mBounds; }
getVertexCount()129     unsigned int getVertexCount() const { return mVertexCount; }
getSize()130     unsigned int getSize() const { return mByteCount; }
getIndexCount()131     unsigned int getIndexCount() const { return mIndexCount; }
updateIndexCount(unsigned int newCount)132     void updateIndexCount(unsigned int newCount)  {
133         mIndexCount = MathUtils::min(newCount, mAllocatedIndexCount);
134     }
updateVertexCount(unsigned int newCount)135     void updateVertexCount(unsigned int newCount)  {
136         mVertexCount = MathUtils::min(newCount, mAllocatedVertexCount);
137     }
getMode()138     Mode getMode() const { return mMode; }
139 
setBounds(Rect bounds)140     void setBounds(Rect bounds) { mBounds = bounds; }
setMode(Mode mode)141     void setMode(Mode mode) { mMode = mode; }
142 
143     template <class TYPE>
createDegenerateSeparators(int allocSize)144     void createDegenerateSeparators(int allocSize) {
145         TYPE* end = (TYPE*)mBuffer + mVertexCount;
146         for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) {
147             memcpy(degen, degen - 1, sizeof(TYPE));
148             memcpy(degen + 1, degen + 2, sizeof(TYPE));
149         }
150     }
151 
152 private:
153     template <class TYPE>
cleanup(void * buffer)154     static void cleanup(void* buffer) {
155         delete[] (TYPE*)buffer;
156     }
157 
158     Rect mBounds;
159 
160     void* mBuffer;
161     void* mIndices;
162 
163     unsigned int mVertexCount;
164     unsigned int mIndexCount;
165     unsigned int mAllocatedVertexCount;
166     unsigned int mAllocatedIndexCount;
167     unsigned int mByteCount;
168 
169     Mode mMode;
170 
171     void* mReallocBuffer; // used for multi-allocation
172 
173     void (*mCleanupMethod)(void*);
174     void (*mCleanupIndexMethod)(void*);
175 };
176 
177 }; // namespace uirenderer
178 }; // namespace android
179 
180 #endif // ANDROID_HWUI_VERTEX_BUFFER_H
181