Chromium Code Reviews| 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" | 9 #include "base/callback_helpers.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/mac/bind_objc_block.h" | 11 #include "base/mac/bind_objc_block.h" |
| 12 #include "base/mac/foundation_util.h" | 12 #include "base/mac/foundation_util.h" |
| 13 #include "base/strings/stringize_macros.h" | 13 #include "base/strings/stringize_macros.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "base/trace_event/memory_allocator_dump.h" | 15 #include "base/trace_event/memory_allocator_dump.h" |
| 16 #include "base/trace_event/memory_dump_manager.h" | 16 #include "base/trace_event/memory_dump_manager.h" |
| 17 #include "base/trace_event/process_memory_dump.h" | 17 #include "base/trace_event/process_memory_dump.h" |
| 18 #include "ui/gl/gl_bindings.h" | 18 #include "ui/gl/gl_bindings.h" |
| 19 #include "ui/gl/gl_context.h" | 19 #include "ui/gl/gl_context.h" |
| 20 #include "ui/gl/gl_helper.h" | 20 #include "ui/gl/gl_helper.h" |
| 21 #include "ui/gl/scoped_api.h" | |
| 21 #include "ui/gl/scoped_binders.h" | 22 #include "ui/gl/scoped_binders.h" |
| 23 #include "ui/gl/scoped_cgl.h" | |
| 22 | 24 |
| 23 // Note that this must be included after gl_bindings.h to avoid conflicts. | 25 // Note that this must be included after gl_bindings.h to avoid conflicts. |
| 24 #include <OpenGL/CGLIOSurface.h> | 26 #include <OpenGL/CGLIOSurface.h> |
| 25 #include <Quartz/Quartz.h> | 27 #include <Quartz/Quartz.h> |
| 26 #include <stddef.h> | 28 #include <stddef.h> |
| 27 | 29 |
| 28 using gfx::BufferFormat; | 30 using gfx::BufferFormat; |
| 29 | 31 |
| 30 namespace gl { | 32 namespace gl { |
| 31 namespace { | 33 namespace { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 NOTREACHED(); | 183 NOTREACHED(); |
| 182 return 0; | 184 return 0; |
| 183 } | 185 } |
| 184 | 186 |
| 185 NOTREACHED(); | 187 NOTREACHED(); |
| 186 return 0; | 188 return 0; |
| 187 } | 189 } |
| 188 | 190 |
| 189 } // namespace | 191 } // namespace |
| 190 | 192 |
| 193 class GLImageIOSurface::RGBConverter | |
| 194 : public base::RefCounted<GLImageIOSurface::RGBConverter> { | |
| 195 public: | |
| 196 static scoped_refptr<RGBConverter> GetForCurrentContext(); | |
| 197 bool CopyTexImage(IOSurfaceRef io_surface, const gfx::Size& size); | |
| 198 | |
| 199 private: | |
| 200 friend class base::RefCounted<RGBConverter>; | |
| 201 RGBConverter(CGLContextObj cgl_context); | |
| 202 ~RGBConverter(); | |
| 203 | |
| 204 unsigned vertex_shader_ = 0; | |
| 205 unsigned fragment_shader_ = 0; | |
| 206 unsigned program_ = 0; | |
| 207 int size_location_ = -1; | |
| 208 unsigned vertex_buffer_ = 0; | |
| 209 base::ScopedTypeRef<CGLContextObj> cgl_context_; | |
| 210 | |
| 211 static base::LazyInstance< | |
| 212 std::map<CGLContextObj, GLImageIOSurface::RGBConverter*>> | |
| 213 g_rgb_converters; | |
| 214 }; | |
| 215 | |
| 216 base::LazyInstance<std::map<CGLContextObj, GLImageIOSurface::RGBConverter*>> | |
| 217 GLImageIOSurface::RGBConverter::g_rgb_converters; | |
| 218 | |
| 219 scoped_refptr<GLImageIOSurface::RGBConverter> | |
| 220 GLImageIOSurface::RGBConverter::GetForCurrentContext() { | |
| 221 CGLContextObj current_context = CGLGetCurrentContext(); | |
|
Daniele Castagna
2016/04/11 19:55:30
Should we DCHECK that current_context is not null?
ccameron
2016/04/11 20:41:21
Good idea -- added.
| |
| 222 auto found = g_rgb_converters.Get().find(current_context); | |
|
Daniele Castagna
2016/04/11 19:55:29
Is it possible that we get GLImageIOSurface::BindT
ccameron
2016/04/11 20:41:21
Yes -- the GLImageIOSurface::thread_checker_ shoul
Daniele Castagna
2016/04/11 20:56:16
That checks that all the calls to an instance of G
ccameron
2016/04/12 00:34:34
My understanding is that there is only one valid t
| |
| 223 if (found != g_rgb_converters.Get().end()) | |
| 224 return make_scoped_refptr(found->second); | |
| 225 return make_scoped_refptr(new RGBConverter(current_context)); | |
| 226 } | |
| 227 | |
| 228 GLImageIOSurface::RGBConverter::RGBConverter(CGLContextObj cgl_context) | |
| 229 : cgl_context_(cgl_context, base::scoped_policy::RETAIN) { | |
| 230 gfx::ScopedSetGLToRealGLApi scoped_set_gl_api; | |
| 231 vertex_buffer_ = gfx::GLHelper::SetupQuadVertexBuffer(); | |
| 232 vertex_shader_ = gfx::GLHelper::LoadShader( | |
| 233 GL_VERTEX_SHADER, | |
| 234 base::StringPrintf("%s\n%s", kGLSLVersion, kVertexShader).c_str()); | |
| 235 fragment_shader_ = gfx::GLHelper::LoadShader( | |
| 236 GL_FRAGMENT_SHADER, | |
| 237 base::StringPrintf("%s\n%s\n%s", kGLSLVersion, kTextureRectangleRequired, | |
| 238 kFragmentShader) | |
| 239 .c_str()); | |
| 240 program_ = gfx::GLHelper::SetupProgram(vertex_shader_, fragment_shader_); | |
| 241 | |
| 242 gfx::ScopedUseProgram use_program(program_); | |
| 243 size_location_ = glGetUniformLocation(program_, "a_texScale"); | |
| 244 DCHECK_NE(-1, size_location_); | |
| 245 int y_sampler_location = glGetUniformLocation(program_, "a_y_texture"); | |
| 246 DCHECK_NE(-1, y_sampler_location); | |
| 247 int uv_sampler_location = glGetUniformLocation(program_, "a_uv_texture"); | |
| 248 DCHECK_NE(-1, uv_sampler_location); | |
| 249 | |
| 250 glUniform1i(y_sampler_location, 0); | |
| 251 glUniform1i(uv_sampler_location, 1); | |
| 252 | |
| 253 DCHECK(g_rgb_converters.Get().find(cgl_context) == | |
| 254 g_rgb_converters.Get().end()); | |
| 255 g_rgb_converters.Get()[cgl_context] = this; | |
| 256 } | |
| 257 | |
| 258 GLImageIOSurface::RGBConverter::~RGBConverter() { | |
| 259 DCHECK(g_rgb_converters.Get()[cgl_context_] == this); | |
| 260 g_rgb_converters.Get().erase(cgl_context_.get()); | |
| 261 { | |
| 262 gfx::ScopedCGLSetCurrentContext(cgl_context_.get()); | |
| 263 gfx::ScopedSetGLToRealGLApi scoped_set_gl_api; | |
| 264 glDeleteProgram(program_); | |
| 265 glDeleteShader(vertex_shader_); | |
| 266 glDeleteShader(fragment_shader_); | |
| 267 glDeleteBuffersARB(1, &vertex_buffer_); | |
| 268 } | |
| 269 cgl_context_.reset(); | |
| 270 } | |
| 271 | |
| 272 bool GLImageIOSurface::RGBConverter::CopyTexImage(IOSurfaceRef io_surface, | |
| 273 const gfx::Size& size) { | |
| 274 gfx::ScopedSetGLToRealGLApi scoped_set_gl_api; | |
| 275 DCHECK_EQ(CGLGetCurrentContext(), cgl_context_.get()); | |
| 276 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, size.width(), size.height(), | |
| 277 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); | |
| 278 GLint target_texture = 0; | |
| 279 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &target_texture); | |
| 280 DCHECK(target_texture); | |
| 281 | |
| 282 GLint old_active_texture = -1; | |
|
Daniele Castagna
2016/04/11 19:55:29
It'd be nice to solve the Scoped* issue before lan
ccameron
2016/04/11 20:41:21
Added a comment for this.
| |
| 283 glGetIntegerv(GL_ACTIVE_TEXTURE, &old_active_texture); | |
| 284 GLint old_texture0_binding = -1; | |
| 285 glActiveTexture(GL_TEXTURE0); | |
| 286 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_texture0_binding); | |
| 287 GLint old_texture1_binding = -1; | |
| 288 glActiveTexture(GL_TEXTURE1); | |
| 289 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_texture1_binding); | |
| 290 | |
| 291 unsigned y_texture = 0; | |
| 292 glGenTextures(1, &y_texture); | |
| 293 unsigned uv_texture = 0; | |
| 294 glGenTextures(1, &uv_texture); | |
| 295 unsigned framebuffer = 0; | |
| 296 glGenFramebuffersEXT(1, &framebuffer); | |
|
Daniele Castagna
2016/04/11 19:55:29
Why did you decide not to put framebuffer in the R
ccameron
2016/04/11 20:41:21
No reason -- updated the patch to leave it in the
| |
| 297 | |
| 298 base::ScopedClosureRunner destroy_resources_runner(base::BindBlock(^{ | |
| 299 glActiveTexture(GL_TEXTURE0); | |
| 300 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, old_texture0_binding); | |
| 301 glActiveTexture(GL_TEXTURE1); | |
| 302 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, old_texture1_binding); | |
| 303 glActiveTexture(old_active_texture); | |
| 304 | |
| 305 glDeleteTextures(1, &y_texture); | |
| 306 glDeleteTextures(1, &uv_texture); | |
| 307 glDeleteFramebuffersEXT(1, &framebuffer); | |
| 308 })); | |
| 309 | |
| 310 CGLError cgl_error = kCGLNoError; | |
| 311 glActiveTexture(GL_TEXTURE0); | |
| 312 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, y_texture); | |
| 313 cgl_error = CGLTexImageIOSurface2D(cgl_context_, GL_TEXTURE_RECTANGLE_ARB, | |
| 314 GL_RED, size.width(), size.height(), | |
| 315 GL_RED, GL_UNSIGNED_BYTE, io_surface, 0); | |
| 316 if (cgl_error != kCGLNoError) { | |
| 317 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the Y plane. " | |
| 318 << cgl_error; | |
| 319 return false; | |
| 320 } | |
| 321 glActiveTexture(GL_TEXTURE1); | |
| 322 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, uv_texture); | |
| 323 cgl_error = CGLTexImageIOSurface2D(cgl_context_, GL_TEXTURE_RECTANGLE_ARB, | |
| 324 GL_RG, size.width() / 2, size.height() / 2, | |
| 325 GL_RG, GL_UNSIGNED_BYTE, io_surface, 1); | |
| 326 if (cgl_error != kCGLNoError) { | |
| 327 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the UV plane. " | |
| 328 << cgl_error; | |
| 329 return false; | |
| 330 } | |
| 331 | |
| 332 gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer); | |
| 333 gfx::ScopedViewport viewport(0, 0, size.width(), size.height()); | |
| 334 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
| 335 GL_TEXTURE_RECTANGLE_ARB, target_texture, 0); | |
| 336 DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), | |
| 337 glCheckFramebufferStatusEXT(GL_FRAMEBUFFER)); | |
| 338 gfx::ScopedUseProgram use_program(program_); | |
| 339 glUniform2f(size_location_, size.width(), size.height()); | |
| 340 gfx::GLHelper::DrawQuad(vertex_buffer_); | |
| 341 return true; | |
| 342 } | |
| 343 | |
| 191 GLImageIOSurface::GLImageIOSurface(const gfx::Size& size, | 344 GLImageIOSurface::GLImageIOSurface(const gfx::Size& size, |
| 192 unsigned internalformat) | 345 unsigned internalformat) |
| 193 : size_(size), | 346 : size_(size), |
| 194 internalformat_(internalformat), | 347 internalformat_(internalformat), |
| 195 format_(BufferFormat::RGBA_8888) {} | 348 format_(BufferFormat::RGBA_8888) {} |
| 196 | 349 |
| 197 GLImageIOSurface::~GLImageIOSurface() { | 350 GLImageIOSurface::~GLImageIOSurface() { |
| 198 DCHECK(thread_checker_.CalledOnValidThread()); | 351 DCHECK(thread_checker_.CalledOnValidThread()); |
| 199 DCHECK(!io_surface_); | 352 DCHECK(!io_surface_); |
| 200 } | 353 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 231 return false; | 384 return false; |
| 232 } | 385 } |
| 233 | 386 |
| 234 if (!Initialize(io_surface, io_surface_id, format)) | 387 if (!Initialize(io_surface, io_surface_id, format)) |
| 235 return false; | 388 return false; |
| 236 | 389 |
| 237 cv_pixel_buffer_.reset(cv_pixel_buffer, base::scoped_policy::RETAIN); | 390 cv_pixel_buffer_.reset(cv_pixel_buffer, base::scoped_policy::RETAIN); |
| 238 return true; | 391 return true; |
| 239 } | 392 } |
| 240 | 393 |
| 241 void GLImageIOSurface::Destroy(bool have_context) { | 394 void GLImageIOSurface::Destroy(bool have_context) { |
|
Daniele Castagna
2016/04/11 20:56:16
Why was have_context always false in the HW decode
ccameron
2016/04/12 00:34:34
The HW decoder will free the GLImage at unpredicta
| |
| 242 DCHECK(thread_checker_.CalledOnValidThread()); | 395 DCHECK(thread_checker_.CalledOnValidThread()); |
| 243 if (have_context && framebuffer_) { | |
| 244 glDeleteProgram(program_); | |
| 245 glDeleteShader(vertex_shader_); | |
| 246 glDeleteShader(fragment_shader_); | |
| 247 glDeleteBuffersARB(1, &vertex_buffer_); | |
| 248 glDeleteFramebuffersEXT(1, &framebuffer_); | |
| 249 } | |
| 250 io_surface_.reset(); | 396 io_surface_.reset(); |
| 251 cv_pixel_buffer_.reset(); | 397 cv_pixel_buffer_.reset(); |
| 252 } | 398 } |
| 253 | 399 |
| 254 gfx::Size GLImageIOSurface::GetSize() { | 400 gfx::Size GLImageIOSurface::GetSize() { |
| 255 return size_; | 401 return size_; |
| 256 } | 402 } |
| 257 | 403 |
| 258 unsigned GLImageIOSurface::GetInternalFormat() { | 404 unsigned GLImageIOSurface::GetInternalFormat() { |
| 259 return internalformat_; | 405 return internalformat_; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 294 bool GLImageIOSurface::CopyTexImage(unsigned target) { | 440 bool GLImageIOSurface::CopyTexImage(unsigned target) { |
| 295 DCHECK(thread_checker_.CalledOnValidThread()); | 441 DCHECK(thread_checker_.CalledOnValidThread()); |
| 296 | 442 |
| 297 if (format_ != BufferFormat::YUV_420_BIPLANAR) | 443 if (format_ != BufferFormat::YUV_420_BIPLANAR) |
| 298 return false; | 444 return false; |
| 299 if (target != GL_TEXTURE_RECTANGLE_ARB) { | 445 if (target != GL_TEXTURE_RECTANGLE_ARB) { |
| 300 LOG(ERROR) << "YUV_420_BIPLANAR requires GL_TEXTURE_RECTANGLE_ARB target"; | 446 LOG(ERROR) << "YUV_420_BIPLANAR requires GL_TEXTURE_RECTANGLE_ARB target"; |
| 301 return false; | 447 return false; |
| 302 } | 448 } |
| 303 | 449 |
| 304 // Ensure that all textures bound to IOSurfaces be destroyed before the | 450 rgb_converter_ = RGBConverter::GetForCurrentContext(); |
| 305 // function exits. If they are not destroyed they may cause deadlocks between | 451 return rgb_converter_->CopyTexImage(io_surface_.get(), size_); |
| 306 // VTDecompressionSession at CGLContextDestroy. | |
| 307 // https://crbug.com/598388 | |
| 308 unsigned y_texture = 0; | |
| 309 glGenTextures(1, &y_texture); | |
| 310 unsigned uv_texture = 0; | |
| 311 glGenTextures(1, &uv_texture); | |
| 312 base::ScopedClosureRunner destroy_resources_runner(base::BindBlock(^{ | |
| 313 glDeleteTextures(1, &y_texture); | |
| 314 glDeleteTextures(1, &uv_texture); | |
| 315 })); | |
| 316 | |
| 317 if (!framebuffer_) { | |
| 318 glGenFramebuffersEXT(1, &framebuffer_); | |
| 319 vertex_buffer_ = gfx::GLHelper::SetupQuadVertexBuffer(); | |
| 320 vertex_shader_ = gfx::GLHelper::LoadShader( | |
| 321 GL_VERTEX_SHADER, | |
| 322 base::StringPrintf("%s\n%s", kGLSLVersion, kVertexShader).c_str()); | |
| 323 fragment_shader_ = gfx::GLHelper::LoadShader( | |
| 324 GL_FRAGMENT_SHADER, | |
| 325 base::StringPrintf("%s\n%s\n%s", kGLSLVersion, | |
| 326 kTextureRectangleRequired, kFragmentShader) | |
| 327 .c_str()); | |
| 328 program_ = gfx::GLHelper::SetupProgram(vertex_shader_, fragment_shader_); | |
| 329 gfx::ScopedUseProgram use_program(program_); | |
| 330 | |
| 331 size_location_ = glGetUniformLocation(program_, "a_texScale"); | |
| 332 DCHECK_NE(-1, size_location_); | |
| 333 int y_sampler_location = glGetUniformLocation(program_, "a_y_texture"); | |
| 334 DCHECK_NE(-1, y_sampler_location); | |
| 335 int uv_sampler_location = glGetUniformLocation(program_, "a_uv_texture"); | |
| 336 DCHECK_NE(-1, uv_sampler_location); | |
| 337 | |
| 338 glUniform1i(y_sampler_location, 0); | |
| 339 glUniform1i(uv_sampler_location, 1); | |
| 340 } | |
| 341 | |
| 342 CGLContextObj cgl_context = | |
| 343 static_cast<CGLContextObj>(gfx::GLContext::GetCurrent()->GetHandle()); | |
| 344 | |
| 345 GLint target_texture = 0; | |
| 346 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &target_texture); | |
| 347 DCHECK(target_texture); | |
| 348 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, size_.width(), | |
| 349 size_.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); | |
| 350 | |
| 351 CGLError cgl_error = kCGLNoError; | |
| 352 { | |
| 353 DCHECK(io_surface_); | |
| 354 | |
| 355 gfx::ScopedActiveTexture active_texture0(GL_TEXTURE0); | |
| 356 gfx::ScopedTextureBinder texture_y_binder(GL_TEXTURE_RECTANGLE_ARB, | |
| 357 y_texture); | |
| 358 cgl_error = CGLTexImageIOSurface2D( | |
| 359 cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RED, size_.width(), | |
| 360 size_.height(), GL_RED, GL_UNSIGNED_BYTE, io_surface_.get(), 0); | |
| 361 if (cgl_error != kCGLNoError) { | |
| 362 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the Y plane. " | |
| 363 << cgl_error; | |
| 364 return false; | |
| 365 } | |
| 366 { | |
| 367 gfx::ScopedActiveTexture active_texture1(GL_TEXTURE1); | |
| 368 gfx::ScopedTextureBinder texture_uv_binder(GL_TEXTURE_RECTANGLE_ARB, | |
| 369 uv_texture); | |
| 370 cgl_error = CGLTexImageIOSurface2D( | |
| 371 cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RG, size_.width() / 2, | |
| 372 size_.height() / 2, GL_RG, GL_UNSIGNED_BYTE, io_surface_.get(), 1); | |
| 373 if (cgl_error != kCGLNoError) { | |
| 374 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the UV plane. " | |
| 375 << cgl_error; | |
| 376 return false; | |
| 377 } | |
| 378 | |
| 379 gfx::ScopedFrameBufferBinder framebuffer_binder(framebuffer_); | |
| 380 gfx::ScopedViewport viewport(0, 0, size_.width(), size_.height()); | |
| 381 glViewport(0, 0, size_.width(), size_.height()); | |
| 382 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
| 383 GL_TEXTURE_RECTANGLE_ARB, target_texture, 0); | |
| 384 DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), | |
| 385 glCheckFramebufferStatusEXT(GL_FRAMEBUFFER)); | |
| 386 | |
| 387 gfx::ScopedUseProgram use_program(program_); | |
| 388 glUniform2f(size_location_, size_.width(), size_.height()); | |
| 389 | |
| 390 gfx::GLHelper::DrawQuad(vertex_buffer_); | |
| 391 // Detach the output texture from the fbo. | |
| 392 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
| 393 GL_TEXTURE_RECTANGLE_ARB, 0, 0); | |
| 394 } | |
| 395 } | |
| 396 return true; | |
| 397 } | 452 } |
| 398 | 453 |
| 399 bool GLImageIOSurface::CopyTexSubImage(unsigned target, | 454 bool GLImageIOSurface::CopyTexSubImage(unsigned target, |
| 400 const gfx::Point& offset, | 455 const gfx::Point& offset, |
| 401 const gfx::Rect& rect) { | 456 const gfx::Rect& rect) { |
| 402 return false; | 457 return false; |
| 403 } | 458 } |
| 404 | 459 |
| 405 bool GLImageIOSurface::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 460 bool GLImageIOSurface::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
| 406 int z_order, | 461 int z_order, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 return cv_pixel_buffer_; | 493 return cv_pixel_buffer_; |
| 439 } | 494 } |
| 440 | 495 |
| 441 // static | 496 // static |
| 442 unsigned GLImageIOSurface::GetInternalFormatForTesting( | 497 unsigned GLImageIOSurface::GetInternalFormatForTesting( |
| 443 gfx::BufferFormat format) { | 498 gfx::BufferFormat format) { |
| 444 DCHECK(ValidFormat(format)); | 499 DCHECK(ValidFormat(format)); |
| 445 return TextureFormat(format); | 500 return TextureFormat(format); |
| 446 } | 501 } |
| 447 } // namespace gl | 502 } // namespace gl |
| OLD | NEW |