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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) | 257 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
| 257 : render_widget_host_(RenderWidgetHostImpl::From(widget)), | 258 : render_widget_host_(RenderWidgetHostImpl::From(widget)), |
| 258 about_to_validate_and_paint_(false), | 259 about_to_validate_and_paint_(false), |
| 259 call_set_needs_display_in_rect_pending_(false), | 260 call_set_needs_display_in_rect_pending_(false), |
| 260 last_frame_was_accelerated_(false), | 261 last_frame_was_accelerated_(false), |
| 261 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 262 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
| 262 can_compose_inline_(true), | 263 can_compose_inline_(true), |
| 263 is_loading_(false), | 264 is_loading_(false), |
| 264 is_hidden_(false), | 265 is_hidden_(false), |
| 265 weak_factory_(this), | 266 weak_factory_(this), |
| 266 accelerated_compositing_active_(false), | |
| 267 needs_gpu_visibility_update_after_repaint_(false), | |
| 268 compositing_surface_(gfx::kNullPluginWindow) { | 267 compositing_surface_(gfx::kNullPluginWindow) { |
| 269 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| | 268 // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| |
| 270 // goes away. Since we autorelease it, our caller must put | 269 // goes away. Since we autorelease it, our caller must put |
| 271 // |GetNativeView()| into the view hierarchy right after calling us. | 270 // |GetNativeView()| into the view hierarchy right after calling us. |
| 272 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 271 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
| 273 initWithRenderWidgetHostViewMac:this] autorelease]; | 272 initWithRenderWidgetHostViewMac:this] autorelease]; |
| 274 render_widget_host_->SetView(this); | 273 render_widget_host_->SetView(this); |
| 275 } | 274 } |
| 276 | 275 |
| 277 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 276 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 } | 351 } |
| 353 | 352 |
| 354 void RenderWidgetHostViewMac::DidBecomeSelected() { | 353 void RenderWidgetHostViewMac::DidBecomeSelected() { |
| 355 if (!is_hidden_) | 354 if (!is_hidden_) |
| 356 return; | 355 return; |
| 357 | 356 |
| 358 if (tab_switch_paint_time_.is_null()) | 357 if (tab_switch_paint_time_.is_null()) |
| 359 tab_switch_paint_time_ = base::TimeTicks::Now(); | 358 tab_switch_paint_time_ = base::TimeTicks::Now(); |
| 360 is_hidden_ = false; | 359 is_hidden_ = false; |
| 361 render_widget_host_->WasRestored(); | 360 render_widget_host_->WasRestored(); |
| 361 | |
| 362 // We're messing with the window, so do this to ensure no flashes. | |
| 363 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
| 362 } | 364 } |
| 363 | 365 |
| 364 void RenderWidgetHostViewMac::WasHidden() { | 366 void RenderWidgetHostViewMac::WasHidden() { |
| 365 if (is_hidden_) | 367 if (is_hidden_) |
| 366 return; | 368 return; |
| 367 | 369 |
| 368 // If we receive any more paint messages while we are hidden, we want to | 370 // If we receive any more paint messages while we are hidden, we want to |
| 369 // ignore them so we don't re-allocate the backing store. We will paint | 371 // ignore them so we don't re-allocate the backing store. We will paint |
| 370 // everything again when we become selected again. | 372 // everything again when we become selected again. |
| 371 is_hidden_ = true; | 373 is_hidden_ = true; |
| 372 | 374 |
| 375 // Send ACKs for any pending SwapBuffers (if any) since we won't be displaying | |
| 376 // them and the GPU process is waiting. | |
| 377 AckPendingCompositorSwapBuffers(); | |
| 378 | |
| 373 // If we have a renderer, then inform it that we are being hidden so it can | 379 // If we have a renderer, then inform it that we are being hidden so it can |
| 374 // reduce its resource utilization. | 380 // reduce its resource utilization. |
| 375 render_widget_host_->WasHidden(); | 381 render_widget_host_->WasHidden(); |
| 382 | |
| 383 // There can be a transparent flash as this view is removed and the next is | |
| 384 // added, because of OSX windowing races between displaying the contents of | |
| 385 // the NSView and its corresponding OpenGL context. | |
| 386 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding | |
| 387 // screen updates until the next tab draws. | |
| 388 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | |
| 376 } | 389 } |
| 377 | 390 |
| 378 void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { | 391 void RenderWidgetHostViewMac::SetSize(const gfx::Size& size) { |
| 379 gfx::Rect rect = GetViewBounds(); | 392 gfx::Rect rect = GetViewBounds(); |
| 380 rect.set_size(size); | 393 rect.set_size(size); |
| 381 SetBounds(rect); | 394 SetBounds(rect); |
| 382 } | 395 } |
| 383 | 396 |
| 384 void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { | 397 void RenderWidgetHostViewMac::SetBounds(const gfx::Rect& rect) { |
| 385 // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, | 398 // |rect.size()| is view coordinates, |rect.origin| is screen coordinates, |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect); | 648 invalid_rect_ = NSUnionRect(invalid_rect_, ns_rect); |
| 636 } | 649 } |
| 637 } else { | 650 } else { |
| 638 [cocoa_view_ setNeedsDisplayInRect:ns_rect]; | 651 [cocoa_view_ setNeedsDisplayInRect:ns_rect]; |
| 639 } | 652 } |
| 640 } | 653 } |
| 641 | 654 |
| 642 if (!about_to_validate_and_paint_) | 655 if (!about_to_validate_and_paint_) |
| 643 [cocoa_view_ displayIfNeeded]; | 656 [cocoa_view_ displayIfNeeded]; |
| 644 } | 657 } |
| 645 | |
| 646 // If |about_to_validate_and_paint_| is set, then -drawRect: is on the stack | |
| 647 // and it's not allowed to call -setHidden on the accelerated view. In that | |
| 648 // case, -callSetNeedsDisplayInRect: will hide it later. | |
| 649 // If |about_to_validate_and_paint_| is not set, do it now. | |
| 650 if (!about_to_validate_and_paint_) | |
| 651 HandleDelayedGpuViewHiding(); | |
| 652 } | 658 } |
| 653 | 659 |
| 654 void RenderWidgetHostViewMac::RenderViewGone(base::TerminationStatus status, | 660 void RenderWidgetHostViewMac::RenderViewGone(base::TerminationStatus status, |
| 655 int error_code) { | 661 int error_code) { |
| 656 Destroy(); | 662 Destroy(); |
| 657 } | 663 } |
| 658 | 664 |
| 659 void RenderWidgetHostViewMac::Destroy() { | 665 void RenderWidgetHostViewMac::Destroy() { |
| 660 // On Windows, popups are implemented with a popup window style, so that when | 666 // On Windows, popups are implemented with a popup window style, so that when |
| 661 // an event comes in that would "cancel" it, it receives the OnCancelMode | 667 // an event comes in that would "cancel" it, it receives the OnCancelMode |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 890 | 896 |
| 891 AcceleratedPluginView* RenderWidgetHostViewMac::ViewForPluginWindowHandle( | 897 AcceleratedPluginView* RenderWidgetHostViewMac::ViewForPluginWindowHandle( |
| 892 gfx::PluginWindowHandle window) { | 898 gfx::PluginWindowHandle window) { |
| 893 PluginViewMap::iterator it = plugin_views_.find(window); | 899 PluginViewMap::iterator it = plugin_views_.find(window); |
| 894 DCHECK(plugin_views_.end() != it); | 900 DCHECK(plugin_views_.end() != it); |
| 895 if (plugin_views_.end() == it) | 901 if (plugin_views_.end() == it) |
| 896 return nil; | 902 return nil; |
| 897 return it->second; | 903 return it->second; |
| 898 } | 904 } |
| 899 | 905 |
| 900 void RenderWidgetHostViewMac::UpdatePluginGeometry( | |
| 901 gfx::PluginWindowHandle window, | |
| 902 int32 width, | |
| 903 int32 height) { | |
| 904 if (plugin_container_manager_.IsRootContainer(window)) { | |
| 905 // Fake up a WebPluginGeometry for the root window to set the | |
| 906 // container's size; we will never get a notification from the | |
| 907 // browser about the root window, only plugins. | |
| 908 webkit::npapi::WebPluginGeometry geom; | |
| 909 gfx::Rect rect(0, 0, width, height); | |
| 910 geom.window = window; | |
| 911 geom.window_rect = rect; | |
| 912 geom.clip_rect = rect; | |
| 913 geom.visible = true; | |
| 914 geom.rects_valid = true; | |
| 915 MovePluginWindows(std::vector<webkit::npapi::WebPluginGeometry>(1, geom)); | |
| 916 } | |
| 917 } | |
| 918 | |
| 919 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( | 906 void RenderWidgetHostViewMac::AcceleratedSurfaceSetIOSurface( |
| 920 gfx::PluginWindowHandle window, | 907 gfx::PluginWindowHandle window, |
| 921 int32 width, | 908 int32 width, |
| 922 int32 height, | 909 int32 height, |
| 923 uint64 io_surface_identifier) { | 910 uint64 io_surface_identifier) { |
| 924 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 911 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 925 plugin_container_manager_.SetSizeAndIOSurface(window, | 912 plugin_container_manager_.SetSizeAndIOSurface(window, |
| 926 width, | 913 width, |
| 927 height, | 914 height, |
| 928 io_surface_identifier); | 915 io_surface_identifier); |
| 929 UpdatePluginGeometry(window, width, height); | |
| 930 } | 916 } |
| 931 | 917 |
| 932 void RenderWidgetHostViewMac::AcceleratedSurfaceSetTransportDIB( | 918 void RenderWidgetHostViewMac::AcceleratedSurfaceSetTransportDIB( |
| 933 gfx::PluginWindowHandle window, | 919 gfx::PluginWindowHandle window, |
| 934 int32 width, | 920 int32 width, |
| 935 int32 height, | 921 int32 height, |
| 936 TransportDIB::Handle transport_dib) { | 922 TransportDIB::Handle transport_dib) { |
| 937 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 923 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 938 plugin_container_manager_.SetSizeAndTransportDIB(window, | 924 plugin_container_manager_.SetSizeAndTransportDIB(window, |
| 939 width, | 925 width, |
| 940 height, | 926 height, |
| 941 transport_dib); | 927 transport_dib); |
| 942 UpdatePluginGeometry(window, width, height); | 928 } |
| 929 | |
| 930 void RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, | |
| 931 int32 route_id, | |
| 932 int32 gpu_host_id) { | |
| 933 pending_swap_buffers_acks_.push_back(std::make_pair(route_id, gpu_host_id)); | |
| 934 if (!compositing_iosurface_.get() && !is_hidden_) { | |
| 935 [cocoa_view_ addedGLContext]; | |
| 936 compositing_iosurface_.reset(CompositingIOSurfaceMac::Create()); | |
| 937 } | |
| 938 | |
| 939 if (compositing_iosurface_.get() && !is_hidden_) { | |
| 940 last_frame_was_accelerated_ = true; | |
| 941 compositing_iosurface_->SetIOSurface(surface_handle); | |
| 942 [cocoa_view_ setNeedsDisplay:YES]; | |
| 943 } else { | |
| 944 AckPendingCompositorSwapBuffers(); | |
| 945 } | |
| 946 } | |
| 947 | |
| 948 void RenderWidgetHostViewMac::AckPendingCompositorSwapBuffers() { | |
| 949 TRACE_EVENT0("browser", | |
| 950 "RenderWidgetHostViewMac::AckPendingCompositorSwapBuffers"); | |
| 951 while (!pending_swap_buffers_acks_.empty()) { | |
| 952 if (pending_swap_buffers_acks_.front().first != 0) { | |
| 953 RenderWidgetHostImpl::AcknowledgeSwapBuffers( | |
| 954 pending_swap_buffers_acks_.front().first, | |
| 955 pending_swap_buffers_acks_.front().second); | |
| 956 } | |
| 957 pending_swap_buffers_acks_.erase(pending_swap_buffers_acks_.begin()); | |
| 958 } | |
| 943 } | 959 } |
| 944 | 960 |
| 945 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 961 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
| 946 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, | 962 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, |
| 947 int gpu_host_id) { | 963 int gpu_host_id) { |
| 948 TRACE_EVENT0("browser", | 964 TRACE_EVENT0("browser", |
| 949 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); | 965 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); |
| 950 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 966 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 951 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); | |
| 952 DCHECK(view); | |
| 953 if (view) { | |
| 954 last_frame_was_accelerated_ = (params.window == | |
| 955 plugin_container_manager_.root_container_handle()); | |
| 956 plugin_container_manager_.SetSurfaceWasPaintedTo(params.window, | |
| 957 params.surface_handle); | |
| 958 | 967 |
| 959 // The surface is hidden until its first paint, to not show garbage. | 968 if (params.window == compositing_surface_) { |
| 960 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) | 969 CompositorSwapBuffers(params.surface_handle, params.route_id, gpu_host_id); |
| 961 [view setHidden:NO]; | 970 } else { |
| 962 [view drawView]; | 971 // Deprecated accelerated plugin code path. |
| 963 } | 972 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); |
| 973 DCHECK(view); | |
| 974 if (view) { | |
| 975 plugin_container_manager_.SetSurfaceWasPaintedTo(params.window, | |
| 976 params.surface_handle); | |
| 964 | 977 |
| 965 if (params.route_id != 0) { | 978 // The surface is hidden until its first paint, to not show garbage. |
| 966 RenderWidgetHostImpl::AcknowledgeSwapBuffers(params.route_id, gpu_host_id); | 979 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) |
| 980 [view setHidden:NO]; | |
| 981 [view drawView]; | |
| 982 } | |
| 983 | |
| 984 if (params.route_id != 0) { | |
| 985 RenderWidgetHostImpl::AcknowledgeSwapBuffers(params.route_id, | |
| 986 gpu_host_id); | |
| 987 } | |
| 967 } | 988 } |
| 968 } | 989 } |
| 969 | 990 |
| 970 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( | 991 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
| 971 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, | 992 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
| 972 int gpu_host_id) { | 993 int gpu_host_id) { |
| 973 TRACE_EVENT0("browser", | 994 TRACE_EVENT0("browser", |
| 974 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); | 995 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); |
| 975 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 996 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 976 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); | |
| 977 DCHECK(view); | |
| 978 if (view) { | |
| 979 last_frame_was_accelerated_ = (params.window == | |
| 980 plugin_container_manager_.root_container_handle()); | |
| 981 plugin_container_manager_.SetSurfaceWasPaintedTo( | |
| 982 params.window, | |
| 983 params.surface_handle, | |
| 984 gfx::Rect(params.x, params.y, params.width, params.height)); | |
| 985 | 997 |
| 986 // The surface is hidden until its first paint, to not show garbage. | 998 if (params.window == compositing_surface_) { |
| 987 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) | 999 CompositorSwapBuffers(params.surface_handle, params.route_id, gpu_host_id); |
| 988 [view setHidden:NO]; | 1000 } else { |
| 989 [view drawView]; | 1001 // Deprecated accelerated plugin code path. |
| 990 } | 1002 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); |
| 1003 DCHECK(view); | |
| 1004 if (view) { | |
| 1005 plugin_container_manager_.SetSurfaceWasPaintedTo( | |
| 1006 params.window, | |
| 1007 params.surface_handle, | |
| 1008 gfx::Rect(params.x, params.y, params.width, params.height)); | |
| 991 | 1009 |
| 992 if (params.route_id != 0) { | 1010 // The surface is hidden until its first paint, to not show garbage. |
| 993 RenderWidgetHostImpl::AcknowledgePostSubBuffer( | 1011 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) |
| 994 params.route_id, gpu_host_id); | 1012 [view setHidden:NO]; |
| 1013 [view drawView]; | |
| 1014 } | |
| 1015 | |
| 1016 if (params.route_id != 0) { | |
| 1017 RenderWidgetHostImpl::AcknowledgePostSubBuffer( | |
| 1018 params.route_id, gpu_host_id); | |
| 1019 } | |
| 995 } | 1020 } |
| 996 } | 1021 } |
| 997 | 1022 |
| 998 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { | 1023 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
| 999 } | 1024 } |
| 1000 | 1025 |
| 1001 void RenderWidgetHostViewMac::UpdateRootGpuViewVisibility( | |
| 1002 bool show_gpu_widget) { | |
| 1003 TRACE_EVENT1("renderer_host", | |
| 1004 "RenderWidgetHostViewMac::UpdateRootGpuViewVisibility", | |
| 1005 "show", show_gpu_widget); | |
| 1006 // Plugins are destroyed on page navigate. The compositor layer on the other | |
| 1007 // hand is created on demand and then stays alive until its renderer process | |
| 1008 // dies (usually on cross-domain navigation). Instead, only a flag | |
| 1009 // |is_accelerated_compositing_active()| is flipped when the compositor output | |
| 1010 // should be shown/hidden. | |
| 1011 // Show/hide the view belonging to the compositor here. | |
| 1012 plugin_container_manager_.set_gpu_rendering_active(show_gpu_widget); | |
| 1013 | |
| 1014 gfx::PluginWindowHandle root_handle = | |
| 1015 plugin_container_manager_.root_container_handle(); | |
| 1016 if (root_handle != gfx::kNullPluginWindow) { | |
| 1017 AcceleratedPluginView* view = ViewForPluginWindowHandle(root_handle); | |
| 1018 DCHECK(view); | |
| 1019 bool visible = | |
| 1020 plugin_container_manager_.SurfaceShouldBeVisible(root_handle); | |
| 1021 [[view window] disableScreenUpdatesUntilFlush]; | |
| 1022 [view setHidden:!visible]; | |
| 1023 } | |
| 1024 } | |
| 1025 | |
| 1026 void RenderWidgetHostViewMac::HandleDelayedGpuViewHiding() { | |
| 1027 TRACE_EVENT0("renderer_host", | |
| 1028 "RenderWidgetHostViewMac::HandleDelayedGpuViewHiding"); | |
| 1029 if (needs_gpu_visibility_update_after_repaint_) { | |
| 1030 UpdateRootGpuViewVisibility(false); | |
| 1031 needs_gpu_visibility_update_after_repaint_ = false; | |
| 1032 } | |
| 1033 } | |
| 1034 | |
| 1035 void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() { | 1026 void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() { |
| 1036 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 1037 bool activated = RenderWidgetHostImpl::From( | |
| 1038 GetRenderWidgetHost())->is_accelerated_compositing_active(); | |
| 1039 bool changed = accelerated_compositing_active_ != activated; | |
| 1040 accelerated_compositing_active_ = activated; | |
| 1041 if (!changed) | |
| 1042 return; | |
| 1043 | |
| 1044 TRACE_EVENT1("renderer_host", | |
| 1045 "RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange", | |
| 1046 "active", accelerated_compositing_active_); | |
| 1047 if (accelerated_compositing_active_) { | |
| 1048 UpdateRootGpuViewVisibility(accelerated_compositing_active_); | |
| 1049 } else { | |
| 1050 needs_gpu_visibility_update_after_repaint_ = true; | |
| 1051 } | |
| 1052 } | 1027 } |
| 1053 | 1028 |
| 1054 void RenderWidgetHostViewMac::GetScreenInfo(WebKit::WebScreenInfo* results) { | 1029 void RenderWidgetHostViewMac::GetScreenInfo(WebKit::WebScreenInfo* results) { |
| 1055 *results = WebKit::WebScreenInfoFactory::screenInfo(GetNativeView()); | 1030 *results = WebKit::WebScreenInfoFactory::screenInfo(GetNativeView()); |
| 1056 } | 1031 } |
| 1057 | 1032 |
| 1058 gfx::Rect RenderWidgetHostViewMac::GetRootWindowBounds() { | 1033 gfx::Rect RenderWidgetHostViewMac::GetRootWindowBounds() { |
| 1059 // TODO(shess): In case of !window, the view has been removed from | 1034 // TODO(shess): In case of !window, the view has been removed from |
| 1060 // the view hierarchy because the tab isn't main. Could retrieve | 1035 // the view hierarchy because the tab isn't main. Could retrieve |
| 1061 // the information from the main tab for our window. | 1036 // the information from the main tab for our window. |
| 1062 NSWindow* enclosing_window = ApparentWindowForView(cocoa_view_); | 1037 NSWindow* enclosing_window = ApparentWindowForView(cocoa_view_); |
| 1063 if (!enclosing_window) | 1038 if (!enclosing_window) |
| 1064 return gfx::Rect(); | 1039 return gfx::Rect(); |
| 1065 | 1040 |
| 1066 NSRect bounds = [enclosing_window frame]; | 1041 NSRect bounds = [enclosing_window frame]; |
| 1067 return FlipNSRectToRectScreen(bounds); | 1042 return FlipNSRectToRectScreen(bounds); |
| 1068 } | 1043 } |
| 1069 | 1044 |
| 1070 gfx::GLSurfaceHandle RenderWidgetHostViewMac::GetCompositingSurface() { | 1045 gfx::GLSurfaceHandle RenderWidgetHostViewMac::GetCompositingSurface() { |
| 1071 if (compositing_surface_ == gfx::kNullPluginWindow) | 1046 // compositing_surface_ is always gfx::kNullPluginWindow. |
| 1072 compositing_surface_ = AllocateFakePluginWindowHandle( | |
| 1073 /*opaque=*/true, /*root=*/true); | |
| 1074 return gfx::GLSurfaceHandle(compositing_surface_, true); | 1047 return gfx::GLSurfaceHandle(compositing_surface_, true); |
| 1075 } | 1048 } |
| 1076 | 1049 |
| 1077 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( | 1050 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( |
| 1078 CGLContextObj context, | 1051 CGLContextObj context, |
| 1079 gfx::PluginWindowHandle plugin_handle, | 1052 gfx::PluginWindowHandle plugin_handle, |
| 1080 NSSize size) { | 1053 NSSize size) { |
| 1081 TRACE_EVENT0("browser", | 1054 TRACE_EVENT0("browser", |
| 1082 "RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance"); | 1055 "RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance"); |
| 1083 // Called on the display link thread. | 1056 // Called on the display link thread. |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1229 | 1202 |
| 1230 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { | 1203 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)r { |
| 1231 self = [super initWithFrame:NSZeroRect]; | 1204 self = [super initWithFrame:NSZeroRect]; |
| 1232 if (self) { | 1205 if (self) { |
| 1233 editCommand_helper_.reset(new RenderWidgetHostViewMacEditCommandHelper); | 1206 editCommand_helper_.reset(new RenderWidgetHostViewMacEditCommandHelper); |
| 1234 editCommand_helper_->AddEditingSelectorsToClass([self class]); | 1207 editCommand_helper_->AddEditingSelectorsToClass([self class]); |
| 1235 | 1208 |
| 1236 renderWidgetHostView_.reset(r); | 1209 renderWidgetHostView_.reset(r); |
| 1237 canBeKeyView_ = YES; | 1210 canBeKeyView_ = YES; |
| 1238 focusedPluginIdentifier_ = -1; | 1211 focusedPluginIdentifier_ = -1; |
| 1212 | |
| 1213 // OpenGL support: | |
| 1214 handlingGlobalFrameDidChange_ = NO; | |
| 1215 hasGLContext_ = NO; | |
| 1216 [[NSNotificationCenter defaultCenter] | |
| 1217 addObserver:self | |
| 1218 selector:@selector(globalFrameDidChange:) | |
| 1219 name:NSViewGlobalFrameDidChangeNotification | |
| 1220 object:self]; | |
| 1239 } | 1221 } |
| 1240 return self; | 1222 return self; |
| 1241 } | 1223 } |
| 1242 | 1224 |
| 1243 - (void)dealloc { | 1225 - (void)dealloc { |
| 1244 if (delegate_ && [delegate_ respondsToSelector:@selector(viewGone:)]) | 1226 if (delegate_ && [delegate_ respondsToSelector:@selector(viewGone:)]) |
| 1245 [delegate_ viewGone:self]; | 1227 [delegate_ viewGone:self]; |
| 1228 [[NSNotificationCenter defaultCenter] removeObserver:self]; | |
| 1246 | 1229 |
| 1247 [super dealloc]; | 1230 [super dealloc]; |
| 1248 } | 1231 } |
| 1249 | 1232 |
| 1250 - (void)setRWHVDelegate:(NSObject<RenderWidgetHostViewMacDelegate>*)delegate { | 1233 - (void)setRWHVDelegate:(NSObject<RenderWidgetHostViewMacDelegate>*)delegate { |
| 1251 delegate_ = delegate; | 1234 delegate_ = delegate; |
| 1252 } | 1235 } |
| 1253 | 1236 |
| 1254 - (void)gotUnhandledWheelEvent { | 1237 - (void)gotUnhandledWheelEvent { |
| 1255 if (delegate_ && | 1238 if (delegate_ && |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1759 for (NSView* subview in [self subviews]) { | 1742 for (NSView* subview in [self subviews]) { |
| 1760 if (![subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) | 1743 if (![subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) |
| 1761 continue; // Skip plugin views. | 1744 continue; // Skip plugin views. |
| 1762 | 1745 |
| 1763 [static_cast<RenderWidgetHostViewCocoa*>(subview) | 1746 [static_cast<RenderWidgetHostViewCocoa*>(subview) |
| 1764 renderWidgetHostViewMac]->KillSelf(); | 1747 renderWidgetHostViewMac]->KillSelf(); |
| 1765 } | 1748 } |
| 1766 } | 1749 } |
| 1767 } | 1750 } |
| 1768 | 1751 |
| 1752 // OpenGL support | |
| 1753 - (void)addedGLContext { | |
| 1754 hasGLContext_ = YES; | |
| 1755 if (![self isHiddenOrHasHiddenAncestor]) { | |
| 1756 // Intentionally leak underlaySurface count so that the window never changes | |
| 1757 // back to opaque. This is to prevent black/transparent flashing that | |
| 1758 // appears during tab switching otherwise. | |
| 1759 // TODO(jbates) Remove the underlaySurfaceAdded feature completely from | |
| 1760 // ChromeBrowserWindow when the subtle gray line corner bug is fixed. Then | |
| 1761 // the window can be permanently set to non-opaque. crbug.com/56154 | |
| 1762 if ([[self window] respondsToSelector:@selector(underlaySurfaceAdded)]) | |
| 1763 [static_cast<id>([self window]) underlaySurfaceAdded]; | |
| 1764 } | |
| 1765 } | |
| 1766 | |
| 1767 - (void)viewWillMoveToWindow:(NSWindow*)newWindow { | |
| 1768 if (![self isHiddenOrHasHiddenAncestor]) { | |
| 1769 // Intentionally leak underlaySurface count (see comment in addedGLContext). | |
| 1770 if (hasGLContext_ && | |
| 1771 [newWindow respondsToSelector:@selector(underlaySurfaceAdded)]) | |
| 1772 [static_cast<id>(newWindow) underlaySurfaceAdded]; | |
| 1773 } | |
| 1774 | |
| 1775 // We're messing with the window, so do this to ensure no flashes. This one | |
| 1776 // prevents a flash when the current tab is closed. | |
| 1777 [[self window] disableScreenUpdatesUntilFlush]; | |
| 1778 } | |
| 1779 | |
| 1780 - (void) globalFrameDidChange:(NSNotification*)notification { | |
|
Nico
2012/04/06 16:01:24
no space after )
| |
| 1781 if (handlingGlobalFrameDidChange_) | |
| 1782 return; | |
| 1783 | |
| 1784 handlingGlobalFrameDidChange_ = YES; | |
| 1785 if (renderWidgetHostView_->compositing_iosurface_.get()) | |
| 1786 renderWidgetHostView_->compositing_iosurface_->GlobalFrameDidChange(); | |
| 1787 handlingGlobalFrameDidChange_ = NO; | |
| 1788 } | |
| 1789 | |
| 1769 - (void)setFrameSize:(NSSize)newSize { | 1790 - (void)setFrameSize:(NSSize)newSize { |
| 1770 // NB: -[NSView setFrame:] calls through -setFrameSize:, so overriding | 1791 // NB: -[NSView setFrame:] calls through -setFrameSize:, so overriding |
| 1771 // -setFrame: isn't neccessary. | 1792 // -setFrame: isn't neccessary. |
| 1772 [super setFrameSize:newSize]; | 1793 [super setFrameSize:newSize]; |
| 1773 if (renderWidgetHostView_->render_widget_host_) | 1794 if (renderWidgetHostView_->render_widget_host_) |
| 1774 renderWidgetHostView_->render_widget_host_->WasResized(); | 1795 renderWidgetHostView_->render_widget_host_->WasResized(); |
| 1775 } | 1796 } |
| 1776 | 1797 |
| 1777 - (void)callSetNeedsDisplayInRect { | 1798 - (void)callSetNeedsDisplayInRect { |
| 1778 DCHECK([NSThread isMainThread]); | 1799 DCHECK([NSThread isMainThread]); |
| 1779 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); | 1800 DCHECK(renderWidgetHostView_->call_set_needs_display_in_rect_pending_); |
| 1780 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; | 1801 [self setNeedsDisplayInRect:renderWidgetHostView_->invalid_rect_]; |
| 1781 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; | 1802 renderWidgetHostView_->call_set_needs_display_in_rect_pending_ = false; |
| 1782 renderWidgetHostView_->invalid_rect_ = NSZeroRect; | 1803 renderWidgetHostView_->invalid_rect_ = NSZeroRect; |
| 1783 | |
| 1784 renderWidgetHostView_->HandleDelayedGpuViewHiding(); | |
| 1785 } | 1804 } |
| 1786 | 1805 |
| 1787 // Fills with white the parts of the area to the right and bottom for |rect| | 1806 // Fills with white the parts of the area to the right and bottom for |rect| |
| 1788 // that intersect |damagedRect|. | 1807 // that intersect |damagedRect|. |
| 1789 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect | 1808 - (void)fillBottomRightRemainderOfRect:(gfx::Rect)rect |
| 1790 dirtyRect:(gfx::Rect)damagedRect { | 1809 dirtyRect:(gfx::Rect)damagedRect { |
| 1791 if (damagedRect.right() > rect.right()) { | 1810 if (damagedRect.right() > rect.right()) { |
| 1792 int x = std::max(rect.right(), damagedRect.x()); | 1811 int x = std::max(rect.right(), damagedRect.x()); |
| 1793 int y = std::min(rect.bottom(), damagedRect.bottom()); | 1812 int y = std::min(rect.bottom(), damagedRect.bottom()); |
| 1794 int width = damagedRect.right() - x; | 1813 int width = damagedRect.right() - x; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1836 if (!renderWidgetHostView_->render_widget_host_) { | 1855 if (!renderWidgetHostView_->render_widget_host_) { |
| 1837 // TODO(shess): Consider using something more noticable? | 1856 // TODO(shess): Consider using something more noticable? |
| 1838 [[NSColor whiteColor] set]; | 1857 [[NSColor whiteColor] set]; |
| 1839 NSRectFill(dirtyRect); | 1858 NSRectFill(dirtyRect); |
| 1840 return; | 1859 return; |
| 1841 } | 1860 } |
| 1842 | 1861 |
| 1843 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); | 1862 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); |
| 1844 | 1863 |
| 1845 if (renderWidgetHostView_->last_frame_was_accelerated_) { | 1864 if (renderWidgetHostView_->last_frame_was_accelerated_) { |
| 1846 gfx::Rect gpuRect; | 1865 // Draw transparency to expose the GL underlay: |
| 1866 // TODO(jbates) avoid doing this every frame. | |
| 1867 [[NSColor clearColor] set]; | |
| 1868 NSRectFill(dirtyRect); | |
| 1847 | 1869 |
| 1848 gfx::PluginWindowHandle root_handle = | 1870 renderWidgetHostView_->compositing_iosurface_->DrawIOSurface(self); |
| 1849 renderWidgetHostView_->plugin_container_manager_.root_container_handle(); | 1871 renderWidgetHostView_->AckPendingCompositorSwapBuffers(); |
| 1850 if (root_handle != gfx::kNullPluginWindow) { | |
| 1851 AcceleratedPluginView* view = | |
| 1852 renderWidgetHostView_->ViewForPluginWindowHandle(root_handle); | |
| 1853 DCHECK(view); | |
| 1854 if (view && ![view isHidden]) { | |
| 1855 gpuRect = [self flipNSRectToRect:[view frame]]; | |
| 1856 } | |
| 1857 } | |
| 1858 | |
| 1859 [self fillBottomRightRemainderOfRect:gpuRect dirtyRect:damagedRect]; | |
| 1860 return; | 1872 return; |
| 1861 } | 1873 } |
| 1862 | 1874 |
| 1875 // In case the last frame was accelerated, ack any pending swaps to unblock | |
| 1876 // the GPU process. | |
| 1877 renderWidgetHostView_->AckPendingCompositorSwapBuffers(); | |
| 1878 | |
| 1863 DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); | 1879 DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); |
| 1864 | 1880 |
| 1865 renderWidgetHostView_->about_to_validate_and_paint_ = true; | 1881 renderWidgetHostView_->about_to_validate_and_paint_ = true; |
| 1866 BackingStoreMac* backingStore = static_cast<BackingStoreMac*>( | 1882 BackingStoreMac* backingStore = static_cast<BackingStoreMac*>( |
| 1867 renderWidgetHostView_->render_widget_host_->GetBackingStore(true)); | 1883 renderWidgetHostView_->render_widget_host_->GetBackingStore(true)); |
| 1868 renderWidgetHostView_->about_to_validate_and_paint_ = false; | 1884 renderWidgetHostView_->about_to_validate_and_paint_ = false; |
| 1869 | 1885 |
| 1870 if (backingStore) { | 1886 if (backingStore) { |
| 1871 gfx::Rect bitmapRect(0, 0, | 1887 gfx::Rect bitmapRect(0, 0, |
| 1872 backingStore->size().width(), | 1888 backingStore->size().width(), |
| (...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2847 if (!string) return NO; | 2863 if (!string) return NO; |
| 2848 | 2864 |
| 2849 // If the user is currently using an IME, confirm the IME input, | 2865 // If the user is currently using an IME, confirm the IME input, |
| 2850 // and then insert the text from the service, the same as TextEdit and Safari. | 2866 // and then insert the text from the service, the same as TextEdit and Safari. |
| 2851 [self confirmComposition]; | 2867 [self confirmComposition]; |
| 2852 [self insertText:string]; | 2868 [self insertText:string]; |
| 2853 return YES; | 2869 return YES; |
| 2854 } | 2870 } |
| 2855 | 2871 |
| 2856 @end | 2872 @end |
| OLD | NEW |