blob: 9be4d84875053131a06a96862ecee55952e9525e [file] [log] [blame]
ztenghui55bfb4e2013-12-03 10:38:55 -08001/*
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
ztenghuid5e8ade2014-08-13 15:48:02 -070020#include "utils/MathUtils.h"
ztenghui55bfb4e2013-12-03 10:38:55 -080021
22namespace android {
23namespace uirenderer {
24
25class VertexBuffer {
26public:
Chris Craik117bdbc2015-02-05 10:12:38 -080027 enum MeshFeatureFlags {
28 kNone = 0,
29 kAlpha = 1 << 0,
30 kIndices = 1 << 1,
Chris Craik05f3d6e2014-06-02 16:27:04 -070031 };
32
33 VertexBuffer()
Chris Craike84a2082014-12-22 14:28:49 -080034 : mBuffer(nullptr)
35 , mIndices(nullptr)
Chris Craik05f3d6e2014-06-02 16:27:04 -070036 , mVertexCount(0)
ztenghuid5e8ade2014-08-13 15:48:02 -070037 , mIndexCount(0)
38 , mAllocatedVertexCount(0)
39 , mAllocatedIndexCount(0)
Chris Craik05f3d6e2014-06-02 16:27:04 -070040 , mByteCount(0)
Chris Craik117bdbc2015-02-05 10:12:38 -080041 , mMeshFeatureFlags(kNone)
Chris Craike84a2082014-12-22 14:28:49 -080042 , mReallocBuffer(nullptr)
43 , mCleanupMethod(nullptr)
44 , mCleanupIndexMethod(nullptr)
ztenghui55bfb4e2013-12-03 10:38:55 -080045 {}
46
47 ~VertexBuffer() {
48 if (mCleanupMethod) mCleanupMethod(mBuffer);
ztenghuid5e8ade2014-08-13 15:48:02 -070049 if (mCleanupIndexMethod) mCleanupIndexMethod(mIndices);
ztenghui55bfb4e2013-12-03 10:38:55 -080050 }
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
Chris Craik05f3d6e2014-06-02 16:27:04 -070056 with PathTessellator::tessellateLines())
ztenghui55bfb4e2013-12-03 10:38:55 -080057 */
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 }
ztenghuid5e8ade2014-08-13 15:48:02 -070070 mAllocatedVertexCount = vertexCount;
ztenghui55bfb4e2013-12-03 10:38:55 -080071 mVertexCount = vertexCount;
Chris Craik05f3d6e2014-06-02 16:27:04 -070072 mByteCount = mVertexCount * sizeof(TYPE);
ztenghui55bfb4e2013-12-03 10:38:55 -080073 mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
Chris Craikc93e45c2014-07-16 10:15:56 -070074
ztenghui55bfb4e2013-12-03 10:38:55 -080075 mCleanupMethod = &(cleanup<TYPE>);
76
77 return (TYPE*)mBuffer;
78 }
79
80 template <class TYPE>
ztenghuid5e8ade2014-08-13 15:48:02 -070081 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>
ztenghui55bfb4e2013-12-03 10:38:55 -080092 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
Chris Craikc93e45c2014-07-16 10:15:56 -0700103 /**
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>
Chris Craik9a89bc62014-07-23 17:21:25 -0700108 void computeBounds(int vertexCount = 0) {
Chris Craikc93e45c2014-07-16 10:15:56 -0700109 if (!mVertexCount) {
110 mBounds.setEmpty();
111 return;
112 }
Chris Craik9a89bc62014-07-23 17:21:25 -0700113
114 // default: compute over every vertex
115 if (vertexCount == 0) vertexCount = mVertexCount;
116
Chris Craikc93e45c2014-07-16 10:15:56 -0700117 TYPE* current = (TYPE*)mBuffer;
Chris Craik9a89bc62014-07-23 17:21:25 -0700118 TYPE* end = current + vertexCount;
Chris Craikc93e45c2014-07-16 10:15:56 -0700119 mBounds.set(current->x, current->y, current->x, current->y);
120 for (; current < end; current++) {
121 mBounds.expandToCoverVertex(current->x, current->y);
122 }
123 }
124
ztenghui55bfb4e2013-12-03 10:38:55 -0800125 const void* getBuffer() const { return mBuffer; }
ztenghuid5e8ade2014-08-13 15:48:02 -0700126 const void* getIndices() const { return mIndices; }
Chris Craik05f3d6e2014-06-02 16:27:04 -0700127 const Rect& getBounds() const { return mBounds; }
ztenghui55bfb4e2013-12-03 10:38:55 -0800128 unsigned int getVertexCount() const { return mVertexCount; }
Chris Craik05f3d6e2014-06-02 16:27:04 -0700129 unsigned int getSize() const { return mByteCount; }
ztenghuid5e8ade2014-08-13 15:48:02 -0700130 unsigned int getIndexCount() const { return mIndexCount; }
131 void updateIndexCount(unsigned int newCount) {
132 mIndexCount = MathUtils::min(newCount, mAllocatedIndexCount);
133 }
134 void updateVertexCount(unsigned int newCount) {
ztenghui512e6432014-09-10 13:08:20 -0700135 mVertexCount = MathUtils::min(newCount, mAllocatedVertexCount);
ztenghuid5e8ade2014-08-13 15:48:02 -0700136 }
Chris Craik117bdbc2015-02-05 10:12:38 -0800137 MeshFeatureFlags getMeshFeatureFlags() const { return mMeshFeatureFlags; }
138 void setMeshFeatureFlags(int flags) {
139 mMeshFeatureFlags = static_cast<MeshFeatureFlags>(flags);
140 }
Chris Craik05f3d6e2014-06-02 16:27:04 -0700141
142 void setBounds(Rect bounds) { mBounds = bounds; }
ztenghui55bfb4e2013-12-03 10:38:55 -0800143
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
153private:
154 template <class TYPE>
155 static void cleanup(void* buffer) {
156 delete[] (TYPE*)buffer;
157 }
158
Chris Craik05f3d6e2014-06-02 16:27:04 -0700159 Rect mBounds;
ztenghuid5e8ade2014-08-13 15:48:02 -0700160
ztenghui55bfb4e2013-12-03 10:38:55 -0800161 void* mBuffer;
ztenghuid5e8ade2014-08-13 15:48:02 -0700162 void* mIndices;
163
ztenghui55bfb4e2013-12-03 10:38:55 -0800164 unsigned int mVertexCount;
ztenghuid5e8ade2014-08-13 15:48:02 -0700165 unsigned int mIndexCount;
166 unsigned int mAllocatedVertexCount;
167 unsigned int mAllocatedIndexCount;
Chris Craik05f3d6e2014-06-02 16:27:04 -0700168 unsigned int mByteCount;
ztenghuid5e8ade2014-08-13 15:48:02 -0700169
Chris Craik117bdbc2015-02-05 10:12:38 -0800170 MeshFeatureFlags mMeshFeatureFlags;
ztenghui55bfb4e2013-12-03 10:38:55 -0800171
172 void* mReallocBuffer; // used for multi-allocation
173
174 void (*mCleanupMethod)(void*);
ztenghuid5e8ade2014-08-13 15:48:02 -0700175 void (*mCleanupIndexMethod)(void*);
ztenghui55bfb4e2013-12-03 10:38:55 -0800176};
177
178}; // namespace uirenderer
179}; // namespace android
180
181#endif // ANDROID_HWUI_VERTEX_BUFFER_H