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