| 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/renderer/render_widget.h" | 5 #include "content/renderer/render_widget.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 #include "ui/base/ui_base_switches.h" | 55 #include "ui/base/ui_base_switches.h" |
| 56 #include "ui/gfx/point.h" | 56 #include "ui/gfx/point.h" |
| 57 #include "ui/gfx/rect_conversions.h" | 57 #include "ui/gfx/rect_conversions.h" |
| 58 #include "ui/gfx/size_conversions.h" | 58 #include "ui/gfx/size_conversions.h" |
| 59 #include "ui/gfx/skia_util.h" | 59 #include "ui/gfx/skia_util.h" |
| 60 #include "ui/gl/gl_switches.h" | 60 #include "ui/gl/gl_switches.h" |
| 61 #include "ui/surface/transport_dib.h" | 61 #include "ui/surface/transport_dib.h" |
| 62 #include "webkit/renderer/compositor_bindings/web_rendering_stats_impl.h" | 62 #include "webkit/renderer/compositor_bindings/web_rendering_stats_impl.h" |
| 63 | 63 |
| 64 #if defined(OS_ANDROID) | 64 #if defined(OS_ANDROID) |
| 65 #include "base/android/sys_utils.h" |
| 65 #include "content/renderer/android/synchronous_compositor_factory.h" | 66 #include "content/renderer/android/synchronous_compositor_factory.h" |
| 66 #endif | 67 #endif |
| 67 | 68 |
| 68 #if defined(OS_POSIX) | 69 #if defined(OS_POSIX) |
| 69 #include "ipc/ipc_channel_posix.h" | 70 #include "ipc/ipc_channel_posix.h" |
| 70 #include "third_party/skia/include/core/SkMallocPixelRef.h" | 71 #include "third_party/skia/include/core/SkMallocPixelRef.h" |
| 71 #include "third_party/skia/include/core/SkPixelRef.h" | 72 #include "third_party/skia/include/core/SkPixelRef.h" |
| 72 #endif // defined(OS_POSIX) | 73 #endif // defined(OS_POSIX) |
| 73 | 74 |
| 74 #include "third_party/WebKit/public/web/WebWidget.h" | 75 #include "third_party/WebKit/public/web/WebWidget.h" |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 return GURL(); | 637 return GURL(); |
| 637 } | 638 } |
| 638 | 639 |
| 639 bool RenderWidget::ForceCompositingModeEnabled() { | 640 bool RenderWidget::ForceCompositingModeEnabled() { |
| 640 return false; | 641 return false; |
| 641 } | 642 } |
| 642 | 643 |
| 643 scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { | 644 scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) { |
| 644 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 645 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 645 | 646 |
| 647 // If we raster too fast we become upload bound, and pending |
| 648 // uploads consume memory. For maximum upload throughput, we would |
| 649 // want to allow for upload_throughput * pipeline_time of pending |
| 650 // uploads, after which we are just wasting memory. Since we don't |
| 651 // know our upload throughput yet, this just caps our memory usage. |
| 646 #if defined(OS_ANDROID) | 652 #if defined(OS_ANDROID) |
| 647 if (SynchronousCompositorFactory* factory = | 653 size_t divider = 1; |
| 648 SynchronousCompositorFactory::GetInstance()) { | 654 if (base::android::SysUtils::IsLowEndDevice()) |
| 649 return factory->CreateOutputSurface(routing_id()); | 655 divider = 3; |
| 656 |
| 657 // For reference Nexus10 can upload 1MB in about 2.5ms. |
| 658 const size_t kMaxBytesUploadedPerMs = (2 * 1024 * 1024) / (5 * divider); |
| 659 #else |
| 660 // For reference Chromebook Pixel can upload 1MB in about 0.5ms. |
| 661 const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2; |
| 662 #endif |
| 663 |
| 664 // Assuming a two frame deep pipeline. |
| 665 const size_t kMsPerFrame = 16; |
| 666 const size_t max_transfer_buffer_usage_bytes = |
| 667 2 * kMsPerFrame * kMaxBytesUploadedPerMs; |
| 668 |
| 669 #if defined(OS_ANDROID) |
| 670 if (SynchronousCompositorFactory* factory = |
| 671 SynchronousCompositorFactory::GetInstance()) { |
| 672 return factory->CreateOutputSurface(routing_id(), |
| 673 max_transfer_buffer_usage_bytes); |
| 650 } | 674 } |
| 651 #endif | 675 #endif |
| 652 | 676 |
| 653 uint32 output_surface_id = next_output_surface_id_++; | 677 uint32 output_surface_id = next_output_surface_id_++; |
| 654 | 678 |
| 655 // Explicitly disable antialiasing for the compositor. As of the time of | 679 // Explicitly disable antialiasing for the compositor. As of the time of |
| 656 // this writing, the only platform that supported antialiasing for the | 680 // this writing, the only platform that supported antialiasing for the |
| 657 // compositor was Mac OS X, because the on-screen OpenGL context creation | 681 // compositor was Mac OS X, because the on-screen OpenGL context creation |
| 658 // code paths on Windows and Linux didn't yet have multisampling support. | 682 // code paths on Windows and Linux didn't yet have multisampling support. |
| 659 // Mac OS X essentially always behaves as though it's rendering offscreen. | 683 // Mac OS X essentially always behaves as though it's rendering offscreen. |
| 660 // Multisampling has a heavy cost especially on devices with relatively low | 684 // Multisampling has a heavy cost especially on devices with relatively low |
| 661 // fill rate like most notebooks, and the Mac implementation would need to | 685 // fill rate like most notebooks, and the Mac implementation would need to |
| 662 // be optimized to resolve directly into the IOSurface shared between the | 686 // be optimized to resolve directly into the IOSurface shared between the |
| 663 // GPU and browser processes. For these reasons and to avoid platform | 687 // GPU and browser processes. For these reasons and to avoid platform |
| 664 // disparities we explicitly disable antialiasing. | 688 // disparities we explicitly disable antialiasing. |
| 665 WebKit::WebGraphicsContext3D::Attributes attributes; | 689 WebKit::WebGraphicsContext3D::Attributes attributes; |
| 666 attributes.antialias = false; | 690 attributes.antialias = false; |
| 667 attributes.shareResources = true; | 691 attributes.shareResources = true; |
| 668 attributes.noAutomaticFlushes = true; | 692 attributes.noAutomaticFlushes = true; |
| 669 attributes.depth = false; | 693 attributes.depth = false; |
| 670 attributes.stencil = false; | 694 attributes.stencil = false; |
| 671 if (command_line.HasSwitch(cc::switches::kForceDirectLayerDrawing)) | 695 if (command_line.HasSwitch(cc::switches::kForceDirectLayerDrawing)) |
| 672 attributes.stencil = true; | 696 attributes.stencil = true; |
| 697 |
| 673 scoped_refptr<ContextProviderCommandBuffer> context_provider; | 698 scoped_refptr<ContextProviderCommandBuffer> context_provider; |
| 674 if (!fallback) { | 699 if (!fallback) { |
| 675 context_provider = ContextProviderCommandBuffer::Create( | 700 context_provider = ContextProviderCommandBuffer::Create( |
| 676 CreateGraphicsContext3D(attributes)); | 701 CreateGraphicsContext3D(attributes, max_transfer_buffer_usage_bytes)); |
| 677 } | 702 } |
| 678 | 703 |
| 679 if (!context_provider.get()) { | 704 if (!context_provider.get()) { |
| 680 if (!command_line.HasSwitch(switches::kEnableSoftwareCompositing)) | 705 if (!command_line.HasSwitch(switches::kEnableSoftwareCompositing)) |
| 681 return scoped_ptr<cc::OutputSurface>(); | 706 return scoped_ptr<cc::OutputSurface>(); |
| 682 | 707 |
| 683 scoped_ptr<cc::SoftwareOutputDevice> software_device( | 708 scoped_ptr<cc::SoftwareOutputDevice> software_device( |
| 684 new CompositorSoftwareOutputDevice()); | 709 new CompositorSoftwareOutputDevice()); |
| 685 | 710 |
| 686 return scoped_ptr<cc::OutputSurface>(new CompositorOutputSurface( | 711 return scoped_ptr<cc::OutputSurface>(new CompositorOutputSurface( |
| 687 routing_id(), | 712 routing_id(), |
| 688 output_surface_id, | 713 output_surface_id, |
| 689 NULL, | 714 NULL, |
| 690 software_device.Pass(), | 715 software_device.Pass(), |
| 691 true)); | 716 true, |
| 717 max_transfer_buffer_usage_bytes)); |
| 692 } | 718 } |
| 693 | 719 |
| 694 if (command_line.HasSwitch(switches::kEnableDelegatedRenderer) && | 720 if (command_line.HasSwitch(switches::kEnableDelegatedRenderer) && |
| 695 !command_line.HasSwitch(switches::kDisableDelegatedRenderer)) { | 721 !command_line.HasSwitch(switches::kDisableDelegatedRenderer)) { |
| 696 DCHECK(is_threaded_compositing_enabled_); | 722 DCHECK(is_threaded_compositing_enabled_); |
| 697 return scoped_ptr<cc::OutputSurface>( | 723 return scoped_ptr<cc::OutputSurface>( |
| 698 new DelegatedCompositorOutputSurface( | 724 new DelegatedCompositorOutputSurface( |
| 699 routing_id(), | 725 routing_id(), |
| 700 output_surface_id, | 726 output_surface_id, |
| 701 context_provider, | 727 context_provider, |
| 702 scoped_ptr<cc::SoftwareOutputDevice>())); | 728 scoped_ptr<cc::SoftwareOutputDevice>(), |
| 729 max_transfer_buffer_usage_bytes)); |
| 703 } | 730 } |
| 704 if (command_line.HasSwitch(cc::switches::kCompositeToMailbox)) { | 731 if (command_line.HasSwitch(cc::switches::kCompositeToMailbox)) { |
| 705 DCHECK(is_threaded_compositing_enabled_); | 732 DCHECK(is_threaded_compositing_enabled_); |
| 706 return scoped_ptr<cc::OutputSurface>( | 733 return scoped_ptr<cc::OutputSurface>( |
| 707 new MailboxOutputSurface( | 734 new MailboxOutputSurface( |
| 708 routing_id(), | 735 routing_id(), |
| 709 output_surface_id, | 736 output_surface_id, |
| 710 context_provider, | 737 context_provider, |
| 711 scoped_ptr<cc::SoftwareOutputDevice>())); | 738 scoped_ptr<cc::SoftwareOutputDevice>(), |
| 739 max_transfer_buffer_usage_bytes)); |
| 712 } | 740 } |
| 713 bool use_swap_compositor_frame_message = false; | 741 bool use_swap_compositor_frame_message = false; |
| 714 return scoped_ptr<cc::OutputSurface>( | 742 return scoped_ptr<cc::OutputSurface>( |
| 715 new CompositorOutputSurface( | 743 new CompositorOutputSurface( |
| 716 routing_id(), | 744 routing_id(), |
| 717 output_surface_id, | 745 output_surface_id, |
| 718 context_provider, | 746 context_provider, |
| 719 scoped_ptr<cc::SoftwareOutputDevice>(), | 747 scoped_ptr<cc::SoftwareOutputDevice>(), |
| 720 use_swap_compositor_frame_message)); | 748 use_swap_compositor_frame_message, |
| 749 max_transfer_buffer_usage_bytes)); |
| 721 } | 750 } |
| 722 | 751 |
| 723 void RenderWidget::OnViewContextSwapBuffersAborted() { | 752 void RenderWidget::OnViewContextSwapBuffersAborted() { |
| 724 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted"); | 753 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted"); |
| 725 while (!updates_pending_swap_.empty()) { | 754 while (!updates_pending_swap_.empty()) { |
| 726 ViewHostMsg_UpdateRect* msg = updates_pending_swap_.front(); | 755 ViewHostMsg_UpdateRect* msg = updates_pending_swap_.front(); |
| 727 updates_pending_swap_.pop_front(); | 756 updates_pending_swap_.pop_front(); |
| 728 // msg can be NULL if the swap doesn't correspond to an DoDeferredUpdate | 757 // msg can be NULL if the swap doesn't correspond to an DoDeferredUpdate |
| 729 // compositing pass, hence doesn't require an UpdateRect message. | 758 // compositing pass, hence doesn't require an UpdateRect message. |
| 730 if (msg) | 759 if (msg) |
| (...skipping 1788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2519 void RenderWidget::hasTouchEventHandlers(bool has_handlers) { | 2548 void RenderWidget::hasTouchEventHandlers(bool has_handlers) { |
| 2520 Send(new ViewHostMsg_HasTouchEventHandlers(routing_id_, has_handlers)); | 2549 Send(new ViewHostMsg_HasTouchEventHandlers(routing_id_, has_handlers)); |
| 2521 } | 2550 } |
| 2522 | 2551 |
| 2523 bool RenderWidget::HasTouchEventHandlersAt(const gfx::Point& point) const { | 2552 bool RenderWidget::HasTouchEventHandlersAt(const gfx::Point& point) const { |
| 2524 return true; | 2553 return true; |
| 2525 } | 2554 } |
| 2526 | 2555 |
| 2527 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> | 2556 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> |
| 2528 RenderWidget::CreateGraphicsContext3D( | 2557 RenderWidget::CreateGraphicsContext3D( |
| 2529 const WebKit::WebGraphicsContext3D::Attributes& attributes) { | 2558 const WebKit::WebGraphicsContext3D::Attributes& attributes, |
| 2559 size_t max_bytes_pending_upload) { |
| 2530 if (!webwidget_) | 2560 if (!webwidget_) |
| 2531 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); | 2561 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); |
| 2532 if (CommandLine::ForCurrentProcess()->HasSwitch( | 2562 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 2533 switches::kDisableGpuCompositing)) | 2563 switches::kDisableGpuCompositing)) |
| 2534 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); | 2564 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); |
| 2535 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( | 2565 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( |
| 2536 new WebGraphicsContext3DCommandBufferImpl( | 2566 new WebGraphicsContext3DCommandBufferImpl( |
| 2537 surface_id(), | 2567 surface_id(), |
| 2538 GetURLForGraphicsContext3D(), | 2568 GetURLForGraphicsContext3D(), |
| 2539 RenderThreadImpl::current(), | 2569 RenderThreadImpl::current(), |
| 2540 weak_ptr_factory_.GetWeakPtr())); | 2570 weak_ptr_factory_.GetWeakPtr())); |
| 2541 | 2571 |
| 2542 if (!context->InitializeWithDefaultBufferSizes( | 2572 // We keep the MappedMemoryReclaimLimit the same as the upload limit |
| 2573 // to avoid unnecessarily stalling the compositor thread. |
| 2574 const size_t kMappedMemoryReclaimLimit = max_bytes_pending_upload; |
| 2575 |
| 2576 if (!context->Initialize( |
| 2543 attributes, | 2577 attributes, |
| 2544 false /* bind generates resources */, | 2578 false /* bind generates resources */, |
| 2545 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)
) | 2579 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE, |
| 2580 kDefaultCommandBufferSize, |
| 2581 kDefaultStartTransferBufferSize, |
| 2582 kDefaultMinTransferBufferSize, |
| 2583 kDefaultMaxTransferBufferSize, |
| 2584 kMappedMemoryReclaimLimit)) |
| 2546 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); | 2585 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); |
| 2547 return context.Pass(); | 2586 return context.Pass(); |
| 2548 } | 2587 } |
| 2549 | 2588 |
| 2550 } // namespace content | 2589 } // namespace content |
| OLD | NEW |