OpenGLRenderer.cpp revision bd6b79b40247aea7bfe13d0831c6c0472df6c636
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 30bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy#include <SkCanvas.h> 31c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy#include <SkPaint.h> 3285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <SkXfermode.h> 3385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy 3485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "OpenGLRenderer.h" 3585bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "Matrix.h" 36e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 37e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guynamespace android { 389d5316e3f56d138504565ff311145ac01621dff4Romain Guynamespace uirenderer { 399d5316e3f56d138504565ff311145ac01621dff4Romain Guy 409d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 419d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Defines 429d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 439d5316e3f56d138504565ff311145ac01621dff4Romain Guy 44bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy#define SV(x, y) { { x, y } } 45bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy#define FV(x, y, u, v) { { x, y }, { u, v } } 469d5316e3f56d138504565ff311145ac01621dff4Romain Guy 479d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 489d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Globals 499d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 509d5316e3f56d138504565ff311145ac01621dff4Romain Guy 51c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyconst SimpleVertex gDrawColorVertices[] = { 52bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy SV(0.0f, 0.0f), 53bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy SV(1.0f, 0.0f), 54bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy SV(0.0f, 1.0f), 55bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy SV(1.0f, 1.0f) 569d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; 57c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyconst GLsizei gDrawColorVertexStride = sizeof(SimpleVertex); 58c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyconst GLsizei gDrawColorVertexCount = 4; 599d5316e3f56d138504565ff311145ac01621dff4Romain Guy 60bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guyconst TextureVertex gDrawTextureVertices[] = { 61bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy FV(0.0f, 0.0f, 0.0f, 1.0f), 62bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy FV(1.0f, 0.0f, 1.0f, 1.0f), 63bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy FV(0.0f, 1.0f, 0.0f, 0.0f), 64bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy FV(1.0f, 1.0f, 1.0f, 0.0f) 65bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy}; 66bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guyconst GLsizei gDrawTextureVertexStride = sizeof(TextureVertex); 67bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guyconst GLsizei gDrawTextureVertexCount = 4; 68bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 699d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 709d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Shaders 719d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 729d5316e3f56d138504565ff311145ac01621dff4Romain Guy 739d5316e3f56d138504565ff311145ac01621dff4Romain Guy#define SHADER_SOURCE(name, source) const char* name = #source 749d5316e3f56d138504565ff311145ac01621dff4Romain Guy 759d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include "shaders/drawColor.vert" 769d5316e3f56d138504565ff311145ac01621dff4Romain Guy#include "shaders/drawColor.frag" 779d5316e3f56d138504565ff311145ac01621dff4Romain Guy 78bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy#include "shaders/drawTexture.vert" 79bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy#include "shaders/drawTexture.frag" 80bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 819d5316e3f56d138504565ff311145ac01621dff4Romain GuyProgram::Program(const char* vertex, const char* fragment) { 827ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy vertexShader = buildShader(vertex, GL_VERTEX_SHADER); 837ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); 847ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy 857ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy id = glCreateProgram(); 867ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glAttachShader(id, vertexShader); 877ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glAttachShader(id, fragmentShader); 887ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glLinkProgram(id); 897ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy 907ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy GLint status; 917ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glGetProgramiv(id, GL_LINK_STATUS, &status); 927ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy if (status != GL_TRUE) { 937ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy GLint infoLen = 0; 947ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen); 957ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy if (infoLen > 1) { 967ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy char* log = (char*) malloc(sizeof(char) * infoLen); 977ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glGetProgramInfoLog(id, infoLen, 0, log); 987ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy LOGE("Error while linking shaders: %s", log); 997ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy delete log; 1007ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 1017ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glDeleteProgram(id); 1027ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 1039d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1049d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1059d5316e3f56d138504565ff311145ac01621dff4Romain GuyProgram::~Program() { 1067ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glDeleteShader(vertexShader); 1077ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glDeleteShader(fragmentShader); 1087ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glDeleteProgram(id); 1099d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1109d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1119d5316e3f56d138504565ff311145ac01621dff4Romain Guyvoid Program::use() { 1127ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glUseProgram(id); 1139d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1149d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1159d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::addAttrib(const char* name) { 1167ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy int slot = glGetAttribLocation(id, name); 1177ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy attributes.add(name, slot); 1187ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return slot; 1199d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1209d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1219d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::getAttrib(const char* name) { 1227ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return attributes.valueFor(name); 1239d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1249d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1259d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::addUniform(const char* name) { 1267ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy int slot = glGetUniformLocation(id, name); 1277ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy uniforms.add(name, slot); 1287ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return slot; 1299d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1309d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1319d5316e3f56d138504565ff311145ac01621dff4Romain Guyint Program::getUniform(const char* name) { 1327ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return uniforms.valueFor(name); 1339d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1349d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1359d5316e3f56d138504565ff311145ac01621dff4Romain GuyGLuint Program::buildShader(const char* source, GLenum type) { 1367ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy GLuint shader = glCreateShader(type); 1377ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glShaderSource(shader, 1, &source, 0); 1387ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glCompileShader(shader); 1399d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1407ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy GLint status; 1417ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 1427ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy if (status != GL_TRUE) { 1437ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy // Some drivers return wrong values for GL_INFO_LOG_LENGTH 1447ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy // use a fixed size instead 1457ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy GLchar log[512]; 1467ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]); 1477ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy LOGE("Error while compiling shader: %s", log); 1487ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glDeleteShader(shader); 1497ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 1509d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1517ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return shader; 1529d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1539d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1549d5316e3f56d138504565ff311145ac01621dff4Romain GuyDrawColorProgram::DrawColorProgram(): 1557ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy Program(gDrawColorVertexShader, gDrawColorFragmentShader) { 156bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy getAttribsAndUniforms(); 157bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy} 158bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 159bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain GuyDrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment): 160bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy Program(vertex, fragment) { 161bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy getAttribsAndUniforms(); 162bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy} 163bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 164bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guyvoid DrawColorProgram::getAttribsAndUniforms() { 1657ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy position = addAttrib("position"); 1667ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy color = addAttrib("color"); 1677ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy projection = addUniform("projection"); 1687ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy modelView = addUniform("modelView"); 1697ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy transform = addUniform("transform"); 170c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy} 171c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy 172c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyvoid DrawColorProgram::use(const GLfloat* projectionMatrix, const GLfloat* modelViewMatrix, 173c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy const GLfloat* transformMatrix) { 1747ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy Program::use(); 1757ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glUniformMatrix4fv(projection, 1, GL_FALSE, projectionMatrix); 1767ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glUniformMatrix4fv(modelView, 1, GL_FALSE, modelViewMatrix); 1777ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glUniformMatrix4fv(transform, 1, GL_FALSE, transformMatrix); 1789d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 1799d5316e3f56d138504565ff311145ac01621dff4Romain Guy 180bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain GuyDrawTextureProgram::DrawTextureProgram(): 181bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) { 182bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy texCoords = addAttrib("texCoords"); 183bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy sampler = addUniform("sampler"); 184bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy} 185bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 1869d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 1879d5316e3f56d138504565ff311145ac01621dff4Romain Guy// Support 1889d5316e3f56d138504565ff311145ac01621dff4Romain Guy/////////////////////////////////////////////////////////////////////////////// 1899d5316e3f56d138504565ff311145ac01621dff4Romain Guy 1909d5316e3f56d138504565ff311145ac01621dff4Romain Guyconst Rect& Snapshot::getMappedClip() { 1917ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy if (flags & kFlagDirtyTransform) { 1927ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy flags &= ~kFlagDirtyTransform; 1937ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mappedClip.set(clipRect); 1947ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy transform.mapRect(mappedClip); 1957ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 1967ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return mappedClip; 1979d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 198e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 199f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 200f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Constructors/destructor 201f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 202f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 20385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain GuyOpenGLRenderer::OpenGLRenderer() { 20485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy LOGD("Create OpenGLRenderer"); 2059d5316e3f56d138504565ff311145ac01621dff4Romain Guy 2069d5316e3f56d138504565ff311145ac01621dff4Romain Guy mDrawColorShader = new DrawColorProgram; 207bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mDrawTextureShader = new DrawTextureProgram; 208e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 209e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 21085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain GuyOpenGLRenderer::~OpenGLRenderer() { 21185bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy LOGD("Destroy OpenGLRenderer"); 212e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 213e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 214f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 215f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Setup 216f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 217f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 21885bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::setViewport(int width, int height) { 21908ae317c21ec3086b5017672bba87420cc38a407Romain Guy glViewport(0, 0, width, height); 22008ae317c21ec3086b5017672bba87420cc38a407Romain Guy 22108ae317c21ec3086b5017672bba87420cc38a407Romain Guy mat4 ortho; 222c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy ortho.loadOrtho(0, width, height, 0, -1, 1); 22308ae317c21ec3086b5017672bba87420cc38a407Romain Guy ortho.copyTo(mOrthoMatrix); 224bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 225bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mWidth = width; 226bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mHeight = height; 227e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 228e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 22985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::prepare() { 2307ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot = &mFirstSnapshot; 2317ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSaveCount = 0; 232f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 23308ae317c21ec3086b5017672bba87420cc38a407Romain Guy glDisable(GL_SCISSOR_TEST); 234bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 23508ae317c21ec3086b5017672bba87420cc38a407Romain Guy glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 23608ae317c21ec3086b5017672bba87420cc38a407Romain Guy glClear(GL_COLOR_BUFFER_BIT); 237bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 23808ae317c21ec3086b5017672bba87420cc38a407Romain Guy glEnable(GL_SCISSOR_TEST); 239c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glScissor(0, 0, mWidth, mHeight); 240f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 241bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy mSnapshot->clipRect.set(0.0f, 0.0f, mWidth, mHeight); 242bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 243bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 244f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 245f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// State management 246f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 247f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 248bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::getSaveCount() const { 2497ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return mSaveCount; 250bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 251bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 252bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::save(int flags) { 2537ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return saveSnapshot(); 254bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 255bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 256bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::restore() { 2577ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy if (mSaveCount == 0) return; 258bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 2597ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy if (restoreSnapshot()) { 2607ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy setScissorFromClip(); 2617ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 262bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 263bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 264bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::restoreToCount(int saveCount) { 2657ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy if (saveCount <= 0 || saveCount > mSaveCount) return; 266bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 2677ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy bool restoreClip = false; 268bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 2697ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy while (mSaveCount != saveCount - 1) { 2707ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy restoreClip |= restoreSnapshot(); 2717ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 272bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 2737ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy if (restoreClip) { 2747ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy setScissorFromClip(); 2757ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 276bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 277bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 278bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::saveSnapshot() { 2797ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot = new Snapshot(mSnapshot); 2807ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return ++mSaveCount; 281bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 282bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 283bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guybool OpenGLRenderer::restoreSnapshot() { 2847ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet; 285bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy bool restoreLayer = mSnapshot->flags & Snapshot::kFlagIsLayer; 286bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 287bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy sp<Snapshot> current = mSnapshot; 2887ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy sp<Snapshot> previous = mSnapshot->previous; 289bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 290bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy if (restoreLayer) { 291bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // Unbind current FBO and restore previous one 292bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // Most of the time, previous->fbo will be 0 to bind the default buffer 293bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo); 294bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 295bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy const Rect& layer = current->layer; 296bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy clipRect(layer.left, layer.top, layer.right, layer.bottom); 297bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mSnapshot->transform.loadIdentity(); 298bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 299bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy drawTextureRect(0.0f, 0.0f, mWidth, mHeight, current->texture, current->alpha); 300bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 301bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glDeleteFramebuffers(1, ¤t->fbo); 302bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glDeleteTextures(1, ¤t->texture); 303bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy } 304bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 3057ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot = previous; 306bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mSaveCount--; 307bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 3087ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return restoreClip; 309bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 310bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 311f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 312bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy// Layers 313bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy/////////////////////////////////////////////////////////////////////////////// 314bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 315bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guyint OpenGLRenderer::saveLayer(float left, float top, float right, float bottom, 316bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy const SkPaint* p, int flags) { 317bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // TODO Implement 318bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy return saveSnapshot(); 319bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy} 320bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 321bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guyint OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bottom, 322bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy int alpha, int flags) { 323bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy int count = saveSnapshot(); 324bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 325bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mSnapshot->flags |= Snapshot::kFlagIsLayer; 326bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mSnapshot->alpha = alpha / 255.0f; 327bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mSnapshot->layer.set(left, top, right, bottom); 328bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 329bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // Generate the FBO and attach the texture 330bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glGenFramebuffers(1, &mSnapshot->fbo); 331bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glBindFramebuffer(GL_FRAMEBUFFER, mSnapshot->fbo); 332bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 333bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // Generate the texture in which the FBO will draw 334bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glGenTextures(1, &mSnapshot->texture); 335bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glBindTexture(GL_TEXTURE_2D, mSnapshot->texture); 336bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 337bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // The FBO will not be scaled, so we can use lower quality filtering 338bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 339bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 340bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 341bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // TODO ***** IMPORTANT ***** 342bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // Creating a texture-backed FBO works only if the texture is the same size 343bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // as the original rendering buffer (in this case, mWidth and mHeight.) 344bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // This is expensive and wasteful and must be fixed. 345bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 346bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy const GLsizei width = mWidth; //right - left; 347bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy const GLsizei height = mHeight; //bottom - right; 348bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 349bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy const GLint format = (flags & SkCanvas::kHasAlphaLayer_SaveFlag) ? GL_RGBA : GL_RGB; 350bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL); 351bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glBindTexture(GL_TEXTURE_2D, 0); 352bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 353bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // Bind texture to FBO 354bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 355bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mSnapshot->texture, 0); 356bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 357bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 358bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy if (status != GL_FRAMEBUFFER_COMPLETE) { 359bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy LOGD("Framebuffer incomplete %d", status); 360bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 361bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glDeleteFramebuffers(1, &mSnapshot->fbo); 362bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glDeleteTextures(1, &mSnapshot->texture); 363bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy } 364bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 365bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy return count; 366bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy} 367bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 368bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy/////////////////////////////////////////////////////////////////////////////// 369f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Transforms 370f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 371f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 372f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::translate(float dx, float dy) { 3737ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->transform.translate(dx, dy, 0.0f); 3747ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 375f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 376f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 377f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::rotate(float degrees) { 3787ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->transform.rotate(degrees, 0.0f, 0.0f, 1.0f); 3797ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 380f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 381f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 382f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::scale(float sx, float sy) { 3837ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->transform.scale(sx, sy, 1.0f); 3847ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 385f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 386f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 387f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::setMatrix(SkMatrix* matrix) { 3887ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->transform.load(*matrix); 3897ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 390f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 391f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 392f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::getMatrix(SkMatrix* matrix) { 3937ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->transform.copyTo(*matrix); 394f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 395f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 396f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guyvoid OpenGLRenderer::concatMatrix(SkMatrix* matrix) { 3977ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mat4 m(*matrix); 3987ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->transform.multiply(m); 3997ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->flags |= Snapshot::kFlagDirtyTransform; 400f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy} 401f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 402f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 403f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Clipping 404f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 405f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 406bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::setScissorFromClip() { 4077ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy const Rect& clip = mSnapshot->getMappedClip(); 4087ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy glScissor(clip.left, mHeight - clip.bottom, clip.getWidth(), clip.getHeight()); 4099d5316e3f56d138504565ff311145ac01621dff4Romain Guy} 4109d5316e3f56d138504565ff311145ac01621dff4Romain Guy 4119d5316e3f56d138504565ff311145ac01621dff4Romain Guyconst Rect& OpenGLRenderer::getClipBounds() { 4127ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return mSnapshot->clipRect; 413bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy} 414bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy 415c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guybool OpenGLRenderer::quickReject(float left, float top, float right, float bottom) { 416c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy /* 417c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * The documentation of quickReject() indicates that the specified rect 418c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * is transformed before being compared to the clip rect. However, the 419c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * clip rect is not stored transformed in the snapshot and can thus be 420c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * compared directly 421c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * 422c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * The following code can be used instead to performed a mapped comparison: 423c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * 424c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * mSnapshot->transform.mapRect(r); 425c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * const Rect& clip = mSnapshot->getMappedClip(); 426c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy * return !clip.intersects(r); 427c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy */ 428c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy 429c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy Rect r(left, top, right, bottom); 430c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy return !mSnapshot->clipRect.intersects(r); 431c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy} 432c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy 433bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guybool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) { 4347ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom); 4357ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy if (clipped) { 4367ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy mSnapshot->flags |= Snapshot::kFlagClipSet; 4377ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy setScissorFromClip(); 4387ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy } 4397ae7ac48aa2b53453c9805075171ecd5bcafd7deRomain Guy return clipped; 440e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy} 441e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy 442f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 443f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy// Drawing 444f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy/////////////////////////////////////////////////////////////////////////////// 445f6a11b8a9e25ff9861bbba19251bea84d8a5daf2Romain Guy 44685bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { 447c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy // TODO: Set the transfer mode 448c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy const Rect& clip = mSnapshot->clipRect; 449c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color); 450c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy} 4519d5316e3f56d138504565ff311145ac01621dff4Romain Guy 452bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guyvoid OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { 453c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy // TODO Support more than just color 454c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy // TODO: Set the transfer mode 455bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy drawColorRect(left, top, right, bottom, p->getColor()); 456c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy} 4579d5316e3f56d138504565ff311145ac01621dff4Romain Guy 458c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guyvoid OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, int color) { 459c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy GLfloat a = ((color >> 24) & 0xFF) / 255.0f; 460c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy GLfloat r = ((color >> 16) & 0xFF) / 255.0f; 461c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy GLfloat g = ((color >> 8) & 0xFF) / 255.0f; 462c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy GLfloat b = ((color ) & 0xFF) / 255.0f; 4639d5316e3f56d138504565ff311145ac01621dff4Romain Guy 464c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy mModelView.loadTranslate(left, top, 0.0f); 465c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy mModelView.scale(right - left, bottom - top, 1.0f); 4669d5316e3f56d138504565ff311145ac01621dff4Romain Guy 467c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy mDrawColorShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]); 4689d5316e3f56d138504565ff311145ac01621dff4Romain Guy 469c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy const GLvoid* p = &gDrawColorVertices[0].position[0]; 4709d5316e3f56d138504565ff311145ac01621dff4Romain Guy 471c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glEnableVertexAttribArray(mDrawColorShader->position); 472c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glVertexAttribPointer(mDrawColorShader->position, 2, GL_FLOAT, GL_FALSE, 473c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy gDrawColorVertexStride, p); 474c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glVertexAttrib4f(mDrawColorShader->color, r, g, b, a); 4759d5316e3f56d138504565ff311145ac01621dff4Romain Guy 476c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawColorVertexCount); 4779d5316e3f56d138504565ff311145ac01621dff4Romain Guy 478c7d53494f1fbd9f9d74af89053ff9fdb1ccbac6cRomain Guy glDisableVertexAttribArray(mDrawColorShader->position); 47985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy} 48085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy 481bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guyvoid OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, 482bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy GLuint texture, float alpha) { 483bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mModelView.loadTranslate(left, top, 0.0f); 484bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mModelView.scale(right - left, bottom - top, 1.0f); 485bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 486bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]); 487bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 488bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy // TODO Correctly set the blend function 489bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glEnable(GL_BLEND); 490bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 491bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 492bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glBindTexture(GL_TEXTURE_2D, texture); 493bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 494bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glActiveTexture(GL_TEXTURE0); 495bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glUniform1i(mDrawTextureShader->sampler, 0); 496bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 497bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy const GLvoid* p = &gDrawTextureVertices[0].position[0]; 498bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy const GLvoid* t = &gDrawTextureVertices[0].texture[0]; 499bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 500bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glEnableVertexAttribArray(mDrawTextureShader->position); 501bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glVertexAttribPointer(mDrawTextureShader->position, 2, GL_FLOAT, GL_FALSE, 502bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy gDrawTextureVertexStride, p); 503bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 504bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glEnableVertexAttribArray(mDrawTextureShader->texCoords); 505bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glVertexAttribPointer(mDrawTextureShader->texCoords, 2, GL_FLOAT, GL_FALSE, 506bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy gDrawTextureVertexStride, t); 507bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 508bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glVertexAttrib4f(mDrawTextureShader->color, 1.0f, 1.0f, 1.0f, alpha); 509bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 510bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawTextureVertexCount); 511bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 512bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glDisableVertexAttribArray(mDrawTextureShader->position); 513bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glDisableVertexAttribArray(mDrawTextureShader->texCoords); 514bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 515bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glBindTexture(GL_TEXTURE_2D, 0); 516bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy glDisable(GL_BLEND); 517bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy} 518bd6b79b40247aea7bfe13d0831c6c0472df6c636Romain Guy 5199d5316e3f56d138504565ff311145ac01621dff4Romain Guy}; // namespace uirenderer 520e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}; // namespace android 521