1 /*
2  * Copyright (C) 2015 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_GLOP_H
18 #define ANDROID_HWUI_GLOP_H
19 
20 #include "FloatColor.h"
21 #include "Matrix.h"
22 #include "Program.h"
23 #include "Rect.h"
24 #include "SkiaShader.h"
25 #include "utils/Macros.h"
26 
27 #include <GLES2/gl2.h>
28 #include <GLES2/gl2ext.h>
29 #include <SkXfermode.h>
30 
31 namespace android {
32 namespace uirenderer {
33 
34 class Program;
35 class RoundRectClipState;
36 class Texture;
37 
38 /*
39  * Enumerates optional vertex attributes
40  *
41  * Position is always enabled by MeshState, these other attributes
42  * are enabled/disabled dynamically based on mesh content.
43  */
44 
45 namespace VertexAttribFlags {
46     enum {
47         None = 0,
48         TextureCoord = 1 << 0,
49         Color = 1 << 1,
50         Alpha = 1 << 2,
51     };
52 };
53 
54 /*
55  * Enumerates transform features
56  */
57 namespace TransformFlags {
58     enum {
59         None = 0,
60 
61         // offset the eventual drawing matrix by a tiny amount to
62         // disambiguate sampling patterns with non-AA rendering
63         OffsetByFudgeFactor = 1 << 0,
64 
65         // Canvas transform isn't applied to the mesh at draw time,
66         //since it's already built in.
67         MeshIgnoresCanvasTransform = 1 << 1,
68     };
69 };
70 
71 /**
72  * Structure containing all data required to issue an OpenGL draw
73  *
74  * Includes all of the mesh, fill, and GL state required to perform
75  * the operation. Pieces of data are either directly copied into the
76  * structure, or stored as a pointer or GL object reference to data
77  * managed.
78  *
79  * Eventually, a Glop should be able to be drawn multiple times from
80  * a single construction, up until GL context destruction. Currently,
81  * vertex/index/Texture/RoundRectClipState pointers prevent this from
82  * being safe.
83  */
84 // TODO: PREVENT_COPY_AND_ASSIGN(...) or similar
85 struct Glop {
86     struct Mesh {
87         GLuint primitiveMode; // GL_TRIANGLES and GL_TRIANGLE_STRIP supported
88 
89         // buffer object and void* are mutually exclusive.
90         // Only GL_UNSIGNED_SHORT supported.
91         struct Indices {
92             GLuint bufferObject;
93             const void* indices;
94         } indices;
95 
96         // buffer object and void*s are mutually exclusive.
97         // TODO: enforce mutual exclusion with restricted setters and/or unions
98         struct Vertices {
99             GLuint bufferObject;
100             int attribFlags;
101             const void* position;
102             const void* texCoord;
103             const void* color;
104             GLsizei stride;
105         } vertices;
106 
107         int elementCount;
108         TextureVertex mappedVertices[4];
109     } mesh;
110 
111     struct Fill {
112         Program* program;
113 
114         struct TextureData {
115             Texture* texture;
116             GLenum target;
117             GLenum filter;
118             GLenum clamp;
119             Matrix4* textureTransform;
120         } texture;
121 
122         bool colorEnabled;
123         FloatColor color;
124 
125         ProgramDescription::ColorFilterMode filterMode;
126         union Filter {
127             struct Matrix {
128                 float matrix[16];
129                 float vector[4];
130             } matrix;
131             FloatColor color;
132         } filter;
133 
134         SkiaShaderData skiaShaderData;
135     } fill;
136 
137     struct Transform {
138         // Orthographic projection matrix for current FBO
139         // TODO: move out of Glop, since this is static per FBO
140         Matrix4 ortho;
141 
142         // modelView transform, accounting for delta between mesh transform and content of the mesh
143         // often represents x/y offsets within command, or scaling for mesh unit size
144         Matrix4 modelView;
145 
146         // Canvas transform of Glop - not necessarily applied to geometry (see flags)
147         Matrix4 canvas;
148         int transformFlags;
149 
meshTransformGlop::Transform150        const Matrix4& meshTransform() const {
151            return (transformFlags & TransformFlags::MeshIgnoresCanvasTransform)
152                    ? Matrix4::identity() : canvas;
153        }
154     } transform;
155 
156     const RoundRectClipState* roundRectClipState;
157 
158     /**
159      * Blending to be used by this draw - both GL_NONE if blending is disabled.
160      *
161      * Defined by fill step, but can be force-enabled by presence of kAlpha_Attrib
162      */
163     struct Blend {
164         GLenum src;
165         GLenum dst;
166     } blend;
167 
168     /**
169      * Bounds of the drawing command in layer space. Only mapped into layer
170      * space once GlopBuilder::build() is called.
171      */
172     Rect bounds;
173 
174     /**
175      * Additional render state to enumerate:
176      * - scissor + (bits for whether each of LTRB needed?)
177      * - stencil mode (draw into, mask, count, etc)
178      */
179 };
180 
181 } /* namespace uirenderer */
182 } /* namespace android */
183 
184 #endif // ANDROID_HWUI_GLOP_H
185