Layer.h revision 51d6a3db97bdd5315f1a17a4b447d10a92217b98
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     * Bounds of the layer.
292     */
293    Rect layer;
294    /**
295     * Texture coordinates of the layer.
296     */
297    Rect texCoords;
298    /**
299     * Clipping rectangle.
300     */
301    Rect clipRect;
302
303    /**
304     * Dirty region indicating what parts of the layer
305     * have been drawn.
306     */
307    Region region;
308    /**
309     * If the region is a rectangle, coordinates of the
310     * region are stored here.
311     */
312    Rect regionRect;
313
314    /**
315     * If the layer can be rendered as a mesh, this is non-null.
316     */
317    TextureVertex* mesh;
318    GLsizei meshElementCount;
319
320    /**
321     * Used for deferred updates.
322     */
323    bool deferredUpdateScheduled;
324    std::unique_ptr<OpenGLRenderer> renderer;
325    sp<RenderNode> renderNode;
326    Rect dirtyRect;
327    bool debugDrawUpdate;
328    bool hasDrawnSinceUpdate;
329    bool wasBuildLayered;
330
331private:
332    void requireRenderer();
333    void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer);
334
335    Caches& caches;
336
337    RenderState& renderState;
338
339    /**
340     * Name of the FBO used to render the layer. If the name is 0
341     * this layer is not backed by an FBO, but a simple texture.
342     */
343    GLuint fbo;
344
345    /**
346     * The render buffer used as the stencil buffer.
347     */
348    RenderBuffer* stencil;
349
350    /**
351     * Indicates whether this layer has been used already.
352     */
353    bool empty;
354
355    /**
356     * The texture backing this layer.
357     */
358    Texture texture;
359
360    /**
361     * If set to true (by default), the layer can be reused.
362     */
363    bool cacheable;
364
365    /**
366     * Denotes whether the layer is a DisplayList, or Texture layer.
367     */
368    const Type type;
369
370    /**
371     * When set to true, this layer is dirty and should be cleared
372     * before any rendering occurs.
373     */
374    bool dirty;
375
376    /**
377     * Indicates the render target.
378     */
379    GLenum renderTarget;
380
381    /**
382     * Color filter used to draw this layer. Optional.
383     */
384    SkColorFilter* colorFilter;
385
386    /**
387     * Indicates raster data backing the layer is scaled, requiring filtration.
388     */
389    bool forceFilter;
390
391    /**
392     * Opacity of the layer.
393     */
394    int alpha;
395
396    /**
397     * Blending mode of the layer.
398     */
399    SkXfermode::Mode mode;
400
401    /**
402     * Optional texture coordinates transform.
403     */
404    mat4 texTransform;
405
406    /**
407     * Optional transform.
408     */
409    mat4 transform;
410
411    /**
412     * Cached transform of layer in window, updated only on creation / resize
413     */
414    mat4 cachedInvTransformInWindow;
415    bool rendererLightPosDirty;
416
417    /**
418     * Used to defer display lists when the layer is updated with a
419     * display list.
420     */
421    std::unique_ptr<DeferredDisplayList> deferredList;
422
423    /**
424     * This convex path should be used to mask the layer's draw to the screen.
425     *
426     * Data not owned/managed by layer object.
427     */
428    const SkPath* convexMask;
429
430}; // struct Layer
431
432}; // namespace uirenderer
433}; // namespace android
434
435#endif // ANDROID_HWUI_LAYER_H
436