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 
14 class SK_API SkPatchUtils {
15 
16 public:
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 
VertexDataVertexData29         VertexData()
30         : fVertexCount(0)
31         , fIndexCount(0)
32         , fPoints(nullptr)
33         , fTexCoords(nullptr)
34         , fColors(nullptr)
35         , fIndices(nullptr) { }
36 
~VertexDataVertexData37         ~VertexData() {
38             delete[] fPoints;
39             delete[] fTexCoords;
40             delete[] fColors;
41             delete[] 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