GLUtils.cpp revision 594c6b805969c2673c84d1d1d1a3556ce376ac7a
18612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/*
28612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * Copyright 2010, The Android Open Source Project
38612b3c490ba10449012086a45b9021daa488e65Nicolas Roard *
48612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * Redistribution and use in source and binary forms, with or without
58612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * modification, are permitted provided that the following conditions
68612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * are met:
78612b3c490ba10449012086a45b9021daa488e65Nicolas Roard *  * Redistributions of source code must retain the above copyright
88612b3c490ba10449012086a45b9021daa488e65Nicolas Roard *    notice, this list of conditions and the following disclaimer.
98612b3c490ba10449012086a45b9021daa488e65Nicolas Roard *  * Redistributions in binary form must reproduce the above copyright
108612b3c490ba10449012086a45b9021daa488e65Nicolas Roard *    notice, this list of conditions and the following disclaimer in the
118612b3c490ba10449012086a45b9021daa488e65Nicolas Roard *    documentation and/or other materials provided with the distribution.
128612b3c490ba10449012086a45b9021daa488e65Nicolas Roard *
138612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
148612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
178612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238612b3c490ba10449012086a45b9021daa488e65Nicolas Roard * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248612b3c490ba10449012086a45b9021daa488e65Nicolas Roard */
258612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
26d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#define LOG_TAG "GLUtils"
27d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#define LOG_NDEBUG 1
28d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik
298612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include "config.h"
308612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include "GLUtils.h"
318612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
328612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#if USE(ACCELERATED_COMPOSITING)
338612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
34594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "AndroidLog.h"
35594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "BaseRenderer.h"
368612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include "ShaderProgram.h"
37594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "TextureInfo.h"
38594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "Tile.h"
397c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#include "TilesManager.h"
40594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "TransferQueue.h"
418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
424f6d7d36d7c42018c2d5fcb76499539d1ccc2f97Mathias Agopian#include <android/native_window.h>
43dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu#include <gui/SurfaceTexture.h>
448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include <wtf/CurrentTime.h>
457c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
46c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu// We will limit GL error logging for LOG_VOLUME_PER_CYCLE times every
47c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu// LOG_VOLUME_PER_CYCLE seconds.
48c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#define LOG_CYCLE 30.0
49c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#define LOG_VOLUME_PER_CYCLE 20
50c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
51dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhustruct ANativeWindowBuffer;
52dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
538612b3c490ba10449012086a45b9021daa488e65Nicolas Roardnamespace WebCore {
548612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
558612b3c490ba10449012086a45b9021daa488e65Nicolas Roardusing namespace android;
568612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
578612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
588612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// Matrix utilities
598612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
608612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
618c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::toGLMatrix(GLfloat* flattened, const TransformationMatrix& m)
628c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
6374427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[0] = m.m11(); // scaleX
6474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[1] = m.m12(); // skewY
658612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[2] = m.m13();
6674427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[3] = m.m14(); // persp0
6774427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[4] = m.m21(); // skewX
6874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[5] = m.m22(); // scaleY
698612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[6] = m.m23();
7074427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[7] = m.m24(); // persp1
718612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[8] = m.m31();
728612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[9] = m.m32();
738612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[10] = m.m33();
748612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[11] = m.m34();
7574427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[12] = m.m41(); // transX
7674427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[13] = m.m42(); // transY
778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[14] = m.m43();
7874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[15] = m.m44(); // persp2
7974427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard}
8074427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard
818c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::toSkMatrix(SkMatrix& matrix, const TransformationMatrix& m)
828c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
8374427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[0] = m.m11(); // scaleX
8474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[1] = m.m21(); // skewX
8574427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[2] = m.m41(); // transX
8674427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[3] = m.m12(); // skewY
8774427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[4] = m.m22(); // scaleY
8874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[5] = m.m42(); // transY
8974427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[6] = m.m14(); // persp0
9074427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[7] = m.m24(); // persp1
9174427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[8] = m.m44(); // persp2
928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
948612b3c490ba10449012086a45b9021daa488e65Nicolas Roardvoid GLUtils::setOrthographicMatrix(TransformationMatrix& ortho, float left, float top,
958c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard                                    float right, float bottom, float nearZ, float farZ)
968c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    float deltaX = right - left;
98f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    float deltaY = top - bottom;
998612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    float deltaZ = farZ - nearZ;
100f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    if (!deltaX || !deltaY || !deltaZ)
101f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard        return;
1028612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1038612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM11(2.0f / deltaX);
1048612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM41(-(right + left) / deltaX);
105f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM22(2.0f / deltaY);
1068612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM42(-(top + bottom) / deltaY);
107f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM33(-2.0f / deltaZ);
108f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM43(-(nearZ + farZ) / deltaZ);
1098612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1108612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1118612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
1128612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// GL & EGL error checks
1138612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
1148612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
115c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhudouble GLUtils::m_previousLogTime = 0;
116c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhuint GLUtils::m_currentLogCounter = 0;
117c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
118c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhubool GLUtils::allowGLLog()
119c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu{
120c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    if (m_currentLogCounter < LOG_VOLUME_PER_CYCLE) {
121c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        m_currentLogCounter++;
122c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        return true;
123c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    }
124c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
125c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    // when we are in Log cycle and over the log limit, just return false
126c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    double currentTime = WTF::currentTime();
127c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    double delta = currentTime - m_previousLogTime;
128c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    bool inLogCycle = (delta <= LOG_CYCLE) && (delta > 0);
129c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    if (inLogCycle)
130c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        return false;
131c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
132c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    // When we are out of Log Cycle and over the log limit, we need to reset
133c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    // the counter and timer.
134c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    m_previousLogTime = currentTime;
135c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    m_currentLogCounter = 0;
136c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    return false;
137c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu}
138c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
139c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhustatic void crashIfOOM(GLint errorCode)
140c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu{
141f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    const GLint OOM_ERROR_CODE = 0x505;
142f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    if (errorCode == OOM_ERROR_CODE) {
143d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("ERROR: Fatal OOM detected.");
144f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        CRASH();
145f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    }
146f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch}
147f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch
1488c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::checkEglError(const char* op, EGLBoolean returnVal)
1498c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1507c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (returnVal != EGL_TRUE) {
151c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
152c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
153c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
154d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("EGL ERROR - %s() returned %d\n", op, returnVal);
1557c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    }
1568612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
157f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) {
158c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
159c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
160c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
161d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("after %s() eglError (0x%x)\n", op, error);
162f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
163f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    }
1648612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1658612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1668c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::checkGlError(const char* op)
1678c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1688612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bool ret = false;
1698612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    for (GLint error = glGetError(); error; error = glGetError()) {
170c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
171c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
172c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
173d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("GL ERROR - after %s() glError (0x%x)\n", op, error);
174f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
1758612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        ret = true;
1768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
1778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return ret;
1788612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1798612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1808c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::checkGlErrorOn(void* p, const char* op)
1818c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1828612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bool ret = false;
1838612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    for (GLint error = glGetError(); error; error = glGetError()) {
184c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
185c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
186c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
187d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("GL ERROR on %x - after %s() glError (0x%x)\n", p, op, error);
188f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
1898612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        ret = true;
1908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
1918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return ret;
1928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
194dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhuvoid GLUtils::checkSurfaceTextureError(const char* functionName, int status)
195dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu{
1967c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (status !=  NO_ERROR) {
197c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
198c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
199c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
200d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("ERROR at calling %s status is (%d)", functionName, status);
2017c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    }
202dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu}
2038612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
20413ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger// GL & EGL extension checks
20513ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////
20613ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
2078c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::isEGLImageSupported()
2088c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
20913ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
21013ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* glExtensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
21113ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
2128c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    return eglExtensions && glExtensions
2138c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(eglExtensions, "EGL_KHR_image_base")
2148c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image")
2158c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(glExtensions, "GL_OES_EGL_image");
21613ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger}
21713ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
2188c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::isEGLFenceSyncSupported()
2198c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
22013ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
221ba25389b2d1f3d6603ed1ea816278f91a4ca95c0Russell Brenner    return eglExtensions && strstr(eglExtensions, "EGL_KHR_fence_sync");
22213ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger}
22313ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
22413ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////
2258612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// Textures utilities
2268612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
2278612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2288612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic GLenum getInternalFormat(SkBitmap::Config config)
2298612b3c490ba10449012086a45b9021daa488e65Nicolas Roard{
2308c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    switch (config) {
2318c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kA8_Config:
2328c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_ALPHA;
2338c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_4444_Config:
2348c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGBA;
2358c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_8888_Config:
2368c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGBA;
2378c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kRGB_565_Config:
2388c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGB;
2398c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    default:
2408c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1;
2418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2448612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic GLenum getType(SkBitmap::Config config)
2458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard{
2468c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    switch (config) {
2478c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kA8_Config:
2488c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_BYTE;
2498c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_4444_Config:
2508c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_SHORT_4_4_4_4;
2518c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_8888_Config:
2528c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_BYTE;
2538c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kIndex8_Config:
2548c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1; // No type for compressed data.
2558c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kRGB_565_Config:
2568c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_SHORT_5_6_5;
2578c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    default:
2588c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1;
2598612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2608612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2618612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2628c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardstatic EGLConfig defaultPbufferConfig(EGLDisplay display)
2638c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
2648612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLConfig config;
2658612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint numConfigs;
2668612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2678612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    static const EGLint configAttribs[] = {
2688612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
2698612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
2708612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_NONE
2718612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
2728612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2738612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
2748612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkEglError("eglPbufferConfig");
2758c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    if (numConfigs != 1)
2766eb6ffadfb7e1afb3190f44e69e833c49d9f82acSteve Block        ALOGI("eglPbufferConfig failed (%d)\n", numConfigs);
2778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2788612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return config;
2798612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2808612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2818612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic EGLSurface createPbufferSurface(EGLDisplay display, const EGLConfig& config,
2828c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard                                       EGLint* errorCode)
2838c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
2848612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    const EGLint attribList[] = {
2858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_WIDTH, 1,
2868612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_HEIGHT, 1,
2878612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_NONE
2888612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
2898612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLSurface surface = eglCreatePbufferSurface(display, config, attribList);
2908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (errorCode)
2928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        *errorCode = eglGetError();
2938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    else
2948612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        GLUtils::checkEglError("eglCreatePbufferSurface");
2958612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (surface == EGL_NO_SURFACE)
2978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_SURFACE;
2988612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2998612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return surface;
3008612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3018612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3028c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas RoardEGLContext GLUtils::createBackgroundContext(EGLContext sharedContext)
3038c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
3048612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("<init>");
3058612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
3068612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglGetDisplay");
3078612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (display == EGL_NO_DISPLAY) {
308d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("eglGetDisplay returned EGL_NO_DISPLAY");
3098612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
3108612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
3118612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3128612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint majorVersion;
3138612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint minorVersion;
3148612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLBoolean returnValue = eglInitialize(display, &majorVersion, &minorVersion);
3158612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglInitialize", returnValue);
3168612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (returnValue != EGL_TRUE) {
317d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("eglInitialize failed\n");
3188612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
3198612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
3208612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3218612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLConfig config = defaultPbufferConfig(display);
3228612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLSurface surface = createPbufferSurface(display, config, 0);
3238612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3248612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint surfaceConfigId;
3258612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLBoolean success = eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &surfaceConfigId);
3268612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3278c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
3288c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    EGLContext context = eglCreateContext(display, config, sharedContext, contextAttribs);
3298612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglCreateContext");
3308612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (context == EGL_NO_CONTEXT) {
331d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("eglCreateContext failed\n");
3328612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
3338612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
3348612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3358612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    returnValue = eglMakeCurrent(display, surface, surface, context);
3368612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglMakeCurrent", returnValue);
3378612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (returnValue != EGL_TRUE) {
338d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("eglMakeCurrent failed\n");
3398612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
3408612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
3418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return context;
3438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3458c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::deleteTexture(GLuint* texture)
3468c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
3478612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glDeleteTextures(1, texture);
3488612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glDeleteTexture");
3498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    *texture = 0;
3508612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3518612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
352c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui ZhuGLuint GLUtils::createSampleColorTexture(int r, int g, int b)
353c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu{
3546edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLuint texture;
3556edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glGenTextures(1, &texture);
3566edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3576edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLubyte pixels[4 *3] = {
3586edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3596edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3606edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3616edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b
3626edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    };
3636edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
3646edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLUtils::checkGlError("glBindTexture");
3656edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
3666edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLUtils::checkGlError("glTexImage2D");
3676edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3686edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3696edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    return texture;
3706edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard}
3716edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard
3728c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas RoardGLuint GLUtils::createSampleTexture()
3738c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
3748612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLuint texture;
3758612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glGenTextures(1, &texture);
3768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLubyte pixels[4 *3] = {
3788612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        255, 0, 0,
3798612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        0, 255, 0,
3808612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        0, 0, 255,
3818612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        255, 255, 0
3828612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
3838612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
3848612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
3858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
3868612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glTexImage2D");
3878612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3888612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3898612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return texture;
3908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
392594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikGLuint GLUtils::createTileGLTexture(int width, int height)
3937c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu{
3947c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLuint texture;
3957c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glGenTextures(1, &texture);
3967c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3977c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLubyte* pixels = 0;
3987c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#ifdef DEBUG
3997c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    int length = width * height * 4;
4007c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    pixels = new GLubyte[length];
4017c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    for (int i = 0; i < length; i++)
4027c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        pixels[i] = i % 256;
4037c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#endif
4047c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glBindTexture(GL_TEXTURE_2D, texture);
4057c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLUtils::checkGlError("glBindTexture");
4067c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
4077c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLUtils::checkGlError("glTexImage2D");
4087c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4097c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
410be9cb848000fc47c0049a30dc167f4bb530835c1Teng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
411be9cb848000fc47c0049a30dc167f4bb530835c1Teng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
41217374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu#ifdef DEBUG
41317374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu    delete pixels;
41417374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu#endif
4157c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    return texture;
4167c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu}
4177c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
4188abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhubool GLUtils::isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor)
4198abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu{
420594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    // If the bitmap is the pure color, skip the transfer step, and update the Tile Info.
4218abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // This check is taking < 1ms if we do full bitmap check per tile.
4228abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // TODO: use the SkPicture to determine whether or not a tile is single color.
4238abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    pureColor = Color(Color::transparent);
4248abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bitmap.lockPixels();
4258abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bool sameColor = true;
4268abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int bitmapWidth = bitmap.width();
4278abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4288abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // Create a row of pure color using the first pixel.
429309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // TODO: improve the perf here, by either picking a random pixel, or
430309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // creating an array of rows with pre-defined commonly used color, add
431309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // smart LUT to speed things up if possible.
4328abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int* firstPixelPtr = static_cast<int*> (bitmap.getPixels());
4338abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int* pixelsRow = new int[bitmapWidth];
4348abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    for (int i = 0; i < bitmapWidth; i++)
4358abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        pixelsRow[i] = (*firstPixelPtr);
4368abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4378abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // Then compare the pure color row with each row of the bitmap.
4388abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    for (int j = 0; j < bitmap.height(); j++) {
4398abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        if (memcmp(pixelsRow, &firstPixelPtr[bitmapWidth * j], 4 * bitmapWidth)) {
4408abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            sameColor = false;
4418abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            break;
4428abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        }
4438abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4448abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    delete pixelsRow;
4458abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    pixelsRow = 0;
4468abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4478abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (sameColor) {
4488abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        char* rgbaPtr = static_cast<char*>(bitmap.getPixels());
4498abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        pureColor = Color(rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
450d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("sameColor tile found , %x at (%d, %d, %d, %d)",
451d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              *firstPixelPtr, rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
4528abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4538abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bitmap.unlockPixels();
4548abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4558abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    return sameColor;
4568abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu}
4578abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4588abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu// Return true when the tile is pure color.
4598abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhubool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo,
4608abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu                                       const SkBitmap& bitmap)
4618abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu{
4628abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bool skipTransfer = false;
463594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    Tile* tilePtr = renderInfo->baseTile;
4648abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
465c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    // TODO: use pure color for partial invals as well
466c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    if (renderInfo->invalRect)
467c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        return false;
468c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
4698abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (tilePtr) {
470594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik        TileTexture* tileTexture = tilePtr->backTexture();
4718abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        // Check the bitmap, and make everything ready here.
4726aea92fd5ffd5a43b1c13769be9a16202f498b59John Reck        if (tileTexture && renderInfo->isPureColor) {
4738abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // update basetile's info
4748abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // Note that we are skipping the whole TransferQueue.
475309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_width = bitmap.width();
476309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_height = bitmap.height();
477309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_internalFormat = GL_RGBA;
478309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu
4796aea92fd5ffd5a43b1c13769be9a16202f498b59John Reck            TilesManager::instance()->transferQueue()->addItemInPureColorQueue(renderInfo);
480309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu
481309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            skipTransfer = true;
4828abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        }
4838abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4848abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    return skipTransfer;
4858abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu}
4868abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4877c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhuvoid GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
4887c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu                                     const SkBitmap& bitmap)
489dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu{
4907c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (!renderInfo)
4917c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        return;
4927c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    const SkSize& requiredSize = renderInfo->tileSize;
4937c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    TextureInfo* textureInfo = renderInfo->textureInfo;
494ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger
4958abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (skipTransferForPureColor(renderInfo, bitmap))
4968abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        return;
4978abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
49862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    if (requiredSize.equals(textureInfo->m_width, textureInfo->m_height))
499a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        GLUtils::updateQueueWithBitmap(renderInfo, bitmap);
50062ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    else {
501ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        if (!requiredSize.equals(bitmap.width(), bitmap.height())) {
502d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik            ALOGV("The bitmap size (%d,%d) does not equal the texture size (%d,%d)",
503d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik                  bitmap.width(), bitmap.height(),
504d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik                  requiredSize.width(), requiredSize.height());
505ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        }
506a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        GLUtils::updateQueueWithBitmap(renderInfo, bitmap);
507ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger
508ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        textureInfo->m_width = bitmap.width();
509ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        textureInfo->m_height = bitmap.height();
5107c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        textureInfo->m_internalFormat = GL_RGBA;
511dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu    }
512dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu}
513dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
514a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reckvoid GLUtils::updateQueueWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap)
5157c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu{
5167c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (!renderInfo
5177c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        || !renderInfo->textureInfo
5187c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        || !renderInfo->baseTile)
5197c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        return;
5207c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
521c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, bitmap);
5227c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu}
523dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
524a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reckbool GLUtils::updateSharedSurfaceTextureWithBitmap(ANativeWindow* anw, const SkBitmap& bitmap)
525a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck{
526a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    SkAutoLockPixels alp(bitmap);
527a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    if (!bitmap.getPixels())
528a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        return false;
529a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    ANativeWindow_Buffer buffer;
530a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    if (ANativeWindow_lock(anw, &buffer, 0))
531a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        return false;
532821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck    if (buffer.width < bitmap.width() || buffer.height < bitmap.height()) {
533821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck        ALOGW("bitmap (%dx%d) too large for buffer (%dx%d)!",
534821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck                bitmap.width(), bitmap.height(),
535821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck                buffer.width, buffer.height);
536821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck        ANativeWindow_unlockAndPost(anw);
537a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        return false;
538821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck    }
539a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    uint8_t* img = (uint8_t*)buffer.bits;
540a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    int row;
541a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    int bpp = 4; // Now we only deal with RGBA8888 format.
542a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    bitmap.lockPixels();
543a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
544a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck
545a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    if (buffer.stride != bitmap.width())
546a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        // Copied line by line since we need to handle the offsets and stride.
547a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        for (row = 0 ; row < bitmap.height(); row ++) {
548a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck            uint8_t* dst = &(img[buffer.stride * row * bpp]);
549a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck            uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
550a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck            memcpy(dst, src, bpp * bitmap.width());
551a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        }
552a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    else
553a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        memcpy(img, bitmapOrigin, bpp * bitmap.width() * bitmap.height());
554a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck
555a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    bitmap.unlockPixels();
556a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    ANativeWindow_unlockAndPost(anw);
557a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    return true;
558a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck}
559a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck
560ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenbergervoid GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter)
5618c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
5628612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5638612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
5648612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
5658612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    SkBitmap::Config config = bitmap.getConfig();
5668612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    int internalformat = getInternalFormat(config);
5678612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    int type = getType(config);
5688612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bitmap.lockPixels();
5698612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, internalformat, bitmap.width(), bitmap.height(),
5708612b3c490ba10449012086a45b9021daa488e65Nicolas Roard                 0, internalformat, type, bitmap.getPixels());
5718612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bitmap.unlockPixels();
57244009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    if (GLUtils::checkGlError("glTexImage2D")) {
573c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
574c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
575c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
576d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("GL ERROR: glTexImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
577d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
578d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
57944009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    }
5808612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
5818612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
582bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard
583bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    // The following is a workaround -- remove when EGLImage texture upload is fixed.
584bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    GLuint fboID;
585bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glGenFramebuffers(1, &fboID);
586bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glBindFramebuffer(GL_FRAMEBUFFER, fboID);
587bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
588bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glCheckFramebufferStatus(GL_FRAMEBUFFER); // should return GL_FRAMEBUFFER_COMPLETE
589bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard
590bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO
591bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glDeleteFramebuffers(1, &fboID);
5928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
594c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roardvoid GLUtils::updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap,
595c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                                      const IntRect& inval, GLint filter)
59667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard{
59767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
59867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
59967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    GLUtils::checkGlError("glBindTexture");
60067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    SkBitmap::Config config = bitmap.getConfig();
60167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    int internalformat = getInternalFormat(config);
60267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    int type = getType(config);
60367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bitmap.lockPixels();
604c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    if (inval.isEmpty()) {
605c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
606c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                        internalformat, type, bitmap.getPixels());
607c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    } else {
608c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        glTexSubImage2D(GL_TEXTURE_2D, 0, inval.x(), inval.y(), inval.width(), inval.height(),
609c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                        internalformat, type, bitmap.getPixels());
610c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    }
61167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bitmap.unlockPixels();
61267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (GLUtils::checkGlError("glTexSubImage2D")) {
613c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
614c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
615c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
616d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
617d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
618d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
61967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
62067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
6218612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
6228612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
6238612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
6248c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::createEGLImageFromTexture(GLuint texture, EGLImageKHR* image)
6258c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
6268612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(texture);
6278612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    static const EGLint attr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
6288612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    *image = eglCreateImageKHR(eglGetCurrentDisplay(), eglGetCurrentContext(),
6298612b3c490ba10449012086a45b9021daa488e65Nicolas Roard                               EGL_GL_TEXTURE_2D_KHR, buffer, attr);
6308612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkEglError("eglCreateImage", (*image != EGL_NO_IMAGE_KHR));
6318612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
6328612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
6338c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter)
6348c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
6358612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
6368612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
6378612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
6388612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
6398612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
6408612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
6418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
642e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhuvoid GLUtils::convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix)
643e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu{
644e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu    transformMatrix.setMatrix(
645e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[0], matrix[1], matrix[2], matrix[3],
646e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[4], matrix[5], matrix[6], matrix[7],
647e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[8], matrix[9], matrix[10], matrix[11],
648e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[12], matrix[13], matrix[14], matrix[15]);
649e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu}
650e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu
651afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhuvoid GLUtils::clearBackgroundIfOpaque(const Color* backgroundColor)
652885e650b12d781be054b31ae6221925a0184dc33Chris Craik{
653afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    if (!backgroundColor->hasAlpha()) {
654afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        if (TilesManager::instance()->invertedScreen()) {
655afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu            float color = 1.0 - ((((float) backgroundColor->red() / 255.0) +
656afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                          ((float) backgroundColor->green() / 255.0) +
657afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                          ((float) backgroundColor->blue() / 255.0)) / 3.0);
658afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu            glClearColor(color, color, color, 1);
659afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        } else {
660afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu            glClearColor((float)backgroundColor->red() / 255.0,
661afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                         (float)backgroundColor->green() / 255.0,
662afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                         (float)backgroundColor->blue() / 255.0, 1);
663afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        }
664afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        glClear(GL_COLOR_BUFFER_BIT);
665885e650b12d781be054b31ae6221925a0184dc33Chris Craik    }
666885e650b12d781be054b31ae6221925a0184dc33Chris Craik}
667885e650b12d781be054b31ae6221925a0184dc33Chris Craik
6688612b3c490ba10449012086a45b9021daa488e65Nicolas Roard} // namespace WebCore
6698612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
6708612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
671