OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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_io_surface.h" | 5 #include "ui/gl/gl_image_io_surface.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/callback_helpers.h" | |
10 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
11 #include "base/mac/bind_objc_block.h" | |
12 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
13 #include "base/strings/stringize_macros.h" | 11 #include "base/strings/stringize_macros.h" |
14 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
15 #include "base/trace_event/memory_allocator_dump.h" | 13 #include "base/trace_event/memory_allocator_dump.h" |
16 #include "base/trace_event/memory_dump_manager.h" | 14 #include "base/trace_event/memory_dump_manager.h" |
17 #include "base/trace_event/process_memory_dump.h" | 15 #include "base/trace_event/process_memory_dump.h" |
18 #include "ui/gl/gl_bindings.h" | 16 #include "ui/gl/gl_bindings.h" |
19 #include "ui/gl/gl_context.h" | 17 #include "ui/gl/gl_context.h" |
20 #include "ui/gl/gl_helper.h" | 18 #include "ui/gl/gl_helper.h" |
21 #include "ui/gl/scoped_binders.h" | 19 #include "ui/gl/scoped_binders.h" |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 } | 223 } |
226 | 224 |
227 void GLImageIOSurface::Destroy(bool have_context) { | 225 void GLImageIOSurface::Destroy(bool have_context) { |
228 DCHECK(thread_checker_.CalledOnValidThread()); | 226 DCHECK(thread_checker_.CalledOnValidThread()); |
229 if (have_context && framebuffer_) { | 227 if (have_context && framebuffer_) { |
230 glDeleteProgram(program_); | 228 glDeleteProgram(program_); |
231 glDeleteShader(vertex_shader_); | 229 glDeleteShader(vertex_shader_); |
232 glDeleteShader(fragment_shader_); | 230 glDeleteShader(fragment_shader_); |
233 glDeleteBuffersARB(1, &vertex_buffer_); | 231 glDeleteBuffersARB(1, &vertex_buffer_); |
234 glDeleteFramebuffersEXT(1, &framebuffer_); | 232 glDeleteFramebuffersEXT(1, &framebuffer_); |
| 233 glDeleteTextures(2, yuv_textures_); |
235 } | 234 } |
236 io_surface_.reset(); | 235 io_surface_.reset(); |
237 } | 236 } |
238 | 237 |
239 gfx::Size GLImageIOSurface::GetSize() { | 238 gfx::Size GLImageIOSurface::GetSize() { |
240 return size_; | 239 return size_; |
241 } | 240 } |
242 | 241 |
243 unsigned GLImageIOSurface::GetInternalFormat() { | 242 unsigned GLImageIOSurface::GetInternalFormat() { |
244 return internalformat_; | 243 return internalformat_; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 bool GLImageIOSurface::CopyTexImage(unsigned target) { | 278 bool GLImageIOSurface::CopyTexImage(unsigned target) { |
280 DCHECK(thread_checker_.CalledOnValidThread()); | 279 DCHECK(thread_checker_.CalledOnValidThread()); |
281 | 280 |
282 if (format_ != BufferFormat::YUV_420_BIPLANAR) | 281 if (format_ != BufferFormat::YUV_420_BIPLANAR) |
283 return false; | 282 return false; |
284 if (target != GL_TEXTURE_RECTANGLE_ARB) { | 283 if (target != GL_TEXTURE_RECTANGLE_ARB) { |
285 LOG(ERROR) << "YUV_420_BIPLANAR requires GL_TEXTURE_RECTANGLE_ARB target"; | 284 LOG(ERROR) << "YUV_420_BIPLANAR requires GL_TEXTURE_RECTANGLE_ARB target"; |
286 return false; | 285 return false; |
287 } | 286 } |
288 | 287 |
289 // Ensure that all textures bound to IOSurfaces be destroyed before the | |
290 // function exits. If they are not destroyed they may cause deadlocks between | |
291 // VTDecompressionSession at CGLContextDestroy. | |
292 // https://crbug.com/598388 | |
293 unsigned y_texture = 0; | |
294 glGenTextures(1, &y_texture); | |
295 unsigned uv_texture = 0; | |
296 glGenTextures(1, &uv_texture); | |
297 base::ScopedClosureRunner destroy_resources_runner(base::BindBlock(^{ | |
298 glDeleteTextures(1, &y_texture); | |
299 glDeleteTextures(1, &uv_texture); | |
300 })); | |
301 | |
302 if (!framebuffer_) { | 288 if (!framebuffer_) { |
303 glGenFramebuffersEXT(1, &framebuffer_); | 289 glGenFramebuffersEXT(1, &framebuffer_); |
304 vertex_buffer_ = gfx::GLHelper::SetupQuadVertexBuffer(); | 290 vertex_buffer_ = gfx::GLHelper::SetupQuadVertexBuffer(); |
305 vertex_shader_ = gfx::GLHelper::LoadShader( | 291 vertex_shader_ = gfx::GLHelper::LoadShader( |
306 GL_VERTEX_SHADER, | 292 GL_VERTEX_SHADER, |
307 base::StringPrintf("%s\n%s", kGLSLVersion, kVertexShader).c_str()); | 293 base::StringPrintf("%s\n%s", kGLSLVersion, kVertexShader).c_str()); |
308 fragment_shader_ = gfx::GLHelper::LoadShader( | 294 fragment_shader_ = gfx::GLHelper::LoadShader( |
309 GL_FRAGMENT_SHADER, | 295 GL_FRAGMENT_SHADER, |
310 base::StringPrintf("%s\n%s\n%s", kGLSLVersion, | 296 base::StringPrintf("%s\n%s\n%s", kGLSLVersion, |
311 kTextureRectangleRequired, kFragmentShader) | 297 kTextureRectangleRequired, kFragmentShader) |
312 .c_str()); | 298 .c_str()); |
313 program_ = gfx::GLHelper::SetupProgram(vertex_shader_, fragment_shader_); | 299 program_ = gfx::GLHelper::SetupProgram(vertex_shader_, fragment_shader_); |
314 gfx::ScopedUseProgram use_program(program_); | 300 gfx::ScopedUseProgram use_program(program_); |
315 | 301 |
316 size_location_ = glGetUniformLocation(program_, "a_texScale"); | 302 size_location_ = glGetUniformLocation(program_, "a_texScale"); |
317 DCHECK_NE(-1, size_location_); | 303 DCHECK_NE(-1, size_location_); |
318 int y_sampler_location = glGetUniformLocation(program_, "a_y_texture"); | 304 int y_sampler_location = glGetUniformLocation(program_, "a_y_texture"); |
319 DCHECK_NE(-1, y_sampler_location); | 305 DCHECK_NE(-1, y_sampler_location); |
320 int uv_sampler_location = glGetUniformLocation(program_, "a_uv_texture"); | 306 int uv_sampler_location = glGetUniformLocation(program_, "a_uv_texture"); |
321 DCHECK_NE(-1, uv_sampler_location); | 307 DCHECK_NE(-1, uv_sampler_location); |
322 | 308 |
323 glUniform1i(y_sampler_location, 0); | 309 glUniform1i(y_sampler_location, 0); |
324 glUniform1i(uv_sampler_location, 1); | 310 glUniform1i(uv_sampler_location, 1); |
| 311 |
| 312 glGenTextures(2, yuv_textures_); |
| 313 DCHECK(yuv_textures_[0]); |
| 314 DCHECK(yuv_textures_[1]); |
325 } | 315 } |
326 | 316 |
327 CGLContextObj cgl_context = | 317 CGLContextObj cgl_context = |
328 static_cast<CGLContextObj>(gfx::GLContext::GetCurrent()->GetHandle()); | 318 static_cast<CGLContextObj>(gfx::GLContext::GetCurrent()->GetHandle()); |
329 | 319 |
330 GLint target_texture = 0; | 320 GLint target_texture = 0; |
331 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &target_texture); | 321 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &target_texture); |
332 DCHECK(target_texture); | 322 DCHECK(target_texture); |
333 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, size_.width(), | 323 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, size_.width(), |
334 size_.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); | 324 size_.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); |
335 | 325 |
336 CGLError cgl_error = kCGLNoError; | 326 CGLError cgl_error = kCGLNoError; |
337 { | 327 { |
338 DCHECK(io_surface_); | 328 DCHECK(io_surface_); |
339 | 329 |
340 gfx::ScopedActiveTexture active_texture0(GL_TEXTURE0); | 330 gfx::ScopedActiveTexture active_texture0(GL_TEXTURE0); |
341 gfx::ScopedTextureBinder texture_y_binder(GL_TEXTURE_RECTANGLE_ARB, | 331 gfx::ScopedTextureBinder texture_y_binder(GL_TEXTURE_RECTANGLE_ARB, |
342 y_texture); | 332 yuv_textures_[0]); |
343 cgl_error = CGLTexImageIOSurface2D( | 333 cgl_error = CGLTexImageIOSurface2D( |
344 cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RED, size_.width(), | 334 cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RED, size_.width(), |
345 size_.height(), GL_RED, GL_UNSIGNED_BYTE, io_surface_.get(), 0); | 335 size_.height(), GL_RED, GL_UNSIGNED_BYTE, io_surface_.get(), 0); |
346 if (cgl_error != kCGLNoError) { | 336 if (cgl_error != kCGLNoError) { |
347 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the Y plane. " | 337 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the Y plane. " |
348 << cgl_error; | 338 << cgl_error; |
349 return false; | 339 return false; |
350 } | 340 } |
351 { | 341 { |
352 gfx::ScopedActiveTexture active_texture1(GL_TEXTURE1); | 342 gfx::ScopedActiveTexture active_texture1(GL_TEXTURE1); |
353 gfx::ScopedTextureBinder texture_uv_binder(GL_TEXTURE_RECTANGLE_ARB, | 343 gfx::ScopedTextureBinder texture_uv_binder(GL_TEXTURE_RECTANGLE_ARB, |
354 uv_texture); | 344 yuv_textures_[1]); |
355 cgl_error = CGLTexImageIOSurface2D( | 345 cgl_error = CGLTexImageIOSurface2D( |
356 cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RG, size_.width() / 2, | 346 cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RG, size_.width() / 2, |
357 size_.height() / 2, GL_RG, GL_UNSIGNED_BYTE, io_surface_.get(), 1); | 347 size_.height() / 2, GL_RG, GL_UNSIGNED_BYTE, io_surface_.get(), 1); |
358 if (cgl_error != kCGLNoError) { | 348 if (cgl_error != kCGLNoError) { |
359 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the UV plane. " | 349 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the UV plane. " |
360 << cgl_error; | 350 << cgl_error; |
361 return false; | 351 return false; |
362 } | 352 } |
363 | 353 |
364 gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer_); | 354 gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer_); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 g_widget_to_layer_map.Pointer()->erase(widget); | 418 g_widget_to_layer_map.Pointer()->erase(widget); |
429 } | 419 } |
430 | 420 |
431 // static | 421 // static |
432 unsigned GLImageIOSurface::GetInternalFormatForTesting( | 422 unsigned GLImageIOSurface::GetInternalFormatForTesting( |
433 gfx::BufferFormat format) { | 423 gfx::BufferFormat format) { |
434 DCHECK(ValidFormat(format)); | 424 DCHECK(ValidFormat(format)); |
435 return TextureFormat(format); | 425 return TextureFormat(format); |
436 } | 426 } |
437 } // namespace gl | 427 } // namespace gl |
OLD | NEW |