OpenGLRenderer.cpp revision c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6c
1e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy/* 2e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Copyright (C) 2010 The Android Open Source Project 3e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * 4e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * you may not use this file except in compliance with the License. 6e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * You may obtain a copy of the License at 7e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * 8e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 9e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * 10e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * Unless required by applicable law or agreed to in writing, software 11e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * See the License for the specific language governing permissions and 14e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy * limitations under the License. 15e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy */ 16e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 1785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#define LOG_TAG "OpenGLRenderer" 18e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 19e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <stdlib.h> 20e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <stdint.h> 21e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <sys/types.h> 22e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 23e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <utils/Errors.h> 249d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include <utils/KeyedVector.h> 25e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <utils/Log.h> 26e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 27e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <GLES2/gl2.h> 28e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <GLES2/gl2ext.h> 29e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 30c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy#include <SkPaint.h> 3185bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <SkXfermode.h> 3285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy 3385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "OpenGLRenderer.h" 3485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "Matrix.h" 35e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 36e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guynamespace android { 379d5316e3f56d138504565ff311145ac01621dff4Romain Guynamespace uirenderer { 389d5316e3f56d138504565ff311145ac01621dff4Romain Guy 399d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 409d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Defines 419d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 429d5316e3f56d138504565ff311145ac01621dff4Romain Guy 43c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy#define V(x, y) { { x, y } } 449d5316e3f56d138504565ff311145ac01621dff4Romain Guy 459d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 469d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Globals 479d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 489d5316e3f56d138504565ff311145ac01621dff4Romain Guy 49c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyconst SimpleVertex gDrawColorVertices[] = { 50c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy V(0.0f, 0.0f), 51c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy V(1.0f, 0.0f), 52c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy V(0.0f, 1.0f), 53c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy V(1.0f, 1.0f) 549d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; 55c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyconst GLsizei gDrawColorVertexStride = sizeof(SimpleVertex); 56c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyconst GLsizei gDrawColorVertexCount = 4; 579d5316e3f56d138504565ff311145ac01621dff4Romain Guy 589d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 599d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Shaders 609d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 619d5316e3f56d138504565ff311145ac01621dff4Romain Guy 629d5316e3f56d138504565ff311145ac01621dff4Romain Guy#define SHADER_SOURCE(name, source) const char* name = #source 639d5316e3f56d138504565ff311145ac01621dff4Romain Guy 649d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include "shaders/drawColor.vert" 659d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include "shaders/drawColor.frag" 669d5316e3f56d138504565ff311145ac01621dff4Romain Guy 679d5316e3f56d138504565ff311145ac01621dff4Romain GuyProgram::Program(const char* vertex, const char* fragment) { 689d5316e3f56d138504565ff311145ac01621dff4Romain Guy vertexShader = buildShader(vertex, GL_VERTEX_SHADER); 699d5316e3f56d138504565ff311145ac01621dff4Romain Guy fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); 709d5316e3f56d138504565ff311145ac01621dff4Romain Guy 719d5316e3f56d138504565ff311145ac01621dff4Romain Guy id = glCreateProgram(); 729d5316e3f56d138504565ff311145ac01621dff4Romain Guy glAttachShader(id, vertexShader); 739d5316e3f56d138504565ff311145ac01621dff4Romain Guy glAttachShader(id, fragmentShader); 749d5316e3f56d138504565ff311145ac01621dff4Romain Guy glLinkProgram(id); 759d5316e3f56d138504565ff311145ac01621dff4Romain Guy 769d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLint status; 779d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetProgramiv(id, GL_LINK_STATUS, &status); 789d5316e3f56d138504565ff311145ac01621dff4Romain Guy if (status != GL_TRUE) { 799d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLint infoLen = 0; 809d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen); 819d5316e3f56d138504565ff311145ac01621dff4Romain Guy if (infoLen > 1) { 829d5316e3f56d138504565ff311145ac01621dff4Romain Guy char* log = (char*) malloc(sizeof(char) * infoLen); 839d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetProgramInfoLog(id, infoLen, 0, log); 849d5316e3f56d138504565ff311145ac01621dff4Romain Guy LOGE("Error while linking shaders: %s", log); 859d5316e3f56d138504565ff311145ac01621dff4Romain Guy delete log; 869d5316e3f56d138504565ff311145ac01621dff4Romain Guy } 879d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteProgram(id); 889d5316e3f56d138504565ff311145ac01621dff4Romain Guy } 899d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 909d5316e3f56d138504565ff311145ac01621dff4Romain Guy 919d5316e3f56d138504565ff311145ac01621dff4Romain GuyProgram::~Program() { 929d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteShader(vertexShader); 939d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteShader(fragmentShader); 949d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteProgram(id); 959d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 969d5316e3f56d138504565ff311145ac01621dff4Romain Guy 979d5316e3f56d138504565ff311145ac01621dff4Romain Guyvoid Program::use() { 989d5316e3f56d138504565ff311145ac01621dff4Romain Guy glUseProgram(id); 999d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1009d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1019d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::addAttrib(const char* name) { 1029d5316e3f56d138504565ff311145ac01621dff4Romain Guy int slot = glGetAttribLocation(id, name); 1039d5316e3f56d138504565ff311145ac01621dff4Romain Guy attributes.add(name, slot); 1049d5316e3f56d138504565ff311145ac01621dff4Romain Guy return slot; 1059d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1069d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1079d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::getAttrib(const char* name) { 1089d5316e3f56d138504565ff311145ac01621dff4Romain Guy return attributes.valueFor(name); 1099d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1109d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1119d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::addUniform(const char* name) { 1129d5316e3f56d138504565ff311145ac01621dff4Romain Guy int slot = glGetUniformLocation(id, name); 1139d5316e3f56d138504565ff311145ac01621dff4Romain Guy uniforms.add(name, slot); 1149d5316e3f56d138504565ff311145ac01621dff4Romain Guy return slot; 1159d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1169d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1179d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::getUniform(const char* name) { 1189d5316e3f56d138504565ff311145ac01621dff4Romain Guy return uniforms.valueFor(name); 1199d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1209d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1219d5316e3f56d138504565ff311145ac01621dff4Romain GuyGLuint Program::buildShader(const char* source, GLenum type) { 1229d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLuint shader = glCreateShader(type); 1239d5316e3f56d138504565ff311145ac01621dff4Romain Guy glShaderSource(shader, 1, &source, 0); 1249d5316e3f56d138504565ff311145ac01621dff4Romain Guy glCompileShader(shader); 1259d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1269d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLint status; 1279d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 1289d5316e3f56d138504565ff311145ac01621dff4Romain Guy if (status != GL_TRUE) { 1299d5316e3f56d138504565ff311145ac01621dff4Romain Guy // Some drivers return wrong values for GL_INFO_LOG_LENGTH 1309d5316e3f56d138504565ff311145ac01621dff4Romain Guy // use a fixed size instead 1319d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLchar log[512]; 1329d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]); 1339d5316e3f56d138504565ff311145ac01621dff4Romain Guy LOGE("Error while compiling shader: %s", log); 1349d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteShader(shader); 1359d5316e3f56d138504565ff311145ac01621dff4Romain Guy } 1369d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1379d5316e3f56d138504565ff311145ac01621dff4Romain Guy return shader; 1389d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1399d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1409d5316e3f56d138504565ff311145ac01621dff4Romain GuyDrawColorProgram::DrawColorProgram(): 1419d5316e3f56d138504565ff311145ac01621dff4Romain Guy Program(gDrawColorVertexShader, gDrawColorFragmentShader) { 1429d5316e3f56d138504565ff311145ac01621dff4Romain Guy position = addAttrib("position"); 1439d5316e3f56d138504565ff311145ac01621dff4Romain Guy color = addAttrib("color"); 1449d5316e3f56d138504565ff311145ac01621dff4Romain Guy projection = addUniform("projection"); 1459d5316e3f56d138504565ff311145ac01621dff4Romain Guy modelView = addUniform("modelView"); 146c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy transform = addUniform("transform"); 147c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy} 148c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy 149c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyvoid DrawColorProgram::use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix, 150c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy const GLfloat* transformMatrix) { 151c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy Program::use(); 152c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glUniformMatrix4fv(projection, 1, GL_FALSE, projectionMatrix); 153c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glUniformMatrix4fv(modelView, 1, GL_FALSE, modelViewMatrix); 154c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glUniformMatrix4fv(transform, 1, GL_FALSE, transformMatrix); 1559d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1569d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1579d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 1589d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Support 1599d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 1609d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1619d5316e3f56d138504565ff311145ac01621dff4Romain Guyconst Rect& Snapshot::getMappedClip() { 1629d5316e3f56d138504565ff311145ac01621dff4Romain Guy if (flags & kFlagDirtyTransform) { 1639d5316e3f56d138504565ff311145ac01621dff4Romain Guy flags &= ~kFlagDirtyTransform; 1649d5316e3f56d138504565ff311145ac01621dff4Romain Guy mappedClip.set(clipRect); 1659d5316e3f56d138504565ff311145ac01621dff4Romain Guy transform.mapRect(mappedClip); 1669d5316e3f56d138504565ff311145ac01621dff4Romain Guy } 1679d5316e3f56d138504565ff311145ac01621dff4Romain Guy return mappedClip; 1689d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 169e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 170f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 171f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Constructors/destructor 172f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 173f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 17485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain GuyOpenGLRenderer::OpenGLRenderer() { 17585bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy LOGD("Create OpenGLRenderer"); 1769d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1779d5316e3f56d138504565ff311145ac01621dff4Romain Guy mDrawColorShader = new DrawColorProgram; 178e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 179e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 18085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain GuyOpenGLRenderer::~OpenGLRenderer() { 18185bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy LOGD("Destroy OpenGLRenderer"); 182e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 183e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 184f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 185f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Setup 186f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 187f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 18885bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::setViewport(int width, int height) { 18908ae317c21ec3086b5017672bba87420cc38a407Romain Guy glViewport(0, 0, width, height); 19008ae317c21ec3086b5017672bba87420cc38a407Romain Guy 19108ae317c21ec3086b5017672bba87420cc38a407Romain Guy mat4 ortho; 192c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy ortho.loadOrtho(0, width, height, 0, -1, 1); 19308ae317c21ec3086b5017672bba87420cc38a407Romain Guy ortho.copyTo(mOrthoMatrix); 194bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 195bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mWidth = width; 196bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mHeight = height; 197e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 198e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 19985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::prepare() { 200f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot = &mFirstSnapshot; 201f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSaveCount = 0; 202f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 20308ae317c21ec3086b5017672bba87420cc38a407Romain Guy glDisable(GL_SCISSOR_TEST); 204bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 20508ae317c21ec3086b5017672bba87420cc38a407Romain Guy glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 20608ae317c21ec3086b5017672bba87420cc38a407Romain Guy glClear(GL_COLOR_BUFFER_BIT); 207bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 20808ae317c21ec3086b5017672bba87420cc38a407Romain Guy glEnable(GL_SCISSOR_TEST); 209c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glScissor(0, 0, mWidth, mHeight); 210f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 211bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mSnapshot->clipRect.set(0.0f, 0.0f, mWidth, mHeight); 212bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 213bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 214f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 215f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// State management 216f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 217f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 218bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::getSaveCount() const { 219bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy return mSaveCount; 220bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 221bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 222bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::save(int flags) { 223bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy return saveSnapshot(); 224bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 225bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 226bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::restore() { 227bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (mSaveCount == 0) return; 228bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 229bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (restoreSnapshot()) { 230bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy setScissorFromClip(); 231bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy } 232bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 233bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 234bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::restoreToCount(int saveCount) { 235bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (saveCount <= 0 || saveCount > mSaveCount) return; 236bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 237bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy bool restoreClip = false; 238bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 239bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy while (mSaveCount != saveCount - 1) { 240bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy restoreClip |= restoreSnapshot(); 241bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy } 242bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 243bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (restoreClip) { 244bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy setScissorFromClip(); 245bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy } 246bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 247bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 248bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::saveSnapshot() { 249bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mSnapshot = new Snapshot(mSnapshot); 250f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy return ++mSaveCount; 251bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 252bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 253bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guybool OpenGLRenderer::restoreSnapshot() { 254bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; 255bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 256bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mSaveCount--; 257f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 258f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy // Do not merge these two lines! 259f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy sp<Snapshot> previous = mSnapshot->previous; 260f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot = previous; 261bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 262bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy return restoreClip; 263bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 264bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 265f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 266f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Transforms 267f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 268f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 269f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::translate(float dx, float dy) { 270f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.translate(dx, dy, 0.0f); 2719d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 272f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 273f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 274f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::rotate(float degrees) { 275f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f); 2769d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 277f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 278f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 279f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::scale(float sx, float sy) { 280f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.scale(sx, sy, 1.0f); 2819d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 282f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 283f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 284f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::setMatrix(SkMatrix* matrix) { 285f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.load(*matrix); 2869d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 287f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 288f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 289f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::getMatrix(SkMatrix* matrix) { 290f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.copyTo(*matrix); 291f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 292f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 293f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::concatMatrix(SkMatrix* matrix) { 294f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mat4 m(*matrix); 295f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.multiply(m); 2969d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 297f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 298f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 299f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 300f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Clipping 301f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 302f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 303bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::setScissorFromClip() { 3049d5316e3f56d138504565ff311145ac01621dff4Romain Guy const Rect& clip = mSnapshot->getMappedClip(); 305c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight()); 3069d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 3079d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3089d5316e3f56d138504565ff311145ac01621dff4Romain Guyconst Rect& OpenGLRenderer::getClipBounds() { 3099d5316e3f56d138504565ff311145ac01621dff4Romain Guy return mSnapshot->clipRect; 310bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 311bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 312c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guybool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) { 313c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy /* 314c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * The documentation of quickReject() indicates that the specified rect 315c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * is transformed before being compared to the clip rect. However, the 316c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * clip rect is not stored transformed in the snapshot and can thus be 317c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * compared directly 318c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * 319c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * The following code can be used instead to performed a mapped comparison: 320c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * 321c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * mSnapshot->transform.mapRect(r); 322c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * const Rect& clip = mSnapshot->getMappedClip(); 323c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * return !clip.intersects(r); 324c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy */ 325c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy 326c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy Rect r(left, top, right, bottom); 327c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy return !mSnapshot->clipRect.intersects(r); 328c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy} 329c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy 330bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guybool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) { 331bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom); 332bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (clipped) { 333bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mSnapshot->flags |= Snapshot::kFlagClipSet; 334bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy setScissorFromClip(); 335bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy } 336bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy return clipped; 337e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 338e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 339f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 340f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Drawing 341f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 342f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 34385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { 344c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy // TODO: Set the transfer mode 345c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy const Rect& clip = mSnapshot->clipRect; 346c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color); 347c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy} 3489d5316e3f56d138504565ff311145ac01621dff4Romain Guy 349c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyvoid OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* paint) { 350c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy // TODO Support more than just color 351c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy // TODO: Set the transfer mode 352c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy drawColorRect(left, top, right, bottom, paint->getColor()); 353c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy} 3549d5316e3f56d138504565ff311145ac01621dff4Romain Guy 355c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyvoid OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, int color) { 356c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy GLfloat a = ((color >> 24) & 0xFF) / 255.0f; 357c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy GLfloat r = ((color >> 16) & 0xFF) / 255.0f; 358c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy GLfloat g = ((color >> 8) & 0xFF) / 255.0f; 359c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy GLfloat b = ((color ) & 0xFF) / 255.0f; 3609d5316e3f56d138504565ff311145ac01621dff4Romain Guy 361c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy mModelView.loadTranslate(left, top, 0.0f); 362c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy mModelView.scale(right - left, bottom - top, 1.0f); 3639d5316e3f56d138504565ff311145ac01621dff4Romain Guy 364c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy mDrawColorShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]); 3659d5316e3f56d138504565ff311145ac01621dff4Romain Guy 366c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy const GLvoid* p = &gDrawColorVertices[0].position[0]; 3679d5316e3f56d138504565ff311145ac01621dff4Romain Guy 368c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glEnableVertexAttribArray(mDrawColorShader->position); 369c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE, 370c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy gDrawColorVertexStride, p); 371c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glVertexAttrib4f(mDrawColorShader->color, r, g, b, a); 3729d5316e3f56d138504565ff311145ac01621dff4Romain Guy 373c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawColorVertexCount); 3749d5316e3f56d138504565ff311145ac01621dff4Romain Guy 375c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glDisableVertexAttribArray(mDrawColorShader->position); 37685bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy} 37785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy 3789d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace uirenderer 379e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}; // namespace android 380