1/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkPatchUtils_DEFINED
9#define SkPatchUtils_DEFINED
10
11#include "SkColorPriv.h"
12#include "SkMatrix.h"
13
14class SK_API SkPatchUtils {
15
16public:
17    /**
18     * Structure that holds the vertex data related to the tessellation of a patch. It is passed
19     * as a parameter to the function getVertexData which sets the points, colors and texture
20     * coordinates of the vertices and the indices for them to be drawn as triangles.
21     */
22    struct VertexData {
23        int fVertexCount, fIndexCount;
24        SkPoint* fPoints;
25        SkPoint* fTexCoords;
26        uint32_t* fColors;
27        uint16_t* fIndices;
28
29        VertexData()
30        : fVertexCount(0)
31        , fIndexCount(0)
32        , fPoints(NULL)
33        , fTexCoords(NULL)
34        , fColors(NULL)
35        , fIndices(NULL) { }
36
37        ~VertexData() {
38            SkDELETE_ARRAY(fPoints);
39            SkDELETE_ARRAY(fTexCoords);
40            SkDELETE_ARRAY(fColors);
41            SkDELETE_ARRAY(fIndices);
42        }
43    };
44
45    // Enums for control points based on the order specified in the constructor (clockwise).
46    enum CubicCtrlPts {
47        kTopP0_CubicCtrlPts = 0,
48        kTopP1_CubicCtrlPts = 1,
49        kTopP2_CubicCtrlPts = 2,
50        kTopP3_CubicCtrlPts = 3,
51
52        kRightP0_CubicCtrlPts = 3,
53        kRightP1_CubicCtrlPts = 4,
54        kRightP2_CubicCtrlPts = 5,
55        kRightP3_CubicCtrlPts = 6,
56
57        kBottomP0_CubicCtrlPts = 9,
58        kBottomP1_CubicCtrlPts = 8,
59        kBottomP2_CubicCtrlPts = 7,
60        kBottomP3_CubicCtrlPts = 6,
61
62        kLeftP0_CubicCtrlPts = 0,
63        kLeftP1_CubicCtrlPts = 11,
64        kLeftP2_CubicCtrlPts = 10,
65        kLeftP3_CubicCtrlPts = 9,
66    };
67
68    // Enum for corner also clockwise.
69    enum Corner {
70        kTopLeft_Corner = 0,
71        kTopRight_Corner,
72        kBottomRight_Corner,
73        kBottomLeft_Corner
74    };
75
76    enum {
77        kNumCtrlPts = 12,
78        kNumCorners = 4,
79        kNumPtsCubic = 4
80    };
81
82    /**
83     * Method that calculates a level of detail (number of subdivisions) for a patch in both axis.
84     */
85    static SkISize GetLevelOfDetail(const SkPoint cubics[12], const SkMatrix* matrix);
86
87    /**
88     * Get the points corresponding to the top cubic of cubics.
89     */
90    static void getTopCubic(const SkPoint cubics[12], SkPoint points[4]);
91
92    /**
93     * Get the points corresponding to the bottom cubic of cubics.
94     */
95    static void getBottomCubic(const SkPoint cubics[12], SkPoint points[4]);
96
97    /**
98     * Get the points corresponding to the left cubic of cubics.
99     */
100    static void getLeftCubic(const SkPoint cubics[12], SkPoint points[4]);
101
102    /**
103     * Get the points corresponding to the right cubic of cubics.
104     */
105    static void getRightCubic(const SkPoint cubics[12], SkPoint points[4]);
106
107    /**
108     * Function that evaluates the coons patch interpolation.
109     * data refers to the pointer of the PatchData struct in which the tessellation data is set.
110     * cubics refers to the points of the cubics.
111     * lod refers the level of detail for each axis.
112     * colors refers to the corner colors that will be bilerp across the patch (optional parameter)
113     * texCoords refers to the corner texture coordinates that will be bilerp across the patch
114        (optional parameter)
115     */
116    static bool getVertexData(SkPatchUtils::VertexData* data, const SkPoint cubics[12],
117                              const SkColor colors[4], const SkPoint texCoords[4],
118                              int lodX, int lodY);
119};
120
121#endif
122