155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui/* 255bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * Copyright (C) 2012 The Android Open Source Project 355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * 455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * Licensed under the Apache License, Version 2.0 (the "License"); 555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * you may not use this file except in compliance with the License. 655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * You may obtain a copy of the License at 755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * 855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * http://www.apache.org/licenses/LICENSE-2.0 955bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * 1055bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * Unless required by applicable law or agreed to in writing, software 1155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * distributed under the License is distributed on an "AS IS" BASIS, 1255bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * See the License for the specific language governing permissions and 1455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui * limitations under the License. 1555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui */ 1655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 1755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui#ifndef ANDROID_HWUI_VERTEX_BUFFER_H 1855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui#define ANDROID_HWUI_VERTEX_BUFFER_H 1955bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 209db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik#include <algorithm> 2155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 2255bfb4e728fe1db619af5d2c287f4abe711b3343ztenghuinamespace android { 2355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghuinamespace uirenderer { 2455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 2555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghuiclass VertexBuffer { 2655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghuipublic: 27117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik enum MeshFeatureFlags { 28117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik kNone = 0, 29117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik kAlpha = 1 << 0, 30117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik kIndices = 1 << 1, 3105f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik }; 3205f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik 3305f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik VertexBuffer() 34e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik : mBuffer(nullptr) 35e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik , mIndices(nullptr) 3605f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik , mVertexCount(0) 37d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui , mIndexCount(0) 38d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui , mAllocatedVertexCount(0) 39d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui , mAllocatedIndexCount(0) 4005f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik , mByteCount(0) 41117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik , mMeshFeatureFlags(kNone) 42e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik , mReallocBuffer(nullptr) 43e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik , mCleanupMethod(nullptr) 44e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik , mCleanupIndexMethod(nullptr) 4555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui {} 4655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 4755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui ~VertexBuffer() { 4855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui if (mCleanupMethod) mCleanupMethod(mBuffer); 49d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui if (mCleanupIndexMethod) mCleanupIndexMethod(mIndices); 5055bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui } 5155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 5255bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui /** 5355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui This should be the only method used by the Tessellator. Subsequent calls to 5455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui alloc will allocate space within the first allocation (useful if you want to 5555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui eventually allocate multiple regions within a single VertexBuffer, such as 5605f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik with PathTessellator::tessellateLines()) 5755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui */ 5855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui template <class TYPE> 5955bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui TYPE* alloc(int vertexCount) { 6055bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui if (mVertexCount) { 6155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui TYPE* reallocBuffer = (TYPE*)mReallocBuffer; 6255bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui // already have allocated the buffer, re-allocate space within 6355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui if (mReallocBuffer != mBuffer) { 6455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui // not first re-allocation, leave space for degenerate triangles to separate strips 6555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui reallocBuffer += 2; 6655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui } 6755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui mReallocBuffer = reallocBuffer + vertexCount; 6855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui return reallocBuffer; 6955bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui } 70d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui mAllocatedVertexCount = vertexCount; 7155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui mVertexCount = vertexCount; 7205f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik mByteCount = mVertexCount * sizeof(TYPE); 7355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount]; 74c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik 7555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui mCleanupMethod = &(cleanup<TYPE>); 7655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 7755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui return (TYPE*)mBuffer; 7855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui } 7955bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 8055bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui template <class TYPE> 81d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui TYPE* allocIndices(int indexCount) { 82d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui mAllocatedIndexCount = indexCount; 83d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui mIndexCount = indexCount; 84d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui mIndices = (void*)new TYPE[indexCount]; 85d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui 86d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui mCleanupIndexMethod = &(cleanup<TYPE>); 87d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui 88d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui return (TYPE*)mIndices; 89d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui } 90d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui 91d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui template <class TYPE> 9255bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) { 9355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui int verticesToCopy = srcBuffer.getVertexCount(); 9455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 9555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui TYPE* dst = alloc<TYPE>(verticesToCopy); 9655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui TYPE* src = (TYPE*)srcBuffer.getBuffer(); 9755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 9855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui for (int i = 0; i < verticesToCopy; i++) { 9955bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset); 10055bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui } 10155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui } 10255bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 103c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik /** 104c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik * Brute force bounds computation, used only if the producer of this 105c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik * vertex buffer can't determine bounds more simply/efficiently 106c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik */ 107c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik template <class TYPE> 1089a89bc6524620c87c7a321433470c668e2b95d69Chris Craik void computeBounds(int vertexCount = 0) { 109c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik if (!mVertexCount) { 110c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik mBounds.setEmpty(); 111c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik return; 112c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik } 1139a89bc6524620c87c7a321433470c668e2b95d69Chris Craik 1149a89bc6524620c87c7a321433470c668e2b95d69Chris Craik // default: compute over every vertex 1159a89bc6524620c87c7a321433470c668e2b95d69Chris Craik if (vertexCount == 0) vertexCount = mVertexCount; 1169a89bc6524620c87c7a321433470c668e2b95d69Chris Craik 117c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik TYPE* current = (TYPE*)mBuffer; 1189a89bc6524620c87c7a321433470c668e2b95d69Chris Craik TYPE* end = current + vertexCount; 119c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik mBounds.set(current->x, current->y, current->x, current->y); 120c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik for (; current < end; current++) { 12115c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik mBounds.expandToCover(current->x, current->y); 122c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik } 123c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik } 124c93e45cf045f41aea95f856173e4043d988a5a5cChris Craik 12555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui const void* getBuffer() const { return mBuffer; } 126d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui const void* getIndices() const { return mIndices; } 12705f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik const Rect& getBounds() const { return mBounds; } 12855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui unsigned int getVertexCount() const { return mVertexCount; } 12905f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik unsigned int getSize() const { return mByteCount; } 130d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui unsigned int getIndexCount() const { return mIndexCount; } 131d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui void updateIndexCount(unsigned int newCount) { 1329db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik mIndexCount = std::min(newCount, mAllocatedIndexCount); 133d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui } 134d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui void updateVertexCount(unsigned int newCount) { 1359db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik mVertexCount = std::min(newCount, mAllocatedVertexCount); 136d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui } 137117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik MeshFeatureFlags getMeshFeatureFlags() const { return mMeshFeatureFlags; } 138117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik void setMeshFeatureFlags(int flags) { 139117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik mMeshFeatureFlags = static_cast<MeshFeatureFlags>(flags); 140117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik } 14105f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik 14205f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik void setBounds(Rect bounds) { mBounds = bounds; } 14355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 14455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui template <class TYPE> 14555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui void createDegenerateSeparators(int allocSize) { 14655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui TYPE* end = (TYPE*)mBuffer + mVertexCount; 14755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) { 14855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui memcpy(degen, degen - 1, sizeof(TYPE)); 14955bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui memcpy(degen + 1, degen + 2, sizeof(TYPE)); 15055bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui } 15155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui } 15255bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 15355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghuiprivate: 15455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui template <class TYPE> 15555bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui static void cleanup(void* buffer) { 15655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui delete[] (TYPE*)buffer; 15755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui } 15855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 15905f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik Rect mBounds; 160d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui 16155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui void* mBuffer; 162d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui void* mIndices; 163d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui 16455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui unsigned int mVertexCount; 165d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui unsigned int mIndexCount; 166d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui unsigned int mAllocatedVertexCount; 167d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui unsigned int mAllocatedIndexCount; 16805f3d6e5111fd08df5cd9aae2c3d28399dc0e7f5Chris Craik unsigned int mByteCount; 169d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui 170117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik MeshFeatureFlags mMeshFeatureFlags; 17155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 17255bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui void* mReallocBuffer; // used for multi-allocation 17355bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 17455bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui void (*mCleanupMethod)(void*); 175d5e8ade498b41b42874273cbfa375aed7b4d6a08ztenghui void (*mCleanupIndexMethod)(void*); 17655bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui}; 17755bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 17855bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui}; // namespace uirenderer 17955bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui}; // namespace android 18055bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui 18155bfb4e728fe1db619af5d2c287f4abe711b3343ztenghui#endif // ANDROID_HWUI_VERTEX_BUFFER_H 182