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: VertexBuffer()31 VertexBuffer(): 32 mBuffer(0), 33 mSize(0), 34 mCleanupMethod(NULL) 35 {} 36 ~VertexBuffer()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> alloc(int size)47 TYPE* alloc(int size) { 48 if (mSize) { 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 + size; 56 return reallocBuffer; 57 } 58 mSize = size; 59 mReallocBuffer = mBuffer = (void*)new TYPE[size]; 60 mCleanupMethod = &(cleanup<TYPE>); 61 62 return (TYPE*)mBuffer; 63 } 64 getBuffer()65 void* getBuffer() const { return mBuffer; } getSize()66 unsigned int getSize() const { return mSize; } 67 68 template <class TYPE> createDegenerateSeparators(int allocSize)69 void createDegenerateSeparators(int allocSize) { 70 TYPE* end = (TYPE*)mBuffer + mSize; 71 for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) { 72 memcpy(degen, degen - 1, sizeof(TYPE)); 73 memcpy(degen + 1, degen + 2, sizeof(TYPE)); 74 } 75 } 76 77 private: 78 template <class TYPE> cleanup(void * buffer)79 static void cleanup(void* buffer) { 80 delete[] (TYPE*)buffer; 81 } 82 83 void* mBuffer; 84 unsigned int mSize; 85 86 void* mReallocBuffer; // used for multi-allocation 87 88 void (*mCleanupMethod)(void*); 89 }; 90 91 class PathTessellator { 92 public: 93 static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint, bool forceExpand); 94 95 static void tessellatePath(const SkPath& path, const SkPaint* paint, 96 const mat4 *transform, VertexBuffer& vertexBuffer); 97 98 static void tessellateLines(const float* points, int count, SkPaint* paint, 99 const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer); 100 101 private: 102 static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose, 103 float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex> &outputVertices); 104 105 /* 106 endpoints a & b, 107 control c 108 */ 109 static void recursiveQuadraticBezierVertices( 110 float ax, float ay, 111 float bx, float by, 112 float cx, float cy, 113 float sqrInvScaleX, float sqrInvScaleY, 114 Vector<Vertex> &outputVertices); 115 116 /* 117 endpoints p1, p2 118 control c1, c2 119 */ 120 static void recursiveCubicBezierVertices( 121 float p1x, float p1y, 122 float c1x, float c1y, 123 float p2x, float p2y, 124 float c2x, float c2y, 125 float sqrInvScaleX, float sqrInvScaleY, 126 Vector<Vertex> &outputVertices); 127 }; 128 129 }; // namespace uirenderer 130 }; // namespace android 131 132 #endif // ANDROID_HWUI_PATH_TESSELLATOR_H 133