Reduced the complexity of layers composition.

This change also refactors the code base a bit by moving classes out of
OpenGLRenderer into separate headers/implementations. This makes the code
more manageable.

This change also adds documentation for implementation methods. The
undocumented methods are simply Skia's Canvas methods.

Change-Id: I54c68b443580a0129251dddc1a7ac95813d5289e
This commit is contained in:
Romain Guy
2010-06-27 22:59:20 -07:00
parent 1d58b498de
commit 5cbbce5357
8 changed files with 550 additions and 251 deletions

View File

@@ -3,7 +3,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
Matrix.cpp \
OpenGLRenderer.cpp
OpenGLRenderer.cpp \
Program.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#define LOG_TAG "Matrix"
#define LOG_TAG "OpenGLRenderer"
#include <math.h>
#include <stdlib.h>

View File

@@ -20,19 +20,11 @@
#include <stdint.h>
#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <SkCanvas.h>
#include <utils/Log.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <SkCanvas.h>
#include <SkPaint.h>
#include <SkXfermode.h>
#include "OpenGLRenderer.h"
#include "Matrix.h"
namespace android {
namespace uirenderer {
@@ -57,7 +49,7 @@ const SimpleVertex gDrawColorVertices[] = {
const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex);
const GLsizei gDrawColorVertexCount = 4;
const TextureVertex gDrawTextureVertices[] = {
TextureVertex gDrawTextureVertices[] = {
FV(0.0f, 0.0f, 0.0f, 1.0f),
FV(1.0f, 0.0f, 1.0f, 1.0f),
FV(0.0f, 1.0f, 0.0f, 0.0f),
@@ -66,134 +58,15 @@ const TextureVertex gDrawTextureVertices[] = {
const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex);
const GLsizei gDrawTextureVertexCount = 4;
///////////////////////////////////////////////////////////////////////////////
// Shaders
///////////////////////////////////////////////////////////////////////////////
#define SHADER_SOURCE(name, source) const char* name = #source
#include "shaders/drawColor.vert"
#include "shaders/drawColor.frag"
#include "shaders/drawTexture.vert"
#include "shaders/drawTexture.frag"
Program::Program(const char* vertex, const char* fragment) {
vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
id = glCreateProgram();
glAttachShader(id, vertexShader);
glAttachShader(id, fragmentShader);
glLinkProgram(id);
GLint status;
glGetProgramiv(id, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
GLint infoLen = 0;
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1) {
char* log = (char*) malloc(sizeof(char) * infoLen);
glGetProgramInfoLog(id, infoLen, 0, log);
LOGE("Error while linking shaders: %s", log);
delete log;
}
glDeleteProgram(id);
}
}
Program::~Program() {
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteProgram(id);
}
void Program::use() {
glUseProgram(id);
}
int Program::addAttrib(const char* name) {
int slot = glGetAttribLocation(id, name);
attributes.add(name, slot);
return slot;
}
int Program::getAttrib(const char* name) {
return attributes.valueFor(name);
}
int Program::addUniform(const char* name) {
int slot = glGetUniformLocation(id, name);
uniforms.add(name, slot);
return slot;
}
int Program::getUniform(const char* name) {
return uniforms.valueFor(name);
}
GLuint Program::buildShader(const char* source, GLenum type) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
// Some drivers return wrong values for GL_INFO_LOG_LENGTH
// use a fixed size instead
GLchar log[512];
glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]);
LOGE("Error while compiling shader: %s", log);
glDeleteShader(shader);
}
return shader;
}
DrawColorProgram::DrawColorProgram():
Program(gDrawColorVertexShader, gDrawColorFragmentShader) {
getAttribsAndUniforms();
}
DrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment):
Program(vertex, fragment) {
getAttribsAndUniforms();
}
void DrawColorProgram::getAttribsAndUniforms() {
position = addAttrib("position");
color = addAttrib("color");
projection = addUniform("projection");
modelView = addUniform("modelView");
transform = addUniform("transform");
}
void DrawColorProgram::use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix,
const GLfloat* transformMatrix) {
Program::use();
glUniformMatrix4fv(projection, 1, GL_FALSE, projectionMatrix);
glUniformMatrix4fv(modelView, 1, GL_FALSE, modelViewMatrix);
glUniformMatrix4fv(transform, 1, GL_FALSE, transformMatrix);
}
DrawTextureProgram::DrawTextureProgram():
DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) {
texCoords = addAttrib("texCoords");
sampler = addUniform("sampler");
}
///////////////////////////////////////////////////////////////////////////////
// Support
///////////////////////////////////////////////////////////////////////////////
const Rect& Snapshot::getMappedClip() {
if (flags & kFlagDirtyTransform) {
flags &= ~kFlagDirtyTransform;
mappedClip.set(clipRect);
transform.mapRect(mappedClip);
}
return mappedClip;
static inline void resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) {
gDrawTextureVertices[0].texture[0] = u1;
gDrawTextureVertices[0].texture[1] = v2;
gDrawTextureVertices[1].texture[0] = u2;
gDrawTextureVertices[1].texture[1] = v2;
gDrawTextureVertices[2].texture[0] = u1;
gDrawTextureVertices[2].texture[1] = v1;
gDrawTextureVertices[3].texture[0] = u2;
gDrawTextureVertices[3].texture[1] = v1;
}
///////////////////////////////////////////////////////////////////////////////
@@ -292,11 +165,28 @@ bool OpenGLRenderer::restoreSnapshot() {
// Most of the time, previous->fbo will be 0 to bind the default buffer
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
const Rect& layer = current->layer;
clipRect(layer.left, layer.top, layer.right, layer.bottom);
mSnapshot->transform.loadIdentity();
// Restore the clip from the previous snapshot
const Rect& clip = previous->getMappedClip();
glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight());
drawTextureRect(0.0f, 0.0f, mWidth, mHeight, current->texture, current->alpha);
// Compute the correct texture coordinates for the FBO texture
// The texture is currently as big as the window but drawn with
// a quad of the appropriate size
const Rect& layer = current->layer;
Rect texCoords(current->layer);
mSnapshot->transform.mapRect(texCoords);
const float u1 = texCoords.left / float(mWidth);
const float v1 = (mHeight - texCoords.top) / float(mHeight);
const float u2 = texCoords.right / float(mWidth);
const float v2 = (mHeight - texCoords.bottom) / float(mHeight);
resetDrawTextureTexCoords(u1, v1, u2, v1);
drawTextureRect(layer.left, layer.top, layer.right, layer.bottom,
current->texture, current->alpha);
resetDrawTextureTexCoords(0.0f, 1.0f, 1.0f, 0.0f);
glDeleteFramebuffers(1, &current->fbo);
glDeleteTextures(1, &current->texture);
@@ -337,11 +227,14 @@ int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bot
// The FBO will not be scaled, so we can use lower quality filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// TODO ***** IMPORTANT *****
// Creating a texture-backed FBO works only if the texture is the same size
// as the original rendering buffer (in this case, mWidth and mHeight.)
// This is expensive and wasteful and must be fixed.
// TODO Additionally we should use an FBO cache
const GLsizei width = mWidth; //right - left;
const GLsizei height = mHeight; //bottom - right;
@@ -425,7 +318,6 @@ bool OpenGLRenderer::quickReject(float left, float top, float right, float botto
* const Rect& clip = mSnapshot->getMappedClip();
* return !clip.intersects(r);
*/
Rect r(left, top, right, bottom);
return !mSnapshot->clipRect.intersects(r);
}
@@ -485,7 +377,7 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b
mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]);
// TODO Correctly set the blend function
// TODO Correctly set the blend function, based on texture format and xfermode
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

View File

@@ -23,11 +23,12 @@
#include <SkMatrix.h>
#include <SkXfermode.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include "Matrix.h"
#include "Program.h"
#include "Rect.h"
#include "Snapshot.h"
namespace android {
namespace uirenderer {
@@ -36,122 +37,30 @@ namespace uirenderer {
// Support
///////////////////////////////////////////////////////////////////////////////
class Snapshot: public LightRefBase<Snapshot> {
public:
Snapshot() {
}
Snapshot(const sp<Snapshot> s):
transform(s->transform),
clipRect(s->clipRect),
flags(kFlagDirtyTransform),
previous(s),
layer(0.0f, 0.0f, 0.0f, 0.0f),
texture(0),
fbo(0),
alpha(255) {
}
enum Flags {
kFlagClipSet = 0x1,
kFlagDirtyTransform = 0x2,
kFlagIsLayer = 0x4,
};
const Rect& getMappedClip();
// Local transformations
mat4 transform;
// Clipping rectangle at the time of this snapshot
Rect clipRect;
// Dirty flags
int flags;
// Previous snapshot in the frames stack
sp<Snapshot> previous;
// Layer, only set if kFlagIsLayer is set
Rect layer;
GLuint texture;
GLuint fbo;
float alpha;
private:
// Clipping rectangle mapped with the transform
Rect mappedClip;
}; // class Snapshot
/**
* Simple structure to describe a vertex with a position.
* This is used to draw filled rectangles without a texture.
*/
struct SimpleVertex {
float position[2];
}; // struct SimpleVertex
/**
* Simple structure to describe a vertex with a position and a texture.
*/
struct TextureVertex {
float position[2];
float texture[2];
}; // struct TextureVertex
class Program: public LightRefBase<Program> {
public:
Program(const char* vertex, const char* fragment);
~Program();
void use();
protected:
int addAttrib(const char* name);
int getAttrib(const char* name);
int addUniform(const char* name);
int getUniform(const char* name);
private:
GLuint buildShader(const char* source, GLenum type);
// Handle of the OpenGL program
GLuint id;
// Handles of the shaders
GLuint vertexShader;
GLuint fragmentShader;
// Keeps track of attributes and uniforms slots
KeyedVector<const char*, int> attributes;
KeyedVector<const char*, int> uniforms;
}; // class Program
class DrawColorProgram: public Program {
public:
DrawColorProgram();
DrawColorProgram(const char* vertex, const char* fragment);
void use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix,
const GLfloat* transformMatrix);
int position;
int color;
int projection;
int modelView;
int transform;
protected:
void getAttribsAndUniforms();
};
class DrawTextureProgram: public DrawColorProgram {
public:
DrawTextureProgram();
int sampler;
int texCoords;
};
///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////
/**
* OpenGL renderer used to draw accelerated 2D graphics. The API is a
* simplified version of Skia's Canvas API.
*/
class OpenGLRenderer {
public:
OpenGLRenderer();
@@ -184,12 +93,52 @@ public:
void drawRect(float left, float top, float right, float bottom, const SkPaint* paint);
private:
/**
* Saves the current state of the renderer as a new snapshot.
* The new snapshot is saved in mSnapshot and the previous snapshot
* is linked from mSnapshot->previous.
*
* @return The new save count. This value can be passed to #restoreToCount()
*/
int saveSnapshot();
/**
* Restores the current snapshot; mSnapshot becomes mSnapshot->previous.
*
* @return True if the clip should be also reapplied by calling
* #setScissorFromClip().
*/
bool restoreSnapshot();
/**
* Sets the clipping rectangle using glScissor. The clip is defined by
* the current snapshot's clipRect member.
*/
void setScissorFromClip();
/**
* Draws a colored rectangle with the specified color. The specified coordinates
* are transformed by the current snapshot's transform matrix.
*
* @param left The left coordinate of the rectangle
* @param top The top coordinate of the rectangle
* @param right The right coordinate of the rectangle
* @param bottom The bottom coordinate of the rectangle
* @param color The rectangle's ARGB color, defined as a packed 32 bits word
*/
void drawColorRect(float left, float top, float right, float bottom, int color);
/**
* Draws a textured rectangle with the specified texture. The specified coordinates
* are transformed by the current snapshot's transform matrix.
*
* @param left The left coordinate of the rectangle
* @param top The top coordinate of the rectangle
* @param right The right coordinate of the rectangle
* @param bottom The bottom coordinate of the rectangle
* @param texture The texture name to map onto the rectangle
* @param alpha An additional translucency parameter, between 0.0f and 1.0f
*/
void drawTextureRect(float left, float top, float right, float bottom, GLuint texture,
float alpha);

154
libs/hwui/Program.cpp Normal file
View File

@@ -0,0 +1,154 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "OpenGLRenderer"
#include "Program.h"
namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Shaders
///////////////////////////////////////////////////////////////////////////////
#define SHADER_SOURCE(name, source) const char* name = #source
#include "shaders/drawColor.vert"
#include "shaders/drawColor.frag"
#include "shaders/drawTexture.vert"
#include "shaders/drawTexture.frag"
///////////////////////////////////////////////////////////////////////////////
// Base program
///////////////////////////////////////////////////////////////////////////////
Program::Program(const char* vertex, const char* fragment) {
vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
id = glCreateProgram();
glAttachShader(id, vertexShader);
glAttachShader(id, fragmentShader);
glLinkProgram(id);
GLint status;
glGetProgramiv(id, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
GLint infoLen = 0;
glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen > 1) {
char* log = (char*) malloc(sizeof(char) * infoLen);
glGetProgramInfoLog(id, infoLen, 0, log);
LOGE("Error while linking shaders: %s", log);
delete log;
}
glDeleteProgram(id);
}
}
Program::~Program() {
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteProgram(id);
}
void Program::use() {
glUseProgram(id);
}
int Program::addAttrib(const char* name) {
int slot = glGetAttribLocation(id, name);
attributes.add(name, slot);
return slot;
}
int Program::getAttrib(const char* name) {
return attributes.valueFor(name);
}
int Program::addUniform(const char* name) {
int slot = glGetUniformLocation(id, name);
uniforms.add(name, slot);
return slot;
}
int Program::getUniform(const char* name) {
return uniforms.valueFor(name);
}
GLuint Program::buildShader(const char* source, GLenum type) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
// Some drivers return wrong values for GL_INFO_LOG_LENGTH
// use a fixed size instead
GLchar log[512];
glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]);
LOGE("Error while compiling shader: %s", log);
glDeleteShader(shader);
}
return shader;
}
///////////////////////////////////////////////////////////////////////////////
// Draw color
///////////////////////////////////////////////////////////////////////////////
DrawColorProgram::DrawColorProgram():
Program(gDrawColorVertexShader, gDrawColorFragmentShader) {
getAttribsAndUniforms();
}
DrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment):
Program(vertex, fragment) {
getAttribsAndUniforms();
}
void DrawColorProgram::getAttribsAndUniforms() {
position = addAttrib("position");
color = addAttrib("color");
projection = addUniform("projection");
modelView = addUniform("modelView");
transform = addUniform("transform");
}
void DrawColorProgram::use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix,
const GLfloat* transformMatrix) {
Program::use();
glUniformMatrix4fv(projection, 1, GL_FALSE, projectionMatrix);
glUniformMatrix4fv(modelView, 1, GL_FALSE, modelViewMatrix);
glUniformMatrix4fv(transform, 1, GL_FALSE, transformMatrix);
}
///////////////////////////////////////////////////////////////////////////////
// Draw texture
///////////////////////////////////////////////////////////////////////////////
DrawTextureProgram::DrawTextureProgram():
DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) {
texCoords = addAttrib("texCoords");
sampler = addUniform("sampler");
}
}; // namespace uirenderer
}; // namespace android

156
libs/hwui/Program.h Normal file
View File

@@ -0,0 +1,156 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_UI_PROGRAM_H
#define ANDROID_UI_PROGRAM_H
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
namespace android {
namespace uirenderer {
/**
* A program holds a vertex and a fragment shader. It offers several utility
* methods to query attributes and uniforms.
*/
class Program: public LightRefBase<Program> {
public:
/**
* Creates a new program with the specified vertex and fragment
* shaders sources.
*/
Program(const char* vertex, const char* fragment);
~Program();
/**
* Binds this program to the GL context.
*/
void use();
protected:
/**
* Adds an attribute with the specified name.
*
* @return The OpenGL name of the attribute.
*/
int addAttrib(const char* name);
/**
* Returns the OpenGL name of the specified attribute.
*/
int getAttrib(const char* name);
/**
* Adds a uniform with the specified name.
*
* @return The OpenGL name of the uniform.
*/
int addUniform(const char* name);
/**
* Returns the OpenGL name of the specified uniform.
*/
int getUniform(const char* name);
private:
/**
* Compiles the specified shader of the specified type.
*
* @return The name of the compiled shader.
*/
GLuint buildShader(const char* source, GLenum type);
// Name of the OpenGL program
GLuint id;
// Name of the shaders
GLuint vertexShader;
GLuint fragmentShader;
// Keeps track of attributes and uniforms slots
KeyedVector<const char*, int> attributes;
KeyedVector<const char*, int> uniforms;
}; // class Program
/**
* Program used to draw vertices with a simple color. The shaders must
* specify the following attributes:
* vec4 position, position of the vertex
* vec4 color, RGBA color of the vertex
*
* And the following uniforms:
* mat4 projection, the projection matrix
* mat4 modelView, the modelView matrix
* mat4 transform, an extra transformation matrix
*/
class DrawColorProgram: public Program {
public:
DrawColorProgram();
DrawColorProgram(const char* vertex, const char* fragment);
/**
* Binds the program with the specified projection, modelView and
* transform matrices.
*/
void use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix,
const GLfloat* transformMatrix);
/**
* Name of the position attribute.
*/
int position;
/**
* Name of the color attribute.
*/
int color;
/**
* Name of the projection uniform.
*/
int projection;
/**
* Name of the modelView uniform.
*/
int modelView;
/**
* Name of the transform uniform.
*/
int transform;
protected:
void getAttribsAndUniforms();
};
/**
* Program used to draw textured vertices. In addition to everything that the
* DrawColorProgram supports, the following two attributes must be specified:
* sampler2D sampler, the texture sampler
* vec2 texCoords, the texture coordinates of the vertex
*/
class DrawTextureProgram: public DrawColorProgram {
public:
DrawTextureProgram();
int sampler;
int texCoords;
};
}; // namespace uirenderer
}; // namespace android
#endif // ANDROID_UI_PROGRAM_H

View File

@@ -17,6 +17,8 @@
#ifndef ANDROID_UI_RECT_H
#define ANDROID_UI_RECT_H
#include <utils/Log.h>
namespace android {
namespace uirenderer {

145
libs/hwui/Snapshot.h Normal file
View File

@@ -0,0 +1,145 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_UI_SNAPSHOT_H
#define ANDROID_UI_SNAPSHOT_H
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <utils/RefBase.h>
#include "Matrix.h"
#include "Rect.h"
namespace android {
namespace uirenderer {
/**
* A snapshot holds information about the current state of the rendering
* surface. A snapshot is usually created whenever the user calls save()
* and discarded when the user calls restore(). Once a snapshot is created,
* it can hold information for deferred rendering.
*
* Each snapshot has a link to a previous snapshot, indicating the previous
* state of the renderer.
*/
class Snapshot: public LightRefBase<Snapshot> {
public:
Snapshot() {
}
/**
* Copies the specified snapshot. Only the transform and clip rectangle
* are copied. The layer information is set to 0 and the transform is
* assumed to be dirty. The specified snapshot is stored as the previous
* snapshot.
*/
Snapshot(const sp<Snapshot> s):
transform(s->transform),
clipRect(s->clipRect),
flags(kFlagDirtyTransform),
previous(s),
layer(0.0f, 0.0f, 0.0f, 0.0f),
texture(0),
fbo(0),
alpha(255) {
}
/**
* Various flags set on #flags.
*/
enum Flags {
/**
* Indicates that the clip region was modified. When this
* snapshot is restored so must the clip.
*/
kFlagClipSet = 0x1,
/**
* Indicates that the snapshot holds new transform
* information.
*/
kFlagDirtyTransform = 0x2,
/**
* Indicates that this snapshot was created when saving
* a new layer.
*/
kFlagIsLayer = 0x4,
};
/**
* Returns the current clip region mapped by the current transform.
*/
const Rect& getMappedClip() {
if (flags & kFlagDirtyTransform) {
flags &= ~kFlagDirtyTransform;
mappedClip.set(clipRect);
transform.mapRect(mappedClip);
}
return mappedClip;
}
/**
* Local transformation. Holds the current translation, scale and
* rotation values.
*/
mat4 transform;
/**
* Current clip region.
*/
Rect clipRect;
/**
* Dirty flags.
*/
int flags;
/**
* Previous snapshot.
*/
sp<Snapshot> previous;
/**
* Coordinates of the layer corresponding to this snapshot.
* Only set when the flag kFlagIsLayer is set.
*/
Rect layer;
/**
* Name of the texture used to render the layer.
* Only set when the flag kFlagIsLayer is set.
*/
GLuint texture;
/**
* Name of the FBO used to render the layer.
* Only set when the flag kFlagIsLayer is set.
*/
GLuint fbo;
/**
* Opacity of the layer.
* Only set when the flag kFlagIsLayer is set.
*/
float alpha;
private:
// Clipping rectangle mapped with the transform
Rect mappedClip;
}; // class Snapshot
}; // namespace uirenderer
}; // namespace android
#endif // ANDROID_UI_SNAPSHOT_H