GLES20RenderEngine.cpp revision c6f216955966e93ea983ba800e651af3de6c90e3
13f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian/*
23f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian * Copyright 2013 The Android Open Source Project
33f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian *
43f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
53f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian * you may not use this file except in compliance with the License.
63f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian * You may obtain a copy of the License at
73f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian *
83f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
93f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian *
103f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian * Unless required by applicable law or agreed to in writing, software
113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
123f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian * See the License for the specific language governing permissions and
143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian * limitations under the License.
153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian */
163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#define ATRACE_TAG ATRACE_TAG_GRAPHICS
183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include <GLES2/gl2.h>
20458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian#include <GLES2/gl2ext.h>
213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include <utils/String8.h>
233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include <utils/Trace.h>
243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include <cutils/compiler.h>
263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "GLES20RenderEngine.h"
283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "Program.h"
293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "ProgramCache.h"
303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "Description.h"
313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "Mesh.h"
3249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian#include "Texture.h"
333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian// ---------------------------------------------------------------------------
353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopiannamespace android {
363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian// ---------------------------------------------------------------------------
373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
38ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias AgopianGLES20RenderEngine::GLES20RenderEngine() :
39ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mVpWidth(0), mVpHeight(0) {
403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glPixelStorei(GL_PACK_ALIGNMENT, 4);
463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    struct pack565 {
483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            return (r<<11)|(g<<5)|b;
503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        }
513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    } pack565;
523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
53c6f216955966e93ea983ba800e651af3de6c90e3Andy McFadden    const uint16_t protTexData[] = { 0 };
543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glGenTextures(1, &mProtectedTexName);
553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
573f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
593f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
62ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
63ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    //mColorBlindnessCorrection = M;
643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
663f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias AgopianGLES20RenderEngine::~GLES20RenderEngine() {
673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
703f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopiansize_t GLES20RenderEngine::getMaxTextureSize() const {
713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    return mMaxTextureSize;
723f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopiansize_t GLES20RenderEngine::getMaxViewportDims() const {
753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    return
763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        mMaxViewportDims[0] < mMaxViewportDims[1] ?
773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::setViewportAndProjection(
813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        size_t vpw, size_t vph, size_t w, size_t h, bool yswap) {
82a8c386f1c36e916c1df18d41a22104d655a89817Mathias Agopian    mat4 m;
83a8c386f1c36e916c1df18d41a22104d655a89817Mathias Agopian    if (yswap)  m = mat4::ortho(0, w, h, 0, 0, 1);
84a8c386f1c36e916c1df18d41a22104d655a89817Mathias Agopian    else        m = mat4::ortho(0, w, 0, h, 0, 1);
853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glViewport(0, 0, vpw, vph);
873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setProjectionMatrix(m);
88ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mVpWidth = vpw;
89ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mVpHeight = vph;
903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
923f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::setupLayerBlending(
933f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    bool premultipliedAlpha, bool opaque, int alpha) {
943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setPremultipliedAlpha(premultipliedAlpha);
963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setOpaque(opaque);
973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setPlaneAlpha(alpha / 255.0f);
983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    if (alpha < 0xFF || !opaque) {
1003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glEnable(GL_BLEND);
1013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    } else {
1033f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glDisable(GL_BLEND);
1043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
1053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1073f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::setupDimLayerBlending(int alpha) {
108bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.setPlaneAlpha(1.0f);
109bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.setPremultipliedAlpha(true);
110bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.setOpaque(false);
111bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.setColor(0, 0, 0, alpha/255.0f);
112bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.disableTexture();
1133f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1143f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    if (alpha == 0xFF) {
1153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glDisable(GL_BLEND);
1163f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    } else {
1173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glEnable(GL_BLEND);
1183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
1203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
12249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopianvoid GLES20RenderEngine::setupLayerTexturing(const Texture& texture) {
12349457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    GLuint target = texture.getTextureTarget();
12449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glBindTexture(target, texture.getTextureName());
1253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    GLenum filter = GL_NEAREST;
12649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    if (texture.getFiltering()) {
1273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        filter = GL_LINEAR;
1283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
12949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
13049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
13149457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
13249457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
1333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
13449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mState.setTexture(texture);
1353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::setupLayerBlackedOut() {
1383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
13949457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    Texture texture(Texture::TEXTURE_2D, mProtectedTexName);
14049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    texture.setDimensions(1, 1); // FIXME: we should get that from somewhere
14149457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mState.setTexture(texture);
1423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::disableTexturing() {
1453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.disableTexture();
1463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::disableBlending() {
1493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glDisable(GL_BLEND);
1503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
152458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
153458197de008be8fe561286b09f4edddb2f5c540aMathias Agopianvoid GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
154458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian        uint32_t* texName, uint32_t* fbName, uint32_t* status) {
155458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    GLuint tname, name;
156458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    // turn our EGLImage into a texture
157458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glGenTextures(1, &tname);
158458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
159458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
160458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
161458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    // create a Framebuffer Object to render into
162458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glGenFramebuffers(1, &name);
163458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glBindFramebuffer(GL_FRAMEBUFFER, name);
164ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
165458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
166458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    *status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
167458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    *texName = tname;
168458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    *fbName = name;
169458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian}
170458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
171458197de008be8fe561286b09f4edddb2f5c540aMathias Agopianvoid GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
172458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glBindFramebuffer(GL_FRAMEBUFFER, 0);
173458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glDeleteFramebuffers(1, &fbName);
174458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glDeleteTextures(1, &texName);
175458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian}
176458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
17719733a32799f792125913e746e8644d16f8dc223Mathias Agopianvoid GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
17819733a32799f792125913e746e8644d16f8dc223Mathias Agopian    mState.setPlaneAlpha(1.0f);
17919733a32799f792125913e746e8644d16f8dc223Mathias Agopian    mState.setPremultipliedAlpha(true);
18019733a32799f792125913e746e8644d16f8dc223Mathias Agopian    mState.setOpaque(false);
1813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setColor(r, g, b, a);
18219733a32799f792125913e746e8644d16f8dc223Mathias Agopian    mState.disableTexture();
1833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glDisable(GL_BLEND);
1843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::drawMesh(const Mesh& mesh) {
1873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    ProgramCache::getInstance().useProgram(mState);
1893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    if (mesh.getTexCoordsSize()) {
1913f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glEnableVertexAttribArray(Program::texCoords);
1923f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glVertexAttribPointer(Program::texCoords,
1933f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                mesh.getTexCoordsSize(),
1943f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                GL_FLOAT, GL_FALSE,
1953f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                mesh.getByteStride(),
1963f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                mesh.getTexCoords());
1973f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
1983f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1993f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glVertexAttribPointer(Program::position,
2003f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            mesh.getVertexSize(),
2013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            GL_FLOAT, GL_FALSE,
2023f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            mesh.getByteStride(),
2035cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian            mesh.getPositions());
2043f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2053f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
2063f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2073f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    if (mesh.getTexCoordsSize()) {
2083f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glDisableVertexAttribArray(Program::texCoords);
2093f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
2103f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
2113f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
212ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopianvoid GLES20RenderEngine::beginGroup(const mat4& colorTransform) {
213ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
214ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    GLuint tname, name;
215ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // create the texture
216ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glGenTextures(1, &tname);
217ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
218ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
219ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
220ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
221ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
222ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mVpWidth, mVpHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
223ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
224ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // create a Framebuffer Object to render into
225ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glGenFramebuffers(1, &name);
226ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glBindFramebuffer(GL_FRAMEBUFFER, name);
227ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
228ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
229ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Group group;
230ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.texture = tname;
231ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.fbo = name;
232ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.width = mVpWidth;
233ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.height = mVpHeight;
234ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.colorTransform = colorTransform;
235ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
236ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mGroupStack.push(group);
237ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian}
238ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
239ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopianvoid GLES20RenderEngine::endGroup() {
240ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
241ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    const Group group(mGroupStack.top());
242ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mGroupStack.pop();
243ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
244ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // activate the previous render target
245ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    GLuint fbo = 0;
246ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    if (!mGroupStack.isEmpty()) {
247ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        fbo = mGroupStack.top().fbo;
248ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    }
249ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
250ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
251ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // set our state
252ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Texture texture(Texture::TEXTURE_2D, group.texture);
253ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texture.setDimensions(group.width, group.height);
254ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glBindTexture(GL_TEXTURE_2D, group.texture);
255ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
256ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setPlaneAlpha(1.0f);
257ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setPremultipliedAlpha(true);
258ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setOpaque(false);
259ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setTexture(texture);
260ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setColorMatrix(group.colorTransform);
261ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glDisable(GL_BLEND);
262ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
263ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
264ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
265ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoord(mesh.getTexCoordArray<vec2>());
266ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = vec2(0, 0);
267ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = vec2(group.width, 0);
268ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = vec2(group.width, group.height);
269ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = vec2(0, group.height);
270ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoord[0] = vec2(0, 0);
271ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoord[1] = vec2(1, 0);
272ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoord[2] = vec2(1, 1);
273ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoord[3] = vec2(0, 1);
274ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    drawMesh(mesh);
275ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
276ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // reset color matrix
277ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setColorMatrix(mat4());
278ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
279ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // free our fbo and texture
280ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glDeleteFramebuffers(1, &group.fbo);
281ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glDeleteTextures(1, &group.texture);
282ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian}
283ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
2843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::dump(String8& result) {
285458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    RenderEngine::dump(result);
2863f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
2873f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2883f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian// ---------------------------------------------------------------------------
2893f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
2903f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian// ---------------------------------------------------------------------------
291458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
292458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian#if defined(__gl_h_)
293458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian#error "don't include gl/gl.h in this file"
294458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian#endif
295