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_aura.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.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/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
14 #include "cc/output/compositor_frame.h" | 14 #include "cc/output/compositor_frame.h" |
15 #include "cc/output/compositor_frame_ack.h" | 15 #include "cc/output/compositor_frame_ack.h" |
16 #include "cc/output/copy_output_request.h" | |
17 #include "cc/output/copy_output_result.h" | |
16 #include "cc/resources/texture_mailbox.h" | 18 #include "cc/resources/texture_mailbox.h" |
17 #include "content/browser/accessibility/browser_accessibility_manager.h" | 19 #include "content/browser/accessibility/browser_accessibility_manager.h" |
18 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 20 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
19 #include "content/browser/renderer_host/backing_store_aura.h" | 21 #include "content/browser/renderer_host/backing_store_aura.h" |
20 #include "content/browser/renderer_host/dip_util.h" | 22 #include "content/browser/renderer_host/dip_util.h" |
21 #include "content/browser/renderer_host/overscroll_controller.h" | 23 #include "content/browser/renderer_host/overscroll_controller.h" |
22 #include "content/browser/renderer_host/render_view_host_delegate.h" | 24 #include "content/browser/renderer_host/render_view_host_delegate.h" |
23 #include "content/browser/renderer_host/render_widget_host_impl.h" | 25 #include "content/browser/renderer_host/render_widget_host_impl.h" |
24 #include "content/browser/renderer_host/touch_smooth_scroll_gesture_aura.h" | 26 #include "content/browser/renderer_host/touch_smooth_scroll_gesture_aura.h" |
25 #include "content/browser/renderer_host/ui_events_helper.h" | 27 #include "content/browser/renderer_host/ui_events_helper.h" |
26 #include "content/browser/renderer_host/web_input_event_aura.h" | 28 #include "content/browser/renderer_host/web_input_event_aura.h" |
27 #include "content/common/gpu/client/gl_helper.h" | 29 #include "content/common/gpu/client/gl_helper.h" |
28 #include "content/common/gpu/gpu_messages.h" | 30 #include "content/common/gpu/gpu_messages.h" |
29 #include "content/common/view_messages.h" | 31 #include "content/common/view_messages.h" |
30 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" | 32 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" |
31 #include "content/port/browser/render_widget_host_view_port.h" | 33 #include "content/port/browser/render_widget_host_view_port.h" |
32 #include "content/public/browser/browser_thread.h" | 34 #include "content/public/browser/browser_thread.h" |
33 #include "content/public/browser/content_browser_client.h" | 35 #include "content/public/browser/content_browser_client.h" |
34 #include "content/public/browser/render_process_host.h" | 36 #include "content/public/browser/render_process_host.h" |
35 #include "content/public/browser/render_view_host.h" | 37 #include "content/public/browser/render_view_host.h" |
36 #include "content/public/browser/user_metrics.h" | 38 #include "content/public/browser/user_metrics.h" |
37 #include "content/public/common/content_switches.h" | 39 #include "content/public/common/content_switches.h" |
38 #include "media/base/video_util.h" | 40 #include "media/base/video_util.h" |
41 #include "skia/ext/image_operations.h" | |
39 #include "third_party/WebKit/public/web/WebCompositionUnderline.h" | 42 #include "third_party/WebKit/public/web/WebCompositionUnderline.h" |
40 #include "third_party/WebKit/public/web/WebInputEvent.h" | 43 #include "third_party/WebKit/public/web/WebInputEvent.h" |
41 #include "third_party/WebKit/public/web/WebScreenInfo.h" | 44 #include "third_party/WebKit/public/web/WebScreenInfo.h" |
42 #include "ui/aura/client/activation_client.h" | 45 #include "ui/aura/client/activation_client.h" |
43 #include "ui/aura/client/aura_constants.h" | 46 #include "ui/aura/client/aura_constants.h" |
44 #include "ui/aura/client/cursor_client.h" | 47 #include "ui/aura/client/cursor_client.h" |
45 #include "ui/aura/client/cursor_client_observer.h" | 48 #include "ui/aura/client/cursor_client_observer.h" |
46 #include "ui/aura/client/focus_client.h" | 49 #include "ui/aura/client/focus_client.h" |
47 #include "ui/aura/client/screen_position_client.h" | 50 #include "ui/aura/client/screen_position_client.h" |
48 #include "ui/aura/client/stacking_client.h" | 51 #include "ui/aura/client/stacking_client.h" |
(...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
941 | 944 |
942 void RenderWidgetHostViewAura::Blur() { | 945 void RenderWidgetHostViewAura::Blur() { |
943 window_->Blur(); | 946 window_->Blur(); |
944 } | 947 } |
945 | 948 |
946 bool RenderWidgetHostViewAura::HasFocus() const { | 949 bool RenderWidgetHostViewAura::HasFocus() const { |
947 return window_->HasFocus(); | 950 return window_->HasFocus(); |
948 } | 951 } |
949 | 952 |
950 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const { | 953 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const { |
951 return current_surface_.get() || current_software_frame_.IsValid() || | 954 return window_->layer()->has_external_content() || |
952 !!host_->GetBackingStore(false); | 955 !!host_->GetBackingStore(false); |
953 } | 956 } |
954 | 957 |
955 void RenderWidgetHostViewAura::Show() { | 958 void RenderWidgetHostViewAura::Show() { |
956 window_->Show(); | 959 window_->Show(); |
957 } | 960 } |
958 | 961 |
959 void RenderWidgetHostViewAura::Hide() { | 962 void RenderWidgetHostViewAura::Hide() { |
960 window_->Hide(); | 963 window_->Hide(); |
961 } | 964 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1158 | 1161 |
1159 BackingStore* RenderWidgetHostViewAura::AllocBackingStore( | 1162 BackingStore* RenderWidgetHostViewAura::AllocBackingStore( |
1160 const gfx::Size& size) { | 1163 const gfx::Size& size) { |
1161 return new BackingStoreAura(host_, size); | 1164 return new BackingStoreAura(host_, size); |
1162 } | 1165 } |
1163 | 1166 |
1164 void RenderWidgetHostViewAura::CopyFromCompositingSurface( | 1167 void RenderWidgetHostViewAura::CopyFromCompositingSurface( |
1165 const gfx::Rect& src_subrect, | 1168 const gfx::Rect& src_subrect, |
1166 const gfx::Size& dst_size, | 1169 const gfx::Size& dst_size, |
1167 const base::Callback<void(bool, const SkBitmap&)>& callback) { | 1170 const base::Callback<void(bool, const SkBitmap&)>& callback) { |
1168 | 1171 if (!window_->layer()->has_external_content()) { |
1169 base::ScopedClosureRunner scoped_callback_runner( | 1172 callback.Run(false, SkBitmap()); |
1170 base::Bind(callback, false, SkBitmap())); | |
1171 if (!current_surface_.get()) | |
1172 return; | 1173 return; |
1174 } | |
1173 | 1175 |
1174 const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size); | 1176 const gfx::Size& dst_size_in_pixel = ConvertViewSizeToPixel(this, dst_size); |
1175 SkBitmap output; | 1177 scoped_ptr<cc::CopyOutputRequest> request = |
1176 output.setConfig(SkBitmap::kARGB_8888_Config, | 1178 cc::CopyOutputRequest::CreateRequest(base::Bind( |
1177 dst_size_in_pixel.width(), dst_size_in_pixel.height()); | 1179 &RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResult, |
1178 if (!output.allocPixels()) | 1180 dst_size_in_pixel, |
1179 return; | 1181 callback)); |
1180 output.setIsOpaque(true); | 1182 request->set_area(src_subrect); |
1181 | 1183 window_->layer()->RequestCopyOfOutput(request.Pass()); |
1182 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | |
1183 GLHelper* gl_helper = factory->GetGLHelper(); | |
1184 if (!gl_helper) | |
1185 return; | |
1186 | |
1187 unsigned char* addr = static_cast<unsigned char*>(output.getPixels()); | |
1188 scoped_callback_runner.Release(); | |
1189 // Wrap the callback with an internal handler so that we can inject our | |
1190 // own completion handlers (where we can try to free the frontbuffer). | |
1191 base::Callback<void(bool)> wrapper_callback = base::Bind( | |
1192 &RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished, | |
1193 output, | |
1194 callback); | |
1195 | |
1196 // Convert |src_subrect| from the views coordinate (upper-left origin) into | |
1197 // the OpenGL coordinate (lower-left origin). | |
1198 gfx::Rect src_subrect_in_gl = src_subrect; | |
1199 src_subrect_in_gl.set_y(GetViewBounds().height() - src_subrect.bottom()); | |
1200 | |
1201 gfx::Rect src_subrect_in_pixel = | |
1202 ConvertRectToPixel(current_surface_->device_scale_factor(), | |
1203 src_subrect_in_gl); | |
1204 gl_helper->CropScaleReadbackAndCleanTexture( | |
1205 current_surface_->PrepareTexture(), | |
1206 current_surface_->size(), | |
1207 src_subrect_in_pixel, | |
1208 dst_size_in_pixel, | |
1209 addr, | |
1210 wrapper_callback); | |
1211 } | 1184 } |
1212 | 1185 |
1213 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame( | 1186 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame( |
1214 const gfx::Rect& src_subrect, | 1187 const gfx::Rect& src_subrect, |
1215 const scoped_refptr<media::VideoFrame>& target, | 1188 const scoped_refptr<media::VideoFrame>& target, |
1216 const base::Callback<void(bool)>& callback) { | 1189 const base::Callback<void(bool)>& callback) { |
1217 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); | 1190 base::ScopedClosureRunner scoped_callback_runner(base::Bind(callback, false)); |
1218 | 1191 |
1219 if (!current_surface_.get()) | 1192 if (!current_surface_.get()) |
1220 return; | 1193 return; |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1652 const gfx::Rect surface_rect = gfx::Rect(surface_size); | 1625 const gfx::Rect surface_rect = gfx::Rect(surface_size); |
1653 | 1626 |
1654 if (!SwapBuffersPrepare(surface_rect, | 1627 if (!SwapBuffersPrepare(surface_rect, |
1655 surface_scale_factor, | 1628 surface_scale_factor, |
1656 damage_rect, | 1629 damage_rect, |
1657 mailbox_name, | 1630 mailbox_name, |
1658 ack_callback)) { | 1631 ack_callback)) { |
1659 return; | 1632 return; |
1660 } | 1633 } |
1661 | 1634 |
1635 DidReceiveRendererFrame(); | |
piman
2013/07/02 01:49:09
For consistency, it's also needed in SwapDelegated
danakj
2013/07/03 18:05:39
Ah, ok I moved it out to the entry point methods i
| |
1636 | |
1662 SkRegion damage(RectToSkIRect(damage_rect)); | 1637 SkRegion damage(RectToSkIRect(damage_rect)); |
1663 if (!skipped_damage_.isEmpty()) { | 1638 if (!skipped_damage_.isEmpty()) { |
1664 damage.op(skipped_damage_, SkRegion::kUnion_Op); | 1639 damage.op(skipped_damage_, SkRegion::kUnion_Op); |
1665 skipped_damage_.setEmpty(); | 1640 skipped_damage_.setEmpty(); |
1666 } | 1641 } |
1667 | 1642 |
1668 DCHECK(surface_rect.Contains(SkIRectToRect(damage.getBounds()))); | 1643 DCHECK(surface_rect.Contains(SkIRectToRect(damage.getBounds()))); |
1669 ui::Texture* current_texture = current_surface_.get(); | 1644 ui::Texture* current_texture = current_surface_.get(); |
1670 | 1645 |
1671 const gfx::Size surface_size_in_pixel = surface_size; | 1646 const gfx::Size surface_size_in_pixel = surface_size; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1758 // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't | 1733 // Aura doesn't use GetBackingStore for accelerated pages, so it doesn't |
1759 // matter what is returned here as GetBackingStore is the only caller of this | 1734 // matter what is returned here as GetBackingStore is the only caller of this |
1760 // method. TODO(jbates) implement this if other Aura code needs it. | 1735 // method. TODO(jbates) implement this if other Aura code needs it. |
1761 return false; | 1736 return false; |
1762 } | 1737 } |
1763 | 1738 |
1764 void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor( | 1739 void RenderWidgetHostViewAura::SetSurfaceNotInUseByCompositor( |
1765 scoped_refptr<ui::Texture>) { | 1740 scoped_refptr<ui::Texture>) { |
1766 } | 1741 } |
1767 | 1742 |
1768 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceFinished( | 1743 // static |
1769 const SkBitmap& bitmap, | 1744 void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResult( |
1745 const gfx::Size& dst_size_in_pixel, | |
1770 const base::Callback<void(bool, const SkBitmap&)>& callback, | 1746 const base::Callback<void(bool, const SkBitmap&)>& callback, |
1747 scoped_ptr<cc::CopyOutputResult> result) { | |
1748 if (result->IsEmpty() || result->size().IsEmpty()) { | |
1749 callback.Run(false, SkBitmap()); | |
1750 return; | |
1751 } | |
1752 | |
1753 if (result->HasTexture()) { | |
1754 PrepareTextureCopyOutputResult(dst_size_in_pixel, callback, result.Pass()); | |
1755 return; | |
1756 } | |
1757 | |
1758 DCHECK(result->HasBitmap()); | |
1759 PrepareBitmapCopyOutputResult(dst_size_in_pixel, callback, result.Pass()); | |
1760 } | |
1761 | |
1762 static void CopyFromCompositingSurfaceFinished( | |
1763 const base::Callback<void(bool, const SkBitmap&)>& callback, | |
1764 scoped_ptr<SkBitmap> bitmap, | |
1765 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, | |
1771 bool result) { | 1766 bool result) { |
1772 callback.Run(result, bitmap); | 1767 bitmap_pixels_lock.reset(); |
1768 callback.Run(result, *bitmap); | |
1769 } | |
1770 | |
1771 // static | |
1772 void RenderWidgetHostViewAura::PrepareTextureCopyOutputResult( | |
1773 const gfx::Size& dst_size_in_pixel, | |
1774 const base::Callback<void(bool, const SkBitmap&)>& callback, | |
1775 scoped_ptr<cc::CopyOutputResult> result) { | |
1776 base::ScopedClosureRunner scoped_callback_runner( | |
1777 base::Bind(callback, false, SkBitmap())); | |
1778 | |
1779 DCHECK(result->HasTexture()); | |
1780 if (!result->HasTexture()) | |
1781 return; | |
1782 | |
1783 scoped_ptr<SkBitmap> bitmap(new SkBitmap); | |
1784 bitmap->setConfig(SkBitmap::kARGB_8888_Config, | |
1785 dst_size_in_pixel.width(), dst_size_in_pixel.height()); | |
1786 if (!bitmap->allocPixels()) | |
1787 return; | |
1788 bitmap->setIsOpaque(true); | |
1789 | |
1790 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); | |
1791 GLHelper* gl_helper = factory->GetGLHelper(); | |
1792 if (!gl_helper) | |
1793 return; | |
1794 | |
1795 scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock( | |
1796 new SkAutoLockPixels(*bitmap)); | |
1797 uint8* pixels = static_cast<uint8*>(bitmap->getPixels()); | |
1798 | |
1799 scoped_ptr<cc::TextureMailbox> texture_mailbox = result->TakeTexture(); | |
1800 DCHECK(texture_mailbox->IsTexture()); | |
1801 if (!texture_mailbox->IsTexture()) | |
1802 return; | |
1803 | |
1804 scoped_callback_runner.Release(); | |
1805 | |
1806 gl_helper->CropScaleReadbackAndCleanMailbox( | |
1807 texture_mailbox->name(), | |
1808 texture_mailbox->sync_point(), | |
1809 result->size(), | |
1810 gfx::Rect(result->size()), | |
1811 dst_size_in_pixel, | |
1812 pixels, | |
1813 base::Bind(&CopyFromCompositingSurfaceFinished, | |
1814 callback, | |
1815 base::Passed(&bitmap), | |
1816 base::Passed(&bitmap_pixels_lock))); | |
1817 } | |
1818 | |
1819 // static | |
1820 void RenderWidgetHostViewAura::PrepareBitmapCopyOutputResult( | |
1821 const gfx::Size& dst_size_in_pixel, | |
1822 const base::Callback<void(bool, const SkBitmap&)>& callback, | |
1823 scoped_ptr<cc::CopyOutputResult> result) { | |
1824 DCHECK(result->HasBitmap()); | |
1825 | |
1826 base::ScopedClosureRunner scoped_callback_runner( | |
1827 base::Bind(callback, false, SkBitmap())); | |
1828 if (!result->HasBitmap()) | |
1829 return; | |
1830 | |
1831 scoped_ptr<SkBitmap> source = result->TakeBitmap(); | |
1832 DCHECK(source); | |
1833 if (!source) | |
1834 return; | |
1835 | |
1836 scoped_callback_runner.Release(); | |
1837 | |
1838 SkBitmap bitmap = skia::ImageOperations::Resize( | |
1839 *source, | |
1840 skia::ImageOperations::RESIZE_BEST, | |
1841 dst_size_in_pixel.width(), | |
1842 dst_size_in_pixel.height()); | |
1843 callback.Run(true, bitmap); | |
1773 } | 1844 } |
1774 | 1845 |
1775 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) { | 1846 void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) { |
1776 GetScreenInfoForWindow(results, window_->GetRootWindow() ? window_ : NULL); | 1847 GetScreenInfoForWindow(results, window_->GetRootWindow() ? window_ : NULL); |
1777 } | 1848 } |
1778 | 1849 |
1779 gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() { | 1850 gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() { |
1780 return window_->GetToplevelWindow()->GetBoundsInScreen(); | 1851 return window_->GetToplevelWindow()->GetBoundsInScreen(); |
1781 } | 1852 } |
1782 | 1853 |
(...skipping 1233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3016 RenderWidgetHost* widget) { | 3087 RenderWidgetHost* widget) { |
3017 return new RenderWidgetHostViewAura(widget); | 3088 return new RenderWidgetHostViewAura(widget); |
3018 } | 3089 } |
3019 | 3090 |
3020 // static | 3091 // static |
3021 void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) { | 3092 void RenderWidgetHostViewPort::GetDefaultScreenInfo(WebScreenInfo* results) { |
3022 GetScreenInfoForWindow(results, NULL); | 3093 GetScreenInfoForWindow(results, NULL); |
3023 } | 3094 } |
3024 | 3095 |
3025 } // namespace content | 3096 } // namespace content |
OLD | NEW |