GLUtils.cpp revision 309ae897e0ad3493fc6acd97a39c631f90580d57
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
397c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
407c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#ifdef DEBUG
417c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
427c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#include <cutils/log.h>
437c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#include <wtf/text/CString.h>
447c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#undef XLOG
468612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLUtils", __VA_ARGS__)
478612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
487c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#else
497c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
507c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#undef XLOG
517c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#define XLOG(...)
527c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
537c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#endif // DEBUG
547c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
55dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhustruct ANativeWindowBuffer;
56dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
578612b3c490ba10449012086a45b9021daa488e65Nicolas Roardnamespace WebCore {
588612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
598612b3c490ba10449012086a45b9021daa488e65Nicolas Roardusing namespace android;
608612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
618612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
628612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// Matrix utilities
638612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
648612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
658c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::toGLMatrix(GLfloat* flattened, const TransformationMatrix& m)
668c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
6774427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[0] = m.m11(); // scaleX
6874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[1] = m.m12(); // skewY
698612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[2] = m.m13();
7074427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[3] = m.m14(); // persp0
7174427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[4] = m.m21(); // skewX
7274427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[5] = m.m22(); // scaleY
738612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[6] = m.m23();
7474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[7] = m.m24(); // persp1
758612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[8] = m.m31();
768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[9] = m.m32();
778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[10] = m.m33();
788612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[11] = m.m34();
7974427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[12] = m.m41(); // transX
8074427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[13] = m.m42(); // transY
818612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    flattened[14] = m.m43();
8274427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    flattened[15] = m.m44(); // persp2
8374427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard}
8474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard
858c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::toSkMatrix(SkMatrix& matrix, const TransformationMatrix& m)
868c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
8774427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[0] = m.m11(); // scaleX
8874427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[1] = m.m21(); // skewX
8974427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[2] = m.m41(); // transX
9074427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[3] = m.m12(); // skewY
9174427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[4] = m.m22(); // scaleY
9274427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[5] = m.m42(); // transY
9374427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[6] = m.m14(); // persp0
9474427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[7] = m.m24(); // persp1
9574427af10b1794f0e99b7e7a451c4a40902c98f4Nicolas Roard    matrix[8] = m.m44(); // persp2
968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
988612b3c490ba10449012086a45b9021daa488e65Nicolas Roardvoid GLUtils::setOrthographicMatrix(TransformationMatrix& ortho, float left, float top,
998c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard                                    float right, float bottom, float nearZ, float farZ)
1008c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1018612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    float deltaX = right - left;
102f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    float deltaY = top - bottom;
1038612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    float deltaZ = farZ - nearZ;
104f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    if (!deltaX || !deltaY || !deltaZ)
105f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard        return;
1068612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1078612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM11(2.0f / deltaX);
1088612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM41(-(right + left) / deltaX);
109f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM22(2.0f / deltaY);
1108612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    ortho.setM42(-(top + bottom) / deltaY);
111f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM33(-2.0f / deltaZ);
112f9b61180850e854778bcc25ef9b58716d8f29b53Nicolas Roard    ortho.setM43(-(nearZ + farZ) / deltaZ);
1138612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1148612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1158612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
1168612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// GL & EGL error checks
1178612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
1188612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
119f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdochstatic void crashIfOOM(GLint errorCode) {
120f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    const GLint OOM_ERROR_CODE = 0x505;
121f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    if (errorCode == OOM_ERROR_CODE) {
122f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        XLOG("Fatal OOM detected.");
123f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        CRASH();
124f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    }
125f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch}
126f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch
1278c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::checkEglError(const char* op, EGLBoolean returnVal)
1288c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1297c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (returnVal != EGL_TRUE) {
1308612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("EGL ERROR - %s() returned %d\n", op, returnVal);
1317c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    }
1328612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
133f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) {
1348612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("after %s() eglError (0x%x)\n", op, error);
135f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
136f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch    }
1378612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1388612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1398c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::checkGlError(const char* op)
1408c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bool ret = false;
1428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    for (GLint error = glGetError(); error; error = glGetError()) {
1438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("GL ERROR - after %s() glError (0x%x)\n", op, error);
144f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
1458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        ret = true;
1468612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
1478612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return ret;
1488612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1508c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::checkGlErrorOn(void* p, const char* op)
1518c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
1528612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bool ret = false;
1538612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    for (GLint error = glGetError(); error; error = glGetError()) {
1548612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("GL ERROR on %x - after %s() glError (0x%x)\n", p, op, error);
155f530a67b51ee304e24ab3e1dabc6b67958c09c68Ben Murdoch        crashIfOOM(error);
1568612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        ret = true;
1578612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
1588612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return ret;
1598612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
1608612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
161dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhuvoid GLUtils::checkSurfaceTextureError(const char* functionName, int status)
162dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu{
1637c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (status !=  NO_ERROR) {
164dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu        XLOG("ERROR at calling %s status is (%d)", functionName, status);
1657c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    }
166dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu}
1678612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
16813ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger// GL & EGL extension checks
16913ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////
17013ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
1718c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::isEGLImageSupported()
1728c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
17313ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
17413ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* glExtensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
17513ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
1768c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    return eglExtensions && glExtensions
1778c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(eglExtensions, "EGL_KHR_image_base")
1788c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image")
1798c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        && strstr(glExtensions, "GL_OES_EGL_image");
18013ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger}
18113ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
1828c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardbool GLUtils::isEGLFenceSyncSupported()
1838c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
18413ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger    const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
185ba25389b2d1f3d6603ed1ea816278f91a4ca95c0Russell Brenner    return eglExtensions && strstr(eglExtensions, "EGL_KHR_fence_sync");
18613ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger}
18713ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger
18813ae18a5652329f6ed05083d98d679087d83c242Derek Sollenberger/////////////////////////////////////////////////////////////////////////////////////////
1898612b3c490ba10449012086a45b9021daa488e65Nicolas Roard// Textures utilities
1908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard/////////////////////////////////////////////////////////////////////////////////////////
1918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
1928612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic GLenum getInternalFormat(SkBitmap::Config config)
1938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard{
1948c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    switch (config) {
1958c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kA8_Config:
1968c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_ALPHA;
1978c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_4444_Config:
1988c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGBA;
1998c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_8888_Config:
2008c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGBA;
2018c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kRGB_565_Config:
2028c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_RGB;
2038c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    default:
2048c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1;
2058612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2068612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2078612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2088612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic GLenum getType(SkBitmap::Config config)
2098612b3c490ba10449012086a45b9021daa488e65Nicolas Roard{
2108c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    switch (config) {
2118c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kA8_Config:
2128c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_BYTE;
2138c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_4444_Config:
2148c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_SHORT_4_4_4_4;
2158c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kARGB_8888_Config:
2168c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_BYTE;
2178c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kIndex8_Config:
2188c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1; // No type for compressed data.
2198c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    case SkBitmap::kRGB_565_Config:
2208c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return GL_UNSIGNED_SHORT_5_6_5;
2218c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    default:
2228c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard        return -1;
2238612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2248612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2258612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2268c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardstatic EGLConfig defaultPbufferConfig(EGLDisplay display)
2278c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
2288612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLConfig config;
2298612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint numConfigs;
2308612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2318612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    static const EGLint configAttribs[] = {
2328612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
2338612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
2348612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_NONE
2358612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
2368612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2378612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
2388612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkEglError("eglPbufferConfig");
2398c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    if (numConfigs != 1)
2408612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        LOGI("eglPbufferConfig failed (%d)\n", numConfigs);
2418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return config;
2438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2458612b3c490ba10449012086a45b9021daa488e65Nicolas Roardstatic EGLSurface createPbufferSurface(EGLDisplay display, const EGLConfig& config,
2468c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard                                       EGLint* errorCode)
2478c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
2488612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    const EGLint attribList[] = {
2498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_WIDTH, 1,
2508612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_HEIGHT, 1,
2518612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        EGL_NONE
2528612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
2538612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLSurface surface = eglCreatePbufferSurface(display, config, attribList);
2548612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2558612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (errorCode)
2568612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        *errorCode = eglGetError();
2578612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    else
2588612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        GLUtils::checkEglError("eglCreatePbufferSurface");
2598612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2608612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (surface == EGL_NO_SURFACE)
2618612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_SURFACE;
2628612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2638612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return surface;
2648612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
2658612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2668c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas RoardEGLContext GLUtils::createBackgroundContext(EGLContext sharedContext)
2678c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
2688612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("<init>");
2698612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
2708612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglGetDisplay");
2718612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (display == EGL_NO_DISPLAY) {
2728612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("eglGetDisplay returned EGL_NO_DISPLAY");
2738612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
2748612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2758612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2768612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint majorVersion;
2778612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint minorVersion;
2788612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLBoolean returnValue = eglInitialize(display, &majorVersion, &minorVersion);
2798612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglInitialize", returnValue);
2808612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (returnValue != EGL_TRUE) {
2818612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("eglInitialize failed\n");
2828612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
2838612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2848612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2858612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLConfig config = defaultPbufferConfig(display);
2868612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLSurface surface = createPbufferSurface(display, config, 0);
2878612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2888612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLint surfaceConfigId;
2898612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLBoolean success = eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &surfaceConfigId);
2908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2918c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
2928c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard    EGLContext context = eglCreateContext(display, config, sharedContext, contextAttribs);
2938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglCreateContext");
2948612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (context == EGL_NO_CONTEXT) {
2958612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("eglCreateContext failed\n");
2968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
2978612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
2988612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
2998612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    returnValue = eglMakeCurrent(display, surface, surface, context);
3008612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    checkEglError("eglMakeCurrent", returnValue);
3018612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    if (returnValue != EGL_TRUE) {
3028612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        XLOG("eglMakeCurrent failed\n");
3038612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        return EGL_NO_CONTEXT;
3048612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    }
3058612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3068612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return context;
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
3166edf92433a1c328f0b8e166fefc687e691dd7298Nicolas RoardGLuint GLUtils::createSampleColorTexture(int r, int g, int b) {
3176edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLuint texture;
3186edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glGenTextures(1, &texture);
3196edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3206edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLubyte pixels[4 *3] = {
3216edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3226edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3236edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b,
3246edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard        r, g, b
3256edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    };
3266edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
3276edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLUtils::checkGlError("glBindTexture");
3286edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
3296edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    GLUtils::checkGlError("glTexImage2D");
3306edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3316edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3326edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard    return texture;
3336edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard}
3346edf92433a1c328f0b8e166fefc687e691dd7298Nicolas Roard
3358c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas RoardGLuint GLUtils::createSampleTexture()
3368c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
3378612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLuint texture;
3388612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glGenTextures(1, &texture);
3398612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3408612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLubyte pixels[4 *3] = {
3418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        255, 0, 0,
3428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        0, 255, 0,
3438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        0, 0, 255,
3448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard        255, 255, 0
3458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    };
3468612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
3478612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
3488612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
3498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glTexImage2D");
3508612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3518612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3528612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    return texture;
3538612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
3548612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
3557c554a61cb935660cdc86905d040c781b490150fTeng-Hui ZhuGLuint GLUtils::createBaseTileGLTexture(int width, int height)
3567c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu{
3577c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLuint texture;
3587c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glGenTextures(1, &texture);
3597c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
3607c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLubyte* pixels = 0;
3617c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#ifdef DEBUG
3627c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    int length = width * height * 4;
3637c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    pixels = new GLubyte[length];
3647c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    for (int i = 0; i < length; i++)
3657c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        pixels[i] = i % 256;
3667c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#endif
3677c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glBindTexture(GL_TEXTURE_2D, texture);
3687c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLUtils::checkGlError("glBindTexture");
3697c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
3707c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    GLUtils::checkGlError("glTexImage2D");
3717c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3727c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
37317374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu#ifdef DEBUG
37417374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu    delete pixels;
37517374f84814bd0398b7d9f10fe6c3f517a0762dfTeng-Hui Zhu#endif
3767c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    return texture;
3777c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu}
3787c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
3798abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhubool GLUtils::isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor)
3808abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu{
3818abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // If the bitmap is the pure color, skip the transfer step, and update the BaseTile Info.
3828abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // This check is taking < 1ms if we do full bitmap check per tile.
3838abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // TODO: use the SkPicture to determine whether or not a tile is single color.
3848abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    pureColor = Color(Color::transparent);
3858abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bitmap.lockPixels();
3868abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bool sameColor = true;
3878abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int bitmapWidth = bitmap.width();
3888abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
3898abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // Create a row of pure color using the first pixel.
390309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // TODO: improve the perf here, by either picking a random pixel, or
391309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // creating an array of rows with pre-defined commonly used color, add
392309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu    // smart LUT to speed things up if possible.
3938abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int* firstPixelPtr = static_cast<int*> (bitmap.getPixels());
3948abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    int* pixelsRow = new int[bitmapWidth];
3958abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    for (int i = 0; i < bitmapWidth; i++)
3968abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        pixelsRow[i] = (*firstPixelPtr);
3978abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
3988abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    // Then compare the pure color row with each row of the bitmap.
3998abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    for (int j = 0; j < bitmap.height(); j++) {
4008abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        if (memcmp(pixelsRow, &firstPixelPtr[bitmapWidth * j], 4 * bitmapWidth)) {
4018abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            sameColor = false;
4028abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            break;
4038abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        }
4048abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4058abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    delete pixelsRow;
4068abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    pixelsRow = 0;
4078abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4088abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (sameColor) {
4098abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        char* rgbaPtr = static_cast<char*>(bitmap.getPixels());
4108abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        pureColor = Color(rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
4118abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        XLOG("sameColor tile found , %x at (%d, %d, %d, %d)",
4128abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu             *firstPixelPtr, rgbaPtr[0], rgbaPtr[1], rgbaPtr[2], rgbaPtr[3]);
4138abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4148abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bitmap.unlockPixels();
4158abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4168abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    return sameColor;
4178abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu}
4188abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4198abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu// Return true when the tile is pure color.
4208abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhubool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo,
4218abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu                                       const SkBitmap& bitmap)
4228abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu{
4238abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    bool skipTransfer = false;
4248abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    BaseTile* tilePtr = renderInfo->baseTile;
4258abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4268abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (tilePtr) {
4278abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        BaseTileTexture* tileTexture = tilePtr->backTexture();
4288abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        // Check the bitmap, and make everything ready here.
4298abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        Color pureColor;
430309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu        if (tileTexture && isPureColorBitmap(bitmap, pureColor)) {
4318abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // update basetile's info
4328abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu            // Note that we are skipping the whole TransferQueue.
433309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_width = bitmap.width();
434309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_height = bitmap.height();
435309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            renderInfo->textureInfo->m_internalFormat = GL_RGBA;
436309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu
437309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            TilesManager::instance()->transferQueue()->addItemInPureColorQueue(renderInfo,
438309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu                                                                               pureColor);
439309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu
440309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu            skipTransfer = true;
4418abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        }
4428abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    }
4438abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    return skipTransfer;
4448abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu}
4458abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
4467c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhuvoid GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
4477c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu                                     const SkBitmap& bitmap)
448dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu{
4497c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (!renderInfo)
4507c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        return;
4517c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    const int x = renderInfo->invalRect->fLeft;
4527c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    const int y = renderInfo->invalRect->fTop;
4537c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    const SkSize& requiredSize = renderInfo->tileSize;
4547c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    TextureInfo* textureInfo = renderInfo->textureInfo;
455ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger
4568abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu    if (skipTransferForPureColor(renderInfo, bitmap))
4578abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu        return;
4588abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu
45962ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    if (requiredSize.equals(textureInfo->m_width, textureInfo->m_height))
46062ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu        GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, x, y, bitmap);
46162ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu    else {
462ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        if (!requiredSize.equals(bitmap.width(), bitmap.height())) {
463ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger            XLOG("The bitmap size (%d,%d) does not equal the texture size (%d,%d)",
464ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger                    bitmap.width(), bitmap.height(),
465ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger                    requiredSize.width(), requiredSize.height());
466ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        }
46762ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu        GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, 0, 0, bitmap);
468ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger
469ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        textureInfo->m_width = bitmap.width();
470ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger        textureInfo->m_height = bitmap.height();
4717c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        textureInfo->m_internalFormat = GL_RGBA;
472dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu    }
473dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu}
474dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
4757c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhuvoid GLUtils::updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, int x, int y, const SkBitmap& bitmap)
4767c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu{
4777c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu    if (!renderInfo
4787c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        || !renderInfo->textureInfo
4797c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        || !renderInfo->baseTile)
4807c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu        return;
4817c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu
48251c84083c0059a8e849bf0031704b0ec402059f0Teng-Hui Zhu    TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, x, y, bitmap);
4837c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu}
484dab8d6ca15f21acf3089e18d85dc88f98d4417feTeng-Hui Zhu
485ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenbergervoid GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter)
4868c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
4878612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
4888612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
4898612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
4908612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    SkBitmap::Config config = bitmap.getConfig();
4918612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    int internalformat = getInternalFormat(config);
4928612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    int type = getType(config);
4938612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bitmap.lockPixels();
4948612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexImage2D(GL_TEXTURE_2D, 0, internalformat, bitmap.width(), bitmap.height(),
4958612b3c490ba10449012086a45b9021daa488e65Nicolas Roard                 0, internalformat, type, bitmap.getPixels());
4968612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    bitmap.unlockPixels();
49744009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    if (GLUtils::checkGlError("glTexImage2D")) {
49844009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu        XLOG("GL ERROR: glTexImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
49944009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu             " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
50044009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu             bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
50144009dc8813df9eb0815bf581740a7c365f3b515Teng-Hui Zhu    }
5028612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
5038612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
504bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard
505bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    // The following is a workaround -- remove when EGLImage texture upload is fixed.
506bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    GLuint fboID;
507bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glGenFramebuffers(1, &fboID);
508bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glBindFramebuffer(GL_FRAMEBUFFER, fboID);
509bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
510bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glCheckFramebufferStatus(GL_FRAMEBUFFER); // should return GL_FRAMEBUFFER_COMPLETE
511bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard
512bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO
513bc87f888df256a489e174b10c22d270f64903a3eNicolas Roard    glDeleteFramebuffers(1, &fboID);
5148612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5158612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
516ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenbergervoid GLUtils::updateTextureWithBitmap(GLuint texture, int x, int y, const SkBitmap& bitmap, GLint filter)
51767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard{
51867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
51967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
52067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    GLUtils::checkGlError("glBindTexture");
52167e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    SkBitmap::Config config = bitmap.getConfig();
52267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    int internalformat = getInternalFormat(config);
52367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    int type = getType(config);
52467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bitmap.lockPixels();
52567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, bitmap.width(), bitmap.height(),
52667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard                    internalformat, type, bitmap.getPixels());
52767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    bitmap.unlockPixels();
52867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    if (GLUtils::checkGlError("glTexSubImage2D")) {
52967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard        XLOG("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
5307e03c379b83d3947f8927ebc4d6f7ca30e1cc53cTeng-Hui Zhu             " x %d, y %d, internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
5317e03c379b83d3947f8927ebc4d6f7ca30e1cc53cTeng-Hui Zhu             bitmap.width(), bitmap.height(), x, y, internalformat, type, bitmap.getPixels());
53267e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    }
53367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
5348612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
5358612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5368612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
5378c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::createEGLImageFromTexture(GLuint texture, EGLImageKHR* image)
5388c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
5398612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(texture);
5408612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    static const EGLint attr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
5418612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    *image = eglCreateImageKHR(eglGetCurrentDisplay(), eglGetCurrentContext(),
5428612b3c490ba10449012086a45b9021daa488e65Nicolas Roard                               EGL_GL_TEXTURE_2D_KHR, buffer, attr);
5438612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkEglError("eglCreateImage", (*image != EGL_NO_IMAGE_KHR));
5448612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5458612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
5468c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roardvoid GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter)
5478c3b4386c279f644e5e9d2c5769fe5a43c6cd0caNicolas Roard{
5488612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glBindTexture(GL_TEXTURE_2D, texture);
5498612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    GLUtils::checkGlError("glBindTexture");
5508612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
5518612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
5528612b3c490ba10449012086a45b9021daa488e65Nicolas Roard    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
5538612b3c490ba10449012086a45b9021daa488e65Nicolas Roard}
5548612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
555e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhuvoid GLUtils::convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix)
556e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu{
557e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu    transformMatrix.setMatrix(
558e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[0], matrix[1], matrix[2], matrix[3],
559e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[4], matrix[5], matrix[6], matrix[7],
560e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[8], matrix[9], matrix[10], matrix[11],
561e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu        matrix[12], matrix[13], matrix[14], matrix[15]);
562e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu}
563e7770b07e6dd4b0edff8725bc0f7a505417dd4f1Teng-Hui Zhu
5648612b3c490ba10449012086a45b9021daa488e65Nicolas Roard} // namespace WebCore
5658612b3c490ba10449012086a45b9021daa488e65Nicolas Roard
5668612b3c490ba10449012086a45b9021daa488e65Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING)
567