OpenGLRenderer.cpp revision 9d5316e3f56d138504565ff311145ac01621dff4
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 3085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <SkXfermode.h> 3185bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy 3285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "OpenGLRenderer.h" 3385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "Matrix.h" 34e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 35e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guynamespace android { 369d5316e3f56d138504565ff311145ac01621dff4Romain Guynamespace uirenderer { 379d5316e3f56d138504565ff311145ac01621dff4Romain Guy 389d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 399d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Defines 409d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 419d5316e3f56d138504565ff311145ac01621dff4Romain Guy 429d5316e3f56d138504565ff311145ac01621dff4Romain Guy#define SOLID_WHITE { 1.0f, 1.0f, 1.0f, 1.0f } 439d5316e3f56d138504565ff311145ac01621dff4Romain Guy 449d5316e3f56d138504565ff311145ac01621dff4Romain Guy#define P(x, y) { x, y } 459d5316e3f56d138504565ff311145ac01621dff4Romain Guy 469d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 479d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Globals 489d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 499d5316e3f56d138504565ff311145ac01621dff4Romain Guy 509d5316e3f56d138504565ff311145ac01621dff4Romain Guyconst Vertex gDrawColorVertices[] = { 519d5316e3f56d138504565ff311145ac01621dff4Romain Guy { P(0.0f, 0.0f), SOLID_WHITE }, 529d5316e3f56d138504565ff311145ac01621dff4Romain Guy { P(1.0f, 0.0f), SOLID_WHITE }, 539d5316e3f56d138504565ff311145ac01621dff4Romain Guy { P(0.0f, 1.0f), SOLID_WHITE }, 549d5316e3f56d138504565ff311145ac01621dff4Romain Guy { P(1.0f, 1.0f), SOLID_WHITE } 559d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; 569d5316e3f56d138504565ff311145ac01621dff4Romain Guy 579d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 589d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Shaders 599d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 609d5316e3f56d138504565ff311145ac01621dff4Romain Guy 619d5316e3f56d138504565ff311145ac01621dff4Romain Guy#define SHADER_SOURCE(name, source) const char* name = #source 629d5316e3f56d138504565ff311145ac01621dff4Romain Guy 639d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include "shaders/drawColor.vert" 649d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include "shaders/drawColor.frag" 659d5316e3f56d138504565ff311145ac01621dff4Romain Guy 669d5316e3f56d138504565ff311145ac01621dff4Romain GuyProgram::Program(const char* vertex, const char* fragment) { 679d5316e3f56d138504565ff311145ac01621dff4Romain Guy vertexShader = buildShader(vertex, GL_VERTEX_SHADER); 689d5316e3f56d138504565ff311145ac01621dff4Romain Guy fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); 699d5316e3f56d138504565ff311145ac01621dff4Romain Guy 709d5316e3f56d138504565ff311145ac01621dff4Romain Guy id = glCreateProgram(); 719d5316e3f56d138504565ff311145ac01621dff4Romain Guy glAttachShader(id, vertexShader); 729d5316e3f56d138504565ff311145ac01621dff4Romain Guy glAttachShader(id, fragmentShader); 739d5316e3f56d138504565ff311145ac01621dff4Romain Guy glLinkProgram(id); 749d5316e3f56d138504565ff311145ac01621dff4Romain Guy 759d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLint status; 769d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetProgramiv(id, GL_LINK_STATUS, &status); 779d5316e3f56d138504565ff311145ac01621dff4Romain Guy if (status != GL_TRUE) { 789d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLint infoLen = 0; 799d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen); 809d5316e3f56d138504565ff311145ac01621dff4Romain Guy if (infoLen > 1) { 819d5316e3f56d138504565ff311145ac01621dff4Romain Guy char* log = (char*) malloc(sizeof(char) * infoLen); 829d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetProgramInfoLog(id, infoLen, 0, log); 839d5316e3f56d138504565ff311145ac01621dff4Romain Guy LOGE("Error while linking shaders: %s", log); 849d5316e3f56d138504565ff311145ac01621dff4Romain Guy delete log; 859d5316e3f56d138504565ff311145ac01621dff4Romain Guy } 869d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteProgram(id); 879d5316e3f56d138504565ff311145ac01621dff4Romain Guy } 889d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 899d5316e3f56d138504565ff311145ac01621dff4Romain Guy 909d5316e3f56d138504565ff311145ac01621dff4Romain GuyProgram::~Program() { 919d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteShader(vertexShader); 929d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteShader(fragmentShader); 939d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteProgram(id); 949d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 959d5316e3f56d138504565ff311145ac01621dff4Romain Guy 969d5316e3f56d138504565ff311145ac01621dff4Romain Guyvoid Program::use() { 979d5316e3f56d138504565ff311145ac01621dff4Romain Guy glUseProgram(id); 989d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 999d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1009d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::addAttrib(const char* name) { 1019d5316e3f56d138504565ff311145ac01621dff4Romain Guy int slot = glGetAttribLocation(id, name); 1029d5316e3f56d138504565ff311145ac01621dff4Romain Guy attributes.add(name, slot); 1039d5316e3f56d138504565ff311145ac01621dff4Romain Guy return slot; 1049d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1059d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1069d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::getAttrib(const char* name) { 1079d5316e3f56d138504565ff311145ac01621dff4Romain Guy return attributes.valueFor(name); 1089d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1099d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1109d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::addUniform(const char* name) { 1119d5316e3f56d138504565ff311145ac01621dff4Romain Guy int slot = glGetUniformLocation(id, name); 1129d5316e3f56d138504565ff311145ac01621dff4Romain Guy uniforms.add(name, slot); 1139d5316e3f56d138504565ff311145ac01621dff4Romain Guy return slot; 1149d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1159d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1169d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::getUniform(const char* name) { 1179d5316e3f56d138504565ff311145ac01621dff4Romain Guy return uniforms.valueFor(name); 1189d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1199d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1209d5316e3f56d138504565ff311145ac01621dff4Romain GuyGLuint Program::buildShader(const char* source, GLenum type) { 1219d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLuint shader = glCreateShader(type); 1229d5316e3f56d138504565ff311145ac01621dff4Romain Guy glShaderSource(shader, 1, &source, 0); 1239d5316e3f56d138504565ff311145ac01621dff4Romain Guy glCompileShader(shader); 1249d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1259d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLint status; 1269d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 1279d5316e3f56d138504565ff311145ac01621dff4Romain Guy if (status != GL_TRUE) { 1289d5316e3f56d138504565ff311145ac01621dff4Romain Guy // Some drivers return wrong values for GL_INFO_LOG_LENGTH 1299d5316e3f56d138504565ff311145ac01621dff4Romain Guy // use a fixed size instead 1309d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLchar log[512]; 1319d5316e3f56d138504565ff311145ac01621dff4Romain Guy glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]); 1329d5316e3f56d138504565ff311145ac01621dff4Romain Guy LOGE("Error while compiling shader: %s", log); 1339d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDeleteShader(shader); 1349d5316e3f56d138504565ff311145ac01621dff4Romain Guy } 1359d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1369d5316e3f56d138504565ff311145ac01621dff4Romain Guy return shader; 1379d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1389d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1399d5316e3f56d138504565ff311145ac01621dff4Romain GuyDrawColorProgram::DrawColorProgram(): 1409d5316e3f56d138504565ff311145ac01621dff4Romain Guy Program(gDrawColorVertexShader, gDrawColorFragmentShader) { 1419d5316e3f56d138504565ff311145ac01621dff4Romain Guy position = addAttrib("position"); 1429d5316e3f56d138504565ff311145ac01621dff4Romain Guy color = addAttrib("color"); 1439d5316e3f56d138504565ff311145ac01621dff4Romain Guy projection = addUniform("projection"); 1449d5316e3f56d138504565ff311145ac01621dff4Romain Guy modelView = addUniform("modelView"); 1459d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1469d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1479d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 1489d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Support 1499d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 1509d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1519d5316e3f56d138504565ff311145ac01621dff4Romain Guyconst Rect& Snapshot::getMappedClip() { 1529d5316e3f56d138504565ff311145ac01621dff4Romain Guy if (flags & kFlagDirtyTransform) { 1539d5316e3f56d138504565ff311145ac01621dff4Romain Guy flags &= ~kFlagDirtyTransform; 1549d5316e3f56d138504565ff311145ac01621dff4Romain Guy mappedClip.set(clipRect); 1559d5316e3f56d138504565ff311145ac01621dff4Romain Guy transform.mapRect(mappedClip); 1569d5316e3f56d138504565ff311145ac01621dff4Romain Guy } 1579d5316e3f56d138504565ff311145ac01621dff4Romain Guy return mappedClip; 1589d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 159e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 160f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 161f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Constructors/destructor 162f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 163f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 16485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain GuyOpenGLRenderer::OpenGLRenderer() { 16585bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy LOGD("Create OpenGLRenderer"); 1669d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1679d5316e3f56d138504565ff311145ac01621dff4Romain Guy mDrawColorShader = new DrawColorProgram; 168e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 169e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 17085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain GuyOpenGLRenderer::~OpenGLRenderer() { 17185bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy LOGD("Destroy OpenGLRenderer"); 172e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 173e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 174f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 175f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Setup 176f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 177f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 17885bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::setViewport(int width, int height) { 17908ae317c21ec3086b5017672bba87420cc38a407Romain Guy glViewport(0, 0, width, height); 18008ae317c21ec3086b5017672bba87420cc38a407Romain Guy 18108ae317c21ec3086b5017672bba87420cc38a407Romain Guy mat4 ortho; 18208ae317c21ec3086b5017672bba87420cc38a407Romain Guy ortho.loadOrtho(0, width, height, 0, 0, 1); 18308ae317c21ec3086b5017672bba87420cc38a407Romain Guy ortho.copyTo(mOrthoMatrix); 184bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 185bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mWidth = width; 186bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mHeight = height; 187e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 188e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 18985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::prepare() { 190f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot = &mFirstSnapshot; 191f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSaveCount = 0; 192f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 19308ae317c21ec3086b5017672bba87420cc38a407Romain Guy glDisable(GL_SCISSOR_TEST); 194bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 19508ae317c21ec3086b5017672bba87420cc38a407Romain Guy glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 19608ae317c21ec3086b5017672bba87420cc38a407Romain Guy glClear(GL_COLOR_BUFFER_BIT); 197bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 19808ae317c21ec3086b5017672bba87420cc38a407Romain Guy glEnable(GL_SCISSOR_TEST); 199f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 200bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mSnapshot->clipRect.set(0.0f, 0.0f, mWidth, mHeight); 201bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 202bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 203f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 204f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// State management 205f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 206f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 207bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::getSaveCount() const { 208bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy return mSaveCount; 209bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 210bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 211bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::save(int flags) { 212bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy return saveSnapshot(); 213bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 214bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 215bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::restore() { 216bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (mSaveCount == 0) return; 217bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 218bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (restoreSnapshot()) { 219bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy setScissorFromClip(); 220bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy } 221bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 222bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 223bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::restoreToCount(int saveCount) { 224bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (saveCount <= 0 || saveCount > mSaveCount) return; 225bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 226bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy bool restoreClip = false; 227bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 228bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy while (mSaveCount != saveCount - 1) { 229bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy restoreClip |= restoreSnapshot(); 230bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy } 231bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 232bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (restoreClip) { 233bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy setScissorFromClip(); 234bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy } 235bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 236bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 237bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::saveSnapshot() { 238bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mSnapshot = new Snapshot(mSnapshot); 239f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy return ++mSaveCount; 240bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 241bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 242bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guybool OpenGLRenderer::restoreSnapshot() { 243bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; 244bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 245bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mSaveCount--; 246f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 247f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy // Do not merge these two lines! 248f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy sp<Snapshot> previous = mSnapshot->previous; 249f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot = previous; 250bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 251bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy return restoreClip; 252bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 253bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 254f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 255f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Transforms 256f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 257f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 258f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::translate(float dx, float dy) { 259f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.translate(dx, dy, 0.0f); 2609d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 261f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 262f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 263f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::rotate(float degrees) { 264f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f); 2659d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 266f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 267f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 268f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::scale(float sx, float sy) { 269f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.scale(sx, sy, 1.0f); 2709d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 271f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 272f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 273f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::setMatrix(SkMatrix* matrix) { 274f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.load(*matrix); 2759d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 276f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 277f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 278f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::getMatrix(SkMatrix* matrix) { 279f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.copyTo(*matrix); 280f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 281f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 282f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::concatMatrix(SkMatrix* matrix) { 283f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mat4 m(*matrix); 284f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy mSnapshot->transform.multiply(m); 2859d5316e3f56d138504565ff311145ac01621dff4Romain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 286f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 287f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 288f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 289f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Clipping 290f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 291f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 292bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::setScissorFromClip() { 2939d5316e3f56d138504565ff311145ac01621dff4Romain Guy const Rect& clip = mSnapshot->getMappedClip(); 2949d5316e3f56d138504565ff311145ac01621dff4Romain Guy glScissor(clip.left, clip.top, clip.getWidth(), clip.getHeight()); 2959d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 2969d5316e3f56d138504565ff311145ac01621dff4Romain Guy 2979d5316e3f56d138504565ff311145ac01621dff4Romain Guyconst Rect& OpenGLRenderer::getClipBounds() { 2989d5316e3f56d138504565ff311145ac01621dff4Romain Guy return mSnapshot->clipRect; 299bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 300bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 301bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guybool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) { 302bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom); 303bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy if (clipped) { 304bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mSnapshot->flags |= Snapshot::kFlagClipSet; 305bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy setScissorFromClip(); 306bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy } 307bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy return clipped; 308e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 309e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 310f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 311f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Drawing 312f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 313f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 31485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { 3159d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLfloat a = ((color >> 24) & 0xFF) / 255.0f; 3169d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLfloat r = ((color >> 16) & 0xFF) / 255.0f; 3179d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLfloat g = ((color >> 8) & 0xFF) / 255.0f; 3189d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLfloat b = ((color ) & 0xFF) / 255.0f; 3199d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3209d5316e3f56d138504565ff311145ac01621dff4Romain Guy // TODO Optimize this section 3219d5316e3f56d138504565ff311145ac01621dff4Romain Guy const Rect& clip = mSnapshot->getMappedClip(); 3229d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3239d5316e3f56d138504565ff311145ac01621dff4Romain Guy mat4 modelView; 3249d5316e3f56d138504565ff311145ac01621dff4Romain Guy modelView.loadScale(clip.getWidth(), clip.getHeight(), 1.0f); 3259d5316e3f56d138504565ff311145ac01621dff4Romain Guy modelView.translate(clip.left, clip.top, 0.0f); 3269d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3279d5316e3f56d138504565ff311145ac01621dff4Romain Guy float matrix[16]; 3289d5316e3f56d138504565ff311145ac01621dff4Romain Guy modelView.copyTo(matrix); 3299d5316e3f56d138504565ff311145ac01621dff4Romain Guy // TODO Optimize this section 3309d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3319d5316e3f56d138504565ff311145ac01621dff4Romain Guy mDrawColorShader->use(); 3329d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3339d5316e3f56d138504565ff311145ac01621dff4Romain Guy glUniformMatrix4fv(mDrawColorShader->projection, 1, GL_FALSE, &mOrthoMatrix[0]); 3349d5316e3f56d138504565ff311145ac01621dff4Romain Guy glUniformMatrix4fv(mDrawColorShader->modelView, 1, GL_FALSE, &matrix[0]); 3359d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3369d5316e3f56d138504565ff311145ac01621dff4Romain Guy glEnableVertexAttribArray(mDrawColorShader->position); 3379d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3389d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLsizei stride = sizeof(Vertex); 3399d5316e3f56d138504565ff311145ac01621dff4Romain Guy const GLvoid* p = &gDrawColorVertices[0].position[0]; 3409d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3419d5316e3f56d138504565ff311145ac01621dff4Romain Guy glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE, stride, p); 3429d5316e3f56d138504565ff311145ac01621dff4Romain Guy glVertexAttrib4f(mDrawColorShader->color, r, g, b, a); 3439d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3449d5316e3f56d138504565ff311145ac01621dff4Romain Guy GLsizei vertexCount = sizeof(gDrawColorVertices) / sizeof(Vertex); 3459d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexCount); 3469d5316e3f56d138504565ff311145ac01621dff4Romain Guy 3479d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDisableVertexAttribArray(mDrawColorShader->position); 3489d5316e3f56d138504565ff311145ac01621dff4Romain Guy glDisableVertexAttribArray(mDrawColorShader->color); 34985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy} 35085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy 3519d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace uirenderer 352e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}; // namespace android 353