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"
36594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "TextureInfo.h"
37594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "Tile.h"
387c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#include "TilesManager.h"
39594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "TransferQueue.h"
408612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
414f6d7d36d7c42018c2d5fcb76499539d1ccc2f97Mathias Agopian#include <android/native_window.h>
42dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu#include <gui/SurfaceTexture.h>
438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#include <wtf/CurrentTime.h>
447c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
45c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu// We will limit GL error logging for LOG_VOLUME_PER_CYCLE times every
46c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu// LOG_VOLUME_PER_CYCLE seconds.
47c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#define LOG_CYCLE 30.0
48c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#define LOG_VOLUME_PER_CYCLE 20
49c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
50dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhustruct ANativeWindowBuffer;
51dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
528612b3c490ba10449012086a45b9021daa488e65Nicolas Roardnamespace WebCore {
538612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
548612b3c490ba10449012086a45b9021daa488e65Nicolas Roardusing namespace android;
558612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
568612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
578612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// Matrix utilities
588612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
598612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
608c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::toGLMatrix(GLfloat* flattened, const TransformationMatrix& m)
618c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
6274427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[0] = m.m11(); // scaleX
6374427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[1] = m.m12(); // skewY
648612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[2] = m.m13();
6574427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[3] = m.m14(); // persp0
6674427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[4] = m.m21(); // skewX
6774427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[5] = m.m22(); // scaleY
688612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[6] = m.m23();
6974427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[7] = m.m24(); // persp1
708612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[8] = m.m31();
718612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[9] = m.m32();
728612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[10] = m.m33();
738612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[11] = m.m34();
7474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[12] = m.m41(); // transX
7574427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[13] = m.m42(); // transY
768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[14] = m.m43();
7774427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[15] = m.m44(); // persp2
7874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard}
7974427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard
808c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::toSkMatrix(SkMatrix& matrix, const TransformationMatrix& m)
818c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
8274427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[0] = m.m11(); // scaleX
8374427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[1] = m.m21(); // skewX
8474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[2] = m.m41(); // transX
8574427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[3] = m.m12(); // skewY
8674427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[4] = m.m22(); // scaleY
8774427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[5] = m.m42(); // transY
8874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[6] = m.m14(); // persp0
8974427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[7] = m.m24(); // persp1
9074427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[8] = m.m44(); // persp2
918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
938612b3c490ba10449012086a45b9021daa488e65Nicolas Roardvoid GLUtils::setOrthographicMatrix(TransformationMatrix& ortho, float left, float top,
948c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard                                    float right, float bottom, float nearZ, float farZ)
958c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    float deltaX = right - left;
97f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    float deltaY = top - bottom;
988612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    float deltaZ = farZ - nearZ;
99f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    if (!deltaX || !deltaY || !deltaZ)
100f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard        return;
1018612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1028612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM11(2.0f / deltaX);
1038612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM41(-(right + left) / deltaX);
104f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM22(2.0f / deltaY);
1058612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM42(-(top + bottom) / deltaY);
106f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM33(-2.0f / deltaZ);
107f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM43(-(nearZ + farZ) / deltaZ);
1088612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1098612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
110418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiwarebool GLUtils::has3dTransform(const TransformationMatrix& matrix)
111418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware{
112418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware    return matrix.m13() != 0 || matrix.m23() != 0
113418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware        || matrix.m31() != 0 || matrix.m32() != 0
114418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware        || matrix.m33() != 1 || matrix.m34() != 0
115418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware        || matrix.m43() != 0;
116418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware}
117418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware
1188612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
1198612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// GL & EGL error checks
1208612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
1218612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
122c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhudouble GLUtils::m_previousLogTime = 0;
123c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhuint GLUtils::m_currentLogCounter = 0;
124c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
125c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhubool GLUtils::allowGLLog()
126c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu{
127c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    if (m_currentLogCounter < LOG_VOLUME_PER_CYCLE) {
128c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        m_currentLogCounter++;
129c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        return true;
130c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    }
131c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
132c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    // when we are in Log cycle and over the log limit, just return false
133c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    double currentTime = WTF::currentTime();
134c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    double delta = currentTime - m_previousLogTime;
135c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    bool inLogCycle = (delta <= LOG_CYCLE) && (delta > 0);
136c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    if (inLogCycle)
137c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        return false;
138c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
139c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    // When we are out of Log Cycle and over the log limit, we need to reset
140c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    // the counter and timer.
141c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    m_previousLogTime = currentTime;
142c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    m_currentLogCounter = 0;
143c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu    return false;
144c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu}
145c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu
146c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhustatic void crashIfOOM(GLint errorCode)
147c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu{
148f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    const GLint OOM_ERROR_CODE = 0x505;
149f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    if (errorCode == OOM_ERROR_CODE) {
150d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("ERROR: Fatal OOM detected.");
151f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        CRASH();
152f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    }
153f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch}
154f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch
1558c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::checkEglError(const char* op, EGLBoolean returnVal)
1568c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1577c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (returnVal != EGL_TRUE) {
158c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
159c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
160c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
161d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("EGL ERROR - %s() returned %d\n", op, returnVal);
1627c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    }
1638612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
164f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) {
165c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
166c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
167c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
168d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("after %s() eglError (0x%x)\n", op, error);
169f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
170f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    }
1718612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1728612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1738c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::checkGlError(const char* op)
1748c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1758612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bool ret = false;
1768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    for (GLint error = glGetError(); error; error = glGetError()) {
177c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
178c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
179c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
180d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("GL ERROR - after %s() glError (0x%x)\n", op, error);
181f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
1828612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        ret = true;
1838612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
1848612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return ret;
1858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1868612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1878c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::checkGlErrorOn(void* p, const char* op)
1888c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1898612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bool ret = false;
1908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    for (GLint error = glGetError(); error; error = glGetError()) {
191c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
192c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
193c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
194d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("GL ERROR on %x - after %s() glError (0x%x)\n", p, op, error);
195f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
1968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        ret = true;
1978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
1988612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return ret;
1998612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2008612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
201dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhuvoid GLUtils::checkSurfaceTextureError(const char* functionName, int status)
202dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu{
2037c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (status !=  NO_ERROR) {
204c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
205c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
206c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
207d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGE("ERROR at calling %s status is (%d)", functionName, status);
2087c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    }
209dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu}
2108612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
21113ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger// GL & EGL extension checks
21213ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////
21313ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
2148c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::isEGLImageSupported()
2158c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
21613ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
21713ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* glExtensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
21813ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
2198c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    return eglExtensions && glExtensions
2208c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(eglExtensions, "EGL_KHR_image_base")
2218c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image")
2228c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(glExtensions, "GL_OES_EGL_image");
22313ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger}
22413ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
2258c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::isEGLFenceSyncSupported()
2268c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
22713ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
228ba25389b2d1f3d6603ed1ea816278f91a4ca95c0Russell Brenner    return eglExtensions && strstr(eglExtensions, "EGL_KHR_fence_sync");
22913ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger}
23013ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
23113ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////
2328612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// Textures utilities
2338612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
2348612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2358612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic GLenum getInternalFormat(SkBitmap::Config config)
2368612b3c490ba10449012086a45b9021daa488e65Nicolas Roard{
2378c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    switch (config) {
2388c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kA8_Config:
2398c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_ALPHA;
2408c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_4444_Config:
2418c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGBA;
2428c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_8888_Config:
2438c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGBA;
2448c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kRGB_565_Config:
2458c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGB;
2468c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    default:
2478c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1;
2488612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2508612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2518612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic GLenum getType(SkBitmap::Config config)
2528612b3c490ba10449012086a45b9021daa488e65Nicolas Roard{
2538c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    switch (config) {
2548c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kA8_Config:
2558c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_BYTE;
2568c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_4444_Config:
2578c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_SHORT_4_4_4_4;
2588c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_8888_Config:
2598c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_BYTE;
2608c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kIndex8_Config:
2618c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1; // No type for compressed data.
2628c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kRGB_565_Config:
2638c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_SHORT_5_6_5;
2648c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    default:
2658c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1;
2668612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2678612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2688612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2698c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardstatic EGLConfig defaultPbufferConfig(EGLDisplay display)
2708c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
2718612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLConfig config;
2728612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint numConfigs;
2738612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2748612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    static const EGLint configAttribs[] = {
2758612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
2768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
2778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_NONE
2788612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
2798612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2808612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
2818612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkEglError("eglPbufferConfig");
2828c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    if (numConfigs != 1)
2836eb6ffadfb7e1afb3190f44e69e833c49d9f82acSteve Block        ALOGI("eglPbufferConfig failed (%d)\n", numConfigs);
2848612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return config;
2868612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2878612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2888612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic EGLSurface createPbufferSurface(EGLDisplay display, const EGLConfig& config,
2898c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard                                       EGLint* errorCode)
2908c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
2918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    const EGLint attribList[] = {
2928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_WIDTH, 1,
2938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_HEIGHT, 1,
2948612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_NONE
2958612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
2968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLSurface surface = eglCreatePbufferSurface(display, config, attribList);
2978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2988612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (errorCode)
2998612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        *errorCode = eglGetError();
3008612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    else
3018612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        GLUtils::checkEglError("eglCreatePbufferSurface");
3028612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3038612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (surface == EGL_NO_SURFACE)
3048612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_SURFACE;
3058612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3068612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return surface;
3078612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3088612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3098c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::deleteTexture(GLuint* texture)
3108c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
3118612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glDeleteTextures(1, texture);
3128612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glDeleteTexture");
3138612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    *texture = 0;
3148612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3158612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
316c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui ZhuGLuint GLUtils::createSampleColorTexture(int r, int g, int b)
317c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu{
3186edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLuint texture;
3196edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glGenTextures(1, &texture);
3206edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3216edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLubyte pixels[4 *3] = {
3226edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3236edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3246edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3256edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b
3266edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    };
3276edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
3286edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLUtils::checkGlError("glBindTexture");
3296edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
3306edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLUtils::checkGlError("glTexImage2D");
3316edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3326edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3336edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    return texture;
3346edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard}
3356edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard
3368c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas RoardGLuint GLUtils::createSampleTexture()
3378c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
3388612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLuint texture;
3398612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glGenTextures(1, &texture);
3408612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLubyte pixels[4 *3] = {
3428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        255, 0, 0,
3438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        0, 255, 0,
3448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        0, 0, 255,
3458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        255, 255, 0
3468612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
3478612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
3488612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
3498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
3508612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glTexImage2D");
3518612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3528612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3538612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return texture;
3548612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3558612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
356594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikGLuint GLUtils::createTileGLTexture(int width, int height)
3577c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu{
3587c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLuint texture;
3597c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glGenTextures(1, &texture);
3607c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3617c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLubyte* pixels = 0;
3627c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#ifdef DEBUG
3637c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    int length = width * height * 4;
3647c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    pixels = new GLubyte[length];
3657c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    for (int i = 0; i < length; i++)
3667c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        pixels[i] = i % 256;
3677c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#endif
3687c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glBindTexture(GL_TEXTURE_2D, texture);
3697c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLUtils::checkGlError("glBindTexture");
3707c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
3717c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLUtils::checkGlError("glTexImage2D");
3727c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3737c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
374be9cb848000fc47c0049a30dc167f4bb530835c1Teng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
375be9cb848000fc47c0049a30dc167f4bb530835c1Teng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
37617374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu#ifdef DEBUG
37717374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu    delete pixels;
37817374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu#endif
3797c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    return texture;
3807c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu}
3817c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
3828abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhubool GLUtils::isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor)
3838abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu{
384594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    // If the bitmap is the pure color, skip the transfer step, and update the Tile Info.
3858abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // This check is taking < 1ms if we do full bitmap check per tile.
3868abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // TODO: use the SkPicture to determine whether or not a tile is single color.
3878abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    pureColor = Color(Color::transparent);
3888abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bitmap.lockPixels();
3898abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bool sameColor = true;
3908abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int bitmapWidth = bitmap.width();
3918abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
3928abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // Create a row of pure color using the first pixel.
393309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // TODO: improve the perf here, by either picking a random pixel, or
394309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // creating an array of rows with pre-defined commonly used color, add
395309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // smart LUT to speed things up if possible.
3968abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int* firstPixelPtr = static_cast<int*> (bitmap.getPixels());
3978abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int* pixelsRow = new int[bitmapWidth];
3988abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    for (int i = 0; i < bitmapWidth; i++)
3998abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        pixelsRow[i] = (*firstPixelPtr);
4008abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4018abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // Then compare the pure color row with each row of the bitmap.
4028abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    for (int j = 0; j < bitmap.height(); j++) {
4038abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        if (memcmp(pixelsRow, &firstPixelPtr[bitmapWidth * j], 4 * bitmapWidth)) {
4048abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            sameColor = false;
4058abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            break;
4068abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        }
4078abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4088abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    delete pixelsRow;
4098abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    pixelsRow = 0;
4108abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4118abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (sameColor) {
4128abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        char* rgbaPtr = static_cast<char*>(bitmap.getPixels());
4138abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        pureColor = Color(rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
414d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik        ALOGV("sameColor tile found , %x at (%d, %d, %d, %d)",
415d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              *firstPixelPtr, rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
4168abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4178abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bitmap.unlockPixels();
4188abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4198abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    return sameColor;
4208abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu}
4218abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4228abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu// Return true when the tile is pure color.
4238abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhubool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo,
4248abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu                                       const SkBitmap& bitmap)
4258abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu{
4268abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bool skipTransfer = false;
427594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik    Tile* tilePtr = renderInfo->baseTile;
4288abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4298abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (tilePtr) {
430594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik        TileTexture* tileTexture = tilePtr->backTexture();
4318abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        // Check the bitmap, and make everything ready here.
4326aea92fd5ffd5a43b1c13769be9a16202f498b59John Reck        if (tileTexture && renderInfo->isPureColor) {
4338abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // update basetile's info
4348abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // Note that we are skipping the whole TransferQueue.
435309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_width = bitmap.width();
436309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_height = bitmap.height();
437309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_internalFormat = GL_RGBA;
438309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu
4396aea92fd5ffd5a43b1c13769be9a16202f498b59John Reck            TilesManager::instance()->transferQueue()->addItemInPureColorQueue(renderInfo);
440309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu
441309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            skipTransfer = true;
4428abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        }
4438abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4448abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    return skipTransfer;
4458abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu}
4468abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4477c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhuvoid GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
4487c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu                                     const SkBitmap& bitmap)
449dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu{
4507c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (!renderInfo)
4517c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        return;
4527c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    const SkSize& requiredSize = renderInfo->tileSize;
4537c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    TextureInfo* textureInfo = renderInfo->textureInfo;
454ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger
4558abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (skipTransferForPureColor(renderInfo, bitmap))
4568abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        return;
4578abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
45862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    if (requiredSize.equals(textureInfo->m_width, textureInfo->m_height))
459a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        GLUtils::updateQueueWithBitmap(renderInfo, bitmap);
46062ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    else {
461ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        if (!requiredSize.equals(bitmap.width(), bitmap.height())) {
462d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik            ALOGV("The bitmap size (%d,%d) does not equal the texture size (%d,%d)",
463d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik                  bitmap.width(), bitmap.height(),
464d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik                  requiredSize.width(), requiredSize.height());
465ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        }
466a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        GLUtils::updateQueueWithBitmap(renderInfo, bitmap);
467ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger
468ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        textureInfo->m_width = bitmap.width();
469ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        textureInfo->m_height = bitmap.height();
4707c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        textureInfo->m_internalFormat = GL_RGBA;
471dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu    }
472dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu}
473dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
474a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reckvoid GLUtils::updateQueueWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap)
4757c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu{
4767c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (!renderInfo
4777c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        || !renderInfo->textureInfo
4787c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        || !renderInfo->baseTile)
4797c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        return;
4807c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
481c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, bitmap);
4827c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu}
483dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
484a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reckbool GLUtils::updateSharedSurfaceTextureWithBitmap(ANativeWindow* anw, const SkBitmap& bitmap)
485a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck{
486a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    SkAutoLockPixels alp(bitmap);
487a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    if (!bitmap.getPixels())
488a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        return false;
489a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    ANativeWindow_Buffer buffer;
490a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    if (ANativeWindow_lock(anw, &buffer, 0))
491a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        return false;
492821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck    if (buffer.width < bitmap.width() || buffer.height < bitmap.height()) {
493821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck        ALOGW("bitmap (%dx%d) too large for buffer (%dx%d)!",
494821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck                bitmap.width(), bitmap.height(),
495821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck                buffer.width, buffer.height);
496821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck        ANativeWindow_unlockAndPost(anw);
497a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        return false;
498821fc38c9e0086ddbe1131e71eccc5b9339495f3John Reck    }
499a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    uint8_t* img = (uint8_t*)buffer.bits;
500a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    int row;
501a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    int bpp = 4; // Now we only deal with RGBA8888 format.
502a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    bitmap.lockPixels();
503a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
504a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck
505a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    if (buffer.stride != bitmap.width())
506a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        // Copied line by line since we need to handle the offsets and stride.
507a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        for (row = 0 ; row < bitmap.height(); row ++) {
508a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck            uint8_t* dst = &(img[buffer.stride * row * bpp]);
509a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck            uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
510a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck            memcpy(dst, src, bpp * bitmap.width());
511a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        }
512a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    else
513a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck        memcpy(img, bitmapOrigin, bpp * bitmap.width() * bitmap.height());
514a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck
515a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    bitmap.unlockPixels();
516a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    ANativeWindow_unlockAndPost(anw);
517a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck    return true;
518a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck}
519a144ac64329978c258faadf3bc484cf4ae6c5d0dJohn Reck
520ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenbergervoid GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter)
5218c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
5228612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
5238612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
5248612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
5258612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    SkBitmap::Config config = bitmap.getConfig();
5268612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    int internalformat = getInternalFormat(config);
5278612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    int type = getType(config);
5288612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bitmap.lockPixels();
5298612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, internalformat, bitmap.width(), bitmap.height(),
5308612b3c490ba10449012086a45b9021daa488e65Nicolas Roard                 0, internalformat, type, bitmap.getPixels());
5318612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bitmap.unlockPixels();
53244009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    if (GLUtils::checkGlError("glTexImage2D")) {
533c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
534c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
535c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
5362984cd062c3533700d08979a1ba76b3b04fcb395Teng-Hui Zhu        ALOGE("GL ERROR: glTexImage2D parameters are : textureId %d,"
5372984cd062c3533700d08979a1ba76b3b04fcb395Teng-Hui Zhu              " bitmap.width() %d, bitmap.height() %d,"
538d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
5392984cd062c3533700d08979a1ba76b3b04fcb395Teng-Hui Zhu              texture, bitmap.width(), bitmap.height(), internalformat, type,
5402984cd062c3533700d08979a1ba76b3b04fcb395Teng-Hui Zhu              bitmap.getPixels());
54144009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    }
5428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
5438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
5448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
546c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roardvoid GLUtils::updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap,
547c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                                      const IntRect& inval, GLint filter)
54867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard{
54967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
55067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
55167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    GLUtils::checkGlError("glBindTexture");
55267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    SkBitmap::Config config = bitmap.getConfig();
55367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    int internalformat = getInternalFormat(config);
55467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    int type = getType(config);
55567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bitmap.lockPixels();
556c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    if (inval.isEmpty()) {
557c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width(), bitmap.height(),
558c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                        internalformat, type, bitmap.getPixels());
559c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    } else {
560c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard        glTexSubImage2D(GL_TEXTURE_2D, 0, inval.x(), inval.y(), inval.width(), inval.height(),
561c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard                        internalformat, type, bitmap.getPixels());
562c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard    }
56367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bitmap.unlockPixels();
56467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (GLUtils::checkGlError("glTexSubImage2D")) {
565c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#ifndef DEBUG
566c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu        if (allowGLLog())
567c08a6b03cd13c774ec0e475ac4813ac1ae1738e5Teng-Hui Zhu#endif
5682984cd062c3533700d08979a1ba76b3b04fcb395Teng-Hui Zhu        ALOGE("GL ERROR: glTexSubImage2D parameters are : textureId %d,"
5692984cd062c3533700d08979a1ba76b3b04fcb395Teng-Hui Zhu              " bitmap.width() %d, bitmap.height() %d,"
570d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik              " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
5712984cd062c3533700d08979a1ba76b3b04fcb395Teng-Hui Zhu              texture, bitmap.width(), bitmap.height(), internalformat, type,
5722984cd062c3533700d08979a1ba76b3b04fcb395Teng-Hui Zhu              bitmap.getPixels());
57367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
57467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
5758612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
5768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
5788c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::createEGLImageFromTexture(GLuint texture, EGLImageKHR* image)
5798c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
5808612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(texture);
5818612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    static const EGLint attr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
5828612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    *image = eglCreateImageKHR(eglGetCurrentDisplay(), eglGetCurrentContext(),
5838612b3c490ba10449012086a45b9021daa488e65Nicolas Roard                               EGL_GL_TEXTURE_2D_KHR, buffer, attr);
5848612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkEglError("eglCreateImage", (*image != EGL_NO_IMAGE_KHR));
5858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5868612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
5878c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter)
5888c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
5898612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
5908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
5918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
5928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
5938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
5948612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5958612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
596e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhuvoid GLUtils::convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix)
597e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu{
598e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu    transformMatrix.setMatrix(
599e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[0], matrix[1], matrix[2], matrix[3],
600e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[4], matrix[5], matrix[6], matrix[7],
601e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[8], matrix[9], matrix[10], matrix[11],
602e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[12], matrix[13], matrix[14], matrix[15]);
603e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu}
604e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu
605afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhuvoid GLUtils::clearBackgroundIfOpaque(const Color* backgroundColor)
606885e650b12d781be054b31ae6221925a0184dc33Chris Craik{
607afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu    if (!backgroundColor->hasAlpha()) {
608afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        if (TilesManager::instance()->invertedScreen()) {
609afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu            float color = 1.0 - ((((float) backgroundColor->red() / 255.0) +
610afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                          ((float) backgroundColor->green() / 255.0) +
611afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                          ((float) backgroundColor->blue() / 255.0)) / 3.0);
612afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu            glClearColor(color, color, color, 1);
613afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        } else {
614afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu            glClearColor((float)backgroundColor->red() / 255.0,
615afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                         (float)backgroundColor->green() / 255.0,
616afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu                         (float)backgroundColor->blue() / 255.0, 1);
617afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        }
618afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu        glClear(GL_COLOR_BUFFER_BIT);
619885e650b12d781be054b31ae6221925a0184dc33Chris Craik    }
620885e650b12d781be054b31ae6221925a0184dc33Chris Craik}
621885e650b12d781be054b31ae6221925a0184dc33Chris Craik
622e859a34171f2a36877d95197d118d962078f8aa0John Reckbool GLUtils::deepCopyBitmapSubset(const SkBitmap& sourceBitmap,
623e859a34171f2a36877d95197d118d962078f8aa0John Reck                                   SkBitmap& subset, int leftOffset, int topOffset)
624e859a34171f2a36877d95197d118d962078f8aa0John Reck{
625e859a34171f2a36877d95197d118d962078f8aa0John Reck    sourceBitmap.lockPixels();
626e859a34171f2a36877d95197d118d962078f8aa0John Reck    subset.lockPixels();
627e859a34171f2a36877d95197d118d962078f8aa0John Reck    char* srcPixels = (char*) sourceBitmap.getPixels();
628e859a34171f2a36877d95197d118d962078f8aa0John Reck    char* dstPixels = (char*) subset.getPixels();
629e859a34171f2a36877d95197d118d962078f8aa0John Reck    if (!dstPixels || !srcPixels || !subset.lockPixelsAreWritable()) {
630e859a34171f2a36877d95197d118d962078f8aa0John Reck        ALOGD("no pixels :( %p, %p (writable=%d)", srcPixels, dstPixels,
631e859a34171f2a36877d95197d118d962078f8aa0John Reck              subset.lockPixelsAreWritable());
632e859a34171f2a36877d95197d118d962078f8aa0John Reck        subset.unlockPixels();
633e859a34171f2a36877d95197d118d962078f8aa0John Reck        sourceBitmap.unlockPixels();
634e859a34171f2a36877d95197d118d962078f8aa0John Reck        return false;
635e859a34171f2a36877d95197d118d962078f8aa0John Reck    }
636e859a34171f2a36877d95197d118d962078f8aa0John Reck    int srcRowSize = sourceBitmap.rowBytes();
637e859a34171f2a36877d95197d118d962078f8aa0John Reck    int destRowSize = subset.rowBytes();
638e859a34171f2a36877d95197d118d962078f8aa0John Reck    for (int i = 0; i < subset.height(); i++) {
639e859a34171f2a36877d95197d118d962078f8aa0John Reck        int srcOffset = (i + topOffset) * srcRowSize;
640e859a34171f2a36877d95197d118d962078f8aa0John Reck        srcOffset += (leftOffset * sourceBitmap.bytesPerPixel());
641e859a34171f2a36877d95197d118d962078f8aa0John Reck        int dstOffset = i * destRowSize;
642e859a34171f2a36877d95197d118d962078f8aa0John Reck        memcpy(dstPixels + dstOffset, srcPixels + srcOffset, destRowSize);
643e859a34171f2a36877d95197d118d962078f8aa0John Reck    }
644e859a34171f2a36877d95197d118d962078f8aa0John Reck    subset.unlockPixels();
645e859a34171f2a36877d95197d118d962078f8aa0John Reck    sourceBitmap.unlockPixels();
646e859a34171f2a36877d95197d118d962078f8aa0John Reck    return true;
647e859a34171f2a36877d95197d118d962078f8aa0John Reck}
648e859a34171f2a36877d95197d118d962078f8aa0John Reck
6498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard} // namespace WebCore
6508612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
6518612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
652