OpenGLRenderer.cpp revision bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4
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>
24e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <utils/Log.h>
25e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
26e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <GLES2/gl2.h>
27e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy#include <GLES2/gl2ext.h>
28e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
2985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include <SkXfermode.h>
3085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
3185bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "OpenGLRenderer.h"
3285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy#include "Matrix.h"
33e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
34e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guynamespace android {
35e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
3685bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain GuyOpenGLRenderer::OpenGLRenderer() {
3785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy    LOGD("Create OpenGLRenderer");
38bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
39bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    mSnapshot = new Snapshot;
40bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    mSaveCount = 0;
41e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
42e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
4385bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain GuyOpenGLRenderer::~OpenGLRenderer() {
4485bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy    LOGD("Destroy OpenGLRenderer");
45e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
46e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
4785bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::setViewport(int width, int height) {
4808ae317c21ec3086b5017672bba87420cc38a407Romain Guy    glViewport(0, 0, width, height);
4908ae317c21ec3086b5017672bba87420cc38a407Romain Guy
5008ae317c21ec3086b5017672bba87420cc38a407Romain Guy    mat4 ortho;
5108ae317c21ec3086b5017672bba87420cc38a407Romain Guy    ortho.loadOrtho(0, width, height, 0, 0, 1);
5208ae317c21ec3086b5017672bba87420cc38a407Romain Guy    ortho.copyTo(mOrthoMatrix);
53bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
54bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    mWidth = width;
55bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    mHeight = height;
56e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
57e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
5885bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::prepare() {
5908ae317c21ec3086b5017672bba87420cc38a407Romain Guy    glDisable(GL_SCISSOR_TEST);
60bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
6108ae317c21ec3086b5017672bba87420cc38a407Romain Guy    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6208ae317c21ec3086b5017672bba87420cc38a407Romain Guy    glClear(GL_COLOR_BUFFER_BIT);
63bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
6408ae317c21ec3086b5017672bba87420cc38a407Romain Guy    glEnable(GL_SCISSOR_TEST);
65bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy    mSnapshot->clipRect.set(0.0f, 0.0f, mWidth, mHeight);
66bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
67bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
68bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::getSaveCount() const {
69bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	return mSaveCount;
70bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
71bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
72bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::save(int flags) {
73bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	return saveSnapshot();
74bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
75bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
76bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::restore() {
77bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	if (mSaveCount == 0) return;
78bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
79bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	if (restoreSnapshot()) {
80bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy		setScissorFromClip();
81bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	}
82bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
83bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
84bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::restoreToCount(int saveCount) {
85bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	if (saveCount <= 0 || saveCount > mSaveCount) return;
86bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
87bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	bool restoreClip = false;
88bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
89bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	while (mSaveCount != saveCount - 1) {
90bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy		restoreClip |= restoreSnapshot();
91bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	}
92bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
93bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	if (restoreClip) {
94bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy		setScissorFromClip();
95bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	}
96bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
97bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
98bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyint OpenGLRenderer::saveSnapshot() {
99bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	mSnapshot = new Snapshot(mSnapshot);
100bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	mSaveCount++;
101bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	return mSaveCount;
102bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
103bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
104bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guybool OpenGLRenderer::restoreSnapshot() {
105bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	// TODO: handle local transformations
106bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet;
107bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
108bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	mSaveCount--;
109bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	mSnapshot = mSnapshot->previous;
110bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
111bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	return restoreClip;
112bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
113bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
114bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guyvoid OpenGLRenderer::setScissorFromClip() {
115bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	Rect clip = mSnapshot->clipRect;
116bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	glScissor(clip.left, clip.top, clip.getWidth(), clip.getHeight());
117bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy}
118bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy
119bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guybool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) {
120bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	// TODO: take local translate transform into account
121bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	bool clipped = mSnapshot->clipRect.intersect(left, top, right, bottom);
122bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	if (clipped) {
123bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy		mSnapshot->flags |= Snapshot::kFlagClipSet;
124bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy		setScissorFromClip();
125bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	}
126bb9524b6bdddc7ac77d8628daa8b366b8a7be4a4Romain Guy	return clipped;
127e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}
128e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy
12985bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guyvoid OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
13085bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy	LOGD("Drawing color");
13185bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy}
13285bf02fc16784d935fb9eebfa9cb20fe46ff7951Romain Guy
133e4d011201cea40d46cb2b2eef401db8fddc5c9c6Romain Guy}; // namespace android
134