OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "ui/gl/gl_image_android_native_buffer.h" | |
6 | |
7 #include "ui/gl/gl_surface_egl.h" | |
8 #include "ui/gl/scoped_binders.h" | |
9 | |
10 namespace gfx { | |
11 | |
12 GLImageAndroidNativeBuffer::GLImageAndroidNativeBuffer(const gfx::Size& size) | |
13 : GLImageEGL(size), | |
14 release_after_use_(false), | |
15 in_use_(false), | |
16 target_(0), | |
17 egl_image_for_unbind_(EGL_NO_IMAGE_KHR), | |
18 texture_id_for_unbind_(0) { | |
19 } | |
20 | |
21 GLImageAndroidNativeBuffer::~GLImageAndroidNativeBuffer() { | |
22 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); | |
23 DCHECK_EQ(0u, texture_id_for_unbind_); | |
24 } | |
25 | |
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); | |
30 } | |
31 | |
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; | |
37 } | |
38 | |
39 if (texture_id_for_unbind_) { | |
40 if (have_context) | |
41 glDeleteTextures(1, &texture_id_for_unbind_); | |
42 texture_id_for_unbind_ = 0u; | |
43 } | |
44 | |
45 GLImageEGL::Destroy(have_context); | |
46 } | |
47 | |
48 bool GLImageAndroidNativeBuffer::BindTexImage(unsigned target) { | |
49 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_); | |
50 | |
51 if (target == GL_TEXTURE_RECTANGLE_ARB) { | |
52 LOG(ERROR) << "EGLImage cannot be bound to TEXTURE_RECTANGLE_ARB target"; | |
53 return false; | |
54 } | |
55 | |
56 if (target_ && target_ != target) { | |
57 LOG(ERROR) << "EGLImage can only be bound to one target"; | |
58 return false; | |
59 } | |
60 target_ = target; | |
61 | |
62 // Defer ImageTargetTexture2D if not currently in use. | |
63 if (!in_use_) | |
64 return true; | |
65 | |
66 glEGLImageTargetTexture2DOES(target_, egl_image_); | |
67 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | |
68 return true; | |
69 } | |
70 | |
71 void GLImageAndroidNativeBuffer::WillUseTexImage() { | |
72 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_); | |
73 DCHECK(!in_use_); | |
74 in_use_ = true; | |
75 glEGLImageTargetTexture2DOES(target_, egl_image_); | |
76 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | |
77 } | |
78 | |
79 void GLImageAndroidNativeBuffer::DidUseTexImage() { | |
80 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_); | |
81 DCHECK(in_use_); | |
82 in_use_ = false; | |
83 | |
84 if (!release_after_use_) | |
85 return; | |
86 | |
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_); | |
90 | |
91 { | |
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); | |
96 | |
97 char zero[4] = {0, }; | |
98 glTexImage2D( | |
99 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &zero); | |
100 } | |
101 | |
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_), | |
110 attrs); | |
111 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_for_unbind_) | |
112 << "Error creating EGLImage: " << eglGetError(); | |
113 } | |
114 | |
115 glEGLImageTargetTexture2DOES(target_, egl_image_for_unbind_); | |
116 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | |
117 } | |
118 | |
119 bool GLImageAndroidNativeBuffer::ScheduleOverlayPlane( | |
120 gfx::AcceleratedWidget widget, | |
121 int z_order, | |
122 OverlayTransform transform, | |
123 const Rect& bounds_rect, | |
124 const RectF& crop_rect) { | |
125 return false; | |
126 } | |
127 | |
128 void GLImageAndroidNativeBuffer::SetReleaseAfterUse() { | |
129 release_after_use_ = true; | |
130 } | |
131 | |
132 } // namespace gfx | |
OLD | NEW |