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