Layer.h revision 9ace8f5e79e76893fe4ca9e4d10f6c4056330485
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 33namespace android { 34namespace uirenderer { 35 36/////////////////////////////////////////////////////////////////////////////// 37// Layers 38/////////////////////////////////////////////////////////////////////////////// 39 40/** 41 * A layer has dimensions and is backed by an OpenGL texture or FBO. 42 */ 43struct Layer { 44 Layer(const uint32_t layerWidth, const uint32_t layerHeight) { 45 mesh = NULL; 46 meshIndices = NULL; 47 meshElementCount = 0; 48 cacheable = true; 49 textureLayer = false; 50 renderTarget = GL_TEXTURE_2D; 51 texture.width = layerWidth; 52 texture.height = layerHeight; 53 colorFilter = NULL; 54 firstFilter = true; 55 firstWrap = true; 56 } 57 58 ~Layer() { 59 if (mesh) delete mesh; 60 if (meshIndices) delete meshIndices; 61 } 62 63 /** 64 * Sets this layer's region to a rectangle. Computes the appropriate 65 * texture coordinates. 66 */ 67 void setRegionAsRect() { 68 const android::Rect& bounds = region.getBounds(); 69 regionRect.set(bounds.leftTop().x, bounds.leftTop().y, 70 bounds.rightBottom().x, bounds.rightBottom().y); 71 72 const float texX = 1.0f / float(texture.width); 73 const float texY = 1.0f / float(texture.height); 74 const float height = layer.getHeight(); 75 texCoords.set( 76 regionRect.left * texX, (height - regionRect.top) * texY, 77 regionRect.right * texX, (height - regionRect.bottom) * texY); 78 79 regionRect.translate(layer.left, layer.top); 80 } 81 82 inline uint32_t getWidth() { 83 return texture.width; 84 } 85 86 inline uint32_t getHeight() { 87 return texture.height; 88 } 89 90 void setSize(uint32_t width, uint32_t height) { 91 texture.width = width; 92 texture.height = height; 93 } 94 95 inline void setBlend(bool blend) { 96 texture.blend = blend; 97 } 98 99 inline bool isBlend() { 100 return texture.blend; 101 } 102 103 inline void setAlpha(int alpha) { 104 this->alpha = alpha; 105 } 106 107 inline void setAlpha(int alpha, SkXfermode::Mode mode) { 108 this->alpha = alpha; 109 this->mode = mode; 110 } 111 112 inline int getAlpha() { 113 return alpha; 114 } 115 116 inline SkXfermode::Mode getMode() { 117 return mode; 118 } 119 120 inline void setEmpty(bool empty) { 121 this->empty = empty; 122 } 123 124 inline bool isEmpty() { 125 return empty; 126 } 127 128 inline void setFbo(GLuint fbo) { 129 this->fbo = fbo; 130 } 131 132 inline GLuint getFbo() { 133 return fbo; 134 } 135 136 inline GLuint* getTexturePointer() { 137 return &texture.id; 138 } 139 140 inline GLuint getTexture() { 141 return texture.id; 142 } 143 144 inline GLenum getRenderTarget() { 145 return renderTarget; 146 } 147 148 inline void setRenderTarget(GLenum renderTarget) { 149 this->renderTarget = renderTarget; 150 } 151 152 void setWrap(GLenum wrapS, GLenum wrapT, bool bindTexture = false, bool force = false) { 153 if (firstWrap || force || wrapS != texture.wrapS || wrapT != texture.wrapT) { 154 firstWrap = true; 155 texture.setWrap(wrapS, wrapT); 156 if (bindTexture) { 157 glBindTexture(renderTarget, texture.id); 158 } 159 glTexParameteri(renderTarget, GL_TEXTURE_WRAP_S, wrapS); 160 glTexParameteri(renderTarget, GL_TEXTURE_WRAP_T, wrapT); 161 } 162 } 163 164 void setFilter(GLenum min, GLenum mag, bool bindTexture = false, bool force = false) { 165 if (firstFilter || force || min != texture.minFilter || mag != texture.magFilter) { 166 firstFilter = false; 167 texture.setFilter(min, mag); 168 if (bindTexture) { 169 glBindTexture(renderTarget, texture.id); 170 } 171 glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min); 172 glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag); 173 } 174 } 175 176 inline bool isCacheable() { 177 return cacheable; 178 } 179 180 inline void setCacheable(bool cacheable) { 181 this->cacheable = cacheable; 182 } 183 184 inline bool isTextureLayer() { 185 return textureLayer; 186 } 187 188 inline void setTextureLayer(bool textureLayer) { 189 this->textureLayer = textureLayer; 190 } 191 192 inline SkiaColorFilter* getColorFilter() { 193 return colorFilter; 194 } 195 196 inline void setColorFilter(SkiaColorFilter* filter) { 197 colorFilter = filter; 198 } 199 200 inline void bindTexture() { 201 glBindTexture(renderTarget, texture.id); 202 } 203 204 inline void generateTexture() { 205 glGenTextures(1, &texture.id); 206 } 207 208 inline void deleteTexture() { 209 if (texture.id) glDeleteTextures(1, &texture.id); 210 } 211 212 inline void allocateTexture(GLenum format, GLenum storage) { 213 glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0, format, storage, NULL); 214 } 215 216 inline mat4& getTexTransform() { 217 return texTransform; 218 } 219 220 /** 221 * Bounds of the layer. 222 */ 223 Rect layer; 224 /** 225 * Texture coordinates of the layer. 226 */ 227 Rect texCoords; 228 229 /** 230 * Dirty region indicating what parts of the layer 231 * have been drawn. 232 */ 233 Region region; 234 /** 235 * If the region is a rectangle, coordinates of the 236 * region are stored here. 237 */ 238 Rect regionRect; 239 240 /** 241 * If the layer can be rendered as a mesh, this is non-null. 242 */ 243 TextureVertex* mesh; 244 uint16_t* meshIndices; 245 GLsizei meshElementCount; 246 247private: 248 /** 249 * Name of the FBO used to render the layer. If the name is 0 250 * this layer is not backed by an FBO, but a simple texture. 251 */ 252 GLuint fbo; 253 254 /** 255 * Indicates whether this layer has been used already. 256 */ 257 bool empty; 258 259 /** 260 * The texture backing this layer. 261 */ 262 Texture texture; 263 264 /** 265 * If set to true (by default), the layer can be reused. 266 */ 267 bool cacheable; 268 269 /** 270 * When set to true, this layer must be treated as a texture 271 * layer. 272 */ 273 bool textureLayer; 274 275 /** 276 * Indicates the render target. 277 */ 278 GLenum renderTarget; 279 280 /** 281 * Color filter used to draw this layer. Optional. 282 */ 283 SkiaColorFilter* colorFilter; 284 285 /** 286 * Opacity of the layer. 287 */ 288 int alpha; 289 /** 290 * Blending mode of the layer. 291 */ 292 SkXfermode::Mode mode; 293 294 /** 295 * Optional texture coordinates transform. 296 */ 297 mat4 texTransform; 298 299 bool firstFilter; 300 bool firstWrap; 301}; // struct Layer 302 303}; // namespace uirenderer 304}; // namespace android 305 306#endif // ANDROID_HWUI_LAYER_H 307