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
toGLMatrix(GLfloat * flattened,const TransformationMatrix & m)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
toSkMatrix(SkMatrix & matrix,const TransformationMatrix & m)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
setOrthographicMatrix(TransformationMatrix & ortho,float left,float top,float right,float bottom,float nearZ,float farZ)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
crashIfOOM(GLint errorCode)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
checkEglError(const char * op,EGLBoolean returnVal)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
checkGlError(const char * op)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
checkGlErrorOn(void * p,const char * op)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
checkSurfaceTextureError(const char * functionName,int status)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
isEGLImageSupported()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
isEGLFenceSyncSupported()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
getInternalFormat(SkBitmap::Config config)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
getType(SkBitmap::Config config)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
defaultPbufferConfig(EGLDisplay display)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
createPbufferSurface(EGLDisplay display,const EGLConfig & config,EGLint * errorCode)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
createBackgroundContext(EGLContext sharedContext)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
deleteTexture(GLuint * texture)309 void GLUtils::deleteTexture(GLuint* texture)
310 {
311 glDeleteTextures(1, texture);
312 GLUtils::checkGlError("glDeleteTexture");
313 *texture = 0;
314 }
315
createSampleColorTexture(int r,int g,int b)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
createSampleTexture()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
createBaseTileGLTexture(int width,int height)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
paintTextureWithBitmap(const TileRenderInfo * renderInfo,const SkBitmap & bitmap)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
createSurfaceTextureWithBitmap(const TileRenderInfo * renderInfo,const SkBitmap & bitmap,GLint filter)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
updateSurfaceTextureWithBitmap(const TileRenderInfo * renderInfo,int x,int y,const SkBitmap & bitmap,GLint filter)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
updateSharedSurfaceTextureWithBitmap(const TileRenderInfo * renderInfo,int x,int y,const SkBitmap & bitmap)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
createTextureWithBitmap(GLuint texture,const SkBitmap & bitmap,GLint filter)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
updateTextureWithBitmap(GLuint texture,int x,int y,const SkBitmap & bitmap,GLint filter)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
createEGLImageFromTexture(GLuint texture,EGLImageKHR * image)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
createTextureFromEGLImage(GLuint texture,EGLImageKHR image,GLint filter)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 } // namespace WebCore
566
567 #endif // USE(ACCELERATED_COMPOSITING)
568