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_PATH_TESSELLATOR_H 18 #define ANDROID_HWUI_PATH_TESSELLATOR_H 19 20 #include <utils/Vector.h> 21 22 #include "Matrix.h" 23 #include "Rect.h" 24 #include "Vertex.h" 25 26 namespace android { 27 namespace uirenderer { 28 29 class VertexBuffer { 30 public: 31 VertexBuffer(): 32 mBuffer(0), 33 mVertexCount(0), 34 mCleanupMethod(NULL) 35 {} 36 37 ~VertexBuffer() { 38 if (mCleanupMethod) mCleanupMethod(mBuffer); 39 } 40 41 /** 42 This should be the only method used by the PathTessellator. Subsequent calls to alloc will 43 allocate space within the first allocation (useful if you want to eventually allocate 44 multiple regions within a single VertexBuffer, such as with PathTessellator::tesselateLines() 45 */ 46 template <class TYPE> 47 TYPE* alloc(int vertexCount) { 48 if (mVertexCount) { 49 TYPE* reallocBuffer = (TYPE*)mReallocBuffer; 50 // already have allocated the buffer, re-allocate space within 51 if (mReallocBuffer != mBuffer) { 52 // not first re-allocation, leave space for degenerate triangles to separate strips 53 reallocBuffer += 2; 54 } 55 mReallocBuffer = reallocBuffer + vertexCount; 56 return reallocBuffer; 57 } 58 mVertexCount = vertexCount; 59 mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount]; 60 mCleanupMethod = &(cleanup<TYPE>); 61 62 return (TYPE*)mBuffer; 63 } 64 65 template <class TYPE> 66 void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) { 67 int verticesToCopy = srcBuffer.getVertexCount(); 68 69 TYPE* dst = alloc<TYPE>(verticesToCopy); 70 TYPE* src = (TYPE*)srcBuffer.getBuffer(); 71 72 for (int i = 0; i < verticesToCopy; i++) { 73 TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset); 74 } 75 } 76 77 void* getBuffer() const { return mBuffer; } // shouldn't be const, since not a const ptr? 78 unsigned int getVertexCount() const { return mVertexCount; } 79 80 template <class TYPE> 81 void createDegenerateSeparators(int allocSize) { 82 TYPE* end = (TYPE*)mBuffer + mVertexCount; 83 for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) { 84 memcpy(degen, degen - 1, sizeof(TYPE)); 85 memcpy(degen + 1, degen + 2, sizeof(TYPE)); 86 } 87 } 88 89 private: 90 template <class TYPE> 91 static void cleanup(void* buffer) { 92 delete[] (TYPE*)buffer; 93 } 94 95 void* mBuffer; 96 unsigned int mVertexCount; 97 98 void* mReallocBuffer; // used for multi-allocation 99 100 void (*mCleanupMethod)(void*); 101 }; 102 103 class PathTessellator { 104 public: 105 static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint, bool forceExpand); 106 107 static void tessellatePath(const SkPath& path, const SkPaint* paint, 108 const mat4 *transform, VertexBuffer& vertexBuffer); 109 110 static void tessellatePoints(const float* points, int count, SkPaint* paint, 111 const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer); 112 113 static void tessellateLines(const float* points, int count, SkPaint* paint, 114 const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer); 115 116 private: 117 static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose, 118 float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex> &outputVertices); 119 120 /* 121 endpoints a & b, 122 control c 123 */ 124 static void recursiveQuadraticBezierVertices( 125 float ax, float ay, 126 float bx, float by, 127 float cx, float cy, 128 float sqrInvScaleX, float sqrInvScaleY, 129 Vector<Vertex> &outputVertices); 130 131 /* 132 endpoints p1, p2 133 control c1, c2 134 */ 135 static void recursiveCubicBezierVertices( 136 float p1x, float p1y, 137 float c1x, float c1y, 138 float p2x, float p2y, 139 float c2x, float c2y, 140 float sqrInvScaleX, float sqrInvScaleY, 141 Vector<Vertex> &outputVertices); 142 }; 143 144 }; // namespace uirenderer 145 }; // namespace android 146 147 #endif // ANDROID_HWUI_PATH_TESSELLATOR_H 148