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