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