1*d57664e9SAndroid Build Coastguard Worker /* 2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2012 The Android Open Source Project 3*d57664e9SAndroid Build Coastguard Worker * 4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*d57664e9SAndroid Build Coastguard Worker * 8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*d57664e9SAndroid Build Coastguard Worker * 10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*d57664e9SAndroid Build Coastguard Worker * limitations under the License. 15*d57664e9SAndroid Build Coastguard Worker */ 16*d57664e9SAndroid Build Coastguard Worker 17*d57664e9SAndroid Build Coastguard Worker #ifndef ANDROID_HWUI_VERTEX_BUFFER_H 18*d57664e9SAndroid Build Coastguard Worker #define ANDROID_HWUI_VERTEX_BUFFER_H 19*d57664e9SAndroid Build Coastguard Worker 20*d57664e9SAndroid Build Coastguard Worker #include <algorithm> 21*d57664e9SAndroid Build Coastguard Worker 22*d57664e9SAndroid Build Coastguard Worker namespace android { 23*d57664e9SAndroid Build Coastguard Worker namespace uirenderer { 24*d57664e9SAndroid Build Coastguard Worker 25*d57664e9SAndroid Build Coastguard Worker class VertexBuffer { 26*d57664e9SAndroid Build Coastguard Worker public: 27*d57664e9SAndroid Build Coastguard Worker enum MeshFeatureFlags { 28*d57664e9SAndroid Build Coastguard Worker kNone = 0, 29*d57664e9SAndroid Build Coastguard Worker kAlpha = 1 << 0, 30*d57664e9SAndroid Build Coastguard Worker kIndices = 1 << 1, 31*d57664e9SAndroid Build Coastguard Worker }; 32*d57664e9SAndroid Build Coastguard Worker VertexBuffer()33*d57664e9SAndroid Build Coastguard Worker VertexBuffer() 34*d57664e9SAndroid Build Coastguard Worker : mBuffer(nullptr) 35*d57664e9SAndroid Build Coastguard Worker , mIndices(nullptr) 36*d57664e9SAndroid Build Coastguard Worker , mVertexCount(0) 37*d57664e9SAndroid Build Coastguard Worker , mIndexCount(0) 38*d57664e9SAndroid Build Coastguard Worker , mAllocatedVertexCount(0) 39*d57664e9SAndroid Build Coastguard Worker , mAllocatedIndexCount(0) 40*d57664e9SAndroid Build Coastguard Worker , mByteCount(0) 41*d57664e9SAndroid Build Coastguard Worker , mMeshFeatureFlags(kNone) 42*d57664e9SAndroid Build Coastguard Worker , mReallocBuffer(nullptr) 43*d57664e9SAndroid Build Coastguard Worker , mCleanupMethod(nullptr) 44*d57664e9SAndroid Build Coastguard Worker , mCleanupIndexMethod(nullptr) {} 45*d57664e9SAndroid Build Coastguard Worker ~VertexBuffer()46*d57664e9SAndroid Build Coastguard Worker ~VertexBuffer() { 47*d57664e9SAndroid Build Coastguard Worker if (mCleanupMethod) mCleanupMethod(mBuffer); 48*d57664e9SAndroid Build Coastguard Worker if (mCleanupIndexMethod) mCleanupIndexMethod(mIndices); 49*d57664e9SAndroid Build Coastguard Worker } 50*d57664e9SAndroid Build Coastguard Worker 51*d57664e9SAndroid Build Coastguard Worker /** 52*d57664e9SAndroid Build Coastguard Worker This should be the only method used by the Tessellator. Subsequent calls to 53*d57664e9SAndroid Build Coastguard Worker alloc will allocate space within the first allocation (useful if you want to 54*d57664e9SAndroid Build Coastguard Worker eventually allocate multiple regions within a single VertexBuffer, such as 55*d57664e9SAndroid Build Coastguard Worker with PathTessellator::tessellateLines()) 56*d57664e9SAndroid Build Coastguard Worker */ 57*d57664e9SAndroid Build Coastguard Worker template <class TYPE> alloc(int vertexCount)58*d57664e9SAndroid Build Coastguard Worker TYPE* alloc(int vertexCount) { 59*d57664e9SAndroid Build Coastguard Worker if (mVertexCount) { 60*d57664e9SAndroid Build Coastguard Worker TYPE* reallocBuffer = (TYPE*)mReallocBuffer; 61*d57664e9SAndroid Build Coastguard Worker // already have allocated the buffer, re-allocate space within 62*d57664e9SAndroid Build Coastguard Worker if (mReallocBuffer != mBuffer) { 63*d57664e9SAndroid Build Coastguard Worker // not first re-allocation, leave space for degenerate triangles to separate strips 64*d57664e9SAndroid Build Coastguard Worker reallocBuffer += 2; 65*d57664e9SAndroid Build Coastguard Worker } 66*d57664e9SAndroid Build Coastguard Worker mReallocBuffer = reallocBuffer + vertexCount; 67*d57664e9SAndroid Build Coastguard Worker return reallocBuffer; 68*d57664e9SAndroid Build Coastguard Worker } 69*d57664e9SAndroid Build Coastguard Worker mAllocatedVertexCount = vertexCount; 70*d57664e9SAndroid Build Coastguard Worker mVertexCount = vertexCount; 71*d57664e9SAndroid Build Coastguard Worker mByteCount = mVertexCount * sizeof(TYPE); 72*d57664e9SAndroid Build Coastguard Worker mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount]; 73*d57664e9SAndroid Build Coastguard Worker 74*d57664e9SAndroid Build Coastguard Worker mCleanupMethod = &(cleanup<TYPE>); 75*d57664e9SAndroid Build Coastguard Worker 76*d57664e9SAndroid Build Coastguard Worker return (TYPE*)mBuffer; 77*d57664e9SAndroid Build Coastguard Worker } 78*d57664e9SAndroid Build Coastguard Worker 79*d57664e9SAndroid Build Coastguard Worker template <class TYPE> allocIndices(int indexCount)80*d57664e9SAndroid Build Coastguard Worker TYPE* allocIndices(int indexCount) { 81*d57664e9SAndroid Build Coastguard Worker mAllocatedIndexCount = indexCount; 82*d57664e9SAndroid Build Coastguard Worker mIndexCount = indexCount; 83*d57664e9SAndroid Build Coastguard Worker mIndices = (void*)new TYPE[indexCount]; 84*d57664e9SAndroid Build Coastguard Worker 85*d57664e9SAndroid Build Coastguard Worker mCleanupIndexMethod = &(cleanup<TYPE>); 86*d57664e9SAndroid Build Coastguard Worker 87*d57664e9SAndroid Build Coastguard Worker return (TYPE*)mIndices; 88*d57664e9SAndroid Build Coastguard Worker } 89*d57664e9SAndroid Build Coastguard Worker 90*d57664e9SAndroid Build Coastguard Worker template <class TYPE> copyInto(const VertexBuffer & srcBuffer,float xOffset,float yOffset)91*d57664e9SAndroid Build Coastguard Worker void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) { 92*d57664e9SAndroid Build Coastguard Worker int verticesToCopy = srcBuffer.getVertexCount(); 93*d57664e9SAndroid Build Coastguard Worker 94*d57664e9SAndroid Build Coastguard Worker TYPE* dst = alloc<TYPE>(verticesToCopy); 95*d57664e9SAndroid Build Coastguard Worker TYPE* src = (TYPE*)srcBuffer.getBuffer(); 96*d57664e9SAndroid Build Coastguard Worker 97*d57664e9SAndroid Build Coastguard Worker for (int i = 0; i < verticesToCopy; i++) { 98*d57664e9SAndroid Build Coastguard Worker TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset); 99*d57664e9SAndroid Build Coastguard Worker } 100*d57664e9SAndroid Build Coastguard Worker } 101*d57664e9SAndroid Build Coastguard Worker 102*d57664e9SAndroid Build Coastguard Worker /** 103*d57664e9SAndroid Build Coastguard Worker * Brute force bounds computation, used only if the producer of this 104*d57664e9SAndroid Build Coastguard Worker * vertex buffer can't determine bounds more simply/efficiently 105*d57664e9SAndroid Build Coastguard Worker */ 106*d57664e9SAndroid Build Coastguard Worker template <class TYPE> 107*d57664e9SAndroid Build Coastguard Worker void computeBounds(int vertexCount = 0) { 108*d57664e9SAndroid Build Coastguard Worker if (!mVertexCount) { 109*d57664e9SAndroid Build Coastguard Worker mBounds.setEmpty(); 110*d57664e9SAndroid Build Coastguard Worker return; 111*d57664e9SAndroid Build Coastguard Worker } 112*d57664e9SAndroid Build Coastguard Worker 113*d57664e9SAndroid Build Coastguard Worker // default: compute over every vertex 114*d57664e9SAndroid Build Coastguard Worker if (vertexCount == 0) vertexCount = mVertexCount; 115*d57664e9SAndroid Build Coastguard Worker 116*d57664e9SAndroid Build Coastguard Worker TYPE* current = (TYPE*)mBuffer; 117*d57664e9SAndroid Build Coastguard Worker TYPE* end = current + vertexCount; 118*d57664e9SAndroid Build Coastguard Worker mBounds.set(current->x, current->y, current->x, current->y); 119*d57664e9SAndroid Build Coastguard Worker for (; current < end; current++) { 120*d57664e9SAndroid Build Coastguard Worker mBounds.expandToCover(current->x, current->y); 121*d57664e9SAndroid Build Coastguard Worker } 122*d57664e9SAndroid Build Coastguard Worker } 123*d57664e9SAndroid Build Coastguard Worker getBuffer()124*d57664e9SAndroid Build Coastguard Worker const void* getBuffer() const { return mBuffer; } getIndices()125*d57664e9SAndroid Build Coastguard Worker const void* getIndices() const { return mIndices; } getBounds()126*d57664e9SAndroid Build Coastguard Worker const Rect& getBounds() const { return mBounds; } getVertexCount()127*d57664e9SAndroid Build Coastguard Worker unsigned int getVertexCount() const { return mVertexCount; } getSize()128*d57664e9SAndroid Build Coastguard Worker unsigned int getSize() const { return mByteCount; } getIndexCount()129*d57664e9SAndroid Build Coastguard Worker unsigned int getIndexCount() const { return mIndexCount; } updateIndexCount(unsigned int newCount)130*d57664e9SAndroid Build Coastguard Worker void updateIndexCount(unsigned int newCount) { 131*d57664e9SAndroid Build Coastguard Worker mIndexCount = std::min(newCount, mAllocatedIndexCount); 132*d57664e9SAndroid Build Coastguard Worker } updateVertexCount(unsigned int newCount)133*d57664e9SAndroid Build Coastguard Worker void updateVertexCount(unsigned int newCount) { 134*d57664e9SAndroid Build Coastguard Worker mVertexCount = std::min(newCount, mAllocatedVertexCount); 135*d57664e9SAndroid Build Coastguard Worker } getMeshFeatureFlags()136*d57664e9SAndroid Build Coastguard Worker MeshFeatureFlags getMeshFeatureFlags() const { return mMeshFeatureFlags; } setMeshFeatureFlags(int flags)137*d57664e9SAndroid Build Coastguard Worker void setMeshFeatureFlags(int flags) { 138*d57664e9SAndroid Build Coastguard Worker mMeshFeatureFlags = static_cast<MeshFeatureFlags>(flags); 139*d57664e9SAndroid Build Coastguard Worker } 140*d57664e9SAndroid Build Coastguard Worker setBounds(Rect bounds)141*d57664e9SAndroid Build Coastguard Worker void setBounds(Rect bounds) { mBounds = bounds; } 142*d57664e9SAndroid Build Coastguard Worker 143*d57664e9SAndroid Build Coastguard Worker template <class TYPE> createDegenerateSeparators(int allocSize)144*d57664e9SAndroid Build Coastguard Worker void createDegenerateSeparators(int allocSize) { 145*d57664e9SAndroid Build Coastguard Worker TYPE* end = (TYPE*)mBuffer + mVertexCount; 146*d57664e9SAndroid Build Coastguard Worker for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) { 147*d57664e9SAndroid Build Coastguard Worker memcpy(degen, degen - 1, sizeof(TYPE)); 148*d57664e9SAndroid Build Coastguard Worker memcpy(degen + 1, degen + 2, sizeof(TYPE)); 149*d57664e9SAndroid Build Coastguard Worker } 150*d57664e9SAndroid Build Coastguard Worker } 151*d57664e9SAndroid Build Coastguard Worker 152*d57664e9SAndroid Build Coastguard Worker private: 153*d57664e9SAndroid Build Coastguard Worker template <class TYPE> cleanup(void * buffer)154*d57664e9SAndroid Build Coastguard Worker static void cleanup(void* buffer) { 155*d57664e9SAndroid Build Coastguard Worker delete[](TYPE*) buffer; 156*d57664e9SAndroid Build Coastguard Worker } 157*d57664e9SAndroid Build Coastguard Worker 158*d57664e9SAndroid Build Coastguard Worker Rect mBounds; 159*d57664e9SAndroid Build Coastguard Worker 160*d57664e9SAndroid Build Coastguard Worker void* mBuffer; 161*d57664e9SAndroid Build Coastguard Worker void* mIndices; 162*d57664e9SAndroid Build Coastguard Worker 163*d57664e9SAndroid Build Coastguard Worker unsigned int mVertexCount; 164*d57664e9SAndroid Build Coastguard Worker unsigned int mIndexCount; 165*d57664e9SAndroid Build Coastguard Worker unsigned int mAllocatedVertexCount; 166*d57664e9SAndroid Build Coastguard Worker unsigned int mAllocatedIndexCount; 167*d57664e9SAndroid Build Coastguard Worker unsigned int mByteCount; 168*d57664e9SAndroid Build Coastguard Worker 169*d57664e9SAndroid Build Coastguard Worker MeshFeatureFlags mMeshFeatureFlags; 170*d57664e9SAndroid Build Coastguard Worker 171*d57664e9SAndroid Build Coastguard Worker void* mReallocBuffer; // used for multi-allocation 172*d57664e9SAndroid Build Coastguard Worker 173*d57664e9SAndroid Build Coastguard Worker void (*mCleanupMethod)(void*); 174*d57664e9SAndroid Build Coastguard Worker void (*mCleanupIndexMethod)(void*); 175*d57664e9SAndroid Build Coastguard Worker }; 176*d57664e9SAndroid Build Coastguard Worker 177*d57664e9SAndroid Build Coastguard Worker } // namespace uirenderer 178*d57664e9SAndroid Build Coastguard Worker } // namespace android 179*d57664e9SAndroid Build Coastguard Worker 180*d57664e9SAndroid Build Coastguard Worker #endif // ANDROID_HWUI_VERTEX_BUFFER_H 181