GLUtils.cpp revision c08a6b03cd13c774ec0e475ac4813ac1ae1738e5
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
268612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include "config.h"
278612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include "GLUtils.h"
288612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
298612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#if USE(ACCELERATED_COMPOSITING)
308612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
318612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include "ShaderProgram.h"
327c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#include "TilesManager.h"
338612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
348612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include <cutils/log.h>
35dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu#include <gui/SurfaceTexture.h>
368612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include <wtf/CurrentTime.h>
378612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include <wtf/text/CString.h>
388612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
39c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard#undef XLOGC
40c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "GLUtils", __VA_ARGS__)
41c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
42c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard#ifdef DEBUG
43c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#undef XLOG
458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLUtils", __VA_ARGS__)
468612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
477c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#else
487c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
497c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#undef XLOG
507c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#define XLOG(...)
517c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
527c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#endif // DEBUG
537c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
54c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu// We will limit GL error logging for LOG_VOLUME_PER_CYCLE times every
55c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu// LOG_VOLUME_PER_CYCLE seconds.
56c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#define LOG_CYCLE 30.0
57c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#define LOG_VOLUME_PER_CYCLE 20
58c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
59dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhustruct ANativeWindowBuffer;
60dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
618612b3c490ba10449012086a45b9021daa488e65Nicolas Roardnamespace WebCore {
628612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
638612b3c490ba10449012086a45b9021daa488e65Nicolas Roardusing namespace android;
648612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
658612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
668612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// Matrix utilities
678612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
688612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
698c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::toGLMatrix(GLfloat* flattened, const TransformationMatrix& m)
708c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
7174427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[0] = m.m11(); // scaleX
7274427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[1] = m.m12(); // skewY
738612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[2] = m.m13();
7474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[3] = m.m14(); // persp0
7574427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[4] = m.m21(); // skewX
7674427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[5] = m.m22(); // scaleY
778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[6] = m.m23();
7874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[7] = m.m24(); // persp1
798612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[8] = m.m31();
808612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[9] = m.m32();
818612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[10] = m.m33();
828612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[11] = m.m34();
8374427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[12] = m.m41(); // transX
8474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[13] = m.m42(); // transY
858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[14] = m.m43();
8674427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[15] = m.m44(); // persp2
8774427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard}
8874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard
898c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::toSkMatrix(SkMatrix& matrix, const TransformationMatrix& m)
908c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
9174427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[0] = m.m11(); // scaleX
9274427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[1] = m.m21(); // skewX
9374427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[2] = m.m41(); // transX
9474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[3] = m.m12(); // skewY
9574427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[4] = m.m22(); // scaleY
9674427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[5] = m.m42(); // transY
9774427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[6] = m.m14(); // persp0
9874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[7] = m.m24(); // persp1
9974427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[8] = m.m44(); // persp2
1008612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1018612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1028612b3c490ba10449012086a45b9021daa488e65Nicolas Roardvoid GLUtils::setOrthographicMatrix(TransformationMatrix& ortho, float left, float top,
1038c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard                                    float right, float bottom, float nearZ, float farZ)
1048c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1058612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    float deltaX = right - left;
106f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    float deltaY = top - bottom;
1078612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    float deltaZ = farZ - nearZ;
108f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    if (!deltaX || !deltaY || !deltaZ)
109f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard        return;
1108612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1118612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM11(2.0f / deltaX);
1128612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM41(-(right + left) / deltaX);
113f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM22(2.0f / deltaY);
1148612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM42(-(top + bottom) / deltaY);
115f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM33(-2.0f / deltaZ);
116f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM43(-(nearZ + farZ) / deltaZ);
1178612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1188612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1198612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
1208612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// GL & EGL error checks
1218612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
1228612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
123c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhudouble GLUtils::m_previousLogTime = 0;
124c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhuint GLUtils::m_currentLogCounter = 0;
125c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
126c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhubool GLUtils::allowGLLog()
127c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu{
128c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    if (m_currentLogCounter < LOG_VOLUME_PER_CYCLE) {
129c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        m_currentLogCounter++;
130c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        return true;
131c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    }
132c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
133c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    // when we are in Log cycle and over the log limit, just return false
134c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    double currentTime = WTF::currentTime();
135c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    double delta = currentTime - m_previousLogTime;
136c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    bool inLogCycle = (delta <= LOG_CYCLE) && (delta > 0);
137c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    if (inLogCycle)
138c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        return false;
139c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
140c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    // When we are out of Log Cycle and over the log limit, we need to reset
141c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    // the counter and timer.
142c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    m_previousLogTime = currentTime;
143c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    m_currentLogCounter = 0;
144c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    return false;
145c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu}
146c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
147c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhustatic void crashIfOOM(GLint errorCode)
148c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu{
149f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    const GLint OOM_ERROR_CODE = 0x505;
150f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    if (errorCode == OOM_ERROR_CODE) {
151c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        XLOGC("ERROR: Fatal OOM detected.");
152f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        CRASH();
153f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    }
154f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch}
155f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch
1568c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::checkEglError(const char* op, EGLBoolean returnVal)
1578c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1587c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (returnVal != EGL_TRUE) {
159c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
160c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
161c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
162c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        XLOGC("EGL ERROR - %s() returned %d\n", op, returnVal);
1637c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    }
1648612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
165f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) {
166c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
167c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
168c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
169c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        XLOGC("after %s() eglError (0x%x)\n", op, error);
170f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
171f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    }
1728612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1738612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1748c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::checkGlError(const char* op)
1758c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bool ret = false;
1778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    for (GLint error = glGetError(); error; error = glGetError()) {
178c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
179c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
180c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
181c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        XLOGC("GL ERROR - after %s() glError (0x%x)\n", op, error);
182f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
1838612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        ret = true;
1848612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
1858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return ret;
1868612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1878612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1888c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::checkGlErrorOn(void* p, const char* op)
1898c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bool ret = false;
1918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    for (GLint error = glGetError(); error; error = glGetError()) {
192c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
193c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
194c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
195c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        XLOGC("GL ERROR on %x - after %s() glError (0x%x)\n", p, op, error);
196f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
1978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        ret = true;
1988612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
1998612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return ret;
2008612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2018612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
202dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhuvoid GLUtils::checkSurfaceTextureError(const char* functionName, int status)
203dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu{
2047c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (status !=  NO_ERROR) {
205c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
206c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
207c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
208c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        XLOGC("ERROR at calling %s status is (%d)", functionName, status);
2097c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    }
210dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu}
2118612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
21213ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger// GL & EGL extension checks
21313ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////
21413ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
2158c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::isEGLImageSupported()
2168c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
21713ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
21813ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* glExtensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
21913ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
2208c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    return eglExtensions && glExtensions
2218c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(eglExtensions, "EGL_KHR_image_base")
2228c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image")
2238c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(glExtensions, "GL_OES_EGL_image");
22413ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger}
22513ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
2268c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::isEGLFenceSyncSupported()
2278c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
22813ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
229ba25389b2d1f3d6603ed1ea816278f91a4ca95c0Russell Brenner    return eglExtensions && strstr(eglExtensions, "EGL_KHR_fence_sync");
23013ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger}
23113ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
23213ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////
2338612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// Textures utilities
2348612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
2358612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2368612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic GLenum getInternalFormat(SkBitmap::Config config)
2378612b3c490ba10449012086a45b9021daa488e65Nicolas Roard{
2388c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    switch (config) {
2398c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kA8_Config:
2408c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_ALPHA;
2418c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_4444_Config:
2428c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGBA;
2438c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_8888_Config:
2448c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGBA;
2458c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kRGB_565_Config:
2468c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGB;
2478c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    default:
2488c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1;
2498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2508612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2518612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2528612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic GLenum getType(SkBitmap::Config config)
2538612b3c490ba10449012086a45b9021daa488e65Nicolas Roard{
2548c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    switch (config) {
2558c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kA8_Config:
2568c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_BYTE;
2578c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_4444_Config:
2588c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_SHORT_4_4_4_4;
2598c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_8888_Config:
2608c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_BYTE;
2618c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kIndex8_Config:
2628c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1; // No type for compressed data.
2638c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kRGB_565_Config:
2648c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_SHORT_5_6_5;
2658c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    default:
2668c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1;
2678612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2688612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2698612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2708c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardstatic EGLConfig defaultPbufferConfig(EGLDisplay display)
2718c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
2728612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLConfig config;
2738612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint numConfigs;
2748612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2758612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    static const EGLint configAttribs[] = {
2768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
2778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
2788612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_NONE
2798612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
2808612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2818612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
2828612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkEglError("eglPbufferConfig");
2838c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    if (numConfigs != 1)
2846eb6ffadfb7e1afb3190f44e69e833c49d9f82acSteve Block        ALOGI("eglPbufferConfig failed (%d)\n", numConfigs);
2858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2868612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return config;
2878612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2888612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2898612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic EGLSurface createPbufferSurface(EGLDisplay display, const EGLConfig& config,
2908c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard                                       EGLint* errorCode)
2918c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
2928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    const EGLint attribList[] = {
2938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_WIDTH, 1,
2948612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_HEIGHT, 1,
2958612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_NONE
2968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
2978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLSurface surface = eglCreatePbufferSurface(display, config, attribList);
2988612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2998612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (errorCode)
3008612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        *errorCode = eglGetError();
3018612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    else
3028612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        GLUtils::checkEglError("eglCreatePbufferSurface");
3038612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3048612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (surface == EGL_NO_SURFACE)
3058612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_SURFACE;
3068612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3078612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return surface;
3088612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3098612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3108c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas RoardEGLContext GLUtils::createBackgroundContext(EGLContext sharedContext)
3118c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
3128612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("<init>");
3138612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
3148612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglGetDisplay");
3158612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (display == EGL_NO_DISPLAY) {
3168612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("eglGetDisplay returned EGL_NO_DISPLAY");
3178612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
3188612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
3198612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3208612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint majorVersion;
3218612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint minorVersion;
3228612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLBoolean returnValue = eglInitialize(display, &majorVersion, &minorVersion);
3238612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglInitialize", returnValue);
3248612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (returnValue != EGL_TRUE) {
3258612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("eglInitialize failed\n");
3268612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
3278612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
3288612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3298612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLConfig config = defaultPbufferConfig(display);
3308612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLSurface surface = createPbufferSurface(display, config, 0);
3318612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3328612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint surfaceConfigId;
3338612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLBoolean success = eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &surfaceConfigId);
3348612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3358c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
3368c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    EGLContext context = eglCreateContext(display, config, sharedContext, contextAttribs);
3378612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglCreateContext");
3388612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (context == EGL_NO_CONTEXT) {
3398612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("eglCreateContext failed\n");
3408612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
3418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
3428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    returnValue = eglMakeCurrent(display, surface, surface, context);
3448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglMakeCurrent", returnValue);
3458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (returnValue != EGL_TRUE) {
3468612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("eglMakeCurrent failed\n");
3478612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
3488612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
3498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3508612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return context;
3518612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3528612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3538c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::deleteTexture(GLuint* texture)
3548c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
3558612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glDeleteTextures(1, texture);
3568612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glDeleteTexture");
3578612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    *texture = 0;
3588612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3598612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
360c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui ZhuGLuint GLUtils::createSampleColorTexture(int r, int g, int b)
361c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu{
3626edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLuint texture;
3636edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glGenTextures(1, &texture);
3646edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3656edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLubyte pixels[4 *3] = {
3666edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3676edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3686edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3696edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b
3706edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    };
3716edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
3726edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLUtils::checkGlError("glBindTexture");
3736edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
3746edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLUtils::checkGlError("glTexImage2D");
3756edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3766edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3776edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    return texture;
3786edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard}
3796edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard
3808c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas RoardGLuint GLUtils::createSampleTexture()
3818c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
3828612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLuint texture;
3838612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glGenTextures(1, &texture);
3848612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLubyte pixels[4 *3] = {
3868612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        255, 0, 0,
3878612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        0, 255, 0,
3888612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        0, 0, 255,
3898612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        255, 255, 0
3908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
3918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
3928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
3938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
3948612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glTexImage2D");
3958612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return texture;
3988612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3998612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
4007c554a61cb935660cdc86905d040c781b490150fTeng-Hui ZhuGLuint GLUtils::createBaseTileGLTexture(int width, int height)
4017c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu{
4027c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLuint texture;
4037c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glGenTextures(1, &texture);
4047c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4057c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLubyte* pixels = 0;
4067c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#ifdef DEBUG
4077c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    int length = width * height * 4;
4087c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    pixels = new GLubyte[length];
4097c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    for (int i = 0; i < length; i++)
4107c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        pixels[i] = i % 256;
4117c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#endif
4127c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glBindTexture(GL_TEXTURE_2D, texture);
4137c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLUtils::checkGlError("glBindTexture");
4147c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
4157c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLUtils::checkGlError("glTexImage2D");
4167c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4177c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
418be9cb848000fc47c0049a30dc167f4bb530835c1Teng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
419be9cb848000fc47c0049a30dc167f4bb530835c1Teng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
42017374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu#ifdef DEBUG
42117374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu    delete pixels;
42217374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu#endif
4237c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    return texture;
4247c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu}
4257c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
4268abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhubool GLUtils::isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor)
4278abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu{
4288abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // If the bitmap is the pure color, skip the transfer step, and update the BaseTile Info.
4298abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // This check is taking < 1ms if we do full bitmap check per tile.
4308abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // TODO: use the SkPicture to determine whether or not a tile is single color.
4318abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    pureColor = Color(Color::transparent);
4328abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bitmap.lockPixels();
4338abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bool sameColor = true;
4348abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int bitmapWidth = bitmap.width();
4358abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4368abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // Create a row of pure color using the first pixel.
437309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // TODO: improve the perf here, by either picking a random pixel, or
438309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // creating an array of rows with pre-defined commonly used color, add
439309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // smart LUT to speed things up if possible.
4408abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int* firstPixelPtr = static_cast<int*> (bitmap.getPixels());
4418abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int* pixelsRow = new int[bitmapWidth];
4428abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    for (int i = 0; i < bitmapWidth; i++)
4438abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        pixelsRow[i] = (*firstPixelPtr);
4448abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4458abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // Then compare the pure color row with each row of the bitmap.
4468abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    for (int j = 0; j < bitmap.height(); j++) {
4478abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        if (memcmp(pixelsRow, &firstPixelPtr[bitmapWidth * j], 4 * bitmapWidth)) {
4488abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            sameColor = false;
4498abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            break;
4508abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        }
4518abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4528abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    delete pixelsRow;
4538abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    pixelsRow = 0;
4548abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4558abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (sameColor) {
4568abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        char* rgbaPtr = static_cast<char*>(bitmap.getPixels());
4578abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        pureColor = Color(rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
4588abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        XLOG("sameColor tile found , %x at (%d, %d, %d, %d)",
4598abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu             *firstPixelPtr, rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
4608abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4618abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bitmap.unlockPixels();
4628abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4638abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    return sameColor;
4648abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu}
4658abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4668abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu// Return true when the tile is pure color.
4678abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhubool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo,
4688abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu                                       const SkBitmap& bitmap)
4698abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu{
4708abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bool skipTransfer = false;
4718abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    BaseTile* tilePtr = renderInfo->baseTile;
4728abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
473c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    // TODO: use pure color for partial invals as well
474c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    if (renderInfo->invalRect)
475c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        return false;
476c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard
4778abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (tilePtr) {
4788abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        BaseTileTexture* tileTexture = tilePtr->backTexture();
4798abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        // Check the bitmap, and make everything ready here.
4808abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        Color pureColor;
481309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu        if (tileTexture && isPureColorBitmap(bitmap, pureColor)) {
4828abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // update basetile's info
4838abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // Note that we are skipping the whole TransferQueue.
484309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_width = bitmap.width();
485309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_height = bitmap.height();
486309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_internalFormat = GL_RGBA;
487309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu
488309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            TilesManager::instance()->transferQueue()->addItemInPureColorQueue(renderInfo,
489309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu                                                                               pureColor);
490309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu
491309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            skipTransfer = true;
4928abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        }
4938abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4948abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    return skipTransfer;
4958abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu}
4968abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4977c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhuvoid GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
4987c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu                                     const SkBitmap& bitmap)
499dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu{
5007c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (!renderInfo)
5017c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        return;
5027c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    const SkSize& requiredSize = renderInfo->tileSize;
5037c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    TextureInfo* textureInfo = renderInfo->textureInfo;
504ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger
5058abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (skipTransferForPureColor(renderInfo, bitmap))
5068abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        return;
5078abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
50862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    if (requiredSize.equals(textureInfo->m_width, textureInfo->m_height))
509c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, bitmap);
51062ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    else {
511ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        if (!requiredSize.equals(bitmap.width(), bitmap.height())) {
512ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger            XLOG("The bitmap size (%d,%d) does not equal the texture size (%d,%d)",
513ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger                    bitmap.width(), bitmap.height(),
514ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger                    requiredSize.width(), requiredSize.height());
515ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        }
516c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, bitmap);
517ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger
518ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        textureInfo->m_width = bitmap.width();
519ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        textureInfo->m_height = bitmap.height();
5207c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        textureInfo->m_internalFormat = GL_RGBA;
521dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu    }
522dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu}
523dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
524c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roardvoid GLUtils::updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap)
5257c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu{
5267c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (!renderInfo
5277c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        || !renderInfo->textureInfo
5287c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        || !renderInfo->baseTile)
5297c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        return;
5307c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
531c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, bitmap);
5327c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu}
533dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
534ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenbergervoid GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter)
5358c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
5368612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5378612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
5388612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
5398612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    SkBitmap::Config config = bitmap.getConfig();
5408612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    int internalformat = getInternalFormat(config);
5418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    int type = getType(config);
5428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bitmap.lockPixels();
5438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, internalformat, bitmap.width(), bitmap.height(),
5448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard                 0, internalformat, type, bitmap.getPixels());
5458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bitmap.unlockPixels();
54644009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    if (GLUtils::checkGlError("glTexImage2D")) {
547c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
548c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
549c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
550c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        XLOGC("GL ERROR: glTexImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
55144009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu             " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
55244009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu             bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
55344009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    }
5548612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
5558612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
556bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard
557bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    // The following is a workaround -- remove when EGLImage texture upload is fixed.
558bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    GLuint fboID;
559bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glGenFramebuffers(1, &fboID);
560bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glBindFramebuffer(GL_FRAMEBUFFER, fboID);
561bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
562bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glCheckFramebufferStatus(GL_FRAMEBUFFER); // should return GL_FRAMEBUFFER_COMPLETE
563bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard
564bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO
565bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glDeleteFramebuffers(1, &fboID);
5668612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5678612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
568c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roardvoid GLUtils::updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap,
569c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                                      const IntRect& inval, GLint filter)
57067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard{
57167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
57267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
57367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    GLUtils::checkGlError("glBindTexture");
57467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    SkBitmap::Config config = bitmap.getConfig();
57567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    int internalformat = getInternalFormat(config);
57667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    int type = getType(config);
57767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bitmap.lockPixels();
578c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    if (inval.isEmpty()) {
579c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
580c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                        internalformat, type, bitmap.getPixels());
581c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    } else {
582c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        glTexSubImage2D(GL_TEXTURE_2D, 0, inval.x(), inval.y(), inval.width(), inval.height(),
583c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                        internalformat, type, bitmap.getPixels());
584c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    }
58567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bitmap.unlockPixels();
58667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (GLUtils::checkGlError("glTexSubImage2D")) {
587c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
588c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
589c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
590c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        XLOGC("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
591c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard             " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
592c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard             bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
59367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
59467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
5958612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
5968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
5988c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::createEGLImageFromTexture(GLuint texture, EGLImageKHR* image)
5998c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
6008612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(texture);
6018612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    static const EGLint attr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
6028612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    *image = eglCreateImageKHR(eglGetCurrentDisplay(), eglGetCurrentContext(),
6038612b3c490ba10449012086a45b9021daa488e65Nicolas Roard                               EGL_GL_TEXTURE_2D_KHR, buffer, attr);
6048612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkEglError("eglCreateImage", (*image != EGL_NO_IMAGE_KHR));
6058612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
6068612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
6078c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter)
6088c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
6098612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
6108612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
6118612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
6128612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
6138612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
6148612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
6158612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
616e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhuvoid GLUtils::convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix)
617e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu{
618e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu    transformMatrix.setMatrix(
619e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[0], matrix[1], matrix[2], matrix[3],
620e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[4], matrix[5], matrix[6], matrix[7],
621e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[8], matrix[9], matrix[10], matrix[11],
622e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[12], matrix[13], matrix[14], matrix[15]);
623e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu}
624e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu
6258612b3c490ba10449012086a45b9021daa488e65Nicolas Roard} // namespace WebCore
6268612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
6278612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
628