Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright 2010, The Android Open Source Project
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *  * Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  *  * Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "GLUtils.h"
     28 
     29 #if USE(ACCELERATED_COMPOSITING)
     30 
     31 #include "ShaderProgram.h"
     32 #include "TilesManager.h"
     33 
     34 #include <cutils/log.h>
     35 #include <gui/SurfaceTexture.h>
     36 #include <wtf/CurrentTime.h>
     37 #include <wtf/text/CString.h>
     38 
     39 
     40 #ifdef DEBUG
     41 
     42 #include <cutils/log.h>
     43 #include <wtf/text/CString.h>
     44 
     45 #undef XLOG
     46 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GLUtils", __VA_ARGS__)
     47 
     48 #else
     49 
     50 #undef XLOG
     51 #define XLOG(...)
     52 
     53 #endif // DEBUG
     54 
     55 struct ANativeWindowBuffer;
     56 
     57 namespace WebCore {
     58 
     59 using namespace android;
     60 
     61 /////////////////////////////////////////////////////////////////////////////////////////
     62 // Matrix utilities
     63 /////////////////////////////////////////////////////////////////////////////////////////
     64 
     65 void GLUtils::toGLMatrix(GLfloat* flattened, const TransformationMatrix& m)
     66 {
     67     flattened[0] = m.m11(); // scaleX
     68     flattened[1] = m.m12(); // skewY
     69     flattened[2] = m.m13();
     70     flattened[3] = m.m14(); // persp0
     71     flattened[4] = m.m21(); // skewX
     72     flattened[5] = m.m22(); // scaleY
     73     flattened[6] = m.m23();
     74     flattened[7] = m.m24(); // persp1
     75     flattened[8] = m.m31();
     76     flattened[9] = m.m32();
     77     flattened[10] = m.m33();
     78     flattened[11] = m.m34();
     79     flattened[12] = m.m41(); // transX
     80     flattened[13] = m.m42(); // transY
     81     flattened[14] = m.m43();
     82     flattened[15] = m.m44(); // persp2
     83 }
     84 
     85 void GLUtils::toSkMatrix(SkMatrix& matrix, const TransformationMatrix& m)
     86 {
     87     matrix[0] = m.m11(); // scaleX
     88     matrix[1] = m.m21(); // skewX
     89     matrix[2] = m.m41(); // transX
     90     matrix[3] = m.m12(); // skewY
     91     matrix[4] = m.m22(); // scaleY
     92     matrix[5] = m.m42(); // transY
     93     matrix[6] = m.m14(); // persp0
     94     matrix[7] = m.m24(); // persp1
     95     matrix[8] = m.m44(); // persp2
     96 }
     97 
     98 void GLUtils::setOrthographicMatrix(TransformationMatrix& ortho, float left, float top,
     99                                     float right, float bottom, float nearZ, float farZ)
    100 {
    101     float deltaX = right - left;
    102     float deltaY = top - bottom;
    103     float deltaZ = farZ - nearZ;
    104     if (!deltaX || !deltaY || !deltaZ)
    105         return;
    106 
    107     ortho.setM11(2.0f / deltaX);
    108     ortho.setM41(-(right + left) / deltaX);
    109     ortho.setM22(2.0f / deltaY);
    110     ortho.setM42(-(top + bottom) / deltaY);
    111     ortho.setM33(-2.0f / deltaZ);
    112     ortho.setM43(-(nearZ + farZ) / deltaZ);
    113 }
    114 
    115 /////////////////////////////////////////////////////////////////////////////////////////
    116 // GL & EGL error checks
    117 /////////////////////////////////////////////////////////////////////////////////////////
    118 
    119 static void crashIfOOM(GLint errorCode) {
    120     const GLint OOM_ERROR_CODE = 0x505;
    121     if (errorCode == OOM_ERROR_CODE) {
    122         XLOG("Fatal OOM detected.");
    123         CRASH();
    124     }
    125 }
    126 
    127 void GLUtils::checkEglError(const char* op, EGLBoolean returnVal)
    128 {
    129     if (returnVal != EGL_TRUE) {
    130         XLOG("EGL ERROR - %s() returned %d\n", op, returnVal);
    131     }
    132 
    133     for (EGLint error = eglGetError(); error != EGL_SUCCESS; error = eglGetError()) {
    134         XLOG("after %s() eglError (0x%x)\n", op, error);
    135         crashIfOOM(error);
    136     }
    137 }
    138 
    139 bool GLUtils::checkGlError(const char* op)
    140 {
    141     bool ret = false;
    142     for (GLint error = glGetError(); error; error = glGetError()) {
    143         XLOG("GL ERROR - after %s() glError (0x%x)\n", op, error);
    144         crashIfOOM(error);
    145         ret = true;
    146     }
    147     return ret;
    148 }
    149 
    150 bool GLUtils::checkGlErrorOn(void* p, const char* op)
    151 {
    152     bool ret = false;
    153     for (GLint error = glGetError(); error; error = glGetError()) {
    154         XLOG("GL ERROR on %x - after %s() glError (0x%x)\n", p, op, error);
    155         crashIfOOM(error);
    156         ret = true;
    157     }
    158     return ret;
    159 }
    160 
    161 void GLUtils::checkSurfaceTextureError(const char* functionName, int status)
    162 {
    163     if (status !=  NO_ERROR) {
    164         XLOG("ERROR at calling %s status is (%d)", functionName, status);
    165     }
    166 }
    167 /////////////////////////////////////////////////////////////////////////////////////////
    168 // GL & EGL extension checks
    169 /////////////////////////////////////////////////////////////////////////////////////////
    170 
    171 bool GLUtils::isEGLImageSupported()
    172 {
    173     const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
    174     const char* glExtensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
    175 
    176     return eglExtensions && glExtensions
    177         && strstr(eglExtensions, "EGL_KHR_image_base")
    178         && strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image")
    179         && strstr(glExtensions, "GL_OES_EGL_image");
    180 }
    181 
    182 bool GLUtils::isEGLFenceSyncSupported()
    183 {
    184     const char* eglExtensions = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
    185     return eglExtensions && strstr(eglExtensions, "EGL_KHR_fence_sync");
    186 }
    187 
    188 /////////////////////////////////////////////////////////////////////////////////////////
    189 // Textures utilities
    190 /////////////////////////////////////////////////////////////////////////////////////////
    191 
    192 static GLenum getInternalFormat(SkBitmap::Config config)
    193 {
    194     switch (config) {
    195     case SkBitmap::kA8_Config:
    196         return GL_ALPHA;
    197     case SkBitmap::kARGB_4444_Config:
    198         return GL_RGBA;
    199     case SkBitmap::kARGB_8888_Config:
    200         return GL_RGBA;
    201     case SkBitmap::kRGB_565_Config:
    202         return GL_RGB;
    203     default:
    204         return -1;
    205     }
    206 }
    207 
    208 static GLenum getType(SkBitmap::Config config)
    209 {
    210     switch (config) {
    211     case SkBitmap::kA8_Config:
    212         return GL_UNSIGNED_BYTE;
    213     case SkBitmap::kARGB_4444_Config:
    214         return GL_UNSIGNED_SHORT_4_4_4_4;
    215     case SkBitmap::kARGB_8888_Config:
    216         return GL_UNSIGNED_BYTE;
    217     case SkBitmap::kIndex8_Config:
    218         return -1; // No type for compressed data.
    219     case SkBitmap::kRGB_565_Config:
    220         return GL_UNSIGNED_SHORT_5_6_5;
    221     default:
    222         return -1;
    223     }
    224 }
    225 
    226 static EGLConfig defaultPbufferConfig(EGLDisplay display)
    227 {
    228     EGLConfig config;
    229     EGLint numConfigs;
    230 
    231     static const EGLint configAttribs[] = {
    232         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    233         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    234         EGL_NONE
    235     };
    236 
    237     eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
    238     GLUtils::checkEglError("eglPbufferConfig");
    239     if (numConfigs != 1)
    240         LOGI("eglPbufferConfig failed (%d)\n", numConfigs);
    241 
    242     return config;
    243 }
    244 
    245 static EGLSurface createPbufferSurface(EGLDisplay display, const EGLConfig& config,
    246                                        EGLint* errorCode)
    247 {
    248     const EGLint attribList[] = {
    249         EGL_WIDTH, 1,
    250         EGL_HEIGHT, 1,
    251         EGL_NONE
    252     };
    253     EGLSurface surface = eglCreatePbufferSurface(display, config, attribList);
    254 
    255     if (errorCode)
    256         *errorCode = eglGetError();
    257     else
    258         GLUtils::checkEglError("eglCreatePbufferSurface");
    259 
    260     if (surface == EGL_NO_SURFACE)
    261         return EGL_NO_SURFACE;
    262 
    263     return surface;
    264 }
    265 
    266 EGLContext GLUtils::createBackgroundContext(EGLContext sharedContext)
    267 {
    268     checkEglError("<init>");
    269     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    270     checkEglError("eglGetDisplay");
    271     if (display == EGL_NO_DISPLAY) {
    272         XLOG("eglGetDisplay returned EGL_NO_DISPLAY");
    273         return EGL_NO_CONTEXT;
    274     }
    275 
    276     EGLint majorVersion;
    277     EGLint minorVersion;
    278     EGLBoolean returnValue = eglInitialize(display, &majorVersion, &minorVersion);
    279     checkEglError("eglInitialize", returnValue);
    280     if (returnValue != EGL_TRUE) {
    281         XLOG("eglInitialize failed\n");
    282         return EGL_NO_CONTEXT;
    283     }
    284 
    285     EGLConfig config = defaultPbufferConfig(display);
    286     EGLSurface surface = createPbufferSurface(display, config, 0);
    287 
    288     EGLint surfaceConfigId;
    289     EGLBoolean success = eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &surfaceConfigId);
    290 
    291     EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
    292     EGLContext context = eglCreateContext(display, config, sharedContext, contextAttribs);
    293     checkEglError("eglCreateContext");
    294     if (context == EGL_NO_CONTEXT) {
    295         XLOG("eglCreateContext failed\n");
    296         return EGL_NO_CONTEXT;
    297     }
    298 
    299     returnValue = eglMakeCurrent(display, surface, surface, context);
    300     checkEglError("eglMakeCurrent", returnValue);
    301     if (returnValue != EGL_TRUE) {
    302         XLOG("eglMakeCurrent failed\n");
    303         return EGL_NO_CONTEXT;
    304     }
    305 
    306     return context;
    307 }
    308 
    309 void GLUtils::deleteTexture(GLuint* texture)
    310 {
    311     glDeleteTextures(1, texture);
    312     GLUtils::checkGlError("glDeleteTexture");
    313     *texture = 0;
    314 }
    315 
    316 GLuint GLUtils::createSampleColorTexture(int r, int g, int b) {
    317     GLuint texture;
    318     glGenTextures(1, &texture);
    319     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    320     GLubyte pixels[4 *3] = {
    321         r, g, b,
    322         r, g, b,
    323         r, g, b,
    324         r, g, b
    325     };
    326     glBindTexture(GL_TEXTURE_2D, texture);
    327     GLUtils::checkGlError("glBindTexture");
    328     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
    329     GLUtils::checkGlError("glTexImage2D");
    330     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    331     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    332     return texture;
    333 }
    334 
    335 GLuint GLUtils::createSampleTexture()
    336 {
    337     GLuint texture;
    338     glGenTextures(1, &texture);
    339     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    340     GLubyte pixels[4 *3] = {
    341         255, 0, 0,
    342         0, 255, 0,
    343         0, 0, 255,
    344         255, 255, 0
    345     };
    346     glBindTexture(GL_TEXTURE_2D, texture);
    347     GLUtils::checkGlError("glBindTexture");
    348     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
    349     GLUtils::checkGlError("glTexImage2D");
    350     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    351     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    352     return texture;
    353 }
    354 
    355 GLuint GLUtils::createBaseTileGLTexture(int width, int height)
    356 {
    357     GLuint texture;
    358     glGenTextures(1, &texture);
    359     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    360     GLubyte* pixels = 0;
    361 #ifdef DEBUG
    362     int length = width * height * 4;
    363     pixels = new GLubyte[length];
    364     for (int i = 0; i < length; i++)
    365         pixels[i] = i % 256;
    366 #endif
    367     glBindTexture(GL_TEXTURE_2D, texture);
    368     GLUtils::checkGlError("glBindTexture");
    369     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    370     GLUtils::checkGlError("glTexImage2D");
    371     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    372     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    373     return texture;
    374 }
    375 
    376 void GLUtils::paintTextureWithBitmap(const TileRenderInfo* renderInfo,
    377                                      const SkBitmap& bitmap)
    378 {
    379     if (!renderInfo)
    380         return;
    381     const int x = renderInfo->invalRect->fLeft;
    382     const int y = renderInfo->invalRect->fTop;
    383     const SkSize& requiredSize = renderInfo->tileSize;
    384     TextureInfo* textureInfo = renderInfo->textureInfo;
    385     SharedTextureMode mode = textureInfo->getSharedTextureMode();
    386     if (requiredSize.equals(textureInfo->m_width, textureInfo->m_height)) {
    387         if (mode == EglImageMode)
    388             GLUtils::updateTextureWithBitmap(textureInfo->m_textureId, x, y, bitmap);
    389         else if (mode == SurfaceTextureMode)
    390 #if DEPRECATED_SURFACE_TEXTURE_MODE
    391             GLUtils::updateSurfaceTextureWithBitmap(renderInfo, x, y, bitmap);
    392 #else
    393             GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, x, y, bitmap);
    394 #endif
    395     } else {
    396 
    397         if (!requiredSize.equals(bitmap.width(), bitmap.height())) {
    398             XLOG("The bitmap size (%d,%d) does not equal the texture size (%d,%d)",
    399                     bitmap.width(), bitmap.height(),
    400                     requiredSize.width(), requiredSize.height());
    401         }
    402 
    403         if (mode == EglImageMode)
    404             GLUtils::createTextureWithBitmap(textureInfo->m_textureId, bitmap);
    405         else if (mode == SurfaceTextureMode)
    406 #if DEPRECATED_SURFACE_TEXTURE_MODE
    407             GLUtils::createSurfaceTextureWithBitmap(renderInfo, bitmap);
    408 #else
    409             GLUtils::updateSharedSurfaceTextureWithBitmap(renderInfo, 0, 0, bitmap);
    410 #endif
    411         textureInfo->m_width = bitmap.width();
    412         textureInfo->m_height = bitmap.height();
    413         textureInfo->m_internalFormat = GL_RGBA;
    414     }
    415 }
    416 
    417 #if DEPRECATED_SURFACE_TEXTURE_MODE
    418 void GLUtils::createSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, const SkBitmap& bitmap, GLint filter)
    419 {
    420 
    421     TextureInfo* texture = renderInfo->textureInfo;
    422 
    423     texture->m_width = bitmap.width();
    424     texture->m_height = bitmap.height();
    425     texture->m_internalFormat = GL_RGBA;
    426 
    427     sp<android::SurfaceTexture> surfaceTexture = texture->m_surfaceTexture;
    428     sp<ANativeWindow> ANW = texture->m_ANW;
    429 
    430     int result;
    431     result = native_window_set_buffers_geometry(ANW.get(),
    432             texture->m_width, texture->m_height, HAL_PIXEL_FORMAT_RGBA_8888);
    433     checkSurfaceTextureError("native_window_set_buffers_geometry", result);
    434     result = native_window_set_usage(ANW.get(),
    435             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
    436     checkSurfaceTextureError("native_window_set_usage", result);
    437 
    438     updateSurfaceTextureWithBitmap(renderInfo, 0, 0, bitmap, filter);
    439 }
    440 
    441 void GLUtils::updateSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, int x, int y, const SkBitmap& bitmap, GLint filter)
    442 {
    443     TextureInfo* texture = renderInfo->textureInfo;
    444     sp<android::SurfaceTexture> surfaceTexture = texture->m_surfaceTexture;
    445     sp<ANativeWindow> ANW = texture->m_ANW;
    446 
    447     ANativeWindowBuffer* anb;
    448     int status = ANW->dequeueBuffer(ANW.get(), &anb);
    449     checkSurfaceTextureError("dequeueBuffer", status);
    450 
    451     if (status != NO_ERROR) { // FIXME: add proper error handling!
    452         native_window_set_buffer_count(ANW.get(), 3);
    453         return;
    454     }
    455 
    456     sp<android::GraphicBuffer> buf(new android::GraphicBuffer(anb, false));
    457     status |= ANW->lockBuffer(ANW.get(), buf->getNativeBuffer());
    458     checkSurfaceTextureError("lockBuffer", status);
    459 
    460     // Fill the buffer with the content of the bitmap
    461     uint8_t* img = 0;
    462     status |= buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
    463     checkSurfaceTextureError("lock", status);
    464 
    465     if (status == NO_ERROR) {
    466         int row, col;
    467         int bpp = 4; // Now only deal with RGBA8888 format.
    468 
    469         bitmap.lockPixels();
    470         uint8_t* bitmapOrigin = static_cast<uint8_t*>(bitmap.getPixels());
    471         // Copied line by line since we need to handle the offsets and stride.
    472         for (row = 0 ; row < bitmap.height(); row ++) {
    473             uint8_t* dst = &(img[(buf->getStride() * (row + x) + y) * bpp]);
    474             uint8_t* src = &(bitmapOrigin[bitmap.width() * row * bpp]);
    475             memcpy(dst, src, bpp * bitmap.width());
    476         }
    477         bitmap.unlockPixels();
    478     }
    479     buf->unlock();
    480     status = ANW->queueBuffer(ANW.get(), buf->getNativeBuffer());
    481     checkSurfaceTextureError("queueBuffer", status);
    482 }
    483 #endif
    484 
    485 void GLUtils::updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* renderInfo, int x, int y, const SkBitmap& bitmap)
    486 {
    487     if (!renderInfo
    488         || !renderInfo->textureInfo
    489         || !renderInfo->baseTile)
    490         return;
    491 
    492     TilesManager::instance()->transferQueue()->updateQueueWithBitmap(renderInfo, x, y, bitmap);
    493 }
    494 
    495 void GLUtils::createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter)
    496 {
    497     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    498     glBindTexture(GL_TEXTURE_2D, texture);
    499     GLUtils::checkGlError("glBindTexture");
    500     SkBitmap::Config config = bitmap.getConfig();
    501     int internalformat = getInternalFormat(config);
    502     int type = getType(config);
    503     bitmap.lockPixels();
    504     glTexImage2D(GL_TEXTURE_2D, 0, internalformat, bitmap.width(), bitmap.height(),
    505                  0, internalformat, type, bitmap.getPixels());
    506     bitmap.unlockPixels();
    507     if (GLUtils::checkGlError("glTexImage2D")) {
    508         XLOG("GL ERROR: glTexImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
    509              " internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
    510              bitmap.width(), bitmap.height(), internalformat, type, bitmap.getPixels());
    511     }
    512     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
    513     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
    514 
    515     // The following is a workaround -- remove when EGLImage texture upload is fixed.
    516     GLuint fboID;
    517     glGenFramebuffers(1, &fboID);
    518     glBindFramebuffer(GL_FRAMEBUFFER, fboID);
    519     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    520     glCheckFramebufferStatus(GL_FRAMEBUFFER); // should return GL_FRAMEBUFFER_COMPLETE
    521 
    522     glBindFramebuffer(GL_FRAMEBUFFER, 0); // rebind the standard FBO
    523     glDeleteFramebuffers(1, &fboID);
    524 }
    525 
    526 void GLUtils::updateTextureWithBitmap(GLuint texture, int x, int y, const SkBitmap& bitmap, GLint filter)
    527 {
    528     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    529     glBindTexture(GL_TEXTURE_2D, texture);
    530     GLUtils::checkGlError("glBindTexture");
    531     SkBitmap::Config config = bitmap.getConfig();
    532     int internalformat = getInternalFormat(config);
    533     int type = getType(config);
    534     bitmap.lockPixels();
    535     glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, bitmap.width(), bitmap.height(),
    536                     internalformat, type, bitmap.getPixels());
    537     bitmap.unlockPixels();
    538     if (GLUtils::checkGlError("glTexSubImage2D")) {
    539         XLOG("GL ERROR: glTexSubImage2D parameters are : bitmap.width() %d, bitmap.height() %d,"
    540              " x %d, y %d, internalformat 0x%x, type 0x%x, bitmap.getPixels() %p",
    541              bitmap.width(), bitmap.height(), x, y, internalformat, type, bitmap.getPixels());
    542     }
    543     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
    544     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
    545 }
    546 
    547 void GLUtils::createEGLImageFromTexture(GLuint texture, EGLImageKHR* image)
    548 {
    549     EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(texture);
    550     static const EGLint attr[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
    551     *image = eglCreateImageKHR(eglGetCurrentDisplay(), eglGetCurrentContext(),
    552                                EGL_GL_TEXTURE_2D_KHR, buffer, attr);
    553     GLUtils::checkEglError("eglCreateImage", (*image != EGL_NO_IMAGE_KHR));
    554 }
    555 
    556 void GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter)
    557 {
    558     glBindTexture(GL_TEXTURE_2D, texture);
    559     GLUtils::checkGlError("glBindTexture");
    560     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
    561     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
    562     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
    563 }
    564 
    565 void GLUtils::convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix)
    566 {
    567     transformMatrix.setMatrix(
    568         matrix[0], matrix[1], matrix[2], matrix[3],
    569         matrix[4], matrix[5], matrix[6], matrix[7],
    570         matrix[8], matrix[9], matrix[10], matrix[11],
    571         matrix[12], matrix[13], matrix[14], matrix[15]);
    572 }
    573 
    574 } // namespace WebCore
    575 
    576 #endif // USE(ACCELERATED_COMPOSITING)
    577