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/backing_store_manager.h" |
27 #include "content/browser/renderer_host/compositing_iosurface_mac.h" | 28 #include "content/browser/renderer_host/compositing_iosurface_mac.h" |
28 #include "content/browser/renderer_host/render_process_host_impl.h" | 29 #include "content/browser/renderer_host/render_process_host_impl.h" |
29 #include "content/browser/renderer_host/render_view_host_impl.h" | 30 #include "content/browser/renderer_host/render_view_host_impl.h" |
30 #import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_h
elper.h" | 31 #import "content/browser/renderer_host/render_widget_host_view_mac_editcommand_h
elper.h" |
31 #import "content/browser/renderer_host/text_input_client_mac.h" | 32 #import "content/browser/renderer_host/text_input_client_mac.h" |
32 #include "content/common/accessibility_messages.h" | 33 #include "content/common/accessibility_messages.h" |
33 #include "content/common/edit_command.h" | 34 #include "content/common/edit_command.h" |
34 #include "content/common/gpu/gpu_messages.h" | 35 #include "content/common/gpu/gpu_messages.h" |
35 #include "content/common/plugin_messages.h" | 36 #include "content/common/plugin_messages.h" |
36 #include "content/common/view_messages.h" | 37 #include "content/common/view_messages.h" |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 | 257 |
257 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) | 258 RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) |
258 : render_widget_host_(RenderWidgetHostImpl::From(widget)), | 259 : render_widget_host_(RenderWidgetHostImpl::From(widget)), |
259 about_to_validate_and_paint_(false), | 260 about_to_validate_and_paint_(false), |
260 call_set_needs_display_in_rect_pending_(false), | 261 call_set_needs_display_in_rect_pending_(false), |
261 last_frame_was_accelerated_(false), | 262 last_frame_was_accelerated_(false), |
262 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 263 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
263 can_compose_inline_(true), | 264 can_compose_inline_(true), |
264 is_loading_(false), | 265 is_loading_(false), |
265 is_hidden_(false), | 266 is_hidden_(false), |
266 weak_factory_(this), | 267 weak_factory_(this) { |
267 compositing_surface_(gfx::kNullPluginWindow) { | |
268 // |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_| |
269 // goes away. Since we autorelease it, our caller must put | 269 // goes away. Since we autorelease it, our caller must put |
270 // |GetNativeView()| into the view hierarchy right after calling us. | 270 // |GetNativeView()| into the view hierarchy right after calling us. |
271 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] | 271 cocoa_view_ = [[[RenderWidgetHostViewCocoa alloc] |
272 initWithRenderWidgetHostViewMac:this] autorelease]; | 272 initWithRenderWidgetHostViewMac:this] autorelease]; |
273 render_widget_host_->SetView(this); | 273 render_widget_host_->SetView(this); |
274 } | 274 } |
275 | 275 |
276 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { | 276 RenderWidgetHostViewMac::~RenderWidgetHostViewMac() { |
277 UnlockMouse(); | 277 UnlockMouse(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 | 365 |
366 void RenderWidgetHostViewMac::WasHidden() { | 366 void RenderWidgetHostViewMac::WasHidden() { |
367 if (is_hidden_) | 367 if (is_hidden_) |
368 return; | 368 return; |
369 | 369 |
370 // 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 |
371 // 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 |
372 // everything again when we become selected again. | 372 // everything again when we become selected again. |
373 is_hidden_ = true; | 373 is_hidden_ = true; |
374 | 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 | |
379 // If we have a renderer, then inform it that we are being hidden so it can | 375 // If we have a renderer, then inform it that we are being hidden so it can |
380 // reduce its resource utilization. | 376 // reduce its resource utilization. |
381 render_widget_host_->WasHidden(); | 377 render_widget_host_->WasHidden(); |
382 | 378 |
383 // There can be a transparent flash as this view is removed and the next is | 379 // 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 | 380 // added, because of OSX windowing races between displaying the contents of |
385 // the NSView and its corresponding OpenGL context. | 381 // the NSView and its corresponding OpenGL context. |
386 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding | 382 // disableScreenUpdatesUntilFlush prevents the transparent flash by avoiding |
387 // screen updates until the next tab draws. | 383 // screen updates until the next tab draws. |
388 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; | 384 [[cocoa_view_ window] disableScreenUpdatesUntilFlush]; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 void RenderWidgetHostViewMac::ImeCompositionRangeChanged( | 602 void RenderWidgetHostViewMac::ImeCompositionRangeChanged( |
607 const ui::Range& range) { | 603 const ui::Range& range) { |
608 // The RangeChanged message is only sent with valid values. The current | 604 // The RangeChanged message is only sent with valid values. The current |
609 // caret position (start == end) will be sent if there is no IME range. | 605 // caret position (start == end) will be sent if there is no IME range. |
610 [cocoa_view_ setMarkedRange:range.ToNSRange()]; | 606 [cocoa_view_ setMarkedRange:range.ToNSRange()]; |
611 } | 607 } |
612 | 608 |
613 void RenderWidgetHostViewMac::DidUpdateBackingStore( | 609 void RenderWidgetHostViewMac::DidUpdateBackingStore( |
614 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, | 610 const gfx::Rect& scroll_rect, int scroll_dx, int scroll_dy, |
615 const std::vector<gfx::Rect>& copy_rects) { | 611 const std::vector<gfx::Rect>& copy_rects) { |
616 last_frame_was_accelerated_ = false; | 612 GotSoftwareFrame(); |
617 | 613 |
618 if (!is_hidden_) { | 614 if (!is_hidden_) { |
619 std::vector<gfx::Rect> rects(copy_rects); | 615 std::vector<gfx::Rect> rects(copy_rects); |
620 | 616 |
621 // Because the findbar might be open, we cannot use scrollRect:by: here. For | 617 // Because the findbar might be open, we cannot use scrollRect:by: here. For |
622 // now, simply mark all of scroll rect as dirty. | 618 // now, simply mark all of scroll rect as dirty. |
623 if (!scroll_rect.IsEmpty()) | 619 if (!scroll_rect.IsEmpty()) |
624 rects.push_back(scroll_rect); | 620 rects.push_back(scroll_rect); |
625 | 621 |
626 for (size_t i = 0; i < rects.size(); ++i) { | 622 for (size_t i = 0; i < rects.size(); ++i) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 for (NSView* subview in [cocoa_view_ subviews]) { | 672 for (NSView* subview in [cocoa_view_ subviews]) { |
677 if ([subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) { | 673 if ([subview isKindOfClass:[RenderWidgetHostViewCocoa class]]) { |
678 [static_cast<RenderWidgetHostViewCocoa*>(subview) | 674 [static_cast<RenderWidgetHostViewCocoa*>(subview) |
679 renderWidgetHostViewMac]->ShutdownHost(); | 675 renderWidgetHostViewMac]->ShutdownHost(); |
680 } else if ([subview isKindOfClass:[AcceleratedPluginView class]]) { | 676 } else if ([subview isKindOfClass:[AcceleratedPluginView class]]) { |
681 [static_cast<AcceleratedPluginView*>(subview) | 677 [static_cast<AcceleratedPluginView*>(subview) |
682 onRenderWidgetHostViewGone]; | 678 onRenderWidgetHostViewGone]; |
683 } | 679 } |
684 } | 680 } |
685 | 681 |
686 // Ack pending swaps (if any). | |
687 AckPendingCompositorSwapBuffers(); | |
688 | |
689 // We've been told to destroy. | 682 // We've been told to destroy. |
690 [cocoa_view_ retain]; | 683 [cocoa_view_ retain]; |
691 [cocoa_view_ removeFromSuperview]; | 684 [cocoa_view_ removeFromSuperview]; |
692 [cocoa_view_ autorelease]; | 685 [cocoa_view_ autorelease]; |
693 | 686 |
694 [fullscreen_window_manager_ exitFullscreenMode]; | 687 [fullscreen_window_manager_ exitFullscreenMode]; |
695 fullscreen_window_manager_.reset(); | 688 fullscreen_window_manager_.reset(); |
696 [pepper_fullscreen_window_ close]; | 689 [pepper_fullscreen_window_ close]; |
697 pepper_fullscreen_window_.reset(); | 690 pepper_fullscreen_window_.reset(); |
698 | 691 |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 int32 width, | 939 int32 width, |
947 int32 height, | 940 int32 height, |
948 TransportDIB::Handle transport_dib) { | 941 TransportDIB::Handle transport_dib) { |
949 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 942 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
950 plugin_container_manager_.SetSizeAndTransportDIB(window, | 943 plugin_container_manager_.SetSizeAndTransportDIB(window, |
951 width, | 944 width, |
952 height, | 945 height, |
953 transport_dib); | 946 transport_dib); |
954 } | 947 } |
955 | 948 |
956 void RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle, | 949 void RenderWidgetHostViewMac::CompositorSwapBuffers(uint64 surface_handle) { |
957 int32 route_id, | 950 if (is_hidden_) |
958 int32 gpu_host_id) { | 951 return; |
959 pending_swap_buffers_acks_.push_back(std::make_pair(route_id, gpu_host_id)); | 952 |
960 if (!compositing_iosurface_.get() && !is_hidden_) { | 953 if (!compositing_iosurface_.get()) |
961 compositing_iosurface_.reset(CompositingIOSurfaceMac::Create()); | 954 compositing_iosurface_.reset(CompositingIOSurfaceMac::Create()); |
962 } | |
963 | 955 |
964 if (compositing_iosurface_.get() && !is_hidden_) { | 956 if (!compositing_iosurface_.get()) |
965 last_frame_was_accelerated_ = true; | 957 return; |
966 compositing_iosurface_->SetIOSurface(surface_handle); | |
967 [cocoa_view_ setNeedsDisplay:YES]; | |
968 } else { | |
969 AckPendingCompositorSwapBuffers(); | |
970 } | |
971 } | |
972 | 958 |
973 void RenderWidgetHostViewMac::AckPendingCompositorSwapBuffers() { | 959 compositing_iosurface_->SetIOSurface(surface_handle); |
974 TRACE_EVENT0("browser", | 960 // No need to draw the surface if we are inside a drawRect. It will be done |
975 "RenderWidgetHostViewMac::AckPendingCompositorSwapBuffers"); | 961 // later. |
976 while (!pending_swap_buffers_acks_.empty()) { | 962 if (!about_to_validate_and_paint_) |
977 if (pending_swap_buffers_acks_.front().first != 0) { | 963 compositing_iosurface_->DrawIOSurface(cocoa_view_); |
978 RenderWidgetHostImpl::AcknowledgeSwapBuffers( | 964 GotAcceleratedFrame(); |
979 pending_swap_buffers_acks_.front().first, | |
980 pending_swap_buffers_acks_.front().second); | |
981 } | |
982 pending_swap_buffers_acks_.erase(pending_swap_buffers_acks_.begin()); | |
983 } | |
984 } | 965 } |
985 | 966 |
986 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( | 967 void RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped( |
987 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, | 968 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, |
988 int gpu_host_id) { | 969 int gpu_host_id) { |
989 TRACE_EVENT0("browser", | 970 TRACE_EVENT0("browser", |
990 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); | 971 "RenderWidgetHostViewMac::AcceleratedSurfaceBuffersSwapped"); |
991 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 972 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
992 | 973 |
993 if (params.window == compositing_surface_) { | 974 // Compositor window is always gfx::kNullPluginWindow. |
994 CompositorSwapBuffers(params.surface_handle, params.route_id, gpu_host_id); | 975 // TODO(jbates) http://crbug.com/105344 This will be removed when there are no |
| 976 // plugin windows. |
| 977 if (params.window == gfx::kNullPluginWindow) { |
| 978 CompositorSwapBuffers(params.surface_handle); |
995 } else { | 979 } else { |
996 // Deprecated accelerated plugin code path. | 980 // Deprecated accelerated plugin code path. |
997 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); | 981 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); |
998 DCHECK(view); | 982 DCHECK(view); |
999 if (view) { | 983 if (view) { |
1000 plugin_container_manager_.SetSurfaceWasPaintedTo(params.window, | 984 plugin_container_manager_.SetSurfaceWasPaintedTo(params.window, |
1001 params.surface_handle); | 985 params.surface_handle); |
1002 | 986 |
1003 // The surface is hidden until its first paint, to not show garbage. | 987 // The surface is hidden until its first paint, to not show garbage. |
1004 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) | 988 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) |
1005 [view setHidden:NO]; | 989 [view setHidden:NO]; |
1006 [view drawView]; | 990 [view drawView]; |
1007 } | 991 } |
| 992 } |
1008 | 993 |
1009 if (params.route_id != 0) { | 994 if (params.route_id != 0) { |
1010 RenderWidgetHostImpl::AcknowledgeSwapBuffers(params.route_id, | 995 RenderWidgetHostImpl::AcknowledgeSwapBuffers(params.route_id, |
1011 gpu_host_id); | 996 gpu_host_id); |
1012 } | |
1013 } | 997 } |
1014 } | 998 } |
1015 | 999 |
1016 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( | 1000 void RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer( |
1017 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, | 1001 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, |
1018 int gpu_host_id) { | 1002 int gpu_host_id) { |
1019 TRACE_EVENT0("browser", | 1003 TRACE_EVENT0("browser", |
1020 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); | 1004 "RenderWidgetHostViewMac::AcceleratedSurfacePostSubBuffer"); |
1021 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1005 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
1022 | 1006 |
1023 if (params.window == compositing_surface_) { | 1007 // Compositor window is always gfx::kNullPluginWindow. |
1024 CompositorSwapBuffers(params.surface_handle, params.route_id, gpu_host_id); | 1008 // TODO(jbates) http://crbug.com/105344 This will be removed when there are no |
| 1009 // plugin windows. |
| 1010 if (params.window == gfx::kNullPluginWindow) { |
| 1011 CompositorSwapBuffers(params.surface_handle); |
1025 } else { | 1012 } else { |
1026 // Deprecated accelerated plugin code path. | 1013 // Deprecated accelerated plugin code path. |
1027 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); | 1014 AcceleratedPluginView* view = ViewForPluginWindowHandle(params.window); |
1028 DCHECK(view); | 1015 DCHECK(view); |
1029 if (view) { | 1016 if (view) { |
1030 plugin_container_manager_.SetSurfaceWasPaintedTo( | 1017 plugin_container_manager_.SetSurfaceWasPaintedTo( |
1031 params.window, | 1018 params.window, |
1032 params.surface_handle, | 1019 params.surface_handle, |
1033 gfx::Rect(params.x, params.y, params.width, params.height)); | 1020 gfx::Rect(params.x, params.y, params.width, params.height)); |
1034 | 1021 |
1035 // The surface is hidden until its first paint, to not show garbage. | 1022 // The surface is hidden until its first paint, to not show garbage. |
1036 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) | 1023 if (plugin_container_manager_.SurfaceShouldBeVisible(params.window)) |
1037 [view setHidden:NO]; | 1024 [view setHidden:NO]; |
1038 [view drawView]; | 1025 [view drawView]; |
1039 } | 1026 } |
| 1027 } |
1040 | 1028 |
1041 if (params.route_id != 0) { | 1029 if (params.route_id != 0) { |
1042 RenderWidgetHostImpl::AcknowledgePostSubBuffer( | 1030 RenderWidgetHostImpl::AcknowledgePostSubBuffer( |
1043 params.route_id, gpu_host_id); | 1031 params.route_id, gpu_host_id); |
1044 } | |
1045 } | 1032 } |
1046 } | 1033 } |
1047 | 1034 |
1048 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { | 1035 void RenderWidgetHostViewMac::AcceleratedSurfaceSuspend() { |
| 1036 if (compositing_iosurface_.get()) |
| 1037 compositing_iosurface_->UnrefIOSurface(); |
| 1038 } |
| 1039 |
| 1040 bool RenderWidgetHostViewMac::HasAcceleratedSurface( |
| 1041 const gfx::Size& desired_size) { |
| 1042 return last_frame_was_accelerated_ && |
| 1043 compositing_iosurface_.get() && |
| 1044 compositing_iosurface_->HasIOSurface() && |
| 1045 (desired_size.IsEmpty() || |
| 1046 compositing_iosurface_->io_surface_size() == desired_size); |
1049 } | 1047 } |
1050 | 1048 |
1051 void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() { | 1049 void RenderWidgetHostViewMac::OnAcceleratedCompositingStateChange() { |
1052 } | 1050 } |
1053 | 1051 |
1054 void RenderWidgetHostViewMac::GetScreenInfo(WebKit::WebScreenInfo* results) { | 1052 void RenderWidgetHostViewMac::GetScreenInfo(WebKit::WebScreenInfo* results) { |
1055 *results = WebKit::WebScreenInfoFactory::screenInfo(GetNativeView()); | 1053 *results = WebKit::WebScreenInfoFactory::screenInfo(GetNativeView()); |
1056 } | 1054 } |
1057 | 1055 |
1058 gfx::Rect RenderWidgetHostViewMac::GetRootWindowBounds() { | 1056 gfx::Rect RenderWidgetHostViewMac::GetRootWindowBounds() { |
1059 // TODO(shess): In case of !window, the view has been removed from | 1057 // TODO(shess): In case of !window, the view has been removed from |
1060 // the view hierarchy because the tab isn't main. Could retrieve | 1058 // the view hierarchy because the tab isn't main. Could retrieve |
1061 // the information from the main tab for our window. | 1059 // the information from the main tab for our window. |
1062 NSWindow* enclosing_window = ApparentWindowForView(cocoa_view_); | 1060 NSWindow* enclosing_window = ApparentWindowForView(cocoa_view_); |
1063 if (!enclosing_window) | 1061 if (!enclosing_window) |
1064 return gfx::Rect(); | 1062 return gfx::Rect(); |
1065 | 1063 |
1066 NSRect bounds = [enclosing_window frame]; | 1064 NSRect bounds = [enclosing_window frame]; |
1067 return FlipNSRectToRectScreen(bounds); | 1065 return FlipNSRectToRectScreen(bounds); |
1068 } | 1066 } |
1069 | 1067 |
1070 gfx::GLSurfaceHandle RenderWidgetHostViewMac::GetCompositingSurface() { | 1068 gfx::GLSurfaceHandle RenderWidgetHostViewMac::GetCompositingSurface() { |
1071 // compositing_surface_ is always gfx::kNullPluginWindow. | 1069 // Compositor window is always gfx::kNullPluginWindow. |
1072 return gfx::GLSurfaceHandle(compositing_surface_, true); | 1070 // TODO(jbates) http://crbug.com/105344 This will be removed when there are no |
| 1071 // plugin windows. |
| 1072 return gfx::GLSurfaceHandle(gfx::kNullPluginWindow, true); |
1073 } | 1073 } |
1074 | 1074 |
1075 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( | 1075 void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( |
1076 CGLContextObj context, | 1076 CGLContextObj context, |
1077 gfx::PluginWindowHandle plugin_handle, | 1077 gfx::PluginWindowHandle plugin_handle, |
1078 NSSize size) { | 1078 NSSize size) { |
1079 TRACE_EVENT0("browser", | 1079 TRACE_EVENT0("browser", |
1080 "RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance"); | 1080 "RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance"); |
1081 // Called on the display link thread. | 1081 // Called on the display link thread. |
1082 CGLSetCurrentContext(context); | 1082 CGLSetCurrentContext(context); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 const WebKit::WebMouseWheelEvent& event) { | 1144 const WebKit::WebMouseWheelEvent& event) { |
1145 [cocoa_view_ gotUnhandledWheelEvent]; | 1145 [cocoa_view_ gotUnhandledWheelEvent]; |
1146 } | 1146 } |
1147 | 1147 |
1148 void RenderWidgetHostViewMac::ShutdownHost() { | 1148 void RenderWidgetHostViewMac::ShutdownHost() { |
1149 weak_factory_.InvalidateWeakPtrs(); | 1149 weak_factory_.InvalidateWeakPtrs(); |
1150 render_widget_host_->Shutdown(); | 1150 render_widget_host_->Shutdown(); |
1151 // Do not touch any members at this point, |this| has been deleted. | 1151 // Do not touch any members at this point, |this| has been deleted. |
1152 } | 1152 } |
1153 | 1153 |
| 1154 void RenderWidgetHostViewMac::GotAcceleratedFrame() { |
| 1155 if (!last_frame_was_accelerated_) { |
| 1156 last_frame_was_accelerated_ = true; |
| 1157 |
| 1158 // Need to wipe the software view with transparency to expose the GL |
| 1159 // underlay. Invalidate the whole window to do that. |
| 1160 if (!about_to_validate_and_paint_) { |
| 1161 [cocoa_view_ setNeedsDisplay:YES]; |
| 1162 [cocoa_view_ displayIfNeeded]; |
| 1163 } |
| 1164 |
| 1165 // Delete software backingstore. |
| 1166 BackingStoreManager::RemoveBackingStore(render_widget_host_); |
| 1167 } |
| 1168 } |
| 1169 |
| 1170 void RenderWidgetHostViewMac::GotSoftwareFrame() { |
| 1171 if (last_frame_was_accelerated_) { |
| 1172 last_frame_was_accelerated_ = false; |
| 1173 |
| 1174 // Forget IOSurface since we are drawing a software frame now. |
| 1175 if (compositing_iosurface_.get() && |
| 1176 compositing_iosurface_->HasIOSurface()) { |
| 1177 compositing_iosurface_->UnrefIOSurface(); |
| 1178 } |
| 1179 } |
| 1180 } |
| 1181 |
1154 gfx::Rect RenderWidgetHostViewMac::GetViewCocoaBounds() const { | 1182 gfx::Rect RenderWidgetHostViewMac::GetViewCocoaBounds() const { |
1155 return gfx::Rect(NSRectToCGRect([cocoa_view_ bounds])); | 1183 return gfx::Rect(NSRectToCGRect([cocoa_view_ bounds])); |
1156 } | 1184 } |
1157 | 1185 |
1158 void RenderWidgetHostViewMac::SetActive(bool active) { | 1186 void RenderWidgetHostViewMac::SetActive(bool active) { |
1159 if (render_widget_host_) | 1187 if (render_widget_host_) |
1160 render_widget_host_->SetActive(active); | 1188 render_widget_host_->SetActive(active); |
1161 if (HasFocus()) | 1189 if (HasFocus()) |
1162 SetTextInputActive(active); | 1190 SetTextInputActive(active); |
1163 if (!active) { | 1191 if (!active) { |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1353 [view performSelector:nonWebContentViewSelector]) { | 1381 [view performSelector:nonWebContentViewSelector]) { |
1354 // The cursor is over a nonWebContentView - ignore this mouse event. | 1382 // The cursor is over a nonWebContentView - ignore this mouse event. |
1355 return YES; | 1383 return YES; |
1356 } | 1384 } |
1357 view = [view superview]; | 1385 view = [view superview]; |
1358 } | 1386 } |
1359 return NO; | 1387 return NO; |
1360 } | 1388 } |
1361 | 1389 |
1362 - (void)mouseEvent:(NSEvent*)theEvent { | 1390 - (void)mouseEvent:(NSEvent*)theEvent { |
| 1391 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::mouseEvent"); |
1363 if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) { | 1392 if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) { |
1364 BOOL handled = [delegate_ handleEvent:theEvent]; | 1393 BOOL handled = [delegate_ handleEvent:theEvent]; |
1365 if (handled) | 1394 if (handled) |
1366 return; | 1395 return; |
1367 } | 1396 } |
1368 | 1397 |
1369 if ([self shouldIgnoreMouseEvent:theEvent]) { | 1398 if ([self shouldIgnoreMouseEvent:theEvent]) { |
1370 // If this is the first such event, send a mouse exit to the host view. | 1399 // If this is the first such event, send a mouse exit to the host view. |
1371 if (!mouseEventWasIgnored_ && renderWidgetHostView_->render_widget_host_) { | 1400 if (!mouseEventWasIgnored_ && renderWidgetHostView_->render_widget_host_) { |
1372 WebMouseEvent exitEvent = | 1401 WebMouseEvent exitEvent = |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1514 if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) { | 1543 if (delegate_ && [delegate_ respondsToSelector:@selector(handleEvent:)]) { |
1515 BOOL handled = [delegate_ handleEvent:theEvent]; | 1544 BOOL handled = [delegate_ handleEvent:theEvent]; |
1516 if (handled) | 1545 if (handled) |
1517 return; | 1546 return; |
1518 } | 1547 } |
1519 | 1548 |
1520 [self keyEvent:theEvent wasKeyEquivalent:NO]; | 1549 [self keyEvent:theEvent wasKeyEquivalent:NO]; |
1521 } | 1550 } |
1522 | 1551 |
1523 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv { | 1552 - (void)keyEvent:(NSEvent*)theEvent wasKeyEquivalent:(BOOL)equiv { |
| 1553 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::keyEvent"); |
1524 DCHECK([theEvent type] != NSKeyDown || | 1554 DCHECK([theEvent type] != NSKeyDown || |
1525 !equiv == !([theEvent modifierFlags] & NSCommandKeyMask)); | 1555 !equiv == !([theEvent modifierFlags] & NSCommandKeyMask)); |
1526 | 1556 |
1527 if ([theEvent type] == NSFlagsChanged) { | 1557 if ([theEvent type] == NSFlagsChanged) { |
1528 // Ignore NSFlagsChanged events from the NumLock and Fn keys as | 1558 // Ignore NSFlagsChanged events from the NumLock and Fn keys as |
1529 // Safari does in -[WebHTMLView flagsChanged:] (of "WebHTMLView.mm"). | 1559 // Safari does in -[WebHTMLView flagsChanged:] (of "WebHTMLView.mm"). |
1530 int keyCode = [theEvent keyCode]; | 1560 int keyCode = [theEvent keyCode]; |
1531 if (!keyCode || keyCode == 10 || keyCode == 63) | 1561 if (!keyCode || keyCode == 10 || keyCode == 63) |
1532 return; | 1562 return; |
1533 } | 1563 } |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1839 height = -height; | 1869 height = -height; |
1840 } | 1870 } |
1841 | 1871 |
1842 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; | 1872 NSRect r = [self flipRectToNSRect:gfx::Rect(x, y, width, height)]; |
1843 [[NSColor whiteColor] set]; | 1873 [[NSColor whiteColor] set]; |
1844 NSRectFill(r); | 1874 NSRectFill(r); |
1845 } | 1875 } |
1846 } | 1876 } |
1847 | 1877 |
1848 - (void)drawRect:(NSRect)dirtyRect { | 1878 - (void)drawRect:(NSRect)dirtyRect { |
| 1879 TRACE_EVENT0("browser", "RenderWidgetHostViewCocoa::drawRect"); |
1849 if (!renderWidgetHostView_->render_widget_host_) { | 1880 if (!renderWidgetHostView_->render_widget_host_) { |
1850 // TODO(shess): Consider using something more noticable? | 1881 // TODO(shess): Consider using something more noticable? |
1851 [[NSColor whiteColor] set]; | 1882 [[NSColor whiteColor] set]; |
1852 NSRectFill(dirtyRect); | 1883 NSRectFill(dirtyRect); |
1853 return; | 1884 return; |
1854 } | 1885 } |
1855 | 1886 |
1856 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); | |
1857 | |
1858 if (renderWidgetHostView_->last_frame_was_accelerated_) { | |
1859 // Draw transparency to expose the GL underlay: | |
1860 // TODO(jbates) avoid doing this every frame. | |
1861 [[NSColor clearColor] set]; | |
1862 NSRectFill(dirtyRect); | |
1863 | |
1864 renderWidgetHostView_->compositing_iosurface_->DrawIOSurface(self); | |
1865 renderWidgetHostView_->AckPendingCompositorSwapBuffers(); | |
1866 return; | |
1867 } | |
1868 | |
1869 // In case the last frame was accelerated, ack any pending swaps to unblock | |
1870 // the GPU process. | |
1871 renderWidgetHostView_->AckPendingCompositorSwapBuffers(); | |
1872 | |
1873 DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); | 1887 DCHECK(!renderWidgetHostView_->about_to_validate_and_paint_); |
1874 | 1888 |
| 1889 // GetBackingStore works for both software and accelerated frames. If a |
| 1890 // SwapBuffers occurs while GetBackingStore is blocking, we will continue to |
| 1891 // blit the IOSurface below. |
1875 renderWidgetHostView_->about_to_validate_and_paint_ = true; | 1892 renderWidgetHostView_->about_to_validate_and_paint_ = true; |
1876 BackingStoreMac* backingStore = static_cast<BackingStoreMac*>( | 1893 BackingStoreMac* backingStore = static_cast<BackingStoreMac*>( |
1877 renderWidgetHostView_->render_widget_host_->GetBackingStore(true)); | 1894 renderWidgetHostView_->render_widget_host_->GetBackingStore(true)); |
1878 renderWidgetHostView_->about_to_validate_and_paint_ = false; | 1895 renderWidgetHostView_->about_to_validate_and_paint_ = false; |
1879 | 1896 |
| 1897 const gfx::Rect damagedRect([self flipNSRectToRect:dirtyRect]); |
| 1898 |
| 1899 if (renderWidgetHostView_->last_frame_was_accelerated_ && |
| 1900 renderWidgetHostView_->compositing_iosurface_.get()) { |
| 1901 // Note that this code path is only executed when there's window damage |
| 1902 // (when the window is foregrounded, for example). Normally, GPU frames |
| 1903 // arrive and are drawn during AcceleratedSurfaceBuffersSwapped. |
| 1904 { |
| 1905 TRACE_EVENT0("browser", "NSRectFill"); |
| 1906 // Draw transparency to expose the GL underlay. NSRectFill is extremely |
| 1907 // slow (15ms for a window on a fast MacPro), so this is only done for the |
| 1908 // dirty rect. The composited swap-buffers typically happens outside of |
| 1909 // drawRect to avoid invalidating the entire NSView. |
| 1910 [[NSColor clearColor] set]; |
| 1911 NSRectFill(dirtyRect); |
| 1912 } |
| 1913 |
| 1914 renderWidgetHostView_->compositing_iosurface_->DrawIOSurface(self); |
| 1915 return; |
| 1916 } |
| 1917 |
1880 if (backingStore) { | 1918 if (backingStore) { |
1881 gfx::Rect bitmapRect(0, 0, | 1919 gfx::Rect bitmapRect(0, 0, |
1882 backingStore->size().width(), | 1920 backingStore->size().width(), |
1883 backingStore->size().height()); | 1921 backingStore->size().height()); |
1884 | 1922 |
1885 // Specify the proper y offset to ensure that the view is rooted to the | 1923 // Specify the proper y offset to ensure that the view is rooted to the |
1886 // upper left corner. This can be negative, if the window was resized | 1924 // upper left corner. This can be negative, if the window was resized |
1887 // smaller and the renderer hasn't yet repainted. | 1925 // smaller and the renderer hasn't yet repainted. |
1888 int yOffset = NSHeight([self bounds]) - backingStore->size().height(); | 1926 int yOffset = NSHeight([self bounds]) - backingStore->size().height(); |
1889 | 1927 |
(...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2859 if (!string) return NO; | 2897 if (!string) return NO; |
2860 | 2898 |
2861 // If the user is currently using an IME, confirm the IME input, | 2899 // If the user is currently using an IME, confirm the IME input, |
2862 // and then insert the text from the service, the same as TextEdit and Safari. | 2900 // and then insert the text from the service, the same as TextEdit and Safari. |
2863 [self confirmComposition]; | 2901 [self confirmComposition]; |
2864 [self insertText:string]; | 2902 [self insertText:string]; |
2865 return YES; | 2903 return YES; |
2866 } | 2904 } |
2867 | 2905 |
2868 @end | 2906 @end |
OLD | NEW |