Layer.h revision d3448e437ac247e96455014e95f15a3ddd5cb328
1/*
2 * Copyright (C) 2010 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_LAYER_H
18#define ANDROID_HWUI_LAYER_H
19
20#include <sys/types.h>
21
22#include <GLES2/gl2.h>
23
24#include <ui/Region.h>
25
26#include <SkPaint.h>
27#include <SkXfermode.h>
28
29#include "Rect.h"
30#include "RenderBuffer.h"
31#include "SkiaColorFilter.h"
32#include "Texture.h"
33#include "Vertex.h"
34
35namespace android {
36namespace uirenderer {
37
38///////////////////////////////////////////////////////////////////////////////
39// Layers
40///////////////////////////////////////////////////////////////////////////////
41
42// Forward declarations
43class Caches;
44class OpenGLRenderer;
45class DisplayList;
46class DeferredDisplayList;
47struct DeferStateStruct;
48
49/**
50 * A layer has dimensions and is backed by an OpenGL texture or FBO.
51 */
52struct Layer {
53    Layer(const uint32_t layerWidth, const uint32_t layerHeight);
54    ~Layer();
55
56    static uint32_t computeIdealWidth(uint32_t layerWidth);
57    static uint32_t computeIdealHeight(uint32_t layerHeight);
58
59    /**
60     * Calling this method will remove (either by recycling or
61     * destroying) the associated FBO, if present, and any render
62     * buffer (stencil for instance.)
63     */
64    void removeFbo(bool flush = true);
65
66    /**
67     * Sets this layer's region to a rectangle. Computes the appropriate
68     * texture coordinates.
69     */
70    void setRegionAsRect() {
71        const android::Rect& bounds = region.getBounds();
72        regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
73               bounds.rightBottom().x, bounds.rightBottom().y);
74
75        const float texX = 1.0f / float(texture.width);
76        const float texY = 1.0f / float(texture.height);
77        const float height = layer.getHeight();
78        texCoords.set(
79               regionRect.left * texX, (height - regionRect.top) * texY,
80               regionRect.right * texX, (height - regionRect.bottom) * texY);
81
82        regionRect.translate(layer.left, layer.top);
83    }
84
85    void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
86            int left, int top, int right, int bottom) {
87        this->renderer = renderer;
88        this->displayList = displayList;
89        const Rect r(left, top, right, bottom);
90        dirtyRect.unionWith(r);
91        deferredUpdateScheduled = true;
92    }
93
94    inline uint32_t getWidth() const {
95        return texture.width;
96    }
97
98    inline uint32_t getHeight() const {
99        return texture.height;
100    }
101
102    /**
103     * Resize the layer and its texture if needed.
104     *
105     * @param width The new width of the layer
106     * @param height The new height of the layer
107     *
108     * @return True if the layer was resized or nothing happened, false if
109     *         a failure occurred during the resizing operation
110     */
111    bool resize(const uint32_t width, const uint32_t height);
112
113    void setSize(uint32_t width, uint32_t height) {
114        texture.width = width;
115        texture.height = height;
116    }
117
118    ANDROID_API void setPaint(SkPaint* paint);
119
120    inline void setBlend(bool blend) {
121        texture.blend = blend;
122    }
123
124    inline bool isBlend() const {
125        return texture.blend;
126    }
127
128    inline void setAlpha(int alpha) {
129        this->alpha = alpha;
130    }
131
132    inline void setAlpha(int alpha, SkXfermode::Mode mode) {
133        this->alpha = alpha;
134        this->mode = mode;
135    }
136
137    inline int getAlpha() const {
138        return alpha;
139    }
140
141    inline SkXfermode::Mode getMode() const {
142        return mode;
143    }
144
145    inline void setEmpty(bool empty) {
146        this->empty = empty;
147    }
148
149    inline bool isEmpty() const {
150        return empty;
151    }
152
153    inline void setFbo(GLuint fbo) {
154        this->fbo = fbo;
155    }
156
157    inline GLuint getFbo() const {
158        return fbo;
159    }
160
161    inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) {
162        if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) {
163            this->stencil = renderBuffer;
164            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
165                    GL_RENDERBUFFER, stencil->getName());
166        } else {
167            ALOGE("The specified render buffer is not a stencil buffer");
168        }
169    }
170
171    inline RenderBuffer* getStencilRenderBuffer() const {
172        return stencil;
173    }
174
175    inline GLuint getTexture() const {
176        return texture.id;
177    }
178
179    inline GLenum getRenderTarget() const {
180        return renderTarget;
181    }
182
183    inline void setRenderTarget(GLenum renderTarget) {
184        this->renderTarget = renderTarget;
185    }
186
187    void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
188        texture.setWrap(wrap, bindTexture, force, renderTarget);
189    }
190
191    void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
192        texture.setFilter(filter, bindTexture, force, renderTarget);
193    }
194
195    inline bool isCacheable() const {
196        return cacheable;
197    }
198
199    inline void setCacheable(bool cacheable) {
200        this->cacheable = cacheable;
201    }
202
203    inline bool isDirty() const {
204        return dirty;
205    }
206
207    inline void setDirty(bool dirty) {
208        this->dirty = dirty;
209    }
210
211    inline bool isTextureLayer() const {
212        return textureLayer;
213    }
214
215    inline void setTextureLayer(bool textureLayer) {
216        this->textureLayer = textureLayer;
217    }
218
219    inline SkiaColorFilter* getColorFilter() const {
220        return colorFilter;
221    }
222
223    ANDROID_API void setColorFilter(SkiaColorFilter* filter);
224
225    void bindStencilRenderBuffer() const;
226
227    void bindTexture() const;
228    void generateTexture();
229    void allocateTexture();
230    void deleteTexture();
231
232    /**
233     * When the caller frees the texture itself, the caller
234     * must call this method to tell this layer that it lost
235     * the texture.
236     */
237    ANDROID_API void clearTexture();
238
239    inline mat4& getTexTransform() {
240        return texTransform;
241    }
242
243    inline mat4& getTransform() {
244        return transform;
245    }
246
247    void defer();
248    void cancelDefer();
249    void flush();
250    void render();
251
252    /**
253     * Bounds of the layer.
254     */
255    Rect layer;
256    /**
257     * Texture coordinates of the layer.
258     */
259    Rect texCoords;
260    /**
261     * Clipping rectangle.
262     */
263    Rect clipRect;
264
265    /**
266     * Dirty region indicating what parts of the layer
267     * have been drawn.
268     */
269    Region region;
270    /**
271     * If the region is a rectangle, coordinates of the
272     * region are stored here.
273     */
274    Rect regionRect;
275
276    /**
277     * If the layer can be rendered as a mesh, this is non-null.
278     */
279    TextureVertex* mesh;
280    GLsizei meshElementCount;
281
282    /**
283     * Used for deferred updates.
284     */
285    bool deferredUpdateScheduled;
286    OpenGLRenderer* renderer;
287    DisplayList* displayList;
288    Rect dirtyRect;
289    bool debugDrawUpdate;
290    bool hasDrawnSinceUpdate;
291
292private:
293    Caches& caches;
294
295    /**
296     * Name of the FBO used to render the layer. If the name is 0
297     * this layer is not backed by an FBO, but a simple texture.
298     */
299    GLuint fbo;
300
301    /**
302     * The render buffer used as the stencil buffer.
303     */
304    RenderBuffer* stencil;
305
306    /**
307     * Indicates whether this layer has been used already.
308     */
309    bool empty;
310
311    /**
312     * The texture backing this layer.
313     */
314    Texture texture;
315
316    /**
317     * If set to true (by default), the layer can be reused.
318     */
319    bool cacheable;
320
321    /**
322     * When set to true, this layer must be treated as a texture
323     * layer.
324     */
325    bool textureLayer;
326
327    /**
328     * When set to true, this layer is dirty and should be cleared
329     * before any rendering occurs.
330     */
331    bool dirty;
332
333    /**
334     * Indicates the render target.
335     */
336    GLenum renderTarget;
337
338    /**
339     * Color filter used to draw this layer. Optional.
340     */
341    SkiaColorFilter* colorFilter;
342
343    /**
344     * Opacity of the layer.
345     */
346    int alpha;
347    /**
348     * Blending mode of the layer.
349     */
350    SkXfermode::Mode mode;
351
352    /**
353     * Optional texture coordinates transform.
354     */
355    mat4 texTransform;
356
357    /**
358     * Optional transform.
359     */
360    mat4 transform;
361
362    /**
363     * Used to defer display lists when the layer is updated with a
364     * display list.
365     */
366    DeferredDisplayList* deferredList;
367
368}; // struct Layer
369
370}; // namespace uirenderer
371}; // namespace android
372
373#endif // ANDROID_HWUI_LAYER_H
374