Home | History | Annotate | Download | only in gl
      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