• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GLImageEGL(gfx::Size size)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 
~GLImageEGL()20 GLImageEGL::~GLImageEGL() {
21   Destroy();
22 }
23 
Initialize(gfx::GpuMemoryBufferHandle buffer)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 
Destroy()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 
GetSize()61 gfx::Size GLImageEGL::GetSize() {
62   return size_;
63 }
64 
BindTexImage(unsigned target)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 
ReleaseTexImage(unsigned target)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 
WillUseTexImage()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 
DidUseTexImage()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 
SetReleaseAfterUse()123 void GLImageEGL::SetReleaseAfterUse() {
124   release_after_use_ = true;
125 }
126 
127 }  // namespace gfx
128