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 |