| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/common/gpu/image_transport_surface.h" | 5 #include "content/common/gpu/image_transport_surface.h" |
| 6 | 6 |
| 7 #include "base/mac/scoped_cftyperef.h" | 7 #include "base/mac/scoped_cftyperef.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "content/common/gpu/gpu_command_buffer_stub.h" | 9 #include "content/common/gpu/gpu_command_buffer_stub.h" |
| 10 #include "content/common/gpu/gpu_messages.h" | 10 #include "content/common/gpu/gpu_messages.h" |
| 11 #include "ui/gfx/native_widget_types.h" | 11 #include "ui/gfx/native_widget_types.h" |
| 12 #include "ui/gl/gl_bindings.h" | 12 #include "ui/gl/gl_bindings.h" |
| 13 #include "ui/gl/gl_context.h" | 13 #include "ui/gl/gl_context.h" |
| 14 #include "ui/gl/gl_implementation.h" | 14 #include "ui/gl/gl_implementation.h" |
| 15 #include "ui/gl/gl_surface_cgl.h" | 15 #include "ui/gl/gl_surface_cgl.h" |
| 16 #include "ui/gl/gl_surface_osmesa.h" | 16 #include "ui/gl/gl_surface_osmesa.h" |
| 17 #include "ui/gl/io_surface_support_mac.h" | 17 |
| 18 // Note that this must be included after gl_bindings.h to avoid conflicts. |
| 19 #include <OpenGL/CGLIOSurface.h> |
| 18 | 20 |
| 19 namespace content { | 21 namespace content { |
| 20 namespace { | 22 namespace { |
| 21 | 23 |
| 22 // IOSurface dimensions will be rounded up to a multiple of this value in order | 24 // IOSurface dimensions will be rounded up to a multiple of this value in order |
| 23 // to reduce memory thrashing during resize. This must be a power of 2. | 25 // to reduce memory thrashing during resize. This must be a power of 2. |
| 24 const uint32 kIOSurfaceDimensionRoundup = 64; | 26 const uint32 kIOSurfaceDimensionRoundup = 64; |
| 25 | 27 |
| 26 int RoundUpSurfaceDimension(int number) { | 28 int RoundUpSurfaceDimension(int number) { |
| 27 DCHECK(number >= 0); | 29 DCHECK(number >= 0); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 void CreateIOSurface(); | 79 void CreateIOSurface(); |
| 78 | 80 |
| 79 // Tracks the current buffer allocation state. | 81 // Tracks the current buffer allocation state. |
| 80 bool backbuffer_suggested_allocation_; | 82 bool backbuffer_suggested_allocation_; |
| 81 bool frontbuffer_suggested_allocation_; | 83 bool frontbuffer_suggested_allocation_; |
| 82 | 84 |
| 83 uint32 fbo_id_; | 85 uint32 fbo_id_; |
| 84 GLuint texture_id_; | 86 GLuint texture_id_; |
| 85 GLuint depth_stencil_renderbuffer_id_; | 87 GLuint depth_stencil_renderbuffer_id_; |
| 86 | 88 |
| 87 base::ScopedCFTypeRef<CFTypeRef> io_surface_; | 89 base::ScopedCFTypeRef<IOSurfaceRef> io_surface_; |
| 88 | 90 |
| 89 // The id of |io_surface_| or 0 if that's NULL. | 91 // The id of |io_surface_| or 0 if that's NULL. |
| 90 uint64 io_surface_handle_; | 92 uint64 io_surface_handle_; |
| 91 | 93 |
| 92 // Weak pointer to the context that this was last made current to. | 94 // Weak pointer to the context that this was last made current to. |
| 93 gfx::GLContext* context_; | 95 gfx::GLContext* context_; |
| 94 | 96 |
| 95 gfx::Size size_; | 97 gfx::Size size_; |
| 96 gfx::Size rounded_size_; | 98 gfx::Size rounded_size_; |
| 97 float scale_factor_; | 99 float scale_factor_; |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 | 378 |
| 377 GLint previous_texture_id = 0; | 379 GLint previous_texture_id = 0; |
| 378 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); | 380 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_id); |
| 379 | 381 |
| 380 // Free the old IO Surface first to reduce memory fragmentation. | 382 // Free the old IO Surface first to reduce memory fragmentation. |
| 381 UnrefIOSurface(); | 383 UnrefIOSurface(); |
| 382 | 384 |
| 383 glGenFramebuffersEXT(1, &fbo_id_); | 385 glGenFramebuffersEXT(1, &fbo_id_); |
| 384 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); | 386 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id_); |
| 385 | 387 |
| 386 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); | |
| 387 | |
| 388 glGenTextures(1, &texture_id_); | 388 glGenTextures(1, &texture_id_); |
| 389 | 389 |
| 390 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on | 390 // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on |
| 391 // Mac OS X and is required for IOSurface interoperability. | 391 // Mac OS X and is required for IOSurface interoperability. |
| 392 GLenum target = GL_TEXTURE_RECTANGLE_ARB; | 392 GLenum target = GL_TEXTURE_RECTANGLE_ARB; |
| 393 glBindTexture(target, texture_id_); | 393 glBindTexture(target, texture_id_); |
| 394 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 394 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 395 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 395 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 396 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 396 glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 397 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 397 glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 } | 434 } |
| 435 | 435 |
| 436 // Allocate a new IOSurface, which is the GPU resource that can be | 436 // Allocate a new IOSurface, which is the GPU resource that can be |
| 437 // shared across processes. | 437 // shared across processes. |
| 438 base::ScopedCFTypeRef<CFMutableDictionaryRef> properties; | 438 base::ScopedCFTypeRef<CFMutableDictionaryRef> properties; |
| 439 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, | 439 properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault, |
| 440 0, | 440 0, |
| 441 &kCFTypeDictionaryKeyCallBacks, | 441 &kCFTypeDictionaryKeyCallBacks, |
| 442 &kCFTypeDictionaryValueCallBacks)); | 442 &kCFTypeDictionaryValueCallBacks)); |
| 443 AddIntegerValue(properties, | 443 AddIntegerValue(properties, |
| 444 io_surface_support->GetKIOSurfaceWidth(), | 444 kIOSurfaceWidth, |
| 445 rounded_size_.width()); | 445 rounded_size_.width()); |
| 446 AddIntegerValue(properties, | 446 AddIntegerValue(properties, |
| 447 io_surface_support->GetKIOSurfaceHeight(), | 447 kIOSurfaceHeight, |
| 448 rounded_size_.height()); | 448 rounded_size_.height()); |
| 449 AddIntegerValue(properties, | 449 AddIntegerValue(properties, |
| 450 io_surface_support->GetKIOSurfaceBytesPerElement(), 4); | 450 kIOSurfaceBytesPerElement, 4); |
| 451 AddBooleanValue(properties, | 451 AddBooleanValue(properties, |
| 452 io_surface_support->GetKIOSurfaceIsGlobal(), true); | 452 kIOSurfaceIsGlobal, true); |
| 453 // I believe we should be able to unreference the IOSurfaces without | 453 // I believe we should be able to unreference the IOSurfaces without |
| 454 // synchronizing with the browser process because they are | 454 // synchronizing with the browser process because they are |
| 455 // ultimately reference counted by the operating system. | 455 // ultimately reference counted by the operating system. |
| 456 io_surface_.reset(io_surface_support->IOSurfaceCreate(properties)); | 456 io_surface_.reset(IOSurfaceCreate(properties)); |
| 457 io_surface_handle_ = io_surface_support->IOSurfaceGetID(io_surface_); | 457 io_surface_handle_ = IOSurfaceGetID(io_surface_); |
| 458 | 458 |
| 459 // Don't think we need to identify a plane. | 459 // Don't think we need to identify a plane. |
| 460 GLuint plane = 0; | 460 GLuint plane = 0; |
| 461 CGLError cglerror = | 461 CGLError cglerror = |
| 462 io_surface_support->CGLTexImageIOSurface2D( | 462 CGLTexImageIOSurface2D( |
| 463 static_cast<CGLContextObj>(context_->GetHandle()), | 463 static_cast<CGLContextObj>(context_->GetHandle()), |
| 464 target, | 464 target, |
| 465 GL_RGBA, | 465 GL_RGBA, |
| 466 rounded_size_.width(), | 466 rounded_size_.width(), |
| 467 rounded_size_.height(), | 467 rounded_size_.height(), |
| 468 GL_BGRA, | 468 GL_BGRA, |
| 469 GL_UNSIGNED_INT_8_8_8_8_REV, | 469 GL_UNSIGNED_INT_8_8_8_8_REV, |
| 470 io_surface_.get(), | 470 io_surface_.get(), |
| 471 plane); | 471 plane); |
| 472 if (cglerror != kCGLNoError) { | 472 if (cglerror != kCGLNoError) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 | 510 |
| 511 } // namespace | 511 } // namespace |
| 512 | 512 |
| 513 // static | 513 // static |
| 514 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface( | 514 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface( |
| 515 GpuChannelManager* manager, | 515 GpuChannelManager* manager, |
| 516 GpuCommandBufferStub* stub, | 516 GpuCommandBufferStub* stub, |
| 517 const gfx::GLSurfaceHandle& surface_handle) { | 517 const gfx::GLSurfaceHandle& surface_handle) { |
| 518 DCHECK(surface_handle.transport_type == gfx::NATIVE_DIRECT || | 518 DCHECK(surface_handle.transport_type == gfx::NATIVE_DIRECT || |
| 519 surface_handle.transport_type == gfx::NATIVE_TRANSPORT); | 519 surface_handle.transport_type == gfx::NATIVE_TRANSPORT); |
| 520 IOSurfaceSupport* io_surface_support = IOSurfaceSupport::Initialize(); | |
| 521 | 520 |
| 522 switch (gfx::GetGLImplementation()) { | 521 switch (gfx::GetGLImplementation()) { |
| 523 case gfx::kGLImplementationDesktopGL: | 522 case gfx::kGLImplementationDesktopGL: |
| 524 case gfx::kGLImplementationAppleGL: | 523 case gfx::kGLImplementationAppleGL: |
| 525 if (!io_surface_support) { | |
| 526 DLOG(WARNING) << "No IOSurface support"; | |
| 527 return scoped_refptr<gfx::GLSurface>(); | |
| 528 } | |
| 529 return scoped_refptr<gfx::GLSurface>(new IOSurfaceImageTransportSurface( | 524 return scoped_refptr<gfx::GLSurface>(new IOSurfaceImageTransportSurface( |
| 530 manager, stub, surface_handle.handle)); | 525 manager, stub, surface_handle.handle)); |
| 531 | 526 |
| 532 default: | 527 default: |
| 533 // Content shell in DRT mode spins up a gpu process which needs an | 528 // Content shell in DRT mode spins up a gpu process which needs an |
| 534 // image transport surface, but that surface isn't used to read pixel | 529 // image transport surface, but that surface isn't used to read pixel |
| 535 // baselines. So this is mostly a dummy surface. | 530 // baselines. So this is mostly a dummy surface. |
| 536 if (!g_allow_os_mesa) { | 531 if (!g_allow_os_mesa) { |
| 537 NOTREACHED(); | 532 NOTREACHED(); |
| 538 return scoped_refptr<gfx::GLSurface>(); | 533 return scoped_refptr<gfx::GLSurface>(); |
| 539 } | 534 } |
| 540 scoped_refptr<gfx::GLSurface> surface(new DRTSurfaceOSMesa()); | 535 scoped_refptr<gfx::GLSurface> surface(new DRTSurfaceOSMesa()); |
| 541 if (!surface.get() || !surface->Initialize()) | 536 if (!surface.get() || !surface->Initialize()) |
| 542 return surface; | 537 return surface; |
| 543 return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface( | 538 return scoped_refptr<gfx::GLSurface>(new PassThroughImageTransportSurface( |
| 544 manager, stub, surface.get())); | 539 manager, stub, surface.get())); |
| 545 } | 540 } |
| 546 } | 541 } |
| 547 | 542 |
| 548 // static | 543 // static |
| 549 void ImageTransportSurface::SetAllowOSMesaForTesting(bool allow) { | 544 void ImageTransportSurface::SetAllowOSMesaForTesting(bool allow) { |
| 550 g_allow_os_mesa = allow; | 545 g_allow_os_mesa = allow; |
| 551 } | 546 } |
| 552 | 547 |
| 553 } // namespace content | 548 } // namespace content |
| OLD | NEW |