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(const gfx::Size
& size
)
14 release_after_use_(false),
17 egl_image_for_unbind_(EGL_NO_IMAGE_KHR
),
18 texture_id_for_unbind_(0) {
21 GLImageAndroidNativeBuffer::~GLImageAndroidNativeBuffer() {
22 DCHECK_EQ(EGL_NO_IMAGE_KHR
, egl_image_
);
23 DCHECK_EQ(0u, texture_id_for_unbind_
);
26 bool GLImageAndroidNativeBuffer::Initialize(EGLClientBuffer native_buffer
) {
27 EGLint attrs
[] = {EGL_IMAGE_PRESERVED_KHR
, EGL_TRUE
, EGL_NONE
};
28 return GLImageEGL::Initialize(
29 EGL_NATIVE_BUFFER_ANDROID
, native_buffer
, attrs
);
32 void GLImageAndroidNativeBuffer::Destroy(bool have_context
) {
33 if (egl_image_for_unbind_
!= EGL_NO_IMAGE_KHR
) {
34 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(),
35 egl_image_for_unbind_
);
36 egl_image_for_unbind_
= EGL_NO_IMAGE_KHR
;
39 if (texture_id_for_unbind_
) {
41 glDeleteTextures(1, &texture_id_for_unbind_
);
42 texture_id_for_unbind_
= 0u;
45 GLImageEGL::Destroy(have_context
);
48 bool GLImageAndroidNativeBuffer::BindTexImage(unsigned target
) {
49 DCHECK_NE(EGL_NO_IMAGE_KHR
, egl_image_
);
51 if (target
== GL_TEXTURE_RECTANGLE_ARB
) {
52 LOG(ERROR
) << "EGLImage cannot be bound to TEXTURE_RECTANGLE_ARB target";
56 if (target_
&& target_
!= target
) {
57 LOG(ERROR
) << "EGLImage can only be bound to one target";
62 // Defer ImageTargetTexture2D if not currently in use.
66 glEGLImageTargetTexture2DOES(target_
, egl_image_
);
67 DCHECK_EQ(static_cast<GLenum
>(GL_NO_ERROR
), glGetError());
71 void GLImageAndroidNativeBuffer::WillUseTexImage() {
72 DCHECK_NE(EGL_NO_IMAGE_KHR
, egl_image_
);
75 glEGLImageTargetTexture2DOES(target_
, egl_image_
);
76 DCHECK_EQ(static_cast<GLenum
>(GL_NO_ERROR
), glGetError());
79 void GLImageAndroidNativeBuffer::DidUseTexImage() {
80 DCHECK_NE(EGL_NO_IMAGE_KHR
, egl_image_
);
84 if (!release_after_use_
)
87 if (egl_image_for_unbind_
== EGL_NO_IMAGE_KHR
) {
88 DCHECK_EQ(0u, texture_id_for_unbind_
);
89 glGenTextures(1, &texture_id_for_unbind_
);
92 ScopedTextureBinder
texture_binder(GL_TEXTURE_2D
, texture_id_for_unbind_
);
93 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
94 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
95 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
99 GL_TEXTURE_2D
, 0, GL_RGBA
, 1, 1, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, &zero
);
102 EGLint attrs
[] = {EGL_IMAGE_PRESERVED_KHR
, EGL_TRUE
, EGL_NONE
};
103 // Need to pass current EGL rendering context to eglCreateImageKHR for
104 // target type EGL_GL_TEXTURE_2D_KHR.
105 egl_image_for_unbind_
= eglCreateImageKHR(
106 GLSurfaceEGL::GetHardwareDisplay(),
107 eglGetCurrentContext(),
108 EGL_GL_TEXTURE_2D_KHR
,
109 reinterpret_cast<EGLClientBuffer
>(texture_id_for_unbind_
),
111 DCHECK_NE(EGL_NO_IMAGE_KHR
, egl_image_for_unbind_
)
112 << "Error creating EGLImage: " << eglGetError();
115 glEGLImageTargetTexture2DOES(target_
, egl_image_for_unbind_
);
116 DCHECK_EQ(static_cast<GLenum
>(GL_NO_ERROR
), glGetError());
119 bool GLImageAndroidNativeBuffer::ScheduleOverlayPlane(
120 gfx::AcceleratedWidget widget
,
122 OverlayTransform transform
,
123 const Rect
& bounds_rect
,
124 const RectF
& crop_rect
) {
128 void GLImageAndroidNativeBuffer::SetReleaseAfterUse() {
129 release_after_use_
= true;