• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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