1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/gl/gl_image_egl.h" 6 7 #include "ui/gl/gl_bindings.h" 8 #include "ui/gl/gl_surface_egl.h" 9 10 namespace gfx { 11 12 GLImageEGL::GLImageEGL(gfx::Size size) 13 : egl_image_(EGL_NO_IMAGE_KHR), 14 size_(size), 15 release_after_use_(false), 16 in_use_(false), 17 target_(0) { 18 } 19 20 GLImageEGL::~GLImageEGL() { 21 Destroy(); 22 } 23 24 bool GLImageEGL::Initialize(gfx::GpuMemoryBufferHandle buffer) { 25 DCHECK(buffer.native_buffer); 26 EGLint attrs[] = { 27 EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 28 EGL_NONE, 29 }; 30 egl_image_ = eglCreateImageKHR( 31 GLSurfaceEGL::GetHardwareDisplay(), 32 EGL_NO_CONTEXT, 33 EGL_NATIVE_BUFFER_ANDROID, 34 buffer.native_buffer, 35 attrs); 36 37 if (egl_image_ == EGL_NO_IMAGE_KHR) { 38 EGLint error = eglGetError(); 39 LOG(ERROR) << "Error creating EGLImage: " << error; 40 return false; 41 } 42 43 return true; 44 } 45 46 void GLImageEGL::Destroy() { 47 if (egl_image_ == EGL_NO_IMAGE_KHR) 48 return; 49 50 EGLBoolean success = eglDestroyImageKHR( 51 GLSurfaceEGL::GetHardwareDisplay(), egl_image_); 52 53 if (success == EGL_FALSE) { 54 EGLint error = eglGetError(); 55 LOG(ERROR) << "Error destroying EGLImage: " << error; 56 } 57 58 egl_image_ = EGL_NO_IMAGE_KHR; 59 } 60 61 gfx::Size GLImageEGL::GetSize() { 62 return size_; 63 } 64 65 bool GLImageEGL::BindTexImage(unsigned target) { 66 if (egl_image_ == EGL_NO_IMAGE_KHR) { 67 LOG(ERROR) << "NULL EGLImage in BindTexImage"; 68 return false; 69 } 70 71 if (target == GL_TEXTURE_RECTANGLE_ARB) { 72 LOG(ERROR) << "EGLImage cannot be bound to TEXTURE_RECTANGLE_ARB target"; 73 return false; 74 } 75 76 if (target_ && target_ != target) { 77 LOG(ERROR) << "EGLImage can only be bound to one target"; 78 return false; 79 } 80 target_ = target; 81 82 // Defer ImageTargetTexture2D if not currently in use. 83 if (!in_use_) 84 return true; 85 86 glEGLImageTargetTexture2DOES(target_, egl_image_); 87 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); 88 return true; 89 } 90 91 void GLImageEGL::ReleaseTexImage(unsigned target) { 92 // Nothing to do here as image is released after each use or there is no need 93 // to release image. 94 } 95 96 void GLImageEGL::WillUseTexImage() { 97 DCHECK(egl_image_); 98 DCHECK(!in_use_); 99 in_use_ = true; 100 glEGLImageTargetTexture2DOES(target_, egl_image_); 101 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); 102 } 103 104 void GLImageEGL::DidUseTexImage() { 105 DCHECK(in_use_); 106 in_use_ = false; 107 108 if (!release_after_use_) 109 return; 110 111 char zero[4] = { 0, }; 112 glTexImage2D(target_, 113 0, 114 GL_RGBA, 115 1, 116 1, 117 0, 118 GL_RGBA, 119 GL_UNSIGNED_BYTE, 120 &zero); 121 } 122 123 void GLImageEGL::SetReleaseAfterUse() { 124 release_after_use_ = true; 125 } 126 127 } // namespace gfx 128