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 #include "VertexBuffer.h"
     26 
     27 namespace android {
     28 namespace uirenderer {
     29 
     30 /**
     31  * Structure used for threshold values in outline path tessellation.
     32  *
     33  * TODO: PaintInfo should store one of this object, and initialized all values in constructor
     34  * depending on its type (point, line or path).
     35  */
     36 struct PathApproximationInfo {
     37     PathApproximationInfo(float invScaleX, float invScaleY, float pixelThreshold)
     38         : thresholdSquared(pixelThreshold * pixelThreshold)
     39         , sqrInvScaleX(invScaleX * invScaleX)
     40         , sqrInvScaleY(invScaleY * invScaleY)
     41         , thresholdForConicQuads(pixelThreshold * MathUtils::min(invScaleX, invScaleY) / 2.0f) {
     42     };
     43 
     44     const float thresholdSquared;
     45     const float sqrInvScaleX;
     46     const float sqrInvScaleY;
     47     const float thresholdForConicQuads;
     48 };
     49 
     50 class PathTessellator {
     51 public:
     52     /**
     53      * Populates scaleX and scaleY with the 'tessellation scale' of the transform - the effective X
     54      * and Y scales that tessellation will take into account when generating the 1.0 pixel thick
     55      * ramp.
     56      *
     57      * Two instances of the same shape (size, paint, etc.) will only generate the same vertices if
     58      * their tessellation scales are equal.
     59      */
     60     static void extractTessellationScales(const Matrix4& transform, float* scaleX, float* scaleY);
     61 
     62     /**
     63      * Populates a VertexBuffer with a tessellated approximation of the input convex path, as a single
     64      * triangle strip. Note: joins are not currently supported.
     65      *
     66      * @param path The path to be approximated
     67      * @param paint The paint the path will be drawn with, indicating AA, painting style
     68      *        (stroke vs fill), stroke width, stroke cap & join style, etc.
     69      * @param transform The transform the path is to be drawn with, used to drive stretch-aware path
     70      *        vertex approximation, and correct AA ramp offsetting.
     71      * @param vertexBuffer The output buffer
     72      */
     73     static void tessellatePath(const SkPath& path, const SkPaint* paint,
     74             const mat4& transform, VertexBuffer& vertexBuffer);
     75 
     76     /**
     77      * Populates a VertexBuffer with a tessellated approximation of points as a single triangle
     78      * strip (with degenerate tris separating), respecting the shape defined by the paint cap.
     79      *
     80      * @param points The center vertices of the points to be drawn
     81      * @param count The number of floats making up the point vertices
     82      * @param paint The paint the points will be drawn with indicating AA, stroke width & cap
     83      * @param transform The transform the points will be drawn with, used to drive stretch-aware path
     84      *        vertex approximation, and correct AA ramp offsetting
     85      * @param vertexBuffer The output buffer
     86      */
     87     static void tessellatePoints(const float* points, int count, const SkPaint* paint,
     88             const mat4& transform, VertexBuffer& vertexBuffer);
     89 
     90     /**
     91      * Populates a VertexBuffer with a tessellated approximation of lines as a single triangle
     92      * strip (with degenerate tris separating).
     93      *
     94      * @param points Pairs of endpoints defining the lines to be drawn
     95      * @param count The number of floats making up the line vertices
     96      * @param paint The paint the lines will be drawn with indicating AA, stroke width & cap
     97      * @param transform The transform the points will be drawn with, used to drive stretch-aware path
     98      *        vertex approximation, and correct AA ramp offsetting
     99      * @param vertexBuffer The output buffer
    100      */
    101     static void tessellateLines(const float* points, int count, const SkPaint* paint,
    102             const mat4& transform, VertexBuffer& vertexBuffer);
    103 
    104     /**
    105      * Approximates a convex outline into a clockwise Vector of 2d vertices.
    106      *
    107      * @param path The outline to be approximated
    108      * @param threshold The threshold of acceptable error (in pixels) when approximating
    109      * @param outputVertices An empty Vector which will be populated with the output
    110      */
    111     static bool approximatePathOutlineVertices(const SkPath &path, float threshold,
    112             Vector<Vertex> &outputVertices);
    113 
    114 private:
    115     static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
    116             const PathApproximationInfo& approximationInfo, Vector<Vertex> &outputVertices);
    117 
    118 /*
    119   endpoints a & b,
    120   control c
    121  */
    122     static void recursiveQuadraticBezierVertices(
    123             float ax, float ay,
    124             float bx, float by,
    125             float cx, float cy,
    126             const PathApproximationInfo& approximationInfo,
    127             Vector<Vertex> &outputVertices, int depth = 0);
    128 
    129 /*
    130   endpoints p1, p2
    131   control c1, c2
    132  */
    133     static void recursiveCubicBezierVertices(
    134             float p1x, float p1y,
    135             float c1x, float c1y,
    136             float p2x, float p2y,
    137             float c2x, float c2y,
    138             const PathApproximationInfo& approximationInfo,
    139             Vector<Vertex> &outputVertices, int depth = 0);
    140 };
    141 
    142 }; // namespace uirenderer
    143 }; // namespace android
    144 
    145 #endif // ANDROID_HWUI_PATH_TESSELLATOR_H
    146