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