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        None = 0,
48        TextureCoord = 1 << 0,
49        Color = 1 << 1,
50        Alpha = 1 << 2,
51    };
52};
53
54/*
55 * Enumerates transform features
56 */
57namespace 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
85struct 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
150       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