Chromium Code Reviews| 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/browser/renderer_host/render_widget_host_view_mac.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" |
| 6 | 6 |
| 7 #include <QuartzCore/QuartzCore.h> | 7 #include <QuartzCore/QuartzCore.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/mac/mac_util.h" | 12 #include "base/mac/mac_util.h" |
| 13 #include "base/mac/closure_blocks_leopard_compat.h" | 13 #include "base/mac/closure_blocks_leopard_compat.h" |
| 14 #include "base/mac/scoped_cftyperef.h" | 14 #include "base/mac/scoped_cftyperef.h" |
| 15 #import "base/mac/scoped_nsautorelease_pool.h" | 15 #import "base/mac/scoped_nsautorelease_pool.h" |
| 16 #import "base/memory/scoped_nsobject.h" | 16 #import "base/memory/scoped_nsobject.h" |
| 17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
| 18 #include "base/string_util.h" | 18 #include "base/string_util.h" |
| 19 #include "base/sys_info.h" | 19 #include "base/sys_info.h" |
| 20 #include "base/sys_string_conversions.h" | 20 #include "base/sys_string_conversions.h" |
| 21 #include "base/utf_string_conversions.h" | 21 #include "base/utf_string_conversions.h" |
| 22 #import "content/browser/accessibility/browser_accessibility_cocoa.h" | 22 #import "content/browser/accessibility/browser_accessibility_cocoa.h" |
| 23 #include "content/browser/accessibility/browser_accessibility_manager.h" | 23 #include "content/browser/accessibility/browser_accessibility_manager.h" |
| 24 #include "content/browser/plugin_process_host.h" | 24 #include "content/browser/plugin_process_host.h" |
| 25 #import "content/browser/renderer_host/accelerated_plugin_view_mac.h" | 25 #import "content/browser/renderer_host/accelerated_plugin_view_mac.h" |
| 26 #include "content/browser/renderer_host/backing_store_mac.h" | 26 #include "content/browser/renderer_host/backing_store_mac.h" |
| 27 #include "content/browser/renderer_host/compositing_iosurface_mac.h" | |
| 27 #include "content/browser/renderer_host/render_process_host_impl.h" | 28 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 28 #include "content/browser/renderer_host/render_view_host_impl.h" | 29 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 29 #import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_h elper.h" | 30 #import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_h elper.h" |
| 30 #import "content/browser/renderer_host/text_input_client_mac.h" | 31 #import "content/browser/renderer_host/text_input_client_mac.h" |
| 31 #include "content/common/accessibility_messages.h" | 32 #include "content/common/accessibility_messages.h" |
| 32 #include "content/common/edit_command.h" | 33 #include "content/common/edit_command.h" |
| 33 #include "content/common/gpu/gpu_messages.h" | 34 #include "content/common/gpu/gpu_messages.h" |
| 34 #include "content/common/plugin_messages.h" | 35 #include "content/common/plugin_messages.h" |
| 35 #include "content/common/view_messages.h" | 36 #include "content/common/view_messages.h" |
| 36 #include "content/public/browser/browser_thread.h" | 37 #include "content/public/browser/browser_thread.h" |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) | 236 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
| 236 : render_widget_host_(RenderWidgetHostImpl::From(widget)), | 237 : render_widget_host_(RenderWidgetHostImpl::From(widget)), |
| 237 about_to_validate_and_paint_(false), | 238 about_to_validate_and_paint_(false), |
| 238 call_set_needs_display_in_rect_pending_(false), | 239 call_set_needs_display_in_rect_pending_(false), |
| 239 last_frame_was_accelerated_(false), | 240 last_frame_was_accelerated_(false), |
| 240 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 241 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
| 241 can_compose_inline_(true), | 242 can_compose_inline_(true), |
| 242 is_loading_(false), | 243 is_loading_(false), |
| 243 is_hidden_(false), | 244 is_hidden_(false), |
| 244 weak_factory_(this), | 245 weak_factory_(this), |
| 245 accelerated_compositing_active_(false), | |
| 246 needs_gpu_visibility_update_after_repaint_(false), | |
| 247 compositing_surface_(gfx::kNullPluginWindow) { | 246 compositing_surface_(gfx::kNullPluginWindow) { |
| 248 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| | 247 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| |
| 249 // goes away. Since we autorelease it, our caller must put | 248 // goes away. Since we autorelease it, our caller must put |
| 250 // |GetNativeView()| into the view hierarchy right after calling us. | 249 // |GetNativeView()| into the view hierarchy right after calling us. |
| 251 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 250 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
| 252 initWithRenderWidgetHostViewMac:this] autorelease]; | 251 initWithRenderWidgetHostViewMac:this] autorelease]; |
| 253 render_widget_host_->SetView(this); | 252 render_widget_host_->SetView(this); |
| 254 } | 253 } |
| 255 | 254 |
| 256 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 255 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 } | 302 } |
| 304 | 303 |
| 305 void RenderWidgetHostViewMac::DidBecomeSelected() { | 304 void RenderWidgetHostViewMac::DidBecomeSelected() { |
| 306 if (!is_hidden_) | 305 if (!is_hidden_) |
| 307 return; | 306 return; |
| 308 | 307 |
| 309 if (tab_switch_paint_time_.is_null()) | 308 if (tab_switch_paint_time_.is_null()) |
| 310 tab_switch_paint_time_ = base::TimeTicks::Now(); | 309 tab_switch_paint_time_ = base::TimeTicks::Now(); |
| 311 is_hidden_ = false; | 310 is_hidden_ = false; |
| 312 render_widget_host_->WasRestored(); | 311 render_widget_host_->WasRestored(); |
| 312 | |
| 313 // We're messing with the window, so do this to ensure no flashes. | |
| 314 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
| 313 } | 315 } |
| 314 | 316 |
| 315 void RenderWidgetHostViewMac::WasHidden() { | 317 void RenderWidgetHostViewMac::WasHidden() { |
| 316 if (is_hidden_) | 318 if (is_hidden_) |
| 317 return; | 319 return; |
| 318 | 320 |
| 319 // If we receive any more paint messages while we are hidden, we want to | 321 // If we receive any more paint messages while we are hidden, we want to |
| 320 // ignore them so we don't re-allocate the backing store. We will paint | 322 // ignore them so we don't re-allocate the backing store. We will paint |
| 321 // everything again when we become selected again. | 323 // everything again when we become selected again. |
| 322 is_hidden_ = true; | 324 is_hidden_ = true; |
| 323 | 325 |
| 326 // Send ACKs for any pending SwapBuffers (if any) since we won't be displaying | |
| 327 // them and the GPU process is waiting. | |
| 328 CompositorSwapBuffersComplete(); | |
| 329 | |
| 324 // If we have a renderer, then inform it that we are being hidden so it can | 330 // If we have a renderer, then inform it that we are being hidden so it can |
| 325 // reduce its resource utilization. | 331 // reduce its resource utilization. |
| 326 render_widget_host_->WasHidden(); | 332 render_widget_host_->WasHidden(); |
| 333 | |
| 334 // There can be a transparent flash as this view is removed and the next is | |
| 335 // added, because of OSX windowing races between displaying the contents of | |
| 336 // the NSView and its corresponding OpenGL context. | |
| 337 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding | |
| 338 // screen updates until the next tab draws. | |
| 339 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
| 327 } | 340 } |
| 328 | 341 |
| 329 void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { | 342 void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { |
| 330 gfx::Rect rect = GetViewBounds(); | 343 gfx::Rect rect = GetViewBounds(); |
| 331 rect.set_size(size); | 344 rect.set_size(size); |
| 332 SetBounds(rect); | 345 SetBounds(rect); |
| 333 } | 346 } |
| 334 | 347 |
| 335 void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { | 348 void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { |
| 336 // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, | 349 // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 586 invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect); | 599 invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect); |
| 587 } | 600 } |
| 588 } else { | 601 } else { |
| 589 [cocoa_view_ setNeedsDisplayInRect:ns_rect]; | 602 [cocoa_view_ setNeedsDisplayInRect:ns_rect]; |
| 590 } | 603 } |
| 591 } | 604 } |
| 592 | 605 |
| 593 if (!about_to_validate_and_paint_) | 606 if (!about_to_validate_and_paint_) |
| 594 [cocoa_view_ displayIfNeeded]; | 607 [cocoa_view_ displayIfNeeded]; |
| 595 } | 608 } |
| 596 | |
| 597 // If |about_to_validate_and_paint_| is set, then -drawRect: is on the stack | |
| 598 // and it's not allowed to call -setHidden on the accelerated view. In that | |
| 599 // case, -callSetNeedsDisplayInRect: will hide it later. | |
| 600 // If |about_to_validate_and_paint_| is not set, do it now. | |
| 601 if (!about_to_validate_and_paint_) | |
| 602 HandleDelayedGpuViewHiding(); | |
| 603 } | 609 } |
| 604 | 610 |
| 605 void RenderWidgetHostViewMac::RenderViewGone(base::TerminationStatus status, | 611 void RenderWidgetHostViewMac::RenderViewGone(base::TerminationStatus status, |
| 606 int error_code) { | 612 int error_code) { |
| 607 Destroy(); | 613 Destroy(); |
| 608 } | 614 } |
| 609 | 615 |
| 610 void RenderWidgetHostViewMac::Destroy() { | 616 void RenderWidgetHostViewMac::Destroy() { |
| 611 // On Windows, popups are implemented with a popup window style, so that when | 617 // On Windows, popups are implemented with a popup window style, so that when |
| 612 // an event comes in that would "cancel" it, it receives the OnCancelMode | 618 // an event comes in that would "cancel" it, it receives the OnCancelMode |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 836 | 842 |
| 837 AcceleratedPluginView* RenderWidgetHostViewMac::ViewForPluginWindowHandle( | 843 AcceleratedPluginView* RenderWidgetHostViewMac::ViewForPluginWindowHandle( |
| 838 gfx::PluginWindowHandle window) { | 844 gfx::PluginWindowHandle window) { |
| 839 PluginViewMap::iterator it = plugin_views_.find(window); | 845 PluginViewMap::iterator it = plugin_views_.find(window); |
| 840 DCHECK(plugin_views_.end() != it); | 846 DCHECK(plugin_views_.end() != it); |
| 841 if (plugin_views_.end() == it) | 847 if (plugin_views_.end() == it) |
| 842 return nil; | 848 return nil; |
| 843 return it->second; | 849 return it->second; |
| 844 } | 850 } |
| 845 | 851 |
| 846 void RenderWidgetHostViewMac::UpdatePluginGeometry( | |
| 847 gfx::PluginWindowHandle window, | |
| 848 int32 width, | |
| 849 int32 height) { | |
| 850 if (plugin_container_manager_.IsRootContainer(window)) { | |
| 851 // Fake up a WebPluginGeometry for the root window to set the | |
| 852 // container's size; we will never get a notification from the | |
| 853 // browser about the root window, only plugins. | |
| 854 webkit::npapi::WebPluginGeometry geom; | |
| 855 gfx::Rect rect(0, 0, width, height); | |
| 856 geom.window = window; | |
| 857 geom.window_rect = rect; | |
| 858 geom.clip_rect = rect; | |
| 859 geom.visible = true; | |
| 860 geom.rects_valid = true; | |
| 861 MovePluginWindows(std::vector<webkit::npapi::WebPluginGeometry>(1, geom)); | |
| 862 } | |
| 863 } | |
| 864 | |
| 865 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( | 852 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( |
| 866 gfx::PluginWindowHandle window, | 853 gfx::PluginWindowHandle window, |
| 867 int32 width, | 854 int32 width, |
| 868 int32 height, | 855 int32 height, |
| 869 uint64 io_surface_identifier) { | 856 uint64 io_surface_identifier) { |
| 870 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 857 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 871 plugin_container_manager_.SetSizeAndIOSurface(window, | 858 plugin_container_manager_.SetSizeAndIOSurface(window, |
| 872 width, | 859 width, |
| 873 height, | 860 height, |
| 874 io_surface_identifier); | 861 io_surface_identifier); |
| 875 UpdatePluginGeometry(window, width, height); | |
| 876 } | 862 } |
| 877 | 863 |
| 878 void RenderWidgetHostViewMac::AcceleratedSurfaceSetTransportDIB( | 864 void RenderWidgetHostViewMac::AcceleratedSurfaceSetTransportDIB( |
| 879 gfx::PluginWindowHandle window, | 865 gfx::PluginWindowHandle window, |
| 880 int32 width, | 866 int32 width, |
| 881 int32 height, | 867 int32 height, |
| 882 TransportDIB::Handle transport_dib) { | 868 TransportDIB::Handle transport_dib) { |
| 883 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 869 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 884 plugin_container_manager_.SetSizeAndTransportDIB(window, | 870 plugin_container_manager_.SetSizeAndTransportDIB(window, |
| 885 width, | 871 width, |
| 886 height, | 872 height, |
| 887 transport_dib); | 873 transport_dib); |
| 888 UpdatePluginGeometry(window, width, height); | 874 } |
| 875 | |
| 876 void RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, | |
| 877 int32 route_id, | |
| 878 int32 gpu_host_id) { | |
| 879 pending_swap_buffers_acks_.push_back(std::make_pair(route_id, gpu_host_id)); | |
| 880 if (!compositing_iosurface_.get() && !is_hidden_) { | |
| 881 [cocoa_view_ addedGLContext]; | |
| 882 compositing_iosurface_.reset(CompositingIOSurfaceMac::Create()); | |
| 883 } | |
| 884 | |
| 885 if (compositing_iosurface_.get() && !is_hidden_) { | |
| 886 last_frame_was_accelerated_ = true; | |
| 887 compositing_iosurface_->SetIOSurface(surface_handle); | |
| 888 [cocoa_view_ setNeedsDisplay:YES]; | |
| 889 } else { | |
| 890 CompositorSwapBuffersComplete(); | |
| 891 } | |
| 892 } | |
| 893 | |
| 894 void RenderWidgetHostViewMac::CompositorSwapBuffersComplete() { | |
| 895 TRACE_EVENT0("browser", | |
| 896 "RenderWidgetHostViewMac::CompositorSwapBuffersComplete"); | |
| 897 while (!pending_swap_buffers_acks_.empty()) { | |
| 898 if (pending_swap_buffers_acks_.front().first != 0) { | |
| 899 RenderWidgetHostImpl::AcknowledgeSwapBuffers( | |
| 900 pending_swap_buffers_acks_.front().first, | |
| 901 pending_swap_buffers_acks_.front().second); | |
| 902 } | |
| 903 pending_swap_buffers_acks_.erase(pending_swap_buffers_acks_.begin()); | |
| 904 } | |
| 889 } | 905 } |
| 890 | 906 |
| 891 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 907 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
| 892 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, | 908 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, |
| 893 int gpu_host_id) { | 909 int gpu_host_id) { |
| 894 TRACE_EVENT0("browser", | 910 TRACE_EVENT0("browser", |
| 895 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); | 911 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); |
| 896 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 912 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 897 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); | |
| 898 DCHECK(view); | |
| 899 if (view) { | |
| 900 last_frame_was_accelerated_ = (params.window == | |
| 901 plugin_container_manager_.root_container_handle()); | |
| 902 plugin_container_manager_.SetSurfaceWasPaintedTo(params.window, | |
| 903 params.surface_handle); | |
| 904 | 913 |
| 905 // The surface is hidden until its first paint, to not show garbage. | 914 if (params.window == compositing_surface_) { |
| 906 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) | 915 CompositorSwapBuffers(params.surface_handle, params.route_id, gpu_host_id); |
| 907 [view setHidden:NO]; | 916 } else { |
| 908 [view drawView]; | 917 // Deprecated accelerated plugin code path. |
| 909 } | 918 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); |
| 919 DCHECK(view); | |
| 920 if (view) { | |
| 921 plugin_container_manager_.SetSurfaceWasPaintedTo(params.window, | |
| 922 params.surface_handle); | |
| 910 | 923 |
| 911 if (params.route_id != 0) { | 924 // The surface is hidden until its first paint, to not show garbage. |
| 912 RenderWidgetHostImpl::AcknowledgeSwapBuffers(params.route_id, gpu_host_id); | 925 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) |
| 926 [view setHidden:NO]; | |
| 927 [view drawView]; | |
| 928 } | |
| 929 | |
| 930 if (params.route_id != 0) { | |
| 931 RenderWidgetHostImpl::AcknowledgeSwapBuffers(params.route_id, | |
| 932 gpu_host_id); | |
| 933 } | |
| 913 } | 934 } |
| 914 } | 935 } |
| 915 | 936 |
| 916 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( | 937 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
| 917 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, | 938 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
| 918 int gpu_host_id) { | 939 int gpu_host_id) { |
| 919 TRACE_EVENT0("browser", | 940 TRACE_EVENT0("browser", |
| 920 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); | 941 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); |
| 921 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 942 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 922 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); | |
| 923 DCHECK(view); | |
| 924 if (view) { | |
| 925 last_frame_was_accelerated_ = (params.window == | |
| 926 plugin_container_manager_.root_container_handle()); | |
| 927 plugin_container_manager_.SetSurfaceWasPaintedTo( | |
| 928 params.window, | |
| 929 params.surface_handle, | |
| 930 gfx::Rect(params.x, params.y, params.width, params.height)); | |
| 931 | 943 |
| 932 // The surface is hidden until its first paint, to not show garbage. | 944 if (params.window == compositing_surface_) { |
| 933 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) | 945 CompositorSwapBuffers(params.surface_handle, params.route_id, gpu_host_id); |
| 934 [view setHidden:NO]; | 946 } else { |
| 935 [view drawView]; | 947 // Deprecated accelerated plugin code path. |
| 936 } | 948 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); |
| 949 DCHECK(view); | |
| 950 if (view) { | |
| 951 plugin_container_manager_.SetSurfaceWasPaintedTo( | |
| 952 params.window, | |
| 953 params.surface_handle, | |
| 954 gfx::Rect(params.x, params.y, params.width, params.height)); | |
| 937 | 955 |
| 938 if (params.route_id != 0) { | 956 // The surface is hidden until its first paint, to not show garbage. |
| 939 RenderWidgetHostImpl::AcknowledgePostSubBuffer( | 957 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) |
| 940 params.route_id, gpu_host_id); | 958 [view setHidden:NO]; |
| 959 [view drawView]; | |
| 960 } | |
| 961 | |
| 962 if (params.route_id != 0) { | |
| 963 RenderWidgetHostImpl::AcknowledgePostSubBuffer( | |
| 964 params.route_id, gpu_host_id); | |
| 965 } | |
| 941 } | 966 } |
| 942 } | 967 } |
| 943 | 968 |
| 944 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { | 969 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
| 945 } | 970 } |
| 946 | 971 |
| 947 void RenderWidgetHostViewMac::UpdateRootGpuViewVisibility( | |
| 948 bool show_gpu_widget) { | |
| 949 TRACE_EVENT1("renderer_host", | |
| 950 "RenderWidgetHostViewMac::UpdateRootGpuViewVisibility", | |
| 951 "show", show_gpu_widget); | |
| 952 // Plugins are destroyed on page navigate. The compositor layer on the other | |
| 953 // hand is created on demand and then stays alive until its renderer process | |
| 954 // dies (usually on cross-domain navigation). Instead, only a flag | |
| 955 // |is_accelerated_compositing_active()| is flipped when the compositor output | |
| 956 // should be shown/hidden. | |
| 957 // Show/hide the view belonging to the compositor here. | |
| 958 plugin_container_manager_.set_gpu_rendering_active(show_gpu_widget); | |
| 959 | |
| 960 gfx::PluginWindowHandle root_handle = | |
| 961 plugin_container_manager_.root_container_handle(); | |
| 962 if (root_handle != gfx::kNullPluginWindow) { | |
| 963 AcceleratedPluginView* view = ViewForPluginWindowHandle(root_handle); | |
| 964 DCHECK(view); | |
| 965 bool visible = | |
| 966 plugin_container_manager_.SurfaceShouldBeVisible(root_handle); | |
| 967 [[view window] disableScreenUpdatesUntilFlush]; | |
| 968 [view setHidden:!visible]; | |
| 969 } | |
| 970 } | |
| 971 | |
| 972 void RenderWidgetHostViewMac::HandleDelayedGpuViewHiding() { | |
| 973 TRACE_EVENT0("renderer_host", | |
| 974 "RenderWidgetHostViewMac::HandleDelayedGpuViewHiding"); | |
| 975 if (needs_gpu_visibility_update_after_repaint_) { | |
| 976 UpdateRootGpuViewVisibility(false); | |
| 977 needs_gpu_visibility_update_after_repaint_ = false; | |
| 978 } | |
| 979 } | |
| 980 | |
| 981 void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() { | 972 void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() { |
| 982 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 983 bool activated = RenderWidgetHostImpl::From( | |
| 984 GetRenderWidgetHost())->is_accelerated_compositing_active(); | |
| 985 bool changed = accelerated_compositing_active_ != activated; | |
| 986 accelerated_compositing_active_ = activated; | |
| 987 if (!changed) | |
| 988 return; | |
| 989 | |
| 990 TRACE_EVENT1("renderer_host", | |
| 991 "RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange", | |
| 992 "active", accelerated_compositing_active_); | |
| 993 if (accelerated_compositing_active_) { | |
| 994 UpdateRootGpuViewVisibility(accelerated_compositing_active_); | |
| 995 } else { | |
| 996 needs_gpu_visibility_update_after_repaint_ = true; | |
| 997 } | |
| 998 } | 973 } |
| 999 | 974 |
| 1000 void RenderWidgetHostViewMac::GetScreenInfo(WebKit::WebScreenInfo* results) { | 975 void RenderWidgetHostViewMac::GetScreenInfo(WebKit::WebScreenInfo* results) { |
| 1001 *results = WebKit::WebScreenInfoFactory::screenInfo(GetNativeView()); | 976 *results = WebKit::WebScreenInfoFactory::screenInfo(GetNativeView()); |
| 1002 } | 977 } |
| 1003 | 978 |
| 1004 gfx::Rect RenderWidgetHostViewMac::GetRootWindowBounds() { | 979 gfx::Rect RenderWidgetHostViewMac::GetRootWindowBounds() { |
| 1005 // TODO(shess): In case of !window, the view has been removed from | 980 // TODO(shess): In case of !window, the view has been removed from |
| 1006 // the view hierarchy because the tab isn't main. Could retrieve | 981 // the view hierarchy because the tab isn't main. Could retrieve |
| 1007 // the information from the main tab for our window. | 982 // the information from the main tab for our window. |
| 1008 NSWindow* enclosing_window = ApparentWindowForView(cocoa_view_); | 983 NSWindow* enclosing_window = ApparentWindowForView(cocoa_view_); |
| 1009 if (!enclosing_window) | 984 if (!enclosing_window) |
| 1010 return gfx::Rect(); | 985 return gfx::Rect(); |
| 1011 | 986 |
| 1012 NSRect bounds = [enclosing_window frame]; | 987 NSRect bounds = [enclosing_window frame]; |
| 1013 return FlipNSRectToRectScreen(bounds); | 988 return FlipNSRectToRectScreen(bounds); |
| 1014 } | 989 } |
| 1015 | 990 |
| 1016 gfx::GLSurfaceHandle RenderWidgetHostViewMac::GetCompositingSurface() { | 991 gfx::GLSurfaceHandle RenderWidgetHostViewMac::GetCompositingSurface() { |
| 1017 if (compositing_surface_ == gfx::kNullPluginWindow) | 992 // compositing_surface_ is always gfx::kNullPluginWindow. |
| 1018 compositing_surface_ = AllocateFakePluginWindowHandle( | |
| 1019 /*opaque=*/true, /*root=*/true); | |
| 1020 return gfx::GLSurfaceHandle(compositing_surface_, true); | 993 return gfx::GLSurfaceHandle(compositing_surface_, true); |
| 1021 } | 994 } |
| 1022 | 995 |
| 1023 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( | 996 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( |
| 1024 CGLContextObj context, | 997 CGLContextObj context, |
| 1025 gfx::PluginWindowHandle plugin_handle, | 998 gfx::PluginWindowHandle plugin_handle, |
| 1026 NSSize size) { | 999 NSSize size) { |
| 1027 TRACE_EVENT0("browser", | 1000 TRACE_EVENT0("browser", |
| 1028 "RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance"); | 1001 "RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance"); |
| 1029 // Called on the display link thread. | 1002 // Called on the display link thread. |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1175 | 1148 |
| 1176 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 1149 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
| 1177 self = [super initWithFrame:NSZeroRect]; | 1150 self = [super initWithFrame:NSZeroRect]; |
| 1178 if (self) { | 1151 if (self) { |
| 1179 editCommand_helper_.reset(new RenderWidgetHostViewMacEditCommandHelper); | 1152 editCommand_helper_.reset(new RenderWidgetHostViewMacEditCommandHelper); |
| 1180 editCommand_helper_->AddEditingSelectorsToClass([self class]); | 1153 editCommand_helper_->AddEditingSelectorsToClass([self class]); |
| 1181 | 1154 |
| 1182 renderWidgetHostView_.reset(r); | 1155 renderWidgetHostView_.reset(r); |
| 1183 canBeKeyView_ = YES; | 1156 canBeKeyView_ = YES; |
| 1184 focusedPluginIdentifier_ = -1; | 1157 focusedPluginIdentifier_ = -1; |
| 1158 | |
| 1159 // OpenGL support: | |
| 1160 handlingGlobalFrameDidChange_ = NO; | |
| 1161 hasGLContext_ = NO; | |
| 1162 [[NSNotificationCenter defaultCenter] | |
| 1163 addObserver:self | |
| 1164 selector:@selector(globalFrameDidChange:) | |
| 1165 name:NSViewGlobalFrameDidChangeNotification | |
| 1166 object:self]; | |
| 1185 } | 1167 } |
| 1186 return self; | 1168 return self; |
| 1187 } | 1169 } |
| 1188 | 1170 |
| 1189 - (void)dealloc { | 1171 - (void)dealloc { |
| 1190 if (delegate_ && [delegate_ respondsToSelector:@selector(viewGone:)]) | 1172 if (delegate_ && [delegate_ respondsToSelector:@selector(viewGone:)]) |
| 1191 [delegate_ viewGone:self]; | 1173 [delegate_ viewGone:self]; |
| 1174 [[NSNotificationCenter defaultCenter] removeObserver:self]; | |
| 1192 | 1175 |
| 1193 [super dealloc]; | 1176 [super dealloc]; |
| 1194 } | 1177 } |
| 1195 | 1178 |
| 1196 - (void)setRWHVDelegate:(NSObject<RenderWidgetHostViewMacDelegate>*)delegate { | 1179 - (void)setRWHVDelegate:(NSObject<RenderWidgetHostViewMacDelegate>*)delegate { |
| 1197 delegate_ = delegate; | 1180 delegate_ = delegate; |
| 1198 } | 1181 } |
| 1199 | 1182 |
| 1200 - (void)gotUnhandledWheelEvent { | 1183 - (void)gotUnhandledWheelEvent { |
| 1201 if (delegate_ && | 1184 if (delegate_ && |
| (...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1696 for (NSView* subview in [self subviews]) { | 1679 for (NSView* subview in [self subviews]) { |
| 1697 if (![subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) | 1680 if (![subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) |
| 1698 continue; // Skip plugin views. | 1681 continue; // Skip plugin views. |
| 1699 | 1682 |
| 1700 [static_cast<RenderWidgetHostViewCocoa*>(subview) | 1683 [static_cast<RenderWidgetHostViewCocoa*>(subview) |
| 1701 renderWidgetHostViewMac]->KillSelf(); | 1684 renderWidgetHostViewMac]->KillSelf(); |
| 1702 } | 1685 } |
| 1703 } | 1686 } |
| 1704 } | 1687 } |
| 1705 | 1688 |
| 1689 // OpenGL support | |
| 1690 - (void)addedGLContext { | |
| 1691 hasGLContext_ = YES; | |
| 1692 if (![self isHiddenOrHasHiddenAncestor]) { | |
| 1693 // Intentionally leak underlaySurface count so that the window never changes | |
| 1694 // back to opaque. This is to prevent black/transparent flashing that | |
| 1695 // appears during tab switching otherwise. | |
|
Ken Russell (switch to Gerrit)
2012/04/04 17:27:17
I think a TODO should be added here. I don't remem
jbates
2012/04/04 19:21:50
Done. Added a TODO about cleaning up this code and
| |
| 1696 if ([[self window] respondsToSelector:@selector(underlaySurfaceAdded)]) | |
| 1697 [static_cast<id>([self window]) underlaySurfaceAdded]; | |
| 1698 } | |
| 1699 } | |
| 1700 | |
| 1701 - (void)viewWillMoveToWindow:(NSWindow*)newWindow { | |
| 1702 if (![self isHiddenOrHasHiddenAncestor]) { | |
| 1703 // Intentionally leak underlaySurface count so that the window never changes | |
| 1704 // back to opaque. This is to prevent black/transparent flashing that | |
| 1705 // appears during tab switching otherwise. | |
| 1706 if (hasGLContext_ && | |
| 1707 [newWindow respondsToSelector:@selector(underlaySurfaceAdded)]) | |
| 1708 [static_cast<id>(newWindow) underlaySurfaceAdded]; | |
| 1709 } | |
| 1710 } | |
| 1711 | |
| 1712 - (void) globalFrameDidChange:(NSNotification*)notification { | |
| 1713 if (handlingGlobalFrameDidChange_) | |
| 1714 return; | |
| 1715 | |
| 1716 handlingGlobalFrameDidChange_ = YES; | |
| 1717 if (renderWidgetHostView_->compositing_iosurface_.get()) | |
| 1718 renderWidgetHostView_->compositing_iosurface_->GlobalFrameDidChange(); | |
| 1719 handlingGlobalFrameDidChange_ = NO; | |
| 1720 } | |
| 1721 | |
| 1706 - (void)setFrameSize:(NSSize)newSize { | 1722 - (void)setFrameSize:(NSSize)newSize { |
| 1707 // NB: -[NSView setFrame:] calls through -setFrameSize:, so overriding | 1723 // NB: -[NSView setFrame:] calls through -setFrameSize:, so overriding |
| 1708 // -setFrame: isn't neccessary. | 1724 // -setFrame: isn't neccessary. |
| 1709 [super setFrameSize:newSize]; | 1725 [super setFrameSize:newSize]; |
| 1710 if (renderWidgetHostView_->render_widget_host_) | 1726 if (renderWidgetHostView_->render_widget_host_) |
| 1711 renderWidgetHostView_->render_widget_host_->WasResized(); | 1727 renderWidgetHostView_->render_widget_host_->WasResized(); |
| 1712 } | 1728 } |
| 1713 | 1729 |
| 1714 - (void)callSetNeedsDisplayInRect { | 1730 - (void)callSetNeedsDisplayInRect { |
| 1715 DCHECK([NSThread isMainThread]); | 1731 DCHECK([NSThread isMainThread]); |
| 1716 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); | 1732 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); |
| 1717 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; | 1733 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; |
| 1718 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; | 1734 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; |
| 1719 renderWidgetHostView_->invalid_rect_ = NSZeroRect; | 1735 renderWidgetHostView_->invalid_rect_ = NSZeroRect; |
| 1720 | |
| 1721 renderWidgetHostView_->HandleDelayedGpuViewHiding(); | |
| 1722 } | 1736 } |
| 1723 | 1737 |
| 1724 // Fills with white the parts of the area to the right and bottom for |rect| | 1738 // Fills with white the parts of the area to the right and bottom for |rect| |
| 1725 // that intersect |damagedRect|. | 1739 // that intersect |damagedRect|. |
| 1726 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect | 1740 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect |
| 1727 dirtyRect:(gfx::Rect)damagedRect { | 1741 dirtyRect:(gfx::Rect)damagedRect { |
| 1728 if (damagedRect.right() > rect.right()) { | 1742 if (damagedRect.right() > rect.right()) { |
| 1729 int x = std::max(rect.right(), damagedRect.x()); | 1743 int x = std::max(rect.right(), damagedRect.x()); |
| 1730 int y = std::min(rect.bottom(), damagedRect.bottom()); | 1744 int y = std::min(rect.bottom(), damagedRect.bottom()); |
| 1731 int width = damagedRect.right() - x; | 1745 int width = damagedRect.right() - x; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1773 if (!renderWidgetHostView_->render_widget_host_) { | 1787 if (!renderWidgetHostView_->render_widget_host_) { |
| 1774 // TODO(shess): Consider using something more noticable? | 1788 // TODO(shess): Consider using something more noticable? |
| 1775 [[NSColor whiteColor] set]; | 1789 [[NSColor whiteColor] set]; |
| 1776 NSRectFill(dirtyRect); | 1790 NSRectFill(dirtyRect); |
| 1777 return; | 1791 return; |
| 1778 } | 1792 } |
| 1779 | 1793 |
| 1780 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); | 1794 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); |
| 1781 | 1795 |
| 1782 if (renderWidgetHostView_->last_frame_was_accelerated_) { | 1796 if (renderWidgetHostView_->last_frame_was_accelerated_) { |
| 1783 gfx::Rect gpuRect; | 1797 // Draw transparency to expose the GL underlay: |
| 1798 // TODO(jbates) avoid doing this every frame. | |
| 1799 [[NSColor clearColor] set]; | |
| 1800 NSRectFill(dirtyRect); | |
| 1784 | 1801 |
| 1785 gfx::PluginWindowHandle root_handle = | 1802 renderWidgetHostView_->compositing_iosurface_->DrawLastIOSurface(self); |
| 1786 renderWidgetHostView_->plugin_container_manager_.root_container_handle(); | 1803 renderWidgetHostView_->CompositorSwapBuffersComplete(); |
| 1787 if (root_handle != gfx::kNullPluginWindow) { | |
| 1788 AcceleratedPluginView* view = | |
| 1789 renderWidgetHostView_->ViewForPluginWindowHandle(root_handle); | |
| 1790 DCHECK(view); | |
| 1791 if (view && ![view isHidden]) { | |
| 1792 gpuRect = [self flipNSRectToRect:[view frame]]; | |
| 1793 } | |
| 1794 } | |
| 1795 | |
| 1796 [self fillBottomRightRemainderOfRect:gpuRect dirtyRect:damagedRect]; | |
| 1797 return; | 1804 return; |
| 1798 } | 1805 } |
| 1799 | 1806 |
| 1807 renderWidgetHostView_->CompositorSwapBuffersComplete(); | |
|
Ken Russell (switch to Gerrit)
2012/04/04 17:27:17
It's a little confusing that this is on the softwa
jbates
2012/04/04 19:21:50
Done.
| |
| 1808 | |
| 1800 DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); | 1809 DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); |
| 1801 | 1810 |
| 1802 renderWidgetHostView_->about_to_validate_and_paint_ = true; | 1811 renderWidgetHostView_->about_to_validate_and_paint_ = true; |
| 1803 BackingStoreMac* backingStore = static_cast<BackingStoreMac*>( | 1812 BackingStoreMac* backingStore = static_cast<BackingStoreMac*>( |
| 1804 renderWidgetHostView_->render_widget_host_->GetBackingStore(true)); | 1813 renderWidgetHostView_->render_widget_host_->GetBackingStore(true)); |
| 1805 renderWidgetHostView_->about_to_validate_and_paint_ = false; | 1814 renderWidgetHostView_->about_to_validate_and_paint_ = false; |
| 1806 | 1815 |
| 1807 if (backingStore) { | 1816 if (backingStore) { |
| 1808 gfx::Rect bitmapRect(0, 0, | 1817 gfx::Rect bitmapRect(0, 0, |
| 1809 backingStore->size().width(), | 1818 backingStore->size().width(), |
| (...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2784 if (!string) return NO; | 2793 if (!string) return NO; |
| 2785 | 2794 |
| 2786 // If the user is currently using an IME, confirm the IME input, | 2795 // If the user is currently using an IME, confirm the IME input, |
| 2787 // and then insert the text from the service, the same as TextEdit and Safari. | 2796 // and then insert the text from the service, the same as TextEdit and Safari. |
| 2788 [self confirmComposition]; | 2797 [self confirmComposition]; |
| 2789 [self insertText:string]; | 2798 [self insertText:string]; |
| 2790 return YES; | 2799 return YES; |
| 2791 } | 2800 } |
| 2792 | 2801 |
| 2793 @end | 2802 @end |
| OLD | NEW |