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