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
22c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza#include <ui/Rect.h>
23c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include <utils/String8.h>
253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include <utils/Trace.h>
263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include <cutils/compiler.h>
28c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews#include <gui/ISurfaceComposer.h>
29c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews#include <math.h>
303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "GLES20RenderEngine.h"
323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "Program.h"
333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "ProgramCache.h"
343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "Description.h"
353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian#include "Mesh.h"
3649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian#include "Texture.h"
373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian// ---------------------------------------------------------------------------
393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopiannamespace android {
403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian// ---------------------------------------------------------------------------
413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
42ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias AgopianGLES20RenderEngine::GLES20RenderEngine() :
43ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        mVpWidth(0), mVpHeight(0) {
443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
463f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glPixelStorei(GL_PACK_ALIGNMENT, 4);
503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    struct pack565 {
523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        inline uint16_t operator() (int r, int g, int b) const {
533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            return (r<<11)|(g<<5)|b;
543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        }
553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    } pack565;
563f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
57c6f216955966e93ea983ba800e651af3de6c90e3Andy McFadden    const uint16_t protTexData[] = { 0 };
583f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glGenTextures(1, &mProtectedTexName);
593f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
603f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
623f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
633f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
643f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
653f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
66ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
67ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    //mColorBlindnessCorrection = M;
683f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
703f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias AgopianGLES20RenderEngine::~GLES20RenderEngine() {
713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
723f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
733f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
743f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopiansize_t GLES20RenderEngine::getMaxTextureSize() const {
753f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    return mMaxTextureSize;
763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopiansize_t GLES20RenderEngine::getMaxViewportDims() const {
793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    return
803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        mMaxViewportDims[0] < mMaxViewportDims[1] ?
813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::setViewportAndProjection(
85c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap,
86c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        Transform::orientation_flags rotation) {
87c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
88c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    size_t l = sourceCrop.left;
89c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    size_t r = sourceCrop.right;
90c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
91c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    // In GL, (0, 0) is the bottom-left corner, so flip y coordinates
92c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    size_t t = hwh - sourceCrop.top;
93c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    size_t b = hwh - sourceCrop.bottom;
94c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza
95a8c386f1c36e916c1df18d41a22104d655a89817Mathias Agopian    mat4 m;
96c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    if (yswap) {
97c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        m = mat4::ortho(l, r, t, b, 0, 1);
98c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    } else {
99c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza        m = mat4::ortho(l, r, b, t, 0, 1);
100c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    }
1013f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
102c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    // Apply custom rotation to the projection.
103c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
104c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    switch (rotation) {
105c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case Transform::ROT_0:
106c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
107c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case Transform::ROT_90:
108c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            m = mat4::rotate(rot90InRadians, vec3(0,0,1)) * m;
109c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
110c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case Transform::ROT_180:
111c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            m = mat4::rotate(rot90InRadians * 2.0f, vec3(0,0,1)) * m;
112c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
113c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        case Transform::ROT_270:
114c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            m = mat4::rotate(rot90InRadians * 3.0f, vec3(0,0,1)) * m;
115c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
116c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        default:
117c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews            break;
118c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    }
119c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
1203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glViewport(0, 0, vpw, vph);
1213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setProjectionMatrix(m);
122ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mVpWidth = vpw;
123ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mVpHeight = vph;
1243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::setupLayerBlending(
1273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    bool premultipliedAlpha, bool opaque, int alpha) {
1283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setPremultipliedAlpha(premultipliedAlpha);
1303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setOpaque(opaque);
1313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setPlaneAlpha(alpha / 255.0f);
1323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    if (alpha < 0xFF || !opaque) {
1343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glEnable(GL_BLEND);
1353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glBlendFunc(premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    } else {
1373f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glDisable(GL_BLEND);
1383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
1393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::setupDimLayerBlending(int alpha) {
142bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.setPlaneAlpha(1.0f);
143bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.setPremultipliedAlpha(true);
144bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.setOpaque(false);
145bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.setColor(0, 0, 0, alpha/255.0f);
146bcab7b17b1c5476935a6f2f916922b4eb57991a4Mathias Agopian    mState.disableTexture();
1473f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1483f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    if (alpha == 0xFF) {
1493f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glDisable(GL_BLEND);
1503f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    } else {
1513f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glEnable(GL_BLEND);
1523f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1533f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
1543f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1553f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
15649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopianvoid GLES20RenderEngine::setupLayerTexturing(const Texture& texture) {
15749457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    GLuint target = texture.getTextureTarget();
15849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glBindTexture(target, texture.getTextureName());
1593f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    GLenum filter = GL_NEAREST;
16049457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    if (texture.getFiltering()) {
1613f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        filter = GL_LINEAR;
1623f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
16349457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
16449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
16549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
16649457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
1673f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
16849457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mState.setTexture(texture);
1693f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1703f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1713f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::setupLayerBlackedOut() {
1723f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
17349457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    Texture texture(Texture::TEXTURE_2D, mProtectedTexName);
17449457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    texture.setDimensions(1, 1); // FIXME: we should get that from somewhere
17549457ac092071a8f964f7f69156093657ccdc3d0Mathias Agopian    mState.setTexture(texture);
1763f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1773f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1783f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::disableTexturing() {
1793f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.disableTexture();
1803f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1813f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
1823f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::disableBlending() {
1833f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glDisable(GL_BLEND);
1843f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
1853f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
186458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
187458197de008be8fe561286b09f4edddb2f5c540aMathias Agopianvoid GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
188458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian        uint32_t* texName, uint32_t* fbName, uint32_t* status) {
189458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    GLuint tname, name;
190458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    // turn our EGLImage into a texture
191458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glGenTextures(1, &tname);
192458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
193458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
194458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
195458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    // create a Framebuffer Object to render into
196458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glGenFramebuffers(1, &name);
197458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glBindFramebuffer(GL_FRAMEBUFFER, name);
198ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
199458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
200458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    *status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
201458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    *texName = tname;
202458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    *fbName = name;
203458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian}
204458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
205458197de008be8fe561286b09f4edddb2f5c540aMathias Agopianvoid GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
206458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glBindFramebuffer(GL_FRAMEBUFFER, 0);
207458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glDeleteFramebuffers(1, &fbName);
208458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    glDeleteTextures(1, &texName);
209458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian}
210458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
21119733a32799f792125913e746e8644d16f8dc223Mathias Agopianvoid GLES20RenderEngine::setupFillWithColor(float r, float g, float b, float a) {
21219733a32799f792125913e746e8644d16f8dc223Mathias Agopian    mState.setPlaneAlpha(1.0f);
21319733a32799f792125913e746e8644d16f8dc223Mathias Agopian    mState.setPremultipliedAlpha(true);
21419733a32799f792125913e746e8644d16f8dc223Mathias Agopian    mState.setOpaque(false);
2153f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    mState.setColor(r, g, b, a);
21619733a32799f792125913e746e8644d16f8dc223Mathias Agopian    mState.disableTexture();
2173f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glDisable(GL_BLEND);
2183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
2193f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::drawMesh(const Mesh& mesh) {
2213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    ProgramCache::getInstance().useProgram(mState);
2233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    if (mesh.getTexCoordsSize()) {
2253f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glEnableVertexAttribArray(Program::texCoords);
2263f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glVertexAttribPointer(Program::texCoords,
2273f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                mesh.getTexCoordsSize(),
2283f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                GL_FLOAT, GL_FALSE,
2293f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                mesh.getByteStride(),
2303f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian                mesh.getTexCoords());
2313f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
2323f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2333f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glVertexAttribPointer(Program::position,
2343f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            mesh.getVertexSize(),
2353f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            GL_FLOAT, GL_FALSE,
2363f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian            mesh.getByteStride(),
2375cdc8994a0ecd751a6350b16a1bef8b6b0d09b11Mathias Agopian            mesh.getPositions());
2383f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2393f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
2403f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
2413f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    if (mesh.getTexCoordsSize()) {
2423f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian        glDisableVertexAttribArray(Program::texCoords);
2433f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian    }
2443f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
2453f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
246ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopianvoid GLES20RenderEngine::beginGroup(const mat4& colorTransform) {
247ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
248ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    GLuint tname, name;
249ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // create the texture
250ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glGenTextures(1, &tname);
251ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glBindTexture(GL_TEXTURE_2D, tname);
252ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
253ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
254ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
255ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
256ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mVpWidth, mVpHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
257ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
258ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // create a Framebuffer Object to render into
259ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glGenFramebuffers(1, &name);
260ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glBindFramebuffer(GL_FRAMEBUFFER, name);
261ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
262ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
263ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Group group;
264ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.texture = tname;
265ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.fbo = name;
266ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.width = mVpWidth;
267ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.height = mVpHeight;
268ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    group.colorTransform = colorTransform;
269ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
270ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mGroupStack.push(group);
271ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian}
272ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
273ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopianvoid GLES20RenderEngine::endGroup() {
274ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
275ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    const Group group(mGroupStack.top());
276ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mGroupStack.pop();
277ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
278ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // activate the previous render target
279ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    GLuint fbo = 0;
280ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    if (!mGroupStack.isEmpty()) {
281ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian        fbo = mGroupStack.top().fbo;
282ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    }
283ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
284ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
285ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // set our state
286ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Texture texture(Texture::TEXTURE_2D, group.texture);
287ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texture.setDimensions(group.width, group.height);
288ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glBindTexture(GL_TEXTURE_2D, group.texture);
289ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
290ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setPlaneAlpha(1.0f);
291ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setPremultipliedAlpha(true);
292ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setOpaque(false);
293ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setTexture(texture);
294ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setColorMatrix(group.colorTransform);
295ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glDisable(GL_BLEND);
296ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
297ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
298ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
299ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    Mesh::VertexArray<vec2> texCoord(mesh.getTexCoordArray<vec2>());
300ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[0] = vec2(0, 0);
301ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[1] = vec2(group.width, 0);
302ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[2] = vec2(group.width, group.height);
303ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    position[3] = vec2(0, group.height);
304ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoord[0] = vec2(0, 0);
305ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoord[1] = vec2(1, 0);
306ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoord[2] = vec2(1, 1);
307ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    texCoord[3] = vec2(0, 1);
308ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    drawMesh(mesh);
309ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
310ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // reset color matrix
311ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    mState.setColorMatrix(mat4());
312ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
313ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    // free our fbo and texture
314ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glDeleteFramebuffers(1, &group.fbo);
315ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian    glDeleteTextures(1, &group.texture);
316ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian}
317ff2ed70fa30f04b90dd1a2c06ec2319e157152d7Mathias Agopian
3183f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopianvoid GLES20RenderEngine::dump(String8& result) {
319458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian    RenderEngine::dump(result);
3203f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}
3213f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian
3223f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian// ---------------------------------------------------------------------------
3233f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian}; // namespace android
3243f84483382be2d528918cc1a6fbc6a7d68e0b181Mathias Agopian// ---------------------------------------------------------------------------
325458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian
326458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian#if defined(__gl_h_)
327458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian#error "don't include gl/gl.h in this file"
328458197de008be8fe561286b09f4edddb2f5c540aMathias Agopian#endif
329