blob: 1e5498bb3d21edcb0ca362eb6b24be0c62db24e2 [file] [log] [blame]
Romain Guydda57022010-07-06 11:39:32 -07001/*
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
Romain Guy5b3b3522010-10-27 18:57:51 -070017#ifndef ANDROID_HWUI_LAYER_H
18#define ANDROID_HWUI_LAYER_H
Romain Guydda57022010-07-06 11:39:32 -070019
Derek Sollenberger76d3a1b2013-12-10 12:28:58 -050020#include <cutils/compiler.h>
Romain Guyf7f93552010-07-08 19:17:03 -070021#include <sys/types.h>
John Reck087bc0c2014-04-04 16:20:08 -070022#include <utils/StrongPointer.h>
Nick Kralevichbfed8272014-11-01 18:37:39 -070023#include <utils/RefBase.h>
Chris Craik51d6a3d2014-12-22 17:16:56 -080024#include <memory>
Romain Guyf7f93552010-07-08 19:17:03 -070025
Romain Guydda57022010-07-06 11:39:32 -070026#include <GLES2/gl2.h>
John Reck38e0c322015-11-10 12:19:17 -080027#include <GpuMemoryTracker.h>
Romain Guydda57022010-07-06 11:39:32 -070028
Romain Guy5b3b3522010-10-27 18:57:51 -070029#include <ui/Region.h>
30
Derek Sollenbergerca79cf62012-08-14 16:44:52 -040031#include <SkPaint.h>
Romain Guydda57022010-07-06 11:39:32 -070032#include <SkXfermode.h>
33
Derek Sollenberger76d3a1b2013-12-10 12:28:58 -050034#include "Matrix.h"
Romain Guydda57022010-07-06 11:39:32 -070035#include "Rect.h"
Romain Guy3bbacf22013-02-06 16:51:04 -080036#include "RenderBuffer.h"
Romain Guy9ace8f52011-07-07 20:50:11 -070037#include "Texture.h"
Romain Guyf219da52011-01-16 12:54:25 -080038#include "Vertex.h"
Romain Guydda57022010-07-06 11:39:32 -070039
40namespace android {
41namespace uirenderer {
42
Romain Guy8550c4c2010-10-08 15:49:53 -070043///////////////////////////////////////////////////////////////////////////////
44// Layers
45///////////////////////////////////////////////////////////////////////////////
Romain Guydda57022010-07-06 11:39:32 -070046
Romain Guy2bf68f02012-03-02 13:37:47 -080047// Forward declarations
Romain Guy8aa195d2013-06-04 18:00:09 -070048class Caches;
Chris Craik51d6a3d2014-12-22 17:16:56 -080049class RenderNode;
John Reck3b202512014-06-23 13:13:08 -070050class RenderState;
Romain Guy2bf68f02012-03-02 13:37:47 -080051class OpenGLRenderer;
Romain Guy96885eb2013-03-26 15:05:58 -070052class DeferredDisplayList;
Chih-Hung Hsiehd3448e42014-09-15 14:28:52 -070053struct DeferStateStruct;
Romain Guy2bf68f02012-03-02 13:37:47 -080054
Romain Guydda57022010-07-06 11:39:32 -070055/**
Romain Guyeb993562010-10-05 18:14:38 -070056 * A layer has dimensions and is backed by an OpenGL texture or FBO.
Romain Guydda57022010-07-06 11:39:32 -070057 */
John Reck38e0c322015-11-10 12:19:17 -080058class Layer : public VirtualLightRefBase, GpuMemoryTracker {
Chris Craik564acf72014-01-02 16:46:18 -080059public:
Chris Craikb9ce116d2015-08-20 15:14:06 -070060 enum class Type {
61 Texture,
62 DisplayList,
Chris Craik8a226d22014-09-08 16:40:21 -070063 };
64
Chris Craikbfd1cd62014-09-10 13:04:31 -070065 // layer lifecycle, controlled from outside
Chris Craikb9ce116d2015-08-20 15:14:06 -070066 enum class State {
67 Uncached = 0,
68 InCache = 1,
69 FailedToCache = 2,
70 RemovedFromCache = 3,
71 DeletedFromCache = 4,
72 InGarbageList = 5,
Chris Craikbfd1cd62014-09-10 13:04:31 -070073 };
74 State state; // public for logging/debugging purposes
75
Chris Craike5c65842015-03-02 17:50:26 -080076 Layer(Type type, RenderState& renderState, uint32_t layerWidth, uint32_t layerHeight);
Chet Haased15ebf22012-09-05 11:40:29 -070077 ~Layer();
Romain Guy8550c4c2010-10-08 15:49:53 -070078
Romain Guy2055aba2013-01-18 16:42:51 -080079 static uint32_t computeIdealWidth(uint32_t layerWidth);
80 static uint32_t computeIdealHeight(uint32_t layerHeight);
81
Romain Guy8ce00302013-01-15 18:51:42 -080082 /**
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);
Dave Burke56257af2012-09-25 20:30:09 -070088
Romain Guydda57022010-07-06 11:39:32 -070089 /**
Romain Guy9fc27812011-04-27 14:21:41 -070090 * 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
John Reck38e0c322015-11-10 12:19:17 -080098 const float texX = 1.0f / float(texture.mWidth);
99 const float texY = 1.0f / float(texture.mHeight);
Romain Guy9fc27812011-04-27 14:21:41 -0700100 const float height = layer.getHeight();
101 texCoords.set(
102 regionRect.left * texX, (height - regionRect.top) * texY,
103 regionRect.right * texX, (height - regionRect.bottom) * texY);
Romain Guy9ace8f52011-07-07 20:50:11 -0700104
105 regionRect.translate(layer.left, layer.top);
106 }
107
Chris Craik69e5adf2014-08-14 13:34:01 -0700108 void setWindowTransform(Matrix4& windowTransform) {
109 cachedInvTransformInWindow.loadInverse(windowTransform);
110 rendererLightPosDirty = true;
111 }
112
Chris Craika7090e02014-06-20 16:01:00 -0700113 void updateDeferred(RenderNode* renderNode, int left, int top, int right, int bottom);
Romain Guy2bf68f02012-03-02 13:37:47 -0800114
Romain Guy3bbacf22013-02-06 16:51:04 -0800115 inline uint32_t getWidth() const {
John Reck38e0c322015-11-10 12:19:17 -0800116 return texture.mWidth;
Romain Guy9ace8f52011-07-07 20:50:11 -0700117 }
118
Romain Guy3bbacf22013-02-06 16:51:04 -0800119 inline uint32_t getHeight() const {
John Reck38e0c322015-11-10 12:19:17 -0800120 return texture.mHeight;
Romain Guy9ace8f52011-07-07 20:50:11 -0700121 }
122
Romain Guy2055aba2013-01-18 16:42:51 -0800123 /**
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
Romain Guy9ace8f52011-07-07 20:50:11 -0700134 void setSize(uint32_t width, uint32_t height) {
John Reck38e0c322015-11-10 12:19:17 -0800135 texture.updateSize(width, height, texture.format());
Romain Guy9ace8f52011-07-07 20:50:11 -0700136 }
137
Derek Sollenberger674554f2014-02-19 16:47:32 +0000138 ANDROID_API void setPaint(const SkPaint* paint);
Chet Haased15ebf22012-09-05 11:40:29 -0700139
Romain Guy9ace8f52011-07-07 20:50:11 -0700140 inline void setBlend(bool blend) {
141 texture.blend = blend;
142 }
143
Romain Guy3bbacf22013-02-06 16:51:04 -0800144 inline bool isBlend() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700145 return texture.blend;
146 }
147
Chris Craik9757ac02014-02-25 18:50:17 -0800148 inline void setForceFilter(bool forceFilter) {
149 this->forceFilter = forceFilter;
150 }
151
152 inline bool getForceFilter() const {
153 return forceFilter;
154 }
155
Romain Guy9ace8f52011-07-07 20:50:11 -0700156 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
Romain Guy3bbacf22013-02-06 16:51:04 -0800165 inline int getAlpha() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700166 return alpha;
167 }
168
Romain Guy3bbacf22013-02-06 16:51:04 -0800169 inline SkXfermode::Mode getMode() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700170 return mode;
171 }
172
173 inline void setEmpty(bool empty) {
174 this->empty = empty;
175 }
176
Romain Guy3bbacf22013-02-06 16:51:04 -0800177 inline bool isEmpty() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700178 return empty;
179 }
180
181 inline void setFbo(GLuint fbo) {
182 this->fbo = fbo;
183 }
184
Romain Guy3bbacf22013-02-06 16:51:04 -0800185 inline GLuint getFbo() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700186 return fbo;
187 }
188
Romain Guy3bbacf22013-02-06 16:51:04 -0800189 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 }
Romain Guy8ce00302013-01-15 18:51:42 -0800197 }
198
Romain Guy3bbacf22013-02-06 16:51:04 -0800199 inline RenderBuffer* getStencilRenderBuffer() const {
Romain Guy8ce00302013-01-15 18:51:42 -0800200 return stencil;
201 }
202
Chris Craikf27133d2015-02-19 09:51:53 -0800203 inline GLuint getTextureId() const {
John Reck38e0c322015-11-10 12:19:17 -0800204 return texture.id();
Romain Guy9ace8f52011-07-07 20:50:11 -0700205 }
206
Chris Craikf27133d2015-02-19 09:51:53 -0800207 inline Texture& getTexture() {
208 return texture;
209 }
210
Romain Guy3bbacf22013-02-06 16:51:04 -0800211 inline GLenum getRenderTarget() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700212 return renderTarget;
213 }
214
215 inline void setRenderTarget(GLenum renderTarget) {
216 this->renderTarget = renderTarget;
217 }
218
John Reck417ed6d2016-03-22 16:01:08 -0700219 inline bool isRenderable() const {
220 return renderTarget != GL_NONE;
221 }
222
Romain Guyd21b6e12011-11-30 20:21:23 -0800223 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) {
224 texture.setWrap(wrap, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700225 }
226
Romain Guyd21b6e12011-11-30 20:21:23 -0800227 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) {
228 texture.setFilter(filter, bindTexture, force, renderTarget);
Romain Guy9ace8f52011-07-07 20:50:11 -0700229 }
230
Romain Guy3bbacf22013-02-06 16:51:04 -0800231 inline bool isCacheable() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700232 return cacheable;
233 }
234
235 inline void setCacheable(bool cacheable) {
236 this->cacheable = cacheable;
237 }
238
Romain Guy3bbacf22013-02-06 16:51:04 -0800239 inline bool isDirty() const {
Romain Guy7c25aab2012-10-18 15:05:02 -0700240 return dirty;
241 }
242
243 inline void setDirty(bool dirty) {
244 this->dirty = dirty;
245 }
246
Romain Guy3bbacf22013-02-06 16:51:04 -0800247 inline bool isTextureLayer() const {
Chris Craikb9ce116d2015-08-20 15:14:06 -0700248 return type == Type::Texture;
Romain Guy9ace8f52011-07-07 20:50:11 -0700249 }
250
Derek Sollenberger76d3a1b2013-12-10 12:28:58 -0500251 inline SkColorFilter* getColorFilter() const {
Romain Guy9ace8f52011-07-07 20:50:11 -0700252 return colorFilter;
253 }
254
Derek Sollenberger76d3a1b2013-12-10 12:28:58 -0500255 ANDROID_API void setColorFilter(SkColorFilter* filter);
Romain Guy9ace8f52011-07-07 20:50:11 -0700256
Chris Craik3f0854292014-04-15 16:18:08 -0700257 inline void setConvexMask(const SkPath* convexMask) {
258 this->convexMask = convexMask;
259 }
260
261 inline const SkPath* getConvexMask() {
262 return convexMask;
263 }
264
Romain Guy8aa195d2013-06-04 18:00:09 -0700265 void bindStencilRenderBuffer() const;
Romain Guy9ace8f52011-07-07 20:50:11 -0700266
Romain Guy8aa195d2013-06-04 18:00:09 -0700267 void bindTexture() const;
268 void generateTexture();
269 void allocateTexture();
Romain Guyef09a212012-09-25 12:17:14 -0700270
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 */
Romain Guy8aa195d2013-06-04 18:00:09 -0700276 ANDROID_API void clearTexture();
Romain Guy2055aba2013-01-18 16:42:51 -0800277
Romain Guy9ace8f52011-07-07 20:50:11 -0700278 inline mat4& getTexTransform() {
279 return texTransform;
Romain Guy9fc27812011-04-27 14:21:41 -0700280 }
281
Romain Guy302a9df2011-08-16 13:55:02 -0700282 inline mat4& getTransform() {
283 return transform;
284 }
285
Chris Craik69e5adf2014-08-14 13:34:01 -0700286 void defer(const OpenGLRenderer& rootRenderer);
Romain Guye93482f2013-06-17 13:14:51 -0700287 void cancelDefer();
Romain Guy96885eb2013-03-26 15:05:58 -0700288 void flush();
Chris Craik69e5adf2014-08-14 13:34:01 -0700289 void render(const OpenGLRenderer& rootRenderer);
Romain Guy96885eb2013-03-26 15:05:58 -0700290
Romain Guy9fc27812011-04-27 14:21:41 -0700291 /**
John Reck0e89e2b2014-10-31 14:49:06 -0700292 * Posts a decStrong call to the appropriate thread.
293 * Thread-safe.
294 */
295 void postDecStrong();
296
297 /**
John Reck57998012015-01-29 10:17:57 -0800298 * 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 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700304 * Bounds of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700305 */
306 Rect layer;
307 /**
Romain Guy8550c4c2010-10-08 15:49:53 -0700308 * Texture coordinates of the layer.
Romain Guydda57022010-07-06 11:39:32 -0700309 */
Romain Guy8550c4c2010-10-08 15:49:53 -0700310 Rect texCoords;
Romain Guyc3fedaf2013-01-29 17:26:25 -0800311 /**
312 * Clipping rectangle.
313 */
314 Rect clipRect;
Romain Guy8550c4c2010-10-08 15:49:53 -0700315
Romain Guydda57022010-07-06 11:39:32 -0700316 /**
Romain Guy5b3b3522010-10-27 18:57:51 -0700317 * Dirty region indicating what parts of the layer
318 * have been drawn.
319 */
320 Region region;
Romain Guy40667672011-03-18 14:34:03 -0700321 /**
322 * If the region is a rectangle, coordinates of the
323 * region are stored here.
324 */
325 Rect regionRect;
Romain Guy171c5922011-01-06 10:04:23 -0800326
327 /**
Romain Guyf219da52011-01-16 12:54:25 -0800328 * If the layer can be rendered as a mesh, this is non-null.
329 */
Chris Craike5c65842015-03-02 17:50:26 -0800330 TextureVertex* mesh = nullptr;
331 GLsizei meshElementCount = 0;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700332
Romain Guy2bf68f02012-03-02 13:37:47 -0800333 /**
334 * Used for deferred updates.
335 */
Chris Craike5c65842015-03-02 17:50:26 -0800336 bool deferredUpdateScheduled = false;
Chris Craik51d6a3d2014-12-22 17:16:56 -0800337 std::unique_ptr<OpenGLRenderer> renderer;
Chris Craika7090e02014-06-20 16:01:00 -0700338 sp<RenderNode> renderNode;
Romain Guy2bf68f02012-03-02 13:37:47 -0800339 Rect dirtyRect;
Chris Craike5c65842015-03-02 17:50:26 -0800340 bool debugDrawUpdate = false;
341 bool hasDrawnSinceUpdate = false;
342 bool wasBuildLayered = false;
Romain Guy2bf68f02012-03-02 13:37:47 -0800343
Romain Guy9ace8f52011-07-07 20:50:11 -0700344private:
John Reck668f0e32014-03-26 15:10:40 -0700345 void requireRenderer();
Chris Craik69e5adf2014-08-14 13:34:01 -0700346 void updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer);
John Reck668f0e32014-03-26 15:10:40 -0700347
Romain Guy8aa195d2013-06-04 18:00:09 -0700348 Caches& caches;
349
John Reck3b202512014-06-23 13:13:08 -0700350 RenderState& renderState;
351
Romain Guy9ace8f52011-07-07 20:50:11 -0700352 /**
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 */
Chris Craike5c65842015-03-02 17:50:26 -0800356 GLuint fbo = 0;
Romain Guy9ace8f52011-07-07 20:50:11 -0700357
358 /**
Romain Guy3bbacf22013-02-06 16:51:04 -0800359 * The render buffer used as the stencil buffer.
Romain Guy8ce00302013-01-15 18:51:42 -0800360 */
Chris Craike5c65842015-03-02 17:50:26 -0800361 RenderBuffer* stencil = nullptr;
Romain Guy8ce00302013-01-15 18:51:42 -0800362
363 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700364 * Indicates whether this layer has been used already.
365 */
Chris Craike5c65842015-03-02 17:50:26 -0800366 bool empty = true;
Romain Guy9ace8f52011-07-07 20:50:11 -0700367
368 /**
369 * The texture backing this layer.
370 */
371 Texture texture;
372
Romain Guyaa6c24c2011-04-28 18:40:04 -0700373 /**
374 * If set to true (by default), the layer can be reused.
375 */
Chris Craike5c65842015-03-02 17:50:26 -0800376 bool cacheable = true;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700377
378 /**
Chris Craik8a226d22014-09-08 16:40:21 -0700379 * Denotes whether the layer is a DisplayList, or Texture layer.
Romain Guyaa6c24c2011-04-28 18:40:04 -0700380 */
Chris Craik8a226d22014-09-08 16:40:21 -0700381 const Type type;
Romain Guy9ace8f52011-07-07 20:50:11 -0700382
383 /**
Romain Guy7c25aab2012-10-18 15:05:02 -0700384 * When set to true, this layer is dirty and should be cleared
385 * before any rendering occurs.
386 */
Chris Craike5c65842015-03-02 17:50:26 -0800387 bool dirty = false;
Romain Guy7c25aab2012-10-18 15:05:02 -0700388
389 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700390 * Indicates the render target.
391 */
Chris Craike5c65842015-03-02 17:50:26 -0800392 GLenum renderTarget = GL_TEXTURE_2D;
Romain Guy9ace8f52011-07-07 20:50:11 -0700393
394 /**
395 * Color filter used to draw this layer. Optional.
396 */
Chris Craike5c65842015-03-02 17:50:26 -0800397 SkColorFilter* colorFilter = nullptr;
Romain Guy9ace8f52011-07-07 20:50:11 -0700398
399 /**
Chris Craik9757ac02014-02-25 18:50:17 -0800400 * Indicates raster data backing the layer is scaled, requiring filtration.
401 */
Chris Craike5c65842015-03-02 17:50:26 -0800402 bool forceFilter = false;
Chris Craik9757ac02014-02-25 18:50:17 -0800403
404 /**
Romain Guy9ace8f52011-07-07 20:50:11 -0700405 * Opacity of the layer.
406 */
Chris Craike5c65842015-03-02 17:50:26 -0800407 int alpha = 255;
Chris Craik9757ac02014-02-25 18:50:17 -0800408
Romain Guy9ace8f52011-07-07 20:50:11 -0700409 /**
410 * Blending mode of the layer.
411 */
Chris Craike5c65842015-03-02 17:50:26 -0800412 SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700413
414 /**
415 * Optional texture coordinates transform.
416 */
417 mat4 texTransform;
Romain Guy8f0095c2011-05-02 17:24:22 -0700418
Romain Guy302a9df2011-08-16 13:55:02 -0700419 /**
420 * Optional transform.
421 */
422 mat4 transform;
423
Romain Guy96885eb2013-03-26 15:05:58 -0700424 /**
Chris Craik69e5adf2014-08-14 13:34:01 -0700425 * Cached transform of layer in window, updated only on creation / resize
426 */
427 mat4 cachedInvTransformInWindow;
Chris Craike5c65842015-03-02 17:50:26 -0800428 bool rendererLightPosDirty = true;
Chris Craik69e5adf2014-08-14 13:34:01 -0700429
430 /**
Romain Guy96885eb2013-03-26 15:05:58 -0700431 * Used to defer display lists when the layer is updated with a
432 * display list.
433 */
Chris Craik51d6a3d2014-12-22 17:16:56 -0800434 std::unique_ptr<DeferredDisplayList> deferredList;
Romain Guy96885eb2013-03-26 15:05:58 -0700435
Chris Craik3f0854292014-04-15 16:18:08 -0700436 /**
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 */
Chris Craike5c65842015-03-02 17:50:26 -0800441 const SkPath* convexMask = nullptr;
Chris Craik3f0854292014-04-15 16:18:08 -0700442
Romain Guydda57022010-07-06 11:39:32 -0700443}; // struct Layer
444
445}; // namespace uirenderer
446}; // namespace android
447
Romain Guy5b3b3522010-10-27 18:57:51 -0700448#endif // ANDROID_HWUI_LAYER_H