Home | History | Annotate | Download | only in hwui
      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         mSize(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 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 
     65     void* getBuffer() const { return mBuffer; }
     66     unsigned int getSize() const { return mSize; }
     67 
     68     template <class TYPE>
     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>
     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