1 // Copyright 2014 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.
5 #include "ui/gl/gl_image_android_native_buffer.h"
7 #include "ui/gl/gl_surface_egl.h"
8 #include "ui/gl/scoped_binders.h"
12 GLImageAndroidNativeBuffer::GLImageAndroidNativeBuffer(gfx::Size size
)
14 release_after_use_(false),
17 egl_image_for_unbind_(EGL_NO_IMAGE_KHR
),
18 texture_id_for_unbind_(0) {}
20 GLImageAndroidNativeBuffer::~GLImageAndroidNativeBuffer() { Destroy(); }
22 bool GLImageAndroidNativeBuffer::Initialize(gfx::GpuMemoryBufferHandle buffer
) {
23 DCHECK(buffer
.native_buffer
);
25 EGLint attrs
[] = {EGL_IMAGE_PRESERVED_KHR
, EGL_TRUE
, EGL_NONE
};
26 return GLImageEGL::Initialize(
27 EGL_NATIVE_BUFFER_ANDROID
, buffer
.native_buffer
, attrs
);
30 void GLImageAndroidNativeBuffer::Destroy() {
31 if (egl_image_for_unbind_
!= EGL_NO_IMAGE_KHR
) {
32 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
33 egl_image_for_unbind_
);
34 egl_image_for_unbind_
= EGL_NO_IMAGE_KHR
;
36 if (texture_id_for_unbind_
) {
37 glDeleteTextures(1, &texture_id_for_unbind_
);
38 texture_id_for_unbind_
= 0;
41 GLImageEGL::Destroy();
44 bool GLImageAndroidNativeBuffer::BindTexImage(unsigned target
) {
45 DCHECK_NE(EGL_NO_IMAGE_KHR
, egl_image_
);
47 if (target
== GL_TEXTURE_RECTANGLE_ARB
) {
48 LOG(ERROR
) << "EGLImage cannot be bound to TEXTURE_RECTANGLE_ARB target";
52 if (target_
&& target_
!= target
) {
53 LOG(ERROR
) << "EGLImage can only be bound to one target";
58 // Defer ImageTargetTexture2D if not currently in use.
62 glEGLImageTargetTexture2DOES(target_
, egl_image_
);
63 DCHECK_EQ(static_cast<GLenum
>(GL_NO_ERROR
), glGetError());
67 void GLImageAndroidNativeBuffer::WillUseTexImage() {
71 glEGLImageTargetTexture2DOES(target_
, egl_image_
);
72 DCHECK_EQ(static_cast<GLenum
>(GL_NO_ERROR
), glGetError());
75 void GLImageAndroidNativeBuffer::DidUseTexImage() {
79 if (!release_after_use_
)
82 if (egl_image_for_unbind_
== EGL_NO_IMAGE_KHR
) {
83 DCHECK_EQ(0u, texture_id_for_unbind_
);
84 glGenTextures(1, &texture_id_for_unbind_
);
87 ScopedTextureBinder
texture_binder(GL_TEXTURE_2D
, texture_id_for_unbind_
);
88 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
89 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
90 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
94 GL_TEXTURE_2D
, 0, GL_RGBA
, 1, 1, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, &zero
);
97 EGLint attrs
[] = {EGL_IMAGE_PRESERVED_KHR
, EGL_TRUE
, EGL_NONE
};
98 // Need to pass current EGL rendering context to eglCreateImageKHR for
99 // target type EGL_GL_TEXTURE_2D_KHR.
100 egl_image_for_unbind_
= eglCreateImageKHR(
101 GLSurfaceEGL::GetHardwareDisplay(),
102 eglGetCurrentContext(),
103 EGL_GL_TEXTURE_2D_KHR
,
104 reinterpret_cast<EGLClientBuffer
>(texture_id_for_unbind_
),
106 DCHECK_NE(EGL_NO_IMAGE_KHR
, egl_image_for_unbind_
)
107 << "Error creating EGLImage: " << eglGetError();
110 glEGLImageTargetTexture2DOES(target_
, egl_image_for_unbind_
);
111 DCHECK_EQ(static_cast<GLenum
>(GL_NO_ERROR
), glGetError());
114 void GLImageAndroidNativeBuffer::SetReleaseAfterUse() {
115 release_after_use_
= true;