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 <sys/types.h> 21 22 #include <GLES2/gl2.h> 23 24 #include <ui/Region.h> 25 26 #include <SkXfermode.h> 27 28 #include "Rect.h" 29 #include "SkiaColorFilter.h" 30 #include "Texture.h" 31 #include "Vertex.h" 32 33 namespace android { 34 namespace uirenderer { 35 36 /////////////////////////////////////////////////////////////////////////////// 37 // Layers 38 /////////////////////////////////////////////////////////////////////////////// 39 40 // Forward declarations 41 class OpenGLRenderer; 42 class DisplayList; 43 44 /** 45 * A layer has dimensions and is backed by an OpenGL texture or FBO. 46 */ 47 struct Layer { 48 Layer(const uint32_t layerWidth, const uint32_t layerHeight); 49 ~Layer(); 50 51 void removeFbo(); 52 53 /** 54 * Sets this layer's region to a rectangle. Computes the appropriate 55 * texture coordinates. 56 */ setRegionAsRectLayer57 void setRegionAsRect() { 58 const android::Rect& bounds = region.getBounds(); 59 regionRect.set(bounds.leftTop().x, bounds.leftTop().y, 60 bounds.rightBottom().x, bounds.rightBottom().y); 61 62 const float texX = 1.0f / float(texture.width); 63 const float texY = 1.0f / float(texture.height); 64 const float height = layer.getHeight(); 65 texCoords.set( 66 regionRect.left * texX, (height - regionRect.top) * texY, 67 regionRect.right * texX, (height - regionRect.bottom) * texY); 68 69 regionRect.translate(layer.left, layer.top); 70 } 71 updateDeferredLayer72 void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList, 73 int left, int top, int right, int bottom) { 74 this->renderer = renderer; 75 this->displayList = displayList; 76 const Rect r(left, top, right, bottom); 77 dirtyRect.unionWith(r); 78 deferredUpdateScheduled = true; 79 } 80 getWidthLayer81 inline uint32_t getWidth() { 82 return texture.width; 83 } 84 getHeightLayer85 inline uint32_t getHeight() { 86 return texture.height; 87 } 88 setSizeLayer89 void setSize(uint32_t width, uint32_t height) { 90 texture.width = width; 91 texture.height = height; 92 } 93 94 ANDROID_API void setPaint(SkPaint* paint); 95 setBlendLayer96 inline void setBlend(bool blend) { 97 texture.blend = blend; 98 } 99 isBlendLayer100 inline bool isBlend() { 101 return texture.blend; 102 } 103 setAlphaLayer104 inline void setAlpha(int alpha) { 105 this->alpha = alpha; 106 } 107 setAlphaLayer108 inline void setAlpha(int alpha, SkXfermode::Mode mode) { 109 this->alpha = alpha; 110 this->mode = mode; 111 } 112 getAlphaLayer113 inline int getAlpha() { 114 return alpha; 115 } 116 getModeLayer117 inline SkXfermode::Mode getMode() { 118 return mode; 119 } 120 setEmptyLayer121 inline void setEmpty(bool empty) { 122 this->empty = empty; 123 } 124 isEmptyLayer125 inline bool isEmpty() { 126 return empty; 127 } 128 setFboLayer129 inline void setFbo(GLuint fbo) { 130 this->fbo = fbo; 131 } 132 getFboLayer133 inline GLuint getFbo() { 134 return fbo; 135 } 136 getTextureLayer137 inline GLuint getTexture() { 138 return texture.id; 139 } 140 getRenderTargetLayer141 inline GLenum getRenderTarget() { 142 return renderTarget; 143 } 144 setRenderTargetLayer145 inline void setRenderTarget(GLenum renderTarget) { 146 this->renderTarget = renderTarget; 147 } 148 149 void setWrap(GLenum wrap, bool bindTexture = false, bool force = false) { 150 texture.setWrap(wrap, bindTexture, force, renderTarget); 151 } 152 153 void setFilter(GLenum filter, bool bindTexture = false, bool force = false) { 154 texture.setFilter(filter, bindTexture, force, renderTarget); 155 } 156 isCacheableLayer157 inline bool isCacheable() { 158 return cacheable; 159 } 160 setCacheableLayer161 inline void setCacheable(bool cacheable) { 162 this->cacheable = cacheable; 163 } 164 isDirtyLayer165 inline bool isDirty() { 166 return dirty; 167 } 168 setDirtyLayer169 inline void setDirty(bool dirty) { 170 this->dirty = dirty; 171 } 172 isTextureLayerLayer173 inline bool isTextureLayer() { 174 return textureLayer; 175 } 176 setTextureLayerLayer177 inline void setTextureLayer(bool textureLayer) { 178 this->textureLayer = textureLayer; 179 } 180 getColorFilterLayer181 inline SkiaColorFilter* getColorFilter() { 182 return colorFilter; 183 } 184 185 ANDROID_API void setColorFilter(SkiaColorFilter* filter); 186 bindTextureLayer187 inline void bindTexture() { 188 if (texture.id) { 189 glBindTexture(renderTarget, texture.id); 190 } 191 } 192 generateTextureLayer193 inline void generateTexture() { 194 if (!texture.id) { 195 glGenTextures(1, &texture.id); 196 } 197 } 198 deleteTextureLayer199 inline void deleteTexture() { 200 if (texture.id) { 201 glDeleteTextures(1, &texture.id); 202 texture.id = 0; 203 } 204 } 205 206 /** 207 * When the caller frees the texture itself, the caller 208 * must call this method to tell this layer that it lost 209 * the texture. 210 */ clearTextureLayer211 void clearTexture() { 212 texture.id = 0; 213 } 214 deleteFboLayer215 inline void deleteFbo() { 216 if (fbo) glDeleteFramebuffers(1, &fbo); 217 } 218 allocateTextureLayer219 inline void allocateTexture(GLenum format, GLenum storage) { 220 #if DEBUG_LAYERS 221 ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight()); 222 #endif 223 glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, format, storage, NULL); 224 } 225 getTexTransformLayer226 inline mat4& getTexTransform() { 227 return texTransform; 228 } 229 getTransformLayer230 inline mat4& getTransform() { 231 return transform; 232 } 233 234 /** 235 * Bounds of the layer. 236 */ 237 Rect layer; 238 /** 239 * Texture coordinates of the layer. 240 */ 241 Rect texCoords; 242 243 /** 244 * Dirty region indicating what parts of the layer 245 * have been drawn. 246 */ 247 Region region; 248 /** 249 * If the region is a rectangle, coordinates of the 250 * region are stored here. 251 */ 252 Rect regionRect; 253 254 /** 255 * If the layer can be rendered as a mesh, this is non-null. 256 */ 257 TextureVertex* mesh; 258 uint16_t* meshIndices; 259 GLsizei meshElementCount; 260 261 /** 262 * Used for deferred updates. 263 */ 264 bool deferredUpdateScheduled; 265 OpenGLRenderer* renderer; 266 DisplayList* displayList; 267 Rect dirtyRect; 268 269 private: 270 /** 271 * Name of the FBO used to render the layer. If the name is 0 272 * this layer is not backed by an FBO, but a simple texture. 273 */ 274 GLuint fbo; 275 276 /** 277 * Indicates whether this layer has been used already. 278 */ 279 bool empty; 280 281 /** 282 * The texture backing this layer. 283 */ 284 Texture texture; 285 286 /** 287 * If set to true (by default), the layer can be reused. 288 */ 289 bool cacheable; 290 291 /** 292 * When set to true, this layer must be treated as a texture 293 * layer. 294 */ 295 bool textureLayer; 296 297 /** 298 * When set to true, this layer is dirty and should be cleared 299 * before any rendering occurs. 300 */ 301 bool dirty; 302 303 /** 304 * Indicates the render target. 305 */ 306 GLenum renderTarget; 307 308 /** 309 * Color filter used to draw this layer. Optional. 310 */ 311 SkiaColorFilter* colorFilter; 312 313 /** 314 * Opacity of the layer. 315 */ 316 int alpha; 317 /** 318 * Blending mode of the layer. 319 */ 320 SkXfermode::Mode mode; 321 322 /** 323 * Optional texture coordinates transform. 324 */ 325 mat4 texTransform; 326 327 /** 328 * Optional transform. 329 */ 330 mat4 transform; 331 332 }; // struct Layer 333 334 }; // namespace uirenderer 335 }; // namespace android 336 337 #endif // ANDROID_HWUI_LAYER_H 338