OSDN Git Service

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