Layer.h revision 49bc4acfadf9c5b1e520217278ccb38010d38c89
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 <cutils/compiler.h>
21#include <sys/types.h>
22#include <utils/StrongPointer.h>
23#include <utils/RefBase.h>
24#include <memory>
25
26#include <GLES2/gl2.h>
27
28#include <ui/Region.h>
29
30#include <SkPaint.h>
31#include <SkXfermode.h>
32
33#include "Matrix.h"
34#include "Rect.h"
35#include "RenderBuffer.h"
36#include "Texture.h"
37#include "Vertex.h"
38
39namespace android {
40namespace uirenderer {
41
42///////////////////////////////////////////////////////////////////////////////
43// Layers
44///////////////////////////////////////////////////////////////////////////////
45
46// Forward declarations
47class Caches;
48class RenderNode;
49class RenderState;
50class OpenGLRenderer;
51class DeferredDisplayList;
52struct DeferStateStruct;
53
54/**
55 * A layer has dimensions and is backed by an OpenGL texture or FBO.
56 */
57class Layer : public VirtualLightRefBase {
58public:
59    enum Type {
60        kType_Texture,
61        kType_DisplayList,
62    };
63
64    // layer lifecycle, controlled from outside
65    enum State {
66        kState_Uncached = 0,
67        kState_InCache = 1,
68        kState_FailedToCache = 2,
69        kState_RemovedFromCache = 3,
70        kState_DeletedFromCache = 4,
71        kState_InGarbageList = 5,
72    };
73    State state; // public for logging/debugging purposes
74
75    Layer(Type type, RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight);
76    ~Layer();
77
78    static uint32_t computeIdealWidth(uint32_t layerWidth);
79    static uint32_t computeIdealHeight(uint32_t layerHeight);
80
81    /**
82     * Calling this method will remove (either by recycling or
83     * destroying) the associated FBO, if present, and any render
84     * buffer (stencil for instance.)
85     */
86    void removeFbo(bool flush = true);
87
88    /**
89     * Sets this layer's region to a rectangle. Computes the appropriate
90     * texture coordinates.
91     */
92    void setRegionAsRect() {
93        const android::Rect& bounds = region.getBounds();
94        regionRect.set(bounds.leftTop().x, bounds.leftTop().y,
95               bounds.rightBottom().x, bounds.rightBottom().y);
96
97        const float texX = 1.0f / float(texture.width);
98        const float texY = 1.0f / float(texture.height);
99        const float height = layer.getHeight();
100        texCoords.set(
101               regionRect.left * texX, (height - regionRect.top) * texY,
102               regionRect.right * texX, (height - regionRect.bottom) * texY);
103
104        regionRect.translate(layer.left, layer.top);
105    }
106
107    void setWindowTransform(Matrix4& windowTransform) {
108        cachedInvTransformInWindow.loadInverse(windowTransform);
109        rendererLightPosDirty = true;
110    }
111
112    void updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom);
113
114    inline uint32_t getWidth() const {
115        return texture.width;
116    }
117
118    inline uint32_t getHeight() const {
119        return texture.height;
120    }
121
122    /**
123     * Resize the layer and its texture if needed.
124     *
125     * @param width The new width of the layer
126     * @param height The new height of the layer
127     *
128     * @return True if the layer was resized or nothing happened, false if
129     *         a failure occurred during the resizing operation
130     */
131    bool resize(const uint32_t width, const uint32_t height);
132
133    void setSize(uint32_t width, uint32_t height) {
134        texture.width = width;
135        texture.height = height;
136    }
137
138    ANDROID_API void setPaint(const SkPaint* paint);
139
140    inline void setBlend(bool blend) {
141        texture.blend = blend;
142    }
143
144    inline bool isBlend() const {
145        return texture.blend;
146    }
147
148    inline void setForceFilter(bool forceFilter) {
149        this->forceFilter = forceFilter;
150    }
151
152    inline bool getForceFilter() const {
153        return forceFilter;
154    }
155
156    inline void setAlpha(int alpha) {
157        this->alpha = alpha;
158    }
159
160    inline void setAlpha(int alpha, SkXfermode::Mode mode) {
161        this->alpha = alpha;
162        this->mode = mode;
163    }
164
165    inline int getAlpha() const {
166        return alpha;
167    }
168
169    inline SkXfermode::Mode getMode() const {
170        return mode;
171    }
172
173    inline void setEmpty(bool empty) {
174        this->empty = empty;
175    }
176
177    inline bool isEmpty() const {
178        return empty;
179    }
180
181    inline void setFbo(GLuint fbo) {
182        this->fbo = fbo;
183    }
184
185    inline GLuint getFbo() const {
186        return fbo;
187    }
188
189    inline void setStencilRenderBuffer(RenderBuffer* renderBuffer) {
190        if (RenderBuffer::isStencilBuffer(renderBuffer->getFormat())) {
191            this->stencil = renderBuffer;
192            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
193                    GL_RENDERBUFFER, stencil->getName());
194        } else {
195            ALOGE("The specified render buffer is not a stencil buffer");
196        }
197    }
198
199    inline RenderBuffer* getStencilRenderBuffer() const {
200        return stencil;
201    }
202
203    inline GLuint getTexture() const {
204        return texture.id;
205    }
206
207    inline GLenum getRenderTarget() const {
208        return renderTarget;
209    }
210
211    inline void setRenderTarget(GLenum renderTarget) {
212        this->renderTarget = renderTarget;
213    }
214
215    void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
216        texture.setWrap(wrap, bindTexture, force, renderTarget);
217    }
218
219    void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
220        texture.setFilter(filter, bindTexture, force, renderTarget);
221    }
222
223    inline bool isCacheable() const {
224        return cacheable;
225    }
226
227    inline void setCacheable(bool cacheable) {
228        this->cacheable = cacheable;
229    }
230
231    inline bool isDirty() const {
232        return dirty;
233    }
234
235    inline void setDirty(bool dirty) {
236        this->dirty = dirty;
237    }
238
239    inline bool isTextureLayer() const {
240        return type == kType_Texture;
241    }
242
243    inline SkColorFilter* getColorFilter() const {
244        return colorFilter;
245    }
246
247    ANDROID_API void setColorFilter(SkColorFilter* filter);
248
249    inline void setConvexMask(const SkPath* convexMask) {
250        this->convexMask = convexMask;
251    }
252
253    inline const SkPath* getConvexMask() {
254        return convexMask;
255    }
256
257    void bindStencilRenderBuffer() const;
258
259    void bindTexture() const;
260    void generateTexture();
261    void allocateTexture();
262    void deleteTexture();
263
264    /**
265     * When the caller frees the texture itself, the caller
266     * must call this method to tell this layer that it lost
267     * the texture.
268     */
269    ANDROID_API void clearTexture();
270
271    inline mat4& getTexTransform() {
272        return texTransform;
273    }
274
275    inline mat4& getTransform() {
276        return transform;
277    }
278
279    void defer(const OpenGLRenderer& rootRenderer);
280    void cancelDefer();
281    void flush();
282    void render(const OpenGLRenderer& rootRenderer);
283
284    /**
285     * Posts a decStrong call to the appropriate thread.
286     * Thread-safe.
287     */
288    void postDecStrong();
289
290    /**
291     * Lost the GL context but the layer is still around, mark it invalid internally
292     * so the dtor knows not to do any GL work
293     */
294    void onGlContextLost();
295
296    /**
297     * Bounds of the layer.
298     */
299    Rect layer;
300    /**
301     * Texture coordinates of the layer.
302     */
303    Rect texCoords;
304    /**
305     * Clipping rectangle.
306     */
307    Rect clipRect;
308
309    /**
310     * Dirty region indicating what parts of the layer
311     * have been drawn.
312     */
313    Region region;
314    /**
315     * If the region is a rectangle, coordinates of the
316     * region are stored here.
317     */
318    Rect regionRect;
319
320    /**
321     * If the layer can be rendered as a mesh, this is non-null.
322     */
323    TextureVertex* mesh;
324    GLsizei meshElementCount;
325
326    /**
327     * Used for deferred updates.
328     */
329    bool deferredUpdateScheduled;
330    std::unique_ptr<OpenGLRenderer> renderer;
331    sp<RenderNode> renderNode;
332    Rect dirtyRect;
333    bool debugDrawUpdate;
334    bool hasDrawnSinceUpdate;
335    bool wasBuildLayered;
336
337private:
338    void requireRenderer();
339    void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer);
340
341    Caches& caches;
342
343    RenderState& renderState;
344
345    /**
346     * Name of the FBO used to render the layer. If the name is 0
347     * this layer is not backed by an FBO, but a simple texture.
348     */
349    GLuint fbo;
350
351    /**
352     * The render buffer used as the stencil buffer.
353     */
354    RenderBuffer* stencil;
355
356    /**
357     * Indicates whether this layer has been used already.
358     */
359    bool empty;
360
361    /**
362     * The texture backing this layer.
363     */
364    Texture texture;
365
366    /**
367     * If set to true (by default), the layer can be reused.
368     */
369    bool cacheable;
370
371    /**
372     * Denotes whether the layer is a DisplayList, or Texture layer.
373     */
374    const Type type;
375
376    /**
377     * When set to true, this layer is dirty and should be cleared
378     * before any rendering occurs.
379     */
380    bool dirty;
381
382    /**
383     * Indicates the render target.
384     */
385    GLenum renderTarget;
386
387    /**
388     * Color filter used to draw this layer. Optional.
389     */
390    SkColorFilter* colorFilter;
391
392    /**
393     * Indicates raster data backing the layer is scaled, requiring filtration.
394     */
395    bool forceFilter;
396
397    /**
398     * Opacity of the layer.
399     */
400    int alpha;
401
402    /**
403     * Blending mode of the layer.
404     */
405    SkXfermode::Mode mode;
406
407    /**
408     * Optional texture coordinates transform.
409     */
410    mat4 texTransform;
411
412    /**
413     * Optional transform.
414     */
415    mat4 transform;
416
417    /**
418     * Cached transform of layer in window, updated only on creation / resize
419     */
420    mat4 cachedInvTransformInWindow;
421    bool rendererLightPosDirty;
422
423    /**
424     * Used to defer display lists when the layer is updated with a
425     * display list.
426     */
427    std::unique_ptr<DeferredDisplayList> deferredList;
428
429    /**
430     * This convex path should be used to mask the layer's draw to the screen.
431     *
432     * Data not owned/managed by layer object.
433     */
434    const SkPath* convexMask;
435
436}; // struct Layer
437
438}; // namespace uirenderer
439}; // namespace android
440
441#endif // ANDROID_HWUI_LAYER_H
442