OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gl/gl_image_memory.h" | 5 #include "ui/gl/gl_image_memory.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "ui/gl/gl_bindings.h" | 9 #include "ui/gl/gl_bindings.h" |
10 #include "ui/gl/scoped_binders.h" | 10 #include "ui/gl/scoped_binders.h" |
11 | 11 |
12 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 12 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
13 defined(USE_OZONE) | 13 defined(USE_OZONE) |
14 #include "ui/gl/gl_surface_egl.h" | 14 #include "ui/gl/gl_surface_egl.h" |
15 #endif | 15 #endif |
16 | 16 |
17 namespace gfx { | 17 namespace gfx { |
18 namespace { | 18 namespace { |
19 | 19 |
20 bool ValidFormat(unsigned internalformat) { | 20 bool ValidInternalFormat(unsigned internalformat) { |
21 switch (internalformat) { | 21 switch (internalformat) { |
22 case GL_BGRA8_EXT: | 22 case GL_RGBA: |
23 case GL_RGBA8_OES: | |
24 return true; | 23 return true; |
25 default: | 24 default: |
26 return false; | 25 return false; |
27 } | 26 } |
28 } | 27 } |
29 | 28 |
30 GLenum TextureFormat(unsigned internalformat) { | 29 bool ValidFormat(gfx::GpuMemoryBuffer::Format format) { |
31 switch (internalformat) { | 30 switch (format) { |
32 case GL_BGRA8_EXT: | 31 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 32 case gfx::GpuMemoryBuffer::BGRA_8888: |
| 33 return true; |
| 34 case gfx::GpuMemoryBuffer::RGBX_8888: |
| 35 return false; |
| 36 } |
| 37 |
| 38 NOTREACHED(); |
| 39 return false; |
| 40 } |
| 41 |
| 42 GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) { |
| 43 switch (format) { |
| 44 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 45 return GL_RGBA; |
| 46 case gfx::GpuMemoryBuffer::BGRA_8888: |
33 return GL_BGRA_EXT; | 47 return GL_BGRA_EXT; |
34 case GL_RGBA8_OES: | 48 case gfx::GpuMemoryBuffer::RGBX_8888: |
35 return GL_RGBA; | |
36 default: | |
37 NOTREACHED(); | 49 NOTREACHED(); |
38 return 0; | 50 return 0; |
39 } | 51 } |
| 52 |
| 53 NOTREACHED(); |
| 54 return 0; |
40 } | 55 } |
41 | 56 |
42 GLenum DataFormat(unsigned internalformat) { | 57 GLenum DataFormat(gfx::GpuMemoryBuffer::Format format) { |
43 return TextureFormat(internalformat); | 58 return TextureFormat(format); |
44 } | 59 } |
45 | 60 |
46 GLenum DataType(unsigned internalformat) { | 61 GLenum DataType(gfx::GpuMemoryBuffer::Format format) { |
47 switch (internalformat) { | 62 switch (format) { |
48 case GL_BGRA8_EXT: | 63 case gfx::GpuMemoryBuffer::RGBA_8888: |
49 case GL_RGBA8_OES: | 64 case gfx::GpuMemoryBuffer::BGRA_8888: |
50 return GL_UNSIGNED_BYTE; | 65 return GL_UNSIGNED_BYTE; |
51 default: | 66 case gfx::GpuMemoryBuffer::RGBX_8888: |
52 NOTREACHED(); | 67 NOTREACHED(); |
53 return 0; | 68 return 0; |
54 } | 69 } |
55 } | |
56 | 70 |
57 int BytesPerPixel(unsigned internalformat) { | 71 NOTREACHED(); |
58 switch (internalformat) { | 72 return 0; |
59 case GL_BGRA8_EXT: | |
60 case GL_RGBA8_OES: | |
61 return 4; | |
62 default: | |
63 NOTREACHED(); | |
64 return 0; | |
65 } | |
66 } | 73 } |
67 | 74 |
68 } // namespace | 75 } // namespace |
69 | 76 |
70 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) | 77 GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) |
71 : memory_(NULL), | 78 : size_(size), |
72 size_(size), | |
73 internalformat_(internalformat), | 79 internalformat_(internalformat), |
| 80 memory_(NULL), |
| 81 format_(gfx::GpuMemoryBuffer::RGBA_8888), |
74 in_use_(false), | 82 in_use_(false), |
75 target_(0), | 83 target_(0), |
76 need_do_bind_tex_image_(false) | 84 need_do_bind_tex_image_(false) |
77 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 85 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
78 defined(USE_OZONE) | 86 defined(USE_OZONE) |
79 , | 87 , |
80 egl_texture_id_(0u), | 88 egl_texture_id_(0u), |
81 egl_image_(EGL_NO_IMAGE_KHR) | 89 egl_image_(EGL_NO_IMAGE_KHR) |
82 #endif | 90 #endif |
83 { | 91 { |
84 } | 92 } |
85 | 93 |
86 GLImageMemory::~GLImageMemory() { | 94 GLImageMemory::~GLImageMemory() { |
87 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 95 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
88 defined(USE_OZONE) | 96 defined(USE_OZONE) |
89 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); | 97 DCHECK_EQ(EGL_NO_IMAGE_KHR, egl_image_); |
90 DCHECK_EQ(0u, egl_texture_id_); | 98 DCHECK_EQ(0u, egl_texture_id_); |
91 #endif | 99 #endif |
92 } | 100 } |
93 | 101 |
94 bool GLImageMemory::Initialize(const unsigned char* memory) { | 102 // static |
95 if (!ValidFormat(internalformat_)) { | 103 size_t GLImageMemory::BytesPerPixel(gfx::GpuMemoryBuffer::Format format) { |
96 DVLOG(0) << "Invalid format: " << internalformat_; | 104 switch (format) { |
| 105 case gfx::GpuMemoryBuffer::RGBA_8888: |
| 106 case gfx::GpuMemoryBuffer::BGRA_8888: |
| 107 return 4; |
| 108 case gfx::GpuMemoryBuffer::RGBX_8888: |
| 109 NOTREACHED(); |
| 110 return 0; |
| 111 } |
| 112 |
| 113 NOTREACHED(); |
| 114 return 0; |
| 115 } |
| 116 |
| 117 bool GLImageMemory::Initialize(const unsigned char* memory, |
| 118 gfx::GpuMemoryBuffer::Format format) { |
| 119 if (!ValidInternalFormat(internalformat_)) { |
| 120 LOG(ERROR) << "Invalid internalformat: " << internalformat_; |
| 121 return false; |
| 122 } |
| 123 |
| 124 if (!ValidFormat(format)) { |
| 125 LOG(ERROR) << "Invalid format: " << format; |
97 return false; | 126 return false; |
98 } | 127 } |
99 | 128 |
100 DCHECK(memory); | 129 DCHECK(memory); |
101 DCHECK(!memory_); | 130 DCHECK(!memory_); |
102 memory_ = memory; | 131 memory_ = memory; |
| 132 format_ = format; |
103 return true; | 133 return true; |
104 } | 134 } |
105 | 135 |
106 void GLImageMemory::Destroy(bool have_context) { | 136 void GLImageMemory::Destroy(bool have_context) { |
107 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 137 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
108 defined(USE_OZONE) | 138 defined(USE_OZONE) |
109 if (egl_image_ != EGL_NO_IMAGE_KHR) { | 139 if (egl_image_ != EGL_NO_IMAGE_KHR) { |
110 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_); | 140 eglDestroyImageKHR(GLSurfaceEGL::GetHardwareDisplay(), egl_image_); |
111 egl_image_ = EGL_NO_IMAGE_KHR; | 141 egl_image_ = EGL_NO_IMAGE_KHR; |
112 } | 142 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 bool GLImageMemory::CopyTexImage(unsigned target) { | 174 bool GLImageMemory::CopyTexImage(unsigned target) { |
145 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage"); | 175 TRACE_EVENT0("gpu", "GLImageMemory::CopyTexImage"); |
146 | 176 |
147 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target. | 177 // GL_TEXTURE_EXTERNAL_OES is not a supported CopyTexImage target. |
148 if (target == GL_TEXTURE_EXTERNAL_OES) | 178 if (target == GL_TEXTURE_EXTERNAL_OES) |
149 return false; | 179 return false; |
150 | 180 |
151 DCHECK(memory_); | 181 DCHECK(memory_); |
152 glTexImage2D(target, | 182 glTexImage2D(target, |
153 0, // mip level | 183 0, // mip level |
154 TextureFormat(internalformat_), | 184 TextureFormat(format_), |
155 size_.width(), | 185 size_.width(), |
156 size_.height(), | 186 size_.height(), |
157 0, // border | 187 0, // border |
158 DataFormat(internalformat_), | 188 DataFormat(format_), |
159 DataType(internalformat_), | 189 DataType(format_), |
160 memory_); | 190 memory_); |
161 | 191 |
162 return true; | 192 return true; |
163 } | 193 } |
164 | 194 |
165 void GLImageMemory::WillUseTexImage() { | 195 void GLImageMemory::WillUseTexImage() { |
166 DCHECK(!in_use_); | 196 DCHECK(!in_use_); |
167 in_use_ = true; | 197 in_use_ = true; |
168 | 198 |
169 if (!need_do_bind_tex_image_) | 199 if (!need_do_bind_tex_image_) |
170 return; | 200 return; |
171 | 201 |
172 DCHECK(target_); | 202 DCHECK(target_); |
173 DoBindTexImage(target_); | 203 DoBindTexImage(target_); |
174 } | 204 } |
175 | 205 |
176 void GLImageMemory::DidUseTexImage() { | 206 void GLImageMemory::DidUseTexImage() { |
177 DCHECK(in_use_); | 207 DCHECK(in_use_); |
178 in_use_ = false; | 208 in_use_ = false; |
179 } | 209 } |
180 | 210 |
181 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 211 bool GLImageMemory::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
182 int z_order, | 212 int z_order, |
183 OverlayTransform transform, | 213 OverlayTransform transform, |
184 const Rect& bounds_rect, | 214 const Rect& bounds_rect, |
185 const RectF& crop_rect) { | 215 const RectF& crop_rect) { |
186 return false; | 216 return false; |
187 } | 217 } |
188 | 218 |
189 bool GLImageMemory::HasValidFormat() const { | |
190 return ValidFormat(internalformat_); | |
191 } | |
192 | |
193 size_t GLImageMemory::Bytes() const { | |
194 return size_.GetArea() * BytesPerPixel(internalformat_); | |
195 } | |
196 | |
197 void GLImageMemory::DoBindTexImage(unsigned target) { | 219 void GLImageMemory::DoBindTexImage(unsigned target) { |
198 TRACE_EVENT0("gpu", "GLImageMemory::DoBindTexImage"); | 220 TRACE_EVENT0("gpu", "GLImageMemory::DoBindTexImage"); |
199 | 221 |
200 DCHECK(need_do_bind_tex_image_); | 222 DCHECK(need_do_bind_tex_image_); |
201 need_do_bind_tex_image_ = false; | 223 need_do_bind_tex_image_ = false; |
202 | 224 |
203 DCHECK(memory_); | 225 DCHECK(memory_); |
204 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ | 226 #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || \ |
205 defined(USE_OZONE) | 227 defined(USE_OZONE) |
206 if (target == GL_TEXTURE_EXTERNAL_OES) { | 228 if (target == GL_TEXTURE_EXTERNAL_OES) { |
207 if (egl_image_ == EGL_NO_IMAGE_KHR) { | 229 if (egl_image_ == EGL_NO_IMAGE_KHR) { |
208 DCHECK_EQ(0u, egl_texture_id_); | 230 DCHECK_EQ(0u, egl_texture_id_); |
209 glGenTextures(1, &egl_texture_id_); | 231 glGenTextures(1, &egl_texture_id_); |
210 | 232 |
211 { | 233 { |
212 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 234 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); |
213 | 235 |
214 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 236 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
215 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
216 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
217 glTexImage2D(GL_TEXTURE_2D, | 239 glTexImage2D(GL_TEXTURE_2D, |
218 0, // mip level | 240 0, // mip level |
219 TextureFormat(internalformat_), | 241 TextureFormat(format_), |
220 size_.width(), | 242 size_.width(), |
221 size_.height(), | 243 size_.height(), |
222 0, // border | 244 0, // border |
223 DataFormat(internalformat_), | 245 DataFormat(format_), |
224 DataType(internalformat_), | 246 DataType(format_), |
225 memory_); | 247 memory_); |
226 } | 248 } |
227 | 249 |
228 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | 250 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
229 // Need to pass current EGL rendering context to eglCreateImageKHR for | 251 // Need to pass current EGL rendering context to eglCreateImageKHR for |
230 // target type EGL_GL_TEXTURE_2D_KHR. | 252 // target type EGL_GL_TEXTURE_2D_KHR. |
231 egl_image_ = | 253 egl_image_ = |
232 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), | 254 eglCreateImageKHR(GLSurfaceEGL::GetHardwareDisplay(), |
233 eglGetCurrentContext(), | 255 eglGetCurrentContext(), |
234 EGL_GL_TEXTURE_2D_KHR, | 256 EGL_GL_TEXTURE_2D_KHR, |
235 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), | 257 reinterpret_cast<EGLClientBuffer>(egl_texture_id_), |
236 attrs); | 258 attrs); |
237 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) | 259 DCHECK_NE(EGL_NO_IMAGE_KHR, egl_image_) |
238 << "Error creating EGLImage: " << eglGetError(); | 260 << "Error creating EGLImage: " << eglGetError(); |
239 } else { | 261 } else { |
240 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); | 262 ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); |
241 | 263 |
242 glTexSubImage2D(GL_TEXTURE_2D, | 264 glTexSubImage2D(GL_TEXTURE_2D, |
243 0, // mip level | 265 0, // mip level |
244 0, // x-offset | 266 0, // x-offset |
245 0, // y-offset | 267 0, // y-offset |
246 size_.width(), | 268 size_.width(), |
247 size_.height(), | 269 size_.height(), |
248 DataFormat(internalformat_), | 270 DataFormat(format_), |
249 DataType(internalformat_), | 271 DataType(format_), |
250 memory_); | 272 memory_); |
251 } | 273 } |
252 | 274 |
253 glEGLImageTargetTexture2DOES(target, egl_image_); | 275 glEGLImageTargetTexture2DOES(target, egl_image_); |
254 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | 276 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); |
255 return; | 277 return; |
256 } | 278 } |
257 #endif | 279 #endif |
258 | 280 |
259 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); | 281 DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); |
260 glTexImage2D(target, | 282 glTexImage2D(target, |
261 0, // mip level | 283 0, // mip level |
262 TextureFormat(internalformat_), | 284 TextureFormat(format_), |
263 size_.width(), | 285 size_.width(), |
264 size_.height(), | 286 size_.height(), |
265 0, // border | 287 0, // border |
266 DataFormat(internalformat_), | 288 DataFormat(format_), |
267 DataType(internalformat_), | 289 DataType(format_), |
268 memory_); | 290 memory_); |
269 } | 291 } |
270 | 292 |
271 } // namespace gfx | 293 } // namespace gfx |
OLD | NEW |