blob: 3837f88e0153589a5f9743686e3f745b9ce0f400 [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
20
21namespace android {
22namespace uirenderer {
23
24class VertexBuffer {
25public:
Chris Craik05f3d6e2014-06-02 16:27:04 -070026 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)
ztenghui55bfb4e2013-12-03 10:38:55 -080038 {}
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
Chris Craik05f3d6e2014-06-02 16:27:04 -070048 with PathTessellator::tessellateLines())
ztenghui55bfb4e2013-12-03 10:38:55 -080049 */
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;
Chris Craik05f3d6e2014-06-02 16:27:04 -070063 mByteCount = mVertexCount * sizeof(TYPE);
ztenghui55bfb4e2013-12-03 10:38:55 -080064 mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
Chris Craikc93e45c2014-07-16 10:15:56 -070065
ztenghui55bfb4e2013-12-03 10:38:55 -080066 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
Chris Craikc93e45c2014-07-16 10:15:56 -070083 /**
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>
Chris Craik9a89bc62014-07-23 17:21:25 -070088 void computeBounds(int vertexCount = 0) {
Chris Craikc93e45c2014-07-16 10:15:56 -070089 if (!mVertexCount) {
90 mBounds.setEmpty();
91 return;
92 }
Chris Craik9a89bc62014-07-23 17:21:25 -070093
94 // default: compute over every vertex
95 if (vertexCount == 0) vertexCount = mVertexCount;
96
Chris Craikc93e45c2014-07-16 10:15:56 -070097 TYPE* current = (TYPE*)mBuffer;
Chris Craik9a89bc62014-07-23 17:21:25 -070098 TYPE* end = current + vertexCount;
Chris Craikc93e45c2014-07-16 10:15:56 -070099 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
ztenghui55bfb4e2013-12-03 10:38:55 -0800105 const void* getBuffer() const { return mBuffer; }
Chris Craik05f3d6e2014-06-02 16:27:04 -0700106 const Rect& getBounds() const { return mBounds; }
ztenghui55bfb4e2013-12-03 10:38:55 -0800107 unsigned int getVertexCount() const { return mVertexCount; }
Chris Craik05f3d6e2014-06-02 16:27:04 -0700108 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; }
ztenghui55bfb4e2013-12-03 10:38:55 -0800113
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
Chris Craik05f3d6e2014-06-02 16:27:04 -0700129 Rect mBounds;
ztenghui55bfb4e2013-12-03 10:38:55 -0800130 void* mBuffer;
131 unsigned int mVertexCount;
Chris Craik05f3d6e2014-06-02 16:27:04 -0700132 unsigned int mByteCount;
133 Mode mMode;
ztenghui55bfb4e2013-12-03 10:38:55 -0800134
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