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