VertexBuffer.h revision 9a89bc6524620c87c7a321433470c668e2b95d69
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 21namespace android { 22namespace uirenderer { 23 24class VertexBuffer { 25public: 26 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) 38 {} 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 48 with PathTessellator::tessellateLines()) 49 */ 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; 63 mByteCount = mVertexCount * sizeof(TYPE); 64 mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount]; 65 66 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 83 /** 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> 88 void computeBounds(int vertexCount = 0) { 89 if (!mVertexCount) { 90 mBounds.setEmpty(); 91 return; 92 } 93 94 // default: compute over every vertex 95 if (vertexCount == 0) vertexCount = mVertexCount; 96 97 TYPE* current = (TYPE*)mBuffer; 98 TYPE* end = current + vertexCount; 99 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 105 const void* getBuffer() const { return mBuffer; } 106 const Rect& getBounds() const { return mBounds; } 107 unsigned int getVertexCount() const { return mVertexCount; } 108 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; } 113 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 129 Rect mBounds; 130 void* mBuffer; 131 unsigned int mVertexCount; 132 unsigned int mByteCount; 133 Mode mMode; 134 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 144