Layer.h revision e5c6584a402fb3b1fe0507e4e00e601bec8f1bbc
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, uint32_t layerWidth, 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 getTextureId() const {
204        return texture.id;
205    }
206
207    inline Texture& getTexture() {
208        return texture;
209    }
210
211    inline GLenum getRenderTarget() const {
212        return renderTarget;
213    }
214
215    inline void setRenderTarget(GLenum renderTarget) {
216        this->renderTarget = renderTarget;
217    }
218
219    void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
220        texture.setWrap(wrap, bindTexture, force, renderTarget);
221    }
222
223    void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
224        texture.setFilter(filter, bindTexture, force, renderTarget);
225    }
226
227    inline bool isCacheable() const {
228        return cacheable;
229    }
230
231    inline void setCacheable(bool cacheable) {
232        this->cacheable = cacheable;
233    }
234
235    inline bool isDirty() const {
236        return dirty;
237    }
238
239    inline void setDirty(bool dirty) {
240        this->dirty = dirty;
241    }
242
243    inline bool isTextureLayer() const {
244        return type == kType_Texture;
245    }
246
247    inline SkColorFilter* getColorFilter() const {
248        return colorFilter;
249    }
250
251    ANDROID_API void setColorFilter(SkColorFilter* filter);
252
253    inline void setConvexMask(const SkPath* convexMask) {
254        this->convexMask = convexMask;
255    }
256
257    inline const SkPath* getConvexMask() {
258        return convexMask;
259    }
260
261    void bindStencilRenderBuffer() const;
262
263    void bindTexture() const;
264    void generateTexture();
265    void allocateTexture();
266    void deleteTexture();
267
268    /**
269     * When the caller frees the texture itself, the caller
270     * must call this method to tell this layer that it lost
271     * the texture.
272     */
273    ANDROID_API void clearTexture();
274
275    inline mat4& getTexTransform() {
276        return texTransform;
277    }
278
279    inline mat4& getTransform() {
280        return transform;
281    }
282
283    void defer(const OpenGLRenderer& rootRenderer);
284    void cancelDefer();
285    void flush();
286    void render(const OpenGLRenderer& rootRenderer);
287
288    /**
289     * Posts a decStrong call to the appropriate thread.
290     * Thread-safe.
291     */
292    void postDecStrong();
293
294    /**
295     * Lost the GL context but the layer is still around, mark it invalid internally
296     * so the dtor knows not to do any GL work
297     */
298    void onGlContextLost();
299
300    /**
301     * Bounds of the layer.
302     */
303    Rect layer;
304    /**
305     * Texture coordinates of the layer.
306     */
307    Rect texCoords;
308    /**
309     * Clipping rectangle.
310     */
311    Rect clipRect;
312
313    /**
314     * Dirty region indicating what parts of the layer
315     * have been drawn.
316     */
317    Region region;
318    /**
319     * If the region is a rectangle, coordinates of the
320     * region are stored here.
321     */
322    Rect regionRect;
323
324    /**
325     * If the layer can be rendered as a mesh, this is non-null.
326     */
327    TextureVertex* mesh = nullptr;
328    GLsizei meshElementCount = 0;
329
330    /**
331     * Used for deferred updates.
332     */
333    bool deferredUpdateScheduled = false;
334    std::unique_ptr<OpenGLRenderer> renderer;
335    sp<RenderNode> renderNode;
336    Rect dirtyRect;
337    bool debugDrawUpdate = false;
338    bool hasDrawnSinceUpdate = false;
339    bool wasBuildLayered = false;
340
341private:
342    void requireRenderer();
343    void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer);
344
345    Caches& caches;
346
347    RenderState& renderState;
348
349    /**
350     * Name of the FBO used to render the layer. If the name is 0
351     * this layer is not backed by an FBO, but a simple texture.
352     */
353    GLuint fbo = 0;
354
355    /**
356     * The render buffer used as the stencil buffer.
357     */
358    RenderBuffer* stencil = nullptr;
359
360    /**
361     * Indicates whether this layer has been used already.
362     */
363    bool empty = true;
364
365    /**
366     * The texture backing this layer.
367     */
368    Texture texture;
369
370    /**
371     * If set to true (by default), the layer can be reused.
372     */
373    bool cacheable = true;
374
375    /**
376     * Denotes whether the layer is a DisplayList, or Texture layer.
377     */
378    const Type type;
379
380    /**
381     * When set to true, this layer is dirty and should be cleared
382     * before any rendering occurs.
383     */
384    bool dirty = false;
385
386    /**
387     * Indicates the render target.
388     */
389    GLenum renderTarget = GL_TEXTURE_2D;
390
391    /**
392     * Color filter used to draw this layer. Optional.
393     */
394    SkColorFilter* colorFilter = nullptr;
395
396    /**
397     * Indicates raster data backing the layer is scaled, requiring filtration.
398     */
399    bool forceFilter = false;
400
401    /**
402     * Opacity of the layer.
403     */
404    int alpha = 255;
405
406    /**
407     * Blending mode of the layer.
408     */
409    SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
410
411    /**
412     * Optional texture coordinates transform.
413     */
414    mat4 texTransform;
415
416    /**
417     * Optional transform.
418     */
419    mat4 transform;
420
421    /**
422     * Cached transform of layer in window, updated only on creation / resize
423     */
424    mat4 cachedInvTransformInWindow;
425    bool rendererLightPosDirty = true;
426
427    /**
428     * Used to defer display lists when the layer is updated with a
429     * display list.
430     */
431    std::unique_ptr<DeferredDisplayList> deferredList;
432
433    /**
434     * This convex path should be used to mask the layer's draw to the screen.
435     *
436     * Data not owned/managed by layer object.
437     */
438    const SkPath* convexMask = nullptr;
439
440}; // struct Layer
441
442}; // namespace uirenderer
443}; // namespace android
444
445#endif // ANDROID_HWUI_LAYER_H
446