summaryrefslogtreecommitdiff
path: root/chromium/ui/ozone
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-16 11:45:35 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-17 08:59:23 +0000
commit552906b0f222c5d5dd11b9fd73829d510980461a (patch)
tree3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/ui/ozone
parent1b05827804eaf047779b597718c03e7d38344261 (diff)
downloadqtwebengine-chromium-552906b0f222c5d5dd11b9fd73829d510980461a.tar.gz
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/ui/ozone')
-rw-r--r--chromium/ui/ozone/BUILD.gn36
-rw-r--r--chromium/ui/ozone/common/BUILD.gn8
-rw-r--r--chromium/ui/ozone/common/gl_ozone_egl.cc5
-rw-r--r--chromium/ui/ozone/common/gl_ozone_egl.h9
-rw-r--r--chromium/ui/ozone/common/gl_surface_egl_readback.cc6
-rw-r--r--chromium/ui/ozone/common/gl_surface_egl_readback.h4
-rw-r--r--chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc19
-rw-r--r--chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h31
-rw-r--r--chromium/ui/ozone/common/gpu/ozone_gpu_messages.h38
-rw-r--r--chromium/ui/ozone/common/linux/BUILD.gn42
-rw-r--r--chromium/ui/ozone/common/linux/OWNERS3
-rw-r--r--chromium/ui/ozone/common/linux/drm_util_linux.cc111
-rw-r--r--chromium/ui/ozone/common/linux/drm_util_linux.h20
-rw-r--r--chromium/ui/ozone/common/linux/gbm_buffer.h44
-rw-r--r--chromium/ui/ozone/common/linux/gbm_device.h40
-rw-r--r--chromium/ui/ozone/common/linux/gbm_wrapper.cc334
-rw-r--r--chromium/ui/ozone/common/linux/gbm_wrapper.h18
-rw-r--r--chromium/ui/ozone/common/linux/scoped_gbm_device.cc14
-rw-r--r--chromium/ui/ozone/common/linux/scoped_gbm_device.h22
-rw-r--r--chromium/ui/ozone/demo/BUILD.gn5
-rw-r--r--chromium/ui/ozone/demo/gl_renderer.cc2
-rw-r--r--chromium/ui/ozone/demo/skia/skia_gl_renderer.cc13
-rw-r--r--chromium/ui/ozone/demo/software_renderer.cc4
-rw-r--r--chromium/ui/ozone/demo/surfaceless_gl_renderer.cc2
-rw-r--r--chromium/ui/ozone/demo/vulkan_renderer.cc13
-rw-r--r--chromium/ui/ozone/demo/window_manager.cc4
-rw-r--r--chromium/ui/ozone/gl/BUILD.gn8
-rw-r--r--chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc10
-rw-r--r--chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.cc7
-rw-r--r--chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.h2
-rw-r--r--chromium/ui/ozone/platform/cast/gl_surface_cast.cc2
-rw-r--r--chromium/ui/ozone/platform/cast/gl_surface_cast.h2
-rw-r--r--chromium/ui/ozone/platform/cast/ozone_platform_cast.cc11
-rw-r--r--chromium/ui/ozone/platform/cast/surface_factory_cast.cc8
-rw-r--r--chromium/ui/ozone/platform/cast/surface_factory_cast.h5
-rw-r--r--chromium/ui/ozone/platform/drm/BUILD.gn23
-rw-r--r--chromium/ui/ozone/platform/drm/OWNERS2
-rw-r--r--chromium/ui/ozone/platform/drm/common/drm_util.cc126
-rw-r--r--chromium/ui/ozone/platform/drm/common/drm_util.h15
-rw-r--r--chromium/ui/ozone/platform/drm/common/drm_util_unittest.cc42
-rw-r--r--chromium/ui/ozone/platform/drm/common/scoped_drm_types.cc5
-rw-r--r--chromium/ui/ozone/platform/drm/common/scoped_drm_types.h5
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc45
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/crtc_controller.h14
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_device.cc35
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_device.h12
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_display.cc43
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_display.h1
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.cc34
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.h1
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc27
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h1
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.cc22
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.h3
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_candidates.cc (renamed from chromium/ui/ozone/platform/drm/common/drm_overlay_candidates.cc)4
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_candidates.h (renamed from chromium/ui/ozone/platform/drm/common/drm_overlay_candidates.h)6
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc (renamed from chromium/ui/ozone/platform/drm/common/drm_overlay_manager.cc)43
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager.h (renamed from chromium/ui/ozone/platform/drm/common/drm_overlay_manager.h)16
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc23
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.h7
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_unittest.cc (renamed from chromium/ui/ozone/platform/drm/common/drm_overlay_manager_unittest.cc)7
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc30
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc413
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread.cc103
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread.h29
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc34
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h11
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc32
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h13
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread_unittest.cc25
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_window_unittest.cc7
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/gbm_pixmap.h2
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc92
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.h5
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc10
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc58
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h8
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc262
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.cc1
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h7
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc68
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h40
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc115
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h14
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc31
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h12
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc499
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/mock_drm_device.cc79
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/mock_drm_device.h42
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/mock_gbm_device.cc166
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/mock_gbm_device.h43
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/screen_manager.cc6
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc160
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.cc24
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.h11
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_cursor.cc1
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_device_connector.cc5
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_display_host.cc4
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_display_host.h1
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_display_host_manager.cc11
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_display_host_manager.h4
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc82
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h20
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.cc6
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.h1
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_overlay_manager_host.cc71
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_overlay_manager_host.h60
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_window_host.cc8
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_window_host.h8
-rw-r--r--chromium/ui/ozone/platform/drm/host/gpu_thread_adapter.h14
-rw-r--r--chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc40
-rw-r--r--chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h9
-rw-r--r--chromium/ui/ozone/platform/drm/host/host_drm_device.cc50
-rw-r--r--chromium/ui/ozone/platform/drm/host/host_drm_device.h19
-rw-r--r--chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc38
-rw-r--r--chromium/ui/ozone/platform/headless/headless_surface_factory.cc31
-rw-r--r--chromium/ui/ozone/platform/headless/headless_surface_factory.h5
-rw-r--r--chromium/ui/ozone/platform/headless/ozone_platform_headless.cc5
-rw-r--r--chromium/ui/ozone/platform/scenic/BUILD.gn14
-rw-r--r--chromium/ui/ozone/platform/scenic/ozone_platform_scenic.cc6
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_gpu_host.cc8
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_gpu_host.h2
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_surface.cc6
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_surface.h4
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_surface_factory.cc18
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_surface_factory.h10
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_window.cc70
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_window.h7
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_window_canvas.cc4
-rw-r--r--chromium/ui/ozone/platform/scenic/scenic_window_canvas.h4
-rw-r--r--chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.cc58
-rw-r--r--chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.h11
-rw-r--r--chromium/ui/ozone/platform/wayland/BUILD.gn40
-rw-r--r--chromium/ui/ozone/platform/wayland/DEPS3
-rw-r--r--chromium/ui/ozone/platform/wayland/common/wayland_util.cc21
-rw-r--r--chromium/ui/ozone/platform/wayland/common/wayland_util.h12
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc48
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h5
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc30
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h18
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc178
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h95
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc2
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.h2
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc17
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h8
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc126
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.h9
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc29
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h5
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc376
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h8
-rw-r--r--chromium/ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.cc52
-rw-r--r--chromium/ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.h36
-rw-r--r--chromium/ui/ozone/platform/wayland/host/shell_object_factory.cc47
-rw-r--r--chromium/ui/ozone/platform/wayland/host/shell_object_factory.h44
-rw-r--r--chromium/ui/ozone/platform/wayland/host/shell_popup_wrapper.h6
-rw-r--r--chromium/ui/ozone/platform/wayland/host/shell_surface_wrapper.h4
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc196
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h12
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_clipboard.cc18
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_clipboard.h2
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_connection.cc31
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_connection.h4
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_cursor.cc7
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_cursor.h1
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_data_device.cc2
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_data_device.h2
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc2
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_drm.cc2
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_input_method_context.cc6
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc1
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_keyboard.cc5
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_keyboard.h3
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_pointer.cc2
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc5
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_popup.cc202
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_popup.h49
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc5
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_subsurface.cc130
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_subsurface.h38
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_surface.cc353
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_surface.h127
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_window.cc743
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_window.h170
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_window_factory.cc57
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc15
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_window_unittest.cc597
-rw-r--r--chromium/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc2
-rw-r--r--chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc104
-rw-r--r--chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h23
-rw-r--r--chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc181
-rw-r--r--chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h27
-rw-r--r--chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc47
-rw-r--r--chromium/ui/ozone/platform/wayland/test/mock_surface.cc5
-rw-r--r--chromium/ui/ozone/platform/wayland/test/mock_surface.h19
-rw-r--r--chromium/ui/ozone/platform/wayland/test/mock_wp_presentation.h2
-rw-r--r--chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.cc10
-rw-r--r--chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.h6
-rw-r--r--chromium/ui/ozone/platform/wayland/test/mock_xdg_shell.cc9
-rw-r--r--chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.cc116
-rw-r--r--chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.h69
-rw-r--r--chromium/ui/ozone/platform/wayland/test/test_data_offer.cc5
-rw-r--r--chromium/ui/ozone/platform/wayland/test/test_data_source.cc5
-rw-r--r--chromium/ui/ozone/platform/wayland/test/test_subcompositor.cc2
-rw-r--r--chromium/ui/ozone/platform/wayland/test/test_subsurface.cc16
-rw-r--r--chromium/ui/ozone/platform/wayland/test/test_subsurface.h12
-rw-r--r--chromium/ui/ozone/platform/wayland/test/wayland_test.cc6
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland.gni3
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc283
-rw-r--r--chromium/ui/ozone/platform/windows/ozone_platform_windows.cc4
-rw-r--r--chromium/ui/ozone/platform/windows/windows_surface_factory.cc4
-rw-r--r--chromium/ui/ozone/platform/x11/BUILD.gn17
-rw-r--r--chromium/ui/ozone/platform/x11/DEPS2
-rw-r--r--chromium/ui/ozone/platform/x11/gl_ozone_glx.cc5
-rw-r--r--chromium/ui/ozone/platform/x11/gl_ozone_glx.h1
-rw-r--r--chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.cc2
-rw-r--r--chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.h2
-rw-r--r--chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.cc2
-rw-r--r--chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.h2
-rw-r--r--chromium/ui/ozone/platform/x11/ozone_platform_x11.cc52
-rw-r--r--chromium/ui/ozone/platform/x11/x11_canvas_surface.cc15
-rw-r--r--chromium/ui/ozone/platform/x11/x11_canvas_surface.h8
-rw-r--r--chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.cc20
-rw-r--r--chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h8
-rw-r--r--chromium/ui/ozone/platform/x11/x11_screen_ozone.cc6
-rw-r--r--chromium/ui/ozone/platform/x11/x11_screen_ozone.h3
-rw-r--r--chromium/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc6
-rw-r--r--chromium/ui/ozone/platform/x11/x11_surface_factory.cc9
-rw-r--r--chromium/ui/ozone/platform/x11/x11_surface_factory.h2
-rw-r--r--chromium/ui/ozone/platform/x11/x11_window_ozone.cc62
-rw-r--r--chromium/ui/ozone/platform/x11/x11_window_ozone.h33
-rw-r--r--chromium/ui/ozone/platform/x11/x11_window_ozone_unittest.cc72
-rw-r--r--chromium/ui/ozone/public/DEPS1
-rw-r--r--chromium/ui/ozone/public/cursor_factory_ozone.cc2
-rw-r--r--chromium/ui/ozone/public/cursor_factory_ozone.h3
-rw-r--r--chromium/ui/ozone/public/gl_ozone.h3
-rw-r--r--chromium/ui/ozone/public/gpu_platform_support_host.h2
-rw-r--r--chromium/ui/ozone/public/input_controller.cc4
-rw-r--r--chromium/ui/ozone/public/input_controller.h4
-rw-r--r--chromium/ui/ozone/public/mojom/BUILD.gn39
-rw-r--r--chromium/ui/ozone/public/mojom/drm_device.mojom13
-rw-r--r--chromium/ui/ozone/public/mojom/overlay_surface_candidate.mojom44
-rw-r--r--chromium/ui/ozone/public/mojom/overlay_surface_candidate.typemap16
-rw-r--r--chromium/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h112
-rw-r--r--chromium/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits_unittest.cc84
-rw-r--r--chromium/ui/ozone/public/mojom/scenic_gpu_host.mojom2
-rw-r--r--chromium/ui/ozone/public/mojom/typemaps.gni5
-rw-r--r--chromium/ui/ozone/public/mojom/wayland/BUILD.gn4
-rw-r--r--chromium/ui/ozone/public/mojom/wayland/wayland_buffer_manager.mojom4
-rw-r--r--chromium/ui/ozone/public/overlay_surface_candidate.cc5
-rw-r--r--chromium/ui/ozone/public/overlay_surface_candidate.h13
-rw-r--r--chromium/ui/ozone/public/ozone_platform.h13
-rw-r--r--chromium/ui/ozone/public/platform_screen.cc17
-rw-r--r--chromium/ui/ozone/public/platform_screen.h13
-rw-r--r--chromium/ui/ozone/public/surface_factory_ozone.cc5
-rw-r--r--chromium/ui/ozone/public/surface_factory_ozone.h21
-rw-r--r--chromium/ui/ozone/public/surface_ozone_canvas.h9
-rw-r--r--chromium/ui/ozone/testhelpers/BUILD.gn4
259 files changed, 5966 insertions, 4404 deletions
diff --git a/chromium/ui/ozone/BUILD.gn b/chromium/ui/ozone/BUILD.gn
index bd18c574998..7e53cb2a7ac 100644
--- a/chromium/ui/ozone/BUILD.gn
+++ b/chromium/ui/ozone/BUILD.gn
@@ -85,6 +85,7 @@ jumbo_component("ozone_base") {
"public/ozone_switches.cc",
"public/ozone_switches.h",
"public/platform_clipboard.h",
+ "public/platform_screen.cc",
"public/platform_screen.h",
"public/platform_window_surface.h",
"public/surface_factory_ozone.cc",
@@ -103,6 +104,7 @@ jumbo_component("ozone_base") {
"//ipc",
"//skia",
"//ui/base/clipboard:clipboard_types",
+ "//ui/base/mojom:cursor_type",
"//ui/display",
"//ui/display/types",
"//ui/display/util",
@@ -126,6 +128,7 @@ jumbo_component("ozone_base") {
# Everyone should depend on //ui/ozone instead except a handful of
# things that would otherwise create a cycle.
"//ui/base",
+ "//ui/base/cursor",
"//ui/events/ozone/*",
"//ui/ozone/common/*",
"//ui/ozone/public/mojom",
@@ -220,20 +223,15 @@ jumbo_source_set("test_support_internal") {
"//testing/gtest",
"//ui/gfx:test_support",
"//ui/gfx/geometry",
- "//ui/ozone/public/mojom:mojom_trait_unit_test",
"//ui/platform_window:platform_window",
]
- public_deps = [
- "//base/test:test_support",
- ]
+ public_deps = [ "//base/test:test_support" ]
}
jumbo_static_library("test_support") {
testonly = true
- public_deps = [
- ":test_support_internal",
- ]
+ public_deps = [ ":test_support_internal" ]
}
action("generate_ozone_platform_list") {
@@ -258,12 +256,8 @@ action("generate_ozone_platform_list") {
action("generate_constructor_list") {
script = "generate_constructor_list.py"
- inputs = [
- platform_list_txt_file,
- ]
- outputs = [
- constructor_list_cc_file,
- ]
+ inputs = [ platform_list_txt_file ]
+ outputs = [ constructor_list_cc_file ]
args = [
"--platform_list=" + rebase_path(platform_list_txt_file, root_build_dir),
@@ -276,15 +270,11 @@ action("generate_constructor_list") {
"--include=\"ui/ozone/public/ozone_platform.h\"",
]
- deps = [
- ":generate_ozone_platform_list",
- ]
+ deps = [ ":generate_ozone_platform_list" ]
}
test("ozone_unittests") {
- deps = [
- ":test_support",
- ]
+ deps = [ ":test_support" ]
# Add tests of platform internals.
deps += ozone_platform_test_deps
@@ -293,18 +283,14 @@ test("ozone_unittests") {
# 2nd copy of any code via the component.
assert_no_deps = [ "//ui/ozone" ]
- data_deps = [
- "//testing/buildbot/filters:ozone_unittests_filters",
- ]
+ data_deps = [ "//testing/buildbot/filters:ozone_unittests_filters" ]
}
# X11 backend has its own test suite only built when we are using the x11
# backend.
if (ozone_platform_x11) {
test("ozone_x11_unittests") {
- deps = [
- ":test_support",
- ]
+ deps = [ ":test_support" ]
deps += [ "platform/x11:x11_unittests" ]
diff --git a/chromium/ui/ozone/common/BUILD.gn b/chromium/ui/ozone/common/BUILD.gn
index 562057e9bdd..05f34b34014 100644
--- a/chromium/ui/ozone/common/BUILD.gn
+++ b/chromium/ui/ozone/common/BUILD.gn
@@ -24,9 +24,7 @@ source_set("common") {
"stub_overlay_manager.h",
]
- public_deps = [
- "//ui/ozone:ozone_base",
- ]
+ public_deps = [ "//ui/ozone:ozone_base" ]
deps = [
"//ui/gfx/ipc/color",
@@ -34,9 +32,7 @@ source_set("common") {
"//ui/gl:buildflags",
]
- data_deps = [
- "//third_party/mesa_headers",
- ]
+ data_deps = [ "//third_party/mesa_headers" ]
visibility = [ "//ui/ozone/platform/*" ]
diff --git a/chromium/ui/ozone/common/gl_ozone_egl.cc b/chromium/ui/ozone/common/gl_ozone_egl.cc
index b9f6aa7213a..7c2758ca8b8 100644
--- a/chromium/ui/ozone/common/gl_ozone_egl.cc
+++ b/chromium/ui/ozone/common/gl_ozone_egl.cc
@@ -35,11 +35,6 @@ bool GLOzoneEGL::InitializeStaticGLBindings(
return true;
}
-void GLOzoneEGL::InitializeLogGLBindings() {
- gl::InitializeLogGLBindingsGL();
- gl::InitializeLogGLBindingsEGL();
-}
-
void GLOzoneEGL::SetDisabledExtensionsPlatform(
const std::string& disabled_extensions) {
gl::SetDisabledExtensionsEGL(disabled_extensions);
diff --git a/chromium/ui/ozone/common/gl_ozone_egl.h b/chromium/ui/ozone/common/gl_ozone_egl.h
index e2889bf50b9..ec8768347c3 100644
--- a/chromium/ui/ozone/common/gl_ozone_egl.h
+++ b/chromium/ui/ozone/common/gl_ozone_egl.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "third_party/khronos/EGL/eglplatform.h"
#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface_egl.h"
#include "ui/ozone/public/gl_ozone.h"
namespace ui {
@@ -22,7 +23,6 @@ class GLOzoneEGL : public GLOzone {
// GLOzone:
bool InitializeGLOneOffPlatform() override;
bool InitializeStaticGLBindings(gl::GLImplementation implementation) override;
- void InitializeLogGLBindings() override;
void SetDisabledExtensionsPlatform(
const std::string& disabled_extensions) override;
bool InitializeExtensionSettingsOneOffPlatform() override;
@@ -42,9 +42,10 @@ class GLOzoneEGL : public GLOzone {
const gfx::Size& size) override = 0;
protected:
- // Returns native platform display handle. This is used to obtain the EGL
- // display connection for the native display.
- virtual EGLNativeDisplayType GetNativeDisplay() = 0;
+ // Returns native platform display handle and platform type as per
+ // EGL platform extensions.
+ // This is used to obtain the EGL display connection for the native display.
+ virtual gl::EGLDisplayPlatform GetNativeDisplay() = 0;
// Sets up GL bindings for the native surface.
virtual bool LoadGLES2Bindings(gl::GLImplementation implementation) = 0;
diff --git a/chromium/ui/ozone/common/gl_surface_egl_readback.cc b/chromium/ui/ozone/common/gl_surface_egl_readback.cc
index fd21b8926d6..4f15ad6fb0d 100644
--- a/chromium/ui/ozone/common/gl_surface_egl_readback.cc
+++ b/chromium/ui/ozone/common/gl_surface_egl_readback.cc
@@ -23,7 +23,7 @@ GLSurfaceEglReadback::GLSurfaceEglReadback()
bool GLSurfaceEglReadback::Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) {
pixels_.reset();
@@ -62,8 +62,8 @@ gfx::SwapResult GLSurfaceEglReadback::SwapBuffers(
return swap_result;
}
-bool GLSurfaceEglReadback::FlipsVertically() const {
- return true;
+gfx::SurfaceOrigin GLSurfaceEglReadback::GetOrigin() const {
+ return gfx::SurfaceOrigin::kTopLeft;
}
GLSurfaceEglReadback::~GLSurfaceEglReadback() {
diff --git a/chromium/ui/ozone/common/gl_surface_egl_readback.h b/chromium/ui/ozone/common/gl_surface_egl_readback.h
index c985eb52338..d25c12da865 100644
--- a/chromium/ui/ozone/common/gl_surface_egl_readback.h
+++ b/chromium/ui/ozone/common/gl_surface_egl_readback.h
@@ -28,11 +28,11 @@ class GLSurfaceEglReadback : public gl::PbufferGLSurfaceEGL {
// GLSurface implementation.
bool Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) override;
bool IsOffscreen() override;
gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
- bool FlipsVertically() const override;
+ gfx::SurfaceOrigin GetOrigin() const override;
// TODO(kylechar): Implement SupportsPostSubBuffer() and PostSubBuffer().
diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc
index 72d40a9990d..48aaeefd2ca 100644
--- a/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc
+++ b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.cc
@@ -7,7 +7,6 @@
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
#include "ui/gfx/ipc/skia/gfx_skia_param_traits.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
namespace ui {
@@ -22,22 +21,4 @@ DisplaySnapshot_Params::DisplaySnapshot_Params(
DisplaySnapshot_Params::~DisplaySnapshot_Params() {}
-OverlayCheck_Params::OverlayCheck_Params() {}
-
-OverlayCheck_Params::OverlayCheck_Params(
- const ui::OverlaySurfaceCandidate& candidate)
- : buffer_size(candidate.buffer_size),
- transform(candidate.transform),
- format(candidate.format),
- display_rect(gfx::ToNearestRect(candidate.display_rect)),
- crop_rect(candidate.crop_rect),
- is_opaque(candidate.is_opaque),
- plane_z_order(candidate.plane_z_order),
- is_overlay_candidate(candidate.overlay_handled) {}
-
-OverlayCheck_Params::OverlayCheck_Params(const OverlayCheck_Params& other) =
- default;
-
-OverlayCheck_Params::~OverlayCheck_Params() {}
-
} // namespace ui
diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h
index efd3ceb7cbc..128252e7d26 100644
--- a/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h
+++ b/chromium/ui/ozone/common/gpu/ozone_gpu_message_params.h
@@ -16,12 +16,8 @@
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/overlay_transform.h"
-#include "ui/ozone/public/overlay_candidates_ozone.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
namespace ui {
-class OverlaySurfaceCandidate;
struct DisplayMode_Params {
DisplayMode_Params();
@@ -43,6 +39,8 @@ struct DisplaySnapshot_Params {
display::DisplayConnectionType type = display::DISPLAY_CONNECTION_TYPE_NONE;
bool is_aspect_preserving_scaling = false;
bool has_overscan = false;
+ display::PrivacyScreenState privacy_screen_state =
+ display::PrivacyScreenState::kNotSupported;
bool has_color_correction_matrix = false;
bool color_correction_in_linear_space = false;
gfx::ColorSpace color_space;
@@ -62,31 +60,6 @@ struct DisplaySnapshot_Params {
gfx::Size maximum_cursor_size;
};
-struct OverlayCheck_Params {
- OverlayCheck_Params();
- OverlayCheck_Params(const OverlaySurfaceCandidate& candidate);
- OverlayCheck_Params(const OverlayCheck_Params& other);
- ~OverlayCheck_Params();
-
- gfx::Size buffer_size;
- gfx::OverlayTransform transform = gfx::OVERLAY_TRANSFORM_NONE;
- gfx::BufferFormat format = gfx::BufferFormat::BGRA_8888;
- gfx::Rect display_rect;
- gfx::RectF crop_rect;
- bool is_opaque = false;
- int plane_z_order = 0;
- // By default we mark this configuration valid for promoting it to an overlay.
- bool is_overlay_candidate = true;
-};
-
-struct OverlayCheckReturn_Params {
- OverlayCheckReturn_Params() = default;
- OverlayCheckReturn_Params(const OverlayCheckReturn_Params& other) = default;
- ~OverlayCheckReturn_Params() = default;
-
- OverlayStatus status = OVERLAY_STATUS_PENDING;
-};
-
} // namespace ui
#endif // UI_OZONE_COMMON_GPU_OZONE_GPU_MESSAGE_PARAMS_H_
diff --git a/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h b/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h
index fd9813f25c2..74caeb476cb 100644
--- a/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h
+++ b/chromium/ui/ozone/common/gpu/ozone_gpu_messages.h
@@ -5,6 +5,7 @@
// Multiply-included message file, hence no include guard here, but see below
// for a much smaller-than-usual include guard section.
// no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
#include <stdint.h>
@@ -38,9 +39,8 @@ IPC_ENUM_TRAITS_MAX_VALUE(display::HDCPState, display::HDCP_STATE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(display::PanelOrientation,
display::PanelOrientation::kLast)
-IPC_ENUM_TRAITS_MAX_VALUE(gfx::OverlayTransform, gfx::OVERLAY_TRANSFORM_LAST)
-
-IPC_ENUM_TRAITS_MAX_VALUE(ui::OverlayStatus, ui::OVERLAY_STATUS_LAST)
+IPC_ENUM_TRAITS_MAX_VALUE(display::PrivacyScreenState,
+ display::PrivacyScreenState::kPrivacyScreenStateLast)
// clang-format off
IPC_STRUCT_TRAITS_BEGIN(ui::DisplayMode_Params)
@@ -56,6 +56,7 @@ IPC_STRUCT_TRAITS_BEGIN(ui::DisplaySnapshot_Params)
IPC_STRUCT_TRAITS_MEMBER(type)
IPC_STRUCT_TRAITS_MEMBER(is_aspect_preserving_scaling)
IPC_STRUCT_TRAITS_MEMBER(has_overscan)
+ IPC_STRUCT_TRAITS_MEMBER(privacy_screen_state)
IPC_STRUCT_TRAITS_MEMBER(has_color_correction_matrix)
IPC_STRUCT_TRAITS_MEMBER(color_correction_in_linear_space)
IPC_STRUCT_TRAITS_MEMBER(color_space)
@@ -79,22 +80,6 @@ IPC_STRUCT_TRAITS_BEGIN(display::GammaRampRGBEntry)
IPC_STRUCT_TRAITS_MEMBER(g)
IPC_STRUCT_TRAITS_MEMBER(b)
IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(ui::OverlayCheck_Params)
- IPC_STRUCT_TRAITS_MEMBER(buffer_size)
- IPC_STRUCT_TRAITS_MEMBER(transform)
- IPC_STRUCT_TRAITS_MEMBER(format)
- IPC_STRUCT_TRAITS_MEMBER(display_rect)
- IPC_STRUCT_TRAITS_MEMBER(crop_rect)
- IPC_STRUCT_TRAITS_MEMBER(is_opaque)
- IPC_STRUCT_TRAITS_MEMBER(plane_z_order)
- IPC_STRUCT_TRAITS_MEMBER(is_overlay_candidate)
-IPC_STRUCT_TRAITS_END()
-
-IPC_STRUCT_TRAITS_BEGIN(ui::OverlayCheckReturn_Params)
- IPC_STRUCT_TRAITS_MEMBER(status)
-IPC_STRUCT_TRAITS_END()
-
// clang-format on
//------------------------------------------------------------------------------
@@ -170,10 +155,10 @@ IPC_MESSAGE_CONTROL3(OzoneGpuMsg_SetGammaCorrection,
std::vector<display::GammaRampRGBEntry>, // Degamma lut
std::vector<display::GammaRampRGBEntry>) // Gamma lut
-IPC_MESSAGE_CONTROL2(OzoneGpuMsg_CheckOverlayCapabilities,
- gfx::AcceleratedWidget /* widget */,
- std::vector<ui::OverlayCheck_Params> /* overlays */)
-
+// Set the privacy screen state of the display with |display_id|
+IPC_MESSAGE_CONTROL2(OzoneGpuMsg_SetPrivacyScreen,
+ int64_t /* display_id */,
+ bool /* enabled */)
//------------------------------------------------------------------------------
// Browser Messages
// These messages are from the GPU to the browser process.
@@ -203,10 +188,3 @@ IPC_MESSAGE_CONTROL1(OzoneHostMsg_DisplayControlTaken, bool /* success */)
// Response to OzoneGpuMsg_RelinquishDisplayControl.
IPC_MESSAGE_CONTROL1(OzoneHostMsg_DisplayControlRelinquished,
bool /* success */)
-
-// Response to OzoneGpuMsg_CheckOverlayCapabilities. Returns list of supported
-// params.
-IPC_MESSAGE_CONTROL3(OzoneHostMsg_OverlayCapabilitiesReceived,
- gfx::AcceleratedWidget /* widget */,
- std::vector<ui::OverlayCheck_Params> /* overlays */,
- std::vector<ui::OverlayCheckReturn_Params> /* returns */)
diff --git a/chromium/ui/ozone/common/linux/BUILD.gn b/chromium/ui/ozone/common/linux/BUILD.gn
deleted file mode 100644
index 7628646fe97..00000000000
--- a/chromium/ui/ozone/common/linux/BUILD.gn
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2018 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/ui.gni")
-import("//ui/ozone/ozone.gni")
-
-assert(ozone_platform_gbm || ozone_platform_wayland)
-
-source_set("drm") {
- sources = [
- "drm_util_linux.cc",
- "drm_util_linux.h",
- ]
-
- deps = [
- "//base:base",
- "//build/config/linux/libdrm",
- "//ui/gfx:buffer_types",
- ]
-}
-
-source_set("gbm") {
- sources = [
- "gbm_buffer.h",
- "gbm_device.h",
- "gbm_wrapper.cc",
- "scoped_gbm_device.cc",
- "scoped_gbm_device.h",
- ]
-
- deps = [
- ":drm",
- "//base:base",
- "//build/config/linux/libdrm",
- "//third_party/minigbm",
- "//ui/gfx:buffer_types",
- "//ui/gfx:memory_buffer",
- "//ui/gfx/geometry:geometry",
- "//ui/ozone:ozone_base",
- ]
-}
diff --git a/chromium/ui/ozone/common/linux/OWNERS b/chromium/ui/ozone/common/linux/OWNERS
deleted file mode 100644
index d047913b027..00000000000
--- a/chromium/ui/ozone/common/linux/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-dcastagna@chromium.org
-dnicoara@chromium.org
-msisov@igalia.com
diff --git a/chromium/ui/ozone/common/linux/drm_util_linux.cc b/chromium/ui/ozone/common/linux/drm_util_linux.cc
deleted file mode 100644
index 7cb7b4ebe5d..00000000000
--- a/chromium/ui/ozone/common/linux/drm_util_linux.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/common/linux/drm_util_linux.h"
-
-#include <drm_fourcc.h>
-
-#include "base/logging.h"
-
-#ifndef DRM_FORMAT_INVALID
-// TODO(mcasas): Remove when uprevving //third_party/libdrm.
-#define DRM_FORMAT_INVALID 0
-#endif
-
-#ifndef DRM_FORMAT_P010
-#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0')
-#endif
-
-namespace ui {
-
-int GetFourCCFormatFromBufferFormat(gfx::BufferFormat format) {
- switch (format) {
- case gfx::BufferFormat::R_8:
- return DRM_FORMAT_R8;
- case gfx::BufferFormat::R_16:
- return DRM_FORMAT_R16;
- case gfx::BufferFormat::RG_88:
- return DRM_FORMAT_GR88;
- case gfx::BufferFormat::BGR_565:
- return DRM_FORMAT_RGB565;
- case gfx::BufferFormat::RGBA_4444:
- return DRM_FORMAT_INVALID;
- case gfx::BufferFormat::RGBA_8888:
- return DRM_FORMAT_ABGR8888;
- case gfx::BufferFormat::RGBX_8888:
- return DRM_FORMAT_XBGR8888;
- case gfx::BufferFormat::BGRA_8888:
- return DRM_FORMAT_ARGB8888;
- case gfx::BufferFormat::BGRX_8888:
- return DRM_FORMAT_XRGB8888;
- case gfx::BufferFormat::BGRX_1010102:
- return DRM_FORMAT_XRGB2101010;
- case gfx::BufferFormat::RGBX_1010102:
- return DRM_FORMAT_XBGR2101010;
- case gfx::BufferFormat::RGBA_F16:
- return DRM_FORMAT_INVALID;
- case gfx::BufferFormat::YVU_420:
- return DRM_FORMAT_YVU420;
- case gfx::BufferFormat::YUV_420_BIPLANAR:
- return DRM_FORMAT_NV12;
- case gfx::BufferFormat::P010:
- return DRM_FORMAT_P010;
- }
- return DRM_FORMAT_INVALID;
-}
-
-gfx::BufferFormat GetBufferFormatFromFourCCFormat(int format) {
- switch (format) {
- case DRM_FORMAT_R8:
- return gfx::BufferFormat::R_8;
- case DRM_FORMAT_GR88:
- return gfx::BufferFormat::RG_88;
- case DRM_FORMAT_ABGR8888:
- return gfx::BufferFormat::RGBA_8888;
- case DRM_FORMAT_XBGR8888:
- return gfx::BufferFormat::RGBX_8888;
- case DRM_FORMAT_ARGB8888:
- return gfx::BufferFormat::BGRA_8888;
- case DRM_FORMAT_XRGB8888:
- return gfx::BufferFormat::BGRX_8888;
- case DRM_FORMAT_XRGB2101010:
- return gfx::BufferFormat::BGRX_1010102;
- case DRM_FORMAT_XBGR2101010:
- return gfx::BufferFormat::RGBX_1010102;
- case DRM_FORMAT_RGB565:
- return gfx::BufferFormat::BGR_565;
- case DRM_FORMAT_NV12:
- return gfx::BufferFormat::YUV_420_BIPLANAR;
- case DRM_FORMAT_YVU420:
- return gfx::BufferFormat::YVU_420;
- case DRM_FORMAT_P010:
- return gfx::BufferFormat::P010;
- default:
- NOTREACHED();
- return gfx::BufferFormat::BGRA_8888;
- }
-}
-
-bool IsValidBufferFormat(uint32_t current_format) {
- switch (current_format) {
- case DRM_FORMAT_R8:
- case DRM_FORMAT_GR88:
- case DRM_FORMAT_ABGR8888:
- case DRM_FORMAT_XBGR8888:
- case DRM_FORMAT_ARGB8888:
- case DRM_FORMAT_XRGB8888:
- case DRM_FORMAT_XRGB2101010:
- case DRM_FORMAT_XBGR2101010:
- case DRM_FORMAT_RGB565:
- case DRM_FORMAT_NV12:
- case DRM_FORMAT_YVU420:
- case DRM_FORMAT_P010:
- return true;
- default:
- return false;
- }
- return false;
-}
-
-} // namespace ui
diff --git a/chromium/ui/ozone/common/linux/drm_util_linux.h b/chromium/ui/ozone/common/linux/drm_util_linux.h
deleted file mode 100644
index 78705b910e7..00000000000
--- a/chromium/ui/ozone/common/linux/drm_util_linux.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_COMMON_LINUX_DRM_UTIL_LINUX_H_
-#define UI_OZONE_COMMON_LINUX_DRM_UTIL_LINUX_H_
-
-#include "ui/gfx/buffer_types.h"
-
-namespace ui {
-
-int GetFourCCFormatFromBufferFormat(gfx::BufferFormat format);
-gfx::BufferFormat GetBufferFormatFromFourCCFormat(int format);
-
-// Returns true if the fourcc format is known.
-bool IsValidBufferFormat(uint32_t current_format);
-
-} // namespace ui
-
-#endif // UI_OZONE_COMMON_LINUX_DRM_UTIL_LINUX_H__
diff --git a/chromium/ui/ozone/common/linux/gbm_buffer.h b/chromium/ui/ozone/common/linux/gbm_buffer.h
deleted file mode 100644
index 2c7d8039fb1..00000000000
--- a/chromium/ui/ozone/common/linux/gbm_buffer.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_COMMON_LINUX_GBM_BUFFER_H_
-#define UI_OZONE_COMMON_LINUX_GBM_BUFFER_H_
-
-#include <inttypes.h>
-
-#include "third_party/skia/include/core/SkRefCnt.h"
-#include "ui/gfx/buffer_types.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/native_pixmap_handle.h"
-
-class SkSurface;
-
-namespace ui {
-
-class GbmBuffer {
- public:
- virtual ~GbmBuffer() {}
-
- virtual uint32_t GetFormat() const = 0;
- virtual uint64_t GetFormatModifier() const = 0;
- virtual uint32_t GetFlags() const = 0;
- // TODO(reveman): This should not be needed once crbug.com/597932 is
- // fixed, as the size would be queried directly from the underlying bo.
- virtual gfx::Size GetSize() const = 0;
- virtual gfx::BufferFormat GetBufferFormat() const = 0;
- virtual bool AreFdsValid() const = 0;
- virtual size_t GetNumPlanes() const = 0;
- virtual int GetPlaneFd(size_t plane) const = 0;
- virtual uint32_t GetPlaneHandle(size_t plane) const = 0;
- virtual uint32_t GetPlaneStride(size_t plane) const = 0;
- virtual size_t GetPlaneOffset(size_t plane) const = 0;
- virtual size_t GetPlaneSize(size_t plane) const = 0;
- virtual uint32_t GetHandle() const = 0;
- virtual gfx::NativePixmapHandle ExportHandle() const = 0;
- virtual sk_sp<SkSurface> GetSurface() = 0;
-};
-
-} // namespace ui
-
-#endif // UI_OZONE_COMMON_LINUX_GBM_BUFFER_H_
diff --git a/chromium/ui/ozone/common/linux/gbm_device.h b/chromium/ui/ozone/common/linux/gbm_device.h
deleted file mode 100644
index 84a43d361b9..00000000000
--- a/chromium/ui/ozone/common/linux/gbm_device.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_COMMON_LINUX_GBM_DEVICE_H_
-#define UI_OZONE_COMMON_LINUX_GBM_DEVICE_H_
-
-#include <gbm.h>
-#include <memory>
-
-#include "base/files/file.h"
-#include "base/macros.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/native_pixmap_handle.h"
-
-namespace ui {
-
-class GbmBuffer;
-
-class GbmDevice {
- public:
- virtual ~GbmDevice() {}
-
- virtual std::unique_ptr<GbmBuffer> CreateBuffer(uint32_t format,
- const gfx::Size& size,
- uint32_t flags) = 0;
- virtual std::unique_ptr<GbmBuffer> CreateBufferWithModifiers(
- uint32_t format,
- const gfx::Size& size,
- uint32_t flags,
- const std::vector<uint64_t>& modifiers) = 0;
- virtual std::unique_ptr<GbmBuffer> CreateBufferFromHandle(
- uint32_t format,
- const gfx::Size& size,
- gfx::NativePixmapHandle handle) = 0;
-};
-
-} // namespace ui
-
-#endif // UI_OZONE_COMMON_LINUX_GBM_DEVICE_H_
diff --git a/chromium/ui/ozone/common/linux/gbm_wrapper.cc b/chromium/ui/ozone/common/linux/gbm_wrapper.cc
deleted file mode 100644
index 00970e3e3c2..00000000000
--- a/chromium/ui/ozone/common/linux/gbm_wrapper.cc
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/common/linux/gbm_wrapper.h"
-
-#include <gbm.h>
-#include <memory>
-#include <utility>
-
-#include "base/posix/eintr_wrapper.h"
-#include "third_party/skia/include/core/SkSurface.h"
-#include "ui/gfx/buffer_format_util.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
-#include "ui/ozone/common/linux/gbm_device.h"
-
-#if !defined(MINIGBM)
-#include <fcntl.h>
-#include <xf86drm.h>
-#endif
-
-namespace gbm_wrapper {
-
-namespace {
-
-int GetPlaneFdForBo(gbm_bo* bo, size_t plane) {
-#if defined(MINIGBM)
- return gbm_bo_get_plane_fd(bo, plane);
-#else
- const int plane_count = gbm_bo_get_plane_count(bo);
- DCHECK(plane_count > 0 && plane < static_cast<size_t>(plane_count));
-
- // System linux gbm (or Mesa gbm) does not provide fds per plane basis. Thus,
- // get plane handle and use drm ioctl to get a prime fd out of it avoid having
- // two different branches for minigbm and Mesa gbm here.
- gbm_device* gbm_dev = gbm_bo_get_device(bo);
- int dev_fd = gbm_device_get_fd(gbm_dev);
- DCHECK_GE(dev_fd, 0);
-
- const uint32_t plane_handle = gbm_bo_get_handle_for_plane(bo, plane).u32;
- int fd = -1;
- int ret;
- // Use DRM_RDWR to allow the fd to be mappable in another process.
- ret = drmPrimeHandleToFD(dev_fd, plane_handle, DRM_CLOEXEC | DRM_RDWR, &fd);
-
- // Older DRM implementations blocked DRM_RDWR, but gave a read/write mapping
- // anyways
- if (ret)
- ret = drmPrimeHandleToFD(dev_fd, plane_handle, DRM_CLOEXEC, &fd);
-
- return ret ? ret : fd;
-#endif
-}
-
-size_t GetSizeOfPlane(gbm_bo* bo,
- uint32_t format,
- const gfx::Size& size,
- size_t plane) {
-#if defined(MINIGBM)
- return gbm_bo_get_plane_size(bo, plane);
-#else
- DCHECK(!size.IsEmpty());
-
- // Get row size of the plane, stride and subsampled height to finally get the
- // size of a plane in bytes.
- const gfx::BufferFormat buffer_format =
- ui::GetBufferFormatFromFourCCFormat(format);
- const base::CheckedNumeric<size_t> stride_for_plane =
- gbm_bo_get_stride_for_plane(bo, plane);
- const base::CheckedNumeric<size_t> subsampled_height =
- size.height() /
- gfx::SubsamplingFactorForBufferFormat(buffer_format, plane);
-
- // Apply subsampling factor to get size in bytes.
- const base::CheckedNumeric<size_t> checked_plane_size =
- subsampled_height * stride_for_plane;
-
- return checked_plane_size.ValueOrDie();
-#endif
-}
-
-} // namespace
-
-class Buffer final : public ui::GbmBuffer {
- public:
- Buffer(struct gbm_bo* bo,
- uint32_t format,
- uint32_t flags,
- uint64_t modifier,
- const gfx::Size& size,
- gfx::NativePixmapHandle handle)
- : bo_(bo),
- format_(format),
- format_modifier_(modifier),
- flags_(flags),
- size_(size),
- handle_(std::move(handle)) {}
-
- ~Buffer() override {
- DCHECK(!mmap_data_);
- gbm_bo_destroy(bo_);
- }
-
- uint32_t GetFormat() const override { return format_; }
- uint64_t GetFormatModifier() const override { return format_modifier_; }
- uint32_t GetFlags() const override { return flags_; }
- // TODO(reveman): This should not be needed once crbug.com/597932 is fixed,
- // as the size would be queried directly from the underlying bo.
- gfx::Size GetSize() const override { return size_; }
- gfx::BufferFormat GetBufferFormat() const override {
- return ui::GetBufferFormatFromFourCCFormat(format_);
- }
- bool AreFdsValid() const override {
- if (handle_.planes.empty())
- return false;
-
- for (const auto& plane : handle_.planes) {
- if (!plane.fd.is_valid())
- return false;
- }
- return true;
- }
- size_t GetNumPlanes() const override { return handle_.planes.size(); }
- int GetPlaneFd(size_t plane) const override {
- DCHECK_LT(plane, handle_.planes.size());
- return handle_.planes[plane].fd.get();
- }
- uint32_t GetPlaneStride(size_t plane) const override {
- DCHECK_LT(plane, handle_.planes.size());
- return handle_.planes[plane].stride;
- }
- size_t GetPlaneOffset(size_t plane) const override {
- DCHECK_LT(plane, handle_.planes.size());
- return handle_.planes[plane].offset;
- }
- size_t GetPlaneSize(size_t plane) const override {
- DCHECK_LT(plane, handle_.planes.size());
- return static_cast<size_t>(handle_.planes[plane].size);
- }
- uint32_t GetPlaneHandle(size_t plane) const override {
- DCHECK_LT(plane, handle_.planes.size());
- return gbm_bo_get_handle_for_plane(bo_, plane).u32;
- }
- uint32_t GetHandle() const override { return gbm_bo_get_handle(bo_).u32; }
- gfx::NativePixmapHandle ExportHandle() const override {
- return CloneHandleForIPC(handle_);
- }
-
- sk_sp<SkSurface> GetSurface() override {
- DCHECK(!mmap_data_);
- uint32_t stride;
- void* addr;
- addr =
-#if defined(MINIGBM)
- gbm_bo_map(bo_, 0, 0, gbm_bo_get_width(bo_), gbm_bo_get_height(bo_),
- GBM_BO_TRANSFER_READ_WRITE, &stride, &mmap_data_, 0);
-#else
- gbm_bo_map(bo_, 0, 0, gbm_bo_get_width(bo_), gbm_bo_get_height(bo_),
- GBM_BO_TRANSFER_READ_WRITE, &stride, &mmap_data_);
-#endif
-
- if (!addr)
- return nullptr;
- SkImageInfo info =
- SkImageInfo::MakeN32Premul(size_.width(), size_.height());
- return SkSurface::MakeRasterDirectReleaseProc(info, addr, stride,
- &Buffer::UnmapGbmBo, this);
- }
-
- private:
- static void UnmapGbmBo(void* pixels, void* context) {
- Buffer* buffer = static_cast<Buffer*>(context);
- gbm_bo_unmap(buffer->bo_, buffer->mmap_data_);
- buffer->mmap_data_ = nullptr;
- }
-
- gbm_bo* const bo_;
- void* mmap_data_ = nullptr;
-
- const uint32_t format_;
- const uint64_t format_modifier_;
- const uint32_t flags_;
-
- const gfx::Size size_;
-
- const gfx::NativePixmapHandle handle_;
-
- DISALLOW_COPY_AND_ASSIGN(Buffer);
-};
-
-std::unique_ptr<Buffer> CreateBufferForBO(struct gbm_bo* bo,
- uint32_t format,
- const gfx::Size& size,
- uint32_t flags) {
- DCHECK(bo);
- gfx::NativePixmapHandle handle;
-
- const uint64_t modifier = gbm_bo_get_modifier(bo);
- const int plane_count = gbm_bo_get_plane_count(bo);
- // The Mesa's gbm implementation explicitly checks whether plane count <= and
- // returns 1 if the condition is true. Nevertheless, use a DCHECK here to make
- // sure the condition is not broken there.
- DCHECK_GT(plane_count, 0);
- // Ensure there are no differences in integer signs by casting any possible
- // values to size_t.
- for (size_t i = 0; i < static_cast<size_t>(plane_count); ++i) {
- // The fd returned by gbm_bo_get_fd is not ref-counted and need to be
- // kept open for the lifetime of the buffer.
- base::ScopedFD fd(GetPlaneFdForBo(bo, i));
-
- if (!fd.is_valid()) {
- PLOG(ERROR) << "Failed to export buffer to dma_buf";
- gbm_bo_destroy(bo);
- return nullptr;
- }
-
- handle.planes.emplace_back(
- gbm_bo_get_stride_for_plane(bo, i), gbm_bo_get_offset(bo, i),
- GetSizeOfPlane(bo, format, size, i), std::move(fd));
- }
-
- handle.modifier = modifier;
- return std::make_unique<Buffer>(bo, format, flags, modifier, size,
- std::move(handle));
-}
-
-class Device final : public ui::GbmDevice {
- public:
- Device(gbm_device* device) : device_(device) {}
- ~Device() override { gbm_device_destroy(device_); }
-
- std::unique_ptr<ui::GbmBuffer> CreateBuffer(uint32_t format,
- const gfx::Size& size,
- uint32_t flags) override {
- struct gbm_bo* bo =
- gbm_bo_create(device_, size.width(), size.height(), format, flags);
- if (!bo) {
-#if DCHECK_IS_ON()
- const char fourcc_as_string[5] = {format & 0xFF, format >> 8 & 0xFF,
- format >> 16 & 0xFF,
- format >> 24 & 0xFF, 0};
-
- LOG(WARNING) << "Failed to create GBM BO, " << fourcc_as_string << ", "
- << size.ToString() << ", flags: 0x" << std::hex << flags
- << "; gbm_device_is_format_supported() = "
- << gbm_device_is_format_supported(device_, format, flags);
-#endif
- return nullptr;
- }
-
- return CreateBufferForBO(bo, format, size, flags);
- }
-
- std::unique_ptr<ui::GbmBuffer> CreateBufferWithModifiers(
- uint32_t format,
- const gfx::Size& size,
- uint32_t flags,
- const std::vector<uint64_t>& modifiers) override {
- if (modifiers.empty())
- return CreateBuffer(format, size, flags);
- struct gbm_bo* bo = gbm_bo_create_with_modifiers(
- device_, size.width(), size.height(), format, modifiers.data(),
- modifiers.size());
- if (!bo)
- return nullptr;
-
- return CreateBufferForBO(bo, format, size, flags);
- }
-
- std::unique_ptr<ui::GbmBuffer> CreateBufferFromHandle(
- uint32_t format,
- const gfx::Size& size,
- gfx::NativePixmapHandle handle) override {
- DCHECK_EQ(handle.planes[0].offset, 0u);
-
- // Try to use scanout if supported.
- int gbm_flags = GBM_BO_USE_SCANOUT;
-#if defined(MINIGBM)
- gbm_flags |= GBM_BO_USE_TEXTURING;
-#endif
- if (!gbm_device_is_format_supported(device_, format, gbm_flags))
- gbm_flags &= ~GBM_BO_USE_SCANOUT;
-
- struct gbm_bo* bo = nullptr;
- if (!gbm_device_is_format_supported(device_, format, gbm_flags)) {
- LOG(ERROR) << "gbm format not supported: " << format;
- return nullptr;
- }
-
- struct gbm_import_fd_modifier_data fd_data;
- fd_data.width = size.width();
- fd_data.height = size.height();
- fd_data.format = format;
- fd_data.num_fds = handle.planes.size();
- fd_data.modifier = handle.modifier;
-
- DCHECK_LE(handle.planes.size(), 3u);
- for (size_t i = 0; i < handle.planes.size(); ++i) {
- fd_data.fds[i] = handle.planes[i < handle.planes.size() ? i : 0].fd.get();
- fd_data.strides[i] = handle.planes[i].stride;
- fd_data.offsets[i] = handle.planes[i].offset;
- }
-
- // The fd passed to gbm_bo_import is not ref-counted and need to be
- // kept open for the lifetime of the buffer.
- bo = gbm_bo_import(device_, GBM_BO_IMPORT_FD_MODIFIER, &fd_data, gbm_flags);
- if (!bo) {
- LOG(ERROR) << "nullptr returned from gbm_bo_import";
- return nullptr;
- }
-
- return std::make_unique<Buffer>(bo, format, gbm_flags, handle.modifier,
- size, std::move(handle));
- }
-
- private:
- gbm_device* const device_;
-
- DISALLOW_COPY_AND_ASSIGN(Device);
-};
-
-} // namespace gbm_wrapper
-
-namespace ui {
-
-std::unique_ptr<GbmDevice> CreateGbmDevice(int fd) {
- gbm_device* device = gbm_create_device(fd);
- if (!device)
- return nullptr;
- return std::make_unique<gbm_wrapper::Device>(device);
-}
-
-} // namespace ui
diff --git a/chromium/ui/ozone/common/linux/gbm_wrapper.h b/chromium/ui/ozone/common/linux/gbm_wrapper.h
deleted file mode 100644
index 926549d6edf..00000000000
--- a/chromium/ui/ozone/common/linux/gbm_wrapper.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_COMMON_LINUX_GBM_WRAPPER_H_
-#define UI_OZONE_COMMON_LINUX_GBM_WRAPPER_H_
-
-#include <memory>
-
-#include "ui/ozone/common/linux/gbm_device.h"
-
-namespace ui {
-
-std::unique_ptr<ui::GbmDevice> CreateGbmDevice(int fd);
-
-} // namespace ui
-
-#endif // UI_OZONE_COMMON_LINUX_GBM_WRAPPER_H_
diff --git a/chromium/ui/ozone/common/linux/scoped_gbm_device.cc b/chromium/ui/ozone/common/linux/scoped_gbm_device.cc
deleted file mode 100644
index 21f00b93bd0..00000000000
--- a/chromium/ui/ozone/common/linux/scoped_gbm_device.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/common/linux/scoped_gbm_device.h"
-
-namespace ui {
-
-void GbmDeviceDeleter::operator()(gbm_device* device) {
- if (device)
- gbm_device_destroy(device);
-}
-
-} // namespace ui
diff --git a/chromium/ui/ozone/common/linux/scoped_gbm_device.h b/chromium/ui/ozone/common/linux/scoped_gbm_device.h
deleted file mode 100644
index 94c97c83b11..00000000000
--- a/chromium/ui/ozone/common/linux/scoped_gbm_device.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_COMMON_LINUX_SCOPED_GBM_DEVICE_H_
-#define UI_OZONE_COMMON_LINUX_SCOPED_GBM_DEVICE_H_
-
-#include <gbm.h>
-
-#include <memory>
-
-namespace ui {
-
-struct GbmDeviceDeleter {
- void operator()(gbm_device* device);
-};
-
-using ScopedGbmDevice = std::unique_ptr<gbm_device, GbmDeviceDeleter>;
-
-} // namespace ui
-
-#endif // UI_OZONE_COMMON_LINUX_SCOPED_GBM_DEVICE_H_
diff --git a/chromium/ui/ozone/demo/BUILD.gn b/chromium/ui/ozone/demo/BUILD.gn
index a77245ced52..9524c025b80 100644
--- a/chromium/ui/ozone/demo/BUILD.gn
+++ b/chromium/ui/ozone/demo/BUILD.gn
@@ -39,7 +39,7 @@ source_set("ozone_demo_lib") {
]
if (is_fuchsia) {
- deps += [ "//third_party/fuchsia-sdk/sdk:fuchsia-ui-policy" ]
+ deps += [ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.policy" ]
}
}
@@ -102,10 +102,11 @@ executable("skia_demo") {
}
if (is_fuchsia) {
- fuchsia_package("ozone_demo_pkg") {
+ cr_fuchsia_package("ozone_demo_pkg") {
testonly = true
binary = ":ozone_demo"
package_name_override = "ozone_demo"
+ manifest = "//build/config/fuchsia/gfx_tests.cmx"
}
fuchsia_package_runner("ozone_demo_fuchsia") {
diff --git a/chromium/ui/ozone/demo/gl_renderer.cc b/chromium/ui/ozone/demo/gl_renderer.cc
index 35a51c5efe4..8c266b61096 100644
--- a/chromium/ui/ozone/demo/gl_renderer.cc
+++ b/chromium/ui/ozone/demo/gl_renderer.cc
@@ -38,7 +38,7 @@ bool GlRenderer::Initialize() {
return false;
}
- gl_surface_->Resize(size_, 1.f, gl::GLSurface::ColorSpace::UNSPECIFIED, true);
+ gl_surface_->Resize(size_, 1.f, gfx::ColorSpace(), true);
if (!context_->MakeCurrent(gl_surface_.get())) {
LOG(ERROR) << "Failed to make GL context current";
diff --git a/chromium/ui/ozone/demo/skia/skia_gl_renderer.cc b/chromium/ui/ozone/demo/skia/skia_gl_renderer.cc
index 6d2dd5d5cf6..a4ed2416df4 100644
--- a/chromium/ui/ozone/demo/skia/skia_gl_renderer.cc
+++ b/chromium/ui/ozone/demo/skia/skia_gl_renderer.cc
@@ -30,12 +30,6 @@ namespace ui {
namespace {
-const GrGLInterface* GrGLCreateNativeInterface() {
- return GrGLAssembleInterface(nullptr, [](void* ctx, const char name[]) {
- return gl::GetGLProcAddress(name);
- });
-}
-
const char kUseDDL[] = "use-ddl";
} // namespace
@@ -64,15 +58,16 @@ bool SkiaGlRenderer::Initialize() {
return false;
}
- gl_surface_->Resize(size_, 1.f, gl::GLSurface::ColorSpace::UNSPECIFIED, true);
+ gl_surface_->Resize(size_, 1.f, gfx::ColorSpace(), true);
if (!gl_context_->MakeCurrent(gl_surface_.get())) {
LOG(FATAL) << "Failed to make GL context current";
return false;
}
- auto native_interface =
- sk_sp<const GrGLInterface>(GrGLCreateNativeInterface());
+ sk_sp<const GrGLInterface> native_interface = GrGLMakeAssembledInterface(
+ nullptr,
+ [](void* ctx, const char name[]) { return gl::GetGLProcAddress(name); });
DCHECK(native_interface);
GrContextOptions options;
// TODO(csmartdalton): enable internal multisampling after the related Skia
diff --git a/chromium/ui/ozone/demo/software_renderer.cc b/chromium/ui/ozone/demo/software_renderer.cc
index 90f1bee0a7e..3214fa4b3e9 100644
--- a/chromium/ui/ozone/demo/software_renderer.cc
+++ b/chromium/ui/ozone/demo/software_renderer.cc
@@ -57,12 +57,12 @@ void SoftwareRenderer::RenderFrame() {
float fraction = NextFraction();
- sk_sp<SkSurface> surface = software_surface_->GetSurface();
+ SkCanvas* canvas = software_surface_->GetCanvas();
SkColor color =
SkColorSetARGB(0xff, 0, 0xff * fraction, 0xff * (1 - fraction));
- surface->getCanvas()->clear(color);
+ canvas->clear(color);
software_surface_->PresentCanvas(gfx::Rect(size_));
diff --git a/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc b/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc
index bda8d2106e9..6117ac4f0f3 100644
--- a/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc
+++ b/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc
@@ -151,7 +151,7 @@ bool SurfacelessGlRenderer::Initialize() {
return false;
}
- gl_surface_->Resize(size_, 1.f, gl::GLSurface::ColorSpace::UNSPECIFIED, true);
+ gl_surface_->Resize(size_, 1.f, gfx::ColorSpace(), true);
if (!context_->MakeCurrent(gl_surface_.get())) {
LOG(ERROR) << "Failed to make GL context current";
diff --git a/chromium/ui/ozone/demo/vulkan_renderer.cc b/chromium/ui/ozone/demo/vulkan_renderer.cc
index cb174ac6c7d..6d778ce8e98 100644
--- a/chromium/ui/ozone/demo/vulkan_renderer.cc
+++ b/chromium/ui/ozone/demo/vulkan_renderer.cc
@@ -222,9 +222,10 @@ void VulkanRenderer::RenderFrame() {
/* .color = */ {/* .float32 = */ {.5f, 1.f - NextFraction(), .5f, 1.f}}};
gpu::VulkanSwapChain* vulkan_swap_chain = vulkan_surface_->swap_chain();
- gpu::VulkanSwapChain::ScopedWrite scoped_write(vulkan_swap_chain);
- const uint32_t image = scoped_write.image_index();
{
+ gpu::VulkanSwapChain::ScopedWrite scoped_write(vulkan_swap_chain);
+ const uint32_t image = scoped_write.image_index();
+
auto& framebuffer = framebuffers_[image];
if (!framebuffer) {
framebuffer = Framebuffer::Create(
@@ -293,14 +294,8 @@ void VulkanRenderer::RenderFrame() {
vkCmdEndRenderPass(recorder.handle());
}
VkSemaphore begin_semaphore = scoped_write.TakeBeginSemaphore();
- VkSemaphoreCreateInfo vk_semaphore_create_info = {
- VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO};
- VkSemaphore end_semaphore;
- CHECK(vkCreateSemaphore(device_queue_->GetVulkanDevice(),
- &vk_semaphore_create_info, nullptr /* pAllocator */,
- &end_semaphore) == VK_SUCCESS);
+ VkSemaphore end_semaphore = scoped_write.GetEndSemaphore();
CHECK(command_buffer.Submit(1, &begin_semaphore, 1, &end_semaphore));
- scoped_write.SetEndSemaphore(end_semaphore);
device_queue_->GetFenceHelper()->EnqueueSemaphoreCleanupForSubmittedWork(
begin_semaphore);
}
diff --git a/chromium/ui/ozone/demo/window_manager.cc b/chromium/ui/ozone/demo/window_manager.cc
index ffea5853158..ed4f66c8df4 100644
--- a/chromium/ui/ozone/demo/window_manager.cc
+++ b/chromium/ui/ozone/demo/window_manager.cc
@@ -69,8 +69,8 @@ void WindowManager::OnConfigurationChanged() {
}
is_configuring_ = true;
- delegate_->GetDisplays(base::BindRepeating(&WindowManager::OnDisplaysAquired,
- base::Unretained(this)));
+ delegate_->GetDisplays(base::BindOnce(&WindowManager::OnDisplaysAquired,
+ base::Unretained(this)));
}
void WindowManager::OnDisplaySnapshotsInvalidated() {}
diff --git a/chromium/ui/ozone/gl/BUILD.gn b/chromium/ui/ozone/gl/BUILD.gn
index 8c7b4f40fb5..812955e9566 100644
--- a/chromium/ui/ozone/gl/BUILD.gn
+++ b/chromium/ui/ozone/gl/BUILD.gn
@@ -5,9 +5,7 @@
import("//testing/test.gni")
test("ozone_gl_unittests") {
- sources = [
- "gl_image_ozone_native_pixmap_unittest.cc",
- ]
+ sources = [ "gl_image_ozone_native_pixmap_unittest.cc" ]
deps = [
"//base/test:test_support",
@@ -18,7 +16,5 @@ test("ozone_gl_unittests") {
"//ui/ozone",
]
- data_deps = [
- "//third_party/mesa_headers",
- ]
+ data_deps = [ "//third_party/mesa_headers" ]
}
diff --git a/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc b/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
index 349b6106e22..229b15167bb 100644
--- a/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
+++ b/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
@@ -91,11 +91,13 @@ INSTANTIATE_TYPED_TEST_SUITE_P(GLImageNativePixmapScanoutBGRA,
using GLImageScanoutTypeDisabled = testing::Types<
GLImageNativePixmapTestDelegate<gfx::BufferUsage::SCANOUT,
- gfx::BufferFormat::RGBX_1010102>>;
+ gfx::BufferFormat::RGBA_1010102>,
+ GLImageNativePixmapTestDelegate<gfx::BufferUsage::SCANOUT,
+ gfx::BufferFormat::BGRA_1010102>>;
-// This test is disabled since we need mesa support for XR30/XB30 that is not
+// This test is disabled since we need mesa support for AB30 that is not
// available on many boards yet.
-INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GLImageNativePixmapScanoutRGBX,
+INSTANTIATE_TYPED_TEST_SUITE_P(DISABLED_GLImageNativePixmapScanoutRGBA,
GLImageTest,
GLImageScanoutTypeDisabled);
@@ -111,7 +113,7 @@ using GLImageBindTestTypes = testing::Types<
GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
gfx::BufferFormat::BGRA_8888>,
GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
- gfx::BufferFormat::RGBX_1010102>,
+ gfx::BufferFormat::RGBA_1010102>,
GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
gfx::BufferFormat::R_8>,
GLImageNativePixmapTestDelegate<gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
diff --git a/chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.cc b/chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.cc
index 446afea24fc..36ae5fac4d5 100644
--- a/chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.cc
+++ b/chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.cc
@@ -79,7 +79,7 @@ void GLOzoneEglCast::TerminateDisplay() {
DCHECK(get_display);
DCHECK(terminate);
- EGLDisplay display = get_display(GetNativeDisplay());
+ EGLDisplay display = get_display(GetNativeDisplay().GetDisplay());
DCHECK_NE(display, EGL_NO_DISPLAY);
EGLBoolean terminate_result = terminate(display);
@@ -100,9 +100,10 @@ scoped_refptr<gl::GLSurface> GLOzoneEglCast::CreateOffscreenGLSurface(
return gl::InitializeGLSurface(new gl::PbufferGLSurfaceEGL(size));
}
-intptr_t GLOzoneEglCast::GetNativeDisplay() {
+gl::EGLDisplayPlatform GLOzoneEglCast::GetNativeDisplay() {
CreateDisplayTypeAndWindowIfNeeded();
- return reinterpret_cast<intptr_t>(display_type_);
+ return gl::EGLDisplayPlatform(
+ reinterpret_cast<EGLNativeDisplayType>(display_type_));
}
void GLOzoneEglCast::CreateDisplayTypeAndWindowIfNeeded() {
diff --git a/chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.h b/chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.h
index ace0cbc94ab..79bcfd833ca 100644
--- a/chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.h
+++ b/chromium/ui/ozone/platform/cast/gl_ozone_egl_cast.h
@@ -32,7 +32,7 @@ class GLOzoneEglCast : public GLOzoneEGL {
gfx::AcceleratedWidget widget) override;
scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface(
const gfx::Size& size) override;
- intptr_t GetNativeDisplay() override;
+ gl::EGLDisplayPlatform GetNativeDisplay() override;
bool LoadGLES2Bindings(gl::GLImplementation implementation) override;
intptr_t GetNativeWindow();
diff --git a/chromium/ui/ozone/platform/cast/gl_surface_cast.cc b/chromium/ui/ozone/platform/cast/gl_surface_cast.cc
index d76bfacb1f8..9d62e734016 100644
--- a/chromium/ui/ozone/platform/cast/gl_surface_cast.cc
+++ b/chromium/ui/ozone/platform/cast/gl_surface_cast.cc
@@ -83,7 +83,7 @@ gfx::SwapResult GLSurfaceCast::SwapBuffersWithBounds(
bool GLSurfaceCast::Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) {
return parent_->ResizeDisplay(size) &&
NativeViewGLSurfaceEGL::Resize(size, scale_factor, color_space,
diff --git a/chromium/ui/ozone/platform/cast/gl_surface_cast.h b/chromium/ui/ozone/platform/cast/gl_surface_cast.h
index e294802478f..30f19d5ab05 100644
--- a/chromium/ui/ozone/platform/cast/gl_surface_cast.h
+++ b/chromium/ui/ozone/platform/cast/gl_surface_cast.h
@@ -30,7 +30,7 @@ class GLSurfaceCast : public gl::NativeViewGLSurfaceEGL {
PresentationCallback callback) override;
bool Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) override;
bool ScheduleOverlayPlane(int z_order,
gfx::OverlayTransform transform,
diff --git a/chromium/ui/ozone/platform/cast/ozone_platform_cast.cc b/chromium/ui/ozone/platform/cast/ozone_platform_cast.cc
index b2e3baa77fd..a2ce0266582 100644
--- a/chromium/ui/ozone/platform/cast/ozone_platform_cast.cc
+++ b/chromium/ui/ozone/platform/cast/ozone_platform_cast.cc
@@ -20,6 +20,7 @@
#include "ui/events/ozone/evdev/event_factory_evdev.h"
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/cast/overlay_manager_cast.h"
#include "ui/ozone/platform/cast/platform_window_cast.h"
#include "ui/ozone/platform/cast/surface_factory_cast.h"
@@ -109,7 +110,8 @@ class OzonePlatformCast : public OzonePlatform {
return nullptr;
}
std::unique_ptr<InputMethod> CreateInputMethod(
- internal::InputMethodDelegate* delegate) override {
+ internal::InputMethodDelegate* delegate,
+ gfx::AcceleratedWidget) override {
return std::make_unique<InputMethodMinimal>(delegate);
}
@@ -124,9 +126,6 @@ class OzonePlatformCast : public OzonePlatform {
cursor_factory_ = std::make_unique<CursorFactoryOzone>();
gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
- if (!params.viz_display_compositor)
- overlay_manager_ = std::make_unique<OverlayManagerCast>();
-
// Enable dummy software rendering support if GPU process disabled
// or if we're an audio-only build.
// Note: switch is kDisableGpu from content/public/common/content_switches.h
@@ -148,9 +147,7 @@ class OzonePlatformCast : public OzonePlatform {
surface_factory_ = std::make_unique<SurfaceFactoryCast>();
}
void InitializeGPU(const InitParams& params) override {
- if (params.viz_display_compositor) {
- overlay_manager_ = std::make_unique<OverlayManagerCast>();
- }
+ overlay_manager_ = std::make_unique<OverlayManagerCast>();
surface_factory_ =
std::make_unique<SurfaceFactoryCast>(std::move(egl_platform_));
}
diff --git a/chromium/ui/ozone/platform/cast/surface_factory_cast.cc b/chromium/ui/ozone/platform/cast/surface_factory_cast.cc
index 562e60e12e2..46928b82e97 100644
--- a/chromium/ui/ozone/platform/cast/surface_factory_cast.cc
+++ b/chromium/ui/ozone/platform/cast/surface_factory_cast.cc
@@ -26,7 +26,7 @@ class DummySurface : public SurfaceOzoneCanvas {
~DummySurface() override {}
// SurfaceOzoneCanvas implementation:
- sk_sp<SkSurface> GetSurface() override { return surface_; }
+ SkCanvas* GetCanvas() override { return surface_->getCanvas(); }
void ResizeCanvas(const gfx::Size& viewport_size) override {
surface_ =
@@ -114,7 +114,7 @@ GLOzone* SurfaceFactoryCast::GetGLOzone(gl::GLImplementation implementation) {
std::unique_ptr<SurfaceOzoneCanvas> SurfaceFactoryCast::CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) {
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
// Software canvas support only in headless mode
if (egl_implementation_)
return nullptr;
@@ -126,7 +126,9 @@ scoped_refptr<gfx::NativePixmap> SurfaceFactoryCast::CreateNativePixmap(
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) {
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size) {
+ DCHECK(!framebuffer_size || framebuffer_size == size);
return base::MakeRefCounted<CastPixmap>();
}
diff --git a/chromium/ui/ozone/platform/cast/surface_factory_cast.h b/chromium/ui/ozone/platform/cast/surface_factory_cast.h
index fd1e30a73db..a7d0ef9b151 100644
--- a/chromium/ui/ozone/platform/cast/surface_factory_cast.h
+++ b/chromium/ui/ozone/platform/cast/surface_factory_cast.h
@@ -33,13 +33,14 @@ class SurfaceFactoryCast : public SurfaceFactoryOzone {
GLOzone* GetGLOzone(gl::GLImplementation implementation) override;
std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) override;
+ scoped_refptr<base::SequencedTaskRunner> task_runner) override;
scoped_refptr<gfx::NativePixmap> CreateNativePixmap(
gfx::AcceleratedWidget widget,
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) override;
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size = base::nullopt) override;
private:
std::unique_ptr<GLOzoneEglCast> egl_implementation_;
diff --git a/chromium/ui/ozone/platform/drm/BUILD.gn b/chromium/ui/ozone/platform/drm/BUILD.gn
index 3319865a62a..d820eee6a6f 100644
--- a/chromium/ui/ozone/platform/drm/BUILD.gn
+++ b/chromium/ui/ozone/platform/drm/BUILD.gn
@@ -20,10 +20,6 @@ source_set("gbm") {
"client_native_pixmap_factory_gbm.cc",
"client_native_pixmap_factory_gbm.h",
"common/display_types.h",
- "common/drm_overlay_candidates.cc",
- "common/drm_overlay_candidates.h",
- "common/drm_overlay_manager.cc",
- "common/drm_overlay_manager.h",
"common/drm_util.cc",
"common/drm_util.h",
"common/scoped_drm_types.cc",
@@ -46,6 +42,10 @@ source_set("gbm") {
"gpu/drm_gpu_display_manager.h",
"gpu/drm_gpu_util.cc",
"gpu/drm_gpu_util.h",
+ "gpu/drm_overlay_candidates.cc",
+ "gpu/drm_overlay_candidates.h",
+ "gpu/drm_overlay_manager.cc",
+ "gpu/drm_overlay_manager.h",
"gpu/drm_overlay_manager_gpu.cc",
"gpu/drm_overlay_manager_gpu.h",
"gpu/drm_overlay_plane.cc",
@@ -106,8 +106,6 @@ source_set("gbm") {
"host/drm_gpu_platform_support_host.h",
"host/drm_native_display_delegate.cc",
"host/drm_native_display_delegate.h",
- "host/drm_overlay_manager_host.cc",
- "host/drm_overlay_manager_host.h",
"host/drm_window_host.cc",
"host/drm_window_host.h",
"host/drm_window_host_manager.cc",
@@ -145,11 +143,11 @@ source_set("gbm") {
"//ui/events/platform",
"//ui/gfx",
"//ui/gfx/geometry",
+ "//ui/gfx/linux:drm",
+ "//ui/gfx/linux:gbm",
"//ui/gl",
"//ui/ozone:ozone_base",
"//ui/ozone/common",
- "//ui/ozone/common/linux:drm",
- "//ui/ozone/common/linux:gbm",
"//ui/ozone/public/mojom",
"//ui/platform_window",
]
@@ -178,8 +176,8 @@ source_set("gbm") {
source_set("gbm_unittests") {
testonly = true
sources = [
- "common/drm_overlay_manager_unittest.cc",
"common/drm_util_unittest.cc",
+ "gpu/drm_overlay_manager_unittest.cc",
"gpu/drm_overlay_validator_unittest.cc",
"gpu/drm_thread_unittest.cc",
"gpu/drm_window_unittest.cc",
@@ -187,8 +185,6 @@ source_set("gbm_unittests") {
"gpu/hardware_display_plane_manager_unittest.cc",
"gpu/mock_drm_device.cc",
"gpu/mock_drm_device.h",
- "gpu/mock_gbm_device.cc",
- "gpu/mock_gbm_device.h",
"gpu/proxy_helpers_unittest.cc",
"gpu/screen_manager_unittest.cc",
]
@@ -201,10 +197,11 @@ source_set("gbm_unittests") {
"//testing/gtest",
"//ui/base/ime",
"//ui/gfx",
+ "//ui/gfx/linux:drm",
+ "//ui/gfx/linux:gbm",
+ "//ui/gfx/linux:test_support",
"//ui/ozone:platform",
"//ui/ozone/common",
- "//ui/ozone/common/linux:drm",
- "//ui/ozone/common/linux:gbm",
]
if (drm_commit_properties_on_page_flip) {
diff --git a/chromium/ui/ozone/platform/drm/OWNERS b/chromium/ui/ozone/platform/drm/OWNERS
index 363a93a5f95..5392283e6fe 100644
--- a/chromium/ui/ozone/platform/drm/OWNERS
+++ b/chromium/ui/ozone/platform/drm/OWNERS
@@ -1,2 +1,4 @@
dcastagna@chromium.org
dnicoara@chromium.org
+
+# COMPONENT: OS>Systems>Display
diff --git a/chromium/ui/ozone/platform/drm/common/drm_util.cc b/chromium/ui/ozone/platform/drm/common/drm_util.cc
index c222c05e479..06a9c37cd2c 100644
--- a/chromium/ui/ozone/platform/drm/common/drm_util.cc
+++ b/chromium/ui/ozone/platform/drm/common/drm_util.cc
@@ -108,6 +108,28 @@ float GetRefreshRate(const drmModeModeInfo& mode) {
return (clock * 1000.0f) / (htotal * vtotal);
}
+display::DisplayConnectionType GetDisplayType(drmModeConnector* connector) {
+ switch (connector->connector_type) {
+ case DRM_MODE_CONNECTOR_VGA:
+ return display::DISPLAY_CONNECTION_TYPE_VGA;
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_DVID:
+ case DRM_MODE_CONNECTOR_DVIA:
+ return display::DISPLAY_CONNECTION_TYPE_DVI;
+ case DRM_MODE_CONNECTOR_LVDS:
+ case DRM_MODE_CONNECTOR_eDP:
+ case DRM_MODE_CONNECTOR_DSI:
+ return display::DISPLAY_CONNECTION_TYPE_INTERNAL;
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ return display::DISPLAY_CONNECTION_TYPE_DISPLAYPORT;
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ return display::DISPLAY_CONNECTION_TYPE_HDMI;
+ default:
+ return display::DISPLAY_CONNECTION_TYPE_UNKNOWN;
+ }
+}
+
int GetDrmProperty(int fd,
drmModeConnector* connector,
const std::string& name,
@@ -151,6 +173,26 @@ ScopedDrmPropertyBlobPtr GetDrmPropertyBlob(int fd,
return nullptr;
}
+display::PrivacyScreenState GetPrivacyScreenState(int fd,
+ drmModeConnector* connector) {
+ ScopedDrmPropertyPtr property;
+ int index = GetDrmProperty(fd, connector, "privacy-screen", &property);
+ if (index < 0)
+ return display::PrivacyScreenState::kNotSupported;
+
+ DCHECK_LT(connector->prop_values[index],
+ display::PrivacyScreenState::kPrivacyScreenStateLast);
+ if (connector->prop_values[index] >=
+ display::PrivacyScreenState::kPrivacyScreenStateLast) {
+ LOG(ERROR) << "Invalid privacy-screen property value: Expected < "
+ << display::PrivacyScreenState::kPrivacyScreenStateLast
+ << ", but got: " << connector->prop_values[index];
+ }
+
+ return static_cast<display::PrivacyScreenState>(
+ connector->prop_values[index]);
+}
+
bool IsAspectPreserving(int fd, drmModeConnector* connector) {
ScopedDrmPropertyPtr property;
int index = GetDrmProperty(fd, connector, "scaling mode", &property);
@@ -403,29 +445,6 @@ display::DisplaySnapshot::DisplayModeList ExtractDisplayModes(
return modes;
}
-display::DisplayConnectionType GetDisplayType(
- const drmModeConnector* connector) {
- switch (connector->connector_type) {
- case DRM_MODE_CONNECTOR_VGA:
- return display::DISPLAY_CONNECTION_TYPE_VGA;
- case DRM_MODE_CONNECTOR_DVII:
- case DRM_MODE_CONNECTOR_DVID:
- case DRM_MODE_CONNECTOR_DVIA:
- return display::DISPLAY_CONNECTION_TYPE_DVI;
- case DRM_MODE_CONNECTOR_LVDS:
- case DRM_MODE_CONNECTOR_eDP:
- case DRM_MODE_CONNECTOR_DSI:
- return display::DISPLAY_CONNECTION_TYPE_INTERNAL;
- case DRM_MODE_CONNECTOR_DisplayPort:
- return display::DISPLAY_CONNECTION_TYPE_DISPLAYPORT;
- case DRM_MODE_CONNECTOR_HDMIA:
- case DRM_MODE_CONNECTOR_HDMIB:
- return display::DISPLAY_CONNECTION_TYPE_HDMI;
- default:
- return display::DISPLAY_CONNECTION_TYPE_UNKNOWN;
- }
-}
-
std::unique_ptr<display::DisplaySnapshot> CreateDisplaySnapshot(
HardwareDisplayControllerInfo* info,
int fd,
@@ -440,6 +459,8 @@ std::unique_ptr<display::DisplaySnapshot> CreateDisplaySnapshot(
IsAspectPreserving(fd, info->connector());
const display::PanelOrientation panel_orientation =
GetPanelOrientation(fd, info->connector());
+ const display::PrivacyScreenState privacy_screen_state =
+ GetPrivacyScreenState(fd, info->connector());
const bool has_color_correction_matrix =
HasColorCorrectionMatrix(fd, info->crtc()) ||
HasPerPlaneColorCorrectionMatrix(fd, info->crtc());
@@ -495,7 +516,7 @@ std::unique_ptr<display::DisplaySnapshot> CreateDisplaySnapshot(
return std::make_unique<display::DisplaySnapshot>(
display_id, origin, physical_size, type, is_aspect_preserving_scaling,
- has_overscan, has_color_correction_matrix,
+ has_overscan, privacy_screen_state, has_color_correction_matrix,
color_correction_in_linear_space, display_color_space, bits_per_channel,
display_name, sys_path, std::move(modes), panel_orientation, edid,
current_mode, native_mode, product_code, year_of_manufacture,
@@ -515,6 +536,7 @@ std::vector<DisplaySnapshot_Params> CreateDisplaySnapshotParams(
p.type = d->type();
p.is_aspect_preserving_scaling = d->is_aspect_preserving_scaling();
p.has_overscan = d->has_overscan();
+ p.privacy_screen_state = d->privacy_screen_state();
p.has_color_correction_matrix = d->has_color_correction_matrix();
p.color_correction_in_linear_space = d->color_correction_in_linear_space();
p.color_space = d->color_space();
@@ -563,7 +585,7 @@ std::unique_ptr<display::DisplaySnapshot> CreateDisplaySnapshot(
return std::make_unique<display::DisplaySnapshot>(
params.display_id, params.origin, params.physical_size, params.type,
params.is_aspect_preserving_scaling, params.has_overscan,
- params.has_color_correction_matrix,
+ params.privacy_screen_state, params.has_color_correction_matrix,
params.color_correction_in_linear_space, params.color_space,
params.bits_per_channel, params.display_name, params.sys_path,
std::move(modes), params.panel_orientation, params.edid, current_mode,
@@ -582,9 +604,9 @@ int GetFourCCFormatForOpaqueFramebuffer(gfx::BufferFormat format) {
case gfx::BufferFormat::BGRA_8888:
case gfx::BufferFormat::BGRX_8888:
return DRM_FORMAT_XRGB8888;
- case gfx::BufferFormat::BGRX_1010102:
+ case gfx::BufferFormat::BGRA_1010102:
return DRM_FORMAT_XRGB2101010;
- case gfx::BufferFormat::RGBX_1010102:
+ case gfx::BufferFormat::RGBA_1010102:
return DRM_FORMAT_XBGR2101010;
case gfx::BufferFormat::BGR_565:
return DRM_FORMAT_RGB565;
@@ -598,54 +620,4 @@ int GetFourCCFormatForOpaqueFramebuffer(gfx::BufferFormat format) {
}
}
-OverlaySurfaceCandidateList CreateOverlaySurfaceCandidateListFrom(
- const std::vector<OverlayCheck_Params>& params) {
- OverlaySurfaceCandidateList candidates;
- for (auto& p : params) {
- OverlaySurfaceCandidate osc;
- osc.transform = p.transform;
- osc.buffer_size = p.buffer_size;
- osc.format = p.format;
- osc.display_rect = gfx::RectF(p.display_rect);
- osc.crop_rect = p.crop_rect;
- osc.is_opaque = p.is_opaque;
- osc.plane_z_order = p.plane_z_order;
- osc.overlay_handled = p.is_overlay_candidate;
- candidates.push_back(osc);
- }
-
- return candidates;
-}
-
-std::vector<OverlayCheck_Params> CreateParamsFromOverlaySurfaceCandidate(
- const OverlaySurfaceCandidateList& candidates) {
- std::vector<OverlayCheck_Params> overlay_params;
- for (auto& candidate : candidates) {
- overlay_params.push_back(OverlayCheck_Params(candidate));
- }
-
- return overlay_params;
-}
-
-OverlayStatusList CreateOverlayStatusListFrom(
- const std::vector<OverlayCheckReturn_Params>& params) {
- OverlayStatusList returns;
- for (auto& p : params) {
- returns.push_back(p.status);
- }
-
- return returns;
-}
-
-std::vector<OverlayCheckReturn_Params> CreateParamsFromOverlayStatusList(
- const OverlayStatusList& returns) {
- std::vector<OverlayCheckReturn_Params> params;
- for (auto& s : returns) {
- OverlayCheckReturn_Params p;
- p.status = s;
- params.push_back(p);
- }
- return params;
-}
-
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/common/drm_util.h b/chromium/ui/ozone/platform/drm/common/drm_util.h
index 71fb0e0ee54..74001bcb0d1 100644
--- a/chromium/ui/ozone/platform/drm/common/drm_util.h
+++ b/chromium/ui/ozone/platform/drm/common/drm_util.h
@@ -71,9 +71,6 @@ display::DisplaySnapshot::DisplayModeList ExtractDisplayModes(
const display::DisplayMode** out_current_mode,
const display::DisplayMode** out_native_mode);
-display::DisplayConnectionType GetDisplayType(
- const drmModeConnector* connector);
-
// |info| provides the DRM information related to the display, |fd| is the
// connection to the DRM device.
std::unique_ptr<display::DisplaySnapshot> CreateDisplaySnapshot(
@@ -114,18 +111,6 @@ float ModeRefreshRate(const drmModeModeInfo& mode);
bool ModeIsInterlaced(const drmModeModeInfo& mode);
-OverlaySurfaceCandidateList CreateOverlaySurfaceCandidateListFrom(
- const std::vector<OverlayCheck_Params>& params);
-
-std::vector<OverlayCheck_Params> CreateParamsFromOverlaySurfaceCandidate(
- const OverlaySurfaceCandidateList& candidates);
-
-OverlayStatusList CreateOverlayStatusListFrom(
- const std::vector<OverlayCheckReturn_Params>& params);
-
-std::vector<OverlayCheckReturn_Params> CreateParamsFromOverlayStatusList(
- const OverlayStatusList& returns);
-
} // namespace ui
#endif // UI_OZONE_PLATFORM_DRM_COMMON_DRM_UTIL_H_
diff --git a/chromium/ui/ozone/platform/drm/common/drm_util_unittest.cc b/chromium/ui/ozone/platform/drm/common/drm_util_unittest.cc
index c0e59bbbe83..b81f31f265e 100644
--- a/chromium/ui/ozone/platform/drm/common/drm_util_unittest.cc
+++ b/chromium/ui/ozone/platform/drm/common/drm_util_unittest.cc
@@ -180,48 +180,6 @@ TEST_F(DrmUtilTest, RoundTripDisplaySnapshot) {
EXPECT_EQ(ep, roundtrip_params[2]);
}
-TEST_F(DrmUtilTest, OverlaySurfaceCandidate) {
- OverlaySurfaceCandidateList input;
-
- OverlaySurfaceCandidate input_osc;
- input_osc.transform = gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
- input_osc.format = gfx::BufferFormat::YUV_420_BIPLANAR;
- input_osc.buffer_size = gfx::Size(100, 50);
- input_osc.display_rect = gfx::RectF(1., 2., 3., 4.);
- input_osc.crop_rect = gfx::RectF(10., 20., 30., 40.);
- input_osc.clip_rect = gfx::Rect(10, 20, 30, 40);
- input_osc.is_clipped = true;
- input_osc.plane_z_order = 42;
- input_osc.overlay_handled = true;
-
- input.push_back(input_osc);
-
- // Roundtrip the conversions.
- auto output = CreateOverlaySurfaceCandidateListFrom(
- CreateParamsFromOverlaySurfaceCandidate(input));
-
- EXPECT_EQ(input.size(), output.size());
- OverlaySurfaceCandidate output_osc = output[0];
-
- EXPECT_EQ(input_osc.transform, output_osc.transform);
- EXPECT_EQ(input_osc.format, output_osc.format);
- EXPECT_EQ(input_osc.buffer_size, output_osc.buffer_size);
- EXPECT_EQ(input_osc.display_rect, output_osc.display_rect);
- EXPECT_EQ(input_osc.crop_rect, output_osc.crop_rect);
- EXPECT_EQ(input_osc.plane_z_order, output_osc.plane_z_order);
- EXPECT_EQ(input_osc.overlay_handled, output_osc.overlay_handled);
-
- EXPECT_FALSE(input < output);
- EXPECT_FALSE(output < input);
-
- std::map<OverlaySurfaceCandidateList, int> map;
- map[input] = 42;
- const auto& iter = map.find(output);
-
- EXPECT_NE(map.end(), iter);
- EXPECT_EQ(42, iter->second);
-}
-
TEST_F(DrmUtilTest, TestDisplayModesExtraction) {
// Initialize a list of display modes.
constexpr size_t kNumModes = 5;
diff --git a/chromium/ui/ozone/platform/drm/common/scoped_drm_types.cc b/chromium/ui/ozone/platform/drm/common/scoped_drm_types.cc
index e8b79412ff7..ef229418e3f 100644
--- a/chromium/ui/ozone/platform/drm/common/scoped_drm_types.cc
+++ b/chromium/ui/ozone/platform/drm/common/scoped_drm_types.cc
@@ -5,6 +5,7 @@
#include "ui/ozone/platform/drm/common/scoped_drm_types.h"
#include <stdint.h> // required by xf86drmMode.h
+#include <xf86drm.h>
#include <xf86drmMode.h>
namespace ui {
@@ -55,4 +56,8 @@ void DrmFramebufferDeleter::operator()(drmModeFB* framebuffer) const {
drmModeFreeFB(framebuffer);
}
+void DrmVersionDeleter::operator()(drmVersion* version) const {
+ drmFreeVersion(version);
+}
+
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/common/scoped_drm_types.h b/chromium/ui/ozone/platform/drm/common/scoped_drm_types.h
index 32f9dc92db3..22345a8545c 100644
--- a/chromium/ui/ozone/platform/drm/common/scoped_drm_types.h
+++ b/chromium/ui/ozone/platform/drm/common/scoped_drm_types.h
@@ -20,6 +20,7 @@ typedef struct _drmModeProperty drmModePropertyRes;
typedef struct _drmModeAtomicReq drmModeAtomicReq;
typedef struct _drmModePropertyBlob drmModePropertyBlobRes;
typedef struct _drmModeRes drmModeRes;
+typedef struct _drmVersion drmVersion;
typedef struct drm_color_lut drm_color_lut;
typedef struct drm_color_ctm drm_color_ctm;
@@ -58,6 +59,9 @@ struct DrmPropertyBlobDeleter {
struct DrmFramebufferDeleter {
void operator()(drmModeFB* framebuffer) const;
};
+struct DrmVersionDeleter {
+ void operator()(drmVersion* version) const;
+};
typedef std::unique_ptr<drmModeRes, DrmResourcesDeleter> ScopedDrmResourcesPtr;
typedef std::unique_ptr<drmModeConnector, DrmConnectorDeleter>
@@ -77,6 +81,7 @@ typedef std::unique_ptr<drmModePropertyBlobRes, DrmPropertyBlobDeleter>
ScopedDrmPropertyBlobPtr;
typedef std::unique_ptr<drmModeFB, DrmFramebufferDeleter>
ScopedDrmFramebufferPtr;
+typedef std::unique_ptr<drmVersion, DrmVersionDeleter> ScopedDrmVersionPtr;
typedef std::unique_ptr<drm_color_lut, base::FreeDeleter> ScopedDrmColorLutPtr;
typedef std::unique_ptr<drm_color_ctm, base::FreeDeleter> ScopedDrmColorCtmPtr;
diff --git a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc
index 6f3690ddaaa..adf1285bb7b 100644
--- a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc
@@ -8,9 +8,7 @@
#include "base/logging.h"
#include "base/time/time.h"
-#include "ui/display/types/display_constants.h"
#include "ui/gfx/presentation_feedback.h"
-#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
#include "ui/ozone/platform/drm/gpu/drm_dumb_buffer.h"
#include "ui/ozone/platform/drm/gpu/drm_framebuffer.h"
@@ -24,9 +22,7 @@ CrtcController::CrtcController(const scoped_refptr<DrmDevice>& drm,
uint32_t connector)
: drm_(drm),
crtc_(crtc),
- connector_(connector),
- internal_diplay_only_modifiers_(
- {I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Yf_TILED_CCS}) {}
+ connector_(connector) {}
CrtcController::~CrtcController() {
if (!is_disabled_) {
@@ -40,14 +36,16 @@ CrtcController::~CrtcController() {
}
DisableCursor();
- drm_->DisableCrtc(crtc_);
+ drm_->plane_manager()->DisableModeset(crtc_, connector_);
}
}
bool CrtcController::Modeset(const DrmOverlayPlane& plane,
- drmModeModeInfo mode) {
- if (!drm_->SetCrtc(crtc_, plane.buffer->opaque_framebuffer_id(),
- std::vector<uint32_t>(1, connector_), &mode)) {
+ const drmModeModeInfo& mode,
+ const ui::HardwareDisplayPlaneList& plane_list) {
+ if (!drm_->plane_manager()->Modeset(crtc_,
+ plane.buffer->opaque_framebuffer_id(),
+ connector_, mode, plane_list)) {
PLOG(ERROR) << "Failed to modeset: crtc=" << crtc_
<< " connector=" << connector_
<< " framebuffer_id=" << plane.buffer->opaque_framebuffer_id()
@@ -74,12 +72,15 @@ bool CrtcController::Disable() {
is_disabled_ = true;
DisableCursor();
- return drm_->DisableCrtc(crtc_);
+ return drm_->plane_manager()->DisableModeset(crtc_, connector_);
}
bool CrtcController::AssignOverlayPlanes(HardwareDisplayPlaneList* plane_list,
- const DrmOverlayPlaneList& overlays) {
- DCHECK(!is_disabled_);
+ const DrmOverlayPlaneList& overlays,
+ bool is_modesetting) {
+ // If we're in the process of modesetting, the CRTC is still disabled.
+ // Once the modeset is done, we expect it to be enabled.
+ DCHECK(is_modesetting || !is_disabled_);
const DrmOverlayPlane* primary = DrmOverlayPlane::GetPrimaryPlane(overlays);
if (primary && !drm_->plane_manager()->ValidatePrimarySize(*primary, mode_)) {
@@ -90,8 +91,8 @@ bool CrtcController::AssignOverlayPlanes(HardwareDisplayPlaneList* plane_list,
return true;
}
- if (!drm_->plane_manager()->AssignOverlayPlanes(plane_list, overlays, crtc_,
- this)) {
+ if (!drm_->plane_manager()->AssignOverlayPlanes(plane_list, overlays,
+ crtc_)) {
PLOG(ERROR) << "Failed to assign overlay planes for crtc " << crtc_;
return false;
}
@@ -100,21 +101,7 @@ bool CrtcController::AssignOverlayPlanes(HardwareDisplayPlaneList* plane_list,
}
std::vector<uint64_t> CrtcController::GetFormatModifiers(uint32_t format) {
- std::vector<uint64_t> modifiers =
- drm_->plane_manager()->GetFormatModifiers(crtc_, format);
-
- display::DisplayConnectionType display_type =
- ui::GetDisplayType(drm_->GetConnector(connector_).get());
- // If this is an external display, remove the modifiers applicable to internal
- // displays only.
- if (display_type != display::DISPLAY_CONNECTION_TYPE_INTERNAL) {
- for (auto modifier : internal_diplay_only_modifiers_) {
- modifiers.erase(std::remove(modifiers.begin(), modifiers.end(), modifier),
- modifiers.end());
- }
- }
-
- return modifiers;
+ return drm_->plane_manager()->GetFormatModifiers(crtc_, format);
}
void CrtcController::SetCursor(uint32_t handle, const gfx::Size& size) {
diff --git a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h
index 0e3d59a5317..258093f28fc 100644
--- a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h
+++ b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h
@@ -40,15 +40,19 @@ class CrtcController {
const scoped_refptr<DrmDevice>& drm() const { return drm_; }
bool is_disabled() const { return is_disabled_; }
- // Perform the initial modesetting operation using |plane| as the buffer for
- // the primary plane. The CRTC configuration is specified by |mode|.
- bool Modeset(const DrmOverlayPlane& plane, drmModeModeInfo mode);
+ // Calls the appropriate Plane Manager to perform the initial modesetting
+ // operation using |plane| as the buffer for the primary plane. The CRTC
+ // configuration is specified by |mode|.
+ bool Modeset(const DrmOverlayPlane& plane,
+ const drmModeModeInfo& mode,
+ const ui::HardwareDisplayPlaneList& plane_list);
// Disables the controller.
bool Disable();
bool AssignOverlayPlanes(HardwareDisplayPlaneList* plane_list,
- const DrmOverlayPlaneList& planes);
+ const DrmOverlayPlaneList& planes,
+ bool is_modesetting);
// Returns a vector of format modifiers for the given fourcc format
// on this CRTCs primary plane. A format modifier describes the
@@ -75,8 +79,6 @@ class CrtcController {
// TODO(dnicoara) Add support for hardware mirroring (multiple connectors).
const uint32_t connector_;
- const std::vector<uint64_t> internal_diplay_only_modifiers_;
-
drmModeModeInfo mode_ = {};
scoped_refptr<DrmFramebuffer> modeset_framebuffer_;
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_device.cc b/chromium/ui/ozone/platform/drm/gpu/drm_device.cc
index 9e049a84b3f..943816dddf9 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_device.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_device.cc
@@ -146,7 +146,7 @@ DrmPropertyBlobMetadata::~DrmPropertyBlobMetadata() {
class DrmDevice::PageFlipManager {
public:
PageFlipManager() : next_id_(0) {}
- ~PageFlipManager() {}
+ ~PageFlipManager() = default;
void OnPageFlip(uint32_t frame, base::TimeTicks timestamp, uint64_t id) {
auto it =
@@ -248,7 +248,7 @@ DrmDevice::DrmDevice(const base::FilePath& device_path,
is_primary_device_(is_primary_device),
gbm_(std::move(gbm)) {}
-DrmDevice::~DrmDevice() {}
+DrmDevice::~DrmDevice() = default;
bool DrmDevice::Initialize() {
// Ignore devices that cannot perform modesetting.
@@ -302,36 +302,22 @@ ScopedDrmCrtcPtr DrmDevice::GetCrtc(uint32_t crtc_id) {
bool DrmDevice::SetCrtc(uint32_t crtc_id,
uint32_t framebuffer,
std::vector<uint32_t> connectors,
- drmModeModeInfo* mode) {
+ const drmModeModeInfo& mode) {
DCHECK(file_.IsValid());
DCHECK(!connectors.empty());
- DCHECK(mode);
TRACE_EVENT2("drm", "DrmDevice::SetCrtc", "crtc", crtc_id, "size",
- gfx::Size(mode->hdisplay, mode->vdisplay).ToString());
+ gfx::Size(mode.hdisplay, mode.vdisplay).ToString());
return !drmModeSetCrtc(file_.GetPlatformFile(), crtc_id, framebuffer, 0, 0,
- connectors.data(), connectors.size(), mode);
-}
-
-bool DrmDevice::SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors) {
- DCHECK(file_.IsValid());
- // If there's no buffer then the CRTC was disabled.
- if (!crtc->buffer_id)
- return DisableCrtc(crtc->crtc_id);
-
- DCHECK(!connectors.empty());
-
- TRACE_EVENT1("drm", "DrmDevice::RestoreCrtc", "crtc", crtc->crtc_id);
- return !drmModeSetCrtc(file_.GetPlatformFile(), crtc->crtc_id,
- crtc->buffer_id, crtc->x, crtc->y, connectors.data(),
- connectors.size(), &crtc->mode);
+ connectors.data(), connectors.size(),
+ const_cast<drmModeModeInfo*>(&mode));
}
bool DrmDevice::DisableCrtc(uint32_t crtc_id) {
DCHECK(file_.IsValid());
TRACE_EVENT1("drm", "DrmDevice::DisableCrtc", "crtc", crtc_id);
- return !drmModeSetCrtc(file_.GetPlatformFile(), crtc_id, 0, 0, 0, NULL, 0,
- NULL);
+ return !drmModeSetCrtc(file_.GetPlatformFile(), crtc_id, 0, 0, 0, nullptr, 0,
+ nullptr);
}
ScopedDrmConnectorPtr DrmDevice::GetConnector(uint32_t connector_id) {
@@ -432,7 +418,8 @@ bool DrmDevice::SetProperty(uint32_t connector_id,
property_id, value);
}
-ScopedDrmPropertyBlob DrmDevice::CreatePropertyBlob(void* blob, size_t size) {
+ScopedDrmPropertyBlob DrmDevice::CreatePropertyBlob(const void* blob,
+ size_t size) {
uint32_t id = 0;
int ret = drmModeCreatePropertyBlob(file_.GetPlatformFile(), blob, size, &id);
DCHECK(!ret && id);
@@ -526,7 +513,7 @@ bool DrmDevice::MapDumbBuffer(uint32_t handle, size_t size, void** pixels) {
return false;
}
- *pixels = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ *pixels = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED,
file_.GetPlatformFile(), map_request.offset);
if (*pixels == MAP_FAILED) {
PLOG(ERROR) << "Cannot mmap dumb buffer";
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_device.h b/chromium/ui/ozone/platform/drm/gpu/drm_device.h
index d5ef13b1b6f..0cbcca2fe96 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_device.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_device.h
@@ -18,8 +18,8 @@
#include "base/time/time.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
+#include "ui/gfx/linux/gbm_device.h"
#include "ui/gfx/overlay_transform.h"
-#include "ui/ozone/common/linux/gbm_device.h"
#include "ui/ozone/platform/drm/common/scoped_drm_types.h"
#include "ui/ozone/platform/drm/gpu/page_flip_request.h"
@@ -106,12 +106,7 @@ class DrmDevice : public base::RefCountedThreadSafe<DrmDevice> {
virtual bool SetCrtc(uint32_t crtc_id,
uint32_t framebuffer,
std::vector<uint32_t> connectors,
- drmModeModeInfo* mode);
-
- // Used to set a specific configuration to the CRTC. Normally this function
- // would be called with a CRTC saved state (from |GetCrtc|) to restore it to
- // its original configuration.
- virtual bool SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors);
+ const drmModeModeInfo& mode);
virtual bool DisableCrtc(uint32_t crtc_id);
@@ -168,7 +163,8 @@ class DrmDevice : public base::RefCountedThreadSafe<DrmDevice> {
uint64_t value);
// Creates a property blob with data |blob| of size |size|.
- virtual ScopedDrmPropertyBlob CreatePropertyBlob(void* blob, size_t size);
+ virtual ScopedDrmPropertyBlob CreatePropertyBlob(const void* blob,
+ size_t size);
virtual void DestroyPropertyBlob(uint32_t id);
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_display.cc b/chromium/ui/ozone/platform/drm/gpu/drm_display.cc
index 6cf5be1105d..89b9ea98bb4 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_display.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_display.cc
@@ -8,6 +8,7 @@
#include <memory>
#include "base/stl_util.h"
+#include "base/trace_event/trace_event.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/display/types/gamma_ramp_rgb_entry.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
@@ -20,6 +21,8 @@ namespace {
const char kContentProtection[] = "Content Protection";
+const char kPrivacyScreen[] = "privacy-screen";
+
struct ContentProtectionMapping {
const char* name;
display::HDCPState state;
@@ -49,15 +52,16 @@ uint32_t GetContentProtectionValue(drmModePropertyRes* property,
return 0;
}
-std::string GetEnumNameForProperty(drmModeConnector* connector,
+std::string GetEnumNameForProperty(drmModeObjectProperties* property_values,
drmModePropertyRes* property) {
- for (int prop_idx = 0; prop_idx < connector->count_props; ++prop_idx) {
- if (connector->props[prop_idx] != property->prop_id)
+ for (uint32_t prop_idx = 0; prop_idx < property_values->count_props;
+ ++prop_idx) {
+ if (property_values->props[prop_idx] != property->prop_id)
continue;
for (int enum_idx = 0; enum_idx < property->count_enums; ++enum_idx) {
const drm_mode_property_enum& property_enum = property->enums[enum_idx];
- if (property_enum.value == connector->prop_values[prop_idx])
+ if (property_enum.value == property_values->prop_values[prop_idx])
return property_enum.name;
}
}
@@ -114,7 +118,7 @@ std::unique_ptr<display::DisplaySnapshot> DrmDisplay::Update(
bool DrmDisplay::Configure(const drmModeModeInfo* mode,
const gfx::Point& origin) {
VLOG(1) << "DRM configuring: device=" << drm_->device_path().value()
- << " crtc=" << crtc_ << " connector=" << connector_
+ << " crtc=" << crtc_ << " connector=" << connector_->connector_id
<< " origin=" << origin.ToString()
<< " size=" << (mode ? GetDrmModeSize(*mode).ToString() : "0x0")
<< " refresh_rate=" << (mode ? mode->vrefresh : 0) << "Hz";
@@ -123,7 +127,7 @@ bool DrmDisplay::Configure(const drmModeModeInfo* mode,
if (!screen_manager_->ConfigureDisplayController(
drm_, crtc_, connector_->connector_id, origin, *mode)) {
VLOG(1) << "Failed to configure: device=" << drm_->device_path().value()
- << " crtc=" << crtc_ << " connector=" << connector_;
+ << " crtc=" << crtc_ << " connector=" << connector_->connector_id;
return false;
}
} else {
@@ -142,6 +146,8 @@ bool DrmDisplay::GetHDCPState(display::HDCPState* state) {
if (!connector_)
return false;
+ TRACE_EVENT1("drm", "DrmDisplay::GetHDCPState", "connector",
+ connector_->connector_id);
ScopedDrmPropertyPtr hdcp_property(
drm_->GetProperty(connector_.get(), kContentProtection));
if (!hdcp_property) {
@@ -149,8 +155,10 @@ bool DrmDisplay::GetHDCPState(display::HDCPState* state) {
return false;
}
+ ScopedDrmObjectPropertyPtr property_values(drm_->GetObjectProperties(
+ connector_->connector_id, DRM_MODE_OBJECT_CONNECTOR));
std::string name =
- GetEnumNameForProperty(connector_.get(), hdcp_property.get());
+ GetEnumNameForProperty(property_values.get(), hdcp_property.get());
for (size_t i = 0; i < base::size(kContentProtectionStates); ++i) {
if (name == kContentProtectionStates[i].name) {
*state = kContentProtectionStates[i].state;
@@ -200,4 +208,25 @@ void DrmDisplay::SetGammaCorrection(
}
}
+// TODO(gildekel): consider reformatting this to use the new DRM API or cache
+// |privacy_screen_property| after crrev.com/c/1715751 lands.
+void DrmDisplay::SetPrivacyScreen(bool enabled) {
+ if (!connector_)
+ return;
+
+ ScopedDrmPropertyPtr privacy_screen_property(
+ drm_->GetProperty(connector_.get(), kPrivacyScreen));
+
+ if (!privacy_screen_property) {
+ LOG(ERROR) << "'" << kPrivacyScreen << "' property doesn't exist.";
+ return;
+ }
+
+ if (!drm_->SetProperty(connector_->connector_id,
+ privacy_screen_property->prop_id, enabled)) {
+ LOG(ERROR) << (enabled ? "Enabling" : "Disabling") << " property '"
+ << kPrivacyScreen << "' failed!";
+ }
+}
+
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_display.h b/chromium/ui/ozone/platform/drm/gpu/drm_display.h
index c2516cb4d8f..b6a1d08f9b2 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_display.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_display.h
@@ -54,6 +54,7 @@ class DrmDisplay {
void SetGammaCorrection(
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
+ void SetPrivacyScreen(bool enabled);
private:
ScreenManager* screen_manager_; // Not owned.
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.cc b/chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.cc
index 9b855fdda03..772786b42ed 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.cc
@@ -6,8 +6,9 @@
#include <utility>
-#include "ui/ozone/common/linux/drm_util_linux.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
+#include "ui/gfx/buffer_format_util.h"
+#include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_buffer.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
@@ -28,8 +29,18 @@ scoped_refptr<DrmFramebuffer> DrmFramebuffer::AddFramebuffer(
modifiers[i] = params.modifier;
}
+ const auto fourcc_format = GetBufferFormatFromFourCCFormat(params.format);
+ const uint32_t opaque_format =
+ GetFourCCFormatForOpaqueFramebuffer(fourcc_format);
+ // Intel Display Controller won't support AR/B30 framebuffers, only XR/B30,
+ // but that doesn't matter because anyway those two bits of alpha are useless;
+ // use the opaque directly in this case.
+ const bool force_opaque = AlphaBitsForBufferFormat(fourcc_format) == 2;
+
+ const auto drm_format = force_opaque ? opaque_format : params.format;
+
uint32_t framebuffer_id = 0;
- if (!drm_device->AddFramebuffer2(params.width, params.height, params.format,
+ if (!drm_device->AddFramebuffer2(params.width, params.height, drm_format,
params.handles, params.strides,
params.offsets, modifiers, &framebuffer_id,
params.flags)) {
@@ -37,10 +48,8 @@ scoped_refptr<DrmFramebuffer> DrmFramebuffer::AddFramebuffer(
return nullptr;
}
- uint32_t opaque_format = GetFourCCFormatForOpaqueFramebuffer(
- GetBufferFormatFromFourCCFormat(params.format));
uint32_t opaque_framebuffer_id = 0;
- if (opaque_format != params.format &&
+ if (opaque_format != drm_format &&
!drm_device->AddFramebuffer2(params.width, params.height, opaque_format,
params.handles, params.strides,
params.offsets, modifiers,
@@ -51,22 +60,23 @@ scoped_refptr<DrmFramebuffer> DrmFramebuffer::AddFramebuffer(
}
return base::MakeRefCounted<DrmFramebuffer>(
- std::move(drm_device), framebuffer_id, params.format,
- opaque_framebuffer_id, opaque_format, params.modifier,
- params.preferred_modifiers, gfx::Size(params.width, params.height));
+ std::move(drm_device), framebuffer_id, drm_format, opaque_framebuffer_id,
+ opaque_format, params.modifier, params.preferred_modifiers,
+ gfx::Size(params.width, params.height));
}
// static
scoped_refptr<DrmFramebuffer> DrmFramebuffer::AddFramebuffer(
scoped_refptr<DrmDevice> drm,
const GbmBuffer* buffer,
+ const gfx::Size& framebuffer_size,
std::vector<uint64_t> preferred_modifiers) {
- gfx::Size size = buffer->GetSize();
+ DCHECK(gfx::Rect(buffer->GetSize()).Contains(gfx::Rect(framebuffer_size)));
AddFramebufferParams params;
params.format = buffer->GetFormat();
params.modifier = buffer->GetFormatModifier();
- params.width = size.width();
- params.height = size.height();
+ params.width = framebuffer_size.width();
+ params.height = framebuffer_size.height();
params.num_planes = buffer->GetNumPlanes();
params.preferred_modifiers = preferred_modifiers;
for (size_t i = 0; i < params.num_planes; ++i) {
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.h b/chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.h
index 9c3991e6b7c..079297ac1a7 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_framebuffer.h
@@ -45,6 +45,7 @@ class DrmFramebuffer : public base::RefCountedThreadSafe<DrmFramebuffer> {
static scoped_refptr<DrmFramebuffer> AddFramebuffer(
scoped_refptr<DrmDevice> drm_device,
const GbmBuffer* buffer,
+ const gfx::Size& framebuffer_size,
std::vector<uint64_t> preferred_modifiers = std::vector<uint64_t>());
DrmFramebuffer(scoped_refptr<DrmDevice> drm_device,
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc b/chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
index e1c2075e66a..74a5f19d91c 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.cc
@@ -11,7 +11,7 @@
#include "ui/display/types/display_mode.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/display/types/gamma_ramp_rgb_entry.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
+#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
#include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
@@ -68,11 +68,10 @@ bool FindMatchingMode(const std::vector<drmModeModeInfo> modes,
DrmGpuDisplayManager::DrmGpuDisplayManager(ScreenManager* screen_manager,
DrmDeviceManager* drm_device_manager)
- : screen_manager_(screen_manager), drm_device_manager_(drm_device_manager) {
-}
+ : screen_manager_(screen_manager),
+ drm_device_manager_(drm_device_manager) {}
-DrmGpuDisplayManager::~DrmGpuDisplayManager() {
-}
+DrmGpuDisplayManager::~DrmGpuDisplayManager() = default;
void DrmGpuDisplayManager::SetClearOverlayCacheCallback(
base::RepeatingClosure callback) {
@@ -87,6 +86,9 @@ MovableDisplaySnapshots DrmGpuDisplayManager::GetDisplays() {
const DrmDeviceVector& devices = drm_device_manager_->GetDrmDevices();
size_t device_index = 0;
for (const auto& drm : devices) {
+ // Receiving a signal that DRM state was updated. Need to reset the plane
+ // manager's resource cache since IDs may have changed.
+ drm->plane_manager()->ResetConnectorsCache(drm->GetResources());
auto display_infos = GetAvailableDisplayControllerInfos(drm->get_fd());
for (const auto& display_info : display_infos) {
auto it = std::find_if(
@@ -215,9 +217,8 @@ void DrmGpuDisplayManager::SetColorMatrix(
display->SetColorMatrix(color_matrix);
}
-void DrmGpuDisplayManager::SetBackgroundColor(
- int64_t display_id,
- const uint64_t background_color) {
+void DrmGpuDisplayManager::SetBackgroundColor(int64_t display_id,
+ const uint64_t background_color) {
DrmDisplay* display = FindDisplay(display_id);
if (!display) {
LOG(ERROR) << "There is no display with ID" << display_id;
@@ -239,6 +240,16 @@ void DrmGpuDisplayManager::SetGammaCorrection(
display->SetGammaCorrection(degamma_lut, gamma_lut);
}
+void DrmGpuDisplayManager::SetPrivacyScreen(int64_t display_id, bool enabled) {
+ DrmDisplay* display = FindDisplay(display_id);
+ if (!display) {
+ LOG(ERROR) << "There is no display with ID " << display_id;
+ return;
+ }
+
+ display->SetPrivacyScreen(enabled);
+}
+
DrmDisplay* DrmGpuDisplayManager::FindDisplay(int64_t display_id) {
for (const auto& display : displays_) {
if (display->display_id() == display_id)
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h b/chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h
index e2af38c90f0..885732aaaaf 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_gpu_display_manager.h
@@ -58,6 +58,7 @@ class DrmGpuDisplayManager {
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
+ void SetPrivacyScreen(int64_t display_id, bool enabled);
private:
DrmDisplay* FindDisplay(int64_t display_id);
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.cc b/chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.cc
index 518916ce903..bc1ab154808 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.cc
@@ -4,8 +4,11 @@
#include "ui/ozone/platform/drm/gpu/drm_gpu_util.h"
+#include <fcntl.h>
+#include <xf86drm.h>
#include <xf86drmMode.h>
+#include "base/files/scoped_file.h"
#include "base/trace_event/trace_event.h"
#include "ui/display/types/gamma_ramp_rgb_entry.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
@@ -117,4 +120,23 @@ std::vector<display::GammaRampRGBEntry> ResampleLut(
return result;
}
+bool IsDriverName(const char* device_file_name, const char* driver) {
+ base::ScopedFD fd(open(device_file_name, O_RDWR));
+ if (!fd.is_valid()) {
+ LOG(ERROR) << "Failed to open DRM device " << device_file_name;
+ return false;
+ }
+
+ ScopedDrmVersionPtr version(drmGetVersion(fd.get()));
+ if (!version) {
+ LOG(ERROR) << "Failed to query DRM version " << device_file_name;
+ return false;
+ }
+
+ if (strncmp(driver, version->name, version->name_len) == 0)
+ return true;
+
+ return false;
+}
+
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.h b/chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.h
index 1972bef7af4..ab04da742d3 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_gpu_util.h
@@ -36,6 +36,9 @@ std::vector<display::GammaRampRGBEntry> ResampleLut(
const std::vector<display::GammaRampRGBEntry>& lut_in,
size_t desired_size);
+// Check DRM driver name match.
+bool IsDriverName(const char* device_file_name, const char* driver);
+
} // namespace ui
#endif // UI_OZONE_PLATFORM_DRM_GPU_DRM_GPU_UTIL_H_
diff --git a/chromium/ui/ozone/platform/drm/common/drm_overlay_candidates.cc b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_candidates.cc
index 97b0deedc49..24f26109b82 100644
--- a/chromium/ui/ozone/platform/drm/common/drm_overlay_candidates.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_candidates.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/ozone/platform/drm/common/drm_overlay_candidates.h"
+#include "ui/ozone/platform/drm/gpu/drm_overlay_candidates.h"
-#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
+#include "ui/ozone/platform/drm/gpu/drm_overlay_manager.h"
#include "ui/ozone/public/overlay_surface_candidate.h"
namespace ui {
diff --git a/chromium/ui/ozone/platform/drm/common/drm_overlay_candidates.h b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_candidates.h
index b0b49fb6eb0..bd9577ea8e7 100644
--- a/chromium/ui/ozone/platform/drm/common/drm_overlay_candidates.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_candidates.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_CANDIDATES_H_
-#define UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_CANDIDATES_H_
+#ifndef UI_OZONE_PLATFORM_DRM_GPU_DRM_OVERLAY_CANDIDATES_H_
+#define UI_OZONE_PLATFORM_DRM_GPU_DRM_OVERLAY_CANDIDATES_H_
#include <vector>
@@ -36,4 +36,4 @@ class DrmOverlayCandidates : public OverlayCandidatesOzone {
} // namespace ui
-#endif // UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_CANDIDATES_H_
+#endif // UI_OZONE_PLATFORM_DRM_GPU_DRM_OVERLAY_CANDIDATES_H_
diff --git a/chromium/ui/ozone/platform/drm/common/drm_overlay_manager.cc b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc
index 2c53f4adbc6..686e6633801 100644
--- a/chromium/ui/ozone/platform/drm/common/drm_overlay_manager.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
+#include "ui/ozone/platform/drm/gpu/drm_overlay_manager.h"
#include <algorithm>
#include <memory>
@@ -10,21 +10,34 @@
#include "base/metrics/histogram_macros.h"
#include "base/trace_event/trace_event.h"
+#include "ui/base/ui_base_features.h"
#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/ozone/platform/drm/common/drm_overlay_candidates.h"
+#include "ui/ozone/platform/drm/gpu/drm_overlay_candidates.h"
#include "ui/ozone/public/overlay_surface_candidate.h"
namespace ui {
namespace {
// Maximum number of overlay configurations to keep in MRU cache.
-constexpr size_t kMaxCacheSize = 10;
+constexpr size_t kMaxCacheSize = 100;
// How many times an overlay configuration needs to be requested before sending
// a query to display controller to see if the request will work. The overlay
// configuration will be rejected until a query is sent and response received.
constexpr int kThrottleRequestSize = 3;
+// Returns |candidates| but with all NativePixmap pointers removed in order to
+// avoid keeping them alive.
+std::vector<OverlaySurfaceCandidate> ToCacheKey(
+ const std::vector<OverlaySurfaceCandidate>& candidates) {
+ std::vector<OverlaySurfaceCandidate> result = candidates;
+ for (auto& candidate : result) {
+ // Make sure the cache entry does not keep the NativePixmap alive.
+ candidate.native_pixmap = nullptr;
+ }
+ return result;
+}
+
} // namespace
DrmOverlayManager::DrmOverlayManager() {
@@ -66,13 +79,28 @@ void DrmOverlayManager::CheckOverlaySupport(
result_candidates.back().overlay_handled = can_handle;
}
+ if (features::IsSynchronousPageFlipTestingEnabled()) {
+ std::vector<OverlayStatus> status =
+ SendOverlayValidationRequestSync(result_candidates, widget);
+ size_t size = candidates->size();
+ DCHECK_EQ(size, status.size());
+ for (size_t i = 0; i < size; i++) {
+ DCHECK(status[i] == OVERLAY_STATUS_ABLE ||
+ status[i] == OVERLAY_STATUS_NOT);
+ candidates->at(i).overlay_handled = status[i] == OVERLAY_STATUS_ABLE;
+ }
+ return;
+ }
+
auto widget_cache_map_it = widget_cache_map_.find(widget);
if (widget_cache_map_it == widget_cache_map_.end()) {
widget_cache_map_it =
widget_cache_map_.emplace(widget, kMaxCacheSize).first;
}
OverlayCandidatesListCache& cache = widget_cache_map_it->second;
- auto iter = cache.Get(result_candidates);
+ std::vector<OverlaySurfaceCandidate> cache_key =
+ ToCacheKey(result_candidates);
+ auto iter = cache.Get(cache_key);
if (iter == cache.end()) {
// We can skip GPU side validation in case all candidates are invalid.
bool needs_gpu_validation = std::any_of(
@@ -82,7 +110,7 @@ void DrmOverlayManager::CheckOverlaySupport(
value.status.resize(result_candidates.size(), needs_gpu_validation
? OVERLAY_STATUS_PENDING
: OVERLAY_STATUS_NOT);
- iter = cache.Put(result_candidates, std::move(value));
+ iter = cache.Put(cache_key, std::move(value));
}
bool cache_hit = false;
@@ -104,7 +132,8 @@ void DrmOverlayManager::CheckOverlaySupport(
candidates->at(i).overlay_handled = status[i] == OVERLAY_STATUS_ABLE;
}
}
- UMA_HISTOGRAM_BOOLEAN("DrmOverlayManager.CacheHit", cache_hit);
+ UMA_HISTOGRAM_BOOLEAN("Compositing.Display.DrmOverlayManager.CacheHit",
+ cache_hit);
}
bool DrmOverlayManager::CanHandleCandidate(
@@ -139,7 +168,7 @@ void DrmOverlayManager::UpdateCacheForOverlayCandidates(
return;
OverlayCandidatesListCache& cache = widget_cache_map_it->second;
- auto iter = cache.Peek(candidates);
+ auto iter = cache.Peek(ToCacheKey(candidates));
if (iter != cache.end())
iter->second.status = status;
}
diff --git a/chromium/ui/ozone/platform/drm/common/drm_overlay_manager.h b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager.h
index f748fe4fa41..87173fa824a 100644
--- a/chromium/ui/ozone/platform/drm/common/drm_overlay_manager.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_MANAGER_H_
-#define UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_MANAGER_H_
+#ifndef UI_OZONE_PLATFORM_DRM_GPU_DRM_OVERLAY_MANAGER_H_
+#define UI_OZONE_PLATFORM_DRM_GPU_DRM_OVERLAY_MANAGER_H_
#include <memory>
#include <vector>
@@ -46,9 +46,15 @@ class DrmOverlayManager : public OverlayManagerOzone {
const std::vector<OverlaySurfaceCandidate>& candidates,
gfx::AcceleratedWidget widget) = 0;
+ // Similar to SendOverlayValidationRequest() but instead of calling
+ // UpdateCacheForOverlayCandidates(), returns the result synchronously.
+ virtual std::vector<OverlayStatus> SendOverlayValidationRequestSync(
+ const std::vector<OverlaySurfaceCandidate>& candidates,
+ gfx::AcceleratedWidget widget) = 0;
+
// Perform basic validation to see if |candidate| is a valid request.
- virtual bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate,
- gfx::AcceleratedWidget widget) const;
+ bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate,
+ gfx::AcceleratedWidget widget) const;
// Updates the MRU cache for overlay configuration |candidates| with |status|.
void UpdateCacheForOverlayCandidates(
@@ -86,4 +92,4 @@ class DrmOverlayManager : public OverlayManagerOzone {
} // namespace ui
-#endif // UI_OZONE_PLATFORM_DRM_COMMON_DRM_OVERLAY_MANAGER_H_
+#endif // UI_OZONE_PLATFORM_DRM_GPU_DRM_OVERLAY_MANAGER_H_
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc
index ecadeb3c81d..2137523fbd8 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.cc
@@ -23,7 +23,25 @@ void DrmOverlayManagerGpu::SendOverlayValidationRequest(
gfx::AcceleratedWidget widget) {
TRACE_EVENT_ASYNC_BEGIN0(
"hwoverlays", "DrmOverlayManagerGpu::SendOverlayValidationRequest", this);
+ SetClearCacheCallbackIfNecessary();
+ drm_thread_proxy_->CheckOverlayCapabilities(
+ widget, candidates,
+ base::BindOnce(&DrmOverlayManagerGpu::ReceiveOverlayValidationResponse,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+std::vector<OverlayStatus>
+DrmOverlayManagerGpu::SendOverlayValidationRequestSync(
+ const std::vector<OverlaySurfaceCandidate>& candidates,
+ gfx::AcceleratedWidget widget) {
+ TRACE_EVENT_ASYNC_BEGIN0(
+ "hwoverlays", "DrmOverlayManagerGpu::SendOverlayValidationRequestSync",
+ this);
+ SetClearCacheCallbackIfNecessary();
+ return drm_thread_proxy_->CheckOverlayCapabilitiesSync(widget, candidates);
+}
+
+void DrmOverlayManagerGpu::SetClearCacheCallbackIfNecessary() {
// Adds a callback for the DRM thread to let us know when display
// configuration has changed and to reset cache of valid overlay
// configurations. This happens in SendOverlayValidationRequest() because the
@@ -35,11 +53,6 @@ void DrmOverlayManagerGpu::SendOverlayValidationRequest(
drm_thread_proxy_->SetClearOverlayCacheCallback(base::BindRepeating(
&DrmOverlayManagerGpu::ResetCache, weak_ptr_factory_.GetWeakPtr()));
}
-
- drm_thread_proxy_->CheckOverlayCapabilities(
- widget, candidates,
- base::BindOnce(&DrmOverlayManagerGpu::ReceiveOverlayValidationResponse,
- weak_ptr_factory_.GetWeakPtr()));
}
void DrmOverlayManagerGpu::ReceiveOverlayValidationResponse(
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.h b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.h
index da66930887f..3931e02dac5 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_gpu.h
@@ -9,7 +9,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
+#include "ui/ozone/platform/drm/gpu/drm_overlay_manager.h"
namespace ui {
class DrmThreadProxy;
@@ -26,6 +26,11 @@ class DrmOverlayManagerGpu : public DrmOverlayManager {
void SendOverlayValidationRequest(
const std::vector<OverlaySurfaceCandidate>& candidates,
gfx::AcceleratedWidget widget) override;
+ std::vector<OverlayStatus> SendOverlayValidationRequestSync(
+ const std::vector<OverlaySurfaceCandidate>& candidates,
+ gfx::AcceleratedWidget widget) override;
+
+ void SetClearCacheCallbackIfNecessary();
void ReceiveOverlayValidationResponse(
gfx::AcceleratedWidget widget,
diff --git a/chromium/ui/ozone/platform/drm/common/drm_overlay_manager_unittest.cc b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_unittest.cc
index 6d13aae57e1..a668e215095 100644
--- a/chromium/ui/ozone/platform/drm/common/drm_overlay_manager_unittest.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_manager_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
+#include "ui/ozone/platform/drm/gpu/drm_overlay_manager.h"
#include "base/bind.h"
#include "base/callback.h"
@@ -33,6 +33,11 @@ class TestDrmOverlayManager : public DrmOverlayManager {
gfx::AcceleratedWidget widget) override {
requests_.push_back(candidates);
}
+ std::vector<OverlayStatus> SendOverlayValidationRequestSync(
+ const std::vector<OverlaySurfaceCandidate>& candidates,
+ gfx::AcceleratedWidget widget) override {
+ return {};
+ }
private:
std::vector<std::vector<OverlaySurfaceCandidate>> requests_;
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
index 27ce37a0be7..4c496547411 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
@@ -9,15 +9,17 @@
#include <vector>
#include "base/files/platform_file.h"
+#include "base/metrics/histogram_macros.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/gpu_fence.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
+#include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_buffer.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
#include "ui/ozone/platform/drm/gpu/drm_framebuffer.h"
#include "ui/ozone/platform/drm/gpu/drm_window.h"
+#include "ui/ozone/platform/drm/gpu/gbm_pixmap.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
namespace ui {
@@ -27,7 +29,12 @@ namespace {
scoped_refptr<DrmFramebuffer> GetBufferForPageFlipTest(
const DrmWindow* drm_window,
const OverlaySurfaceCandidate& overlay_surface,
- std::vector<scoped_refptr<DrmFramebuffer>>* reusable_buffers) {
+ std::vector<scoped_refptr<DrmFramebuffer>>* reusable_buffers,
+ size_t* total_allocated_memory_size) {
+ if (overlay_surface.native_pixmap) {
+ return static_cast<GbmPixmap*>(overlay_surface.native_pixmap.get())
+ ->framebuffer();
+ }
uint32_t fourcc_format =
overlay_surface.is_opaque
? GetFourCCFormatForOpaqueFramebuffer(overlay_surface.format)
@@ -58,11 +65,16 @@ scoped_refptr<DrmFramebuffer> GetBufferForPageFlipTest(
fourcc_format, size, GBM_BO_USE_SCANOUT, modifiers)
: drm_device->gbm_device()->CreateBuffer(fourcc_format, size,
GBM_BO_USE_SCANOUT);
+
if (!buffer)
return nullptr;
+ for (size_t i = 0; i < buffer->GetNumPlanes(); ++i)
+ *total_allocated_memory_size += buffer->GetPlaneSize(i);
+
scoped_refptr<DrmFramebuffer> drm_framebuffer =
- DrmFramebuffer::AddFramebuffer(drm_device, buffer.get(), modifiers);
+ DrmFramebuffer::AddFramebuffer(drm_device, buffer.get(),
+ buffer->GetSize(), modifiers);
if (!drm_framebuffer)
return nullptr;
@@ -96,14 +108,16 @@ OverlayStatusList DrmOverlayValidator::TestPageFlip(
for (const auto& plane : last_used_planes)
reusable_buffers.push_back(plane.buffer);
+ size_t total_allocated_memory_size = 0;
+
for (size_t i = 0; i < params.size(); ++i) {
if (!params[i].overlay_handled) {
returns[i] = OVERLAY_STATUS_NOT;
continue;
}
- scoped_refptr<DrmFramebuffer> buffer =
- GetBufferForPageFlipTest(window_, params[i], &reusable_buffers);
+ scoped_refptr<DrmFramebuffer> buffer = GetBufferForPageFlipTest(
+ window_, params[i], &reusable_buffers, &total_allocated_memory_size);
DrmOverlayPlane plane(buffer, params[i].plane_z_order, params[i].transform,
gfx::ToNearestRect(params[i].display_rect),
@@ -125,6 +139,10 @@ OverlayStatusList DrmOverlayValidator::TestPageFlip(
}
}
+ UMA_HISTOGRAM_MEMORY_KB(
+ "Compositing.Display.DrmOverlayManager.TotalTestBufferMemorySize",
+ total_allocated_memory_size / 1024);
+
return returns;
}
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
index e6517340906..cc86756bdf3 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator_unittest.cc
@@ -14,9 +14,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/gpu_fence.h"
+#include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_buffer.h"
+#include "ui/gfx/linux/test/mock_gbm_device.h"
#include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
@@ -25,7 +26,6 @@
#include "ui/ozone/platform/drm/gpu/drm_window.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
#include "ui/ozone/platform/drm/gpu/mock_drm_device.h"
-#include "ui/ozone/platform/drm/gpu/mock_gbm_device.h"
#include "ui/ozone/platform/drm/gpu/screen_manager.h"
namespace {
@@ -40,14 +40,14 @@ constexpr uint32_t kConnectorIdBase = 100;
constexpr uint32_t kPlaneIdBase = 200;
constexpr uint32_t kInFormatsBlobPropIdBase = 400;
-constexpr uint32_t kTypePropId = 300;
-constexpr uint32_t kInFormatsPropId = 301;
+constexpr uint32_t kTypePropId = 3010;
+constexpr uint32_t kInFormatsPropId = 3011;
} // namespace
class DrmOverlayValidatorTest : public testing::Test {
public:
- DrmOverlayValidatorTest() {}
+ DrmOverlayValidatorTest() = default;
void SetUp() override;
void TearDown() override;
@@ -67,14 +67,15 @@ class DrmOverlayValidatorTest : public testing::Test {
scoped_refptr<ui::DrmFramebuffer> CreateBuffer() {
auto gbm_buffer = drm_->gbm_device()->CreateBuffer(
DRM_FORMAT_XRGB8888, primary_rect_.size(), GBM_BO_USE_SCANOUT);
- return ui::DrmFramebuffer::AddFramebuffer(drm_, gbm_buffer.get());
+ return ui::DrmFramebuffer::AddFramebuffer(drm_, gbm_buffer.get(),
+ primary_rect_.size());
}
scoped_refptr<ui::DrmFramebuffer> CreateOverlayBuffer(uint32_t format,
const gfx::Size& size) {
auto gbm_buffer =
drm_->gbm_device()->CreateBuffer(format, size, GBM_BO_USE_SCANOUT);
- return ui::DrmFramebuffer::AddFramebuffer(drm_, gbm_buffer.get());
+ return ui::DrmFramebuffer::AddFramebuffer(drm_, gbm_buffer.get(), size);
}
protected:
@@ -86,7 +87,7 @@ class DrmOverlayValidatorTest : public testing::Test {
std::vector<PlaneState> planes;
};
- void InitializeDrmState(const std::vector<CrtcState>& crtc_states);
+ void InitDrmStatesAndControllers(const std::vector<CrtcState>& crtc_states);
base::test::SingleThreadTaskEnvironment task_environment_{
base::test::SingleThreadTaskEnvironment::MainThreadType::UI};
@@ -105,6 +106,8 @@ class DrmOverlayValidatorTest : public testing::Test {
gfx::Rect primary_rect_;
private:
+ void SetupControllers();
+
DISALLOW_COPY_AND_ASSIGN(DrmOverlayValidatorTest);
};
@@ -115,70 +118,42 @@ void DrmOverlayValidatorTest::SetUp() {
auto gbm = std::make_unique<ui::MockGbmDevice>();
gbm_ = gbm.get();
drm_ = new ui::MockDrmDevice(std::move(gbm));
-
- CrtcState crtc_state = {/* .planes = */ {
- {/* .formats = */ {DRM_FORMAT_XRGB8888}},
- }};
- InitializeDrmState({crtc_state});
-
- screen_manager_ = std::make_unique<ui::ScreenManager>();
- screen_manager_->AddDisplayController(drm_, kCrtcIdBase, kConnectorIdBase);
- screen_manager_->ConfigureDisplayController(
- drm_, kCrtcIdBase, kConnectorIdBase, gfx::Point(), kDefaultMode);
-
- drm_device_manager_ = std::make_unique<ui::DrmDeviceManager>(nullptr);
-
- std::unique_ptr<ui::DrmWindow> window(new ui::DrmWindow(
- kDefaultWidgetHandle, drm_device_manager_.get(), screen_manager_.get()));
- window->Initialize();
- window->SetBounds(
- gfx::Rect(gfx::Size(kDefaultMode.hdisplay, kDefaultMode.vdisplay)));
- screen_manager_->AddWindow(kDefaultWidgetHandle, std::move(window));
- window_ = screen_manager_->GetWindow(kDefaultWidgetHandle);
- overlay_validator_ = std::make_unique<ui::DrmOverlayValidator>(window_);
-
- overlay_rect_ =
- gfx::Rect(0, 0, kDefaultMode.hdisplay / 2, kDefaultMode.vdisplay / 2);
-
- primary_rect_ = gfx::Rect(0, 0, kDefaultMode.hdisplay, kDefaultMode.vdisplay);
-
- ui::OverlaySurfaceCandidate primary_candidate;
- primary_candidate.buffer_size = primary_rect_.size();
- primary_candidate.display_rect = gfx::RectF(primary_rect_);
- primary_candidate.is_opaque = true;
- primary_candidate.format = gfx::BufferFormat::BGRX_8888;
- primary_candidate.overlay_handled = true;
- overlay_params_.push_back(primary_candidate);
- AddPlane(primary_candidate);
-
- ui::OverlaySurfaceCandidate overlay_candidate;
- overlay_candidate.buffer_size = overlay_rect_.size();
- overlay_candidate.display_rect = gfx::RectF(overlay_rect_);
- overlay_candidate.plane_z_order = 1;
- primary_candidate.is_opaque = true;
- overlay_candidate.format = gfx::BufferFormat::BGRX_8888;
- overlay_candidate.overlay_handled = true;
- overlay_params_.push_back(overlay_candidate);
- AddPlane(overlay_candidate);
}
-void DrmOverlayValidatorTest::InitializeDrmState(
+void DrmOverlayValidatorTest::InitDrmStatesAndControllers(
const std::vector<CrtcState>& crtc_states) {
std::vector<ui::MockDrmDevice::CrtcProperties> crtc_properties(
crtc_states.size());
+ std::map<uint32_t, std::string> crtc_property_names = {
+ {1000, "ACTIVE"},
+ {1001, "MODE_ID"},
+ };
+
+ std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(2);
+ std::map<uint32_t, std::string> connector_property_names = {
+ {2000, "CRTC_ID"},
+ };
+ for (size_t i = 0; i < connector_properties.size(); ++i) {
+ connector_properties[i].id = kConnectorIdBase + i;
+ for (const auto& pair : connector_property_names) {
+ connector_properties[i].properties.push_back(
+ {/* .id = */ pair.first, /* .value = */ 0});
+ }
+ }
+
std::vector<ui::MockDrmDevice::PlaneProperties> plane_properties;
- std::map<uint32_t, std::string> property_names = {
+ std::map<uint32_t, std::string> plane_property_names = {
// Add all required properties.
- {1000, "CRTC_ID"},
- {1001, "CRTC_X"},
- {1002, "CRTC_Y"},
- {1003, "CRTC_W"},
- {1004, "CRTC_H"},
- {1005, "FB_ID"},
- {1006, "SRC_X"},
- {1007, "SRC_Y"},
- {1008, "SRC_W"},
- {1009, "SRC_H"},
+ {3000, "CRTC_ID"},
+ {3001, "CRTC_X"},
+ {3002, "CRTC_Y"},
+ {3003, "CRTC_W"},
+ {3004, "CRTC_H"},
+ {3005, "FB_ID"},
+ {3006, "SRC_X"},
+ {3007, "SRC_Y"},
+ {3008, "SRC_W"},
+ {3009, "SRC_H"},
// Defines some optional properties we use for convenience.
{kTypePropId, "type"},
{kInFormatsPropId, "IN_FORMATS"},
@@ -189,6 +164,10 @@ void DrmOverlayValidatorTest::InitializeDrmState(
for (size_t crtc_idx = 0; crtc_idx < crtc_states.size(); ++crtc_idx) {
crtc_properties[crtc_idx].id = kCrtcIdBase + crtc_idx;
+ for (const auto& pair : crtc_property_names) {
+ crtc_properties[crtc_idx].properties.push_back(
+ {/* .id = */ pair.first, /* .value = */ 0});
+ }
std::vector<ui::MockDrmDevice::PlaneProperties> crtc_plane_properties(
crtc_states[crtc_idx].planes.size());
@@ -197,7 +176,7 @@ void DrmOverlayValidatorTest::InitializeDrmState(
crtc_plane_properties[plane_idx].id = plane_id++;
crtc_plane_properties[plane_idx].crtc_mask = 1 << crtc_idx;
- for (const auto& pair : property_names) {
+ for (const auto& pair : plane_property_names) {
uint64_t value = 0;
if (pair.first == kTypePropId) {
value =
@@ -219,8 +198,59 @@ void DrmOverlayValidatorTest::InitializeDrmState(
crtc_plane_properties.end());
}
- drm_->InitializeState(crtc_properties, plane_properties, property_names,
+ std::map<uint32_t, std::string> property_names;
+ property_names.insert(crtc_property_names.begin(), crtc_property_names.end());
+ property_names.insert(connector_property_names.begin(),
+ connector_property_names.end());
+ property_names.insert(plane_property_names.begin(),
+ plane_property_names.end());
+ drm_->InitializeState(crtc_properties, connector_properties, plane_properties,
+ property_names,
/* use_atomic= */ true);
+
+ SetupControllers();
+}
+
+void DrmOverlayValidatorTest::SetupControllers() {
+ screen_manager_ = std::make_unique<ui::ScreenManager>();
+ screen_manager_->AddDisplayController(drm_, kCrtcIdBase, kConnectorIdBase);
+ screen_manager_->ConfigureDisplayController(
+ drm_, kCrtcIdBase, kConnectorIdBase, gfx::Point(), kDefaultMode);
+
+ drm_device_manager_ = std::make_unique<ui::DrmDeviceManager>(nullptr);
+
+ std::unique_ptr<ui::DrmWindow> window(new ui::DrmWindow(
+ kDefaultWidgetHandle, drm_device_manager_.get(), screen_manager_.get()));
+ window->Initialize();
+ window->SetBounds(
+ gfx::Rect(gfx::Size(kDefaultMode.hdisplay, kDefaultMode.vdisplay)));
+ screen_manager_->AddWindow(kDefaultWidgetHandle, std::move(window));
+ window_ = screen_manager_->GetWindow(kDefaultWidgetHandle);
+ overlay_validator_ = std::make_unique<ui::DrmOverlayValidator>(window_);
+
+ overlay_rect_ =
+ gfx::Rect(0, 0, kDefaultMode.hdisplay / 2, kDefaultMode.vdisplay / 2);
+
+ primary_rect_ = gfx::Rect(0, 0, kDefaultMode.hdisplay, kDefaultMode.vdisplay);
+
+ ui::OverlaySurfaceCandidate primary_candidate;
+ primary_candidate.buffer_size = primary_rect_.size();
+ primary_candidate.display_rect = gfx::RectF(primary_rect_);
+ primary_candidate.is_opaque = true;
+ primary_candidate.format = gfx::BufferFormat::BGRX_8888;
+ primary_candidate.overlay_handled = true;
+ overlay_params_.push_back(primary_candidate);
+ AddPlane(primary_candidate);
+
+ ui::OverlaySurfaceCandidate overlay_candidate;
+ overlay_candidate.buffer_size = overlay_rect_.size();
+ overlay_candidate.display_rect = gfx::RectF(overlay_rect_);
+ overlay_candidate.plane_z_order = 1;
+ primary_candidate.is_opaque = true;
+ overlay_candidate.format = gfx::BufferFormat::BGRX_8888;
+ overlay_candidate.overlay_handled = true;
+ overlay_params_.push_back(overlay_candidate);
+ AddPlane(overlay_candidate);
}
void DrmOverlayValidatorTest::AddPlane(
@@ -242,6 +272,11 @@ void DrmOverlayValidatorTest::TearDown() {
}
TEST_F(DrmOverlayValidatorTest, WindowWithNoController) {
+ CrtcState crtc_state = {/* .planes = */ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ }};
+ InitDrmStatesAndControllers({crtc_state});
+
// We should never promote layers to overlay when controller is not
// present.
ui::HardwareDisplayController* controller = window_->GetController();
@@ -254,6 +289,11 @@ TEST_F(DrmOverlayValidatorTest, WindowWithNoController) {
}
TEST_F(DrmOverlayValidatorTest, DontPromoteMoreLayersThanAvailablePlanes) {
+ CrtcState crtc_state = {/* .planes = */ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ }};
+ InitDrmStatesAndControllers({crtc_state});
+
std::vector<ui::OverlayStatus> returns = overlay_validator_->TestPageFlip(
overlay_params_, ui::DrmOverlayPlaneList());
EXPECT_EQ(returns.front(), ui::OVERLAY_STATUS_ABLE);
@@ -261,6 +301,11 @@ TEST_F(DrmOverlayValidatorTest, DontPromoteMoreLayersThanAvailablePlanes) {
}
TEST_F(DrmOverlayValidatorTest, DontCollapseOverlayToPrimaryInFullScreen) {
+ CrtcState crtc_state = {/* .planes = */ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ }};
+ InitDrmStatesAndControllers({crtc_state});
+
// Overlay Validator should not collapse planes during validation.
overlay_params_.back().buffer_size = primary_rect_.size();
overlay_params_.back().display_rect = gfx::RectF(primary_rect_);
@@ -277,10 +322,6 @@ TEST_F(DrmOverlayValidatorTest, DontCollapseOverlayToPrimaryInFullScreen) {
TEST_F(DrmOverlayValidatorTest, OverlayFormat_XRGB) {
// This test checks for optimal format in case of non full screen video case.
// This should be XRGB when overlay doesn't support YUV.
- overlay_params_.back().buffer_size = overlay_rect_.size();
- overlay_params_.back().display_rect = gfx::RectF(overlay_rect_);
- plane_list_.back().display_bounds = overlay_rect_;
-
CrtcState state = {
/* .planes = */
{
@@ -288,7 +329,11 @@ TEST_F(DrmOverlayValidatorTest, OverlayFormat_XRGB) {
{/* .formats = */ {DRM_FORMAT_XRGB8888}},
},
};
- InitializeDrmState(std::vector<CrtcState>(1, state));
+ InitDrmStatesAndControllers(std::vector<CrtcState>(1, state));
+
+ overlay_params_.back().buffer_size = overlay_rect_.size();
+ overlay_params_.back().display_rect = gfx::RectF(overlay_rect_);
+ plane_list_.back().display_bounds = overlay_rect_;
std::vector<ui::OverlayStatus> returns = overlay_validator_->TestPageFlip(
overlay_params_, ui::DrmOverlayPlaneList());
@@ -301,6 +346,15 @@ TEST_F(DrmOverlayValidatorTest, OverlayFormat_YUV) {
// This test checks for optimal format in case of non full screen video case.
// Prefer YUV as optimal format when Overlay supports it and scaling is
// needed.
+ CrtcState state = {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
+ },
+ };
+ InitDrmStatesAndControllers(std::vector<CrtcState>(1, state));
+
gfx::RectF crop_rect = gfx::RectF(0, 0, 0.5, 0.5);
overlay_params_.back().buffer_size = overlay_rect_.size();
overlay_params_.back().display_rect = gfx::RectF(overlay_rect_);
@@ -310,15 +364,6 @@ TEST_F(DrmOverlayValidatorTest, OverlayFormat_YUV) {
plane_list_.pop_back();
AddPlane(overlay_params_.back());
- CrtcState state = {
- /* .planes = */
- {
- {/* .formats = */ {DRM_FORMAT_XRGB8888}},
- {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
- },
- };
- InitializeDrmState(std::vector<CrtcState>(1, state));
-
std::vector<ui::OverlayStatus> returns = overlay_validator_->TestPageFlip(
overlay_params_, ui::DrmOverlayPlaneList());
EXPECT_EQ(2u, returns.size());
@@ -329,12 +374,6 @@ TEST_F(DrmOverlayValidatorTest, OverlayFormat_YUV) {
TEST_F(DrmOverlayValidatorTest, RejectYUVBuffersIfNotSupported) {
// Check case where buffer storage format is already YUV 420 but planes don't
// support it.
- overlay_params_.back().buffer_size = overlay_rect_.size();
- overlay_params_.back().display_rect = gfx::RectF(overlay_rect_);
- overlay_params_.back().format = gfx::BufferFormat::YUV_420_BIPLANAR;
- plane_list_.pop_back();
- AddPlane(overlay_params_.back());
-
CrtcState state = {
/* .planes = */
{
@@ -342,7 +381,13 @@ TEST_F(DrmOverlayValidatorTest, RejectYUVBuffersIfNotSupported) {
{/* .formats = */ {DRM_FORMAT_XRGB8888}},
},
};
- InitializeDrmState(std::vector<CrtcState>(1, state));
+ InitDrmStatesAndControllers(std::vector<CrtcState>(1, state));
+
+ overlay_params_.back().buffer_size = overlay_rect_.size();
+ overlay_params_.back().display_rect = gfx::RectF(overlay_rect_);
+ overlay_params_.back().format = gfx::BufferFormat::YUV_420_BIPLANAR;
+ plane_list_.pop_back();
+ AddPlane(overlay_params_.back());
std::vector<ui::OverlaySurfaceCandidate> validated_params = overlay_params_;
std::vector<ui::OverlayStatus> returns = overlay_validator_->TestPageFlip(
@@ -369,7 +414,7 @@ TEST_F(DrmOverlayValidatorTest,
},
},
};
- InitializeDrmState(crtc_states);
+ InitDrmStatesAndControllers(crtc_states);
ui::HardwareDisplayController* controller = window_->GetController();
controller->AddCrtc(
@@ -392,30 +437,96 @@ TEST_F(DrmOverlayValidatorTest,
validated_params, ui::DrmOverlayPlaneList());
EXPECT_EQ(2u, returns.size());
EXPECT_EQ(returns.back(), ui::OVERLAY_STATUS_ABLE);
+}
+TEST_F(DrmOverlayValidatorTest,
+ RejectYUVBuffersIfNotSupported_NoPackedFormatsInMirroredCrtc) {
// This configuration should not be promoted to Overlay when either of the
// controllers don't support YUV 420 format.
- // Check case where we dont have support for packed formats in Mirrored CRTC.
- crtc_states[1].planes[1].formats = {DRM_FORMAT_XRGB8888};
- InitializeDrmState(crtc_states);
+ std::vector<CrtcState> crtc_states = {
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
+ },
+ },
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ },
+ },
+ };
+ InitDrmStatesAndControllers(crtc_states);
- returns = overlay_validator_->TestPageFlip(validated_params,
- ui::DrmOverlayPlaneList());
+ ui::HardwareDisplayController* controller = window_->GetController();
+ controller->AddCrtc(
+ std::unique_ptr<ui::CrtcController>(new ui::CrtcController(
+ drm_.get(), kCrtcIdBase + 1, kConnectorIdBase + 1)));
+ ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
+
+ EXPECT_TRUE(controller->Modeset(plane1, kDefaultMode));
+
+ gfx::RectF crop_rect = gfx::RectF(0, 0, 0.5, 0.5);
+ overlay_params_.back().buffer_size = overlay_rect_.size();
+ overlay_params_.back().display_rect = gfx::RectF(overlay_rect_);
+ overlay_params_.back().crop_rect = crop_rect;
+ plane_list_.back().display_bounds = overlay_rect_;
+ plane_list_.back().crop_rect = crop_rect;
+
+ std::vector<ui::OverlaySurfaceCandidate> validated_params = overlay_params_;
+ validated_params.back().format = gfx::BufferFormat::YUV_420_BIPLANAR;
+ std::vector<ui::OverlayStatus> returns = overlay_validator_->TestPageFlip(
+ validated_params, ui::DrmOverlayPlaneList());
EXPECT_EQ(2u, returns.size());
EXPECT_EQ(returns.back(), ui::OVERLAY_STATUS_NOT);
+}
- // Check case where we dont have support for packed formats in primary
- // display.
- crtc_states[0].planes[1].formats = {DRM_FORMAT_XRGB8888};
- crtc_states[1].planes[1].formats = {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12};
- InitializeDrmState(crtc_states);
+TEST_F(DrmOverlayValidatorTest,
+ RejectYUVBuffersIfNotSupported_NoPackedFormatsInPrimaryDisplay) {
+ std::vector<CrtcState> crtc_states = {
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ },
+ },
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
+ },
+ },
+ };
+ InitDrmStatesAndControllers(crtc_states);
+
+ ui::HardwareDisplayController* controller = window_->GetController();
+ controller->AddCrtc(
+ std::unique_ptr<ui::CrtcController>(new ui::CrtcController(
+ drm_.get(), kCrtcIdBase + 1, kConnectorIdBase + 1)));
+ ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
+
+ EXPECT_TRUE(controller->Modeset(plane1, kDefaultMode));
+
+ gfx::RectF crop_rect = gfx::RectF(0, 0, 0.5, 0.5);
+ overlay_params_.back().buffer_size = overlay_rect_.size();
+ overlay_params_.back().display_rect = gfx::RectF(overlay_rect_);
+ overlay_params_.back().crop_rect = crop_rect;
+ plane_list_.back().display_bounds = overlay_rect_;
+ plane_list_.back().crop_rect = crop_rect;
+
+ std::vector<ui::OverlaySurfaceCandidate> validated_params = overlay_params_;
+ validated_params.back().format = gfx::BufferFormat::YUV_420_BIPLANAR;
- returns = overlay_validator_->TestPageFlip(validated_params,
- ui::DrmOverlayPlaneList());
+ std::vector<ui::OverlayStatus> returns = overlay_validator_->TestPageFlip(
+ validated_params, ui::DrmOverlayPlaneList());
EXPECT_EQ(2u, returns.size());
EXPECT_EQ(returns.back(), ui::OVERLAY_STATUS_NOT);
- controller->RemoveCrtc(drm_, kCrtcIdBase + 1);
}
TEST_F(DrmOverlayValidatorTest, OptimalFormatXRGB_MirroredControllers) {
@@ -435,7 +546,7 @@ TEST_F(DrmOverlayValidatorTest, OptimalFormatXRGB_MirroredControllers) {
},
},
};
- InitializeDrmState(crtc_states);
+ InitDrmStatesAndControllers(crtc_states);
ui::HardwareDisplayController* controller = window_->GetController();
controller->AddCrtc(
@@ -452,30 +563,87 @@ TEST_F(DrmOverlayValidatorTest, OptimalFormatXRGB_MirroredControllers) {
overlay_params_, ui::DrmOverlayPlaneList());
EXPECT_EQ(2u, returns.size());
EXPECT_EQ(returns.back(), ui::OVERLAY_STATUS_ABLE);
+}
- // Check case where we dont have support for packed formats in Mirrored CRTC.
- crtc_states[1].planes[1].formats = {DRM_FORMAT_XRGB8888};
- InitializeDrmState(crtc_states);
+TEST_F(DrmOverlayValidatorTest,
+ OptimalFormatXRGB_NoPackedFormatInMirroredCrtc) {
+ std::vector<CrtcState> crtc_states = {
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
+ },
+ },
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ },
+ },
+ };
+ InitDrmStatesAndControllers(crtc_states);
+
+ ui::HardwareDisplayController* controller = window_->GetController();
+ controller->AddCrtc(
+ std::unique_ptr<ui::CrtcController>(new ui::CrtcController(
+ drm_.get(), kCrtcIdBase + 1, kConnectorIdBase + 1)));
+ ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
+ EXPECT_TRUE(controller->Modeset(plane1, kDefaultMode));
+
+ overlay_params_.back().buffer_size = overlay_rect_.size();
+ overlay_params_.back().display_rect = gfx::RectF(overlay_rect_);
+ plane_list_.back().display_bounds = overlay_rect_;
- returns = overlay_validator_->TestPageFlip(overlay_params_,
- ui::DrmOverlayPlaneList());
+ std::vector<ui::OverlayStatus> returns = overlay_validator_->TestPageFlip(
+ overlay_params_, ui::DrmOverlayPlaneList());
EXPECT_EQ(returns.back(), ui::OVERLAY_STATUS_ABLE);
+}
+
+TEST_F(DrmOverlayValidatorTest,
+ OptimalFormatXRGB_NoPackedFormatInPrimaryDisplay) {
+ std::vector<CrtcState> crtc_states = {
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ },
+ },
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
+ },
+ },
+ };
+ InitDrmStatesAndControllers(crtc_states);
+
+ ui::HardwareDisplayController* controller = window_->GetController();
+ controller->AddCrtc(
+ std::unique_ptr<ui::CrtcController>(new ui::CrtcController(
+ drm_.get(), kCrtcIdBase + 1, kConnectorIdBase + 1)));
+ ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
+ EXPECT_TRUE(controller->Modeset(plane1, kDefaultMode));
- // Check case where we dont have support for packed formats in primary
- // display.
- crtc_states[0].planes[1].formats = {DRM_FORMAT_XRGB8888};
- crtc_states[1].planes[1].formats = {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12};
- InitializeDrmState(crtc_states);
+ overlay_params_.back().buffer_size = overlay_rect_.size();
+ overlay_params_.back().display_rect = gfx::RectF(overlay_rect_);
+ plane_list_.back().display_bounds = overlay_rect_;
- returns = overlay_validator_->TestPageFlip(overlay_params_,
- ui::DrmOverlayPlaneList());
+ std::vector<ui::OverlayStatus> returns = overlay_validator_->TestPageFlip(
+ overlay_params_, ui::DrmOverlayPlaneList());
EXPECT_EQ(2u, returns.size());
EXPECT_EQ(returns.back(), ui::OVERLAY_STATUS_ABLE);
-
- controller->RemoveCrtc(drm_, kCrtcIdBase + 1);
}
TEST_F(DrmOverlayValidatorTest, RejectBufferAllocationFail) {
+ CrtcState crtc_state = {/* .planes = */ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ }};
+ InitDrmStatesAndControllers({crtc_state});
+
// Buffer allocation for scanout might fail.
// In that case we should reject the overlay candidate.
gbm_->set_allocation_failure(true);
@@ -490,9 +658,6 @@ TEST_F(DrmOverlayValidatorTest, RejectBufferAllocationFail) {
// candidates purely on the basis of having non-integer bounds. Instead, they
// should be rounded to the nearest integer.
TEST_F(DrmOverlayValidatorTest, NonIntegerDisplayRect) {
- overlay_params_.back().display_rect.Inset(0.005f, 0.005f);
- plane_list_.pop_back();
- AddPlane(overlay_params_.back());
CrtcState state = {
/* .planes = */
{
@@ -500,7 +665,11 @@ TEST_F(DrmOverlayValidatorTest, NonIntegerDisplayRect) {
{/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
},
};
- InitializeDrmState(std::vector<CrtcState>(1, state));
+ InitDrmStatesAndControllers(std::vector<CrtcState>(1, state));
+
+ overlay_params_.back().display_rect.Inset(0.005f, 0.005f);
+ plane_list_.pop_back();
+ AddPlane(overlay_params_.back());
std::vector<ui::OverlayStatus> returns = overlay_validator_->TestPageFlip(
overlay_params_, ui::DrmOverlayPlaneList());
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc
index 6a1a23c8343..33e3370b983 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -16,9 +16,11 @@
#include "base/trace_event/trace_event.h"
#include "ui/display/types/display_mode.h"
#include "ui/display/types/display_snapshot.h"
+#include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_defines.h"
+#include "ui/gfx/linux/gbm_device.h"
+#include "ui/gfx/linux/gbm_util.h"
#include "ui/gfx/presentation_feedback.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
-#include "ui/ozone/common/linux/gbm_device.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
#include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
@@ -36,32 +38,10 @@ namespace ui {
namespace {
-uint32_t BufferUsageToGbmFlags(gfx::BufferUsage usage) {
- switch (usage) {
- case gfx::BufferUsage::GPU_READ:
- return GBM_BO_USE_TEXTURING;
- case gfx::BufferUsage::SCANOUT:
- return GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING;
- case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE:
- return GBM_BO_USE_LINEAR | GBM_BO_USE_CAMERA_WRITE | GBM_BO_USE_SCANOUT |
- GBM_BO_USE_TEXTURING;
- case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE:
- return GBM_BO_USE_LINEAR | GBM_BO_USE_CAMERA_WRITE;
- case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE:
- return GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING;
- case gfx::BufferUsage::SCANOUT_VDA_WRITE:
- return GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING |
- GBM_BO_USE_HW_VIDEO_DECODER;
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
- return GBM_BO_USE_LINEAR | GBM_BO_USE_TEXTURING;
- case gfx::BufferUsage::SCANOUT_VEA_READ_CAMERA_AND_CPU_READ_WRITE:
- return GBM_BO_USE_TEXTURING | GBM_BO_USE_HW_VIDEO_ENCODER;
- }
-}
-
void CreateBufferWithGbmFlags(const scoped_refptr<DrmDevice>& drm,
uint32_t fourcc_format,
const gfx::Size& size,
+ const gfx::Size& framebuffer_size,
uint32_t flags,
const std::vector<uint64_t>& modifiers,
std::unique_ptr<GbmBuffer>* out_buffer,
@@ -74,7 +54,8 @@ void CreateBufferWithGbmFlags(const scoped_refptr<DrmDevice>& drm,
scoped_refptr<DrmFramebuffer> framebuffer;
if (flags & GBM_BO_USE_SCANOUT) {
- framebuffer = DrmFramebuffer::AddFramebuffer(drm, buffer.get(), modifiers);
+ framebuffer = DrmFramebuffer::AddFramebuffer(drm, buffer.get(),
+ framebuffer_size, modifiers);
if (!framebuffer)
return;
}
@@ -125,6 +106,7 @@ void DrmThread::RunTaskAfterWindowReady(gfx::AcceleratedWidget window,
}
void DrmThread::Init() {
+ TRACE_EVENT0("drm", "DrmThread::Init");
device_manager_ =
std::make_unique<DrmDeviceManager>(std::move(device_generator_));
screen_manager_ = std::make_unique<ScreenManager>();
@@ -141,16 +123,18 @@ void DrmThread::Init() {
void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget,
const gfx::Size& size,
+ const gfx::Size& framebuffer_size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
uint32_t client_flags,
std::unique_ptr<GbmBuffer>* buffer,
scoped_refptr<DrmFramebuffer>* framebuffer) {
+ TRACE_EVENT0("drm", "DrmThread::CreateBuffer");
scoped_refptr<ui::DrmDevice> drm = device_manager_->GetDrmDevice(widget);
CHECK(drm) << "No devices available for buffer allocation.";
DrmWindow* window = screen_manager_->GetWindow(widget);
- uint32_t flags = BufferUsageToGbmFlags(usage);
+ uint32_t flags = ui::BufferUsageToGbmFlags(usage);
uint32_t fourcc_format = ui::GetFourCCFormatFromBufferFormat(format);
// TODO(hoegsberg): We shouldn't really get here without a window,
@@ -161,8 +145,8 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget,
modifiers = window->GetController()->GetFormatModifiers(fourcc_format);
}
- CreateBufferWithGbmFlags(drm, fourcc_format, size, flags, modifiers, buffer,
- framebuffer);
+ CreateBufferWithGbmFlags(drm, fourcc_format, size, framebuffer_size, flags,
+ modifiers, buffer, framebuffer);
// NOTE: BufferUsage::SCANOUT is used to create buffers that will be
// explicitly set via kms on a CRTC (e.g: BufferQueue buffers), therefore
@@ -170,8 +154,8 @@ void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget,
// buffer in that case.
if (!*buffer && usage != gfx::BufferUsage::SCANOUT) {
flags &= ~GBM_BO_USE_SCANOUT;
- CreateBufferWithGbmFlags(drm, fourcc_format, size, flags, modifiers, buffer,
- framebuffer);
+ CreateBufferWithGbmFlags(drm, fourcc_format, size, framebuffer_size, flags,
+ modifiers, buffer, framebuffer);
}
}
@@ -181,10 +165,11 @@ void DrmThread::CreateBufferAsync(gfx::AcceleratedWidget widget,
gfx::BufferUsage usage,
uint32_t client_flags,
CreateBufferAsyncCallback callback) {
+ TRACE_EVENT0("drm", "DrmThread::CreateBufferAsync");
std::unique_ptr<GbmBuffer> buffer;
scoped_refptr<DrmFramebuffer> framebuffer;
- CreateBuffer(widget, size, format, usage, client_flags, &buffer,
- &framebuffer);
+ CreateBuffer(widget, size, /*framebuffer_size=*/size, format, usage,
+ client_flags, &buffer, &framebuffer);
std::move(callback).Run(std::move(buffer), std::move(framebuffer));
}
@@ -195,6 +180,7 @@ void DrmThread::CreateBufferFromHandle(
gfx::NativePixmapHandle handle,
std::unique_ptr<GbmBuffer>* out_buffer,
scoped_refptr<DrmFramebuffer>* out_framebuffer) {
+ TRACE_EVENT0("drm", "DrmThread::CreateBufferFromHandle");
scoped_refptr<ui::DrmDevice> drm = device_manager_->GetDrmDevice(widget);
DCHECK(drm);
@@ -207,7 +193,8 @@ void DrmThread::CreateBufferFromHandle(
if (buffer->GetFlags() & GBM_BO_USE_SCANOUT) {
// NB: This is not required to succeed; framebuffers are added for
// imported buffers on a best effort basis.
- framebuffer = DrmFramebuffer::AddFramebuffer(drm, buffer.get());
+ framebuffer =
+ DrmFramebuffer::AddFramebuffer(drm, buffer.get(), buffer->GetSize());
}
*out_buffer = std::move(buffer);
@@ -223,6 +210,7 @@ void DrmThread::SchedulePageFlip(
std::vector<DrmOverlayPlane> planes,
SwapCompletionOnceCallback submission_callback,
PresentationOnceCallback presentation_callback) {
+ TRACE_EVENT0("drm", "DrmThread::SchedulePageFlip");
scoped_refptr<ui::DrmDevice> drm_device =
device_manager_->GetDrmDevice(widget);
@@ -238,6 +226,7 @@ void DrmThread::OnPlanesReadyForPageFlip(
SwapCompletionOnceCallback submission_callback,
PresentationOnceCallback presentation_callback,
std::vector<DrmOverlayPlane> planes) {
+ TRACE_EVENT0("drm", "DrmThread::OnPlanesReadyForPageFlip");
DrmWindow* window = screen_manager_->GetWindow(widget);
if (window) {
window->SchedulePageFlip(std::move(planes), std::move(submission_callback),
@@ -249,6 +238,7 @@ void DrmThread::OnPlanesReadyForPageFlip(
}
void DrmThread::IsDeviceAtomic(gfx::AcceleratedWidget widget, bool* is_atomic) {
+ TRACE_EVENT0("drm", "DrmThread::IsDeviceAtomic");
scoped_refptr<ui::DrmDevice> drm_device =
device_manager_->GetDrmDevice(widget);
@@ -257,6 +247,7 @@ void DrmThread::IsDeviceAtomic(gfx::AcceleratedWidget widget, bool* is_atomic) {
void DrmThread::CreateWindow(gfx::AcceleratedWidget widget,
const gfx::Rect& initial_bounds) {
+ TRACE_EVENT0("drm", "DrmThread::CreateWindow");
DCHECK_GT(widget, last_created_window_);
last_created_window_ = widget;
@@ -271,12 +262,14 @@ void DrmThread::CreateWindow(gfx::AcceleratedWidget widget,
}
void DrmThread::DestroyWindow(gfx::AcceleratedWidget widget) {
+ TRACE_EVENT0("drm", "DrmThread::DestroyWindow");
std::unique_ptr<DrmWindow> window = screen_manager_->RemoveWindow(widget);
window->Shutdown();
}
void DrmThread::SetWindowBounds(gfx::AcceleratedWidget widget,
const gfx::Rect& bounds) {
+ TRACE_EVENT0("drm", "DrmThread::SetWindowBounds");
screen_manager_->GetWindow(widget)->SetBounds(bounds);
}
@@ -284,26 +277,41 @@ void DrmThread::SetCursor(gfx::AcceleratedWidget widget,
const std::vector<SkBitmap>& bitmaps,
const gfx::Point& location,
int32_t frame_delay_ms) {
+ TRACE_EVENT0("drm", "DrmThread::SetCursor");
screen_manager_->GetWindow(widget)
->SetCursor(bitmaps, location, frame_delay_ms);
}
void DrmThread::MoveCursor(gfx::AcceleratedWidget widget,
const gfx::Point& location) {
+ TRACE_EVENT0("drm", "DrmThread::MoveCursor");
screen_manager_->GetWindow(widget)->MoveCursor(location);
}
void DrmThread::CheckOverlayCapabilities(
gfx::AcceleratedWidget widget,
const OverlaySurfaceCandidateList& overlays,
- base::OnceCallback<void(gfx::AcceleratedWidget,
- const OverlaySurfaceCandidateList&,
- const OverlayStatusList&)> callback) {
+ OverlayCapabilitiesCallback callback) {
TRACE_EVENT0("drm,hwoverlays", "DrmThread::CheckOverlayCapabilities");
- std::move(callback).Run(
- widget, overlays,
- screen_manager_->GetWindow(widget)->TestPageFlip(overlays));
+ std::vector<OverlayStatus> result;
+ CheckOverlayCapabilitiesSync(widget, overlays, &result);
+ std::move(callback).Run(widget, overlays, std::move(result));
+}
+
+void DrmThread::CheckOverlayCapabilitiesSync(
+ gfx::AcceleratedWidget widget,
+ const OverlaySurfaceCandidateList& overlays,
+ std::vector<OverlayStatus>* result) {
+ TRACE_EVENT0("drm,hwoverlays", "DrmThread::CheckOverlayCapabilitiesSync");
+
+ DrmWindow* window = screen_manager_->GetWindow(widget);
+ if (!window) {
+ result->clear();
+ result->insert(result->end(), overlays.size(), OVERLAY_STATUS_NOT);
+ return;
+ }
+ *result = window->TestPageFlip(overlays);
}
void DrmThread::GetDeviceCursor(
@@ -313,6 +321,7 @@ void DrmThread::GetDeviceCursor(
void DrmThread::RefreshNativeDisplays(
base::OnceCallback<void(MovableDisplaySnapshots)> callback) {
+ TRACE_EVENT0("drm", "DrmThread::RefreshNativeDisplays");
std::move(callback).Run(display_manager_->GetDisplays());
}
@@ -321,6 +330,7 @@ void DrmThread::ConfigureNativeDisplay(
std::unique_ptr<display::DisplayMode> mode,
const gfx::Point& origin,
base::OnceCallback<void(int64_t, bool)> callback) {
+ TRACE_EVENT0("drm", "DrmThread::ConfigureNativeDisplay");
std::move(callback).Run(
id, display_manager_->ConfigureDisplay(id, *mode, origin));
}
@@ -328,20 +338,24 @@ void DrmThread::ConfigureNativeDisplay(
void DrmThread::DisableNativeDisplay(
int64_t id,
base::OnceCallback<void(int64_t, bool)> callback) {
+ TRACE_EVENT0("drm", "DrmThread::DisableNativeDisplay");
std::move(callback).Run(id, display_manager_->DisableDisplay(id));
}
void DrmThread::TakeDisplayControl(base::OnceCallback<void(bool)> callback) {
+ TRACE_EVENT0("drm", "DrmThread::TakeDisplayControl");
std::move(callback).Run(display_manager_->TakeDisplayControl());
}
void DrmThread::RelinquishDisplayControl(
base::OnceCallback<void(bool)> callback) {
+ TRACE_EVENT0("drm", "DrmThread::RelinquishDisplayControl");
display_manager_->RelinquishDisplayControl();
std::move(callback).Run(true);
}
void DrmThread::AddGraphicsDevice(const base::FilePath& path, base::File file) {
+ TRACE_EVENT0("drm", "DrmThread::AddGraphicsDevice");
device_manager_->AddDrmDevice(path, std::move(file));
// There might be tasks that were blocked on a DrmDevice becoming available.
@@ -349,12 +363,14 @@ void DrmThread::AddGraphicsDevice(const base::FilePath& path, base::File file) {
}
void DrmThread::RemoveGraphicsDevice(const base::FilePath& path) {
+ TRACE_EVENT0("drm", "DrmThread::RemoveGraphicsDevice");
device_manager_->RemoveDrmDevice(path);
}
void DrmThread::GetHDCPState(
int64_t display_id,
base::OnceCallback<void(int64_t, bool, display::HDCPState)> callback) {
+ TRACE_EVENT0("drm", "DrmThread::GetHDCPState");
display::HDCPState state = display::HDCP_STATE_UNDESIRED;
bool success = display_manager_->GetHDCPState(display_id, &state);
std::move(callback).Run(display_id, success, state);
@@ -363,12 +379,14 @@ void DrmThread::GetHDCPState(
void DrmThread::SetHDCPState(int64_t display_id,
display::HDCPState state,
base::OnceCallback<void(int64_t, bool)> callback) {
+ TRACE_EVENT0("drm", "DrmThread::SetHDCPState");
std::move(callback).Run(display_id,
display_manager_->SetHDCPState(display_id, state));
}
void DrmThread::SetColorMatrix(int64_t display_id,
const std::vector<float>& color_matrix) {
+ TRACE_EVENT0("drm", "DrmThread::SetColorMatrix");
display_manager_->SetColorMatrix(display_id, color_matrix);
}
@@ -376,9 +394,14 @@ void DrmThread::SetGammaCorrection(
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) {
+ TRACE_EVENT0("drm", "DrmThread::SetGammaCorrection");
display_manager_->SetGammaCorrection(display_id, degamma_lut, gamma_lut);
}
+void DrmThread::SetPrivacyScreen(int64_t display_id, bool enabled) {
+ display_manager_->SetPrivacyScreen(display_id, enabled);
+}
+
void DrmThread::AddDrmDeviceReceiver(
mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver) {
TRACE_EVENT0("drm", "DrmThread::AddDrmDeviceReceiver");
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread.h b/chromium/ui/ozone/platform/drm/gpu/drm_thread.h
index cb4268aaf50..69586599c7d 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread.h
@@ -25,6 +25,7 @@
#include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
#include "ui/ozone/public/mojom/device_cursor.mojom.h"
#include "ui/ozone/public/mojom/drm_device.mojom.h"
+#include "ui/ozone/public/overlay_surface_candidate.h"
#include "ui/ozone/public/swap_completion_callback.h"
namespace base {
@@ -62,6 +63,11 @@ class DrmThread : public base::Thread,
public ozone::mojom::DeviceCursor,
public ozone::mojom::DrmDevice {
public:
+ using OverlayCapabilitiesCallback =
+ base::OnceCallback<void(gfx::AcceleratedWidget,
+ const std::vector<OverlaySurfaceCandidate>&,
+ const std::vector<OverlayStatus>&)>;
+
DrmThread();
~DrmThread() override;
@@ -78,6 +84,7 @@ class DrmThread : public base::Thread,
// DrmThreadProxy (on GPU)thread) is the client for these methods.
void CreateBuffer(gfx::AcceleratedWidget widget,
const gfx::Size& size,
+ const gfx::Size& framebuffer_size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
uint32_t flags,
@@ -102,6 +109,21 @@ class DrmThread : public base::Thread,
void AddDrmDeviceReceiver(
mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver);
+ // Verifies if the display controller can successfully scanout the given set
+ // of OverlaySurfaceCandidates and return the status associated with each
+ // candidate.
+ void CheckOverlayCapabilities(
+ gfx::AcceleratedWidget widget,
+ const std::vector<OverlaySurfaceCandidate>& candidates,
+ OverlayCapabilitiesCallback callback);
+
+ // Similar to CheckOverlayCapabilities() but stores the result in |result|
+ // instead of running a callback.
+ void CheckOverlayCapabilitiesSync(
+ gfx::AcceleratedWidget widget,
+ const std::vector<OverlaySurfaceCandidate>& candidates,
+ std::vector<OverlayStatus>* result);
+
// DrmWindowProxy (on GPU thread) is the client for these methods.
void SchedulePageFlip(gfx::AcceleratedWidget widget,
std::vector<DrmOverlayPlane> planes,
@@ -143,12 +165,7 @@ class DrmThread : public base::Thread,
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
- void CheckOverlayCapabilities(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& overlays,
- base::OnceCallback<void(gfx::AcceleratedWidget,
- const OverlaySurfaceCandidateList&,
- const OverlayStatusList&)> callback) override;
+ void SetPrivacyScreen(int64_t display_id, bool enabled) override;
void GetDeviceCursor(
mojo::PendingAssociatedReceiver<ozone::mojom::DeviceCursor> receiver)
override;
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
index d55cab5a79b..f7072c320e1 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
@@ -58,8 +58,7 @@ bool DrmThreadMessageProxy::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetHDCPState, OnSetHDCPState)
IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetColorMatrix, OnSetColorMatrix)
IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetGammaCorrection, OnSetGammaCorrection)
- IPC_MESSAGE_HANDLER(OzoneGpuMsg_CheckOverlayCapabilities,
- OnCheckOverlayCapabilities)
+ IPC_MESSAGE_HANDLER(OzoneGpuMsg_SetPrivacyScreen, OnSetPrivacyScreen)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
@@ -110,22 +109,6 @@ void DrmThreadMessageProxy::OnCursorMove(gfx::AcceleratedWidget widget,
widget, location));
}
-void DrmThreadMessageProxy::OnCheckOverlayCapabilities(
- gfx::AcceleratedWidget widget,
- const std::vector<OverlayCheck_Params>& param_overlays) {
- DCHECK(drm_thread_->IsRunning());
- auto overlays = CreateOverlaySurfaceCandidateListFrom(param_overlays);
- auto callback =
- base::BindOnce(&DrmThreadMessageProxy::OnCheckOverlayCapabilitiesCallback,
- weak_ptr_factory_.GetWeakPtr());
-
- auto safe_callback = CreateSafeOnceCallback(std::move(callback));
- drm_thread_->task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&DrmThread::CheckOverlayCapabilities,
- base::Unretained(drm_thread_), widget, overlays,
- std::move(safe_callback)));
-}
-
void DrmThreadMessageProxy::OnRefreshNativeDisplays() {
DCHECK(drm_thread_->IsRunning());
auto callback =
@@ -253,14 +236,13 @@ void DrmThreadMessageProxy::OnSetGammaCorrection(
degamma_lut, gamma_lut));
}
-void DrmThreadMessageProxy::OnCheckOverlayCapabilitiesCallback(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& candidates,
- const OverlayStatusList& returns) const {
- auto param_overlays = CreateParamsFromOverlaySurfaceCandidate(candidates);
- auto param_returns = CreateParamsFromOverlayStatusList(returns);
- sender_->Send(new OzoneHostMsg_OverlayCapabilitiesReceived(
- widget, param_overlays, param_returns));
+void DrmThreadMessageProxy::OnSetPrivacyScreen(int64_t display_id,
+ bool enabled) {
+ DCHECK(drm_thread_->IsRunning());
+ drm_thread_->task_runner()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&DrmThread::SetPrivacyScreen,
+ base::Unretained(drm_thread_), display_id, enabled));
}
void DrmThreadMessageProxy::OnRefreshNativeDisplaysCallback(
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h
index b1bdf683eaf..55407d6d44f 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h
@@ -15,7 +15,6 @@
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/drm/common/display_types.h"
#include "ui/ozone/platform/drm/gpu/inter_thread_messaging_proxy.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
namespace base {
struct FileDescriptor;
@@ -30,7 +29,6 @@ class Rect;
namespace ui {
class DrmThread;
struct DisplayMode_Params;
-struct OverlayCheck_Params;
class DrmThreadMessageProxy : public IPC::MessageFilter,
public InterThreadMessagingProxy {
@@ -57,9 +55,6 @@ class DrmThreadMessageProxy : public IPC::MessageFilter,
const gfx::Point& location,
int frame_delay_ms);
void OnCursorMove(gfx::AcceleratedWidget widget, const gfx::Point& location);
- void OnCheckOverlayCapabilities(
- gfx::AcceleratedWidget widget,
- const std::vector<OverlayCheck_Params>& overlays);
// Display related IPC handlers.
void OnRefreshNativeDisplays();
@@ -80,11 +75,7 @@ class DrmThreadMessageProxy : public IPC::MessageFilter,
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
-
- void OnCheckOverlayCapabilitiesCallback(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& overlays,
- const OverlayStatusList& returns) const;
+ void OnSetPrivacyScreen(int64_t display_id, bool enabled);
void OnRefreshNativeDisplaysCallback(MovableDisplaySnapshots displays) const;
void OnConfigureNativeDisplayCallback(int64_t display_id, bool success) const;
void OnDisableNativeDisplayCallback(int64_t display_id, bool success) const;
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
index 745b3974f89..8a0178c20e9 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
@@ -8,7 +8,7 @@
#include <utility>
#include "base/bind.h"
-#include "ui/ozone/common/linux/gbm_wrapper.h"
+#include "ui/gfx/linux/gbm_wrapper.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
#include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
#include "ui/ozone/platform/drm/gpu/drm_thread_message_proxy.h"
@@ -80,16 +80,19 @@ std::unique_ptr<DrmWindowProxy> DrmThreadProxy::CreateDrmWindowProxy(
void DrmThreadProxy::CreateBuffer(gfx::AcceleratedWidget widget,
const gfx::Size& size,
+ const gfx::Size& framebuffer_size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
uint32_t flags,
std::unique_ptr<GbmBuffer>* buffer,
scoped_refptr<DrmFramebuffer>* framebuffer) {
+ TRACE_EVENT0("drm", "DrmThreadProxy::CreateBuffer");
DCHECK(drm_thread_.task_runner())
<< "no task runner! in DrmThreadProxy::CreateBuffer";
- base::OnceClosure task =
- base::BindOnce(&DrmThread::CreateBuffer, base::Unretained(&drm_thread_),
- widget, size, format, usage, flags, buffer, framebuffer);
+ base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
+ base::OnceClosure task = base::BindOnce(
+ &DrmThread::CreateBuffer, base::Unretained(&drm_thread_), widget, size,
+ framebuffer_size, format, usage, flags, buffer, framebuffer);
PostSyncTask(
drm_thread_.task_runner(),
base::BindOnce(&DrmThread::RunTaskAfterWindowReady,
@@ -127,6 +130,8 @@ void DrmThreadProxy::CreateBufferFromHandle(
gfx::NativePixmapHandle handle,
std::unique_ptr<GbmBuffer>* buffer,
scoped_refptr<DrmFramebuffer>* framebuffer) {
+ TRACE_EVENT0("drm", "DrmThreadProxy::CreateBufferFromHandle");
+ base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
base::OnceClosure task = base::BindOnce(
&DrmThread::CreateBufferFromHandle, base::Unretained(&drm_thread_),
widget, size, format, std::move(handle), buffer, framebuffer);
@@ -150,7 +155,7 @@ void DrmThreadProxy::SetClearOverlayCacheCallback(
void DrmThreadProxy::CheckOverlayCapabilities(
gfx::AcceleratedWidget widget,
const std::vector<OverlaySurfaceCandidate>& candidates,
- OverlayCapabilitiesCallback callback) {
+ DrmThread::OverlayCapabilitiesCallback callback) {
DCHECK(drm_thread_.task_runner());
base::OnceClosure task = base::BindOnce(
&DrmThread::CheckOverlayCapabilities, base::Unretained(&drm_thread_),
@@ -162,6 +167,23 @@ void DrmThreadProxy::CheckOverlayCapabilities(
std::move(task), nullptr));
}
+std::vector<OverlayStatus> DrmThreadProxy::CheckOverlayCapabilitiesSync(
+ gfx::AcceleratedWidget widget,
+ const std::vector<OverlaySurfaceCandidate>& candidates) {
+ TRACE_EVENT0("drm", "DrmThreadProxy::CheckOverlayCapabilitiesSync");
+ DCHECK(drm_thread_.task_runner());
+ base::ScopedAllowBaseSyncPrimitivesOutsideBlockingScope allow_wait;
+ std::vector<OverlayStatus> result;
+ base::OnceClosure task = base::BindOnce(
+ &DrmThread::CheckOverlayCapabilitiesSync, base::Unretained(&drm_thread_),
+ widget, candidates, &result);
+ PostSyncTask(
+ drm_thread_.task_runner(),
+ base::BindOnce(&DrmThread::RunTaskAfterWindowReady,
+ base::Unretained(&drm_thread_), widget, std::move(task)));
+ return result;
+}
+
void DrmThreadProxy::AddDrmDeviceReceiver(
mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver) {
DCHECK(drm_thread_.task_runner()) << "DrmThreadProxy::AddDrmDeviceReceiver "
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
index 1327102e343..303a7eb9cbe 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
@@ -26,11 +26,6 @@ class InterThreadMessagingProxy;
// proxy objects then deal with safely posting the messages to the DRM thread.
class DrmThreadProxy {
public:
- using OverlayCapabilitiesCallback =
- base::OnceCallback<void(gfx::AcceleratedWidget,
- const std::vector<OverlaySurfaceCandidate>&,
- const std::vector<OverlayStatus>&)>;
-
DrmThreadProxy();
~DrmThreadProxy();
@@ -43,6 +38,7 @@ class DrmThreadProxy {
void CreateBuffer(gfx::AcceleratedWidget widget,
const gfx::Size& size,
+ const gfx::Size& framebuffer_size,
gfx::BufferFormat format,
gfx::BufferUsage usage,
uint32_t flags,
@@ -77,7 +73,12 @@ class DrmThreadProxy {
void CheckOverlayCapabilities(
gfx::AcceleratedWidget widget,
const std::vector<OverlaySurfaceCandidate>& candidates,
- OverlayCapabilitiesCallback callback);
+ DrmThread::OverlayCapabilitiesCallback callback);
+
+ // Similar to CheckOverlayCapabilities() but returns the result synchronously.
+ std::vector<OverlayStatus> CheckOverlayCapabilitiesSync(
+ gfx::AcceleratedWidget widget,
+ const std::vector<OverlaySurfaceCandidate>& candidates);
void AddDrmDeviceReceiver(
mojo::PendingReceiver<ozone::mojom::DrmDevice> receiver);
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_unittest.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread_unittest.cc
index 5f576a8f6d7..fdd7a2e3785 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_unittest.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_unittest.cc
@@ -11,9 +11,9 @@
#include "base/test/task_environment.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/linux/test/mock_gbm_device.h"
#include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
#include "ui/ozone/platform/drm/gpu/mock_drm_device.h"
-#include "ui/ozone/platform/drm/gpu/mock_gbm_device.h"
namespace ui {
@@ -167,4 +167,27 @@ TEST_F(DrmThreadTest, RunTaskAfterWindowReady) {
drm_thread_.FlushForTesting();
}
+// Verifies that we gracefully handle the case where CheckOverlayCapabilities()
+// is called on a destroyed window.
+TEST_F(DrmThreadTest, CheckOverlayCapabilitiesDestroyedWindow) {
+ gfx::AcceleratedWidget widget = 5;
+ constexpr gfx::Rect bounds(10, 10);
+ constexpr size_t candidates_size = 9;
+ std::vector<OverlaySurfaceCandidate> candidates(candidates_size);
+ std::vector<OverlayStatus> result;
+ AddGraphicsDevice();
+ drm_device_->CreateWindow(widget, bounds);
+ drm_device_->DestroyWindow(widget);
+ drm_device_.FlushForTesting();
+ drm_thread_.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(&DrmThread::CheckOverlayCapabilitiesSync,
+ base::Unretained(&drm_thread_), widget,
+ candidates, &result));
+ drm_thread_.FlushForTesting();
+ EXPECT_EQ(candidates_size, result.size());
+ for (const auto& status : result) {
+ EXPECT_EQ(OVERLAY_STATUS_NOT, status);
+ }
+}
+
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_window_unittest.cc b/chromium/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
index f3240ed685c..824992ab157 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
@@ -20,14 +20,14 @@
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "ui/gfx/gpu_fence.h"
+#include "ui/gfx/linux/gbm_buffer.h"
+#include "ui/gfx/linux/test/mock_gbm_device.h"
#include "ui/gfx/presentation_feedback.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
#include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
#include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
#include "ui/ozone/platform/drm/gpu/drm_framebuffer.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
#include "ui/ozone/platform/drm/gpu/mock_drm_device.h"
-#include "ui/ozone/platform/drm/gpu/mock_gbm_device.h"
#include "ui/ozone/platform/drm/gpu/screen_manager.h"
#include "ui/ozone/public/surface_ozone_canvas.h"
@@ -182,8 +182,9 @@ TEST_F(DrmWindowTest, CheckDeathOnFailedSwap) {
std::unique_ptr<ui::GbmBuffer> buffer = drm_->gbm_device()->CreateBuffer(
DRM_FORMAT_XRGB8888, window_size, GBM_BO_USE_SCANOUT);
+ ASSERT_TRUE(buffer);
scoped_refptr<ui::DrmFramebuffer> framebuffer =
- ui::DrmFramebuffer::AddFramebuffer(drm_, buffer.get());
+ ui::DrmFramebuffer::AddFramebuffer(drm_, buffer.get(), window_size);
ui::DrmOverlayPlane plane(framebuffer, nullptr);
drm_->set_page_flip_expectation(false);
diff --git a/chromium/ui/ozone/platform/drm/gpu/gbm_pixmap.h b/chromium/ui/ozone/platform/drm/gpu/gbm_pixmap.h
index 17e1de67075..1c4d9aeb58f 100644
--- a/chromium/ui/ozone/platform/drm/gpu/gbm_pixmap.h
+++ b/chromium/ui/ozone/platform/drm/gpu/gbm_pixmap.h
@@ -8,8 +8,8 @@
#include <memory>
#include <vector>
+#include "ui/gfx/linux/gbm_buffer.h"
#include "ui/gfx/native_pixmap.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
#include "ui/ozone/platform/drm/gpu/drm_framebuffer.h"
namespace ui {
diff --git a/chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc b/chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
index d015577ba1b..fcb45780025 100644
--- a/chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.cc
@@ -5,6 +5,7 @@
#include "ui/ozone/platform/drm/gpu/gbm_surface_factory.h"
#include <gbm.h>
+#include <xf86drm.h>
#include <memory>
#include <utility>
@@ -14,13 +15,16 @@
#include "build/build_config.h"
#include "third_party/khronos/EGL/egl.h"
#include "ui/gfx/buffer_format_util.h"
+#include "ui/gfx/extension_set.h"
+#include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_defines.h"
+#include "ui/gfx/linux/scoped_gbm_device.h"
#include "ui/gfx/native_pixmap.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/ozone/common/egl_util.h"
#include "ui/ozone/common/gl_ozone_egl.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
-#include "ui/ozone/common/linux/scoped_gbm_device.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
+#include "ui/ozone/platform/drm/gpu/drm_gpu_util.h"
#include "ui/ozone/platform/drm/gpu/drm_thread_proxy.h"
#include "ui/ozone/platform/drm/gpu/drm_window_proxy.h"
#include "ui/ozone/platform/drm/gpu/gbm_overlay_surface.h"
@@ -83,7 +87,68 @@ class GLOzoneEGLGbm : public GLOzoneEGL {
}
protected:
- intptr_t GetNativeDisplay() override { return EGL_DEFAULT_DISPLAY; }
+ gl::EGLDisplayPlatform GetNativeDisplay() override {
+ if (native_display_.Valid())
+ return native_display_;
+
+ // Default to null platform
+ native_display_ = gl::EGLDisplayPlatform(EGL_DEFAULT_DISPLAY);
+
+ gl::g_driver_egl.InitializeClientExtensionBindings();
+
+ const char* client_extensions_string =
+ eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+
+ gfx::ExtensionSet client_extensions =
+ client_extensions_string
+ ? gfx::MakeExtensionSet(client_extensions_string)
+ : gfx::ExtensionSet();
+
+ if (gfx::HasExtension(client_extensions, "EGL_MESA_platform_surfaceless")) {
+ native_display_ = gl::EGLDisplayPlatform(EGL_DEFAULT_DISPLAY,
+ EGL_PLATFORM_SURFACELESS_MESA);
+ }
+
+ if (!(gfx::HasExtension(client_extensions, "EGL_EXT_device_query") &&
+ gfx::HasExtension(client_extensions, "EGL_EXT_platform_device") &&
+ gfx::HasExtension(client_extensions, "EGL_EXT_device_enumeration"))) {
+ LOG(WARNING) << "Platform device extensions not found.";
+ return native_display_;
+ }
+
+ std::vector<EGLDeviceEXT> devices(DRM_MAX_MINOR, EGL_NO_DEVICE_EXT);
+ EGLDeviceEXT amdgpu_device = EGL_NO_DEVICE_EXT;
+ EGLDeviceEXT i915_device = EGL_NO_DEVICE_EXT;
+ EGLint num_devices = 0;
+
+ eglQueryDevicesEXT(DRM_MAX_MINOR, devices.data(), &num_devices);
+ devices.resize(num_devices);
+ for (EGLDeviceEXT device : devices) {
+ const char* filename =
+ eglQueryDeviceStringEXT(device, EGL_DRM_DEVICE_FILE_EXT);
+ if (!filename) // Not a DRM device.
+ continue;
+ if (IsDriverName(filename, "amdgpu"))
+ amdgpu_device = device;
+ if (IsDriverName(filename, "i915"))
+ i915_device = device;
+ }
+
+ if (amdgpu_device != EGL_NO_DEVICE_EXT) {
+ native_display_ = gl::EGLDisplayPlatform(
+ reinterpret_cast<EGLNativeDisplayType>(amdgpu_device),
+ EGL_PLATFORM_DEVICE_EXT);
+ }
+
+ // If we also have Intel integrated, use it instead.
+ if (i915_device != EGL_NO_DEVICE_EXT) {
+ native_display_ = gl::EGLDisplayPlatform(
+ reinterpret_cast<EGLNativeDisplayType>(i915_device),
+ EGL_PLATFORM_DEVICE_EXT);
+ }
+
+ return native_display_;
+ }
bool LoadGLES2Bindings(gl::GLImplementation impl) override {
return LoadDefaultEGLGLES2Bindings(impl);
@@ -92,6 +157,7 @@ class GLOzoneEGLGbm : public GLOzoneEGL {
private:
GbmSurfaceFactory* surface_factory_;
DrmThreadProxy* drm_thread_proxy_;
+ gl::EGLDisplayPlatform native_display_;
DISALLOW_COPY_AND_ASSIGN(GLOzoneEGLGbm);
};
@@ -213,9 +279,9 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmapForVulkan(
std::unique_ptr<GbmBuffer> buffer;
scoped_refptr<DrmFramebuffer> framebuffer;
- drm_thread_proxy_->CreateBuffer(widget, size, format, usage,
- GbmPixmap::kFlagNoModifiers, &buffer,
- &framebuffer);
+ drm_thread_proxy_->CreateBuffer(widget, size, /*framebuffer_size=*/size,
+ format, usage, GbmPixmap::kFlagNoModifiers,
+ &buffer, &framebuffer);
if (!buffer)
return nullptr;
@@ -274,7 +340,7 @@ std::unique_ptr<OverlaySurface> GbmSurfaceFactory::CreateOverlaySurface(
std::unique_ptr<SurfaceOzoneCanvas> GbmSurfaceFactory::CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) {
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
DCHECK(thread_checker_.CalledOnValidThread());
LOG(ERROR) << "Software rendering mode is not supported with GBM platform";
return nullptr;
@@ -285,11 +351,17 @@ scoped_refptr<gfx::NativePixmap> GbmSurfaceFactory::CreateNativePixmap(
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) {
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size) {
+ if (framebuffer_size &&
+ !gfx::Rect(size).Contains(gfx::Rect(*framebuffer_size))) {
+ return nullptr;
+ }
std::unique_ptr<GbmBuffer> buffer;
scoped_refptr<DrmFramebuffer> framebuffer;
- drm_thread_proxy_->CreateBuffer(widget, size, format, usage, 0 /* flags */,
- &buffer, &framebuffer);
+ drm_thread_proxy_->CreateBuffer(
+ widget, size, framebuffer_size ? *framebuffer_size : size, format, usage,
+ 0 /* flags */, &buffer, &framebuffer);
if (!buffer)
return nullptr;
return base::MakeRefCounted<GbmPixmap>(this, std::move(buffer),
diff --git a/chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.h b/chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.h
index 679848c3d31..ab3089b7242 100644
--- a/chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.h
+++ b/chromium/ui/ozone/platform/drm/gpu/gbm_surface_factory.h
@@ -55,13 +55,14 @@ class GbmSurfaceFactory : public SurfaceFactoryOzone {
gfx::AcceleratedWidget window) override;
std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) override;
+ scoped_refptr<base::SequencedTaskRunner> task_runner) override;
scoped_refptr<gfx::NativePixmap> CreateNativePixmap(
gfx::AcceleratedWidget widget,
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) override;
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size = base::nullopt) override;
void CreateNativePixmapAsync(gfx::AcceleratedWidget widget,
VkDevice vk_device,
gfx::Size size,
diff --git a/chromium/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc b/chromium/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc
index 62cac1b7bb2..ae654f1dbf8 100644
--- a/chromium/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/trace_event/trace_event.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/presentation_feedback.h"
@@ -154,11 +155,10 @@ void GbmSurfaceless::SwapBuffersAsync(
base::OnceClosure fence_retired_callback = base::BindOnce(
&GbmSurfaceless::FenceRetired, weak_factory_.GetWeakPtr(), frame);
- base::PostTaskAndReply(FROM_HERE,
- {base::ThreadPool(), base::MayBlock(),
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
- std::move(fence_wait_task),
- std::move(fence_retired_callback));
+ base::ThreadPool::PostTaskAndReply(
+ FROM_HERE,
+ {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ std::move(fence_wait_task), std::move(fence_retired_callback));
}
void GbmSurfaceless::PostSubBufferAsync(
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
index b8b8b4229a3..6f240331ab6 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
@@ -29,6 +29,12 @@
#include "ui/ozone/platform/drm/gpu/hardware_display_plane.h"
#include "ui/ozone/platform/drm/gpu/page_flip_request.h"
+// Vendor ID for downstream, interim ChromeOS specific modifiers.
+#define DRM_FORMAT_MOD_VENDOR_CHROMEOS 0xf0
+// TODO(gurchetansingh) Remove once DRM_FORMAT_MOD_ARM_AFBC is used by all
+// kernels and allocators.
+#define DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC fourcc_mod_code(CHROMEOS, 1)
+
namespace ui {
namespace {
@@ -52,7 +58,7 @@ void DrawCursor(DrmDumbBuffer* cursor, const SkBitmap& image) {
// Clear to transparent in case |image| is smaller than the canvas.
SkCanvas* canvas = cursor->GetCanvas();
canvas->clear(SK_ColorTRANSPARENT);
- canvas->drawBitmapRect(image, damage, NULL);
+ canvas->drawBitmapRect(image, damage, nullptr);
}
} // namespace
@@ -65,29 +71,39 @@ HardwareDisplayController::HardwareDisplayController(
AllocateCursorBuffers();
}
-HardwareDisplayController::~HardwareDisplayController() {
-}
+HardwareDisplayController::~HardwareDisplayController() = default;
bool HardwareDisplayController::Modeset(const DrmOverlayPlane& primary,
- drmModeModeInfo mode) {
+ const drmModeModeInfo& mode) {
TRACE_EVENT0("drm", "HDC::Modeset");
- DCHECK(primary.buffer.get());
- bool status = true;
- for (const auto& controller : crtc_controllers_)
- status &= controller->Modeset(primary, mode);
-
- is_disabled_ = false;
- ResetCursor();
- OnModesetComplete(primary);
- return status;
+ return ModesetCrtc(primary, /*use_current_crtc_mode=*/false, mode);
}
bool HardwareDisplayController::Enable(const DrmOverlayPlane& primary) {
TRACE_EVENT0("drm", "HDC::Enable");
+ drmModeModeInfo empty_mode = {};
+ return ModesetCrtc(primary, /*use_current_crtc_mode=*/true, empty_mode);
+}
+
+bool HardwareDisplayController::ModesetCrtc(const DrmOverlayPlane& primary,
+ bool use_current_crtc_mode,
+ const drmModeModeInfo& mode) {
DCHECK(primary.buffer.get());
bool status = true;
- for (const auto& controller : crtc_controllers_)
- status &= controller->Modeset(primary, controller->mode());
+
+ GetDrmDevice()->plane_manager()->BeginFrame(&owned_hardware_planes_);
+ DrmOverlayPlaneList plane_list;
+ plane_list.push_back(primary.Clone());
+
+ for (const auto& controller : crtc_controllers_) {
+ status &=
+ controller->AssignOverlayPlanes(&owned_hardware_planes_, plane_list,
+ /*is_modesetting=*/true);
+
+ status &= controller->Modeset(
+ primary, use_current_crtc_mode ? controller->mode() : mode,
+ owned_hardware_planes_);
+ }
is_disabled_ = false;
ResetCursor();
@@ -99,6 +115,10 @@ void HardwareDisplayController::Disable() {
TRACE_EVENT0("drm", "HDC::Disable");
for (const auto& controller : crtc_controllers_)
+ // TODO(crbug.com/1015104): Modeset and Disable operations should go
+ // together. The current split is due to how the legacy/atomic split
+ // evolved. It should be cleaned up under the more generic
+ // HardwareDisplayPlaneManager{Legacy,Atomic} calls.
controller->Disable();
bool ret = GetDrmDevice()->plane_manager()->DisableOverlayPlanes(
@@ -166,12 +186,13 @@ bool HardwareDisplayController::ScheduleOrTestPageFlip(
bool status = true;
for (const auto& controller : crtc_controllers_) {
- status &= controller->AssignOverlayPlanes(&owned_hardware_planes_,
- pending_planes);
+ status &= controller->AssignOverlayPlanes(
+ &owned_hardware_planes_, pending_planes, /*is_modesetting=*/false);
}
status &= GetDrmDevice()->plane_manager()->Commit(
- &owned_hardware_planes_, page_flip_request, out_fence);
+ &owned_hardware_planes_, /*should_modeset=*/false, page_flip_request,
+ out_fence);
return status;
}
@@ -347,6 +368,7 @@ void HardwareDisplayController::OnModesetComplete(
// pending planes to the same values so that the callback keeps the correct
// state.
page_flip_request_ = nullptr;
+ owned_hardware_planes_.legacy_page_flips.clear();
current_planes_.clear();
current_planes_.push_back(primary.Clone());
time_of_last_flip_ = base::TimeTicks::Now();
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h
index 264e25005da..6fb71b24860 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h
@@ -95,7 +95,7 @@ class HardwareDisplayController {
// Performs the initial CRTC configuration. If successful, it will display the
// framebuffer for |primary| with |mode|.
- bool Modeset(const DrmOverlayPlane& primary, drmModeModeInfo mode);
+ bool Modeset(const DrmOverlayPlane& primary, const drmModeModeInfo& mode);
// Performs a CRTC configuration re-using the modes from the CRTCs.
bool Enable(const DrmOverlayPlane& primary);
@@ -169,6 +169,12 @@ class HardwareDisplayController {
const gfx::PresentationFeedback& presentation_feedback);
private:
+ // If multiple CRTC Controllers exist and they're enabled, each will be
+ // enabled with its own mode. Set |use_current_crtc_mode| to Modeset using
+ // controller's mode instead of |mode|.
+ bool ModesetCrtc(const DrmOverlayPlane& primary,
+ bool use_current_crtc_mode,
+ const drmModeModeInfo& mode);
void OnModesetComplete(const DrmOverlayPlane& primary);
bool ScheduleOrTestPageFlip(const DrmOverlayPlaneList& plane_list,
scoped_refptr<PageFlipRequest> page_flip_request,
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
index 2f5ceca4c53..80118d38fdc 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc
@@ -13,29 +13,35 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/gpu_fence.h"
+#include "ui/gfx/linux/gbm_buffer.h"
+#include "ui/gfx/linux/test/mock_gbm_device.h"
#include "ui/gfx/native_pixmap.h"
#include "ui/gfx/presentation_feedback.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_framebuffer.h"
#include "ui/ozone/platform/drm/gpu/drm_gpu_util.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_plane.h"
#include "ui/ozone/platform/drm/gpu/mock_drm_device.h"
-#include "ui/ozone/platform/drm/gpu/mock_gbm_device.h"
namespace {
// Create a basic mode for a 6x4 screen.
-const drmModeModeInfo kDefaultMode =
- {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
+const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, {'\0'}};
-constexpr uint32_t kCrtcIdBase = 1;
+constexpr uint32_t kCrtcIdBase = 100;
constexpr uint32_t kPrimaryCrtc = kCrtcIdBase;
constexpr uint32_t kSecondaryCrtc = kCrtcIdBase + 1;
-constexpr uint32_t kPrimaryConnector = 10;
-constexpr uint32_t kSecondaryConnector = 11;
-constexpr uint32_t kPlaneOffset = 1000;
+constexpr uint32_t kConnectorIdBase = 200;
+constexpr uint32_t kPlaneOffset = 300;
+constexpr uint32_t kInFormatsBlobPropId = 400;
+
+constexpr uint32_t kActivePropId = 1000;
+constexpr uint32_t kModePropId = 1001;
+constexpr uint32_t kCrtcIdPropId = 2000;
+constexpr uint32_t kTypePropId = 3010;
+constexpr uint32_t kInFormatsPropId = 3011;
const gfx::Size kDefaultModeSize(kDefaultMode.hdisplay, kDefaultMode.vdisplay);
const gfx::Size kOverlaySize(kDefaultMode.hdisplay / 2,
@@ -63,13 +69,14 @@ class HardwareDisplayControllerTest : public testing::Test {
scoped_refptr<ui::DrmFramebuffer> CreateBuffer() {
std::unique_ptr<ui::GbmBuffer> buffer = drm_->gbm_device()->CreateBuffer(
DRM_FORMAT_XRGB8888, kDefaultModeSize, GBM_BO_USE_SCANOUT);
- return ui::DrmFramebuffer::AddFramebuffer(drm_, buffer.get());
+ return ui::DrmFramebuffer::AddFramebuffer(drm_, buffer.get(),
+ kDefaultModeSize);
}
scoped_refptr<ui::DrmFramebuffer> CreateOverlayBuffer() {
std::unique_ptr<ui::GbmBuffer> buffer = drm_->gbm_device()->CreateBuffer(
DRM_FORMAT_XRGB8888, kOverlaySize, GBM_BO_USE_SCANOUT);
- return ui::DrmFramebuffer::AddFramebuffer(drm_, buffer.get());
+ return ui::DrmFramebuffer::AddFramebuffer(drm_, buffer.get(), kOverlaySize);
}
protected:
@@ -94,7 +101,7 @@ void HardwareDisplayControllerTest::SetUp() {
controller_ = std::make_unique<ui::HardwareDisplayController>(
std::make_unique<ui::CrtcController>(drm_.get(), kPrimaryCrtc,
- kPrimaryConnector),
+ kConnectorIdBase),
gfx::Point());
}
@@ -104,24 +111,37 @@ void HardwareDisplayControllerTest::TearDown() {
}
void HardwareDisplayControllerTest::InitializeDrmDevice(bool use_atomic) {
- constexpr uint32_t kTypePropId = 300;
- constexpr uint32_t kInFormatsPropId = 301;
- constexpr uint32_t kInFormatsBlobPropId = 400;
-
std::vector<ui::MockDrmDevice::CrtcProperties> crtc_properties(2);
+ std::map<uint32_t, std::string> crtc_property_names = {
+ {1000, "ACTIVE"},
+ {1001, "MODE_ID"},
+ };
+
+ std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(2);
+ std::map<uint32_t, std::string> connector_property_names = {
+ {kCrtcIdPropId, "CRTC_ID"},
+ };
+ for (size_t i = 0; i < connector_properties.size(); ++i) {
+ connector_properties[i].id = kConnectorIdBase + i;
+ for (const auto& pair : connector_property_names) {
+ connector_properties[i].properties.push_back(
+ {/* .id = */ pair.first, /* .value = */ 0});
+ }
+ }
+
std::vector<ui::MockDrmDevice::PlaneProperties> plane_properties;
- std::map<uint32_t, std::string> property_names = {
+ std::map<uint32_t, std::string> plane_property_names = {
// Add all required properties.
- {200, "CRTC_ID"},
- {201, "CRTC_X"},
- {202, "CRTC_Y"},
- {203, "CRTC_W"},
- {204, "CRTC_H"},
- {205, "FB_ID"},
- {206, "SRC_X"},
- {207, "SRC_Y"},
- {208, "SRC_W"},
- {209, "SRC_H"},
+ {3000, "CRTC_ID"},
+ {3001, "CRTC_X"},
+ {3002, "CRTC_Y"},
+ {3003, "CRTC_W"},
+ {3004, "CRTC_H"},
+ {3005, "FB_ID"},
+ {3006, "SRC_X"},
+ {3007, "SRC_Y"},
+ {3008, "SRC_W"},
+ {3009, "SRC_H"},
// Add some optional properties we use for convenience.
{kTypePropId, "type"},
{kInFormatsPropId, "IN_FORMATS"},
@@ -129,6 +149,10 @@ void HardwareDisplayControllerTest::InitializeDrmDevice(bool use_atomic) {
for (size_t i = 0; i < crtc_properties.size(); ++i) {
crtc_properties[i].id = kCrtcIdBase + i;
+ for (const auto& pair : crtc_property_names) {
+ crtc_properties[i].properties.push_back(
+ {/* .id = */ pair.first, /* .value = */ 0});
+ }
for (size_t j = 0; j < 2; ++j) {
const uint32_t offset = plane_properties.size();
@@ -136,7 +160,7 @@ void HardwareDisplayControllerTest::InitializeDrmDevice(bool use_atomic) {
ui::MockDrmDevice::PlaneProperties plane;
plane.id = kPlaneOffset + offset;
plane.crtc_mask = 1 << i;
- for (const auto& pair : property_names) {
+ for (const auto& pair : plane_property_names) {
uint32_t value = 0;
if (pair.first == kTypePropId)
value = j == 0 ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
@@ -147,24 +171,21 @@ void HardwareDisplayControllerTest::InitializeDrmDevice(bool use_atomic) {
{/* .id = */ pair.first, /*.value = */ value});
};
- drm_format_modifier y_css = {.formats = 1UL,
- .modifier = I915_FORMAT_MOD_Y_TILED_CCS};
- drm_format_modifier yf_css = {.formats = 1UL,
- .modifier = I915_FORMAT_MOD_Yf_TILED_CCS};
- drm_format_modifier x = {.formats = 1UL,
- .modifier = I915_FORMAT_MOD_X_TILED};
- drm_format_modifier linear = {.formats = 1UL,
- .modifier = DRM_FORMAT_MOD_LINEAR};
drm_->SetPropertyBlob(ui::MockDrmDevice::AllocateInFormatsBlob(
- kInFormatsBlobPropId, {DRM_FORMAT_XRGB8888},
- {y_css, yf_css, x, linear}));
+ kInFormatsBlobPropId, {DRM_FORMAT_XRGB8888}, {}));
plane_properties.emplace_back(std::move(plane));
}
}
- drm_->InitializeState(crtc_properties, plane_properties, property_names,
- use_atomic);
+ std::map<uint32_t, std::string> property_names;
+ property_names.insert(crtc_property_names.begin(), crtc_property_names.end());
+ property_names.insert(connector_property_names.begin(),
+ connector_property_names.end());
+ property_names.insert(plane_property_names.begin(),
+ plane_property_names.end());
+ drm_->InitializeState(crtc_properties, connector_properties, plane_properties,
+ property_names, use_atomic);
}
void HardwareDisplayControllerTest::SchedulePageFlip(
@@ -207,56 +228,78 @@ TEST_F(HardwareDisplayControllerTest, CheckModesettingResult) {
EXPECT_FALSE(plane.buffer->HasOneRef());
}
-TEST_F(HardwareDisplayControllerTest, ModifiersWithConnectorType) {
- ui::DrmOverlayPlane plane(CreateBuffer(), nullptr);
+TEST_F(HardwareDisplayControllerTest, CheckModesettingSetsProps) {
+ ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
+
+ EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
+
+ ui::DrmOverlayPlane plane2(CreateBuffer(), nullptr);
+ std::vector<ui::DrmOverlayPlane> planes = {};
+ planes.push_back(plane2.Clone());
- // With internal displays, all modifiers including compressed (css) should be
- // there.
- drm_->set_connector_type(DRM_MODE_CONNECTOR_eDP);
-
- std::vector<uint64_t> internal_modifiers =
- controller_->GetFormatModifiers(DRM_FORMAT_XRGB8888);
- ASSERT_FALSE(internal_modifiers.empty());
-
- EXPECT_NE(std::find(internal_modifiers.begin(), internal_modifiers.end(),
- I915_FORMAT_MOD_Y_TILED_CCS),
- internal_modifiers.end());
- EXPECT_NE(std::find(internal_modifiers.begin(), internal_modifiers.end(),
- I915_FORMAT_MOD_Yf_TILED_CCS),
- internal_modifiers.end());
- EXPECT_NE(std::find(internal_modifiers.begin(), internal_modifiers.end(),
- I915_FORMAT_MOD_X_TILED),
- internal_modifiers.end());
- EXPECT_NE(std::find(internal_modifiers.begin(), internal_modifiers.end(),
- DRM_FORMAT_MOD_LINEAR),
- internal_modifiers.end());
-
- // With external displays, *_CSS modifiers (2 of them) should not exist.
- drm_->set_connector_type(DRM_MODE_CONNECTOR_DisplayPort);
-
- std::vector<uint64_t> external_modifiers =
- controller_->GetFormatModifiers(DRM_FORMAT_XRGB8888);
- ASSERT_FALSE(external_modifiers.empty());
- EXPECT_EQ(external_modifiers.size(), internal_modifiers.size() - 2);
-
- EXPECT_EQ(std::find(external_modifiers.begin(), external_modifiers.end(),
- I915_FORMAT_MOD_Y_TILED_CCS),
- external_modifiers.end());
- EXPECT_EQ(std::find(external_modifiers.begin(), external_modifiers.end(),
- I915_FORMAT_MOD_Yf_TILED_CCS),
- external_modifiers.end());
- EXPECT_NE(std::find(internal_modifiers.begin(), internal_modifiers.end(),
- I915_FORMAT_MOD_X_TILED),
- internal_modifiers.end());
- EXPECT_NE(std::find(internal_modifiers.begin(), internal_modifiers.end(),
- DRM_FORMAT_MOD_LINEAR),
- internal_modifiers.end());
+ SchedulePageFlip(std::move(planes));
+
+ // Test props values after modesetting.
+ ui::DrmDevice::Property connector_prop_crtc_id = {};
+ ui::ScopedDrmObjectPropertyPtr connector_props =
+ drm_->GetObjectProperties(kConnectorIdBase, DRM_MODE_OBJECT_CONNECTOR);
+ ui::GetDrmPropertyForName(drm_.get(), connector_props.get(), "CRTC_ID",
+ &connector_prop_crtc_id);
+ EXPECT_EQ(kCrtcIdPropId, connector_prop_crtc_id.id);
+ EXPECT_EQ(kCrtcIdBase, connector_prop_crtc_id.value);
+
+ ui::DrmDevice::Property crtc_prop_for_name = {};
+ ui::ScopedDrmObjectPropertyPtr crtc_props =
+ drm_->GetObjectProperties(kPrimaryCrtc, DRM_MODE_OBJECT_CRTC);
+ GetDrmPropertyForName(drm_.get(), crtc_props.get(), "ACTIVE",
+ &crtc_prop_for_name);
+ EXPECT_EQ(kActivePropId, crtc_prop_for_name.id);
+ EXPECT_EQ(1U, crtc_prop_for_name.value);
+
+ GetDrmPropertyForName(drm_.get(), crtc_props.get(), "MODE_ID",
+ &crtc_prop_for_name);
+ EXPECT_EQ(kModePropId, crtc_prop_for_name.id);
+}
+
+TEST_F(HardwareDisplayControllerTest, CheckDisableResetsProps) {
+ ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
+
+ EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
+
+ ui::DrmOverlayPlane plane2(CreateBuffer(), nullptr);
+ std::vector<ui::DrmOverlayPlane> planes = {};
+ planes.push_back(plane2.Clone());
+
+ SchedulePageFlip(std::move(planes));
+
+ // Test props values after disabling.
+ controller_->Disable();
+
+ ui::DrmDevice::Property connector_prop_crtc_id;
+ ui::ScopedDrmObjectPropertyPtr connector_props =
+ drm_->GetObjectProperties(kConnectorIdBase, DRM_MODE_OBJECT_CONNECTOR);
+ ui::GetDrmPropertyForName(drm_.get(), connector_props.get(), "CRTC_ID",
+ &connector_prop_crtc_id);
+ EXPECT_EQ(0U, connector_prop_crtc_id.value);
+
+ ui::DrmDevice::Property crtc_prop_for_name;
+ ui::ScopedDrmObjectPropertyPtr crtc_props =
+ drm_->GetObjectProperties(kPrimaryCrtc, DRM_MODE_OBJECT_CRTC);
+ GetDrmPropertyForName(drm_.get(), crtc_props.get(), "ACTIVE",
+ &crtc_prop_for_name);
+ EXPECT_EQ(0U, crtc_prop_for_name.value);
+
+ crtc_props = drm_->GetObjectProperties(kPrimaryCrtc, DRM_MODE_OBJECT_CRTC);
+ GetDrmPropertyForName(drm_.get(), crtc_props.get(), "MODE_ID",
+ &crtc_prop_for_name);
+ EXPECT_EQ(0U, crtc_prop_for_name.value);
}
TEST_F(HardwareDisplayControllerTest, CheckStateAfterPageFlip) {
ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
+ EXPECT_EQ(1, drm_->get_commit_count());
ui::DrmOverlayPlane plane2(CreateBuffer(), nullptr);
std::vector<ui::DrmOverlayPlane> planes;
@@ -270,13 +313,14 @@ TEST_F(HardwareDisplayControllerTest, CheckStateAfterPageFlip) {
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_);
EXPECT_EQ(1, page_flips_);
- EXPECT_EQ(1, drm_->get_commit_count());
+ EXPECT_EQ(2, drm_->get_commit_count());
// Verify only the primary display have a valid framebuffer.
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID"));
EXPECT_EQ(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID"));
}
TEST_F(HardwareDisplayControllerTest, CheckStateIfModesetFails) {
+ InitializeDrmDevice(/* use_atomic */ false);
drm_->set_set_crtc_expectation(false);
ui::DrmOverlayPlane plane(CreateBuffer(), nullptr);
@@ -284,20 +328,6 @@ TEST_F(HardwareDisplayControllerTest, CheckStateIfModesetFails) {
EXPECT_FALSE(controller_->Modeset(plane, kDefaultMode));
}
-TEST_F(HardwareDisplayControllerTest, CheckStateIfPageFlipFails) {
- drm_->set_commit_expectation(false);
-
- ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
-
- EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
-
- ui::DrmOverlayPlane plane2(CreateBuffer(), nullptr);
- std::vector<ui::DrmOverlayPlane> planes;
- planes.push_back(plane2.Clone());
- EXPECT_DEATH_IF_SUPPORTED(SchedulePageFlip(std::move(planes)),
- "SchedulePageFlip failed");
-}
-
TEST_F(HardwareDisplayControllerTest, CheckOverlayPresent) {
ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
ui::DrmOverlayPlane plane2(
@@ -305,6 +335,7 @@ TEST_F(HardwareDisplayControllerTest, CheckOverlayPresent) {
gfx::Rect(kOverlaySize), gfx::RectF(kDefaultModeSizeF), true, nullptr);
EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
+ EXPECT_EQ(1, drm_->get_commit_count());
std::vector<ui::DrmOverlayPlane> planes;
planes.push_back(plane1.Clone());
@@ -314,7 +345,7 @@ TEST_F(HardwareDisplayControllerTest, CheckOverlayPresent) {
drm_->RunCallbacks();
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_);
EXPECT_EQ(1, page_flips_);
- EXPECT_EQ(1, drm_->get_commit_count());
+ EXPECT_EQ(2, drm_->get_commit_count());
// Verify both planes on the primary display have a valid framebuffer.
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID"));
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID"));
@@ -327,13 +358,14 @@ TEST_F(HardwareDisplayControllerTest, CheckOverlayTestMode) {
gfx::Rect(kOverlaySize), gfx::RectF(kDefaultModeSizeF), true, nullptr);
EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
+ EXPECT_EQ(1, drm_->get_commit_count());
std::vector<ui::DrmOverlayPlane> planes;
planes.push_back(plane1.Clone());
planes.push_back(plane2.Clone());
SchedulePageFlip(ui::DrmOverlayPlane::Clone(planes));
- EXPECT_EQ(1, drm_->get_commit_count());
+ EXPECT_EQ(2, drm_->get_commit_count());
// Verify both planes on the primary display have a valid framebuffer.
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID"));
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID"));
@@ -343,14 +375,14 @@ TEST_F(HardwareDisplayControllerTest, CheckOverlayTestMode) {
drm_->RunCallbacks();
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_);
EXPECT_EQ(1, page_flips_);
- EXPECT_EQ(2, drm_->get_commit_count());
+ EXPECT_EQ(3, drm_->get_commit_count());
// Regular flips should continue on normally.
SchedulePageFlip(ui::DrmOverlayPlane::Clone(planes));
drm_->RunCallbacks();
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_);
EXPECT_EQ(2, page_flips_);
- EXPECT_EQ(3, drm_->get_commit_count());
+ EXPECT_EQ(4, drm_->get_commit_count());
// Verify both planes on the primary display have a valid framebuffer.
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID"));
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID"));
@@ -375,12 +407,13 @@ TEST_F(HardwareDisplayControllerTest, AcceptUnderlays) {
}
TEST_F(HardwareDisplayControllerTest, PageflipMirroredControllers) {
- controller_->AddCrtc(std::unique_ptr<ui::CrtcController>(
- new ui::CrtcController(drm_.get(), kSecondaryCrtc, kSecondaryConnector)));
+ controller_->AddCrtc(
+ std::unique_ptr<ui::CrtcController>(new ui::CrtcController(
+ drm_.get(), kSecondaryCrtc, kConnectorIdBase + 1)));
ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
- EXPECT_EQ(2, drm_->get_set_crtc_call_count());
+ EXPECT_EQ(2, drm_->get_commit_count());
ui::DrmOverlayPlane plane2(CreateBuffer(), nullptr);
std::vector<ui::DrmOverlayPlane> planes;
@@ -389,7 +422,7 @@ TEST_F(HardwareDisplayControllerTest, PageflipMirroredControllers) {
drm_->RunCallbacks();
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_);
EXPECT_EQ(1, page_flips_);
- EXPECT_EQ(1, drm_->get_commit_count());
+ EXPECT_EQ(3, drm_->get_commit_count());
// Verify only the displays have a valid framebuffer on the primary plane.
// First display:
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID"));
@@ -400,8 +433,9 @@ TEST_F(HardwareDisplayControllerTest, PageflipMirroredControllers) {
}
TEST_F(HardwareDisplayControllerTest, PlaneStateAfterRemoveCrtc) {
- controller_->AddCrtc(std::unique_ptr<ui::CrtcController>(
- new ui::CrtcController(drm_.get(), kSecondaryCrtc, kSecondaryConnector)));
+ controller_->AddCrtc(
+ std::unique_ptr<ui::CrtcController>(new ui::CrtcController(
+ drm_.get(), kSecondaryCrtc, kConnectorIdBase + 1)));
ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
@@ -472,8 +506,9 @@ TEST_F(HardwareDisplayControllerTest, PlaneStateAfterDestroyingCrtc) {
}
TEST_F(HardwareDisplayControllerTest, PlaneStateAfterAddCrtc) {
- controller_->AddCrtc(std::unique_ptr<ui::CrtcController>(
- new ui::CrtcController(drm_.get(), kSecondaryCrtc, kSecondaryConnector)));
+ controller_->AddCrtc(
+ std::unique_ptr<ui::CrtcController>(new ui::CrtcController(
+ drm_.get(), kSecondaryCrtc, kConnectorIdBase + 1)));
ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
@@ -534,10 +569,10 @@ TEST_F(HardwareDisplayControllerTest, ModesetWhilePageFlipping) {
}
TEST_F(HardwareDisplayControllerTest, FailPageFlipping) {
- drm_->set_commit_expectation(false);
-
ui::DrmOverlayPlane plane1(CreateBuffer(), nullptr);
EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode));
+
+ drm_->set_commit_expectation(false);
std::vector<ui::DrmOverlayPlane> planes;
planes.push_back(plane1.Clone());
EXPECT_DEATH_IF_SUPPORTED(SchedulePageFlip(std::move(planes)),
@@ -565,8 +600,9 @@ TEST_F(HardwareDisplayControllerTest, AddCrtcMidPageFlip) {
planes.push_back(plane1.Clone());
SchedulePageFlip(std::move(planes));
- controller_->AddCrtc(std::unique_ptr<ui::CrtcController>(
- new ui::CrtcController(drm_.get(), kSecondaryCrtc, kSecondaryConnector)));
+ controller_->AddCrtc(
+ std::unique_ptr<ui::CrtcController>(new ui::CrtcController(
+ drm_.get(), kSecondaryCrtc, kConnectorIdBase + 1)));
drm_->RunCallbacks();
EXPECT_EQ(gfx::SwapResult::SWAP_ACK, last_swap_result_);
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.cc
index a118c818103..28d692268d7 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.cc
@@ -123,6 +123,7 @@ bool HardwareDisplayPlaneAtomic::SetPlaneData(
return false;
}
+ crtc_id_ = crtc_id;
return true;
}
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h
index a28f562a468..af874abf6c7 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h
@@ -18,8 +18,6 @@ class Rect;
namespace ui {
-class CrtcController;
-
class HardwareDisplayPlaneAtomic : public HardwareDisplayPlane {
public:
HardwareDisplayPlaneAtomic(uint32_t id);
@@ -37,11 +35,10 @@ class HardwareDisplayPlaneAtomic : public HardwareDisplayPlane {
bool SetPlaneCtm(drmModeAtomicReq* property_set, uint32_t ctm_blob_id);
- void set_crtc(CrtcController* crtc) { crtc_ = crtc; }
- CrtcController* crtc() const { return crtc_; }
+ uint32_t crtc_id() { return crtc_id_; }
private:
- CrtcController* crtc_ = nullptr;
+ uint32_t crtc_id_ = 0;
DISALLOW_COPY_AND_ASSIGN(HardwareDisplayPlaneAtomic);
};
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
index 66f79d06038..0cdaaca15cf 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -28,20 +28,16 @@ HardwareDisplayPlaneList::HardwareDisplayPlaneList() {
atomic_property_set.reset(drmModeAtomicAlloc());
}
-HardwareDisplayPlaneList::~HardwareDisplayPlaneList() {
-}
+HardwareDisplayPlaneList::~HardwareDisplayPlaneList() = default;
HardwareDisplayPlaneList::PageFlipInfo::PageFlipInfo(uint32_t crtc_id,
- uint32_t framebuffer,
- CrtcController* crtc)
- : crtc_id(crtc_id), framebuffer(framebuffer), crtc(crtc) {
-}
+ uint32_t framebuffer)
+ : crtc_id(crtc_id), framebuffer(framebuffer) {}
HardwareDisplayPlaneList::PageFlipInfo::PageFlipInfo(
const PageFlipInfo& other) = default;
-HardwareDisplayPlaneList::PageFlipInfo::~PageFlipInfo() {
-}
+HardwareDisplayPlaneList::PageFlipInfo::~PageFlipInfo() = default;
HardwareDisplayPlaneManager::CrtcState::CrtcState() = default;
@@ -52,8 +48,7 @@ HardwareDisplayPlaneManager::CrtcState::CrtcState(CrtcState&&) = default;
HardwareDisplayPlaneManager::HardwareDisplayPlaneManager(DrmDevice* drm)
: drm_(drm) {}
-HardwareDisplayPlaneManager::~HardwareDisplayPlaneManager() {
-}
+HardwareDisplayPlaneManager::~HardwareDisplayPlaneManager() = default;
bool HardwareDisplayPlaneManager::Initialize() {
// Try to get all of the planes if possible, so we don't have to try to
@@ -99,9 +94,19 @@ HardwareDisplayPlane* HardwareDisplayPlaneManager::FindNextUnusedPlane(
}
int HardwareDisplayPlaneManager::LookupCrtcIndex(uint32_t crtc_id) const {
- for (size_t i = 0; i < crtc_state_.size(); ++i)
+ for (size_t i = 0; i < crtc_state_.size(); ++i) {
if (crtc_state_[i].properties.id == crtc_id)
return i;
+ }
+ return -1;
+}
+
+int HardwareDisplayPlaneManager::LookupConnectorIndex(
+ uint32_t connector_id) const {
+ for (size_t i = 0; i < connectors_props_.size(); ++i) {
+ if (connectors_props_[i].id == connector_id)
+ return i;
+ }
return -1;
}
@@ -159,8 +164,7 @@ void HardwareDisplayPlaneManager::BeginFrame(
bool HardwareDisplayPlaneManager::AssignOverlayPlanes(
HardwareDisplayPlaneList* plane_list,
const DrmOverlayPlaneList& overlay_list,
- uint32_t crtc_id,
- CrtcController* crtc) {
+ uint32_t crtc_id) {
int crtc_index = LookupCrtcIndex(crtc_id);
if (crtc_index < 0) {
LOG(ERROR) << "Cannot find crtc " << crtc_id;
@@ -185,16 +189,16 @@ bool HardwareDisplayPlaneManager::AssignOverlayPlanes(
// This returns a number in 16.16 fixed point, required by the DRM overlay
// APIs.
- auto to_fixed_point =
- [](double v) -> uint32_t { return v * kFixedPointScaleValue; };
+ auto to_fixed_point = [](double v) -> uint32_t {
+ return v * kFixedPointScaleValue;
+ };
fixed_point_rect = gfx::Rect(to_fixed_point(crop_rect.x()),
to_fixed_point(crop_rect.y()),
to_fixed_point(crop_rect.width()),
to_fixed_point(crop_rect.height()));
}
- if (!SetPlaneData(plane_list, hw_plane, plane, crtc_id, fixed_point_rect,
- crtc)) {
+ if (!SetPlaneData(plane_list, hw_plane, plane, crtc_id, fixed_point_rect)) {
ResetCurrentPlaneList(plane_list);
return false;
}
@@ -226,6 +230,28 @@ std::vector<uint64_t> HardwareDisplayPlaneManager::GetFormatModifiers(
return std::vector<uint64_t>();
}
+void HardwareDisplayPlaneManager::ResetConnectorsCache(
+ const ScopedDrmResourcesPtr& resources) {
+ connectors_props_.clear();
+
+ for (int i = 0; i < resources->count_connectors; ++i) {
+ ConnectorProperties state_props;
+ state_props.id = resources->connectors[i];
+
+ ScopedDrmObjectPropertyPtr props(drm_->GetObjectProperties(
+ resources->connectors[i], DRM_MODE_OBJECT_CONNECTOR));
+ if (!props) {
+ PLOG(ERROR) << "Failed to get Connector properties for connector="
+ << state_props.id;
+ continue;
+ }
+ GetDrmPropertyForName(drm_, props.get(), "CRTC_ID", &state_props.crtc_id);
+ DCHECK(!drm_->is_atomic() || state_props.crtc_id.id);
+
+ connectors_props_.emplace_back(std::move(state_props));
+ }
+}
+
bool HardwareDisplayPlaneManager::SetColorMatrix(
uint32_t crtc_id,
const std::vector<float>& color_matrix) {
@@ -319,6 +345,8 @@ bool HardwareDisplayPlaneManager::InitializeCrtcState() {
return false;
}
+ ResetConnectorsCache(resources);
+
unsigned int num_crtcs_with_out_fence_ptr = 0;
for (int i = 0; i < resources->count_crtcs; ++i) {
@@ -333,6 +361,12 @@ bool HardwareDisplayPlaneManager::InitializeCrtcState() {
continue;
}
+ GetDrmPropertyForName(drm_, props.get(), "ACTIVE",
+ &state.properties.active);
+ DCHECK(!drm_->is_atomic() || state.properties.active.id);
+ GetDrmPropertyForName(drm_, props.get(), "MODE_ID",
+ &state.properties.mode_id);
+ DCHECK(!drm_->is_atomic() || state.properties.mode_id.id);
// These properties are optional. If they don't exist we can tell by the
// invalid ID.
GetDrmPropertyForName(drm_, props.get(), "CTM", &state.properties.ctm);
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
index 6298d579e4f..b24007d6611 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -40,13 +40,12 @@ struct HardwareDisplayPlaneList {
std::vector<HardwareDisplayPlane*> old_plane_list;
struct PageFlipInfo {
- PageFlipInfo(uint32_t crtc_id, uint32_t framebuffer, CrtcController* crtc);
+ PageFlipInfo(uint32_t crtc_id, uint32_t framebuffer);
PageFlipInfo(const PageFlipInfo& other);
~PageFlipInfo();
uint32_t crtc_id;
uint32_t framebuffer;
- CrtcController* crtc;
};
// In the case of non-atomic operation, this info will be used for
// pageflipping.
@@ -57,13 +56,22 @@ struct HardwareDisplayPlaneList {
class HardwareDisplayPlaneManager {
public:
- HardwareDisplayPlaneManager(DrmDevice* drm);
+ explicit HardwareDisplayPlaneManager(DrmDevice* drm);
virtual ~HardwareDisplayPlaneManager();
// This parses information from the drm driver, adding any new planes
// or crtcs found.
bool Initialize();
+ // Performs modesetting, either atomic or legacy, depending on the device.
+ virtual bool Modeset(uint32_t crtc_id,
+ uint32_t framebuffer_id,
+ uint32_t connector_id,
+ const drmModeModeInfo& mode,
+ const HardwareDisplayPlaneList& plane_list) = 0;
+
+ virtual bool DisableModeset(uint32_t crtc_id, uint32_t connector) = 0;
+
// Clears old frame state out. Must be called before any AssignOverlayPlanes
// calls.
void BeginFrame(HardwareDisplayPlaneList* plane_list);
@@ -86,11 +94,10 @@ class HardwareDisplayPlaneManager {
// |crtc_id| will be used. |overlay_list| must be sorted bottom-to-top.
virtual bool AssignOverlayPlanes(HardwareDisplayPlaneList* plane_list,
const DrmOverlayPlaneList& overlay_list,
- uint32_t crtc_id,
- CrtcController* crtc);
+ uint32_t crtc_id);
// Commit the plane states in |plane_list|.
- //
+ // if |should_modeset| is set, it only modesets without page flipping.
// If |page_flip_request| is null, this tests the plane configuration without
// submitting it.
// The fence returned in |out_fence| will signal when the currently scanned
@@ -98,6 +105,7 @@ class HardwareDisplayPlaneManager {
// |page_flip_request|. Note that the returned fence may be a nullptr
// if the system doesn't support out fences.
virtual bool Commit(HardwareDisplayPlaneList* plane_list,
+ bool should_modeset,
scoped_refptr<PageFlipRequest> page_flip_request,
std::unique_ptr<gfx::GpuFence>* out_fence) = 0;
@@ -134,11 +142,21 @@ class HardwareDisplayPlaneManager {
std::vector<uint64_t> GetFormatModifiers(uint32_t crtc_id,
uint32_t format) const;
+ // Cache the most updated connectors found in DRM resources. This needs to be
+ // called whenever a DRM hotplug event is received via UDEV.
+ void ResetConnectorsCache(const ScopedDrmResourcesPtr& resources);
+
protected:
+ struct ConnectorProperties {
+ uint32_t id;
+ DrmDevice::Property crtc_id;
+ };
+
struct CrtcProperties {
// Unique identifier for the CRTC. This must be greater than 0 to be valid.
uint32_t id;
-
+ DrmDevice::Property active;
+ DrmDevice::Property mode_id;
// Optional properties.
DrmDevice::Property ctm;
DrmDevice::Property gamma_lut;
@@ -173,8 +191,7 @@ class HardwareDisplayPlaneManager {
HardwareDisplayPlane* hw_plane,
const DrmOverlayPlane& overlay,
uint32_t crtc_id,
- const gfx::Rect& src_rect,
- CrtcController* crtc) = 0;
+ const gfx::Rect& src_rect) = 0;
virtual std::unique_ptr<HardwareDisplayPlane> CreatePlane(uint32_t plane_id);
@@ -185,8 +202,10 @@ class HardwareDisplayPlaneManager {
uint32_t crtc_index,
const DrmOverlayPlane& overlay) const;
- // Convert |crtc_id| into an index, returning -1 if the ID couldn't be found.
+ // Convert |crtc/connector_id| into an index, returning -1 if the ID couldn't
+ // be found.
int LookupCrtcIndex(uint32_t crtc_id) const;
+ int LookupConnectorIndex(uint32_t connector_idx) const;
// Returns true if |plane| can support |overlay| and compatible with
// |crtc_index|.
@@ -211,6 +230,7 @@ class HardwareDisplayPlaneManager {
std::vector<std::unique_ptr<HardwareDisplayPlane>> planes_;
std::vector<CrtcState> crtc_state_;
+ std::vector<ConnectorProperties> connectors_props_;
std::vector<uint32_t> supported_formats_;
DISALLOW_COPY_AND_ASSIGN(HardwareDisplayPlaneManager);
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
index 869c4414763..5f4a4101c2c 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.cc
@@ -57,17 +57,81 @@ HardwareDisplayPlaneManagerAtomic::HardwareDisplayPlaneManagerAtomic(
DrmDevice* drm)
: HardwareDisplayPlaneManager(drm) {}
-HardwareDisplayPlaneManagerAtomic::~HardwareDisplayPlaneManagerAtomic() {
+HardwareDisplayPlaneManagerAtomic::~HardwareDisplayPlaneManagerAtomic() =
+ default;
+
+bool HardwareDisplayPlaneManagerAtomic::Modeset(
+ uint32_t crtc_id,
+ uint32_t framebuffer_id,
+ uint32_t connector_id,
+ const drmModeModeInfo& mode,
+ const HardwareDisplayPlaneList& plane_list) {
+ const int connector_idx = LookupConnectorIndex(connector_id);
+ DCHECK_GE(connector_idx, 0);
+ connectors_props_[connector_idx].crtc_id.value = crtc_id;
+ bool res =
+ AddPropertyIfValid(plane_list.atomic_property_set.get(), connector_id,
+ connectors_props_[connector_idx].crtc_id);
+
+ const int crtc_idx = LookupCrtcIndex(crtc_id);
+ DCHECK_GE(crtc_idx, 0);
+ crtc_state_[crtc_idx].properties.active.value = 1UL;
+ ScopedDrmPropertyBlob mode_blob =
+ drm_->CreatePropertyBlob(&mode, sizeof(mode));
+ crtc_state_[crtc_idx].properties.mode_id.value =
+ mode_blob ? mode_blob->id() : 0;
+
+ res &= AddPropertyIfValid(plane_list.atomic_property_set.get(), crtc_id,
+ crtc_state_[crtc_idx].properties.active);
+ res &= AddPropertyIfValid(plane_list.atomic_property_set.get(), crtc_id,
+ crtc_state_[crtc_idx].properties.mode_id);
+
+ DCHECK(res);
+ return Commit(const_cast<HardwareDisplayPlaneList*>(&plane_list),
+ /*should_modeset=*/true,
+ /*page_flip_request=*/nullptr,
+ /*out_fence=*/nullptr);
+}
+
+bool HardwareDisplayPlaneManagerAtomic::DisableModeset(uint32_t crtc_id,
+ uint32_t connector) {
+ ScopedDrmAtomicReqPtr property_set(drmModeAtomicAlloc());
+
+ const int connector_idx = LookupConnectorIndex(connector);
+ DCHECK_GE(connector_idx, 0);
+ connectors_props_[connector_idx].crtc_id.value = 0UL;
+ bool res = AddPropertyIfValid(property_set.get(), connector,
+ connectors_props_[connector_idx].crtc_id);
+
+ const int crtc_idx = LookupCrtcIndex(crtc_id);
+ DCHECK_GE(crtc_idx, 0);
+ crtc_state_[crtc_idx].properties.active.value = 0UL;
+ crtc_state_[crtc_idx].properties.mode_id.value = 0UL;
+ res &= AddPropertyIfValid(property_set.get(), crtc_id,
+ crtc_state_[crtc_idx].properties.active);
+ res &= AddPropertyIfValid(property_set.get(), crtc_id,
+ crtc_state_[crtc_idx].properties.mode_id);
+
+ DCHECK(res);
+ return drm_->CommitProperties(property_set.get(),
+ DRM_MODE_ATOMIC_ALLOW_MODESET, 1, nullptr);
}
bool HardwareDisplayPlaneManagerAtomic::Commit(
HardwareDisplayPlaneList* plane_list,
+ bool should_modeset,
scoped_refptr<PageFlipRequest> page_flip_request,
std::unique_ptr<gfx::GpuFence>* out_fence) {
- bool test_only = !page_flip_request;
+ bool test_only = !should_modeset && !page_flip_request;
+
for (HardwareDisplayPlane* plane : plane_list->old_plane_list) {
if (!base::Contains(plane_list->plane_list, plane)) {
- // This plane is being released, so we need to zero it.
+ // |plane| is shared state between |old_plane_list| and |plane_list|.
+ // When we call BeginFrame(), we reset in_use since we need to be able to
+ // allocate the planes as needed. The current frame might not need to use
+ // |plane|, thus |plane->in_use()| would be false even though the previous
+ // frame used it. It's existence in |old_plane_list| is sufficient to
+ // signal that |plane| was in use previously.
plane->set_in_use(false);
HardwareDisplayPlaneAtomic* atomic_plane =
static_cast<HardwareDisplayPlaneAtomic*>(plane);
@@ -77,31 +141,29 @@ bool HardwareDisplayPlaneManagerAtomic::Commit(
}
}
- std::vector<CrtcController*> crtcs;
+ std::vector<uint32_t> crtcs;
for (HardwareDisplayPlane* plane : plane_list->plane_list) {
HardwareDisplayPlaneAtomic* atomic_plane =
static_cast<HardwareDisplayPlaneAtomic*>(plane);
- if (crtcs.empty() || crtcs.back() != atomic_plane->crtc())
- crtcs.push_back(atomic_plane->crtc());
+ if (crtcs.empty() || crtcs.back() != atomic_plane->crtc_id())
+ crtcs.push_back(atomic_plane->crtc_id());
}
drmModeAtomicReqPtr request = plane_list->atomic_property_set.get();
- for (auto* const crtc : crtcs) {
- int idx = LookupCrtcIndex(crtc->crtc());
+ for (uint32_t crtc : crtcs) {
+ int idx = LookupCrtcIndex(crtc);
#if defined(COMMIT_PROPERTIES_ON_PAGE_FLIP)
// Apply all CRTC properties in the page-flip so we don't block the
// swap chain for a vsync.
// TODO(dnicoara): See if we can apply these properties async using
// DRM_MODE_ATOMIC_ASYNC_UPDATE flag when committing.
- AddPropertyIfValid(request, crtc->crtc(),
- crtc_state_[idx].properties.degamma_lut);
- AddPropertyIfValid(request, crtc->crtc(),
- crtc_state_[idx].properties.gamma_lut);
- AddPropertyIfValid(request, crtc->crtc(), crtc_state_[idx].properties.ctm);
+ AddPropertyIfValid(request, crtc, crtc_state_[idx].properties.degamma_lut);
+ AddPropertyIfValid(request, crtc, crtc_state_[idx].properties.gamma_lut);
+ AddPropertyIfValid(request, crtc, crtc_state_[idx].properties.ctm);
#endif
- AddPropertyIfValid(request, crtc->crtc(),
+ AddPropertyIfValid(request, crtc,
crtc_state_[idx].properties.background_color);
}
@@ -114,11 +176,10 @@ bool HardwareDisplayPlaneManagerAtomic::Commit(
}
uint32_t flags = 0;
- if (test_only) {
- flags = DRM_MODE_ATOMIC_TEST_ONLY;
- } else {
- flags = DRM_MODE_ATOMIC_NONBLOCK;
- }
+ if (should_modeset)
+ flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
+ else
+ flags = test_only ? DRM_MODE_ATOMIC_TEST_ONLY : DRM_MODE_ATOMIC_NONBLOCK;
// After we perform the atomic commit, and if the caller has requested an
// out-fence, the out_fence_fds vector will contain any provided out-fence
@@ -230,8 +291,7 @@ bool HardwareDisplayPlaneManagerAtomic::SetPlaneData(
HardwareDisplayPlane* hw_plane,
const DrmOverlayPlane& overlay,
uint32_t crtc_id,
- const gfx::Rect& src_rect,
- CrtcController* crtc) {
+ const gfx::Rect& src_rect) {
HardwareDisplayPlaneAtomic* atomic_plane =
static_cast<HardwareDisplayPlaneAtomic*>(hw_plane);
uint32_t framebuffer_id = overlay.enable_blend
@@ -256,7 +316,6 @@ bool HardwareDisplayPlaneManagerAtomic::SetPlaneData(
LOG(ERROR) << "Failed to set plane properties";
return false;
}
- atomic_plane->set_crtc(crtc);
return true;
}
@@ -346,7 +405,7 @@ bool HardwareDisplayPlaneManagerAtomic::CommitGammaCorrection(
bool HardwareDisplayPlaneManagerAtomic::AddOutFencePtrProperties(
drmModeAtomicReqPtr property_set,
- const std::vector<CrtcController*>& crtcs,
+ const std::vector<uint32_t>& crtcs,
std::vector<base::ScopedFD>* out_fence_fds,
std::vector<base::ScopedFD::Receiver>* out_fence_fd_receivers) {
// Reserve space in vector to ensure no reallocation will take place
@@ -356,8 +415,8 @@ bool HardwareDisplayPlaneManagerAtomic::AddOutFencePtrProperties(
out_fence_fds->reserve(crtcs.size());
out_fence_fd_receivers->reserve(crtcs.size());
- for (auto* crtc : crtcs) {
- const auto crtc_index = LookupCrtcIndex(crtc->crtc());
+ for (uint32_t crtc : crtcs) {
+ const auto crtc_index = LookupCrtcIndex(crtc);
DCHECK_GE(crtc_index, 0);
const auto out_fence_ptr_id =
crtc_state_[crtc_index].properties.out_fence_ptr.id;
@@ -371,11 +430,11 @@ bool HardwareDisplayPlaneManagerAtomic::AddOutFencePtrProperties(
// commit, so we need to ensure that the pointer remains valid
// until then.
int ret = drmModeAtomicAddProperty(
- property_set, crtc->crtc(), out_fence_ptr_id,
+ property_set, crtc, out_fence_ptr_id,
reinterpret_cast<uint64_t>(out_fence_fd_receivers->back().get()));
if (ret < 0) {
- LOG(ERROR) << "Failed to set OUT_FENCE_PTR property for crtc="
- << crtc->crtc() << " error=" << -ret;
+ LOG(ERROR) << "Failed to set OUT_FENCE_PTR property for crtc=" << crtc
+ << " error=" << -ret;
out_fence_fd_receivers->pop_back();
out_fence_fds->pop_back();
return false;
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h
index c259643ef5a..2aa11b73071 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h
@@ -15,11 +15,18 @@ namespace ui {
class HardwareDisplayPlaneManagerAtomic : public HardwareDisplayPlaneManager {
public:
- HardwareDisplayPlaneManagerAtomic(DrmDevice* drm);
+ explicit HardwareDisplayPlaneManagerAtomic(DrmDevice* drm);
~HardwareDisplayPlaneManagerAtomic() override;
// HardwareDisplayPlaneManager:
+ bool Modeset(uint32_t crtc_id,
+ uint32_t framebuffer_id,
+ uint32_t connector_id,
+ const drmModeModeInfo& mode,
+ const HardwareDisplayPlaneList& plane_list) override;
+ bool DisableModeset(uint32_t crtc_id, uint32_t connector) override;
bool Commit(HardwareDisplayPlaneList* plane_list,
+ bool should_modeset,
scoped_refptr<PageFlipRequest> page_flip_request,
std::unique_ptr<gfx::GpuFence>* out_fence) override;
bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override;
@@ -38,8 +45,7 @@ class HardwareDisplayPlaneManagerAtomic : public HardwareDisplayPlaneManager {
HardwareDisplayPlane* hw_plane,
const DrmOverlayPlane& overlay,
uint32_t crtc_id,
- const gfx::Rect& src_rect,
- CrtcController* crtc) override;
+ const gfx::Rect& src_rect) override;
private:
bool InitializePlanes() override;
@@ -48,7 +54,7 @@ class HardwareDisplayPlaneManagerAtomic : public HardwareDisplayPlaneManager {
bool CommitGammaCorrection(const CrtcProperties& crtc_props) override;
bool AddOutFencePtrProperties(
drmModeAtomicReqPtr property_set,
- const std::vector<CrtcController*>& crtcs,
+ const std::vector<uint32_t>& crtcs,
std::vector<base::ScopedFD>* out_fence_fds,
std::vector<base::ScopedFD::Receiver>* out_fence_fd_receivers);
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
index 11b6c8de1da..a09037cf0df 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.cc
@@ -12,6 +12,7 @@
#include "base/bind.h"
#include "base/posix/eintr_wrapper.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/presentation_feedback.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
@@ -42,13 +43,31 @@ HardwareDisplayPlaneManagerLegacy::HardwareDisplayPlaneManagerLegacy(
DrmDevice* drm)
: HardwareDisplayPlaneManager(drm) {}
-HardwareDisplayPlaneManagerLegacy::~HardwareDisplayPlaneManagerLegacy() {
+HardwareDisplayPlaneManagerLegacy::~HardwareDisplayPlaneManagerLegacy() =
+ default;
+
+bool HardwareDisplayPlaneManagerLegacy::Modeset(
+ uint32_t crtc_id,
+ uint32_t framebuffer_id,
+ uint32_t connector_id,
+ const drmModeModeInfo& mode,
+ const HardwareDisplayPlaneList&) {
+ return drm_->SetCrtc(crtc_id, framebuffer_id,
+ std::vector<uint32_t>(1, connector_id), mode);
+}
+
+bool HardwareDisplayPlaneManagerLegacy::DisableModeset(uint32_t crtc_id,
+ uint32_t connector) {
+ return drm_->DisableCrtc(crtc_id);
}
bool HardwareDisplayPlaneManagerLegacy::Commit(
HardwareDisplayPlaneList* plane_list,
+ bool should_modeset,
scoped_refptr<PageFlipRequest> page_flip_request,
std::unique_ptr<gfx::GpuFence>* out_fence) {
+ DCHECK(!should_modeset);
+
bool test_only = !page_flip_request;
if (test_only) {
for (HardwareDisplayPlane* plane : plane_list->plane_list) {
@@ -121,10 +140,9 @@ bool HardwareDisplayPlaneManagerLegacy::ValidatePrimarySize(
void HardwareDisplayPlaneManagerLegacy::RequestPlanesReadyCallback(
DrmOverlayPlaneList planes,
base::OnceCallback<void(DrmOverlayPlaneList planes)> callback) {
- base::PostTaskAndReplyWithResult(
+ base::ThreadPool::PostTaskAndReplyWithResult(
FROM_HERE,
- {base::ThreadPool(), base::MayBlock(),
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(&WaitForPlaneFences, std::move(planes)),
std::move(callback));
}
@@ -178,8 +196,7 @@ bool HardwareDisplayPlaneManagerLegacy::SetPlaneData(
HardwareDisplayPlane* hw_plane,
const DrmOverlayPlane& overlay,
uint32_t crtc_id,
- const gfx::Rect& src_rect,
- CrtcController* crtc) {
+ const gfx::Rect& src_rect) {
// Legacy modesetting rejects transforms.
if (overlay.plane_transform != gfx::OVERLAY_TRANSFORM_NONE)
return false;
@@ -188,7 +205,7 @@ bool HardwareDisplayPlaneManagerLegacy::SetPlaneData(
plane_list->legacy_page_flips.back().crtc_id != crtc_id) {
plane_list->legacy_page_flips.push_back(
HardwareDisplayPlaneList::PageFlipInfo(
- crtc_id, overlay.buffer->opaque_framebuffer_id(), crtc));
+ crtc_id, overlay.buffer->opaque_framebuffer_id()));
} else {
return false;
}
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h
index 3843560218e..668ffde7258 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h
@@ -15,11 +15,18 @@ namespace ui {
class HardwareDisplayPlaneManagerLegacy : public HardwareDisplayPlaneManager {
public:
- HardwareDisplayPlaneManagerLegacy(DrmDevice* device);
+ explicit HardwareDisplayPlaneManagerLegacy(DrmDevice* device);
~HardwareDisplayPlaneManagerLegacy() override;
// HardwareDisplayPlaneManager:
+ bool Modeset(uint32_t crtc_id,
+ uint32_t framebuffer_id,
+ uint32_t connector_id,
+ const drmModeModeInfo& mode,
+ const HardwareDisplayPlaneList& plane_list) override;
+ bool DisableModeset(uint32_t crtc_id, uint32_t connector) override;
bool Commit(HardwareDisplayPlaneList* plane_list,
+ bool should_modeset,
scoped_refptr<PageFlipRequest> page_flip_request,
std::unique_ptr<gfx::GpuFence>* out_fence) override;
bool DisableOverlayPlanes(HardwareDisplayPlaneList* plane_list) override;
@@ -41,8 +48,7 @@ class HardwareDisplayPlaneManagerLegacy : public HardwareDisplayPlaneManager {
HardwareDisplayPlane* hw_plane,
const DrmOverlayPlane& overlay,
uint32_t crtc_id,
- const gfx::Rect& src_rect,
- CrtcController* crtc) override;
+ const gfx::Rect& src_rect) override;
bool IsCompatible(HardwareDisplayPlane* plane,
const DrmOverlayPlane& overlay,
uint32_t crtc_index) const override;
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
index 3450da8065e..5acf29f9eb8 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager_unittest.cc
@@ -18,7 +18,10 @@
#include "ui/display/types/gamma_ramp_rgb_entry.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_fence_handle.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
+#include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_buffer.h"
+#include "ui/gfx/linux/test/mock_gbm_device.h"
+#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_framebuffer.h"
#include "ui/ozone/platform/drm/gpu/drm_gpu_util.h"
@@ -26,30 +29,40 @@
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h"
#include "ui/ozone/platform/drm/gpu/mock_drm_device.h"
-#include "ui/ozone/platform/drm/gpu/mock_gbm_device.h"
namespace {
constexpr uint32_t kPlaneOffset = 100;
-constexpr uint32_t kTypePropId = 300;
-constexpr uint32_t kInFormatsPropId = 301;
-constexpr uint32_t kPlaneCtmId = 302;
-constexpr uint32_t kCtmPropId = 303;
-constexpr uint32_t kGammaLutPropId = 304;
-constexpr uint32_t kGammaLutSizePropId = 305;
-constexpr uint32_t kDegammaLutPropId = 306;
-constexpr uint32_t kDegammaLutSizePropId = 307;
-constexpr uint32_t kOutFencePtrPropId = 308;
+constexpr uint32_t kCrtcIdBase = 500;
+constexpr uint32_t kConnectorIdBase = 700;
+
+constexpr uint32_t kActivePropId = 1000;
+constexpr uint32_t kModePropId = 1001;
+constexpr uint32_t kBackgroundColorPropId = 1002;
+constexpr uint32_t kCtmPropId = 1003;
+constexpr uint32_t kGammaLutPropId = 1004;
+constexpr uint32_t kGammaLutSizePropId = 1005;
+constexpr uint32_t kDegammaLutPropId = 1006;
+constexpr uint32_t kDegammaLutSizePropId = 1007;
+constexpr uint32_t kOutFencePtrPropId = 1008;
+
+constexpr uint32_t kCrtcIdPropId = 2000;
+constexpr uint32_t kTypePropId = 3010;
+constexpr uint32_t kInFormatsPropId = 3011;
+constexpr uint32_t kPlaneCtmId = 3012;
+
constexpr uint32_t kInFormatsBlobPropId = 400;
-constexpr uint32_t kBackgroundColorPropId = 401;
const gfx::Size kDefaultBufferSize(2, 2);
+// Create a basic mode for a 6x4 screen.
+drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0,
+ 0, 0, 0, 0, 0, 0, {'\0'}};
class HardwareDisplayPlaneManagerTest
: public testing::Test,
public testing::WithParamInterface<bool> {
public:
- HardwareDisplayPlaneManagerTest() {}
+ HardwareDisplayPlaneManagerTest() = default;
void InitializeDrmState(size_t crtc_count, size_t planes_per_crtc);
@@ -74,7 +87,7 @@ class HardwareDisplayPlaneManagerTest
uint32_t format) {
std::unique_ptr<ui::GbmBuffer> buffer =
fake_drm_->gbm_device()->CreateBuffer(format, size, GBM_BO_USE_SCANOUT);
- return ui::DrmFramebuffer::AddFramebuffer(fake_drm_, buffer.get());
+ return ui::DrmFramebuffer::AddFramebuffer(fake_drm_, buffer.get(), size);
}
protected:
@@ -83,6 +96,7 @@ class HardwareDisplayPlaneManagerTest
scoped_refptr<ui::MockDrmDevice> fake_drm_;
std::vector<ui::MockDrmDevice::CrtcProperties> crtc_properties_;
+ std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties_;
std::vector<ui::MockDrmDevice::PlaneProperties> plane_properties_;
std::map<uint32_t, std::string> property_names_;
@@ -106,35 +120,60 @@ void HardwareDisplayPlaneManagerTest::SetUp() {
void HardwareDisplayPlaneManagerTest::InitializeDrmState(
size_t crtc_count,
size_t planes_per_crtc) {
- property_names_ = {
+ std::map<uint32_t, std::string> crtc_property_names = {
+ {kActivePropId, "ACTIVE"},
+ {kModePropId, "MODE_ID"},
+ };
+
+ std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(1);
+ std::map<uint32_t, std::string> connector_property_names = {
+ {kCrtcIdPropId, "CRTC_ID"},
+ };
+ for (size_t i = 0; i < connector_properties.size(); ++i) {
+ connector_properties[i].id = kConnectorIdBase + i;
+ for (const auto& pair : connector_property_names) {
+ connector_properties[i].properties.push_back(
+ {/* .id = */ pair.first, /* .value = */ 0});
+ }
+ }
+ connector_properties_ = connector_properties;
+
+ std::vector<ui::MockDrmDevice::PlaneProperties> plane_properties(
+ planes_per_crtc * crtc_count);
+ std::map<uint32_t, std::string> plane_property_names = {
// Add all required properties.
- {200, "CRTC_ID"},
- {201, "CRTC_X"},
- {202, "CRTC_Y"},
- {203, "CRTC_W"},
- {204, "CRTC_H"},
- {205, "FB_ID"},
- {206, "SRC_X"},
- {207, "SRC_Y"},
- {208, "SRC_W"},
- {209, "SRC_H"},
+ {3000, "CRTC_ID"},
+ {3001, "CRTC_X"},
+ {3002, "CRTC_Y"},
+ {3003, "CRTC_W"},
+ {3004, "CRTC_H"},
+ {3005, "FB_ID"},
+ {3006, "SRC_X"},
+ {3007, "SRC_Y"},
+ {3008, "SRC_W"},
+ {3009, "SRC_H"},
// Defines some optional properties we use for convenience.
{kTypePropId, "type"},
{kInFormatsPropId, "IN_FORMATS"},
};
+
// Always add an additional cursor plane.
++planes_per_crtc;
for (size_t i = 0; i < crtc_count; ++i) {
ui::MockDrmDevice::CrtcProperties crtc_prop;
// Start ID at 1 cause 0 is an invalid ID.
- crtc_prop.id = i + 1;
+ crtc_prop.id = kCrtcIdBase + i;
+ for (const auto& pair : crtc_property_names) {
+ crtc_prop.properties.push_back(
+ {/* .id = */ pair.first, /* .value = */ 0});
+ }
crtc_properties_.emplace_back(std::move(crtc_prop));
for (size_t j = 0; j < planes_per_crtc; ++j) {
ui::MockDrmDevice::PlaneProperties plane_prop;
plane_prop.id = kPlaneOffset + i * planes_per_crtc + j;
plane_prop.crtc_mask = 1 << i;
- for (const auto& pair : property_names_) {
+ for (const auto& pair : plane_property_names) {
uint32_t value = 0;
if (pair.first == kTypePropId) {
if (j == 0)
@@ -154,36 +193,42 @@ void HardwareDisplayPlaneManagerTest::InitializeDrmState(
}
}
+ property_names_.insert(crtc_property_names.begin(),
+ crtc_property_names.end());
+ property_names_.insert(connector_property_names.begin(),
+ connector_property_names.end());
+ property_names_.insert(plane_property_names.begin(),
+ plane_property_names.end());
+
// Separately add optional properties that will be used in some tests, but the
// tests will append the property to the planes on a case-by-case basis.
//
// Plane properties:
property_names_.insert({kPlaneCtmId, "PLANE_CTM"});
// CRTC properties:
+ property_names_.insert({kBackgroundColorPropId, "BACKGROUND_COLOR"});
property_names_.insert({kCtmPropId, "CTM"});
property_names_.insert({kGammaLutPropId, "GAMMA_LUT"});
property_names_.insert({kGammaLutSizePropId, "GAMMA_LUT_SIZE"});
property_names_.insert({kDegammaLutPropId, "DEGAMMA_LUT"});
property_names_.insert({kDegammaLutSizePropId, "DEGAMMA_LUT_SIZE"});
property_names_.insert({kOutFencePtrPropId, "OUT_FENCE_PTR"});
- property_names_.insert({kBackgroundColorPropId, "BACKGROUND_COLOR"});
}
void HardwareDisplayPlaneManagerTest::PerformPageFlip(
size_t crtc_idx,
ui::HardwareDisplayPlaneList* state) {
ui::DrmOverlayPlaneList assigns;
- ui::CrtcController crtc(fake_drm_, crtc_properties_[crtc_idx].id, 0);
scoped_refptr<ui::DrmFramebuffer> xrgb_buffer =
CreateBuffer(kDefaultBufferSize);
assigns.push_back(ui::DrmOverlayPlane(xrgb_buffer, nullptr));
fake_drm_->plane_manager()->BeginFrame(state);
ASSERT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- state, assigns, crtc_properties_[crtc_idx].id, &crtc));
+ state, assigns, crtc_properties_[crtc_idx].id));
scoped_refptr<ui::PageFlipRequest> page_flip_request =
base::MakeRefCounted<ui::PageFlipRequest>(base::TimeDelta());
- ASSERT_TRUE(
- fake_drm_->plane_manager()->Commit(state, page_flip_request, nullptr));
+ ASSERT_TRUE(fake_drm_->plane_manager()->Commit(
+ state, /*should_modeset*/ false, page_flip_request, nullptr));
}
uint64_t HardwareDisplayPlaneManagerTest::GetObjectPropertyValue(
@@ -213,16 +258,86 @@ uint64_t HardwareDisplayPlaneManagerTest::GetPlanePropertyValue(
using HardwareDisplayPlaneManagerLegacyTest = HardwareDisplayPlaneManagerTest;
using HardwareDisplayPlaneManagerAtomicTest = HardwareDisplayPlaneManagerTest;
+TEST_P(HardwareDisplayPlaneManagerTest, ResettingConnectorCache) {
+ const int connector_and_crtc_count = 3;
+ InitializeDrmState(/*crtc_count=*/connector_and_crtc_count,
+ /*planes_per_crtc=*/1);
+
+ // Create 3 connectors, kConnectorIdBase + 0/1/2
+ std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(
+ connector_and_crtc_count);
+ for (size_t i = 0; i < connector_and_crtc_count; ++i) {
+ connector_properties[i].id = kConnectorIdBase + i;
+ connector_properties[i].properties.push_back(
+ {/* .id = */ kCrtcIdPropId, /* .value = */ 0});
+ }
+
+ fake_drm_->InitializeState(crtc_properties_, connector_properties,
+ plane_properties_, property_names_,
+ /*use_atomic=*/true);
+
+ constexpr uint32_t kFrameBuffer = 2;
+ ui::HardwareDisplayPlaneList state;
+ // Check all 3 connectors exist
+ for (size_t i = 0; i < connector_and_crtc_count; ++i) {
+ EXPECT_TRUE(fake_drm_->plane_manager()->Modeset(
+ crtc_properties_[i].id, kFrameBuffer, connector_properties[i].id,
+ kDefaultMode, state));
+ }
+
+ // Replace last connector and update state.
+ connector_properties[connector_and_crtc_count - 1].id = kConnectorIdBase + 3;
+ fake_drm_->UpdateState(crtc_properties_, connector_properties,
+ plane_properties_, property_names_);
+ fake_drm_->plane_manager()->ResetConnectorsCache(fake_drm_->GetResources());
+
+ EXPECT_TRUE(fake_drm_->plane_manager()->Modeset(
+ crtc_properties_[0].id, kFrameBuffer, kConnectorIdBase, kDefaultMode,
+ state));
+ EXPECT_TRUE(fake_drm_->plane_manager()->Modeset(
+ crtc_properties_[1].id, kFrameBuffer, kConnectorIdBase + 1, kDefaultMode,
+ state));
+ EXPECT_TRUE(fake_drm_->plane_manager()->Modeset(
+ crtc_properties_[2].id, kFrameBuffer, kConnectorIdBase + 3, kDefaultMode,
+ state));
+}
+
+TEST_P(HardwareDisplayPlaneManagerLegacyTest, Modeset) {
+ InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_,
+ /*use_atomic=*/false);
+ fake_drm_->set_set_crtc_expectation(false);
+
+ constexpr uint32_t kFrameBuffer = 2;
+ ui::HardwareDisplayPlaneList state;
+ EXPECT_FALSE(fake_drm_->plane_manager()->Modeset(
+ crtc_properties_[0].id, kFrameBuffer, connector_properties_[0].id,
+ kDefaultMode, state));
+ EXPECT_EQ(kFrameBuffer, fake_drm_->current_framebuffer());
+ EXPECT_EQ(1, fake_drm_->get_set_crtc_call_count());
+}
+
+TEST_P(HardwareDisplayPlaneManagerLegacyTest, DisableModeset) {
+ InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_,
+ /*use_atomic*/ false);
+
+ EXPECT_TRUE(
+ fake_drm_->plane_manager()->DisableModeset(crtc_properties_[0].id, 0));
+}
+
TEST_P(HardwareDisplayPlaneManagerLegacyTest, SinglePlaneAssignment) {
ui::DrmOverlayPlaneList assigns;
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/1);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
EXPECT_EQ(1u, state_.plane_list.size());
}
@@ -231,8 +346,8 @@ TEST_P(HardwareDisplayPlaneManagerLegacyTest, AddCursor) {
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/1);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
bool cursor_found = false;
for (const auto& plane : fake_drm_->plane_manager()->planes()) {
@@ -249,11 +364,11 @@ TEST_P(HardwareDisplayPlaneManagerLegacyTest, BadCrtc) {
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/1);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
- EXPECT_FALSE(fake_drm_->plane_manager()->AssignOverlayPlanes(&state_, assigns,
- 0, nullptr));
+ EXPECT_FALSE(
+ fake_drm_->plane_manager()->AssignOverlayPlanes(&state_, assigns, 0));
}
TEST_P(HardwareDisplayPlaneManagerLegacyTest, NotEnoughPlanes) {
@@ -262,11 +377,11 @@ TEST_P(HardwareDisplayPlaneManagerLegacyTest, NotEnoughPlanes) {
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/1);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_FALSE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
}
TEST_P(HardwareDisplayPlaneManagerLegacyTest, MultipleCrtcs) {
@@ -274,13 +389,13 @@ TEST_P(HardwareDisplayPlaneManagerLegacyTest, MultipleCrtcs) {
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/1);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[1].id, nullptr));
+ &state_, assigns, crtc_properties_[1].id));
EXPECT_EQ(2u, state_.plane_list.size());
}
@@ -290,13 +405,13 @@ TEST_P(HardwareDisplayPlaneManagerLegacyTest, MultiplePlanesAndCrtcs) {
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/2);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_FALSE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
EXPECT_FALSE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[1].id, nullptr));
+ &state_, assigns, crtc_properties_[1].id));
EXPECT_EQ(0u, state_.plane_list.size());
}
@@ -307,24 +422,109 @@ TEST_P(HardwareDisplayPlaneManagerLegacyTest, CheckFramebufferFormatMatch) {
assigns.push_back(ui::DrmOverlayPlane(buffer, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/1);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
fake_drm_->plane_manager()->BeginFrame(&state_);
// This should return false as plane manager creates planes which support
// DRM_FORMAT_XRGB8888 while buffer returns kDummyFormat as its pixelFormat.
EXPECT_FALSE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
assigns.clear();
scoped_refptr<ui::DrmFramebuffer> xrgb_buffer =
CreateBuffer(kDefaultBufferSize);
assigns.push_back(ui::DrmOverlayPlane(xrgb_buffer, nullptr));
fake_drm_->plane_manager()->BeginFrame(&state_);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
fake_drm_->plane_manager()->BeginFrame(&state_);
EXPECT_FALSE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
+}
+
+TEST_P(HardwareDisplayPlaneManagerAtomicTest, Modeset) {
+ InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_,
+ /*use_atomic=*/true);
+
+ constexpr uint32_t kFrameBuffer = 2;
+ ui::HardwareDisplayPlaneList state;
+ EXPECT_TRUE(fake_drm_->plane_manager()->Modeset(
+ crtc_properties_[0].id, kFrameBuffer, connector_properties_[0].id,
+ kDefaultMode, state));
+
+ EXPECT_EQ(1, fake_drm_->get_commit_count());
+}
+
+TEST_P(HardwareDisplayPlaneManagerAtomicTest, DisableModeset) {
+ InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_,
+ /*use_atomic*/ true);
+
+ EXPECT_TRUE(fake_drm_->plane_manager()->DisableModeset(
+ crtc_properties_[0].id, connector_properties_[0].id));
+ EXPECT_EQ(1, fake_drm_->get_commit_count());
+}
+
+TEST_P(HardwareDisplayPlaneManagerAtomicTest, CheckPropsAfterModeset) {
+ InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_,
+ /*use_atomic=*/true);
+
+ constexpr uint32_t kFrameBuffer = 2;
+ ui::HardwareDisplayPlaneList state;
+ EXPECT_TRUE(fake_drm_->plane_manager()->Modeset(
+ crtc_properties_[0].id, kFrameBuffer, connector_properties_[0].id,
+ kDefaultMode, state));
+
+ // Test props values after modesetting.
+ ui::DrmDevice::Property connector_prop_crtc_id;
+ ui::ScopedDrmObjectPropertyPtr connector_props =
+ fake_drm_->GetObjectProperties(kConnectorIdBase,
+ DRM_MODE_OBJECT_CONNECTOR);
+ ui::GetDrmPropertyForName(fake_drm_.get(), connector_props.get(), "CRTC_ID",
+ &connector_prop_crtc_id);
+ EXPECT_EQ(kCrtcIdPropId, connector_prop_crtc_id.id);
+
+ ui::DrmDevice::Property crtc_prop_for_name;
+ ui::ScopedDrmObjectPropertyPtr crtc_props =
+ fake_drm_->GetObjectProperties(kCrtcIdBase, DRM_MODE_OBJECT_CRTC);
+ ui::GetDrmPropertyForName(fake_drm_.get(), crtc_props.get(), "ACTIVE",
+ &crtc_prop_for_name);
+ EXPECT_EQ(kActivePropId, crtc_prop_for_name.id);
+ EXPECT_EQ(1U, crtc_prop_for_name.value);
+
+ ui::GetDrmPropertyForName(fake_drm_.get(), crtc_props.get(), "MODE_ID",
+ &crtc_prop_for_name);
+ EXPECT_EQ(kModePropId, crtc_prop_for_name.id);
+}
+
+TEST_P(HardwareDisplayPlaneManagerAtomicTest, CheckPropsAfterDisable) {
+ InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_,
+ /*use_atomic=*/true);
+
+ constexpr uint32_t kFrameBuffer = 2;
+ ui::HardwareDisplayPlaneList state;
+ EXPECT_TRUE(fake_drm_->plane_manager()->Modeset(
+ crtc_properties_[0].id, kFrameBuffer, connector_properties_[0].id,
+ kDefaultMode, state));
+
+ // Test props values after disabling.
+ EXPECT_TRUE(fake_drm_->plane_manager()->DisableModeset(
+ crtc_properties_[0].id, connector_properties_[0].id));
+
+ ui::DrmDevice::Property crtc_prop_for_name;
+ ui::ScopedDrmObjectPropertyPtr crtc_props =
+ fake_drm_->GetObjectProperties(kCrtcIdBase, DRM_MODE_OBJECT_CRTC);
+ ui::GetDrmPropertyForName(fake_drm_.get(), crtc_props.get(), "ACTIVE",
+ &crtc_prop_for_name);
+ EXPECT_EQ(kActivePropId, crtc_prop_for_name.id);
+ EXPECT_EQ(0U, crtc_prop_for_name.value);
}
TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultiplePlaneAssignment) {
@@ -333,11 +533,11 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultiplePlaneAssignment) {
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/2);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
EXPECT_EQ(2u, state_.plane_list.size());
}
@@ -347,13 +547,13 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultiplePlanesAndCrtcs) {
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/2);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[1].id, nullptr));
+ &state_, assigns, crtc_properties_[1].id));
EXPECT_EQ(4u, state_.plane_list.size());
}
@@ -373,21 +573,21 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest, SharedPlanes) {
{/* .id = */ kInFormatsPropId, /* .value = */ kInFormatsBlobPropId},
};
plane_properties_.emplace_back(std::move(plane_prop));
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[1].id, nullptr));
+ &state_, assigns, crtc_properties_[1].id));
EXPECT_EQ(2u, state_.plane_list.size());
// The shared plane is now unavailable for use by the other CRTC.
EXPECT_FALSE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
}
TEST_P(HardwareDisplayPlaneManagerAtomicTest, UnusedPlanesAreReleased) {
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/2);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
ui::DrmOverlayPlaneList assigns;
scoped_refptr<ui::DrmFramebuffer> primary_buffer =
@@ -397,25 +597,24 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest, UnusedPlanesAreReleased) {
assigns.push_back(ui::DrmOverlayPlane(primary_buffer, nullptr));
assigns.push_back(ui::DrmOverlayPlane(overlay_buffer, nullptr));
ui::HardwareDisplayPlaneList hdpl;
- ui::CrtcController crtc(fake_drm_, crtc_properties_[0].id, 0);
scoped_refptr<ui::PageFlipRequest> page_flip_request =
base::MakeRefCounted<ui::PageFlipRequest>(base::TimeDelta());
fake_drm_->plane_manager()->BeginFrame(&hdpl);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &hdpl, assigns, crtc_properties_[0].id, &crtc));
- EXPECT_TRUE(
- fake_drm_->plane_manager()->Commit(&hdpl, page_flip_request, nullptr));
+ &hdpl, assigns, crtc_properties_[0].id));
+ EXPECT_TRUE(fake_drm_->plane_manager()->Commit(
+ &hdpl, /*should_modeset*/ false, page_flip_request, nullptr));
assigns.clear();
assigns.push_back(ui::DrmOverlayPlane(primary_buffer, nullptr));
fake_drm_->plane_manager()->BeginFrame(&hdpl);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &hdpl, assigns, crtc_properties_[0].id, &crtc));
+ &hdpl, assigns, crtc_properties_[0].id));
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID"));
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID"));
- EXPECT_TRUE(
- fake_drm_->plane_manager()->Commit(&hdpl, page_flip_request, nullptr));
+ EXPECT_TRUE(fake_drm_->plane_manager()->Commit(
+ &hdpl, /*should_modeset*/ false, page_flip_request, nullptr));
EXPECT_NE(0u, GetPlanePropertyValue(kPlaneOffset, "FB_ID"));
EXPECT_EQ(0u, GetPlanePropertyValue(kPlaneOffset + 1, "FB_ID"));
}
@@ -425,11 +624,11 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultipleFrames) {
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/2);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
EXPECT_EQ(1u, state_.plane_list.size());
// Pretend we committed the frame.
state_.plane_list.swap(state_.old_plane_list);
@@ -437,7 +636,7 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultipleFrames) {
ui::HardwareDisplayPlane* old_plane = state_.old_plane_list[0];
// The same plane should be used.
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
EXPECT_EQ(1u, state_.plane_list.size());
EXPECT_EQ(state_.plane_list[0], old_plane);
}
@@ -447,15 +646,15 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest, MultipleFramesDifferentPlanes) {
assigns.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/2);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
EXPECT_EQ(1u, state_.plane_list.size());
// The other plane should be used.
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns, crtc_properties_[0].id, nullptr));
+ &state_, assigns, crtc_properties_[0].id));
EXPECT_EQ(2u, state_.plane_list.size());
EXPECT_NE(state_.plane_list[0], state_.plane_list[1]);
}
@@ -467,8 +666,8 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest,
{/* .id = */ kPlaneCtmId, /* .value = */ 0});
plane_properties_[1].properties.push_back(
{/* .id = */ kPlaneCtmId, /* .value = */ 0});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
ui::ScopedDrmColorCtmPtr ctm_blob(ui::CreateCTMBlob(std::vector<float>(9)));
EXPECT_TRUE(fake_drm_->plane_manager()->SetColorCorrectionOnAllCrtcPlanes(
@@ -479,8 +678,8 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest,
TEST_P(HardwareDisplayPlaneManagerAtomicTest,
SetColorCorrectionOnAllCrtcPlanes_NoPlaneCtmProperty) {
InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
ui::ScopedDrmColorCtmPtr ctm_blob(ui::CreateCTMBlob(std::vector<float>(9)));
EXPECT_FALSE(fake_drm_->plane_manager()->SetColorCorrectionOnAllCrtcPlanes(
@@ -493,8 +692,8 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest,
InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/2);
plane_properties_[0].properties.push_back(
{/* .id = */ kPlaneCtmId, /* .value = */ 0});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
ui::ScopedDrmColorCtmPtr ctm_blob(ui::CreateCTMBlob(std::vector<float>(9)));
EXPECT_FALSE(fake_drm_->plane_manager()->SetColorCorrectionOnAllCrtcPlanes(
@@ -506,8 +705,8 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetColorMatrix_Success) {
InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
crtc_properties_[0].properties.push_back(
{/* .id = */ kCtmPropId, /* .value = */ 0});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_TRUE(fake_drm_->plane_manager()->SetColorMatrix(
crtc_properties_[0].id, std::vector<float>(9)));
@@ -529,8 +728,8 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetColorMatrix_ErrorEmptyCtm) {
InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
crtc_properties_[0].properties.push_back(
{/* .id = */ kCtmPropId, /* .value = */ 0});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_FALSE(
fake_drm_->plane_manager()->SetColorMatrix(crtc_properties_[0].id, {}));
@@ -548,8 +747,8 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_MissingDegamma) {
InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
crtc_properties_[0].properties.push_back(
{/* .id = */ kCtmPropId, /* .value = */ 0});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_FALSE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {{0, 0, 0}}, {}));
@@ -564,8 +763,9 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_MissingDegamma) {
crtc_properties_[0].properties.push_back(
{/* .id = */ kDegammaLutSizePropId, /* .value = */ 1});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, /*use_atomic=*/true);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_,
+ /*use_atomic=*/true);
EXPECT_FALSE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {{0, 0, 0}}, {}));
@@ -583,8 +783,8 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_MissingGamma) {
InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
crtc_properties_[0].properties.push_back(
{/* .id = */ kCtmPropId, /* .value = */ 0});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_FALSE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {}, {{0, 0, 0}}));
@@ -599,8 +799,9 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_MissingGamma) {
crtc_properties_[0].properties.push_back(
{/* .id = */ kGammaLutSizePropId, /* .value = */ 1});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, /*use_atomic=*/true);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_,
+ /*use_atomic=*/true);
EXPECT_FALSE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {}, {{0, 0, 0}}));
@@ -616,8 +817,8 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_MissingGamma) {
TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_LegacyGamma) {
InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
fake_drm_->set_legacy_gamma_ramp_expectation(true);
EXPECT_TRUE(fake_drm_->plane_manager()->SetGammaCorrection(
@@ -638,8 +839,8 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_Success) {
InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
crtc_properties_[0].properties.push_back(
{/* .id = */ kCtmPropId, /* .value = */ 0});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
EXPECT_FALSE(fake_drm_->plane_manager()->SetGammaCorrection(
crtc_properties_[0].id, {{0, 0, 0}}, {}));
@@ -653,8 +854,8 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetGammaCorrection_Success) {
{/* .id = */ kGammaLutSizePropId, /* .value = */ 1});
crtc_properties_[0].properties.push_back(
{/* .id = */ kGammaLutPropId, /* .value = */ 0});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
ui::HardwareDisplayPlaneList state;
// Check that we reset the properties correctly.
@@ -693,30 +894,30 @@ TEST_P(HardwareDisplayPlaneManagerTest, SetBackgroundColor_Success) {
InitializeDrmState(/*crtc_count=*/1, /*planes_per_crtc=*/1);
crtc_properties_[0].properties.push_back(
{/* .id = */ kBackgroundColorPropId, /* .value = */ 0});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
fake_drm_->plane_manager()->SetBackgroundColor(crtc_properties_[0].id, 0);
if (use_atomic_) {
ui::HardwareDisplayPlaneList state;
PerformPageFlip(/*crtc_idx=*/0, &state);
EXPECT_EQ(1, fake_drm_->get_commit_count());
- EXPECT_EQ(0u, GetCrtcPropertyValue(crtc_properties_[0].id,
- "BACKGROUND_COLOR"));
+ EXPECT_EQ(0u,
+ GetCrtcPropertyValue(crtc_properties_[0].id, "BACKGROUND_COLOR"));
} else {
EXPECT_EQ(0, fake_drm_->get_set_object_property_count());
}
crtc_properties_[0].properties.push_back(
{/* .id = */ kBackgroundColorPropId, /* .value = */ 1});
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
fake_drm_->plane_manager()->SetBackgroundColor(crtc_properties_[0].id, 1);
if (use_atomic_) {
ui::HardwareDisplayPlaneList state;
PerformPageFlip(/*crtc_idx=*/0, &state);
EXPECT_EQ(2, fake_drm_->get_commit_count());
- EXPECT_EQ(1u, GetCrtcPropertyValue(crtc_properties_[0].id,
- "BACKGROUND_COLOR"));
+ EXPECT_EQ(1u,
+ GetCrtcPropertyValue(crtc_properties_[0].id, "BACKGROUND_COLOR"));
} else {
EXPECT_EQ(0, fake_drm_->get_set_object_property_count());
}
@@ -728,11 +929,8 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest,
CreateBuffer(kDefaultBufferSize);
InitializeDrmState(/*crtc_count=*/2, /*planes_per_crtc=*/1);
- fake_drm_->InitializeState(crtc_properties_, plane_properties_,
- property_names_, use_atomic_);
-
- ui::CrtcController crtc1(fake_drm_, crtc_properties_[0].id, 0);
- ui::CrtcController crtc2(fake_drm_, crtc_properties_[1].id, 0);
+ fake_drm_->InitializeState(crtc_properties_, connector_properties_,
+ plane_properties_, property_names_, use_atomic_);
ui::DrmOverlayPlaneList assigns1;
assigns1.push_back(ui::DrmOverlayPlane(fake_buffer_, nullptr));
@@ -741,16 +939,16 @@ TEST_P(HardwareDisplayPlaneManagerAtomicTest,
fake_drm_->plane_manager()->BeginFrame(&state_);
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns1, crtc_properties_[0].id, &crtc1));
+ &state_, assigns1, crtc_properties_[0].id));
EXPECT_TRUE(fake_drm_->plane_manager()->AssignOverlayPlanes(
- &state_, assigns2, crtc_properties_[1].id, &crtc2));
+ &state_, assigns2, crtc_properties_[1].id));
scoped_refptr<ui::PageFlipRequest> page_flip_request =
base::MakeRefCounted<ui::PageFlipRequest>(base::TimeDelta());
std::unique_ptr<gfx::GpuFence> out_fence;
- EXPECT_TRUE(fake_drm_->plane_manager()->Commit(&state_, page_flip_request,
- &out_fence));
+ EXPECT_TRUE(fake_drm_->plane_manager()->Commit(
+ &state_, /*should_modeset*/ false, page_flip_request, &out_fence));
EXPECT_EQ(nullptr, out_fence);
}
@@ -763,7 +961,8 @@ TEST_P(HardwareDisplayPlaneManagerTest,
{/* .id = */ kOutFencePtrPropId, /* .value = */ 2});
EXPECT_FALSE(fake_drm_->InitializeStateWithResult(
- crtc_properties_, plane_properties_, property_names_, use_atomic_));
+ crtc_properties_, connector_properties_, plane_properties_,
+ property_names_, use_atomic_));
}
TEST_P(HardwareDisplayPlaneManagerTest,
@@ -777,19 +976,42 @@ TEST_P(HardwareDisplayPlaneManagerTest,
{/* .id = */ kOutFencePtrPropId, /* .value = */ 3});
EXPECT_TRUE(fake_drm_->InitializeStateWithResult(
- crtc_properties_, plane_properties_, property_names_, use_atomic_));
+ crtc_properties_, connector_properties_, plane_properties_,
+ property_names_, use_atomic_));
+}
+
+// Verifies that formats with 2 bits of alpha decay to opaques for AddFB2().
+TEST_P(HardwareDisplayPlaneManagerTest, ForceOpaqueFormatsForAddFramebuffer) {
+ InitializeDrmState(/*crtc_count=*/3, /*planes_per_crtc=*/1);
+
+ struct {
+ uint32_t input_fourcc; // FourCC presented to AddFramebuffer.
+ uint32_t used_fourcc; // FourCC expected to be used in AddFramebuffer.
+ } kFourCCFormats[] = {
+ {DRM_FORMAT_ABGR2101010, DRM_FORMAT_XBGR2101010},
+ {DRM_FORMAT_ARGB2101010, DRM_FORMAT_XRGB2101010},
+ };
+
+ for (const auto& format_pair : kFourCCFormats) {
+ scoped_refptr<ui::DrmFramebuffer> drm_fb =
+ CreateBufferWithFormat(kDefaultBufferSize, format_pair.input_fourcc);
+
+ EXPECT_EQ(drm_fb->framebuffer_pixel_format(), format_pair.used_fourcc);
+ EXPECT_EQ(drm_fb->opaque_framebuffer_pixel_format(),
+ format_pair.used_fourcc);
+ }
}
-INSTANTIATE_TEST_SUITE_P(/* no prefix */,
+INSTANTIATE_TEST_SUITE_P(All,
HardwareDisplayPlaneManagerTest,
testing::Values(false, true));
// TODO(dnicoara): Migrate as many tests as possible to the general list above.
-INSTANTIATE_TEST_SUITE_P(/* no prefix */,
+INSTANTIATE_TEST_SUITE_P(All,
HardwareDisplayPlaneManagerLegacyTest,
testing::Values(false));
-INSTANTIATE_TEST_SUITE_P(/* no prefix */,
+INSTANTIATE_TEST_SUITE_P(All,
HardwareDisplayPlaneManagerAtomicTest,
testing::Values(true));
@@ -826,7 +1048,7 @@ void FakeFenceFD::Signal() const {
class HardwareDisplayPlaneManagerPlanesReadyTest : public testing::Test {
protected:
- HardwareDisplayPlaneManagerPlanesReadyTest() {}
+ HardwareDisplayPlaneManagerPlanesReadyTest() = default;
void SetUp() override {
auto gbm_device = std::make_unique<ui::MockGbmDevice>();
@@ -844,7 +1066,7 @@ class HardwareDisplayPlaneManagerPlanesReadyTest : public testing::Test {
std::unique_ptr<ui::GbmBuffer> buffer =
fake_drm_->gbm_device()->CreateBuffer(DRM_FORMAT_XRGB8888, size,
GBM_BO_USE_SCANOUT);
- return ui::DrmFramebuffer::AddFramebuffer(fake_drm_, buffer.get());
+ return ui::DrmFramebuffer::AddFramebuffer(fake_drm_, buffer.get(), size);
}
ui::DrmOverlayPlaneList CreatePlanesWithoutFences() {
@@ -955,7 +1177,7 @@ TEST_F(HardwareDisplayPlaneManagerPlanesReadyTest,
class HardwareDisplayPlaneAtomicMock : public ui::HardwareDisplayPlaneAtomic {
public:
HardwareDisplayPlaneAtomicMock() : ui::HardwareDisplayPlaneAtomic(1) {}
- ~HardwareDisplayPlaneAtomicMock() override {}
+ ~HardwareDisplayPlaneAtomicMock() override = default;
bool SetPlaneData(drmModeAtomicReq* property_set,
uint32_t crtc_id,
@@ -985,16 +1207,15 @@ TEST(HardwareDisplayPlaneManagerAtomic, EnableBlend) {
drm_device->gbm_device()->CreateBuffer(
DRM_FORMAT_XRGB8888, kDefaultBufferSize, GBM_BO_USE_SCANOUT);
scoped_refptr<ui::DrmFramebuffer> framebuffer =
- ui::DrmFramebuffer::AddFramebuffer(drm_device, buffer.get());
+ ui::DrmFramebuffer::AddFramebuffer(drm_device, buffer.get(),
+ kDefaultBufferSize);
ui::DrmOverlayPlane overlay(framebuffer, nullptr);
overlay.enable_blend = true;
- plane_manager->SetPlaneData(&plane_list, &hw_plane, overlay, 1, gfx::Rect(),
- nullptr);
+ plane_manager->SetPlaneData(&plane_list, &hw_plane, overlay, 1, gfx::Rect());
EXPECT_EQ(hw_plane.framebuffer(), framebuffer->framebuffer_id());
overlay.enable_blend = false;
- plane_manager->SetPlaneData(&plane_list, &hw_plane, overlay, 1, gfx::Rect(),
- nullptr);
+ plane_manager->SetPlaneData(&plane_list, &hw_plane, overlay, 1, gfx::Rect());
EXPECT_EQ(hw_plane.framebuffer(), framebuffer->opaque_framebuffer_id());
}
diff --git a/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.cc b/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.cc
index b895557f44b..32c5052a2a0 100644
--- a/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.cc
@@ -70,6 +70,11 @@ MockDrmDevice::CrtcProperties::CrtcProperties() = default;
MockDrmDevice::CrtcProperties::CrtcProperties(const CrtcProperties&) = default;
MockDrmDevice::CrtcProperties::~CrtcProperties() = default;
+MockDrmDevice::ConnectorProperties::ConnectorProperties() = default;
+MockDrmDevice::ConnectorProperties::ConnectorProperties(
+ const ConnectorProperties&) = default;
+MockDrmDevice::ConnectorProperties::~ConnectorProperties() = default;
+
MockDrmDevice::PlaneProperties::PlaneProperties() = default;
MockDrmDevice::PlaneProperties::PlaneProperties(const PlaneProperties&) =
default;
@@ -82,7 +87,6 @@ MockDrmDevice::MockDrmDevice(std::unique_ptr<GbmDevice> gbm_device)
std::move(gbm_device)),
get_crtc_call_count_(0),
set_crtc_call_count_(0),
- restore_crtc_call_count_(0),
add_framebuffer_call_count_(0),
remove_framebuffer_call_count_(0),
page_flip_call_count_(0),
@@ -96,6 +100,8 @@ MockDrmDevice::MockDrmDevice(std::unique_ptr<GbmDevice> gbm_device)
plane_manager_ = std::make_unique<HardwareDisplayPlaneManagerLegacy>(this);
}
+MockDrmDevice::~MockDrmDevice() = default;
+
// static
ScopedDrmPropertyBlobPtr MockDrmDevice::AllocateInFormatsBlob(
uint32_t id,
@@ -126,21 +132,23 @@ ScopedDrmPropertyBlobPtr MockDrmDevice::AllocateInFormatsBlob(
void MockDrmDevice::InitializeState(
const std::vector<CrtcProperties>& crtc_properties,
+ const std::vector<ConnectorProperties>& connector_properties,
const std::vector<PlaneProperties>& plane_properties,
const std::map<uint32_t, std::string>& property_names,
bool use_atomic) {
- CHECK(InitializeStateWithResult(crtc_properties, plane_properties,
- property_names, use_atomic));
+ CHECK(InitializeStateWithResult(crtc_properties, connector_properties,
+ plane_properties, property_names,
+ use_atomic));
}
bool MockDrmDevice::InitializeStateWithResult(
const std::vector<CrtcProperties>& crtc_properties,
+ const std::vector<ConnectorProperties>& connector_properties,
const std::vector<PlaneProperties>& plane_properties,
const std::map<uint32_t, std::string>& property_names,
bool use_atomic) {
- crtc_properties_ = crtc_properties;
- plane_properties_ = plane_properties;
- property_names_ = property_names;
+ UpdateState(crtc_properties, connector_properties, plane_properties,
+ property_names);
if (use_atomic) {
plane_manager_ = std::make_unique<HardwareDisplayPlaneManagerAtomic>(this);
} else {
@@ -150,7 +158,16 @@ bool MockDrmDevice::InitializeStateWithResult(
return plane_manager_->Initialize();
}
-MockDrmDevice::~MockDrmDevice() {}
+void MockDrmDevice::UpdateState(
+ const std::vector<CrtcProperties>& crtc_properties,
+ const std::vector<ConnectorProperties>& connector_properties,
+ const std::vector<PlaneProperties>& plane_properties,
+ const std::map<uint32_t, std::string>& property_names) {
+ crtc_properties_ = crtc_properties;
+ connector_properties_ = connector_properties;
+ plane_properties_ = plane_properties;
+ property_names_ = property_names;
+}
ScopedDrmResourcesPtr MockDrmDevice::GetResources() {
ScopedDrmResourcesPtr resources(DrmAllocator<drmModeRes>());
@@ -160,6 +177,12 @@ ScopedDrmResourcesPtr MockDrmDevice::GetResources() {
for (size_t i = 0; i < crtc_properties_.size(); ++i)
resources->crtcs[i] = crtc_properties_[i].id;
+ resources->count_connectors = connector_properties_.size();
+ resources->connectors = static_cast<uint32_t*>(
+ drmMalloc(sizeof(uint32_t) * resources->count_connectors));
+ for (size_t i = 0; i < connector_properties_.size(); ++i)
+ resources->connectors[i] = connector_properties_[i].id;
+
return resources;
}
@@ -185,6 +208,11 @@ ScopedDrmObjectPropertyPtr MockDrmDevice::GetObjectProperties(
CrtcProperties* properties = FindObjectById(object_id, crtc_properties_);
if (properties)
return CreatePropertyObject(properties->properties);
+ } else if (object_type == DRM_MODE_OBJECT_CONNECTOR) {
+ ConnectorProperties* properties =
+ FindObjectById(object_id, connector_properties_);
+ if (properties)
+ return CreatePropertyObject(properties->properties);
}
return nullptr;
@@ -198,30 +226,20 @@ ScopedDrmCrtcPtr MockDrmDevice::GetCrtc(uint32_t crtc_id) {
bool MockDrmDevice::SetCrtc(uint32_t crtc_id,
uint32_t framebuffer,
std::vector<uint32_t> connectors,
- drmModeModeInfo* mode) {
+ const drmModeModeInfo& mode) {
crtc_fb_[crtc_id] = framebuffer;
current_framebuffer_ = framebuffer;
set_crtc_call_count_++;
return set_crtc_expectation_;
}
-bool MockDrmDevice::SetCrtc(drmModeCrtc* crtc,
- std::vector<uint32_t> connectors) {
- restore_crtc_call_count_++;
- return true;
-}
-
bool MockDrmDevice::DisableCrtc(uint32_t crtc_id) {
current_framebuffer_ = 0;
return true;
}
ScopedDrmConnectorPtr MockDrmDevice::GetConnector(uint32_t connector_id) {
- ScopedDrmConnectorPtr connector =
- ScopedDrmConnectorPtr(DrmAllocator<drmModeConnector>());
- connector->connector_id = connector_id;
- connector->connector_type = connector_type_;
- return connector;
+ return ScopedDrmConnectorPtr(DrmAllocator<drmModeConnector>());
}
bool MockDrmDevice::AddFramebuffer2(uint32_t width,
@@ -304,7 +322,7 @@ bool MockDrmDevice::SetProperty(uint32_t connector_id,
return true;
}
-ScopedDrmPropertyBlob MockDrmDevice::CreatePropertyBlob(void* blob,
+ScopedDrmPropertyBlob MockDrmDevice::CreatePropertyBlob(const void* blob,
size_t size) {
uint32_t id = ++property_id_generator_;
allocated_property_blobs_.insert(id);
@@ -412,8 +430,10 @@ bool MockDrmDevice::CommitProperties(
return false;
for (uint32_t i = 0; i < request->cursor; ++i) {
- EXPECT_TRUE(ValidatePropertyValue(request->items[i].property_id,
- request->items[i].value));
+ bool res = ValidatePropertyValue(request->items[i].property_id,
+ request->items[i].value);
+ if (!res)
+ return false;
}
if (page_flip_request)
@@ -424,9 +444,11 @@ bool MockDrmDevice::CommitProperties(
// Only update values if not testing.
for (uint32_t i = 0; i < request->cursor; ++i) {
- EXPECT_TRUE(UpdateProperty(request->items[i].object_id,
- request->items[i].property_id,
- request->items[i].value));
+ bool res =
+ UpdateProperty(request->items[i].object_id,
+ request->items[i].property_id, request->items[i].value);
+ if (!res)
+ return false;
}
return true;
@@ -484,6 +506,13 @@ bool MockDrmDevice::UpdateProperty(uint32_t object_id,
if (crtc_properties)
return UpdateProperty(property_id, value, &crtc_properties->properties);
+ ConnectorProperties* connector_properties =
+ FindObjectById(object_id, connector_properties_);
+ if (connector_properties) {
+ return UpdateProperty(property_id, value,
+ &connector_properties->properties);
+ }
+
return false;
}
diff --git a/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.h b/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.h
index 656870049e3..7eedf4e1939 100644
--- a/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.h
+++ b/chromium/ui/ozone/platform/drm/gpu/mock_drm_device.h
@@ -34,6 +34,16 @@ class MockDrmDevice : public DrmDevice {
std::vector<DrmDevice::Property> properties;
};
+ struct ConnectorProperties {
+ ConnectorProperties();
+ ConnectorProperties(const ConnectorProperties&);
+ ~ConnectorProperties();
+
+ uint32_t id;
+
+ std::vector<DrmDevice::Property> properties;
+ };
+
struct PlaneProperties {
PlaneProperties();
PlaneProperties(const PlaneProperties&);
@@ -44,7 +54,7 @@ class MockDrmDevice : public DrmDevice {
std::vector<DrmDevice::Property> properties;
};
- MockDrmDevice(std::unique_ptr<GbmDevice> gbm_device);
+ explicit MockDrmDevice(std::unique_ptr<GbmDevice> gbm_device);
static ScopedDrmPropertyBlobPtr AllocateInFormatsBlob(
uint32_t id,
@@ -53,7 +63,6 @@ class MockDrmDevice : public DrmDevice {
int get_get_crtc_call_count() const { return get_crtc_call_count_; }
int get_set_crtc_call_count() const { return set_crtc_call_count_; }
- int get_restore_crtc_call_count() const { return restore_crtc_call_count_; }
int get_add_framebuffer_call_count() const {
return add_framebuffer_call_count_;
}
@@ -89,18 +98,24 @@ class MockDrmDevice : public DrmDevice {
return it != crtc_cursor_map_.end() ? it->second : 0;
}
- void set_connector_type(uint32_t type) { connector_type_ = type; }
-
- void InitializeState(const std::vector<CrtcProperties>& crtc_properties,
- const std::vector<PlaneProperties>& plane_properties,
- const std::map<uint32_t, std::string>& property_names,
- bool use_atomic);
+ void InitializeState(
+ const std::vector<CrtcProperties>& crtc_properties,
+ const std::vector<ConnectorProperties>& connector_properties,
+ const std::vector<PlaneProperties>& plane_properties,
+ const std::map<uint32_t, std::string>& property_names,
+ bool use_atomic);
bool InitializeStateWithResult(
const std::vector<CrtcProperties>& crtc_properties,
+ const std::vector<ConnectorProperties>& connector_properties,
const std::vector<PlaneProperties>& plane_properties,
const std::map<uint32_t, std::string>& property_names,
bool use_atomic);
+ void UpdateState(const std::vector<CrtcProperties>& crtc_properties,
+ const std::vector<ConnectorProperties>& connector_properties,
+ const std::vector<PlaneProperties>& plane_properties,
+ const std::map<uint32_t, std::string>& property_names);
+
void RunCallbacks();
void SetPropertyBlob(ScopedDrmPropertyBlobPtr blob);
@@ -114,8 +129,7 @@ class MockDrmDevice : public DrmDevice {
bool SetCrtc(uint32_t crtc_id,
uint32_t framebuffer,
std::vector<uint32_t> connectors,
- drmModeModeInfo* mode) override;
- bool SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors) override;
+ const drmModeModeInfo& mode) override;
bool DisableCrtc(uint32_t crtc_id) override;
ScopedDrmConnectorPtr GetConnector(uint32_t connector_id) override;
bool AddFramebuffer2(uint32_t width,
@@ -139,7 +153,8 @@ class MockDrmDevice : public DrmDevice {
bool SetProperty(uint32_t connector_id,
uint32_t property_id,
uint64_t value) override;
- ScopedDrmPropertyBlob CreatePropertyBlob(void* blob, size_t size) override;
+ ScopedDrmPropertyBlob CreatePropertyBlob(const void* blob,
+ size_t size) override;
void DestroyPropertyBlob(uint32_t id) override;
bool GetCapability(uint64_t capability, uint64_t* value) override;
ScopedDrmPropertyBlobPtr GetPropertyBlob(uint32_t property_id) override;
@@ -183,7 +198,6 @@ class MockDrmDevice : public DrmDevice {
int get_crtc_call_count_;
int set_crtc_call_count_;
- int restore_crtc_call_count_;
int add_framebuffer_call_count_;
int remove_framebuffer_call_count_;
int page_flip_call_count_;
@@ -214,7 +228,7 @@ class MockDrmDevice : public DrmDevice {
base::queue<PageFlipCallback> callbacks_;
std::vector<CrtcProperties> crtc_properties_;
-
+ std::vector<ConnectorProperties> connector_properties_;
std::vector<PlaneProperties> plane_properties_;
std::map<uint32_t, std::string> property_names_;
@@ -225,8 +239,6 @@ class MockDrmDevice : public DrmDevice {
std::set<uint32_t> allocated_property_blobs_;
- uint32_t connector_type_ = DRM_MODE_CONNECTOR_eDP;
-
DISALLOW_COPY_AND_ASSIGN(MockDrmDevice);
};
diff --git a/chromium/ui/ozone/platform/drm/gpu/mock_gbm_device.cc b/chromium/ui/ozone/platform/drm/gpu/mock_gbm_device.cc
deleted file mode 100644
index 8e22910ae5b..00000000000
--- a/chromium/ui/ozone/platform/drm/gpu/mock_gbm_device.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/platform/drm/gpu/mock_gbm_device.h"
-
-#include <drm_fourcc.h>
-#include <xf86drm.h>
-#include <memory>
-#include <utility>
-
-#include "base/logging.h"
-#include "base/numerics/safe_math.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkSurface.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
-
-namespace ui {
-namespace {
-
-class MockGbmBuffer final : public ui::GbmBuffer {
- public:
- MockGbmBuffer(uint32_t format,
- uint32_t flags,
- uint64_t modifier,
- const gfx::Size& size,
- std::vector<gfx::NativePixmapPlane> planes,
- std::vector<uint32_t> handles)
- : format_(format),
- format_modifier_(modifier),
- flags_(flags),
- size_(size),
- planes_(std::move(planes)),
- handles_(std::move(handles)) {}
-
- ~MockGbmBuffer() override {}
-
- uint32_t GetFormat() const override { return format_; }
- uint64_t GetFormatModifier() const override { return format_modifier_; }
- uint32_t GetFlags() const override { return flags_; }
- gfx::Size GetSize() const override { return size_; }
- gfx::BufferFormat GetBufferFormat() const override {
- return ui::GetBufferFormatFromFourCCFormat(format_);
- }
- bool AreFdsValid() const override { return false; }
- size_t GetNumPlanes() const override { return planes_.size(); }
- int GetPlaneFd(size_t plane) const override {
- NOTREACHED();
- return -1;
- }
- uint32_t GetPlaneStride(size_t plane) const override {
- DCHECK_LT(plane, planes_.size());
- return planes_[plane].stride;
- }
- size_t GetPlaneOffset(size_t plane) const override {
- DCHECK_LT(plane, planes_.size());
- return planes_[plane].offset;
- }
- size_t GetPlaneSize(size_t plane) const override {
- DCHECK_LT(plane, planes_.size());
- return static_cast<size_t>(planes_[plane].size);
- }
- uint32_t GetPlaneHandle(size_t plane) const override {
- DCHECK_LT(plane, planes_.size());
- return handles_[plane];
- }
- uint32_t GetHandle() const override { return GetPlaneHandle(0); }
- gfx::NativePixmapHandle ExportHandle() const override {
- NOTIMPLEMENTED();
- return gfx::NativePixmapHandle();
- }
-
- sk_sp<SkSurface> GetSurface() override { return nullptr; }
-
- private:
- uint32_t format_ = 0;
- uint64_t format_modifier_ = 0;
- uint32_t flags_ = 0;
- gfx::Size size_;
- std::vector<gfx::NativePixmapPlane> planes_;
- std::vector<uint32_t> handles_;
-
- DISALLOW_COPY_AND_ASSIGN(MockGbmBuffer);
-};
-
-} // namespace
-
-MockGbmDevice::MockGbmDevice() {}
-
-MockGbmDevice::~MockGbmDevice() {}
-
-void MockGbmDevice::set_allocation_failure(bool should_fail_allocations) {
- should_fail_allocations_ = should_fail_allocations;
-}
-
-std::unique_ptr<GbmBuffer> MockGbmDevice::CreateBuffer(uint32_t format,
- const gfx::Size& size,
- uint32_t flags) {
- if (should_fail_allocations_)
- return nullptr;
-
- return CreateBufferWithModifiers(format, size, flags, {});
-}
-
-std::unique_ptr<GbmBuffer> MockGbmDevice::CreateBufferWithModifiers(
- uint32_t format,
- const gfx::Size& size,
- uint32_t flags,
- const std::vector<uint64_t>& modifiers) {
- if (should_fail_allocations_)
- return nullptr;
-
- uint32_t bytes_per_pixel;
- switch (format) {
- case DRM_FORMAT_XRGB8888:
- case DRM_FORMAT_ARGB8888:
- bytes_per_pixel = 4;
- break;
- case DRM_FORMAT_NV12:
- bytes_per_pixel = 2;
- break;
- default:
- NOTREACHED() << "Unsupported format: " << format;
- return nullptr;
- }
-
- if (modifiers.size() > 1)
- return nullptr;
-
- uint64_t format_modifier =
- modifiers.size() ? modifiers[0] : DRM_FORMAT_MOD_NONE;
- switch (format_modifier) {
- case DRM_FORMAT_MOD_NONE:
- case I915_FORMAT_MOD_X_TILED:
- break;
- default:
- NOTREACHED() << "Unsupported format modifier: " << format_modifier;
- return nullptr;
- }
-
- uint32_t width = base::checked_cast<uint32_t>(size.width());
- uint32_t height = base::checked_cast<uint32_t>(size.height());
- uint32_t plane_stride = base::CheckMul(bytes_per_pixel, width).ValueOrDie();
- uint32_t plane_size = base::CheckMul(plane_stride, height).ValueOrDie();
- uint32_t plane_offset = 0;
-
- std::vector<gfx::NativePixmapPlane> planes;
- planes.push_back(gfx::NativePixmapPlane(plane_stride, plane_offset,
- plane_size, base::ScopedFD()));
- std::vector<uint32_t> handles;
- handles.push_back(next_handle_++);
-
- return std::make_unique<MockGbmBuffer>(format, flags, format_modifier, size,
- std::move(planes), std::move(handles));
-}
-
-std::unique_ptr<GbmBuffer> MockGbmDevice::CreateBufferFromHandle(
- uint32_t format,
- const gfx::Size& size,
- gfx::NativePixmapHandle handle) {
- NOTREACHED();
- return nullptr;
-}
-
-} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/gpu/mock_gbm_device.h b/chromium/ui/ozone/platform/drm/gpu/mock_gbm_device.h
deleted file mode 100644
index 5b31b5d1af4..00000000000
--- a/chromium/ui/ozone/platform/drm/gpu/mock_gbm_device.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_PLATFORM_DRM_GPU_MOCK_GBM_DEVICE_H_
-#define UI_OZONE_PLATFORM_DRM_GPU_MOCK_GBM_DEVICE_H_
-
-#include "ui/ozone/common/linux/gbm_device.h"
-
-namespace ui {
-
-// The real DrmDevice makes actual DRM calls which we can't use in unit tests.
-class MockGbmDevice : public GbmDevice {
- public:
- MockGbmDevice();
- ~MockGbmDevice() override;
-
- void set_allocation_failure(bool should_fail_allocations);
-
- // GbmDevice:
- std::unique_ptr<GbmBuffer> CreateBuffer(uint32_t format,
- const gfx::Size& size,
- uint32_t flags) override;
- std::unique_ptr<GbmBuffer> CreateBufferWithModifiers(
- uint32_t format,
- const gfx::Size& size,
- uint32_t flags,
- const std::vector<uint64_t>& modifiers) override;
- std::unique_ptr<GbmBuffer> CreateBufferFromHandle(
- uint32_t format,
- const gfx::Size& size,
- gfx::NativePixmapHandle handle) override;
-
- private:
- uint32_t next_handle_ = 0;
- bool should_fail_allocations_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(MockGbmDevice);
-};
-
-} // namespace ui
-
-#endif // UI_OZONE_PLATFORM_DRM_GPU_MOCK_GBM_DEVICE_H_
diff --git a/chromium/ui/ozone/platform/drm/gpu/screen_manager.cc b/chromium/ui/ozone/platform/drm/gpu/screen_manager.cc
index 1a347ea3b3c..42473035751 100644
--- a/chromium/ui/ozone/platform/drm/gpu/screen_manager.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/screen_manager.cc
@@ -16,8 +16,8 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_fence.h"
+#include "ui/gfx/linux/gbm_buffer.h"
#include "ui/gfx/skia_util.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
@@ -392,8 +392,8 @@ DrmOverlayPlane ScreenManager::GetModesetBuffer(
return DrmOverlayPlane::Error();
}
- scoped_refptr<DrmFramebuffer> framebuffer =
- DrmFramebuffer::AddFramebuffer(drm, buffer.get(), modifiers);
+ scoped_refptr<DrmFramebuffer> framebuffer = DrmFramebuffer::AddFramebuffer(
+ drm, buffer.get(), buffer->GetSize(), modifiers);
if (!framebuffer) {
LOG(ERROR) << "Failed to add framebuffer for scanout buffer";
return DrmOverlayPlane::Error();
diff --git a/chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc b/chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
index b97acb43851..fea1047c7a2 100644
--- a/chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
@@ -13,7 +13,8 @@
#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/gpu_fence.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
+#include "ui/gfx/linux/gbm_buffer.h"
+#include "ui/gfx/linux/test/mock_gbm_device.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
#include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
@@ -21,7 +22,6 @@
#include "ui/ozone/platform/drm/gpu/drm_window.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
#include "ui/ozone/platform/drm/gpu/mock_drm_device.h"
-#include "ui/ozone/platform/drm/gpu/mock_gbm_device.h"
#include "ui/ozone/platform/drm/gpu/screen_manager.h"
namespace ui {
@@ -31,10 +31,18 @@ namespace {
const drmModeModeInfo kDefaultMode = {0, 6, 0, 0, 0, 0, 4, 0,
0, 0, 0, 0, 0, 0, {'\0'}};
-const uint32_t kPrimaryCrtc = 1;
-const uint32_t kPrimaryConnector = 2;
-const uint32_t kSecondaryCrtc = 3;
-const uint32_t kSecondaryConnector = 4;
+constexpr uint32_t kCrtcIdBase = 100;
+constexpr uint32_t kPrimaryCrtc = kCrtcIdBase;
+constexpr uint32_t kSecondaryCrtc = kCrtcIdBase + 1;
+
+constexpr uint32_t kConnectorIdBase = 200;
+constexpr uint32_t kPrimaryConnector = kConnectorIdBase;
+constexpr uint32_t kSecondaryConnector = kConnectorIdBase + 1;
+constexpr uint32_t kPlaneIdBase = 300;
+constexpr uint32_t kInFormatsBlobPropIdBase = 400;
+
+constexpr uint32_t kTypePropId = 3010;
+constexpr uint32_t kInFormatsPropId = 3011;
drmModeModeInfo Mode(uint16_t hdisplay, uint16_t vdisplay) {
return {0, hdisplay, 0, 0, 0, 0, vdisplay, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
@@ -44,8 +52,16 @@ drmModeModeInfo Mode(uint16_t hdisplay, uint16_t vdisplay) {
class ScreenManagerTest : public testing::Test {
public:
- ScreenManagerTest() {}
- ~ScreenManagerTest() override {}
+ struct PlaneState {
+ std::vector<uint32_t> formats;
+ };
+
+ struct CrtcState {
+ std::vector<PlaneState> planes;
+ };
+
+ ScreenManagerTest() = default;
+ ~ScreenManagerTest() override = default;
gfx::Rect GetPrimaryBounds() const {
return gfx::Rect(0, 0, kDefaultMode.hdisplay, kDefaultMode.vdisplay);
@@ -57,12 +73,102 @@ class ScreenManagerTest : public testing::Test {
kDefaultMode.vdisplay);
}
+ void InitializeDrmState(const std::vector<CrtcState>& crtc_states) {
+ std::vector<ui::MockDrmDevice::CrtcProperties> crtc_properties(
+ crtc_states.size());
+ std::map<uint32_t, std::string> crtc_property_names = {
+ {1000, "ACTIVE"},
+ {1001, "MODE_ID"},
+ };
+
+ std::vector<ui::MockDrmDevice::ConnectorProperties> connector_properties(2);
+ std::map<uint32_t, std::string> connector_property_names = {
+ {2000, "CRTC_ID"},
+ };
+ for (size_t i = 0; i < connector_properties.size(); ++i) {
+ connector_properties[i].id = kPrimaryConnector + i;
+ for (const auto& pair : connector_property_names) {
+ connector_properties[i].properties.push_back(
+ {/* .id = */ pair.first, /* .value = */ 0});
+ }
+ }
+
+ std::vector<ui::MockDrmDevice::PlaneProperties> plane_properties;
+ std::map<uint32_t, std::string> plane_property_names = {
+ // Add all required properties.
+ {3000, "CRTC_ID"},
+ {3001, "CRTC_X"},
+ {3002, "CRTC_Y"},
+ {3003, "CRTC_W"},
+ {3004, "CRTC_H"},
+ {3005, "FB_ID"},
+ {3006, "SRC_X"},
+ {3007, "SRC_Y"},
+ {3008, "SRC_W"},
+ {3009, "SRC_H"},
+ // Defines some optional properties we use for convenience.
+ {kTypePropId, "type"},
+ {kInFormatsPropId, "IN_FORMATS"},
+ };
+
+ uint32_t plane_id = kPlaneIdBase;
+ uint32_t property_id = kInFormatsBlobPropIdBase;
+
+ for (size_t crtc_idx = 0; crtc_idx < crtc_states.size(); ++crtc_idx) {
+ crtc_properties[crtc_idx].id = kPrimaryCrtc + crtc_idx;
+ for (const auto& pair : crtc_property_names) {
+ crtc_properties[crtc_idx].properties.push_back(
+ {/* .id = */ pair.first, /* .value = */ 0});
+ }
+
+ std::vector<ui::MockDrmDevice::PlaneProperties> crtc_plane_properties(
+ crtc_states[crtc_idx].planes.size());
+ for (size_t plane_idx = 0;
+ plane_idx < crtc_states[crtc_idx].planes.size(); ++plane_idx) {
+ crtc_plane_properties[plane_idx].id = plane_id++;
+ crtc_plane_properties[plane_idx].crtc_mask = 1 << crtc_idx;
+
+ for (const auto& pair : plane_property_names) {
+ uint64_t value = 0;
+ if (pair.first == kTypePropId) {
+ value = plane_idx == 0 ? DRM_PLANE_TYPE_PRIMARY
+ : DRM_PLANE_TYPE_OVERLAY;
+ } else if (pair.first == kInFormatsPropId) {
+ value = property_id++;
+ drm_->SetPropertyBlob(ui::MockDrmDevice::AllocateInFormatsBlob(
+ value, crtc_states[crtc_idx].planes[plane_idx].formats,
+ std::vector<drm_format_modifier>()));
+ }
+
+ crtc_plane_properties[plane_idx].properties.push_back(
+ {/* .id = */ pair.first, /* .value = */ value});
+ }
+ }
+
+ plane_properties.insert(plane_properties.end(),
+ crtc_plane_properties.begin(),
+ crtc_plane_properties.end());
+ }
+
+ std::map<uint32_t, std::string> property_names;
+ property_names.insert(crtc_property_names.begin(),
+ crtc_property_names.end());
+ property_names.insert(connector_property_names.begin(),
+ connector_property_names.end());
+ property_names.insert(plane_property_names.begin(),
+ plane_property_names.end());
+ drm_->InitializeState(crtc_properties, connector_properties,
+ plane_properties, property_names,
+ /* use_atomic= */ true);
+ }
+
void SetUp() override {
auto gbm = std::make_unique<ui::MockGbmDevice>();
drm_ = new ui::MockDrmDevice(std::move(gbm));
device_manager_ = std::make_unique<ui::DrmDeviceManager>(nullptr);
screen_manager_ = std::make_unique<ui::ScreenManager>();
}
+
void TearDown() override {
screen_manager_.reset();
drm_ = nullptr;
@@ -82,7 +188,7 @@ class ScreenManagerTest : public testing::Test {
modifiers.push_back(format_modifier);
auto buffer = drm_->gbm_device()->CreateBufferWithModifiers(
format, size, GBM_BO_USE_SCANOUT, modifiers);
- return DrmFramebuffer::AddFramebuffer(drm_, buffer.get(), modifiers);
+ return DrmFramebuffer::AddFramebuffer(drm_, buffer.get(), size, modifiers);
}
protected:
@@ -201,6 +307,24 @@ TEST_F(ScreenManagerTest, CheckForControllersInMirroredMode) {
}
TEST_F(ScreenManagerTest, CheckMirrorModeTransitions) {
+ std::vector<CrtcState> crtc_states = {
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
+ },
+ },
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
+ },
+ },
+ };
+ InitializeDrmState(crtc_states);
+
screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
screen_manager_->ConfigureDisplayController(
drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
@@ -352,6 +476,24 @@ TEST_F(ScreenManagerTest, ReuseFramebufferIfDisabledThenReEnabled) {
}
TEST_F(ScreenManagerTest, CheckMirrorModeAfterBeginReEnabled) {
+ std::vector<CrtcState> crtc_states = {
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
+ },
+ },
+ {
+ /* .planes = */
+ {
+ {/* .formats = */ {DRM_FORMAT_XRGB8888}},
+ {/* .formats = */ {DRM_FORMAT_XRGB8888, DRM_FORMAT_NV12}},
+ },
+ },
+ };
+ InitializeDrmState(crtc_states);
+
screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
screen_manager_->ConfigureDisplayController(
drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(),
diff --git a/chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.cc b/chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.cc
index 41f63b230e1..6858ff5053c 100644
--- a/chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.cc
@@ -9,6 +9,7 @@
#include "base/files/file_path.h"
#include "base/native_library.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
+#include "gpu/vulkan/vulkan_image.h"
#include "gpu/vulkan/vulkan_instance.h"
#include "gpu/vulkan/vulkan_posix_util.h"
#include "gpu/vulkan/vulkan_surface.h"
@@ -28,9 +29,9 @@ bool VulkanImplementationGbm::InitializeVulkanInstance(bool using_surface) {
gpu::GetVulkanFunctionPointers();
base::NativeLibraryLoadError native_library_load_error;
- vulkan_function_pointers->vulkan_loader_library_ = base::LoadNativeLibrary(
+ vulkan_function_pointers->vulkan_loader_library = base::LoadNativeLibrary(
base::FilePath("libvulkan.so.1"), &native_library_load_error);
- if (!vulkan_function_pointers->vulkan_loader_library_)
+ if (!vulkan_function_pointers->vulkan_loader_library)
return false;
std::vector<const char*> required_extensions = {
@@ -92,6 +93,12 @@ VulkanImplementationGbm::GetRequiredDeviceExtensions() {
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME};
}
+
+std::vector<const char*>
+VulkanImplementationGbm::GetOptionalDeviceExtensions() {
+ return {};
+}
+
VkFence VulkanImplementationGbm::CreateVkFenceForGpuFence(VkDevice vk_device) {
VkFenceCreateInfo fence_create_info = {};
fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
@@ -162,17 +169,14 @@ bool VulkanImplementationGbm::CanImportGpuMemoryBuffer(
return false;
}
-bool VulkanImplementationGbm::CreateImageFromGpuMemoryHandle(
- VkDevice vk_device,
+std::unique_ptr<gpu::VulkanImage>
+VulkanImplementationGbm::CreateImageFromGpuMemoryHandle(
+ gpu::VulkanDeviceQueue* device_queue,
gfx::GpuMemoryBufferHandle gmb_handle,
gfx::Size size,
- VkImage* vk_image,
- VkImageCreateInfo* vk_image_info,
- VkDeviceMemory* vk_device_memory,
- VkDeviceSize* mem_allocation_size,
- base::Optional<gpu::VulkanYCbCrInfo>* ycbcr_info) {
+ VkFormat vk_formae) {
NOTIMPLEMENTED();
- return false;
+ return nullptr;
}
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.h b/chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.h
index cbbbbcc5344..66bf3750705 100644
--- a/chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.h
+++ b/chromium/ui/ozone/platform/drm/gpu/vulkan_implementation_gbm.h
@@ -27,6 +27,7 @@ class VulkanImplementationGbm : public gpu::VulkanImplementation {
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
+ std::vector<const char*> GetOptionalDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
@@ -39,15 +40,11 @@ class VulkanImplementationGbm : public gpu::VulkanImplementation {
VkExternalMemoryHandleTypeFlagBits GetExternalImageHandleType() override;
bool CanImportGpuMemoryBuffer(
gfx::GpuMemoryBufferType memory_buffer_type) override;
- bool CreateImageFromGpuMemoryHandle(
- VkDevice vk_device,
+ std::unique_ptr<gpu::VulkanImage> CreateImageFromGpuMemoryHandle(
+ gpu::VulkanDeviceQueue* device_queue,
gfx::GpuMemoryBufferHandle gmb_handle,
gfx::Size size,
- VkImage* vk_image,
- VkImageCreateInfo* vk_image_info,
- VkDeviceMemory* vk_device_memory,
- VkDeviceSize* mem_allocation_size,
- base::Optional<gpu::VulkanYCbCrInfo>* ycbcr_info) override;
+ VkFormat vk_formae) override;
private:
gpu::VulkanInstance vulkan_instance_;
diff --git a/chromium/ui/ozone/platform/drm/host/drm_cursor.cc b/chromium/ui/ozone/platform/drm/host/drm_cursor.cc
index 8e420a59c34..afed5c26d24 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_cursor.cc
+++ b/chromium/ui/ozone/platform/drm/host/drm_cursor.cc
@@ -220,6 +220,7 @@ gfx::Rect DrmCursor::GetCursorConfinedBounds() {
void DrmCursor::InitializeOnEvdev() {
DCHECK(evdev_thread_checker_.CalledOnValidThread());
+ base::AutoLock lock(lock_);
proxy_->InitializeOnEvdevIfNecessary();
}
diff --git a/chromium/ui/ozone/platform/drm/host/drm_device_connector.cc b/chromium/ui/ozone/platform/drm/host/drm_device_connector.cc
index 47ee622e339..0b3cf4a8775 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_device_connector.cc
+++ b/chromium/ui/ozone/platform/drm/host/drm_device_connector.cc
@@ -41,11 +41,6 @@ void DrmDeviceConnector::OnGpuServiceLaunched(
scoped_refptr<base::SingleThreadTaskRunner> io_runner,
GpuHostBindInterfaceCallback binder,
GpuHostTerminateCallback terminate_callback) {
- // We can get into this state if a new instance of GpuProcessHost is created
- // before the old one is destroyed.
- if (host_drm_device_->IsConnected())
- host_drm_device_->OnGpuServiceLost();
-
// We need to preserve |binder| to let us bind interfaces later.
binder_callback_ = std::move(binder);
host_id_ = host_id;
diff --git a/chromium/ui/ozone/platform/drm/host/drm_display_host.cc b/chromium/ui/ozone/platform/drm/host/drm_display_host.cc
index a0bcdbcc06c..10f559bb623 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_display_host.cc
+++ b/chromium/ui/ozone/platform/drm/host/drm_display_host.cc
@@ -117,6 +117,10 @@ void DrmDisplayHost::SetGammaCorrection(
gamma_lut);
}
+void DrmDisplayHost::SetPrivacyScreen(bool enabled) {
+ sender_->GpuSetPrivacyScreen(snapshot_->display_id(), enabled);
+}
+
void DrmDisplayHost::OnGpuProcessLaunched() {}
void DrmDisplayHost::OnGpuThreadReady() {
diff --git a/chromium/ui/ozone/platform/drm/host/drm_display_host.h b/chromium/ui/ozone/platform/drm/host/drm_display_host.h
index 1311e66db3d..bca23f727b9 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_display_host.h
+++ b/chromium/ui/ozone/platform/drm/host/drm_display_host.h
@@ -40,6 +40,7 @@ class DrmDisplayHost : public GpuThreadObserver {
void SetGammaCorrection(
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut);
+ void SetPrivacyScreen(bool enabled);
// Called when the IPC from the GPU process arrives to answer the above
// commands.
diff --git a/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.cc b/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.cc
index 360f06cd6c6..ceb96616272 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.cc
+++ b/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.cc
@@ -15,12 +15,12 @@
#include "base/files/file_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/events/ozone/device/device_event.h"
#include "ui/events/ozone/device/device_manager.h"
-#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/host/drm_device_handle.h"
#include "ui/ozone/platform/drm/host/drm_display_host.h"
@@ -112,11 +112,9 @@ DrmDisplayHostManager::DrmDisplayHostManager(
GpuThreadAdapter* proxy,
DeviceManager* device_manager,
OzonePlatform::InitializedHostProperties* host_properties,
- DrmOverlayManager* overlay_manager,
InputControllerEvdev* input_controller)
: proxy_(proxy),
device_manager_(device_manager),
- overlay_manager_(overlay_manager),
input_controller_(input_controller),
primary_graphics_card_path_(GetPrimaryDisplayCardPath()) {
{
@@ -251,9 +249,9 @@ void DrmDisplayHostManager::ProcessEvent() {
switch (event.action_type) {
case DeviceEvent::ADD:
if (drm_devices_.find(event.path) == drm_devices_.end()) {
- base::PostTask(
+ base::ThreadPool::PostTask(
FROM_HERE,
- {base::ThreadPool(), base::MayBlock(),
+ {base::MayBlock(),
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
base::BindOnce(
&OpenDeviceAsync, event.path,
@@ -400,9 +398,6 @@ void DrmDisplayHostManager::GpuConfiguredDisplay(int64_t display_id,
DrmDisplayHost* display = GetDisplay(display_id);
if (display) {
display->OnDisplayConfigured(status);
-
- if (overlay_manager_)
- overlay_manager_->ResetCache();
} else {
LOG(ERROR) << "Couldn't find display with id=" << display_id;
}
diff --git a/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.h b/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.h
index a126bd4b5d6..1ded8afe89e 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.h
+++ b/chromium/ui/ozone/platform/drm/host/drm_display_host_manager.h
@@ -28,7 +28,6 @@ class DrmDeviceHandle;
class DrmDisplayHost;
class DrmDisplayHostManager;
class DrmNativeDisplayDelegate;
-class DrmOverlayManager;
class GpuThreadAdapter;
struct DisplaySnapshot_Params;
@@ -42,7 +41,6 @@ class DrmDisplayHostManager : public DeviceEventObserver, GpuThreadObserver {
GpuThreadAdapter* proxy,
DeviceManager* device_manager,
OzonePlatform::InitializedHostProperties* host_properties,
- DrmOverlayManager* overlay_manager,
InputControllerEvdev* input_controller);
~DrmDisplayHostManager() override;
@@ -102,8 +100,6 @@ class DrmDisplayHostManager : public DeviceEventObserver, GpuThreadObserver {
GpuThreadAdapter* const proxy_; // Not owned.
DeviceManager* const device_manager_; // Not owned.
- // TODO(crbug.com/936425): Remove after VizDisplayCompositor feature launches.
- DrmOverlayManager* const overlay_manager_; // Not owned.
InputControllerEvdev* const input_controller_; // Not owned.
DrmNativeDisplayDelegate* delegate_ = nullptr; // Not owned.
diff --git a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
index 5dcbf2072d4..3a435294dcd 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
+++ b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
@@ -14,11 +14,9 @@
#include "ui/base/ui_base_switches.h"
#include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
#include "ui/ozone/common/gpu/ozone_gpu_messages.h"
-#include "ui/ozone/platform/drm/common/drm_overlay_candidates.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/host/drm_cursor.h"
#include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
#include "ui/ozone/platform/drm/host/gpu_thread_observer.h"
namespace ui {
@@ -167,15 +165,23 @@ void DrmGpuPlatformSupportHost::OnChannelDestroyed(int host_id) {
void DrmGpuPlatformSupportHost::OnMessageReceived(const IPC::Message& message) {
DCHECK(ui_runner_);
- if (ui_runner_->BelongsToCurrentThread()) {
- if (OnMessageReceivedForDrmDisplayHostManager(message))
- return;
- OnMessageReceivedForDrmOverlayManager(message);
- } else {
+ if (!ui_runner_->BelongsToCurrentThread()) {
ui_runner_->PostTask(
FROM_HERE, base::BindOnce(&DrmGpuPlatformSupportHost::OnMessageReceived,
weak_ptr_, message));
+ return;
}
+
+ IPC_BEGIN_MESSAGE_MAP(DrmGpuPlatformSupportHost, message)
+ IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays,
+ OnUpdateNativeDisplays)
+ IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayConfigured, OnDisplayConfigured)
+ IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateReceived, OnHDCPStateReceived)
+ IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateUpdated, OnHDCPStateUpdated)
+ IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlTaken, OnTakeDisplayControl)
+ IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlRelinquished,
+ OnRelinquishDisplayControl)
+ IPC_END_MESSAGE_MAP()
}
bool DrmGpuPlatformSupportHost::Send(IPC::Message* message) {
@@ -213,25 +219,6 @@ void DrmGpuPlatformSupportHost::OnChannelEstablished() {
std::make_unique<CursorIPC>(send_runner_, send_callback_));
}
-bool DrmGpuPlatformSupportHost::OnMessageReceivedForDrmDisplayHostManager(
- const IPC::Message& message) {
- bool handled = true;
-
- IPC_BEGIN_MESSAGE_MAP(DrmGpuPlatformSupportHost, message)
- IPC_MESSAGE_HANDLER(OzoneHostMsg_UpdateNativeDisplays,
- OnUpdateNativeDisplays)
- IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayConfigured, OnDisplayConfigured)
- IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateReceived, OnHDCPStateReceived)
- IPC_MESSAGE_HANDLER(OzoneHostMsg_HDCPStateUpdated, OnHDCPStateUpdated)
- IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlTaken, OnTakeDisplayControl)
- IPC_MESSAGE_HANDLER(OzoneHostMsg_DisplayControlRelinquished,
- OnRelinquishDisplayControl)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
-
- return handled;
-}
-
void DrmGpuPlatformSupportHost::OnUpdateNativeDisplays(
const std::vector<DisplaySnapshot_Params>& params) {
display_manager_->GpuHasUpdatedNativeDisplays(params);
@@ -293,44 +280,6 @@ bool DrmGpuPlatformSupportHost::GpuRemoveGraphicsDevice(
return Send(new OzoneGpuMsg_RemoveGraphicsDevice(path));
}
-// Overlays
-void DrmGpuPlatformSupportHost::RegisterHandlerForDrmOverlayManager(
- DrmOverlayManagerHost* handler) {
- overlay_manager_ = handler;
-}
-
-void DrmGpuPlatformSupportHost::UnRegisterHandlerForDrmOverlayManager() {
- overlay_manager_ = nullptr;
-}
-
-bool DrmGpuPlatformSupportHost::OnMessageReceivedForDrmOverlayManager(
- const IPC::Message& message) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(DrmGpuPlatformSupportHost, message)
- IPC_MESSAGE_HANDLER(OzoneHostMsg_OverlayCapabilitiesReceived,
- OnOverlayResult)
- // TODO(rjk): insert the extra
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void DrmGpuPlatformSupportHost::OnOverlayResult(
- gfx::AcceleratedWidget widget,
- const std::vector<OverlayCheck_Params>& params,
- const std::vector<OverlayCheckReturn_Params>& param_returns) {
- auto candidates = CreateOverlaySurfaceCandidateListFrom(params);
- auto returns = CreateOverlayStatusListFrom(param_returns);
- overlay_manager_->GpuSentOverlayResult(widget, candidates, returns);
-}
-
-bool DrmGpuPlatformSupportHost::GpuCheckOverlayCapabilities(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& candidates) {
- auto params = CreateParamsFromOverlaySurfaceCandidate(candidates);
- return Send(new OzoneGpuMsg_CheckOverlayCapabilities(widget, params));
-}
-
// DrmDisplayHost
bool DrmGpuPlatformSupportHost::GpuConfigureNativeDisplay(
int64_t display_id,
@@ -372,6 +321,11 @@ bool DrmGpuPlatformSupportHost::GpuDestroyWindow(
return Send(new OzoneGpuMsg_DestroyWindow(widget));
}
+bool DrmGpuPlatformSupportHost::GpuSetPrivacyScreen(int64_t display_id,
+ bool enabled) {
+ return Send(new OzoneGpuMsg_SetPrivacyScreen(display_id, enabled));
+}
+
bool DrmGpuPlatformSupportHost::GpuCreateWindow(
gfx::AcceleratedWidget widget,
const gfx::Rect& initial_bounds) {
diff --git a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
index 4b07ff5ab37..0d319cc3070 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
+++ b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
@@ -24,7 +24,6 @@ namespace ui {
class DrmCursor;
class DrmDisplayHostMananger;
-class DrmOverlayManagerHost;
class GpuThreadObserver;
class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
@@ -73,17 +72,6 @@ class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
base::ScopedFD fd) override;
bool GpuRemoveGraphicsDevice(const base::FilePath& path) override;
- // Methods needed for DrmOverlayManagerHost.
- // Methods for DrmOverlayManagerHost.
- void RegisterHandlerForDrmOverlayManager(
- DrmOverlayManagerHost* handler) override;
- void UnRegisterHandlerForDrmOverlayManager() override;
-
- // Services needed by DrmOverlayManagerHost
- bool GpuCheckOverlayCapabilities(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& new_params) override;
-
// Services needed by DrmDisplayHost
bool GpuConfigureNativeDisplay(int64_t display_id,
const ui::DisplayMode_Params& display_mode,
@@ -97,6 +85,7 @@ class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
+ bool GpuSetPrivacyScreen(int64_t display_id, bool enabled) override;
// Services needed by DrmWindowHost
bool GpuDestroyWindow(gfx::AcceleratedWidget widget) override;
@@ -107,7 +96,6 @@ class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
private:
void OnChannelEstablished();
- bool OnMessageReceivedForDrmDisplayHostManager(const IPC::Message& message);
void OnUpdateNativeDisplays(
const std::vector<DisplaySnapshot_Params>& displays);
void OnDisplayConfigured(int64_t display_id, bool status);
@@ -118,11 +106,6 @@ class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
void OnTakeDisplayControl(bool status);
void OnRelinquishDisplayControl(bool status);
- bool OnMessageReceivedForDrmOverlayManager(const IPC::Message& message);
- void OnOverlayResult(gfx::AcceleratedWidget widget,
- const std::vector<OverlayCheck_Params>& params,
- const std::vector<OverlayCheckReturn_Params>& returns);
-
int host_id_ = -1;
bool channel_established_ = false;
@@ -131,7 +114,6 @@ class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
base::RepeatingCallback<void(IPC::Message*)> send_callback_;
DrmDisplayHostManager* display_manager_; // Not owned.
- DrmOverlayManagerHost* overlay_manager_; // Not owned.
DrmCursor* const cursor_; // Not owned.
base::ObserverList<GpuThreadObserver>::Unchecked gpu_thread_observers_;
diff --git a/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.cc b/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
index 54ecf769e5b..c5465582fb1 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
+++ b/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.cc
@@ -91,6 +91,12 @@ bool DrmNativeDisplayDelegate::SetGammaCorrection(
return true;
}
+void DrmNativeDisplayDelegate::SetPrivacyScreen(int64_t display_id,
+ bool enabled) {
+ DrmDisplayHost* display = display_manager_->GetDisplay(display_id);
+ display->SetPrivacyScreen(enabled);
+}
+
void DrmNativeDisplayDelegate::AddObserver(
display::NativeDisplayObserver* observer) {
observers_.AddObserver(observer);
diff --git a/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.h b/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.h
index ce322d3c10b..249e032e73a 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.h
+++ b/chromium/ui/ozone/platform/drm/host/drm_native_display_delegate.h
@@ -44,6 +44,7 @@ class DrmNativeDisplayDelegate : public display::NativeDisplayDelegate {
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
+ void SetPrivacyScreen(int64_t display_id, bool enabled) override;
void AddObserver(display::NativeDisplayObserver* observer) override;
void RemoveObserver(display::NativeDisplayObserver* observer) override;
display::FakeDisplayController* GetFakeDisplayController() override;
diff --git a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager_host.cc b/chromium/ui/ozone/platform/drm/host/drm_overlay_manager_host.cc
deleted file mode 100644
index b08f2c9bb39..00000000000
--- a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager_host.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
-
-#include <stddef.h>
-
-#include "base/trace_event/trace_event.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/ozone/platform/drm/host/drm_window_host.h"
-#include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
-
-namespace ui {
-
-DrmOverlayManagerHost::DrmOverlayManagerHost(
- GpuThreadAdapter* proxy,
- DrmWindowHostManager* window_manager)
- : proxy_(proxy), window_manager_(window_manager) {
- proxy_->RegisterHandlerForDrmOverlayManager(this);
-}
-
-DrmOverlayManagerHost::~DrmOverlayManagerHost() {
- proxy_->UnRegisterHandlerForDrmOverlayManager();
-}
-
-void DrmOverlayManagerHost::GpuSentOverlayResult(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& candidates,
- const OverlayStatusList& returns) {
- TRACE_EVENT_ASYNC_END0("hwoverlays",
- "DrmOverlayManagerHost::SendOverlayValidationRequest",
- this);
- UpdateCacheForOverlayCandidates(candidates, widget, returns);
-}
-
-void DrmOverlayManagerHost::SendOverlayValidationRequest(
- const OverlaySurfaceCandidateList& candidates,
- gfx::AcceleratedWidget widget) {
- if (!proxy_->IsConnected())
- return;
- TRACE_EVENT_ASYNC_BEGIN0(
- "hwoverlays", "DrmOverlayManagerHost::SendOverlayValidationRequest",
- this);
- proxy_->GpuCheckOverlayCapabilities(widget, candidates);
-}
-
-bool DrmOverlayManagerHost::CanHandleCandidate(
- const OverlaySurfaceCandidate& candidate,
- gfx::AcceleratedWidget widget) const {
- if (!DrmOverlayManager::CanHandleCandidate(candidate, widget))
- return false;
-
- if (candidate.plane_z_order != 0) {
- // It is possible that the cc rect we get actually falls off the edge of
- // the screen. Usually this is prevented via things like status bars
- // blocking overlaying or cc clipping it, but in case it wasn't properly
- // clipped (since GL will render this situation fine) just ignore it
- // here. This should be an extremely rare occurrence.
- DrmWindowHost* window = window_manager_->GetWindow(widget);
- if (!window->GetBounds().Contains(
- gfx::ToNearestRect(candidate.display_rect))) {
- return false;
- }
- }
-
- return true;
-}
-
-} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager_host.h b/chromium/ui/ozone/platform/drm/host/drm_overlay_manager_host.h
deleted file mode 100644
index afc354194ea..00000000000
--- a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager_host.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_HOST_H_
-#define UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_HOST_H_
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "base/macros.h"
-#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
-#include "ui/ozone/platform/drm/host/gpu_thread_adapter.h"
-#include "ui/ozone/public/overlay_candidates_ozone.h"
-
-namespace ui {
-class DrmWindowHostManager;
-class OverlaySurfaceCandidate;
-
-// This is an implementation of DrmOverlayManager where the driver is asked
-// about overlay capabilities via IPC. We have no way of querying abstract
-// capabilities, only if a particular configuration is supported or not.
-// Each time we we are asked if a particular configuration is supported, if we
-// have not seen that configuration before, it is IPCed to the GPU via
-// OzoneGpuMsg_CheckOverlayCapabilities, a test commit is then performed and
-// the result is returned in OzoneHostMsg_OverlayCapabilitiesReceived. Testing
-// is asynchronous, until the reply arrives that configuration will be failed.
-//
-// All widgets share a single cache of tested configurations stored in the
-// overlay manager.
-class DrmOverlayManagerHost : public DrmOverlayManager {
- public:
- DrmOverlayManagerHost(GpuThreadAdapter* proxy,
- DrmWindowHostManager* window_manager);
- ~DrmOverlayManagerHost() override;
-
- // Communication-free implementations of actions performed in response to
- // messages from the GPU thread.
- void GpuSentOverlayResult(gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& params,
- const OverlayStatusList& returns);
-
- private:
- // DrmOverlayManager:
- void SendOverlayValidationRequest(
- const OverlaySurfaceCandidateList& candidates,
- gfx::AcceleratedWidget widget) override;
- bool CanHandleCandidate(const OverlaySurfaceCandidate& candidate,
- gfx::AcceleratedWidget widget) const override;
-
- GpuThreadAdapter* const proxy_; // Not owned.
- DrmWindowHostManager* const window_manager_; // Not owned.
-
- DISALLOW_COPY_AND_ASSIGN(DrmOverlayManagerHost);
-};
-
-} // namespace ui
-
-#endif // UI_OZONE_PLATFORM_DRM_HOST_DRM_OVERLAY_MANAGER_HOST_H_
diff --git a/chromium/ui/ozone/platform/drm/host/drm_window_host.cc b/chromium/ui/ozone/platform/drm/host/drm_window_host.cc
index 735b2e41bf3..e1b181ce095 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_window_host.cc
+++ b/chromium/ui/ozone/platform/drm/host/drm_window_host.cc
@@ -11,7 +11,6 @@
#include "ui/events/ozone/evdev/event_factory_evdev.h"
#include "ui/events/ozone/events_ozone.h"
#include "ui/events/platform/platform_event_source.h"
-#include "ui/ozone/platform/drm/common/drm_overlay_manager.h"
#include "ui/ozone/platform/drm/host/drm_cursor.h"
#include "ui/ozone/platform/drm/host/drm_display_host.h"
#include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
@@ -26,15 +25,13 @@ DrmWindowHost::DrmWindowHost(PlatformWindowDelegate* delegate,
EventFactoryEvdev* event_factory,
DrmCursor* cursor,
DrmWindowHostManager* window_manager,
- DrmDisplayHostManager* display_manager,
- DrmOverlayManager* overlay_manager)
+ DrmDisplayHostManager* display_manager)
: delegate_(delegate),
sender_(sender),
event_factory_(event_factory),
cursor_(cursor),
window_manager_(window_manager),
display_manager_(display_manager),
- overlay_manager_(overlay_manager),
bounds_(bounds),
widget_(window_manager->NextAcceleratedWidget()) {
window_manager_->AddWindow(widget_, this);
@@ -244,9 +241,6 @@ void DrmWindowHost::SendBoundsChange() {
// window bounds when the window size shrinks.
cursor_->CommitBoundsChange(widget_, bounds_, GetCursorConfinedBounds());
sender_->GpuWindowBoundsChanged(widget_, bounds_);
-
- if (overlay_manager_)
- overlay_manager_->ResetCache();
}
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/host/drm_window_host.h b/chromium/ui/ozone/platform/drm/host/drm_window_host.h
index 3b70802e052..99bf436fd61 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_window_host.h
+++ b/chromium/ui/ozone/platform/drm/host/drm_window_host.h
@@ -20,9 +20,8 @@
namespace ui {
-class DrmDisplayHostManager;
class DrmCursor;
-class DrmOverlayManager;
+class DrmDisplayHostManager;
class DrmWindowHostManager;
class EventFactoryEvdev;
class GpuThreadAdapter;
@@ -47,8 +46,7 @@ class DrmWindowHost : public PlatformWindow,
EventFactoryEvdev* event_factory,
DrmCursor* cursor,
DrmWindowHostManager* window_manager,
- DrmDisplayHostManager* display_manager,
- DrmOverlayManager* overlay_manager);
+ DrmDisplayHostManager* display_manager);
~DrmWindowHost() override;
void Initialize();
@@ -107,8 +105,6 @@ class DrmWindowHost : public PlatformWindow,
DrmCursor* const cursor_; // Not owned.
DrmWindowHostManager* const window_manager_; // Not owned.
DrmDisplayHostManager* const display_manager_; // Not owned.
- // TODO(crbug.com/936425): Remove after VizDisplayCompositor feature launches.
- DrmOverlayManager* const overlay_manager_; // Not owned.
gfx::Rect bounds_;
const gfx::AcceleratedWidget widget_;
diff --git a/chromium/ui/ozone/platform/drm/host/gpu_thread_adapter.h b/chromium/ui/ozone/platform/drm/host/gpu_thread_adapter.h
index 074b8260abf..5035672702e 100644
--- a/chromium/ui/ozone/platform/drm/host/gpu_thread_adapter.h
+++ b/chromium/ui/ozone/platform/drm/host/gpu_thread_adapter.h
@@ -8,14 +8,13 @@
#include "base/file_descriptor_posix.h"
#include "ui/display/types/display_constants.h"
#include "ui/display/types/gamma_ramp_rgb_entry.h"
+#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
-#include "ui/ozone/public/overlay_candidates_ozone.h"
namespace ui {
class DrmDisplayHostManager;
-class DrmOverlayManagerHost;
class GpuThreadObserver;
// Provides the services that the various host components need
@@ -43,16 +42,6 @@ class GpuThreadAdapter {
base::ScopedFD fd) = 0;
virtual bool GpuRemoveGraphicsDevice(const base::FilePath& path) = 0;
- // Methods for DrmOverlayManagerHost.
- virtual void RegisterHandlerForDrmOverlayManager(
- DrmOverlayManagerHost* handler) = 0;
- virtual void UnRegisterHandlerForDrmOverlayManager() = 0;
-
- // Services needed by DrmOverlayManagerHost
- virtual bool GpuCheckOverlayCapabilities(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& overlays) = 0;
-
// Services needed by DrmDisplayHost
virtual bool GpuConfigureNativeDisplay(
int64_t display_id,
@@ -68,6 +57,7 @@ class GpuThreadAdapter {
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) = 0;
+ virtual bool GpuSetPrivacyScreen(int64_t display_id, bool enabled) = 0;
// Services needed by DrmWindowHost
virtual bool GpuDestroyWindow(gfx::AcceleratedWidget widget) = 0;
diff --git a/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc
index c0b9083601c..1486038b808 100644
--- a/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc
+++ b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc
@@ -6,58 +6,64 @@
#include <utility>
+#include "base/threading/thread_task_runner_handle.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/ozone/public/gpu_platform_support_host.h"
namespace ui {
+namespace {
+
+void DestroyRemoteOnEvdevThread(
+ mojo::AssociatedRemote<ui::ozone::mojom::DeviceCursor> remote) {
+ // Don't do anything. |remote| will automatically get destroyed.
+}
+
+} // namespace
+
// We assume that this is invoked only on the Mus/UI thread.
HostCursorProxy::HostCursorProxy(
mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> main_cursor,
mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> evdev_cursor)
: main_cursor_(std::move(main_cursor)),
- evdev_cursor_(std::move(evdev_cursor)),
+ evdev_cursor_pending_remote_(std::move(evdev_cursor)),
ui_thread_ref_(base::PlatformThread::CurrentRef()) {}
-HostCursorProxy::~HostCursorProxy() {}
+HostCursorProxy::~HostCursorProxy() {
+ if (evdev_task_runner_) {
+ evdev_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(DestroyRemoteOnEvdevThread, std::move(evdev_cursor_)));
+ }
+}
void HostCursorProxy::CursorSet(gfx::AcceleratedWidget widget,
const std::vector<SkBitmap>& bitmaps,
const gfx::Point& location,
int frame_delay_ms) {
- InitializeOnEvdevIfNecessary();
if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) {
main_cursor_->SetCursor(widget, bitmaps, location, frame_delay_ms);
} else {
+ InitializeOnEvdevIfNecessary();
evdev_cursor_->SetCursor(widget, bitmaps, location, frame_delay_ms);
}
}
void HostCursorProxy::Move(gfx::AcceleratedWidget widget,
const gfx::Point& location) {
- InitializeOnEvdevIfNecessary();
if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) {
main_cursor_->MoveCursor(widget, location);
} else {
+ InitializeOnEvdevIfNecessary();
evdev_cursor_->MoveCursor(widget, location);
}
}
-// Evdev runs this method on starting. But if a HostCursorProxy is created long
-// after Evdev has started (e.g. if the Viz process crashes (and the
-// |HostCursorProxy| self-destructs and then a new |HostCursorProxy| is built
-// when the GpuThread/DrmThread pair are once again running), we need to run it
-// on cursor motions.
void HostCursorProxy::InitializeOnEvdevIfNecessary() {
- // TODO(rjkroege): Rebind on Viz process restart.
- if (evdev_bound_)
+ if (evdev_cursor_.is_bound())
return;
-
- if (ui_thread_ref_ != base::PlatformThread::CurrentRef()) {
- // Rebind the mojo pipe on the current thread. We expect this to be the
- // thread running EVDEV.
- evdev_cursor_.Bind(evdev_cursor_.Unbind());
- }
+ evdev_cursor_.Bind(std::move(evdev_cursor_pending_remote_));
+ evdev_task_runner_ = base::ThreadTaskRunnerHandle::Get();
}
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h
index 22c16f47081..05e6ffa05d6 100644
--- a/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h
+++ b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h
@@ -5,6 +5,7 @@
#ifndef UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_
#define UI_OZONE_PLATFORM_DRM_HOST_HOST_CURSOR_PROXY_H_
+#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "ui/gfx/native_widget_types.h"
@@ -35,12 +36,16 @@ class HostCursorProxy : public DrmCursorProxy {
void Move(gfx::AcceleratedWidget window, const gfx::Point& point) override;
void InitializeOnEvdevIfNecessary() override;
- // Mojo implementation of the DrmCursorProxy.
+ // Accessed from UI thread only.
mojo::AssociatedRemote<ui::ozone::mojom::DeviceCursor> main_cursor_;
+
+ // Accessed from evdev thread only.
mojo::AssociatedRemote<ui::ozone::mojom::DeviceCursor> evdev_cursor_;
+ mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor>
+ evdev_cursor_pending_remote_;
base::PlatformThreadRef ui_thread_ref_;
- bool evdev_bound_ = false;
+ scoped_refptr<base::SingleThreadTaskRunner> evdev_task_runner_;
DISALLOW_COPY_AND_ASSIGN(HostCursorProxy);
};
diff --git a/chromium/ui/ozone/platform/drm/host/host_drm_device.cc b/chromium/ui/ozone/platform/drm/host/host_drm_device.cc
index aaf88ca43bc..922b895b423 100644
--- a/chromium/ui/ozone/platform/drm/host/host_drm_device.cc
+++ b/chromium/ui/ozone/platform/drm/host/host_drm_device.cc
@@ -19,7 +19,6 @@
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/host/drm_device_connector.h"
#include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
#include "ui/ozone/platform/drm/host/host_cursor_proxy.h"
namespace ui {
@@ -51,10 +50,8 @@ void HostDrmDevice::OnDrmServiceStarted() {
// DRM thread is broken.
}
-void HostDrmDevice::ProvideManagers(DrmDisplayHostManager* display_manager,
- DrmOverlayManagerHost* overlay_manager) {
+void HostDrmDevice::SetDisplayManager(DrmDisplayHostManager* display_manager) {
display_manager_ = display_manager;
- overlay_manager_ = overlay_manager;
}
void HostDrmDevice::AddGpuThreadObserver(GpuThreadObserver* observer) {
@@ -119,35 +116,6 @@ bool HostDrmDevice::GpuWindowBoundsChanged(gfx::AcceleratedWidget widget,
return true;
}
-// Services needed for DrmOverlayManagerHost.
-void HostDrmDevice::RegisterHandlerForDrmOverlayManager(
- DrmOverlayManagerHost* handler) {
- // TODO(rjkroege): Permit overlay manager to run in Viz when the display
- // compositor runs in Viz.
- DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
- overlay_manager_ = handler;
-}
-
-void HostDrmDevice::UnRegisterHandlerForDrmOverlayManager() {
- DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
- overlay_manager_ = nullptr;
-}
-
-bool HostDrmDevice::GpuCheckOverlayCapabilities(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& overlays) {
- DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
- if (!IsConnected())
- return false;
-
- auto callback =
- base::BindOnce(&HostDrmDevice::GpuCheckOverlayCapabilitiesCallback, this);
-
- drm_device_->CheckOverlayCapabilities(widget, overlays, std::move(callback));
-
- return true;
-}
-
bool HostDrmDevice::GpuRefreshNativeDisplays() {
DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
if (!IsConnected())
@@ -289,12 +257,13 @@ bool HostDrmDevice::GpuSetGammaCorrection(
return true;
}
-void HostDrmDevice::GpuCheckOverlayCapabilitiesCallback(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& overlays,
- const OverlayStatusList& returns) const {
+bool HostDrmDevice::GpuSetPrivacyScreen(int64_t display_id, bool enabled) {
DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
- overlay_manager_->GpuSentOverlayResult(widget, overlays, returns);
+ if (!IsConnected())
+ return false;
+
+ drm_device_->SetPrivacyScreen(display_id, enabled);
+ return true;
}
void HostDrmDevice::GpuConfigureNativeDisplayCallback(int64_t display_id,
@@ -364,6 +333,11 @@ void HostDrmDevice::OnGpuServiceLaunchedOnUIThread(
mojo::PendingRemote<ui::ozone::mojom::DrmDevice> drm_device) {
DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
+ // We can get into this state if a new instance of GpuProcessHost is created
+ // before the old one is destroyed.
+ if (IsConnected())
+ OnGpuServiceLost();
+
drm_device_.Bind(std::move(drm_device));
// Create two DeviceCursor connections: one for the UI thread and one for the
diff --git a/chromium/ui/ozone/platform/drm/host/host_drm_device.h b/chromium/ui/ozone/platform/drm/host/host_drm_device.h
index 7c8c636f586..c88343d152a 100644
--- a/chromium/ui/ozone/platform/drm/host/host_drm_device.h
+++ b/chromium/ui/ozone/platform/drm/host/host_drm_device.h
@@ -28,7 +28,6 @@ class DisplaySnapshot;
namespace ui {
class DrmDisplayHostManager;
-class DrmOverlayManagerHost;
class GpuThreadObserver;
class DrmDeviceConnector;
class HostCursorProxy;
@@ -40,8 +39,7 @@ class HostDrmDevice : public base::RefCountedThreadSafe<HostDrmDevice>,
public:
explicit HostDrmDevice(DrmCursor* cursor);
- void ProvideManagers(DrmDisplayHostManager* display_manager,
- DrmOverlayManagerHost* overlay_manager);
+ void SetDisplayManager(DrmDisplayHostManager* display_manager);
void OnGpuServiceLaunchedOnIOThread(
mojo::PendingRemote<ui::ozone::mojom::DrmDevice> drm_device,
@@ -69,14 +67,6 @@ class HostDrmDevice : public base::RefCountedThreadSafe<HostDrmDevice>,
base::ScopedFD fd) override;
bool GpuRemoveGraphicsDevice(const base::FilePath& path) override;
- // Services needed for DrmOverlayManagerHost.
- void RegisterHandlerForDrmOverlayManager(
- DrmOverlayManagerHost* handler) override;
- void UnRegisterHandlerForDrmOverlayManager() override;
- bool GpuCheckOverlayCapabilities(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& new_params) override;
-
// Services needed by DrmDisplayHost
bool GpuConfigureNativeDisplay(int64_t display_id,
const ui::DisplayMode_Params& display_mode,
@@ -90,6 +80,7 @@ class HostDrmDevice : public base::RefCountedThreadSafe<HostDrmDevice>,
int64_t display_id,
const std::vector<display::GammaRampRGBEntry>& degamma_lut,
const std::vector<display::GammaRampRGBEntry>& gamma_lut) override;
+ bool GpuSetPrivacyScreen(int64_t display_id, bool enabled) override;
// Services needed by DrmWindowHost
bool GpuDestroyWindow(gfx::AcceleratedWidget widget) override;
@@ -109,11 +100,6 @@ class HostDrmDevice : public base::RefCountedThreadSafe<HostDrmDevice>,
// TODO(rjkroege): Get rid of the need for this method in a subsequent CL.
void PollForSingleThreadReady(int previous_delay);
- void GpuCheckOverlayCapabilitiesCallback(
- gfx::AcceleratedWidget widget,
- const OverlaySurfaceCandidateList& overlays,
- const OverlayStatusList& returns) const;
-
void GpuConfigureNativeDisplayCallback(int64_t display_id,
bool success) const;
@@ -135,7 +121,6 @@ class HostDrmDevice : public base::RefCountedThreadSafe<HostDrmDevice>,
mojo::Remote<ui::ozone::mojom::DrmDevice> drm_device_on_io_thread_;
DrmDisplayHostManager* display_manager_; // Not owned.
- DrmOverlayManagerHost* overlay_manager_; // Not owned.
DrmCursor* const cursor_; // Not owned.
std::unique_ptr<HostCursorProxy> cursor_proxy_;
diff --git a/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc b/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc
index 70a1a61a8ea..16d379a0e89 100644
--- a/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc
+++ b/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -25,6 +25,7 @@
#include "ui/events/ozone/evdev/event_factory_evdev.h"
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/gfx/linux/client_native_pixmap_dmabuf.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/gpu/drm_device_generator.h"
#include "ui/ozone/platform/drm/gpu/drm_device_manager.h"
@@ -40,7 +41,6 @@
#include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
#include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
#include "ui/ozone/platform/drm/host/drm_native_display_delegate.h"
-#include "ui/ozone/platform/drm/host/drm_overlay_manager_host.h"
#include "ui/ozone/platform/drm/host/drm_window_host.h"
#include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
#include "ui/ozone/platform/drm/host/host_drm_device.h"
@@ -160,8 +160,7 @@ class OzonePlatformGbm : public OzonePlatform {
auto platform_window = std::make_unique<DrmWindowHost>(
delegate, properties.bounds, adapter, event_factory_ozone_.get(),
- cursor_.get(), window_manager_.get(), display_manager_.get(),
- overlay_manager_.get());
+ cursor_.get(), window_manager_.get(), display_manager_.get());
platform_window->Initialize();
return std::move(platform_window);
}
@@ -170,7 +169,8 @@ class OzonePlatformGbm : public OzonePlatform {
return std::make_unique<DrmNativeDisplayDelegate>(display_manager_.get());
}
std::unique_ptr<InputMethod> CreateInputMethod(
- internal::InputMethodDelegate* delegate) override {
+ internal::InputMethodDelegate* delegate,
+ gfx::AcceleratedWidget) override {
#if defined(OS_CHROMEOS)
return std::make_unique<InputMethodChromeOS>(delegate);
#else
@@ -227,23 +227,13 @@ class OzonePlatformGbm : public OzonePlatform {
adapter = gpu_platform_support_host_.get();
}
- std::unique_ptr<DrmOverlayManagerHost> overlay_manager_host;
- if (!args.viz_display_compositor) {
- overlay_manager_host = std::make_unique<DrmOverlayManagerHost>(
- adapter, window_manager_.get());
- }
-
display_manager_ = std::make_unique<DrmDisplayHostManager>(
adapter, device_manager_.get(), &host_properties_,
- overlay_manager_host.get(), event_factory_ozone_->input_controller());
+ event_factory_ozone_->input_controller());
cursor_factory_ozone_ = std::make_unique<BitmapCursorFactoryOzone>();
- if (using_mojo_) {
- host_drm_device_->ProvideManagers(display_manager_.get(),
- overlay_manager_host.get());
- }
-
- overlay_manager_ = std::move(overlay_manager_host);
+ if (using_mojo_)
+ host_drm_device_->SetDisplayManager(display_manager_.get());
}
void InitializeGPU(const InitParams& args) override {
@@ -268,10 +258,8 @@ class OzonePlatformGbm : public OzonePlatform {
drm_thread_proxy_->BindThreadIntoMessagingProxy(itmp);
}
- if (args.viz_display_compositor) {
- overlay_manager_ =
- std::make_unique<DrmOverlayManagerGpu>(drm_thread_proxy_.get());
- }
+ overlay_manager_ =
+ std::make_unique<DrmOverlayManagerGpu>(drm_thread_proxy_.get());
// If gpu is in a separate process, rest of the initialization happens after
// entering the sandbox.
@@ -338,6 +326,7 @@ class OzonePlatformGbm : public OzonePlatform {
std::unique_ptr<GbmSurfaceFactory> surface_factory_;
scoped_refptr<IPC::MessageFilter> gpu_message_filter_;
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_;
+ std::unique_ptr<DrmOverlayManager> overlay_manager_;
// TODO(rjkroege,sadrul): Provide a more elegant solution for this issue when
// running in single process mode.
@@ -351,9 +340,9 @@ class OzonePlatformGbm : public OzonePlatform {
// TODO(rjkroege): Remove gpu_platform_support_host_ once ozone/drm with mojo
// has reached the stable channel.
// A raw pointer to either |gpu_platform_support_host_| or |host_drm_device_|
- // is passed to |display_manager_| and |overlay_manager_| in IntializeUI.
- // To avoid a use after free, the following two members should be declared
- // before the two managers, so that they're deleted after them.
+ // is passed to |display_manager_| in InitializeUI(). To avoid a use after
+ // free, the following two members should be declared before the two managers,
+ // so that they're deleted after them.
std::unique_ptr<DrmGpuPlatformSupportHost> gpu_platform_support_host_;
// Objects in the host process.
@@ -370,7 +359,6 @@ class OzonePlatformGbm : public OzonePlatform {
std::unique_ptr<DrmCursor> cursor_;
std::unique_ptr<EventFactoryEvdev> event_factory_ozone_;
std::unique_ptr<DrmDisplayHostManager> display_manager_;
- std::unique_ptr<DrmOverlayManager> overlay_manager_;
InitializedHostProperties host_properties_;
base::WeakPtrFactory<OzonePlatformGbm> weak_factory_{this};
diff --git a/chromium/ui/ozone/platform/headless/headless_surface_factory.cc b/chromium/ui/ozone/platform/headless/headless_surface_factory.cc
index 2829df06710..fc1f019133f 100644
--- a/chromium/ui/ozone/platform/headless/headless_surface_factory.cc
+++ b/chromium/ui/ozone/platform/headless/headless_surface_factory.cc
@@ -12,6 +12,7 @@
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "build/build_config.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -75,7 +76,7 @@ class FileSurface : public SurfaceOzoneCanvas {
surface_ = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(
viewport_size.width(), viewport_size.height()));
}
- sk_sp<SkSurface> GetSurface() override { return surface_; }
+ SkCanvas* GetCanvas() override { return surface_->getCanvas(); }
void PresentCanvas(const gfx::Rect& damage) override {
if (base_path_.empty())
return;
@@ -85,10 +86,10 @@ class FileSurface : public SurfaceOzoneCanvas {
// TODO(dnicoara) Use SkImage instead to potentially avoid a copy.
// See crbug.com/361605 for details.
if (surface_->getCanvas()->readPixels(bitmap, 0, 0)) {
- base::PostTask(FROM_HERE,
- {base::ThreadPool(), base::MayBlock(),
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
- base::BindOnce(&WriteDataToFile, base_path_, bitmap));
+ base::ThreadPool::PostTask(
+ FROM_HERE,
+ {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ base::BindOnce(&WriteDataToFile, base_path_, bitmap));
}
}
std::unique_ptr<gfx::VSyncProvider> CreateVSyncProvider() override {
@@ -122,10 +123,10 @@ class FileGLSurface : public GLSurfaceEglReadback {
if (!bitmap.writePixels(pixmap))
return false;
- base::PostTask(FROM_HERE,
- {base::ThreadPool(), base::MayBlock(),
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
- base::BindOnce(&WriteDataToFile, location_, bitmap));
+ base::ThreadPool::PostTask(
+ FROM_HERE,
+ {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ base::BindOnce(&WriteDataToFile, location_, bitmap));
return true;
}
@@ -191,7 +192,9 @@ class GLOzoneEGLHeadless : public GLOzoneEGL {
protected:
// GLOzoneEGL:
- intptr_t GetNativeDisplay() override { return EGL_DEFAULT_DISPLAY; }
+ gl::EGLDisplayPlatform GetNativeDisplay() override {
+ return gl::EGLDisplayPlatform(EGL_DEFAULT_DISPLAY);
+ }
bool LoadGLES2Bindings(gl::GLImplementation implementation) override {
return LoadDefaultEGLGLES2Bindings(implementation);
@@ -232,8 +235,9 @@ GLOzone* HeadlessSurfaceFactory::GetGLOzone(
}
std::unique_ptr<SurfaceOzoneCanvas>
-HeadlessSurfaceFactory::CreateCanvasForWidget(gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) {
+HeadlessSurfaceFactory::CreateCanvasForWidget(
+ gfx::AcceleratedWidget widget,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
return std::make_unique<FileSurface>(GetPathForWidget(base_path_, widget));
}
@@ -242,7 +246,8 @@ scoped_refptr<gfx::NativePixmap> HeadlessSurfaceFactory::CreateNativePixmap(
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) {
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size) {
return new TestPixmap(format);
}
diff --git a/chromium/ui/ozone/platform/headless/headless_surface_factory.h b/chromium/ui/ozone/platform/headless/headless_surface_factory.h
index 8270d643e78..abde7d4d8ab 100644
--- a/chromium/ui/ozone/platform/headless/headless_surface_factory.h
+++ b/chromium/ui/ozone/platform/headless/headless_surface_factory.h
@@ -25,13 +25,14 @@ class HeadlessSurfaceFactory : public SurfaceFactoryOzone {
GLOzone* GetGLOzone(gl::GLImplementation implementation) override;
std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) override;
+ scoped_refptr<base::SequencedTaskRunner> task_runner) override;
scoped_refptr<gfx::NativePixmap> CreateNativePixmap(
gfx::AcceleratedWidget widget,
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) override;
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size = base::nullopt) override;
private:
void CheckBasePath() const;
diff --git a/chromium/ui/ozone/platform/headless/ozone_platform_headless.cc b/chromium/ui/ozone/platform/headless/ozone_platform_headless.cc
index c84e960f5f5..9d356f701e3 100644
--- a/chromium/ui/ozone/platform/headless/ozone_platform_headless.cc
+++ b/chromium/ui/ozone/platform/headless/ozone_platform_headless.cc
@@ -89,9 +89,10 @@ class OzonePlatformHeadless : public OzonePlatform {
return std::make_unique<HeadlessScreen>();
}
std::unique_ptr<InputMethod> CreateInputMethod(
- internal::InputMethodDelegate* delegate) override {
+ internal::InputMethodDelegate* delegate,
+ gfx::AcceleratedWidget widget) override {
#if defined(OS_FUCHSIA)
- return std::make_unique<InputMethodFuchsia>(delegate);
+ return std::make_unique<InputMethodFuchsia>(delegate, widget);
#else
return std::make_unique<InputMethodMinimal>(delegate);
#endif
diff --git a/chromium/ui/ozone/platform/scenic/BUILD.gn b/chromium/ui/ozone/platform/scenic/BUILD.gn
index 472e835d73a..f927e8dda1c 100644
--- a/chromium/ui/ozone/platform/scenic/BUILD.gn
+++ b/chromium/ui/ozone/platform/scenic/BUILD.gn
@@ -46,13 +46,13 @@ source_set("scenic") {
"//mojo/public/cpp/system",
"//services/service_manager/public/cpp",
"//skia",
- "//third_party/fuchsia-sdk/sdk:fuchsia-images",
- "//third_party/fuchsia-sdk/sdk:fuchsia-mem",
- "//third_party/fuchsia-sdk/sdk:fuchsia-sysmem",
- "//third_party/fuchsia-sdk/sdk:fuchsia-ui-gfx",
- "//third_party/fuchsia-sdk/sdk:fuchsia-ui-scenic",
- "//third_party/fuchsia-sdk/sdk:scenic_cpp",
- "//third_party/fuchsia-sdk/sdk:sys_cpp",
+ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.images",
+ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem",
+ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.sysmem",
+ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.gfx",
+ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.scenic",
+ "//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
+ "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
"//ui/base",
"//ui/base/ime/fuchsia",
"//ui/display/fake",
diff --git a/chromium/ui/ozone/platform/scenic/ozone_platform_scenic.cc b/chromium/ui/ozone/platform/scenic/ozone_platform_scenic.cc
index 535751d99bb..d05d7fbe1fa 100644
--- a/chromium/ui/ozone/platform/scenic/ozone_platform_scenic.cc
+++ b/chromium/ui/ozone/platform/scenic/ozone_platform_scenic.cc
@@ -20,6 +20,7 @@
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
#include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/platform/scenic/scenic_gpu_host.h"
#include "ui/ozone/platform/scenic/scenic_gpu_service.h"
@@ -118,8 +119,9 @@ class OzonePlatformScenic
}
std::unique_ptr<InputMethod> CreateInputMethod(
- internal::InputMethodDelegate* delegate) override {
- return std::make_unique<InputMethodFuchsia>(delegate);
+ internal::InputMethodDelegate* delegate,
+ gfx::AcceleratedWidget widget) override {
+ return std::make_unique<InputMethodFuchsia>(delegate, widget);
}
void InitializeUI(const InitParams& params) override {
diff --git a/chromium/ui/ozone/platform/scenic/scenic_gpu_host.cc b/chromium/ui/ozone/platform/scenic/scenic_gpu_host.cc
index 348f085dd95..e596541637f 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_gpu_host.cc
+++ b/chromium/ui/ozone/platform/scenic/scenic_gpu_host.cc
@@ -13,7 +13,6 @@
#include "base/threading/thread_task_runner_handle.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/system/message_pipe.h"
-#include "mojo/public/cpp/system/platform_handle.h"
#include "ui/ozone/platform/scenic/scenic_window.h"
#include "ui/ozone/platform/scenic/scenic_window_manager.h"
#include "ui/ozone/public/mojom/scenic_gpu_host.mojom.h"
@@ -53,15 +52,14 @@ ScenicGpuHost::CreateHostProcessSelfRemote() {
void ScenicGpuHost::AttachSurfaceToWindow(
int32_t window_id,
- mojo::ScopedHandle surface_view_holder_token_mojo) {
+ mojo::PlatformHandle surface_view_holder_token_mojo) {
DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_);
ScenicWindow* scenic_window = scenic_window_manager_->GetWindow(window_id);
if (!scenic_window)
return;
fuchsia::ui::views::ViewHolderToken surface_view_holder_token;
- surface_view_holder_token.value = zx::eventpair(
- mojo::UnwrapPlatformHandle(std::move(surface_view_holder_token_mojo))
- .TakeHandle());
+ surface_view_holder_token.value =
+ zx::eventpair(surface_view_holder_token_mojo.TakeHandle());
scenic_window->AttachSurfaceView(std::move(surface_view_holder_token));
}
diff --git a/chromium/ui/ozone/platform/scenic/scenic_gpu_host.h b/chromium/ui/ozone/platform/scenic/scenic_gpu_host.h
index b83f175da4e..25d073ba0fe 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_gpu_host.h
+++ b/chromium/ui/ozone/platform/scenic/scenic_gpu_host.h
@@ -42,7 +42,7 @@ class ScenicGpuHost : public mojom::ScenicGpuHost,
// mojom::ScenicGpuHost:
void AttachSurfaceToWindow(
int32_t window_id,
- mojo::ScopedHandle surface_view_holder_token_mojo) override;
+ mojo::PlatformHandle surface_view_holder_token_mojo) override;
// GpuPlatformSupportHost:
void OnGpuProcessLaunched(
diff --git a/chromium/ui/ozone/platform/scenic/scenic_surface.cc b/chromium/ui/ozone/platform/scenic/scenic_surface.cc
index 2b744f2bc79..2d75a091190 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_surface.cc
+++ b/chromium/ui/ozone/platform/scenic/scenic_surface.cc
@@ -8,7 +8,6 @@
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <lib/zx/eventpair.h>
-#include "mojo/public/cpp/system/platform_handle.h"
#include "ui/ozone/platform/scenic/scenic_gpu_host.h"
#include "ui/ozone/platform/scenic/scenic_surface_factory.h"
@@ -53,7 +52,7 @@ void ScenicSurface::SetTextureToImage(const scenic::Image& image) {
material_.SetTexture(image);
}
-mojo::ScopedHandle ScenicSurface::CreateView() {
+mojo::PlatformHandle ScenicSurface::CreateView() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// Scenic will associate the View and ViewHolder regardless of which it
@@ -68,8 +67,7 @@ mojo::ScopedHandle ScenicSurface::CreateView() {
/*requested_presentation_time=*/0,
/*requested_prediction_span=*/0,
[](fuchsia::scenic::scheduling::FuturePresentationTimes info) {});
- return mojo::WrapPlatformHandle(
- mojo::PlatformHandle(std::move(tokens.view_holder_token.value)));
+ return mojo::PlatformHandle(std::move(tokens.view_holder_token.value));
}
} // namespace ui
diff --git a/chromium/ui/ozone/platform/scenic/scenic_surface.h b/chromium/ui/ozone/platform/scenic/scenic_surface.h
index 4a731383594..d9b730ae611 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_surface.h
+++ b/chromium/ui/ozone/platform/scenic/scenic_surface.h
@@ -11,7 +11,7 @@
#include "base/macros.h"
#include "base/threading/thread_checker.h"
-#include "mojo/public/cpp/system/handle.h"
+#include "mojo/public/cpp/platform/platform_handle.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/public/platform_window_surface.h"
@@ -43,7 +43,7 @@ class ScenicSurface : public ui::PlatformWindowSurface {
// Creates a View for this surface, and returns a ViewHolderToken handle
// that can be used to attach it into a scene graph.
- mojo::ScopedHandle CreateView();
+ mojo::PlatformHandle CreateView();
void AssertBelongsToCurrentThread() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
diff --git a/chromium/ui/ozone/platform/scenic/scenic_surface_factory.cc b/chromium/ui/ozone/platform/scenic/scenic_surface_factory.cc
index 8cdaf028b7c..14053720363 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_surface_factory.cc
+++ b/chromium/ui/ozone/platform/scenic/scenic_surface_factory.cc
@@ -52,8 +52,8 @@ class GLOzoneEGLScenic : public GLOzoneEGL {
base::MakeRefCounted<gl::PbufferGLSurfaceEGL>(size));
}
- EGLNativeDisplayType GetNativeDisplay() override {
- return EGL_DEFAULT_DISPLAY;
+ gl::EGLDisplayPlatform GetNativeDisplay() override {
+ return gl::EGLDisplayPlatform(EGL_DEFAULT_DISPLAY);
}
protected:
@@ -111,7 +111,7 @@ GLOzone* ScenicSurfaceFactory::GetGLOzone(gl::GLImplementation implementation) {
std::unique_ptr<PlatformWindowSurface>
ScenicSurfaceFactory::CreatePlatformWindowSurface(
gfx::AcceleratedWidget window) {
- DCHECK(gpu_host_);
+ DCHECK_NE(window, gfx::kNullAcceleratedWidget);
auto surface =
std::make_unique<ScenicSurface>(this, window, CreateScenicSession());
main_thread_task_runner_->PostTask(
@@ -123,7 +123,7 @@ ScenicSurfaceFactory::CreatePlatformWindowSurface(
std::unique_ptr<SurfaceOzoneCanvas> ScenicSurfaceFactory::CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) {
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
ScenicSurface* surface = GetSurface(widget);
return std::make_unique<ScenicWindowCanvas>(surface);
}
@@ -133,7 +133,9 @@ scoped_refptr<gfx::NativePixmap> ScenicSurfaceFactory::CreateNativePixmap(
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) {
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size) {
+ DCHECK(!framebuffer_size || framebuffer_size == size);
auto collection = sysmem_buffer_manager_.CreateCollection(vk_device, size,
format, usage, 1);
if (!collection)
@@ -158,10 +160,6 @@ std::unique_ptr<gpu::VulkanImplementation>
ScenicSurfaceFactory::CreateVulkanImplementation(
bool allow_protected_memory,
bool enforce_protected_memory) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (!gpu_host_)
- LOG(FATAL) << "Vulkan implementation requires InitializeForGPU";
-
return std::make_unique<ui::VulkanImplementationScenic>(
this, &sysmem_buffer_manager_, allow_protected_memory,
enforce_protected_memory);
@@ -233,7 +231,7 @@ void ScenicSurfaceFactory::CreateScenicSessionOnMainThread(
void ScenicSurfaceFactory::AttachSurfaceToWindow(
gfx::AcceleratedWidget window,
- mojo::ScopedHandle surface_view_holder_token_mojo) {
+ mojo::PlatformHandle surface_view_holder_token_mojo) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
gpu_host_->AttachSurfaceToWindow(window,
std::move(surface_view_holder_token_mojo));
diff --git a/chromium/ui/ozone/platform/scenic/scenic_surface_factory.h b/chromium/ui/ozone/platform/scenic/scenic_surface_factory.h
index 2214f0ad174..a14be294357 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_surface_factory.h
+++ b/chromium/ui/ozone/platform/scenic/scenic_surface_factory.h
@@ -41,13 +41,14 @@ class ScenicSurfaceFactory : public SurfaceFactoryOzone {
gfx::AcceleratedWidget widget) override;
std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) override;
+ scoped_refptr<base::SequencedTaskRunner> task_runner) override;
scoped_refptr<gfx::NativePixmap> CreateNativePixmap(
gfx::AcceleratedWidget widget,
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) override;
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size = base::nullopt) override;
void CreateNativePixmapAsync(gfx::AcceleratedWidget widget,
VkDevice vk_device,
gfx::Size size,
@@ -88,8 +89,9 @@ class ScenicSurfaceFactory : public SurfaceFactoryOzone {
fidl::InterfaceHandle<fuchsia::ui::scenic::SessionListener> listener);
// Links a surface to its parent window in the host process.
- void AttachSurfaceToWindow(gfx::AcceleratedWidget window,
- mojo::ScopedHandle surface_view_holder_token_mojo);
+ void AttachSurfaceToWindow(
+ gfx::AcceleratedWidget window,
+ mojo::PlatformHandle surface_view_holder_token_mojo);
base::flat_map<gfx::AcceleratedWidget, ScenicSurface*> surface_map_
GUARDED_BY(surface_lock_);
diff --git a/chromium/ui/ozone/platform/scenic/scenic_window.cc b/chromium/ui/ozone/platform/scenic/scenic_window.cc
index 965ee62ff60..0de00de69aa 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_window.cc
+++ b/chromium/ui/ozone/platform/scenic/scenic_window.cc
@@ -37,7 +37,8 @@ ScenicWindow::ScenicWindow(ScenicWindowManager* window_manager,
"chromium window"),
node_(&scenic_session_),
input_node_(&scenic_session_),
- render_node_(&scenic_session_) {
+ render_node_(&scenic_session_),
+ background_node_(&scenic_session_) {
scenic_session_.set_error_handler(
fit::bind_member(this, &ScenicWindow::OnScenicError));
scenic_session_.set_event_handler(
@@ -51,9 +52,28 @@ ScenicWindow::ScenicWindow(ScenicWindowManager* window_manager,
// Add input shape.
node_.AddChild(input_node_);
- // Add rendering subtree.
+ // Add rendering subtree, rooted at Z=-2 to make room for background layers in
+ // the Z-order (lesser values are higher in the visual ordering).
+ constexpr float kRenderNodeZPosition = -2.;
+ constexpr float kBackgroundNodeZPosition = kRenderNodeZPosition + 1.;
+ render_node_.SetTranslation(0., 0., kRenderNodeZPosition);
node_.AddChild(render_node_);
+ // Initialize a black background to be just behind |render_node_|.
+ scenic::Material background_color(&scenic_session_);
+ background_color.SetColor(0, 0, 0, 255); // RGBA (0,0,0,255) = opaque black.
+ background_node_.SetMaterial(background_color);
+ scenic::Rectangle background_shape(&scenic_session_, 1., 1.);
+ background_node_.SetShape(background_shape);
+ background_node_.SetTranslation(0., 0., kBackgroundNodeZPosition);
+ node_.AddChild(background_node_);
+
+ // Render the background immediately.
+ scenic_session_.Present2(
+ /*requested_presentation_time=*/0,
+ /*requested_prediction_span=*/0,
+ [](fuchsia::scenic::scheduling::FuturePresentationTimes info) {});
+
delegate_->OnAcceleratedWidgetAvailable(window_id_);
}
@@ -223,8 +243,12 @@ void ScenicWindow::UpdateSize() {
render_node_.SetScale(size_dips_.width(), size_dips_.height(), 1.f);
// Resize input node to cover the whole surface.
- input_node_.SetShape(scenic::Rectangle(&scenic_session_, size_dips_.width(),
- size_dips_.height()));
+ scenic::Rectangle window_rect(&scenic_session_, size_dips_.width(),
+ size_dips_.height());
+ input_node_.SetShape(window_rect);
+
+ // Resize the input and background nodes to cover the whole surface.
+ background_node_.SetShape(window_rect);
// This is necessary when using vulkan because ImagePipes are presented
// separately and we need to make sure our sizes change is committed.
@@ -245,14 +269,30 @@ void ScenicWindow::OnScenicEvents(
std::vector<fuchsia::ui::scenic::Event> events) {
for (const auto& event : events) {
if (event.is_gfx()) {
- if (event.gfx().is_metrics()) {
- if (event.gfx().metrics().node_id != node_.id())
- continue;
- OnViewMetrics(event.gfx().metrics().metrics);
- } else if (event.gfx().is_view_properties_changed()) {
- if (event.gfx().view_properties_changed().view_id != view_.id())
- continue;
- OnViewProperties(event.gfx().view_properties_changed().properties);
+ switch (event.gfx().Which()) {
+ case fuchsia::ui::gfx::Event::kMetrics: {
+ if (event.gfx().metrics().node_id != node_.id())
+ continue;
+ OnViewMetrics(event.gfx().metrics().metrics);
+ break;
+ }
+ case fuchsia::ui::gfx::Event::kViewPropertiesChanged: {
+ DCHECK(event.gfx().view_properties_changed().view_id == view_.id());
+ OnViewProperties(event.gfx().view_properties_changed().properties);
+ break;
+ }
+ case fuchsia::ui::gfx::Event::kViewAttachedToScene: {
+ DCHECK(event.gfx().view_attached_to_scene().view_id == view_.id());
+ OnViewAttachedChanged(true);
+ break;
+ }
+ case fuchsia::ui::gfx::Event::kViewDetachedFromScene: {
+ DCHECK(event.gfx().view_detached_from_scene().view_id == view_.id());
+ OnViewAttachedChanged(false);
+ break;
+ }
+ default:
+ break;
}
} else if (event.is_input()) {
OnInputEvent(event.input());
@@ -283,6 +323,12 @@ void ScenicWindow::OnViewProperties(
UpdateSize();
}
+void ScenicWindow::OnViewAttachedChanged(bool is_view_attached) {
+ delegate_->OnWindowStateChanged(is_view_attached
+ ? PlatformWindowState::kNormal
+ : PlatformWindowState::kMinimized);
+}
+
void ScenicWindow::OnInputEvent(const fuchsia::ui::input::InputEvent& event) {
if (event.is_focus()) {
delegate_->OnActivationChanged(event.focus().focused);
diff --git a/chromium/ui/ozone/platform/scenic/scenic_window.h b/chromium/ui/ozone/platform/scenic/scenic_window.h
index 7a32a91d31e..d70d88b218f 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_window.h
+++ b/chromium/ui/ozone/platform/scenic/scenic_window.h
@@ -10,6 +10,7 @@
#include <lib/ui/scenic/cpp/resources.h>
#include <lib/ui/scenic/cpp/session.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
+#include <memory>
#include <string>
#include <vector>
@@ -86,6 +87,7 @@ class COMPONENT_EXPORT(OZONE) ScenicWindow
// Called from OnScenicEvents() to handle view properties and metrics changes.
void OnViewProperties(const fuchsia::ui::gfx::ViewProperties& properties);
void OnViewMetrics(const fuchsia::ui::gfx::Metrics& metrics);
+ void OnViewAttachedChanged(bool is_view_attached);
// Called from OnScenicEvents() to handle input events.
void OnInputEvent(const fuchsia::ui::input::InputEvent& event);
@@ -116,6 +118,11 @@ class COMPONENT_EXPORT(OZONE) ScenicWindow
// Node in |scenic_session_| for rendering (hit testing disabled).
scenic::EntityNode render_node_;
+
+ // Node in |scenic_session_| for rendering a solid color, placed just behind
+ // |render_node_| in the Z order.
+ scenic::ShapeNode background_node_;
+
std::unique_ptr<scenic::ViewHolder> surface_view_holder_;
// The ratio used for translating device-independent coordinates to absolute
diff --git a/chromium/ui/ozone/platform/scenic/scenic_window_canvas.cc b/chromium/ui/ozone/platform/scenic/scenic_window_canvas.cc
index 9d5367176b1..14ef76692c8 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_window_canvas.cc
+++ b/chromium/ui/ozone/platform/scenic/scenic_window_canvas.cc
@@ -83,7 +83,7 @@ void ScenicWindowCanvas::ResizeCanvas(const gfx::Size& viewport_size) {
}
}
-sk_sp<SkSurface> ScenicWindowCanvas::GetSurface() {
+SkCanvas* ScenicWindowCanvas::GetCanvas() {
if (viewport_size_.IsEmpty() || frames_[current_frame_].is_empty())
return nullptr;
@@ -108,7 +108,7 @@ sk_sp<SkSurface> ScenicWindowCanvas::GetSurface() {
}
}
- return frames_[current_frame_].surface;
+ return frames_[current_frame_].surface->getCanvas();
}
void ScenicWindowCanvas::PresentCanvas(const gfx::Rect& damage) {
diff --git a/chromium/ui/ozone/platform/scenic/scenic_window_canvas.h b/chromium/ui/ozone/platform/scenic/scenic_window_canvas.h
index 237e621a105..858711723a2 100644
--- a/chromium/ui/ozone/platform/scenic/scenic_window_canvas.h
+++ b/chromium/ui/ozone/platform/scenic/scenic_window_canvas.h
@@ -17,6 +17,8 @@
#include "ui/ozone/platform/scenic/scenic_surface_factory.h"
#include "ui/ozone/public/surface_ozone_canvas.h"
+class SkSurface;
+
namespace scenic {
class Session;
} // namespace scenic
@@ -36,7 +38,7 @@ class ScenicWindowCanvas : public SurfaceOzoneCanvas {
// SurfaceOzoneCanvas implementation.
void ResizeCanvas(const gfx::Size& viewport_size) override;
- sk_sp<SkSurface> GetSurface() override;
+ SkCanvas* GetCanvas() override;
void PresentCanvas(const gfx::Rect& damage) override;
std::unique_ptr<gfx::VSyncProvider> CreateVSyncProvider() override;
diff --git a/chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.cc b/chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.cc
index 191d274a9cf..599c0cb345e 100644
--- a/chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.cc
+++ b/chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.cc
@@ -18,6 +18,7 @@
#include "gpu/ipc/common/vulkan_ycbcr_info.h"
#include "gpu/vulkan/fuchsia/vulkan_fuchsia_ext.h"
#include "gpu/vulkan/vulkan_function_pointers.h"
+#include "gpu/vulkan/vulkan_image.h"
#include "gpu/vulkan/vulkan_instance.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "gpu/vulkan/vulkan_util.h"
@@ -57,7 +58,7 @@ bool VulkanImplementationScenic::InitializeVulkanInstance(bool using_surface) {
gpu::VulkanFunctionPointers* vulkan_function_pointers =
gpu::GetVulkanFunctionPointers();
- vulkan_function_pointers->vulkan_loader_library_ = handle;
+ vulkan_function_pointers->vulkan_loader_library = handle;
std::vector<const char*> required_extensions = {
VK_KHR_SURFACE_EXTENSION_NAME,
VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME,
@@ -118,9 +119,6 @@ bool VulkanImplementationScenic::GetPhysicalDevicePresentationSupport(
VkPhysicalDevice physical_device,
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) {
- // TODO(spang): vkGetPhysicalDeviceMagmaPresentationSupportKHR returns false
- // here. Use it once it is fixed.
- NOTIMPLEMENTED();
return true;
}
@@ -140,6 +138,11 @@ VulkanImplementationScenic::GetRequiredDeviceExtensions() {
};
}
+std::vector<const char*>
+VulkanImplementationScenic::GetOptionalDeviceExtensions() {
+ return {};
+}
+
VkFence VulkanImplementationScenic::CreateVkFenceForGpuFence(
VkDevice vk_device) {
NOTIMPLEMENTED();
@@ -230,33 +233,52 @@ bool VulkanImplementationScenic::CanImportGpuMemoryBuffer(
return memory_buffer_type == gfx::NATIVE_PIXMAP;
}
-bool VulkanImplementationScenic::CreateImageFromGpuMemoryHandle(
- VkDevice vk_device,
+std::unique_ptr<gpu::VulkanImage>
+VulkanImplementationScenic::CreateImageFromGpuMemoryHandle(
+ gpu::VulkanDeviceQueue* device_queue,
gfx::GpuMemoryBufferHandle gmb_handle,
gfx::Size size,
- VkImage* vk_image,
- VkImageCreateInfo* vk_image_info,
- VkDeviceMemory* vk_device_memory,
- VkDeviceSize* mem_allocation_size,
- base::Optional<gpu::VulkanYCbCrInfo>* ycbcr_info) {
+ VkFormat vk_format) {
if (gmb_handle.type != gfx::NATIVE_PIXMAP)
- return false;
+ return nullptr;
if (!gmb_handle.native_pixmap_handle.buffer_collection_id) {
DLOG(ERROR) << "NativePixmapHandle.buffer_collection_id is not set.";
- return false;
+ return nullptr;
}
auto collection = sysmem_buffer_manager_->GetCollectionById(
gmb_handle.native_pixmap_handle.buffer_collection_id.value());
if (!collection) {
- DLOG(ERROR) << "Tried to use an unknown buffer collection ID";
- return false;
+ DLOG(ERROR) << "Tried to use an unknown buffer collection ID.";
+ return nullptr;
+ }
+ VkImage vk_image = VK_NULL_HANDLE;
+ VkImageCreateInfo vk_image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
+ VkDeviceMemory vk_device_memory = VK_NULL_HANDLE;
+ VkDeviceSize vk_device_size = 0;
+ base::Optional<gpu::VulkanYCbCrInfo> ycbcr_info;
+ if (!collection->CreateVkImage(gmb_handle.native_pixmap_handle.buffer_index,
+ device_queue->GetVulkanDevice(), size,
+ &vk_image, &vk_image_info, &vk_device_memory,
+ &vk_device_size, &ycbcr_info)) {
+ DLOG(ERROR) << "CreateVkImage failed.";
+ return nullptr;
+ }
+
+ auto image = gpu::VulkanImage::Create(
+ device_queue, vk_image, vk_device_memory, size, vk_image_info.format,
+ vk_image_info.tiling, vk_device_size, 0 /* memory_type_index */,
+ ycbcr_info);
+
+ if (image->format() != vk_format) {
+ DLOG(ERROR) << "Unexpected format " << vk_format << " vs "
+ << image->format();
+ image->Destroy();
+ return nullptr;
}
- return collection->CreateVkImage(
- gmb_handle.native_pixmap_handle.buffer_index, vk_device, size, vk_image,
- vk_image_info, vk_device_memory, mem_allocation_size, ycbcr_info);
+ return image;
}
class SysmemBufferCollectionImpl : public gpu::SysmemBufferCollection {
diff --git a/chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.h b/chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.h
index 8b077b836a6..6b1a1afa1f1 100644
--- a/chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.h
+++ b/chromium/ui/ozone/platform/scenic/vulkan_implementation_scenic.h
@@ -35,6 +35,7 @@ class VulkanImplementationScenic : public gpu::VulkanImplementation {
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
+ std::vector<const char*> GetOptionalDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
@@ -47,15 +48,11 @@ class VulkanImplementationScenic : public gpu::VulkanImplementation {
VkExternalMemoryHandleTypeFlagBits GetExternalImageHandleType() override;
bool CanImportGpuMemoryBuffer(
gfx::GpuMemoryBufferType memory_buffer_type) override;
- bool CreateImageFromGpuMemoryHandle(
- VkDevice vk_device,
+ std::unique_ptr<gpu::VulkanImage> CreateImageFromGpuMemoryHandle(
+ gpu::VulkanDeviceQueue* device_queue,
gfx::GpuMemoryBufferHandle gmb_handle,
gfx::Size size,
- VkImage* vk_image,
- VkImageCreateInfo* vk_image_info,
- VkDeviceMemory* vk_device_memory,
- VkDeviceSize* mem_allocation_size,
- base::Optional<gpu::VulkanYCbCrInfo>* ycbcr_info) override;
+ VkFormat vk_format) override;
std::unique_ptr<gpu::SysmemBufferCollection> RegisterSysmemBufferCollection(
VkDevice device,
gfx::SysmemBufferCollectionId id,
diff --git a/chromium/ui/ozone/platform/wayland/BUILD.gn b/chromium/ui/ozone/platform/wayland/BUILD.gn
index 37e7ffb5d83..cb2257c898b 100644
--- a/chromium/ui/ozone/platform/wayland/BUILD.gn
+++ b/chromium/ui/ozone/platform/wayland/BUILD.gn
@@ -4,6 +4,7 @@
visibility = [ "//ui/ozone/*" ]
+import("//build/config/linux/gtk/gtk.gni")
import("//build/config/linux/pkg_config.gni")
import("//testing/libfuzzer/fuzzer_test.gni")
import("//ui/ozone/platform/wayland/wayland.gni")
@@ -22,6 +23,8 @@ source_set("wayland") {
"common/wayland_util.h",
"gpu/drm_render_node_path_finder.cc",
"gpu/drm_render_node_path_finder.h",
+ "gpu/gl_surface_egl_readback_wayland.cc",
+ "gpu/gl_surface_egl_readback_wayland.h",
"gpu/gl_surface_wayland.cc",
"gpu/gl_surface_wayland.h",
"gpu/wayland_buffer_manager_gpu.cc",
@@ -45,6 +48,8 @@ source_set("wayland") {
"host/internal/wayland_data_offer_base.h",
"host/internal/wayland_data_source_base.cc",
"host/internal/wayland_data_source_base.h",
+ "host/shell_object_factory.cc",
+ "host/shell_object_factory.h",
"host/shell_popup_wrapper.cc",
"host/shell_popup_wrapper.h",
"host/shell_surface_wrapper.cc",
@@ -83,16 +88,23 @@ source_set("wayland") {
"host/wayland_output_manager.h",
"host/wayland_pointer.cc",
"host/wayland_pointer.h",
+ "host/wayland_popup.cc",
+ "host/wayland_popup.h",
"host/wayland_screen.cc",
"host/wayland_screen.h",
"host/wayland_shm.cc",
"host/wayland_shm.h",
"host/wayland_shm_buffer.cc",
"host/wayland_shm_buffer.h",
+ "host/wayland_subsurface.cc",
+ "host/wayland_subsurface.h",
+ "host/wayland_surface.cc",
+ "host/wayland_surface.h",
"host/wayland_touch.cc",
"host/wayland_touch.h",
"host/wayland_window.cc",
"host/wayland_window.h",
+ "host/wayland_window_factory.cc",
"host/wayland_window_manager.cc",
"host/wayland_window_manager.h",
"host/wayland_window_observer.cc",
@@ -141,9 +153,9 @@ source_set("wayland") {
"//ui/gfx",
"//ui/gfx:memory_buffer",
"//ui/gfx/geometry",
+ "//ui/gfx/linux:drm",
"//ui/ozone:ozone_base",
"//ui/ozone/common",
- "//ui/ozone/common/linux:drm",
"//ui/ozone/public/mojom/wayland:wayland_mojom",
"//ui/platform_window",
"//ui/platform_window/platform_window_handler",
@@ -153,6 +165,17 @@ source_set("wayland") {
deps += [ "//ui/base/ime/linux" ]
}
+ if (use_gtk) {
+ sources += [
+ "host/gtk_ui_delegate_wayland.cc",
+ "host/gtk_ui_delegate_wayland.h",
+ ]
+ deps += [
+ "//build/config/linux/gtk",
+ "//ui/gtk:gtk_ui_delegate",
+ ]
+ }
+
defines = [ "OZONE_IMPLEMENTATION" ]
if (use_wayland_gbm) {
@@ -169,10 +192,14 @@ source_set("wayland") {
deps += [
"//third_party/minigbm",
"//ui/gfx:memory_buffer",
- "//ui/ozone/common/linux:gbm",
+ "//ui/gfx/linux:gbm",
]
}
+ if (use_bundled_weston) {
+ data_deps = [ "//third_party/weston" ]
+ }
+
configs += [
":wayland-egl",
"//third_party/khronos:khronos_headers",
@@ -292,10 +319,11 @@ source_set("wayland_unittests") {
"//ui/base:buildflags",
"//ui/base/ime/linux",
"//ui/events/ozone/layout",
+ "//ui/gfx/linux:drm",
+ "//ui/gfx/linux:gbm",
+ "//ui/gfx/linux:test_support",
"//ui/ozone:platform",
"//ui/ozone:test_support",
- "//ui/ozone/common/linux:drm",
- "//ui/ozone/common/linux:gbm",
"//ui/platform_window/platform_window_handler",
]
@@ -312,9 +340,7 @@ source_set("wayland_unittests") {
fuzzer_test("wayland_buffer_fuzzer") {
defines = [ "WL_HIDE_DEPRECATED" ]
- sources = [
- "fuzzer/wayland_buffer_fuzzer.cc",
- ]
+ sources = [ "fuzzer/wayland_buffer_fuzzer.cc" ]
deps = [
":test_support",
":wayland",
diff --git a/chromium/ui/ozone/platform/wayland/DEPS b/chromium/ui/ozone/platform/wayland/DEPS
index 60eec9ee675..d61519af80c 100644
--- a/chromium/ui/ozone/platform/wayland/DEPS
+++ b/chromium/ui/ozone/platform/wayland/DEPS
@@ -2,10 +2,11 @@ include_rules = [
"+ui/base/buildflags.h", # Doesn't bring in all of ui/base.
"+ui/base/hit_test.h", # UI hit test doesn't bring in all of ui/base.
"+ui/base/ui_base_features.h",
+ "+ui/gtk/gtk_ui_delegate.h",
"+mojo/public",
"+ui/base/clipboard/clipboard_constants.h",
"+ui/base/dragdrop/drag_drop_types.h",
- "+ui/base/dragdrop/file_info.h",
+ "+ui/base/dragdrop/file_info/file_info.h",
"+ui/base/dragdrop/os_exchange_data.h",
"+ui/base/dragdrop/os_exchange_data_provider_aura.h",
]
diff --git a/chromium/ui/ozone/platform/wayland/common/wayland_util.cc b/chromium/ui/ozone/platform/wayland/common/wayland_util.cc
index 0201f689e90..14593b1c614 100644
--- a/chromium/ui/ozone/platform/wayland/common/wayland_util.cc
+++ b/chromium/ui/ozone/platform/wayland/common/wayland_util.cc
@@ -109,7 +109,7 @@ uint32_t IdentifyDirection(const ui::WaylandConnection& connection,
bool DrawBitmap(const SkBitmap& bitmap, ui::WaylandShmBuffer* out_buffer) {
DCHECK(out_buffer);
DCHECK(out_buffer->GetMemory());
- DCHECK(out_buffer->size() == gfx::Size(bitmap.width(), bitmap.height()));
+ DCHECK_EQ(out_buffer->size(), gfx::Size(bitmap.width(), bitmap.height()));
auto* mapped_memory = out_buffer->GetMemory();
auto size = out_buffer->size();
@@ -141,4 +141,23 @@ void ReadDataFromFD(base::ScopedFD fd, std::vector<uint8_t>* contents) {
contents->insert(contents->end(), buffer, buffer + length);
}
+gfx::Rect TranslateBoundsToParentCoordinates(const gfx::Rect& child_bounds,
+ const gfx::Rect& parent_bounds) {
+ return gfx::Rect(
+ (child_bounds.origin() - parent_bounds.origin().OffsetFromOrigin()),
+ child_bounds.size());
+}
+
+gfx::Rect TranslateBoundsToTopLevelCoordinates(const gfx::Rect& child_bounds,
+ const gfx::Rect& parent_bounds) {
+ return gfx::Rect(
+ (child_bounds.origin() + parent_bounds.origin().OffsetFromOrigin()),
+ child_bounds.size());
+}
+
+bool IsMenuType(ui::PlatformWindowType type) {
+ return type == ui::PlatformWindowType::kMenu ||
+ type == ui::PlatformWindowType::kPopup;
+}
+
} // namespace wl
diff --git a/chromium/ui/ozone/platform/wayland/common/wayland_util.h b/chromium/ui/ozone/platform/wayland/common/wayland_util.h
index 368f3d9a942..3db36965402 100644
--- a/chromium/ui/ozone/platform/wayland/common/wayland_util.h
+++ b/chromium/ui/ozone/platform/wayland/common/wayland_util.h
@@ -13,7 +13,9 @@
#include "base/containers/flat_map.h"
#include "base/files/scoped_file.h"
#include "base/macros.h"
+#include "ui/gfx/geometry/rect.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
+#include "ui/platform_window/platform_window_init_properties.h"
class SkBitmap;
@@ -50,6 +52,16 @@ bool DrawBitmap(const SkBitmap& bitmap, ui::WaylandShmBuffer* out_buffer);
// Helper function to read data from a file.
void ReadDataFromFD(base::ScopedFD fd, std::vector<uint8_t>* contents);
+// Translates bounds relative to top level window to specified parent.
+gfx::Rect TranslateBoundsToParentCoordinates(const gfx::Rect& child_bounds,
+ const gfx::Rect& parent_bounds);
+// Translates bounds relative to parent window to top level window.
+gfx::Rect TranslateBoundsToTopLevelCoordinates(const gfx::Rect& child_bounds,
+ const gfx::Rect& parent_bounds);
+
+// Says if the type is kPopup or kMenu.
+bool IsMenuType(ui::PlatformWindowType type);
+
} // namespace wl
#endif // UI_OZONE_PLATFORM_WAYLAND_COMMON_WAYLAND_UTIL_H_
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc b/chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
index f36ec10cac1..c78ca1d02aa 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
@@ -18,9 +18,10 @@
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/buffer_usage_util.h"
#include "ui/gfx/geometry/size_conversions.h"
+#include "ui/gfx/linux/drm_util_linux.h"
+#include "ui/gfx/linux/gbm_device.h"
+#include "ui/gfx/linux/gbm_util.h"
#include "ui/gfx/native_pixmap_handle.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
-#include "ui/ozone/common/linux/gbm_device.h"
#include "ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h"
#include "ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h"
#include "ui/ozone/public/overlay_plane.h"
@@ -29,11 +30,12 @@
namespace ui {
GbmPixmapWayland::GbmPixmapWayland(WaylandBufferManagerGpu* buffer_manager)
- : buffer_manager_(buffer_manager) {}
+ : buffer_manager_(buffer_manager),
+ buffer_id_(buffer_manager->AllocateBufferID()) {}
GbmPixmapWayland::~GbmPixmapWayland() {
if (gbm_bo_)
- buffer_manager_->DestroyBuffer(widget_, GetUniqueId());
+ buffer_manager_->DestroyBuffer(widget_, buffer_id_);
}
bool GbmPixmapWayland::InitializeBuffer(gfx::Size size,
@@ -44,35 +46,14 @@ bool GbmPixmapWayland::InitializeBuffer(gfx::Size size,
if (!buffer_manager_->gbm_device())
return false;
- uint32_t flags = 0;
- switch (usage) {
- case gfx::BufferUsage::GPU_READ:
- flags = GBM_BO_USE_LINEAR;
- break;
- case gfx::BufferUsage::SCANOUT:
- flags = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT;
- break;
- case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE:
- flags = GBM_BO_USE_LINEAR | GBM_BO_USE_WRITE | GBM_BO_USE_SCANOUT;
- break;
- case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE:
- flags = GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT;
- break;
- case gfx::BufferUsage::SCANOUT_VDA_WRITE:
- flags = GBM_BO_USE_SCANOUT;
- break;
- case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
- flags = GBM_BO_USE_LINEAR;
- break;
- default:
- NOTREACHED() << "Not supported buffer format";
- break;
- }
-
const uint32_t fourcc_format = GetFourCCFormatFromBufferFormat(format);
- auto modifiers = buffer_manager_->GetModifiersForBufferFormat(format);
+ auto gbm_usage = ui::BufferUsageToGbmFlags(usage);
+ std::vector<uint64_t> modifiers;
+ if (!(gbm_usage & GBM_BO_USE_LINEAR))
+ modifiers = buffer_manager_->GetModifiersForBufferFormat(format);
+
gbm_bo_ = buffer_manager_->gbm_device()->CreateBufferWithModifiers(
- fourcc_format, size, flags, modifiers);
+ fourcc_format, size, gbm_usage, modifiers);
if (!gbm_bo_) {
LOG(ERROR) << "Cannot create bo with format= "
<< gfx::BufferFormatToString(format) << " and usage "
@@ -153,7 +134,8 @@ bool GbmPixmapWayland::ScheduleOverlayPlane(
surfaceless->QueueOverlayPlane(
OverlayPlane(this, std::move(gpu_fence), plane_z_order, plane_transform,
- display_bounds, crop_rect, enable_blend));
+ display_bounds, crop_rect, enable_blend),
+ buffer_id_);
return true;
}
@@ -204,7 +186,7 @@ void GbmPixmapWayland::CreateDmabufBasedBuffer() {
// Asks Wayland to create a wl_buffer based on the |file| fd.
buffer_manager_->CreateDmabufBasedBuffer(
std::move(fd), GetBufferSize(), strides, offsets, modifiers,
- gbm_bo_->GetFormat(), plane_count, GetUniqueId());
+ gbm_bo_->GetFormat(), plane_count, buffer_id_);
}
} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h b/chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h
index b84aebd2733..e344054c251 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.h
@@ -12,8 +12,8 @@
#include "base/macros.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/linux/gbm_buffer.h"
#include "ui/gfx/native_pixmap.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
namespace ui {
@@ -67,6 +67,9 @@ class GbmPixmapWayland : public gfx::NativePixmap {
// Represents widget this pixmap backs.
gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
+ // A unique ID to identify the buffer for this pixmap.
+ const uint32_t buffer_id_;
+
DISALLOW_COPY_AND_ASSIGN(GbmPixmapWayland);
};
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
index 24df94f3836..95c840cbf77 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/task/post_task.h"
+#include "base/task/thread_pool.h"
#include "base/trace_event/trace_event.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/ozone/common/egl_util.h"
@@ -38,8 +39,9 @@ GbmSurfacelessWayland::GbmSurfacelessWayland(
unsubmitted_frames_.push_back(std::make_unique<PendingFrame>());
}
-void GbmSurfacelessWayland::QueueOverlayPlane(OverlayPlane plane) {
- planes_.push_back(std::move(plane));
+void GbmSurfacelessWayland::QueueOverlayPlane(OverlayPlane plane,
+ uint32_t buffer_id) {
+ planes_.push_back({std::move(plane), buffer_id});
}
bool GbmSurfacelessWayland::ScheduleOverlayPlane(
@@ -93,7 +95,8 @@ void GbmSurfacelessWayland::SwapBuffersAsync(
// TODO(dcastagna): remove glFlush since eglImageFlushExternalEXT called on
// the image should be enough (https://crbug.com/720045).
- glFlush();
+ if (!no_gl_flush_for_tests_)
+ glFlush();
unsubmitted_frames_.back()->Flush();
PendingFrame* frame = unsubmitted_frames_.back().get();
@@ -118,11 +121,10 @@ void GbmSurfacelessWayland::SwapBuffersAsync(
base::OnceClosure fence_retired_callback = base::BindOnce(
&GbmSurfacelessWayland::FenceRetired, weak_factory_.GetWeakPtr(), frame);
- base::PostTaskAndReply(FROM_HERE,
- {base::ThreadPool(), base::MayBlock(),
- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
- std::move(fence_wait_task),
- std::move(fence_retired_callback));
+ base::ThreadPool::PostTaskAndReply(
+ FROM_HERE,
+ {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
+ std::move(fence_wait_task), std::move(fence_retired_callback));
}
void GbmSurfacelessWayland::PostSubBufferAsync(
@@ -165,6 +167,12 @@ void GbmSurfacelessWayland::SetRelyOnImplicitSync() {
use_egl_fence_sync_ = false;
}
+gfx::SurfaceOrigin GbmSurfacelessWayland::GetOrigin() const {
+ // GbmSurfacelessWayland's y-axis is flipped compare to GL - (0,0) is at top
+ // left corner.
+ return gfx::SurfaceOrigin::kTopLeft;
+}
+
GbmSurfacelessWayland::~GbmSurfacelessWayland() {
buffer_manager_->UnregisterSurface(widget_);
}
@@ -209,7 +217,7 @@ void GbmSurfacelessWayland::SubmitFrame() {
return;
}
- submitted_frame_->buffer_id = planes_.back().pixmap->GetUniqueId();
+ submitted_frame_->buffer_id = planes_.back().buffer_id;
buffer_manager_->CommitBuffer(widget_, submitted_frame_->buffer_id,
submitted_frame_->damage_region_);
@@ -230,6 +238,10 @@ void GbmSurfacelessWayland::FenceRetired(PendingFrame* frame) {
SubmitFrame();
}
+void GbmSurfacelessWayland::SetNoGLFlushForTests() {
+ no_gl_flush_for_tests_ = true;
+}
+
void GbmSurfacelessWayland::OnSubmission(uint32_t buffer_id,
const gfx::SwapResult& swap_result) {
submitted_frame_->overlays.clear();
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h
index 0f584991f60..991d1718fad 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h
@@ -29,7 +29,7 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL,
GbmSurfacelessWayland(WaylandBufferManagerGpu* buffer_manager,
gfx::AcceleratedWidget widget);
- void QueueOverlayPlane(OverlayPlane plane);
+ void QueueOverlayPlane(OverlayPlane plane, uint32_t buffer_id);
// gl::GLSurface:
bool ScheduleOverlayPlane(int z_order,
@@ -57,8 +57,12 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL,
PresentationCallback presentation_callback) override;
EGLConfig GetConfig() override;
void SetRelyOnImplicitSync() override;
+ gfx::SurfaceOrigin GetOrigin() const override;
private:
+ FRIEND_TEST_ALL_PREFIXES(WaylandSurfaceFactoryTest,
+ GbmSurfacelessWaylandCheckOrderOfCallbacksTest);
+
~GbmSurfacelessWayland() override;
// WaylandSurfaceGpu overrides:
@@ -88,13 +92,21 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL,
PresentationCallback presentation_callback;
};
+ struct PlaneData {
+ OverlayPlane plane;
+ const uint32_t buffer_id;
+ };
+
void SubmitFrame();
EGLSyncKHR InsertFence(bool implicit);
void FenceRetired(PendingFrame* frame);
+ // Sets a flag that skips glFlush step in unittests.
+ void SetNoGLFlushForTests();
+
WaylandBufferManagerGpu* const buffer_manager_;
- std::vector<OverlayPlane> planes_;
+ std::vector<PlaneData> planes_;
// The native surface. Deleting this is allowed to free the EGLNativeWindow.
gfx::AcceleratedWidget widget_;
@@ -105,6 +117,8 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL,
bool last_swap_buffers_result_ = true;
bool use_egl_fence_sync_ = true;
+ bool no_gl_flush_for_tests_ = false;
+
base::WeakPtrFactory<GbmSurfacelessWayland> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(GbmSurfacelessWayland);
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc
new file mode 100644
index 00000000000..700cb969edf
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc
@@ -0,0 +1,178 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h"
+
+#include "base/memory/shared_memory_mapping.h"
+#include "base/memory/unsafe_shared_memory_region.h"
+#include "base/numerics/checked_math.h"
+#include "ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h"
+
+namespace ui {
+
+namespace {
+
+constexpr size_t kMaxBuffers = 2;
+
+constexpr size_t kBytesPerPixelBGRA = 4;
+
+} // namespace
+
+GLSurfaceEglReadbackWayland::PixelBuffer::PixelBuffer(
+ base::WritableSharedMemoryMapping shm_mapping,
+ uint32_t buffer_id)
+ : shm_mapping_(std::move(shm_mapping)), buffer_id_(buffer_id) {}
+
+GLSurfaceEglReadbackWayland::PixelBuffer::~PixelBuffer() = default;
+
+GLSurfaceEglReadbackWayland::GLSurfaceEglReadbackWayland(
+ gfx::AcceleratedWidget widget,
+ WaylandBufferManagerGpu* buffer_manager)
+ : PbufferGLSurfaceEGL(gfx::Size(1, 1)),
+ widget_(widget),
+ buffer_manager_(buffer_manager) {
+ buffer_manager_->RegisterSurface(widget_, this);
+}
+
+void GLSurfaceEglReadbackWayland::Destroy() {
+ DestroyBuffers();
+ buffer_manager_->UnregisterSurface(widget_);
+
+ PbufferGLSurfaceEGL::Destroy();
+}
+
+bool GLSurfaceEglReadbackWayland::Resize(const gfx::Size& size,
+ float scale_factor,
+ const gfx::ColorSpace& color_space,
+ bool has_alpha) {
+ DestroyBuffers();
+
+ pending_frames_ = 0;
+
+ if (!PbufferGLSurfaceEGL::Resize(size, scale_factor, color_space, has_alpha))
+ return false;
+
+ for (size_t i = 0; i < kMaxBuffers; ++i) {
+ base::CheckedNumeric<size_t> checked_length(size.width());
+ checked_length *= size.height();
+ checked_length *= kBytesPerPixelBGRA;
+ if (!checked_length.IsValid())
+ return false;
+
+ base::UnsafeSharedMemoryRegion shm_region =
+ base::UnsafeSharedMemoryRegion::Create(checked_length.ValueOrDie());
+ if (!shm_region.IsValid())
+ return false;
+
+ auto shm_mapping = shm_region.Map();
+ if (!shm_mapping.IsValid())
+ return false;
+
+ base::subtle::PlatformSharedMemoryRegion platform_shm =
+ base::UnsafeSharedMemoryRegion::TakeHandleForSerialization(
+ std::move(shm_region));
+ base::subtle::ScopedFDPair fd_pair = platform_shm.PassPlatformHandle();
+
+ auto buffer_id = buffer_manager_->AllocateBufferID();
+ available_buffers_.push_back(
+ std::make_unique<PixelBuffer>(std::move(shm_mapping), buffer_id));
+
+ buffer_manager_->CreateShmBasedBuffer(
+ std::move(fd_pair.fd), checked_length.ValueOrDie(), size, buffer_id);
+ }
+
+ return true;
+}
+
+bool GLSurfaceEglReadbackWayland::IsOffscreen() {
+ return false;
+}
+
+bool GLSurfaceEglReadbackWayland::SupportsAsyncSwap() {
+ return true;
+}
+
+gfx::SwapResult GLSurfaceEglReadbackWayland::SwapBuffers(
+ PresentationCallback callback) {
+ NOTREACHED();
+ return gfx::SwapResult::SWAP_FAILED;
+}
+
+void GLSurfaceEglReadbackWayland::SwapBuffersAsync(
+ SwapCompletionCallback completion_callback,
+ PresentationCallback presentation_callback) {
+ DCHECK(pending_frames_ < kMaxBuffers);
+
+ // Increase pending frames number.
+ ++pending_frames_;
+
+ completion_callbacks_.push_back(std::move(completion_callback));
+ presentation_callbacks_.push_back(std::move(presentation_callback));
+
+ DCHECK(!available_buffers_.empty());
+ in_flight_pixel_buffers_.push_back(std::move(available_buffers_.front()));
+ auto* next_buffer = in_flight_pixel_buffers_.back().get();
+ available_buffers_.erase(available_buffers_.begin());
+
+ const gfx::Size size = GetSize();
+ CHECK(next_buffer->shm_mapping_.memory());
+ glReadPixels(0, 0, size.width(), size.height(), GL_BGRA, GL_UNSIGNED_BYTE,
+ next_buffer->shm_mapping_.memory());
+
+ buffer_manager_->CommitBuffer(widget_, next_buffer->buffer_id_,
+ {{0, 0}, size});
+}
+
+gfx::SurfaceOrigin GLSurfaceEglReadbackWayland::GetOrigin() const {
+ // GLSurfaceEglReadbackWayland's y-axis is flipped compare to GL - (0,0) is at
+ // top left corner.
+ return gfx::SurfaceOrigin::kTopLeft;
+}
+
+GLSurfaceEglReadbackWayland::~GLSurfaceEglReadbackWayland() {
+ Destroy();
+}
+
+void GLSurfaceEglReadbackWayland::OnSubmission(
+ uint32_t buffer_id,
+ const gfx::SwapResult& swap_result) {
+ --pending_frames_;
+
+ if (in_flight_pixel_buffers_.front()) {
+ if (displayed_buffer_)
+ available_buffers_.push_back(std::move(displayed_buffer_));
+ displayed_buffer_ = std::move(in_flight_pixel_buffers_.front());
+ DCHECK_EQ(displayed_buffer_->buffer_id_, buffer_id);
+ }
+
+ in_flight_pixel_buffers_.pop_front();
+
+ DCHECK(!completion_callbacks_.empty());
+ std::move(completion_callbacks_.front()).Run(swap_result, nullptr);
+ completion_callbacks_.erase(completion_callbacks_.begin());
+}
+
+void GLSurfaceEglReadbackWayland::OnPresentation(
+ uint32_t buffer_id,
+ const gfx::PresentationFeedback& feedback) {
+ DCHECK(!presentation_callbacks_.empty());
+ std::move(presentation_callbacks_.front()).Run(feedback);
+ presentation_callbacks_.erase(presentation_callbacks_.begin());
+}
+
+void GLSurfaceEglReadbackWayland::DestroyBuffers() {
+ for (const auto& pixel_buffer : available_buffers_)
+ buffer_manager_->DestroyBuffer(widget_, pixel_buffer->buffer_id_);
+ for (const auto& pixel_buffer : in_flight_pixel_buffers_)
+ buffer_manager_->DestroyBuffer(widget_, pixel_buffer->buffer_id_);
+
+ if (displayed_buffer_)
+ buffer_manager_->DestroyBuffer(widget_, displayed_buffer_->buffer_id_);
+
+ available_buffers_.clear();
+ in_flight_pixel_buffers_.clear();
+ displayed_buffer_.reset();
+}
+
+} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h
new file mode 100644
index 00000000000..de83a75b2a6
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h
@@ -0,0 +1,95 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_WAYLAND_GPU_GL_SURFACE_EGL_READBACK_WAYLAND_H_
+#define UI_OZONE_PLATFORM_WAYLAND_GPU_GL_SURFACE_EGL_READBACK_WAYLAND_H_
+
+#include "base/containers/circular_deque.h"
+#include "base/containers/flat_map.h"
+#include "base/memory/shared_memory_mapping.h"
+#include "ui/ozone/common/gl_surface_egl_readback.h"
+#include "ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h"
+
+namespace ui {
+
+class WaylandBufferManagerGpu;
+
+// GLSurface implementation that copies pixels from readback to shared memory
+// and let Wayland compositor to present them.
+class GLSurfaceEglReadbackWayland : public gl::PbufferGLSurfaceEGL,
+ public WaylandSurfaceGpu {
+ public:
+ GLSurfaceEglReadbackWayland(gfx::AcceleratedWidget widget,
+ WaylandBufferManagerGpu* buffer_manager);
+ GLSurfaceEglReadbackWayland(const GLSurfaceEglReadbackWayland&) = delete;
+ GLSurfaceEglReadbackWayland& operator=(const GLSurfaceEglReadbackWayland&) =
+ delete;
+
+ // gl::GLSurface:
+ void Destroy() override;
+ bool Resize(const gfx::Size& size,
+ float scale_factor,
+ const gfx::ColorSpace& color_space,
+ bool has_alpha) override;
+ bool IsOffscreen() override;
+ gfx::SwapResult SwapBuffers(PresentationCallback callback) override;
+ bool SupportsAsyncSwap() override;
+ void SwapBuffersAsync(SwapCompletionCallback completion_callback,
+ PresentationCallback presentation_callback) override;
+ gfx::SurfaceOrigin GetOrigin() const override;
+
+ private:
+ struct PixelBuffer {
+ PixelBuffer(base::WritableSharedMemoryMapping shm_mapping,
+ uint32_t buffer_id);
+ ~PixelBuffer();
+ PixelBuffer(const PixelBuffer&) = delete;
+ PixelBuffer& operator=(const PixelBuffer&) = delete;
+
+ // Shared memory mapping that readback pixels are written to so that Wayland
+ // is able to turn them in light.
+ base::WritableSharedMemoryMapping shm_mapping_;
+
+ // The buffer id that corresponds to the |wl_buffer| created on the browser
+ // process side.
+ uint32_t buffer_id_ = 0;
+ };
+
+ ~GLSurfaceEglReadbackWayland() override;
+
+ // WaylandSurfaceGpu:
+ void OnSubmission(uint32_t buffer_id,
+ const gfx::SwapResult& swap_result) override;
+ void OnPresentation(uint32_t buffer_id,
+ const gfx::PresentationFeedback& feedback) override;
+
+ void DestroyBuffers();
+
+ // Widget of the window that this readback writes pixels to.
+ const gfx::AcceleratedWidget widget_;
+
+ WaylandBufferManagerGpu* const buffer_manager_;
+
+ // Size of the buffer.
+ gfx::Size size_;
+
+ // Available pixel buffers based on shared memory.
+ std::vector<std::unique_ptr<PixelBuffer>> available_buffers_;
+
+ // Displayed buffer that will become available after another buffer is
+ // submitted.
+ std::unique_ptr<PixelBuffer> displayed_buffer_;
+
+ // Submitted buffers waiting to be displayed.
+ base::circular_deque<std::unique_ptr<PixelBuffer>> in_flight_pixel_buffers_;
+
+ std::vector<SwapCompletionCallback> completion_callbacks_;
+ std::vector<PresentationCallback> presentation_callbacks_;
+
+ size_t pending_frames_ = 0;
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_GL_SURFACE_EGL_READBACK_WAYLAND_H_
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc
index 22d06a8affe..02ec5b8088e 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc
@@ -35,7 +35,7 @@ GLSurfaceWayland::GLSurfaceWayland(WaylandEglWindowPtr egl_window)
bool GLSurfaceWayland::Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) {
if (size_ == size)
return true;
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.h b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.h
index 4b9b15ea92d..87a7da0d18b 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.h
@@ -34,7 +34,7 @@ class GLSurfaceWayland : public gl::NativeViewGLSurfaceEGL {
// gl::GLSurface:
bool Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) override;
EGLConfig GetConfig() override;
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc b/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
index 86980f3d598..6adfc621532 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
@@ -9,8 +9,7 @@
#include "base/bind.h"
#include "base/message_loop/message_loop_current.h"
#include "base/process/process.h"
-#include "mojo/public/cpp/system/platform_handle.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
+#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h"
namespace ui {
@@ -158,6 +157,10 @@ WaylandBufferManagerGpu::GetModifiersForBufferFormat(
return dummy;
}
+uint32_t WaylandBufferManagerGpu::AllocateBufferID() {
+ return ++next_buffer_id_;
+}
+
void WaylandBufferManagerGpu::CreateDmabufBasedBufferInternal(
base::ScopedFD dmabuf_fd,
gfx::Size size,
@@ -170,9 +173,8 @@ void WaylandBufferManagerGpu::CreateDmabufBasedBufferInternal(
DCHECK(io_thread_runner_->BelongsToCurrentThread());
DCHECK(remote_host_);
remote_host_->CreateDmabufBasedBuffer(
- mojo::WrapPlatformHandle(mojo::PlatformHandle(std::move(dmabuf_fd))),
- size, strides, offsets, modifiers, current_format, planes_count,
- buffer_id);
+ mojo::PlatformHandle(std::move(dmabuf_fd)), size, strides, offsets,
+ modifiers, current_format, planes_count, buffer_id);
}
void WaylandBufferManagerGpu::CreateShmBasedBufferInternal(
@@ -182,9 +184,8 @@ void WaylandBufferManagerGpu::CreateShmBasedBufferInternal(
uint32_t buffer_id) {
DCHECK(io_thread_runner_->BelongsToCurrentThread());
DCHECK(remote_host_);
- remote_host_->CreateShmBasedBuffer(
- mojo::WrapPlatformHandle(mojo::PlatformHandle(std::move(shm_fd))), length,
- size, buffer_id);
+ remote_host_->CreateShmBasedBuffer(mojo::PlatformHandle(std::move(shm_fd)),
+ length, size, buffer_id);
}
void WaylandBufferManagerGpu::CommitBufferInternal(
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h b/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
index e998717b692..819d64a9834 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
@@ -19,7 +19,7 @@
#include "ui/ozone/public/mojom/wayland/wayland_buffer_manager.mojom.h"
#if defined(WAYLAND_GBM)
-#include "ui/ozone/common/linux/gbm_device.h" // nogncheck
+#include "ui/gfx/linux/gbm_device.h" // nogncheck
#endif
namespace gfx {
@@ -123,6 +123,9 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu {
const std::vector<uint64_t>& GetModifiersForBufferFormat(
gfx::BufferFormat buffer_format) const;
+ // Allocates a unique buffer ID.
+ uint32_t AllocateBufferID();
+
private:
void CreateDmabufBasedBufferInternal(base::ScopedFD dmabuf_fd,
gfx::Size size,
@@ -193,6 +196,9 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu {
// Protects access to |widget_to_surface_map_|.
base::Lock lock_;
+ // Keeps track of the next unique buffer ID.
+ uint32_t next_buffer_id_ = 0;
+
DISALLOW_COPY_AND_ASSIGN(WaylandBufferManagerGpu);
};
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc b/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc
index fe1040e5263..09cfac561f6 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc
@@ -35,10 +35,9 @@ size_t CalculateStride(int width) {
class WaylandCanvasSurface::SharedMemoryBuffer {
public:
- SharedMemoryBuffer(uint32_t buffer_id,
- gfx::AcceleratedWidget widget,
+ SharedMemoryBuffer(gfx::AcceleratedWidget widget,
WaylandBufferManagerGpu* buffer_manager)
- : buffer_id_(buffer_id),
+ : buffer_id_(buffer_manager->AllocateBufferID()),
widget_(widget),
buffer_manager_(buffer_manager) {
DCHECK(buffer_manager_);
@@ -51,9 +50,8 @@ class WaylandCanvasSurface::SharedMemoryBuffer {
// Returns the id of the buffer.
uint32_t buffer_id() const { return buffer_id_; }
- // Tells if the buffer is pending to be processed. Set on
- // SetPendingDamageRegion calls.
- bool pending() const { return pending_; }
+ // Tells if the buffer is currently being used.
+ bool used() const { return used_; }
// Initializes the shared memory and asks Wayland to import a shared memory
// based wl_buffer, which can be attached to a surface and have its contents
@@ -95,9 +93,14 @@ class WaylandCanvasSurface::SharedMemoryBuffer {
buffer_manager_->CommitBuffer(widget_, buffer_id_, damage);
}
- void OnSubmissionCompleted() {
- DCHECK(pending_);
- pending_ = false;
+ void OnUse() {
+ DCHECK(!used_);
+ used_ = true;
+ }
+
+ void OnRelease() {
+ DCHECK(used_);
+ used_ = false;
}
void UpdateDirtyRegion(const gfx::Rect& damage, SkRegion::Op op) {
@@ -120,22 +123,20 @@ class WaylandCanvasSurface::SharedMemoryBuffer {
dirty_region_.setEmpty();
}
- void SetPendingDamageRegion(const gfx::Rect& damage) {
- DCHECK(!pending_);
+ void set_pending_damage_region(const gfx::Rect& damage) {
pending_damage_region_ = damage;
- pending_ = true;
}
- gfx::Rect pending_damage_region() {
- return std::move(pending_damage_region_);
+ const gfx::Rect& pending_damage_region() const {
+ return pending_damage_region_;
}
private:
// The id of the buffer this surface is backed.
const uint32_t buffer_id_;
- // Says if the buffer is pending to be submitted.
- bool pending_ = false;
+ // Whether this buffer is currently being used.
+ bool used_ = false;
// The widget this buffer is created for.
const gfx::AcceleratedWidget widget_;
@@ -169,12 +170,12 @@ WaylandCanvasSurface::~WaylandCanvasSurface() {
buffer_manager_->UnregisterSurface(widget_);
}
-sk_sp<SkSurface> WaylandCanvasSurface::GetSurface() {
+SkCanvas* WaylandCanvasSurface::GetCanvas() {
DCHECK(!pending_buffer_)
<< "The previous pending buffer has not been presented yet";
for (const auto& buffer : buffers_) {
- if (!buffer->pending()) {
+ if (!buffer->used()) {
pending_buffer_ = buffer.get();
break;
}
@@ -194,8 +195,9 @@ sk_sp<SkSurface> WaylandCanvasSurface::GetSurface() {
buffers_.push_back(std::move(buffer));
}
- DCHECK(pending_buffer_ && !pending_buffer_->pending());
- return pending_buffer_->sk_surface();
+ DCHECK(pending_buffer_);
+ pending_buffer_->OnUse();
+ return pending_buffer_->sk_surface()->getCanvas();
}
void WaylandCanvasSurface::ResizeCanvas(const gfx::Size& viewport_size) {
@@ -205,13 +207,11 @@ void WaylandCanvasSurface::ResizeCanvas(const gfx::Size& viewport_size) {
// by allocating buffers rounded up to larger sizes, and then reusing them if
// the new size still fits (but still reallocate if the new size is much
// smaller than the old size).
- if (!buffers_.empty()) {
- buffers_.clear();
- current_buffer_ = nullptr;
- previous_buffer_ = nullptr;
- pending_buffer_ = nullptr;
- unsubmitted_buffers_.clear();
- }
+ buffers_.clear();
+ current_buffer_ = nullptr;
+ previous_buffer_ = nullptr;
+ pending_buffer_ = nullptr;
+ unsubmitted_buffers_.clear();
size_ = viewport_size;
}
@@ -219,7 +219,7 @@ void WaylandCanvasSurface::PresentCanvas(const gfx::Rect& damage) {
if (!pending_buffer_)
return;
- pending_buffer_->SetPendingDamageRegion(damage);
+ pending_buffer_->set_pending_damage_region(damage);
unsubmitted_buffers_.push_back(pending_buffer_);
pending_buffer_ = nullptr;
@@ -235,49 +235,61 @@ WaylandCanvasSurface::CreateVSyncProvider() {
}
void WaylandCanvasSurface::ProcessUnsubmittedBuffers() {
- DCHECK(!unsubmitted_buffers_.empty());
+ DCHECK(!unsubmitted_buffers_.empty() && unsubmitted_buffers_.front()->used());
- if (!current_buffer_ && unsubmitted_buffers_.front()->pending()) {
- current_buffer_ = std::move(unsubmitted_buffers_.front());
- unsubmitted_buffers_.erase(unsubmitted_buffers_.begin());
+ // Don't submit a new buffer if there's one already submitted being
+ // processed.
+ if (current_buffer_)
+ return;
- gfx::Rect damage = current_buffer_->pending_damage_region();
+ current_buffer_ = std::move(unsubmitted_buffers_.front());
+ unsubmitted_buffers_.erase(unsubmitted_buffers_.begin());
- // The buffer has been updated. Thus, the |damage| can be subtracted
- // from its dirty region.
- current_buffer_->UpdateDirtyRegion(damage, SkRegion::kDifference_Op);
+ gfx::Rect damage = current_buffer_->pending_damage_region();
- // Make sure the buffer is up-to-date by copying the outdated region from
- // the previous buffer.
- if (previous_buffer_ && previous_buffer_ != current_buffer_)
- current_buffer_->CopyDirtyRegionFrom(previous_buffer_);
+ // The buffer has been updated. Thus, the |damage| can be subtracted
+ // from its dirty region.
+ current_buffer_->UpdateDirtyRegion(damage, SkRegion::kDifference_Op);
- // As long as the |current_buffer_| has been updated, add dirty region to
- // other buffers to make sure their regions will be updated with up-to-date
- // content.
- for (auto& buffer : buffers_) {
- if (buffer.get() != current_buffer_)
- buffer->UpdateDirtyRegion(damage, SkRegion::kUnion_Op);
- }
+ // Make sure the buffer is up-to-date by copying the outdated region from
+ // the previous buffer.
+ if (previous_buffer_ && previous_buffer_ != current_buffer_)
+ current_buffer_->CopyDirtyRegionFrom(previous_buffer_);
- current_buffer_->CommitBuffer(damage);
+ // As long as the |current_buffer_| has been updated, add dirty region to
+ // other buffers to make sure their regions will be updated with up-to-date
+ // content.
+ for (auto& buffer : buffers_) {
+ if (buffer.get() != current_buffer_)
+ buffer->UpdateDirtyRegion(damage, SkRegion::kUnion_Op);
}
+
+ current_buffer_->CommitBuffer(damage);
}
void WaylandCanvasSurface::OnSubmission(uint32_t buffer_id,
const gfx::SwapResult& swap_result) {
- // Upper layer does not care about the submission result, and the buffer may
- // be destroyed by this time (when the surface is resized, for example).
- if (!current_buffer_)
+ // We may get an OnSubmission callback for a buffer that was submitted
+ // before a ResizeCanvas call, which clears all our buffers. Check to
+ // see if we still know about this buffer. If we know about this buffer
+ // it must be |current_buffer_| because we only submit new buffers when
+ // |current_buffer_| is nullptr, and it is only set to nullptr in
+ // |OnSubmission| and |ResizeCanvas|. In |ResizeCanvas|, |buffers_| is cleared
+ // so we will not know about |buffer_id|.
+ if (std::none_of(buffers_.begin(), buffers_.end(),
+ [buffer_id](const auto& buffer) {
+ return buffer->buffer_id() == buffer_id;
+ }))
return;
+ DCHECK(current_buffer_);
DCHECK_EQ(current_buffer_->buffer_id(), buffer_id);
- auto* buffer = current_buffer_;
- previous_buffer_ = buffer;
- current_buffer_ = nullptr;
+ if (previous_buffer_)
+ previous_buffer_->OnRelease();
- buffer->OnSubmissionCompleted();
+ previous_buffer_ = current_buffer_;
+ current_buffer_ = nullptr;
if (!unsubmitted_buffers_.empty())
ProcessUnsubmittedBuffers();
@@ -294,8 +306,8 @@ std::unique_ptr<WaylandCanvasSurface::SharedMemoryBuffer>
WaylandCanvasSurface::CreateSharedMemoryBuffer() {
DCHECK(!size_.IsEmpty());
- auto canvas_buffer = std::make_unique<SharedMemoryBuffer>(
- ++buffer_id_, widget_, buffer_manager_);
+ auto canvas_buffer =
+ std::make_unique<SharedMemoryBuffer>(widget_, buffer_manager_);
return canvas_buffer->Initialize(size_) ? std::move(canvas_buffer) : nullptr;
}
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.h b/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.h
index a7596721ddd..054e27de8f1 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.h
@@ -15,6 +15,8 @@
#include "ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h"
#include "ui/ozone/public/surface_ozone_canvas.h"
+class SkCanvas;
+
namespace ui {
class WaylandBufferManagerGpu;
@@ -31,7 +33,7 @@ class WaylandCanvasSurface : public SurfaceOzoneCanvas,
~WaylandCanvasSurface() override;
// SurfaceOzoneCanvas
- sk_sp<SkSurface> GetSurface() override;
+ SkCanvas* GetCanvas() override;
void ResizeCanvas(const gfx::Size& viewport_size) override;
void PresentCanvas(const gfx::Rect& damage) override;
std::unique_ptr<gfx::VSyncProvider> CreateVSyncProvider() override;
@@ -73,11 +75,6 @@ class WaylandCanvasSurface : public SurfaceOzoneCanvas,
// Previously used buffer. Set on OnSubmission().
SharedMemoryBuffer* previous_buffer_ = nullptr;
- // The id of the current existing buffer. Even though, there can only be one
- // buffer (SkSurface) at a time, the buffer manager on the browser process
- // side requires buffer id to be passed.
- uint32_t buffer_id_ = 0;
-
DISALLOW_COPY_AND_ASSIGN(WaylandCanvasSurface);
};
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
index 99ed42401c0..b8258fda199 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
@@ -11,6 +11,7 @@
#include "ui/ozone/common/egl_util.h"
#include "ui/ozone/common/gl_ozone_egl.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
+#include "ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.h"
#include "ui/ozone/platform/wayland/gpu/gl_surface_wayland.h"
#include "ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h"
#include "ui/ozone/platform/wayland/gpu/wayland_canvas_surface.h"
@@ -45,7 +46,7 @@ class GLOzoneEGLWayland : public GLOzoneEGL {
const gfx::Size& size) override;
protected:
- intptr_t GetNativeDisplay() override;
+ gl::EGLDisplayPlatform GetNativeDisplay() override;
bool LoadGLES2Bindings(gl::GLImplementation impl) override;
private:
@@ -77,10 +78,11 @@ scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateViewGLSurface(
scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateSurfacelessViewGLSurface(
gfx::AcceleratedWidget window) {
- // Only EGLGLES2 is supported with surfaceless view gl.
- if (gl::GetGLImplementation() != gl::kGLImplementationEGLGLES2)
- return nullptr;
-
+ if (gl::GetGLImplementation() == gl::kGLImplementationSwiftShaderGL) {
+ return gl::InitializeGLSurface(
+ base::MakeRefCounted<GLSurfaceEglReadbackWayland>(window,
+ buffer_manager_));
+ } else {
#if defined(WAYLAND_GBM)
// If there is a gbm device available, use surfaceless gl surface.
if (!buffer_manager_->gbm_device())
@@ -90,6 +92,7 @@ scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateSurfacelessViewGLSurface(
#else
return nullptr;
#endif
+ }
}
scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateOffscreenGLSurface(
@@ -102,10 +105,11 @@ scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateOffscreenGLSurface(
}
}
-intptr_t GLOzoneEGLWayland::GetNativeDisplay() {
+gl::EGLDisplayPlatform GLOzoneEGLWayland::GetNativeDisplay() {
if (connection_)
- return reinterpret_cast<intptr_t>(connection_->display());
- return EGL_DEFAULT_DISPLAY;
+ return gl::EGLDisplayPlatform(
+ reinterpret_cast<EGLNativeDisplayType>(connection_->display()));
+ return gl::EGLDisplayPlatform(EGL_DEFAULT_DISPLAY);
}
bool GLOzoneEGLWayland::LoadGLES2Bindings(gl::GLImplementation impl) {
@@ -128,8 +132,9 @@ WaylandSurfaceFactory::WaylandSurfaceFactory(
WaylandSurfaceFactory::~WaylandSurfaceFactory() = default;
std::unique_ptr<SurfaceOzoneCanvas>
-WaylandSurfaceFactory::CreateCanvasForWidget(gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) {
+WaylandSurfaceFactory::CreateCanvasForWidget(
+ gfx::AcceleratedWidget widget,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
return std::make_unique<WaylandCanvasSurface>(buffer_manager_, widget);
}
@@ -159,7 +164,9 @@ scoped_refptr<gfx::NativePixmap> WaylandSurfaceFactory::CreateNativePixmap(
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) {
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size) {
+ DCHECK(!framebuffer_size || framebuffer_size == size);
#if defined(WAYLAND_GBM)
scoped_refptr<GbmPixmapWayland> pixmap =
base::MakeRefCounted<GbmPixmapWayland>(buffer_manager_);
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h
index 07c132c2021..51e7f9ecf95 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h
@@ -31,13 +31,14 @@ class WaylandSurfaceFactory : public SurfaceFactoryOzone {
GLOzone* GetGLOzone(gl::GLImplementation implementation) override;
std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) override;
+ scoped_refptr<base::SequencedTaskRunner> task_runner) override;
scoped_refptr<gfx::NativePixmap> CreateNativePixmap(
gfx::AcceleratedWidget widget,
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) override;
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size = base::nullopt) override;
void CreateNativePixmapAsync(gfx::AcceleratedWidget widget,
VkDevice vk_device,
gfx::Size size,
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
index 448a4a7c476..585e5666283 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
@@ -5,17 +5,24 @@
#include <memory>
#include <utility>
+#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
+#include "base/test/mock_callback.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkSurface.h"
-#include "ui/ozone/common/linux/gbm_buffer.h"
-#include "ui/ozone/common/linux/gbm_device.h"
+#include "ui/gfx/linux/gbm_buffer.h"
+#include "ui/gfx/linux/gbm_device.h"
+#include "ui/gfx/linux/test/mock_gbm_device.h"
+#include "ui/gfx/native_pixmap.h"
+#include "ui/gl/gl_image_egl.h"
+#include "ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h"
#include "ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h"
#include "ui/ozone/platform/wayland/gpu/wayland_surface_factory.h"
#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h"
#include "ui/ozone/platform/wayland/test/mock_surface.h"
#include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h"
+#include "ui/ozone/platform/wayland/test/test_zwp_linux_buffer_params.h"
#include "ui/ozone/platform/wayland/test/wayland_test.h"
#include "ui/ozone/public/surface_ozone_canvas.h"
#include "ui/ozone/test/mock_platform_window_delegate.h"
@@ -28,62 +35,128 @@ namespace ui {
namespace {
-class FakeGbmBuffer : public GbmBuffer {
+// Fake GLImage that just schedules overlay plane. It must become busy when
+// scheduled and be associated with the swap id to track correct order of swaps
+// and releases of the image.
+class FakeGLImageNativePixmap : public gl::GLImageEGL {
public:
- FakeGbmBuffer() = default;
- ~FakeGbmBuffer() override = default;
-
- uint32_t GetFormat() const override { return 0; }
- uint64_t GetFormatModifier() const override { return 0; }
- uint32_t GetFlags() const override { return 0; }
- gfx::Size GetSize() const override { return gfx::Size(); }
- gfx::BufferFormat GetBufferFormat() const override {
- return gfx::BufferFormat::BGRA_8888;
+ FakeGLImageNativePixmap(scoped_refptr<gfx::NativePixmap> pixmap,
+ const gfx::Size& size)
+ : gl::GLImageEGL(size), pixmap_(pixmap) {}
+
+ // Associates swap id with this image.
+ void AssociateWithSwapId(uint32_t swap_id) {
+ DCHECK_NE(swap_id_, swap_id);
+ swap_id_ = swap_id;
}
- bool AreFdsValid() const override { return false; }
- size_t GetNumPlanes() const override { return 0; }
- int GetPlaneFd(size_t plane) const override { return -1; }
- uint32_t GetPlaneHandle(size_t plane) const override { return 0; }
- uint32_t GetPlaneStride(size_t plane) const override { return 0u; }
- size_t GetPlaneOffset(size_t plane) const override { return 0u; }
- size_t GetPlaneSize(size_t plane) const override { return 0; }
- uint32_t GetHandle() const override { return 0; }
- gfx::NativePixmapHandle ExportHandle() const override {
- return gfx::NativePixmapHandle();
+
+ // Returns associated swap id with this image.
+ uint32_t GetAssociateWithSwapId() { return swap_id_; }
+
+ // The image is set busy when scheduled as overlay plane for
+ // GbmSurfacelessWayland
+ void SetBusy(bool busy) { busy_ = busy; }
+ bool busy() const { return busy_; }
+
+ // Sets the image as displayed.
+ void SetDisplayed(bool displayed) { displayed_ = displayed; }
+ bool displayed() const { return displayed_; }
+
+ // Overridden from GLImage:
+ void Flush() override {}
+ bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
+ int z_order,
+ gfx::OverlayTransform transform,
+ const gfx::Rect& bounds_rect,
+ const gfx::RectF& crop_rect,
+ bool enable_blend,
+ std::unique_ptr<gfx::GpuFence> gpu_fence) override {
+ // The GLImage must be set busy as it has been scheduled before when
+ // GbmSurfacelessWayland::ScheduleOverlayPlane was called.
+ DCHECK(busy_);
+ return pixmap_->ScheduleOverlayPlane(widget, z_order, transform,
+ bounds_rect, crop_rect, enable_blend,
+ std::move(gpu_fence));
+ }
+ scoped_refptr<gfx::NativePixmap> GetNativePixmap() override {
+ return pixmap_;
}
- sk_sp<SkSurface> GetSurface() override { return nullptr; }
+
+ protected:
+ ~FakeGLImageNativePixmap() override {}
private:
- DISALLOW_COPY_AND_ASSIGN(FakeGbmBuffer);
+ scoped_refptr<gfx::NativePixmap> pixmap_;
+
+ // Indicated if the gl image is busy. If yes, it was scheduled as overlay
+ // plane for further submission and can't be reused until it's freed.
+ bool busy_ = false;
+
+ bool displayed_ = false;
+
+ uint32_t swap_id_ = std::numeric_limits<uint32_t>::max();
};
-class FakeGbmDevice : public GbmDevice {
+// Helper that helps to identify the last swap id. Also sets gl image associated
+// with that swap as free.
+class CallbacksHelper {
public:
- FakeGbmDevice() = default;
- ~FakeGbmDevice() override = default;
+ CallbacksHelper() = default;
+ ~CallbacksHelper() = default;
+
+ // Returns last executed swap id that received SwapCompletionCallback.
+ uint32_t GetLastFinishedSwapId() const { return last_finish_swap_id_; }
+
+ // Returns next available swap id that must be used for the next submission of
+ // the buffer.
+ uint32_t GetNextLocalSwapId() {
+ auto next_swap_id = local_swap_id_++;
+ pending_local_swap_ids_.push(next_swap_id);
+ return next_swap_id;
+ }
- std::unique_ptr<GbmBuffer> CreateBuffer(uint32_t format,
- const gfx::Size& size,
- uint32_t flags) override {
- return nullptr;
+ void ResetLastFinishedSwapId() {
+ last_finish_swap_id_ = std::numeric_limits<uint32_t>::max();
}
- std::unique_ptr<GbmBuffer> CreateBufferWithModifiers(
- uint32_t format,
- const gfx::Size& size,
- uint32_t flags,
- const std::vector<uint64_t>& modifiers) override {
- return nullptr;
+ // Finishes the submission by setting the swap id of completed buffer swap and
+ // sets the associated gl_image as displayed and non-busy, which indicates
+ // that 1) the image has been sent to be shown after being scheduled 2) the
+ // image is displayed. This sort of mimics a buffer queue, but in a simpliear
+ // way.
+ void FinishSwapBuffersAsync(uint32_t local_swap_id,
+ scoped_refptr<FakeGLImageNativePixmap> gl_image,
+ gfx::SwapResult result,
+ std::unique_ptr<gfx::GpuFence> gpu_fence) {
+ last_finish_swap_id_ = pending_local_swap_ids_.front();
+ pending_local_swap_ids_.pop();
+
+ EXPECT_EQ(gl_image->GetAssociateWithSwapId(), last_finish_swap_id_);
+ EXPECT_TRUE(gl_image->busy() && !gl_image->displayed());
+ if (displayed_image_)
+ displayed_image_->SetDisplayed(false);
+ displayed_image_ = gl_image;
+ displayed_image_->SetBusy(false);
+ displayed_image_->SetDisplayed(true);
}
- std::unique_ptr<GbmBuffer> CreateBufferFromHandle(
- uint32_t format,
- const gfx::Size& size,
- gfx::NativePixmapHandle handle) override {
- return nullptr;
+
+ void BufferPresented(uint64_t local_swap_id,
+ const gfx::PresentationFeedback& feedback) {
+ // Make sure the presentation doesn't come earlier than than swap
+ // completion. We don't explicitly check if the buffer is presented as this
+ // DCHECK is more that enough.
+ DCHECK(pending_local_swap_ids_.empty() ||
+ pending_local_swap_ids_.front() > local_swap_id);
}
private:
- DISALLOW_COPY_AND_ASSIGN(FakeGbmDevice);
+ uint32_t local_swap_id_ = 0;
+ // Make sure that local_swap_id_ != last_finish_swap_id_.
+ uint32_t last_finish_swap_id_ = std::numeric_limits<uint32_t>::max();
+ base::queue<uint64_t> pending_local_swap_ids_;
+
+ // Keeps track of a displayed image.
+ scoped_refptr<FakeGLImageNativePixmap> displayed_image_;
};
} // namespace
@@ -123,12 +196,219 @@ class WaylandSurfaceFactoryTest : public WaylandTest {
DISALLOW_COPY_AND_ASSIGN(WaylandSurfaceFactoryTest);
};
+TEST_P(WaylandSurfaceFactoryTest,
+ GbmSurfacelessWaylandCheckOrderOfCallbacksTest) {
+ gl::SetGLImplementation(gl::kGLImplementationEGLGLES2);
+
+ buffer_manager_gpu_->set_gbm_device(std::make_unique<MockGbmDevice>());
+
+ auto* gl_ozone = surface_factory_->GetGLOzone(gl::kGLImplementationEGLGLES2);
+ auto gl_surface = gl_ozone->CreateSurfacelessViewGLSurface(widget_);
+ EXPECT_TRUE(gl_surface);
+ gl_surface->SetRelyOnImplicitSync();
+ static_cast<ui::GbmSurfacelessWayland*>(gl_surface.get())
+ ->SetNoGLFlushForTests();
+
+ // Expect to create 3 buffers.
+ EXPECT_CALL(*server_.zwp_linux_dmabuf_v1(), CreateParams(_, _, _)).Times(3);
+
+ // Create buffers and FakeGlImageNativePixmap.
+ std::vector<scoped_refptr<FakeGLImageNativePixmap>> fake_gl_image;
+ for (int i = 0; i < 3; ++i) {
+ auto native_pixmap = surface_factory_->CreateNativePixmap(
+ widget_, nullptr, window_->GetBounds().size(),
+ gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::SCANOUT);
+ fake_gl_image.push_back(base::MakeRefCounted<FakeGLImageNativePixmap>(
+ native_pixmap, window_->GetBounds().size()));
+
+ Sync();
+
+ // Create one buffer at a time.
+ auto params_vector = server_.zwp_linux_dmabuf_v1()->buffer_params();
+ DCHECK_EQ(params_vector.size(), 1u);
+ zwp_linux_buffer_params_v1_send_created(
+ params_vector.front()->resource(),
+ params_vector.front()->buffer_resource());
+
+ Sync();
+ }
+
+ // Now, schedule 3 buffers for swap.
+ auto* mock_surface = server_.GetObject<wl::MockSurface>(widget_);
+
+ CallbacksHelper cbs_helper;
+ // Submit all the available buffers.
+ for (const auto& gl_image : fake_gl_image) {
+ // Associate each image with swap id so that we could track released
+ // buffers.
+ auto swap_id = cbs_helper.GetNextLocalSwapId();
+ // Associate the image with the next swap id so that we can easily track if
+ // it became free to reuse.
+ gl_image->AssociateWithSwapId(swap_id);
+ // And set it to be busy...
+ gl_image->SetBusy(true);
+
+ // Prepare overlay plane.
+ gl_surface->ScheduleOverlayPlane(
+ 0, gfx::OverlayTransform::OVERLAY_TRANSFORM_FLIP_VERTICAL,
+ gl_image.get(), window_->GetBounds(), {}, false, nullptr);
+
+ // And submit each image. They will be executed in FIFO manner.
+ gl_surface->SwapBuffersAsync(
+ base::BindOnce(&CallbacksHelper::FinishSwapBuffersAsync,
+ base::Unretained(&cbs_helper), swap_id, gl_image),
+ base::BindOnce(&CallbacksHelper::BufferPresented,
+ base::Unretained(&cbs_helper), swap_id));
+ }
+
+ // Let's sync so that 1) GbmSurfacelessWayland submits the buffer according to
+ // internal queue and fake server processes the request.
+
+ // Also, we expect only one buffer to be committed.
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(1);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(1);
+ EXPECT_CALL(*mock_surface, Commit()).Times(1);
+
+ Sync();
+
+ testing::Mock::VerifyAndClearExpectations(&mock_surface);
+
+ // Give mojo the chance to pass the callbacks.
+ base::RunLoop().RunUntilIdle();
+
+ // We have just received Attach/DamageBuffer/Commit for buffer with swap
+ // id=0u. The SwapCompletionCallback must be executed automatically as long as
+ // we didn't have any buffers attached to the surface before.
+ EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(), 0u);
+
+ cbs_helper.ResetLastFinishedSwapId();
+
+ for (const auto& gl_image : fake_gl_image) {
+ // All the images except the first one, which was associated with swap
+ // id=0u, must be busy and not displayed. The first one must be displayed.
+ if (gl_image->GetAssociateWithSwapId() == 0u) {
+ EXPECT_FALSE(gl_image->busy());
+ EXPECT_TRUE(gl_image->displayed());
+ } else {
+ EXPECT_TRUE(gl_image->busy());
+ EXPECT_FALSE(gl_image->displayed());
+ }
+ }
+
+ // Expect buffer for swap with id=1u to be committed.
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(1);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(1);
+ EXPECT_CALL(*mock_surface, Commit()).Times(1);
+
+ // Send the frame callback so that pending buffer for swap id=1u is processed
+ // and swapped.
+ mock_surface->SendFrameCallback();
+
+ Sync();
+
+ // Give mojo the chance to pass the callbacks.
+ base::RunLoop().RunUntilIdle();
+
+ // Even though the second buffer was submitted, we mustn't receive
+ // SwapCompletionCallback until the previous buffer is released.
+ EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(),
+ std::numeric_limits<uint32_t>::max());
+
+ // This will result in Wayland server releasing previously attached buffer for
+ // swap id=0u and calling OnSubmission for buffer with swap id=1u.
+ mock_surface->ReleasePrevAttachedBuffer();
+
+ Sync();
+
+ // Give mojo the chance to pass the callbacks.
+ base::RunLoop().RunUntilIdle();
+
+ // We expect only one buffer to be released. Thus, the last swap id must be
+ // 0 as we waited until next buffer was attached to the surface.
+ EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(), 1u);
+
+ // Reset to test further swap ids.
+ cbs_helper.ResetLastFinishedSwapId();
+
+ for (const auto& gl_image : fake_gl_image) {
+ // The first image is not displayed and not busy, the second is displayed
+ // and not busy. And others are not display and busy.
+ if (gl_image->GetAssociateWithSwapId() == 0u) {
+ EXPECT_FALSE(gl_image->busy());
+ EXPECT_FALSE(gl_image->displayed());
+ } else if (gl_image->GetAssociateWithSwapId() == 1u) {
+ EXPECT_FALSE(gl_image->busy());
+ EXPECT_TRUE(gl_image->displayed());
+ } else {
+ EXPECT_TRUE(gl_image->busy());
+ EXPECT_FALSE(gl_image->displayed());
+ }
+ }
+
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(1);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(1);
+ EXPECT_CALL(*mock_surface, Commit()).Times(1);
+
+ // Send the frame callback, so that the pending buffer with swap id=2u can
+ // be processed.
+ mock_surface->SendFrameCallback();
+
+ Sync();
+
+ // Give mojo the chance to pass the callbacks.
+ base::RunLoop().RunUntilIdle();
+
+ // Even though the second buffer was submitted, we mustn't receive
+ // SwapCompletionCallback until the previous buffer is released.
+ EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(),
+ std::numeric_limits<uint32_t>::max());
+
+ // This will result in Wayland server releasing previously attached buffer for
+ // swap id=1u and calling OnSubmission for buffer with swap id=2u.
+ mock_surface->ReleasePrevAttachedBuffer();
+
+ Sync();
+
+ // Give mojo the chance to pass the callbacks.
+ base::RunLoop().RunUntilIdle();
+
+ // We should receive next callbacks for the next swap id.
+ EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(), 2u);
+
+ cbs_helper.ResetLastFinishedSwapId();
+
+ // All images must be free now and the last one is displayed.
+ for (const auto& gl_image : fake_gl_image) {
+ if (gl_image->GetAssociateWithSwapId() == 2u) {
+ EXPECT_TRUE(gl_image->displayed());
+ EXPECT_FALSE(gl_image->busy());
+ } else {
+ EXPECT_FALSE(gl_image->displayed());
+ EXPECT_FALSE(gl_image->busy());
+ }
+ }
+
+ // There are no buffers left. Send last frame callback and verify that.
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(0);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(0);
+ EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(0);
+ EXPECT_CALL(*mock_surface, Commit()).Times(0);
+
+ // Send a frame callback so that the WaylandBufferManagerHost processes the
+ // pending buffers if any exist.
+ mock_surface->SendFrameCallback();
+}
+
TEST_P(WaylandSurfaceFactoryTest, Canvas) {
auto canvas = CreateCanvas(widget_);
ASSERT_TRUE(canvas);
canvas->ResizeCanvas(window_->GetBounds().size());
- canvas->GetSurface();
+ auto* sk_canvas = canvas->GetCanvas();
+ DCHECK(sk_canvas);
canvas->PresentCanvas(gfx::Rect(5, 10, 20, 15));
// Wait until the mojo calls are done.
@@ -157,9 +437,11 @@ TEST_P(WaylandSurfaceFactoryTest, CanvasResize) {
ASSERT_TRUE(canvas);
canvas->ResizeCanvas(window_->GetBounds().size());
- canvas->GetSurface();
+ auto* sk_canvas = canvas->GetCanvas();
+ DCHECK(sk_canvas);
canvas->ResizeCanvas(gfx::Size(100, 50));
- canvas->GetSurface();
+ sk_canvas = canvas->GetCanvas();
+ DCHECK(sk_canvas);
canvas->PresentCanvas(gfx::Rect(0, 0, 100, 50));
base::RunLoop().RunUntilIdle();
@@ -192,7 +474,7 @@ TEST_P(WaylandSurfaceFactoryTest, CreateSurfaceCheckGbm) {
EXPECT_FALSE(gl_surface);
// Now, set gbm.
- buffer_manager_gpu_->set_gbm_device(std::make_unique<FakeGbmDevice>());
+ buffer_manager_gpu_->set_gbm_device(std::make_unique<MockGbmDevice>());
gl_surface = gl_ozone->CreateSurfacelessViewGLSurface(widget_);
EXPECT_TRUE(gl_surface);
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h
index c6e36f4e191..a33e0e1f018 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h
@@ -23,12 +23,16 @@ class WaylandSurfaceGpu {
virtual ~WaylandSurfaceGpu() {}
// Tells the surface the result of the last swap of buffer with the
- // |buffer_id|.
+ // |buffer_id|. After this callback, the previously (before |buffer_id|)
+ // submitted buffer may be reused. This is guaranteed to be called
+ // in the same order that buffers were submitted.
virtual void OnSubmission(uint32_t buffer_id,
const gfx::SwapResult& swap_result) = 0;
// Tells the surface the result of the last presentation of buffer with the
- // |buffer_id|.
+ // |buffer_id|. This is guaranteed to be called in the same order that
+ // buffers were submitted, and is guaranteed to be called after the
+ // corresponding call to |OnSubmission| for this buffer.
virtual void OnPresentation(uint32_t buffer_id,
const gfx::PresentationFeedback& feedback) = 0;
};
diff --git a/chromium/ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.cc b/chromium/ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.cc
new file mode 100644
index 00000000000..fef56d4fcc8
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.cc
@@ -0,0 +1,52 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.h"
+
+#include <gdk/gdkwayland.h>
+#include <gtk/gtk.h>
+
+#include "base/logging.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/platform/wayland/host/wayland_connection.h"
+
+namespace ui {
+
+GtkUiDelegateWayland::GtkUiDelegateWayland(WaylandConnection* connection)
+ : connection_(connection) {
+ DCHECK(connection_);
+ gdk_set_allowed_backends("wayland");
+}
+
+GtkUiDelegateWayland::~GtkUiDelegateWayland() = default;
+
+void GtkUiDelegateWayland::OnInitialized() {
+ // Nothing to do upon initialization for Wayland.
+}
+
+GdkKeymap* GtkUiDelegateWayland::GetGdkKeymap() {
+ NOTIMPLEMENTED_LOG_ONCE();
+ return nullptr;
+}
+
+GdkWindow* GtkUiDelegateWayland::GetGdkWindow(
+ gfx::AcceleratedWidget window_id) {
+ NOTIMPLEMENTED_LOG_ONCE();
+ return nullptr;
+}
+
+bool GtkUiDelegateWayland::SetGdkWindowTransientFor(
+ GdkWindow* window,
+ gfx::AcceleratedWidget parent) {
+ NOTIMPLEMENTED_LOG_ONCE();
+ return false;
+}
+
+void GtkUiDelegateWayland::ShowGtkWindow(GtkWindow* window) {
+ // TODO(crbug.com/1008755): Check if gtk_window_present_with_time is needed
+ // here as well, similarly to what is done in X11 impl.
+ gtk_window_present(window);
+}
+
+} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.h b/chromium/ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.h
new file mode 100644
index 00000000000..dd7baf93bf7
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.h
@@ -0,0 +1,36 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_GTK_UI_DELEGATE_WAYLAND_H_
+#define UI_OZONE_PLATFORM_WAYLAND_HOST_GTK_UI_DELEGATE_WAYLAND_H_
+
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gtk/gtk_ui_delegate.h"
+
+namespace ui {
+
+class WaylandConnection;
+
+class GtkUiDelegateWayland : public GtkUiDelegate {
+ public:
+ explicit GtkUiDelegateWayland(WaylandConnection* connection);
+ GtkUiDelegateWayland(const GtkUiDelegateWayland&) = delete;
+ GtkUiDelegateWayland& operator=(const GtkUiDelegateWayland&) = delete;
+ ~GtkUiDelegateWayland() override;
+
+ // GtkUiDelegate:
+ void OnInitialized() override;
+ GdkKeymap* GetGdkKeymap() override;
+ GdkWindow* GetGdkWindow(gfx::AcceleratedWidget window_id) override;
+ bool SetGdkWindowTransientFor(GdkWindow* window,
+ gfx::AcceleratedWidget parent) override;
+ void ShowGtkWindow(GtkWindow* window) override;
+
+ private:
+ WaylandConnection* const connection_;
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_GTK_UI_DELEGATE_WAYLAND_H_
diff --git a/chromium/ui/ozone/platform/wayland/host/shell_object_factory.cc b/chromium/ui/ozone/platform/wayland/host/shell_object_factory.cc
new file mode 100644
index 00000000000..57383be20da
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/shell_object_factory.cc
@@ -0,0 +1,47 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/wayland/host/shell_object_factory.h"
+
+#include "ui/ozone/platform/wayland/host/wayland_connection.h"
+#include "ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h"
+#include "ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h"
+
+namespace ui {
+
+ShellObjectFactory::ShellObjectFactory() = default;
+ShellObjectFactory::~ShellObjectFactory() = default;
+
+std::unique_ptr<ShellSurfaceWrapper>
+ShellObjectFactory::CreateShellSurfaceWrapper(WaylandConnection* connection,
+ WaylandWindow* wayland_window) {
+ if (connection->shell() || connection->shell_v6()) {
+ auto surface =
+ std::make_unique<XDGSurfaceWrapperImpl>(wayland_window, connection);
+ return surface->Initialize(true /* with_top_level */) ? std::move(surface)
+ : nullptr;
+ }
+ LOG(WARNING) << "Shell protocol is not available.";
+ return nullptr;
+}
+
+std::unique_ptr<ShellPopupWrapper> ShellObjectFactory::CreateShellPopupWrapper(
+ WaylandConnection* connection,
+ WaylandWindow* wayland_window,
+ const gfx::Rect& bounds) {
+ if (connection->shell() || connection->shell_v6()) {
+ auto surface =
+ std::make_unique<XDGSurfaceWrapperImpl>(wayland_window, connection);
+ if (!surface->Initialize(false /* with_top_level */))
+ return nullptr;
+
+ auto popup = std::make_unique<XDGPopupWrapperImpl>(std::move(surface),
+ wayland_window);
+ return popup->Initialize(connection, bounds) ? std::move(popup) : nullptr;
+ }
+ LOG(WARNING) << "Shell protocol is not available.";
+ return nullptr;
+}
+
+} // namespace ui \ No newline at end of file
diff --git a/chromium/ui/ozone/platform/wayland/host/shell_object_factory.h b/chromium/ui/ozone/platform/wayland/host/shell_object_factory.h
new file mode 100644
index 00000000000..a915326c23f
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/shell_object_factory.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_SHELL_OBJECT_FACTORY_H_
+#define UI_OZONE_PLATFORM_WAYLAND_HOST_SHELL_OBJECT_FACTORY_H_
+
+#include <memory>
+
+namespace gfx {
+class Rect;
+}
+
+namespace ui {
+
+class ShellSurfaceWrapper;
+class ShellPopupWrapper;
+class WaylandConnection;
+class WaylandWindow;
+
+// Shell factory that creates shell objects for different protocols. Preferred
+// protocols are defined in the following order:
+// 1) xdg-shell-stable-protocol.
+// 2) xdg-shell-v6-unstable-protocol.
+class ShellObjectFactory {
+ public:
+ ShellObjectFactory();
+ ~ShellObjectFactory();
+
+ // Creates and initializes a ShellSurfaceWrapper.
+ std::unique_ptr<ShellSurfaceWrapper> CreateShellSurfaceWrapper(
+ WaylandConnection* connection,
+ WaylandWindow* wayland_window);
+
+ // Creates and intitializes a ShellPopupSurface.
+ std::unique_ptr<ShellPopupWrapper> CreateShellPopupWrapper(
+ WaylandConnection* connection,
+ WaylandWindow* wayland_window,
+ const gfx::Rect& bounds);
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_SHELL_OBJECT_FACTORY_H_ \ No newline at end of file
diff --git a/chromium/ui/ozone/platform/wayland/host/shell_popup_wrapper.h b/chromium/ui/ozone/platform/wayland/host/shell_popup_wrapper.h
index 952c0a2a278..2970549dd09 100644
--- a/chromium/ui/ozone/platform/wayland/host/shell_popup_wrapper.h
+++ b/chromium/ui/ozone/platform/wayland/host/shell_popup_wrapper.h
@@ -10,6 +10,8 @@
namespace ui {
+class WaylandConnection;
+
enum class MenuType {
TYPE_RIGHT_CLICK,
TYPE_3DOT_PARENT_MENU,
@@ -67,6 +69,10 @@ inline WlConstraintAdjustment operator&(WlConstraintAdjustment a,
class ShellPopupWrapper {
public:
virtual ~ShellPopupWrapper() {}
+
+ // Initializes the popup surface.
+ virtual bool Initialize(WaylandConnection* connection,
+ const gfx::Rect& bounds) = 0;
};
gfx::Rect GetAnchorRect(MenuType menu_type,
diff --git a/chromium/ui/ozone/platform/wayland/host/shell_surface_wrapper.h b/chromium/ui/ozone/platform/wayland/host/shell_surface_wrapper.h
index 49b27e4c721..c75e87a627b 100644
--- a/chromium/ui/ozone/platform/wayland/host/shell_surface_wrapper.h
+++ b/chromium/ui/ozone/platform/wayland/host/shell_surface_wrapper.h
@@ -21,6 +21,10 @@ class ShellSurfaceWrapper {
public:
virtual ~ShellSurfaceWrapper() {}
+ // Initializes the ShellSurface. Some protocols may require to create shell
+ // surface without toplevel role and assign a popup role to it later.
+ virtual bool Initialize(bool with_toplevel) = 0;
+
// Sets a native window to maximized state.
virtual void SetMaximized() = 0;
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc b/chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
index 7434e702d24..79495b21a37 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.cc
@@ -12,8 +12,7 @@
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/trace_event.h"
-#include "mojo/public/cpp/system/platform_handle.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
+#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_drm.h"
#include "ui/ozone/platform/wayland/host/wayland_shm.h"
@@ -175,7 +174,7 @@ class WaylandBufferManagerHost::Surface {
void ClearState() {
buffers_.clear();
wl_frame_callback_.reset();
- presentation_feedbacks_ = PresentationFeedbackQueue();
+ feedback_queue_ = PresentationFeedbackQueue();
ResetSurfaceContents();
@@ -212,21 +211,38 @@ class WaylandBufferManagerHost::Surface {
bool HasWindow() const { return !!window_; }
private:
- using PresentationFeedbackQueue = base::queue<
- std::pair<uint32_t, wl::Object<struct wp_presentation_feedback>>>;
+ struct FeedbackInfo {
+ // The wayland object identifying this feedback.
+ wl::Object<struct wp_presentation_feedback> wp_presentation_feedback;
+ // The buffer that this presentation feedback is for.
+ uint32_t buffer_id;
+ // The actual presentation feedback. May be missing if the callback from the
+ // Wayland server has not arrived yet.
+ base::Optional<gfx::PresentationFeedback> feedback;
+ // True iff OnSubmission has been called.
+ bool submission_completed;
+ };
+
+ using PresentationFeedbackQueue = std::vector<FeedbackInfo>;
bool CommitBufferInternal(WaylandBuffer* buffer) {
DCHECK(buffer && window_);
DCHECK(!pending_buffer_);
- // Once the BufferRelease is called, the buffer will be released.
- DCHECK(buffer->released);
- buffer->released = false;
-
DCHECK(!submitted_buffer_);
submitted_buffer_ = buffer;
- AttachAndDamageBuffer(buffer);
+ // if the same buffer has been submitted again right after the client
+ // received OnSubmission for that buffer, just damage the buffer and
+ // commit the surface again.
+ if (prev_submitted_buffer_ != submitted_buffer_) {
+ // Once the BufferRelease is called, the buffer will be released.
+ DCHECK(buffer->released);
+ buffer->released = false;
+ AttachBuffer(buffer);
+ }
+
+ DamageBuffer(buffer);
SetupFrameCallback();
SetupPresentationFeedback(buffer->buffer_id);
@@ -246,13 +262,18 @@ class WaylandBufferManagerHost::Surface {
// If it was the very first frame, the surface has not had a back buffer
// before, and Wayland won't release the front buffer until next buffer is
// attached. Thus, notify about successful submission immediately.
- if (!prev_submitted_buffer_)
+ //
+ // As said above, if the client submits the same buffer again, we must
+ // notify the client about the submission immediately as Wayland compositor
+ // is not going to send a release callback for a buffer committed more than
+ // once.
+ if (!prev_submitted_buffer_ || prev_submitted_buffer_ == submitted_buffer_)
CompleteSubmission();
return true;
}
- void AttachAndDamageBuffer(WaylandBuffer* buffer) {
+ void DamageBuffer(WaylandBuffer* buffer) {
DCHECK(window_);
gfx::Rect pending_damage_region = std::move(buffer->damage_region);
@@ -263,11 +284,41 @@ class WaylandBufferManagerHost::Surface {
pending_damage_region.set_size(buffer->size);
DCHECK(!pending_damage_region.size().IsEmpty());
- auto* surface = window_->surface();
- wl_surface_damage_buffer(
- surface, pending_damage_region.x(), pending_damage_region.y(),
- pending_damage_region.width(), pending_damage_region.height());
- wl_surface_attach(surface, buffer->wl_buffer.get(), 0, 0);
+ if (connection_->compositor_version() >=
+ WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) {
+ // wl_surface_damage_buffer relies on compositor API version 4. See
+ // https://bit.ly/2u00lv6 for details.
+ // We don't need to apply any scaling because pending_damage_region is
+ // already in buffer coordinates.
+ wl_surface_damage_buffer(window_->surface(), pending_damage_region.x(),
+ pending_damage_region.y(),
+ pending_damage_region.width(),
+ pending_damage_region.height());
+ } else {
+ // The calculation for damage region relies on two assumptions:
+ // 1) The buffer is always attached at surface location (0, 0)
+ // 2) The API wl_surface::set_buffer_transform is not used.
+ // It's possible to write logic that accounts for both cases above, but
+ // it's currently unnecessary.
+ //
+ // Note: The damage region may not be an integer multiple of scale. To
+ // keep the implementation simple, the x() and y() coordinates round down,
+ // and the width() and height() calculations always add an extra pixel.
+ int scale = window_->buffer_scale();
+ wl_surface_damage(window_->surface(), pending_damage_region.x() / scale,
+ pending_damage_region.y() / scale,
+ pending_damage_region.width() / scale + 1,
+ pending_damage_region.height() / scale + 1);
+ }
+ }
+
+ void AttachBuffer(WaylandBuffer* buffer) {
+ DCHECK(window_);
+
+ // The logic in DamageBuffer currently relies on attachment coordinates of
+ // (0, 0). If this changes, then the calculation in DamageBuffer will also
+ // need to be updated.
+ wl_surface_attach(window_->surface(), buffer->wl_buffer.get(), 0, 0);
}
void CommitSurface() {
@@ -295,12 +346,14 @@ class WaylandBufferManagerHost::Surface {
&Surface::FeedbackSyncOutput, &Surface::FeedbackPresented,
&Surface::FeedbackDiscarded};
- presentation_feedbacks_.push(std::make_pair(
- buffer_id,
- wl::Object<struct wp_presentation_feedback>(wp_presentation_feedback(
- connection_->presentation(), window_->surface()))));
+ feedback_queue_.push_back(
+ {wl::Object<struct wp_presentation_feedback>(wp_presentation_feedback(
+ connection_->presentation(), window_->surface())),
+ buffer_id, /*feedback=*/base::nullopt,
+ /*submission_completed=*/false});
wp_presentation_feedback_add_listener(
- presentation_feedbacks_.back().second.get(), &feedback_listener, this);
+ feedback_queue_.back().wp_presentation_feedback.get(),
+ &feedback_listener, this);
}
void SetupBufferReleaseListener(WaylandBuffer* buffer) {
@@ -382,11 +435,6 @@ class WaylandBufferManagerHost::Surface {
void CompleteSubmission() {
DCHECK(submitted_buffer_);
auto id = submitted_buffer_->buffer_id;
-
- auto feedback = std::move(submitted_buffer_->feedback);
- bool needs_send_feedback = submitted_buffer_->needs_send_feedback;
- submitted_buffer_->needs_send_feedback = false;
-
prev_submitted_buffer_ = submitted_buffer_;
submitted_buffer_ = nullptr;
@@ -402,30 +450,68 @@ class WaylandBufferManagerHost::Surface {
// If presentation feedback is not supported, use a fake feedback. This
// literally means there are no presentation feedback callbacks created.
if (!connection_->presentation()) {
- DCHECK(presentation_feedbacks_.empty());
- OnPresentation(id, gfx::PresentationFeedback(
- base::TimeTicks::Now(), base::TimeDelta(),
- GetPresentationKindFlags(0)));
- } else if (needs_send_feedback) {
- OnPresentation(id, std::move(feedback));
+ DCHECK(feedback_queue_.empty());
+ buffer_manager_->OnPresentation(
+ window_->GetWidget(), id,
+ gfx::PresentationFeedback(base::TimeTicks::Now(), base::TimeDelta(),
+ GetPresentationKindFlags(0)));
+ } else {
+ for (auto& info : feedback_queue_) {
+ if (info.buffer_id == id && !info.submission_completed) {
+ info.submission_completed = true;
+ ProcessPresentationFeedbacks();
+ return;
+ }
+ }
+ NOTREACHED() << "Did not find matching feedback for buffer_id=" << id;
}
}
- void OnPresentation(uint32_t buffer_id,
+ void OnPresentation(struct wp_presentation_feedback* wp_presentation_feedback,
const gfx::PresentationFeedback& feedback) {
- // The order of submission and presentation callbacks cannot be controlled.
- // Some Wayland compositors may fire presentation callbacks earlier than we
- // are able to send submission callbacks and this is bad. Thus, handle it
- // here.
- if (submitted_buffer_ && submitted_buffer_->buffer_id == buffer_id) {
- submitted_buffer_->needs_send_feedback = true;
- submitted_buffer_->feedback = feedback;
- return;
+ FeedbackInfo* feedback_info = nullptr;
+ for (auto& info : feedback_queue_) {
+ if (info.wp_presentation_feedback.get() == wp_presentation_feedback) {
+ feedback_info = &info;
+ break;
+ } else if (!info.feedback.has_value()) { // Feedback must come in order.
+ info.feedback = gfx::PresentationFeedback::Failure();
+ }
}
+ DCHECK(feedback_info);
+ DCHECK(!feedback_info->feedback.has_value());
+ feedback_info->feedback = feedback;
+
+ ProcessPresentationFeedbacks();
+ }
+
+ // We provide the guarantee to the client that:
+ // 1. OnPresentation and OnSubmission will be called for each submitted buffer
+ // 2. OnPresentation(buffer_id) will be called after OnSubmission(buffer_id)
+ // 3. OnPresentation and OnSubmission will be called in the same order
+ // of buffer submission.
+ // We make the following assumptions about the server:
+ // 1. Presentation feedback will arrive in the same order of submission.
+ // 2. Presentation feedback may never arrive if the buffer is destroyed.
+ // 3. Presentation feedback may arrive at an arbitrary time after commit.
+ // For these reasons, we can't associate feedback with a specific buffer,
+ // as there may be more than one feedback in-flight for a single buffer.
+ // This function ensures that we send OnPresentation for each buffer that
+ // already has had OnSubmission called for it (condition #2).
+ void ProcessPresentationFeedbacks() {
+ if (!window_)
+ return;
- if (window_)
- buffer_manager_->OnPresentation(window_->GetWidget(), buffer_id,
- feedback);
+ while (!feedback_queue_.empty()) {
+ const auto& info = feedback_queue_.front();
+ if (!info.submission_completed || !info.feedback.has_value())
+ break;
+ buffer_manager_->OnPresentation(window_->GetWidget(), info.buffer_id,
+ *info.feedback);
+ feedback_queue_.erase(feedback_queue_.begin());
+ }
+ // This queue should be small - if not it's likely a bug.
+ DCHECK_LE(feedback_queue_.size(), 25u);
}
// wp_presentation_feedback_listener
@@ -446,11 +532,8 @@ class WaylandBufferManagerHost::Surface {
uint32_t flags) {
Surface* self = static_cast<Surface*>(data);
DCHECK(self);
- auto presentation = std::move(self->presentation_feedbacks_.front());
- DCHECK(presentation.second.get() == wp_presentation_feedback);
- self->presentation_feedbacks_.pop();
self->OnPresentation(
- presentation.first,
+ wp_presentation_feedback,
gfx::PresentationFeedback(
GetPresentationFeedbackTimeStamp(tv_sec_hi, tv_sec_lo, tv_nsec),
base::TimeDelta::FromNanoseconds(refresh),
@@ -462,10 +545,7 @@ class WaylandBufferManagerHost::Surface {
struct wp_presentation_feedback* wp_presentation_feedback) {
Surface* self = static_cast<Surface*>(data);
DCHECK(self);
- auto presentation = std::move(self->presentation_feedbacks_.front());
- DCHECK(presentation.second.get() == wp_presentation_feedback);
- self->presentation_feedbacks_.pop();
- self->OnPresentation(presentation.first,
+ self->OnPresentation(wp_presentation_feedback,
gfx::PresentationFeedback::Failure());
}
@@ -500,7 +580,7 @@ class WaylandBufferManagerHost::Surface {
// A presentation feedback provided by the Wayland server once frame is
// shown.
- PresentationFeedbackQueue presentation_feedbacks_;
+ PresentationFeedbackQueue feedback_queue_;
// A buffer, which is pending to be submitted (look the comment in the
// CommitBuffer method).
@@ -598,7 +678,7 @@ void WaylandBufferManagerHost::SetWaylandBufferManagerGpu(
}
void WaylandBufferManagerHost::CreateDmabufBasedBuffer(
- mojo::ScopedHandle dmabuf_fd,
+ mojo::PlatformHandle dmabuf_fd,
const gfx::Size& size,
const std::vector<uint32_t>& strides,
const std::vector<uint32_t>& offsets,
@@ -612,7 +692,7 @@ void WaylandBufferManagerHost::CreateDmabufBasedBuffer(
TRACE_EVENT2("wayland", "WaylandBufferManagerHost::CreateDmabufBasedBuffer",
"Format", format, "Buffer id", buffer_id);
- base::ScopedFD fd = mojo::UnwrapPlatformHandle(std::move(dmabuf_fd)).TakeFD();
+ base::ScopedFD fd = dmabuf_fd.TakeFD();
// Validate data and ask surface to create a buffer associated with the
// |buffer_id|.
@@ -642,7 +722,7 @@ void WaylandBufferManagerHost::CreateDmabufBasedBuffer(
}
}
-void WaylandBufferManagerHost::CreateShmBasedBuffer(mojo::ScopedHandle shm_fd,
+void WaylandBufferManagerHost::CreateShmBasedBuffer(mojo::PlatformHandle shm_fd,
uint64_t length,
const gfx::Size& size,
uint32_t buffer_id) {
@@ -652,7 +732,7 @@ void WaylandBufferManagerHost::CreateShmBasedBuffer(mojo::ScopedHandle shm_fd,
TRACE_EVENT1("wayland", "WaylandBufferManagerHost::CreateShmBasedBuffer",
"Buffer id", buffer_id);
- base::ScopedFD fd = mojo::UnwrapPlatformHandle(std::move(shm_fd)).TakeFD();
+ base::ScopedFD fd = shm_fd.TakeFD();
// Validate data and create a buffer associated with the |buffer_id|.
if (!ValidateDataFromGpu(fd, length, size, buffer_id) ||
!CreateBuffer(size, buffer_id)) {
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h b/chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h
index 1f455154f34..9049a3f5a4f 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h
@@ -65,14 +65,6 @@ struct WaylandBuffer {
// surface can tell the gpu about successful swap.
bool released = true;
- // In some cases, a presentation feedback can come earlier than we fire a
- // submission callback. Thus, instead of sending it immediately to the GPU
- // process, we store it and fire as soon as the submission callback is
- // fired.
- bool needs_send_feedback = false;
-
- gfx::PresentationFeedback feedback;
-
DISALLOW_COPY_AND_ASSIGN(WaylandBuffer);
};
@@ -117,7 +109,7 @@ class WaylandBufferManagerHost : public ozone::mojom::WaylandBufferManagerHost,
// Called by the GPU and asks to import a wl_buffer based on a gbm file
// descriptor using zwp_linux_dmabuf protocol. Check comments in the
// ui/ozone/public/mojom/wayland/wayland_connection.mojom.
- void CreateDmabufBasedBuffer(mojo::ScopedHandle dmabuf_fd,
+ void CreateDmabufBasedBuffer(mojo::PlatformHandle dmabuf_fd,
const gfx::Size& size,
const std::vector<uint32_t>& strides,
const std::vector<uint32_t>& offsets,
@@ -128,7 +120,7 @@ class WaylandBufferManagerHost : public ozone::mojom::WaylandBufferManagerHost,
// Called by the GPU and asks to import a wl_buffer based on a shared memory
// file descriptor using wl_shm protocol. Check comments in the
// ui/ozone/public/mojom/wayland/wayland_connection.mojom.
- void CreateShmBasedBuffer(mojo::ScopedHandle shm_fd,
+ void CreateShmBasedBuffer(mojo::PlatformHandle shm_fd,
uint64_t length,
const gfx::Size& size,
uint32_t buffer_id) override;
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_clipboard.cc b/chromium/ui/ozone/platform/wayland/host/wayland_clipboard.cc
index dd8c23269b1..0191f14247c 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_clipboard.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_clipboard.cc
@@ -4,6 +4,8 @@
#include "ui/ozone/platform/wayland/host/wayland_clipboard.h"
+#include <string>
+
#include "ui/ozone/platform/wayland/host/gtk_primary_selection_device.h"
#include "ui/ozone/platform/wayland/host/gtk_primary_selection_device_manager.h"
#include "ui/ozone/platform/wayland/host/gtk_primary_selection_source.h"
@@ -38,7 +40,7 @@ void WaylandClipboard::OfferClipboardData(
clipboard_data_source_ = data_device_manager_->CreateSource();
data_source = clipboard_data_source_.get();
} else {
- if (!primary_selection_device_manager_) {
+ if (!IsPrimarySelectionSupported()) {
std::move(callback).Run();
return;
}
@@ -66,8 +68,10 @@ void WaylandClipboard::RequestClipboardData(
if (!data_device_->RequestSelectionData(mime_type))
SetData({}, mime_type);
} else {
- if (!primary_selection_device_->RequestSelectionData(mime_type))
+ if (!IsPrimarySelectionSupported() ||
+ !primary_selection_device_->RequestSelectionData(mime_type)) {
SetData({}, mime_type);
+ }
}
}
@@ -91,8 +95,10 @@ void WaylandClipboard::GetAvailableMimeTypes(
if (buffer == ClipboardBuffer::kCopyPaste) {
std::move(callback).Run(data_device_->GetAvailableMimeTypes());
} else {
- DCHECK(primary_selection_device_);
- std::move(callback).Run(primary_selection_device_->GetAvailableMimeTypes());
+ std::move(callback).Run(
+ IsPrimarySelectionSupported()
+ ? primary_selection_device_->GetAvailableMimeTypes()
+ : std::vector<std::string>{});
}
}
@@ -128,4 +134,8 @@ void WaylandClipboard::UpdateSequenceNumber(ClipboardBuffer buffer) {
update_sequence_cb_.Run(buffer);
}
+bool WaylandClipboard::IsPrimarySelectionSupported() const {
+ return primary_selection_device_manager_ && primary_selection_device_;
+}
+
} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_clipboard.h b/chromium/ui/ozone/platform/wayland/host/wayland_clipboard.h
index cd95b60ec74..a4482490071 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_clipboard.h
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_clipboard.h
@@ -57,6 +57,8 @@ class WaylandClipboard : public PlatformClipboard {
void UpdateSequenceNumber(ClipboardBuffer buffer);
private:
+ bool IsPrimarySelectionSupported() const;
+
// Holds a temporary instance of the client's clipboard content
// so that we can asynchronously write to it.
PlatformClipboard::DataMap* data_map_ = nullptr;
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_connection.cc b/chromium/ui/ozone/platform/wayland/host/wayland_connection.cc
index bb0ab87a01d..21590d85a26 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_connection.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_connection.cc
@@ -83,15 +83,16 @@ bool WaylandConnection::Initialize() {
LOG(ERROR) << "No wl_shm object";
return false;
}
- if (!seat_) {
- LOG(ERROR) << "No wl_seat object";
- return false;
- }
if (!shell_v6_ && !shell_) {
LOG(ERROR) << "No Wayland shell found";
return false;
}
+ // When we are running tests with weston in headless mode, the seat is not
+ // announced.
+ if (!seat_)
+ LOG(WARNING) << "No wl_seat object. The functionality may suffer.";
+
return true;
}
@@ -122,13 +123,17 @@ void WaylandConnection::MaybePrepareReadQueue() {
}
void WaylandConnection::ScheduleFlush() {
- if (scheduled_flush_)
- return;
- DCHECK(base::MessageLoopCurrentForUI::IsSet());
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&WaylandConnection::Flush, base::Unretained(this)));
- scheduled_flush_ = true;
+ // When we are in tests, the message loop is set later when the
+ // initialization of the OzonePlatform complete. Thus, just
+ // flush directly. This doesn't happen in normal run.
+ if (!base::MessageLoopCurrentForUI::IsSet()) {
+ Flush();
+ } else if (!scheduled_flush_) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&WaylandConnection::Flush, base::Unretained(this)));
+ scheduled_flush_ = true;
+ }
}
void WaylandConnection::SetCursorBitmap(const std::vector<SkBitmap>& bitmaps,
@@ -174,6 +179,9 @@ void WaylandConnection::RequestDragData(
}
bool WaylandConnection::IsDragInProgress() {
+ // |data_device_| can be null when running on headless weston.
+ if (!data_device_)
+ return false;
return data_device_->IsDragEntered() || drag_data_source();
}
@@ -281,6 +289,7 @@ void WaylandConnection::Global(void* data,
if (!connection->compositor_ && strcmp(interface, "wl_compositor") == 0) {
connection->compositor_ = wl::Bind<wl_compositor>(
registry, name, std::min(version, kMaxCompositorVersion));
+ connection->compositor_version_ = version;
if (!connection->compositor_)
LOG(ERROR) << "Failed to bind to wl_compositor global";
} else if (!connection->subcompositor_ &&
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_connection.h b/chromium/ui/ozone/platform/wayland/host/wayland_connection.h
index d6a985fc0fe..9adc5be026a 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_connection.h
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_connection.h
@@ -52,6 +52,7 @@ class WaylandConnection : public PlatformEventSource,
wl_display* display() const { return display_.get(); }
wl_compositor* compositor() const { return compositor_.get(); }
+ uint32_t compositor_version() const { return compositor_version_; }
wl_subcompositor* subcompositor() const { return subcompositor_.get(); }
xdg_wm_base* shell() const { return shell_.get(); }
zxdg_shell_v6* shell_v6() const { return shell_v6_.get(); }
@@ -108,6 +109,8 @@ class WaylandConnection : public PlatformEventSource,
return &wayland_window_manager_;
}
+ WaylandDataDevice* wayland_data_device() const { return data_device_.get(); }
+
// Starts drag with |data| to be delivered, |operation| supported by the
// source side initiated the dragging.
void StartDrag(const ui::OSExchangeData& data, int operation);
@@ -177,6 +180,7 @@ class WaylandConnection : public PlatformEventSource,
wl::Object<wl_display> display_;
wl::Object<wl_registry> registry_;
wl::Object<wl_compositor> compositor_;
+ uint32_t compositor_version_ = 0;
wl::Object<wl_subcompositor> subcompositor_;
wl::Object<wl_seat> seat_;
wl::Object<xdg_wm_base> shell_;
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_cursor.cc b/chromium/ui/ozone/platform/wayland/host/wayland_cursor.cc
index 85b16dc3c68..3e0fc6562a7 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_cursor.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_cursor.cc
@@ -35,6 +35,8 @@ void WaylandCursor::Init(wl_pointer* pointer, WaylandConnection* connection) {
shm_ = connection->shm();
pointer_surface_.reset(
wl_compositor_create_surface(connection->compositor()));
+
+ connection_ = connection;
}
void WaylandCursor::UpdateBitmap(const std::vector<SkBitmap>& cursor_image,
@@ -79,6 +81,11 @@ void WaylandCursor::UpdateBitmap(const std::vector<SkBitmap>& cursor_image,
void WaylandCursor::HideCursor(uint32_t serial) {
DCHECK(input_pointer_);
wl_pointer_set_cursor(input_pointer_, serial, nullptr, 0, 0);
+
+ wl_surface_attach(pointer_surface_.get(), nullptr, 0, 0);
+ wl_surface_commit(pointer_surface_.get());
+
+ connection_->ScheduleFlush();
}
} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_cursor.h b/chromium/ui/ozone/platform/wayland/host/wayland_cursor.h
index c2890f96e7a..2d53782ed68 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_cursor.h
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_cursor.h
@@ -57,6 +57,7 @@ class WaylandCursor {
WaylandShm* shm_ = nullptr; // Owned by WaylandConnection.
wl_pointer* input_pointer_ = nullptr; // Owned by WaylandPointer.
+ WaylandConnection* connection_ = nullptr;
// Holds the buffers and their memory until the compositor releases them.
base::flat_map<wl_buffer*, WaylandShmBuffer> buffers_;
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_data_device.cc b/chromium/ui/ozone/platform/wayland/host/wayland_data_device.cc
index 20a347a592b..4c5008dd42b 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_data_device.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_data_device.cc
@@ -15,7 +15,7 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/dragdrop/drag_drop_types.h"
-#include "ui/base/dragdrop/file_info.h"
+#include "ui/base/dragdrop/file_info/file_info.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
#include "ui/ozone/platform/wayland/common/wayland_util.h"
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_data_device.h b/chromium/ui/ozone/platform/wayland/host/wayland_data_device.h
index 0bd746513c3..3f4ade9c4ea 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_data_device.h
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_data_device.h
@@ -58,6 +58,8 @@ class WaylandDataDevice : public internal::WaylandDataDeviceBase {
bool IsDragEntered() { return drag_offer_ != nullptr; }
+ WaylandWindow* entered_window() const { return window_; }
+
private:
void ReadDragDataFromFD(
base::ScopedFD fd,
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc b/chromium/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc
index 6ffe6a94b3e..cfd1eca7b26 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_data_device_unittest.cc
@@ -15,7 +15,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/clipboard/clipboard_constants.h"
#include "ui/base/dragdrop/drag_drop_types.h"
-#include "ui/base/dragdrop/file_info.h"
+#include "ui/base/dragdrop/file_info/file_info.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/events/base_event_utils.h"
#include "ui/ozone/platform/wayland/test/constants.h"
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_drm.cc b/chromium/ui/ozone/platform/wayland/host/wayland_drm.cc
index 7b551543430..12a91eed83a 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_drm.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_drm.cc
@@ -9,7 +9,7 @@
#include "base/files/scoped_file.h"
#include "ui/gfx/buffer_format_util.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
+#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_drm.h"
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_input_method_context.cc b/chromium/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
index 37feebecc9d..81a75d4661a 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_input_method_context.cc
@@ -90,9 +90,9 @@ void WaylandInputMethodContext::UpdatePreeditText(
auto length = preedit.text.size();
preedit.selection = gfx::Range(length);
- preedit.ime_text_spans.push_back(
- ImeTextSpan(ImeTextSpan::Type::kComposition, 0, length,
- ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT));
+ preedit.ime_text_spans.push_back(ImeTextSpan(
+ ImeTextSpan::Type::kComposition, 0, length, ImeTextSpan::Thickness::kThin,
+ ImeTextSpan::UnderlineStyle::kSolid, SK_ColorTRANSPARENT));
delegate_->OnPreeditChanged(preedit);
}
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc b/chromium/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
index 08b2ddb20a5..09936ef8d2f 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_input_method_context_unittest.cc
@@ -6,7 +6,6 @@
#include <wayland-server.h>
#include <memory>
-#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/linux/linux_input_method_context.h"
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_keyboard.cc b/chromium/ui/ozone/platform/wayland/host/wayland_keyboard.cc
index fbadb0e3b1e..7da3270a9e3 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_keyboard.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_keyboard.cc
@@ -125,7 +125,7 @@ void WaylandKeyboard::Key(void* data,
// TODO(tonikitoo,msisov): Handler 'repeat' parameter below.
keyboard->DispatchKey(key, down, false /*repeat*/, EventTimeForNow(),
- device_id);
+ device_id, EF_NONE);
}
void WaylandKeyboard::Modifiers(void* data,
@@ -174,7 +174,8 @@ void WaylandKeyboard::DispatchKey(uint32_t key,
bool down,
bool repeat,
base::TimeTicks timestamp,
- int device_id) {
+ int device_id,
+ int flags) {
DomCode dom_code =
KeycodeConverter::NativeKeycodeToDomCode(EvdevCodeToNativeCode(key));
if (dom_code == ui::DomCode::NONE)
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_keyboard.h b/chromium/ui/ozone/platform/wayland/host/wayland_keyboard.h
index 1e5fd7a4038..497a95506b1 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_keyboard.h
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_keyboard.h
@@ -77,7 +77,8 @@ class WaylandKeyboard : public EventAutoRepeatHandler::Delegate {
bool down,
bool repeat,
base::TimeTicks timestamp,
- int device_id) override;
+ int device_id,
+ int flags) override;
WaylandConnection* connection_ = nullptr;
wl::Object<wl_keyboard> obj_;
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_pointer.cc b/chromium/ui/ozone/platform/wayland/host/wayland_pointer.cc
index 4731b684565..c1620cedac0 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_pointer.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_pointer.cc
@@ -117,9 +117,11 @@ void WaylandPointer::Button(void* data,
changed_button = EF_RIGHT_MOUSE_BUTTON;
break;
case BTN_BACK:
+ case BTN_SIDE:
changed_button = EF_BACK_MOUSE_BUTTON;
break;
case BTN_FORWARD:
+ case BTN_EXTRA:
changed_button = EF_FORWARD_MOUSE_BUTTON;
break;
default:
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc b/chromium/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
index be9cd942d6e..b96f2e6f73f 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_pointer_unittest.cc
@@ -72,14 +72,15 @@ TEST_P(WaylandPointerTest, Enter) {
TEST_P(WaylandPointerTest, Leave) {
MockPlatformWindowDelegate other_delegate;
- WaylandWindow other_window(&other_delegate, connection_.get());
gfx::AcceleratedWidget other_widget = gfx::kNullAcceleratedWidget;
EXPECT_CALL(other_delegate, OnAcceleratedWidgetAvailable(_))
.WillOnce(SaveArg<0>(&other_widget));
+
PlatformWindowInitProperties properties;
properties.bounds = gfx::Rect(0, 0, 10, 10);
properties.type = PlatformWindowType::kWindow;
- ASSERT_TRUE(other_window.Initialize(std::move(properties)));
+ auto other_window = WaylandWindow::Create(&other_delegate, connection_.get(),
+ std::move(properties));
ASSERT_NE(other_widget, gfx::kNullAcceleratedWidget);
Sync();
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_popup.cc b/chromium/ui/ozone/platform/wayland/host/wayland_popup.cc
new file mode 100644
index 00000000000..dd9e6c268ab
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_popup.cc
@@ -0,0 +1,202 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/wayland/host/wayland_popup.h"
+
+#include "ui/ozone/platform/wayland/common/wayland_util.h"
+#include "ui/ozone/platform/wayland/host/shell_object_factory.h"
+#include "ui/ozone/platform/wayland/host/shell_popup_wrapper.h"
+#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h"
+#include "ui/ozone/platform/wayland/host/wayland_connection.h"
+
+namespace ui {
+
+WaylandPopup::WaylandPopup(PlatformWindowDelegate* delegate,
+ WaylandConnection* connection)
+ : WaylandWindow(delegate, connection) {}
+
+WaylandPopup::~WaylandPopup() = default;
+
+bool WaylandPopup::CreateShellPopup() {
+ if (GetBounds().IsEmpty())
+ return false;
+
+ DCHECK(parent_window() && !shell_popup_);
+
+ auto bounds_px = AdjustPopupWindowPosition();
+
+ ShellObjectFactory factory;
+ shell_popup_ = factory.CreateShellPopupWrapper(connection(), this, bounds_px);
+ if (!shell_popup_) {
+ LOG(ERROR) << "Failed to create Wayland shell popup";
+ return false;
+ }
+
+ parent_window()->set_child_window(this);
+ return true;
+}
+
+void WaylandPopup::Show(bool inactive) {
+ if (shell_popup_)
+ return;
+
+ set_keyboard_focus(true);
+
+ if (!CreateShellPopup()) {
+ Close();
+ return;
+ }
+
+ UpdateBufferScale(false);
+ connection()->ScheduleFlush();
+}
+
+void WaylandPopup::Hide() {
+ if (!shell_popup_)
+ return;
+
+ if (child_window())
+ child_window()->Hide();
+
+ if (shell_popup_) {
+ parent_window()->set_child_window(nullptr);
+ shell_popup_.reset();
+ }
+
+ // Detach buffer from surface in order to completely shutdown popups and
+ // tooltips, and release resources.
+ connection()->buffer_manager_host()->ResetSurfaceContents(GetWidget());
+}
+
+bool WaylandPopup::IsVisible() const {
+ return !!shell_popup_;
+}
+
+bool WaylandPopup::HasCapture() const {
+ // WaylandPopups always have captures.
+ return shell_popup();
+}
+
+void WaylandPopup::HandlePopupConfigure(const gfx::Rect& bounds_dip) {
+ DCHECK(shell_popup());
+ DCHECK(parent_window());
+
+ SetBufferScale(parent_window()->buffer_scale(), true);
+
+ gfx::Rect new_bounds_dip = bounds_dip;
+
+ // It's not enough to just set new bounds. If it is a menu window, whose
+ // parent is a top level window a.k.a browser window, it can be flipped
+ // vertically along y-axis and have negative values set. Chromium cannot
+ // understand that and starts to position nested menu windows incorrectly. To
+ // fix that, we have to bear in mind that Wayland compositor does not share
+ // global coordinates for any surfaces, and Chromium assumes the top level
+ // window is always located at 0,0 origin. What is more, child windows must
+ // always be positioned relative to parent window local surface coordinates.
+ // Thus, if the menu window is flipped along y-axis by Wayland and its origin
+ // is above the top level parent window, the origin of the top level window
+ // has to be shifted by that value on y-axis so that the origin of the menu
+ // becomes x,0, and events can be handled normally.
+ if (!wl::IsMenuType(parent_window()->type())) {
+ gfx::Rect parent_bounds = parent_window()->GetBounds();
+ // The menu window is flipped along y-axis and have x,-y origin. Shift the
+ // parent top level window instead.
+ if (new_bounds_dip.y() < 0) {
+ // Move parent bounds along y-axis.
+ parent_bounds.set_y(-(new_bounds_dip.y() * buffer_scale()));
+ new_bounds_dip.set_y(0);
+ } else {
+ // If the menu window is located at correct origin from the browser point
+ // of view, return the top level window back to 0,0.
+ parent_bounds.set_y(0);
+ }
+ parent_window()->SetBounds(parent_bounds);
+ } else {
+ // The nested menu windows are located relative to the parent menu windows.
+ // Thus, the location must be translated to be relative to the top level
+ // window, which automatically becomes the same as relative to an origin of
+ // a display.
+ new_bounds_dip = gfx::ScaleToRoundedRect(
+ wl::TranslateBoundsToTopLevelCoordinates(
+ gfx::ScaleToRoundedRect(new_bounds_dip, buffer_scale()),
+ parent_window()->GetBounds()),
+ 1.0 / buffer_scale());
+ DCHECK(new_bounds_dip.y() >= 0);
+ }
+
+ SetBoundsDip(new_bounds_dip);
+}
+
+void WaylandPopup::OnCloseRequest() {
+ // Before calling OnCloseRequest, the |shell_popup_| must become hidden and
+ // only then call OnCloseRequest().
+ DCHECK(!shell_popup_);
+ WaylandWindow::OnCloseRequest();
+}
+
+bool WaylandPopup::OnInitialize(PlatformWindowInitProperties properties) {
+ if (!wl::IsMenuType(type()))
+ return false;
+
+ set_parent_window(GetParentWindow(properties.parent_widget));
+ if (!parent_window()) {
+ LOG(ERROR) << "Failed to get a parent window for this popup";
+ return false;
+ }
+ // If parent window is known in advanced, we may set the scale early.
+ SetBufferScale(parent_window()->buffer_scale(), false);
+ set_ui_scale(parent_window()->ui_scale());
+ return true;
+}
+
+gfx::Rect WaylandPopup::AdjustPopupWindowPosition() {
+ auto* top_level_parent = wl::IsMenuType(parent_window()->type())
+ ? parent_window()->parent_window()
+ : parent_window();
+ DCHECK(top_level_parent);
+ DCHECK(buffer_scale() == top_level_parent->buffer_scale());
+ DCHECK(ui_scale() == top_level_parent->ui_scale());
+
+ // Chromium positions windows in screen coordinates, but Wayland requires them
+ // to be in local surface coordinates a.k.a relative to parent window.
+ const gfx::Rect parent_bounds_dip =
+ gfx::ScaleToRoundedRect(parent_window()->GetBounds(), 1.0 / ui_scale());
+ gfx::Rect new_bounds_dip = wl::TranslateBoundsToParentCoordinates(
+ gfx::ScaleToRoundedRect(GetBounds(), 1.0 / ui_scale()),
+ parent_bounds_dip);
+
+ // Chromium may decide to position nested menu windows on the left side
+ // instead of the right side of parent menu windows when the size of the
+ // window becomes larger than the display it is shown on. It's correct when
+ // the window is located on one display and occupies the whole work area, but
+ // as soon as it's moved and there is space on the right side, Chromium
+ // continues positioning the nested menus on the left side relative to the
+ // parent menu (Wayland does not provide clients with global coordinates).
+ // Instead, reposition that window to be on the right side of the parent menu
+ // window and let the compositor decide how to position it if it does not fit
+ // a single display. However, there is one exception - if the window is
+ // maximized, let Chromium position it on the left side as long as the Wayland
+ // compositor may decide to position the nested window on the right side of
+ // the parent menu window, which results in showing it on a second display if
+ // more than one display is used.
+ if (wl::IsMenuType(parent_window()->type()) &&
+ parent_window()->parent_window() &&
+ (parent_window()->parent_window()->GetPlatformWindowState() !=
+ PlatformWindowState::kMaximized)) {
+ auto* top_level_window = parent_window()->parent_window();
+ DCHECK(top_level_window && !wl::IsMenuType(top_level_window->type()));
+ if (new_bounds_dip.x() <= 0 && top_level_window->GetPlatformWindowState() !=
+ PlatformWindowState::kMaximized) {
+ // Position the child menu window on the right side of the parent window
+ // and let the Wayland compositor decide how to do constraint
+ // adjustments.
+ int new_x = parent_bounds_dip.width() -
+ (new_bounds_dip.width() + new_bounds_dip.x());
+ new_bounds_dip.set_x(new_x);
+ }
+ }
+ return gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale() / buffer_scale());
+}
+
+} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_popup.h b/chromium/ui/ozone/platform/wayland/host/wayland_popup.h
new file mode 100644
index 00000000000..7bc48bb29a0
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_popup.h
@@ -0,0 +1,49 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_POPUP_H_
+#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_POPUP_H_
+
+#include "ui/ozone/platform/wayland/host/wayland_window.h"
+
+namespace ui {
+
+class WaylandConnection;
+class ShellPopupWrapper;
+
+class WaylandPopup : public WaylandWindow {
+ public:
+ WaylandPopup(PlatformWindowDelegate* delegate, WaylandConnection* connection);
+ ~WaylandPopup() override;
+
+ ShellPopupWrapper* shell_popup() const { return shell_popup_.get(); }
+
+ // PlatformWindow
+ void Show(bool inactive) override;
+ void Hide() override;
+ bool IsVisible() const override;
+ bool HasCapture() const override;
+
+ private:
+ // WaylandWindow overrides:
+ void HandlePopupConfigure(const gfx::Rect& bounds) override;
+ void OnCloseRequest() override;
+ bool OnInitialize(PlatformWindowInitProperties properties) override;
+
+ // Creates a popup window, which is visible as a menu window.
+ bool CreateShellPopup();
+
+ // Returns bounds with origin relative to parent window's origin.
+ gfx::Rect AdjustPopupWindowPosition();
+
+ // Wrappers around xdg v5 and xdg v6 objects. WaylandPopup doesn't
+ // know anything about the version.
+ std::unique_ptr<ShellPopupWrapper> shell_popup_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandPopup);
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_POPUP_H_
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc b/chromium/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
index e1e3cc823ac..9198aa88e05 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_screen_unittest.cc
@@ -89,13 +89,12 @@ class WaylandScreenTest : public WaylandTest {
PlatformWindowType window_type,
gfx::AcceleratedWidget parent_widget,
MockPlatformWindowDelegate* delegate) {
- auto window = std::make_unique<WaylandWindow>(delegate, connection_.get());
PlatformWindowInitProperties properties;
properties.bounds = bounds;
properties.type = window_type;
properties.parent_widget = parent_widget;
- EXPECT_TRUE(window->Initialize(std::move(properties)));
- return window;
+ return WaylandWindow::Create(delegate, connection_.get(),
+ std::move(properties));
}
void UpdateOutputGeometry(wl_resource* output_resource,
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_subsurface.cc b/chromium/ui/ozone/platform/wayland/host/wayland_subsurface.cc
new file mode 100644
index 00000000000..28f435f39de
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_subsurface.cc
@@ -0,0 +1,130 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/wayland/host/wayland_subsurface.h"
+
+#include "ui/ozone/platform/wayland/common/wayland_util.h"
+#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h"
+#include "ui/ozone/platform/wayland/host/wayland_connection.h"
+#include "ui/ozone/platform/wayland/host/wayland_window_manager.h"
+
+namespace ui {
+
+namespace {
+
+gfx::Rect AdjustSubsurfaceBounds(const gfx::Rect& bounds_px,
+ const gfx::Rect& parent_bounds_px,
+ int32_t ui_scale,
+ int32_t buffer_scale) {
+ const auto parent_bounds_dip =
+ gfx::ScaleToRoundedRect(parent_bounds_px, 1.0 / ui_scale);
+ auto new_bounds_dip =
+ wl::TranslateBoundsToParentCoordinates(bounds_px, parent_bounds_dip);
+ return gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale / buffer_scale);
+}
+
+} // namespace
+
+WaylandSubsurface::WaylandSubsurface(PlatformWindowDelegate* delegate,
+ WaylandConnection* connection)
+ : WaylandWindow(delegate, connection) {}
+
+WaylandSubsurface::~WaylandSubsurface() = default;
+
+void WaylandSubsurface::Show(bool inactive) {
+ if (subsurface_)
+ return;
+
+ CreateSubsurface();
+ UpdateBufferScale(false);
+}
+
+void WaylandSubsurface::Hide() {
+ if (!subsurface_)
+ return;
+
+ subsurface_.reset();
+
+ // Detach buffer from surface in order to completely shutdown menus and
+ // tooltips, and release resources.
+ connection()->buffer_manager_host()->ResetSurfaceContents(GetWidget());
+}
+
+bool WaylandSubsurface::IsVisible() const {
+ return !!subsurface_;
+}
+
+void WaylandSubsurface::SetBounds(const gfx::Rect& bounds) {
+ auto old_bounds = GetBounds();
+ WaylandWindow::SetBounds(bounds);
+
+ if (old_bounds == bounds || !parent_window())
+ return;
+
+ // Translate location from screen to surface coordinates.
+ auto bounds_px = AdjustSubsurfaceBounds(
+ GetBounds(), parent_window()->GetBounds(), ui_scale(), buffer_scale());
+ wl_subsurface_set_position(subsurface_.get(), bounds_px.x() / buffer_scale(),
+ bounds_px.y() / buffer_scale());
+ wl_surface_commit(surface());
+ connection()->ScheduleFlush();
+}
+
+void WaylandSubsurface::CreateSubsurface() {
+ auto* parent = parent_window();
+ if (!parent) {
+ // wl_subsurface can be used for several purposes: tooltips and drag arrow
+ // windows. If we are in a drag process, use the entered window. Otherwise,
+ // it must be a tooltip.
+ if (connection()->IsDragInProgress()) {
+ parent = connection()->wayland_data_device()->entered_window();
+ set_parent_window(parent);
+ } else {
+ // If Aura does not not provide a reference parent window, needed by
+ // Wayland, we get the current focused window to place and show the
+ // tooltips.
+ parent =
+ connection()->wayland_window_manager()->GetCurrentFocusedWindow();
+ }
+ }
+
+ // Tooltip and drag arrow creation is an async operation. By the time Aura
+ // actually creates them, it is possible that the user has already moved the
+ // mouse/pointer out of the window that triggered the tooltip, or user is no
+ // longer in a drag/drop process. In this case, parent is NULL.
+ if (!parent)
+ return;
+
+ wl_subcompositor* subcompositor = connection()->subcompositor();
+ DCHECK(subcompositor);
+ subsurface_.reset(wl_subcompositor_get_subsurface(subcompositor, surface(),
+ parent->surface()));
+
+ // Chromium positions tooltip windows in screen coordinates, but Wayland
+ // requires them to be in local surface coordinates a.k.a relative to parent
+ // window.
+ auto bounds_px = AdjustSubsurfaceBounds(GetBounds(), parent->GetBounds(),
+ ui_scale(), buffer_scale());
+
+ DCHECK(subsurface_);
+ // Convert position to DIP.
+ wl_subsurface_set_position(subsurface_.get(), bounds_px.x() / buffer_scale(),
+ bounds_px.y() / buffer_scale());
+ wl_subsurface_set_desync(subsurface_.get());
+ wl_surface_commit(parent->surface());
+ connection()->ScheduleFlush();
+}
+
+bool WaylandSubsurface::OnInitialize(PlatformWindowInitProperties properties) {
+ // If we do not have parent window provided, we must always use a focused
+ // window or a window that entered drag whenever the subsurface is created.
+ if (properties.parent_widget == gfx::kNullAcceleratedWidget) {
+ DCHECK(!parent_window());
+ return true;
+ }
+ set_parent_window(GetParentWindow(properties.parent_widget));
+ return true;
+}
+
+} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_subsurface.h b/chromium/ui/ozone/platform/wayland/host/wayland_subsurface.h
new file mode 100644
index 00000000000..e5c8bed26f8
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_subsurface.h
@@ -0,0 +1,38 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_
+#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_
+
+#include "ui/ozone/platform/wayland/host/wayland_window.h"
+
+namespace ui {
+
+class WaylandSubsurface : public WaylandWindow {
+ public:
+ WaylandSubsurface(PlatformWindowDelegate* delegate,
+ WaylandConnection* connection);
+ ~WaylandSubsurface() override;
+
+ // PlatformWindow overrides:
+ void Show(bool inactive) override;
+ void Hide() override;
+ bool IsVisible() const override;
+ void SetBounds(const gfx::Rect& bounds) override;
+
+ private:
+ // WaylandWindow overrides:
+ bool OnInitialize(PlatformWindowInitProperties properties) override;
+
+ // Creates (if necessary) and shows a subsurface window.
+ void CreateSubsurface();
+
+ wl::Object<wl_subsurface> subsurface_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandSubsurface);
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SUBSURFACE_H_
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_surface.cc b/chromium/ui/ozone/platform/wayland/host/wayland_surface.cc
new file mode 100644
index 00000000000..bc45f677a75
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_surface.cc
@@ -0,0 +1,353 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/wayland/host/wayland_surface.h"
+
+#include "ui/base/dragdrop/drag_drop_types.h"
+#include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/hit_test.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/platform/wayland/host/shell_object_factory.h"
+#include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h"
+#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h"
+#include "ui/ozone/platform/wayland/host/wayland_connection.h"
+#include "ui/platform_window/platform_window_handler/wm_drop_handler.h"
+
+namespace ui {
+
+WaylandSurface::WaylandSurface(PlatformWindowDelegate* delegate,
+ WaylandConnection* connection)
+ : WaylandWindow(delegate, connection),
+ state_(PlatformWindowState::kNormal) {
+ // Set a class property key, which allows |this| to be used for interactive
+ // events, e.g. move or resize.
+ SetWmMoveResizeHandler(this, AsWmMoveResizeHandler());
+
+ // Set a class property key, which allows |this| to be used for drag action.
+ SetWmDragHandler(this, this);
+}
+
+WaylandSurface::~WaylandSurface() {
+ if (drag_closed_callback_) {
+ std::move(drag_closed_callback_)
+ .Run(DragDropTypes::DragOperation::DRAG_NONE);
+ }
+}
+
+bool WaylandSurface::CreateShellSurface() {
+ ShellObjectFactory factory;
+ shell_surface_ = factory.CreateShellSurfaceWrapper(connection(), this);
+ if (!shell_surface_) {
+ LOG(ERROR) << "Failed to create a ShellSurface.";
+ return false;
+ }
+
+ shell_surface_->SetAppId(app_id_);
+ shell_surface_->SetTitle(window_title_);
+ SetSizeConstraints();
+ TriggerStateChanges();
+ return true;
+}
+
+void WaylandSurface::ApplyPendingBounds() {
+ if (pending_bounds_dip_.IsEmpty())
+ return;
+ DCHECK(shell_surface_);
+
+ SetBoundsDip(pending_bounds_dip_);
+ shell_surface_->SetWindowGeometry(pending_bounds_dip_);
+ pending_bounds_dip_ = gfx::Rect();
+ connection()->ScheduleFlush();
+}
+
+void WaylandSurface::DispatchHostWindowDragMovement(
+ int hittest,
+ const gfx::Point& pointer_location_in_px) {
+ DCHECK(shell_surface_);
+
+ connection()->ResetPointerFlags();
+ if (hittest == HTCAPTION)
+ shell_surface_->SurfaceMove(connection());
+ else
+ shell_surface_->SurfaceResize(connection(), hittest);
+
+ connection()->ScheduleFlush();
+}
+
+void WaylandSurface::StartDrag(const ui::OSExchangeData& data,
+ int operation,
+ gfx::NativeCursor cursor,
+ base::OnceCallback<void(int)> callback) {
+ DCHECK(!drag_closed_callback_);
+ drag_closed_callback_ = std::move(callback);
+ connection()->StartDrag(data, operation);
+}
+
+void WaylandSurface::Show(bool inactive) {
+ if (shell_surface_)
+ return;
+
+ if (!CreateShellSurface()) {
+ Close();
+ return;
+ }
+
+ set_keyboard_focus(true);
+ UpdateBufferScale(false);
+}
+
+void WaylandSurface::Hide() {
+ if (!shell_surface_)
+ return;
+
+ if (child_window()) {
+ child_window()->Hide();
+ set_child_window(nullptr);
+ }
+
+ shell_surface_.reset();
+ connection()->ScheduleFlush();
+
+ // Detach buffer from surface in order to completely shutdown menus and
+ // tooltips, and release resources.
+ connection()->buffer_manager_host()->ResetSurfaceContents(GetWidget());
+}
+
+bool WaylandSurface::IsVisible() const {
+ // X and Windows return true if the window is minimized. For consistency, do
+ // the same.
+ return !!shell_surface_ || state_ == PlatformWindowState::kMinimized;
+}
+
+void WaylandSurface::SetTitle(const base::string16& title) {
+ if (window_title_ == title)
+ return;
+
+ window_title_ = title;
+
+ if (shell_surface_) {
+ shell_surface_->SetTitle(title);
+ connection()->ScheduleFlush();
+ }
+}
+
+void WaylandSurface::ToggleFullscreen() {
+ // TODO(msisov, tonikitoo): add multiscreen support. As the documentation says
+ // if xdg_toplevel_set_fullscreen() is not provided with wl_output, it's up
+ // to the compositor to choose which display will be used to map this surface.
+
+ // We must track the previous state to correctly say our state as long as it
+ // can be the maximized instead of normal one.
+ PlatformWindowState new_state = PlatformWindowState::kUnknown;
+ if (state_ == PlatformWindowState::kFullScreen) {
+ if (previous_state_ == PlatformWindowState::kMaximized)
+ new_state = previous_state_;
+ else
+ new_state = PlatformWindowState::kNormal;
+ } else {
+ new_state = PlatformWindowState::kFullScreen;
+ }
+
+ SetWindowState(new_state);
+}
+
+void WaylandSurface::Maximize() {
+ SetWindowState(PlatformWindowState::kMaximized);
+}
+
+void WaylandSurface::Minimize() {
+ SetWindowState(PlatformWindowState::kMinimized);
+}
+
+void WaylandSurface::Restore() {
+ DCHECK(shell_surface_);
+ SetWindowState(PlatformWindowState::kNormal);
+}
+
+PlatformWindowState WaylandSurface::GetPlatformWindowState() const {
+ return state_;
+}
+
+void WaylandSurface::SizeConstraintsChanged() {
+ // Size constraints only make sense for normal windows.
+ if (!shell_surface_)
+ return;
+
+ DCHECK(delegate());
+ min_size_ = delegate()->GetMinimumSizeForWindow();
+ max_size_ = delegate()->GetMaximumSizeForWindow();
+ SetSizeConstraints();
+}
+
+void WaylandSurface::HandleSurfaceConfigure(int32_t width,
+ int32_t height,
+ bool is_maximized,
+ bool is_fullscreen,
+ bool is_activated) {
+ // Store the old state to propagte state changes if Wayland decides to change
+ // the state to something else.
+ PlatformWindowState old_state = state_;
+ if (state_ == PlatformWindowState::kMinimized && !is_activated) {
+ state_ = PlatformWindowState::kMinimized;
+ } else if (is_fullscreen) {
+ state_ = PlatformWindowState::kFullScreen;
+ } else if (is_maximized) {
+ state_ = PlatformWindowState::kMaximized;
+ } else {
+ state_ = PlatformWindowState::kNormal;
+ }
+
+ const bool state_changed = old_state != state_;
+ const bool is_normal = state_ == PlatformWindowState::kNormal;
+
+ // Update state before notifying delegate.
+ const bool did_active_change = is_active_ != is_activated;
+ is_active_ = is_activated;
+
+ // Rather than call SetBounds here for every configure event, just save the
+ // most recent bounds, and have WaylandConnection call ApplyPendingBounds
+ // when it has finished processing events. We may get many configure events
+ // in a row during an interactive resize, and only the last one matters.
+ //
+ // Width or height set to 0 means that we should decide on width and height by
+ // ourselves, but we don't want to set them to anything else. Use restored
+ // bounds size or the current bounds iff the current state is normal (neither
+ // maximized nor fullscreen).
+ //
+ // Note: if the browser was started with --start-fullscreen and a user exits
+ // the fullscreen mode, wayland may set the width and height to be 1. Instead,
+ // explicitly set the bounds to the current desired ones or the previous
+ // bounds.
+ if (width > 1 && height > 1) {
+ pending_bounds_dip_ = gfx::Rect(0, 0, width, height);
+ } else if (is_normal) {
+ pending_bounds_dip_.set_size(
+ gfx::ScaleToRoundedSize(GetRestoredBoundsInPixels().IsEmpty()
+ ? GetBounds().size()
+ : GetRestoredBoundsInPixels().size(),
+
+ 1.0 / buffer_scale()));
+ }
+
+ // Store the restored bounds of current state differs from the normal state.
+ // It can be client or compositor side change from normal to something else.
+ // Thus, we must store previous bounds to restore later.
+ SetOrResetRestoredBounds();
+ ApplyPendingBounds();
+
+ if (state_changed)
+ delegate()->OnWindowStateChanged(state_);
+
+ if (did_active_change)
+ delegate()->OnActivationChanged(is_active_);
+}
+
+void WaylandSurface::OnDragEnter(const gfx::PointF& point,
+ std::unique_ptr<OSExchangeData> data,
+ int operation) {
+ WmDropHandler* drop_handler = GetWmDropHandler(*this);
+ if (!drop_handler)
+ return;
+
+ // Wayland sends locations in DIP so they need to be translated to
+ // physical pixels.
+ drop_handler->OnDragEnter(
+ gfx::ScalePoint(point, buffer_scale(), buffer_scale()), std::move(data),
+ operation);
+}
+
+int WaylandSurface::OnDragMotion(const gfx::PointF& point,
+ uint32_t time,
+ int operation) {
+ WmDropHandler* drop_handler = GetWmDropHandler(*this);
+ if (!drop_handler)
+ return 0;
+
+ // Wayland sends locations in DIP so they need to be translated to
+ // physical pixels.
+ return drop_handler->OnDragMotion(
+ gfx::ScalePoint(point, buffer_scale(), buffer_scale()), operation);
+}
+
+void WaylandSurface::OnDragDrop(std::unique_ptr<OSExchangeData> data) {
+ WmDropHandler* drop_handler = GetWmDropHandler(*this);
+ if (!drop_handler)
+ return;
+ drop_handler->OnDragDrop(std::move(data));
+}
+
+void WaylandSurface::OnDragLeave() {
+ WmDropHandler* drop_handler = GetWmDropHandler(*this);
+ if (!drop_handler)
+ return;
+ drop_handler->OnDragLeave();
+}
+
+void WaylandSurface::OnDragSessionClose(uint32_t dnd_action) {
+ std::move(drag_closed_callback_).Run(dnd_action);
+ connection()->ResetPointerFlags();
+}
+
+bool WaylandSurface::OnInitialize(PlatformWindowInitProperties properties) {
+ app_id_ = properties.wm_class_class;
+ return true;
+}
+
+void WaylandSurface::TriggerStateChanges() {
+ if (!shell_surface_)
+ return;
+
+ if (state_ == PlatformWindowState::kFullScreen)
+ shell_surface_->SetFullscreen();
+ else
+ shell_surface_->UnSetFullscreen();
+
+ // Call UnSetMaximized only if current state is normal. Otherwise, if the
+ // current state is fullscreen and the previous is maximized, calling
+ // UnSetMaximized may result in wrong restored window position that clients
+ // are not allowed to know about.
+ if (state_ == PlatformWindowState::kMaximized)
+ shell_surface_->SetMaximized();
+ else if (state_ == PlatformWindowState::kNormal)
+ shell_surface_->UnSetMaximized();
+
+ if (state_ == PlatformWindowState::kMinimized)
+ shell_surface_->SetMinimized();
+
+ connection()->ScheduleFlush();
+}
+
+void WaylandSurface::SetWindowState(PlatformWindowState state) {
+ previous_state_ = state_;
+ state_ = state;
+ TriggerStateChanges();
+}
+
+WmMoveResizeHandler* WaylandSurface::AsWmMoveResizeHandler() {
+ return static_cast<WmMoveResizeHandler*>(this);
+}
+
+void WaylandSurface::SetSizeConstraints() {
+ if (min_size_.has_value())
+ shell_surface_->SetMinSize(min_size_->width(), min_size_->height());
+ if (max_size_.has_value())
+ shell_surface_->SetMaxSize(max_size_->width(), max_size_->height());
+
+ connection()->ScheduleFlush();
+}
+
+void WaylandSurface::SetOrResetRestoredBounds() {
+ // The |restored_bounds_| are used when the window gets back to normal
+ // state after it went maximized or fullscreen. So we reset these if the
+ // window has just become normal and store the current bounds if it is
+ // either going out of normal state or simply changes the state and we don't
+ // have any meaningful value stored.
+ if (GetPlatformWindowState() == PlatformWindowState::kNormal) {
+ SetRestoredBoundsInPixels({});
+ } else if (GetRestoredBoundsInPixels().IsEmpty()) {
+ SetRestoredBoundsInPixels(GetBounds());
+ }
+}
+
+} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_surface.h b/chromium/ui/ozone/platform/wayland/host/wayland_surface.h
new file mode 100644
index 00000000000..ceda32d24a7
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_surface.h
@@ -0,0 +1,127 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SURFACE_H_
+#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SURFACE_H_
+
+#include "ui/ozone/platform/wayland/host/wayland_window.h"
+
+#include "ui/platform_window/platform_window_handler/wm_drag_handler.h"
+#include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h"
+
+namespace ui {
+
+class ShellSurfaceWrapper;
+
+class WaylandSurface : public WaylandWindow,
+ public WmMoveResizeHandler,
+ public WmDragHandler {
+ public:
+ WaylandSurface(PlatformWindowDelegate* delegate,
+ WaylandConnection* connection);
+ ~WaylandSurface() override;
+
+ ShellSurfaceWrapper* shell_surface() const { return shell_surface_.get(); }
+
+ // Apply the bounds specified in the most recent configure event. This should
+ // be called after processing all pending events in the wayland connection.
+ void ApplyPendingBounds();
+
+ // WmMoveResizeHandler
+ void DispatchHostWindowDragMovement(
+ int hittest,
+ const gfx::Point& pointer_location_in_px) override;
+
+ // WmDragHandler
+ void StartDrag(const ui::OSExchangeData& data,
+ int operation,
+ gfx::NativeCursor cursor,
+ base::OnceCallback<void(int)> callback) override;
+
+ // PlatformWindow
+ void Show(bool inactive) override;
+ void Hide() override;
+ bool IsVisible() const override;
+ void SetTitle(const base::string16& title) override;
+ void ToggleFullscreen() override;
+ void Maximize() override;
+ void Minimize() override;
+ void Restore() override;
+ PlatformWindowState GetPlatformWindowState() const override;
+ void SizeConstraintsChanged() override;
+
+ private:
+ // WaylandWindow overrides:
+ void HandleSurfaceConfigure(int32_t widht,
+ int32_t height,
+ bool is_maximized,
+ bool is_fullscreen,
+ bool is_activated) override;
+ void OnDragEnter(const gfx::PointF& point,
+ std::unique_ptr<OSExchangeData> data,
+ int operation) override;
+ int OnDragMotion(const gfx::PointF& point,
+ uint32_t time,
+ int operation) override;
+ void OnDragDrop(std::unique_ptr<OSExchangeData> data) override;
+ void OnDragLeave() override;
+ void OnDragSessionClose(uint32_t dnd_action) override;
+ bool OnInitialize(PlatformWindowInitProperties properties) override;
+
+ void TriggerStateChanges();
+ void SetWindowState(PlatformWindowState state);
+
+ // Creates a surface window, which is visible as a main window.
+ bool CreateShellSurface();
+
+ WmMoveResizeHandler* AsWmMoveResizeHandler();
+
+ // Propagates the |min_size_| and |max_size_| to the ShellSurface.
+ void SetSizeConstraints();
+
+ void SetOrResetRestoredBounds();
+
+ // Wrappers around shell surface.
+ std::unique_ptr<ShellSurfaceWrapper> shell_surface_;
+
+ base::OnceCallback<void(int)> drag_closed_callback_;
+
+ // These bounds attributes below have suffices that indicate units used.
+ // Wayland operates in DIP but the platform operates in physical pixels so
+ // our WaylandSurface is the link that has to translate the units. See also
+ // comments in the implementation.
+ //
+ // Bounds that will be applied when the window state is finalized. The window
+ // may get several configuration events that update the pending bounds, and
+ // only upon finalizing the state is the latest value stored as the current
+ // bounds via |ApplyPendingBounds|. Measured in DIP because updated in the
+ // handler that receives DIP from Wayland.
+ gfx::Rect pending_bounds_dip_;
+
+ // Contains the current state of the window.
+ PlatformWindowState state_;
+ // Contains the previous state of the window.
+ PlatformWindowState previous_state_;
+
+ bool is_active_ = false;
+
+ // Id of the chromium app passed through
+ // PlatformWindowInitProperties::wm_class_class. This is used by Wayland
+ // compositor to identify the app, unite it's windows into the same stack of
+ // windows and find *.desktop file to set various preferences including icons.
+ std::string app_id_;
+
+ // Title of the ShellSurface.
+ base::string16 window_title_;
+
+ // Max and min sizes of the WaylandSurface window.
+ base::Optional<gfx::Size> min_size_;
+ base::Optional<gfx::Size> max_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandSurface);
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_SURFACE_H_
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_window.cc b/chromium/ui/ozone/platform/wayland/host/wayland_window.cc
index 4787a1f3b39..cfb9644b1f5 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_window.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -9,103 +9,24 @@
#include "base/bind.h"
#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
-#include "ui/base/dragdrop/drag_drop_types.h"
-#include "ui/base/dragdrop/os_exchange_data.h"
-#include "ui/base/hit_test.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/events/ozone/events_ozone.h"
#include "ui/gfx/geometry/point_f.h"
-#include "ui/ozone/platform/wayland/host/shell_popup_wrapper.h"
-#include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h"
+#include "ui/ozone/platform/wayland/common/wayland_util.h"
#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_cursor_position.h"
#include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
#include "ui/ozone/platform/wayland/host/wayland_pointer.h"
-#include "ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h"
-#include "ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h"
-#include "ui/platform_window/platform_window_handler/wm_drop_handler.h"
namespace ui {
-namespace {
-
-// Factory, which decides which version type of xdg object to build.
-class XDGShellObjectFactory {
- public:
- XDGShellObjectFactory() = default;
- ~XDGShellObjectFactory() = default;
-
- std::unique_ptr<ShellPopupWrapper> CreateXDGPopup(
- WaylandConnection* connection,
- WaylandWindow* wayland_window,
- const gfx::Rect& bounds) {
- std::unique_ptr<XDGSurfaceWrapperImpl> surface =
- std::make_unique<XDGSurfaceWrapperImpl>(wayland_window);
- if (connection->shell()) {
- surface->InitializeStable(connection, wayland_window->surface(), false);
- std::unique_ptr<XDGPopupWrapperImpl> popup =
- std::make_unique<XDGPopupWrapperImpl>(std::move(surface),
- wayland_window);
- popup->InitializeStable(connection, wayland_window->surface(),
- wayland_window->parent_window(), bounds);
- return popup;
- }
- DCHECK(connection->shell_v6());
-
- surface->InitializeV6(connection, wayland_window->surface(), false);
- std::unique_ptr<XDGPopupWrapperImpl> popup =
- std::make_unique<XDGPopupWrapperImpl>(std::move(surface),
- wayland_window);
- popup->InitializeV6(connection, wayland_window->surface(),
- wayland_window->parent_window(), bounds);
- return popup;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(XDGShellObjectFactory);
-};
-
-// Translates bounds relative to top level window to specified parent.
-gfx::Rect TranslateBoundsToParentCoordinates(const gfx::Rect& child_bounds,
- const gfx::Rect& parent_bounds) {
- return gfx::Rect(gfx::Point(child_bounds.x() - parent_bounds.x(),
- child_bounds.y() - parent_bounds.y()),
- child_bounds.size());
-}
-
-// Translates bounds relative to parent window to top level window.
-gfx::Rect TranslateBoundsToTopLevelCoordinates(const gfx::Rect& child_bounds,
- const gfx::Rect& parent_bounds) {
- return gfx::Rect(gfx::Point(child_bounds.x() + parent_bounds.x(),
- child_bounds.y() + parent_bounds.y()),
- child_bounds.size());
-}
-
-} // namespace
-
WaylandWindow::WaylandWindow(PlatformWindowDelegate* delegate,
WaylandConnection* connection)
- : delegate_(delegate),
- connection_(connection),
- xdg_shell_objects_factory_(new XDGShellObjectFactory()),
- state_(PlatformWindowState::kNormal),
- pending_state_(PlatformWindowState::kUnknown) {
- // Set a class property key, which allows |this| to be used for interactive
- // events, e.g. move or resize.
- SetWmMoveResizeHandler(this, AsWmMoveResizeHandler());
-
- // Set a class property key, which allows |this| to be used for drag action.
- SetWmDragHandler(this, this);
-}
+ : delegate_(delegate), connection_(connection) {}
WaylandWindow::~WaylandWindow() {
- if (drag_closed_callback_) {
- std::move(drag_closed_callback_)
- .Run(DragDropTypes::DragOperation::DRAG_NONE);
- }
-
PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
if (surface_)
connection_->wayland_window_manager()->RemoveWindow(GetWidget());
@@ -123,78 +44,14 @@ WaylandWindow* WaylandWindow::FromSurface(wl_surface* surface) {
wl_proxy_get_user_data(reinterpret_cast<wl_proxy*>(surface)));
}
-bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
- DCHECK(xdg_shell_objects_factory_);
-
- // Properties contain DIP bounds but the buffer scale is initially 1 so it's
- // OK to assign. The bounds will be recalculated when the buffer scale
- // changes.
- DCHECK_EQ(buffer_scale_, 1);
- bounds_px_ = properties.bounds;
- opacity_ = properties.opacity;
-
- surface_.reset(wl_compositor_create_surface(connection_->compositor()));
- if (!surface_) {
- LOG(ERROR) << "Failed to create wl_surface";
- return false;
- }
- wl_surface_set_user_data(surface_.get(), this);
- AddSurfaceListener();
-
- connection_->wayland_window_manager()->AddWindow(GetWidget(), this);
-
- ui::PlatformWindowType ui_window_type = properties.type;
- switch (ui_window_type) {
- case ui::PlatformWindowType::kMenu:
- case ui::PlatformWindowType::kPopup:
- parent_window_ = GetParentWindow(properties.parent_widget);
-
- // Popups need to know their scale earlier to position themselves.
- if (!parent_window_) {
- LOG(ERROR) << "Failed to get a parent window for this popup";
- return false;
- }
-
- SetBufferScale(parent_window_->buffer_scale_, false);
- ui_scale_ = parent_window_->ui_scale_;
-
- // TODO(msisov, jkim): Handle notification windows, which are marked
- // as popup windows as well. Those are the windows that do not have
- // parents and pop up when the browser receives a notification.
- CreateShellPopup();
- break;
- case ui::PlatformWindowType::kTooltip:
- // Tooltips subsurfaces are created on demand, upon ::Show calls.
- is_tooltip_ = true;
- break;
- case ui::PlatformWindowType::kWindow:
- case ui::PlatformWindowType::kBubble:
- case ui::PlatformWindowType::kDrag:
- // TODO(msisov): Figure out what kind of surface we need to create for
- // bubble and drag windows.
- CreateShellSurface();
- break;
- }
-
- if (shell_surface_ && !properties.wm_class_class.empty())
- shell_surface_->SetAppId(properties.wm_class_class);
-
- connection_->ScheduleFlush();
-
- PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
- delegate_->OnAcceleratedWidgetAvailable(GetWidget());
-
- // Will do nothing for popups because they have got their scale above.
- UpdateBufferScale(false);
-
- MaybeUpdateOpaqueRegion();
- return true;
-}
-
void WaylandWindow::UpdateBufferScale(bool update_bounds) {
DCHECK(connection_->wayland_output_manager());
const auto* screen = connection_->wayland_output_manager()->wayland_screen();
- DCHECK(screen);
+
+ // The client might not create screen at all.
+ if (!screen)
+ return;
+
const auto widget = GetWidget();
int32_t new_scale = 0;
@@ -222,112 +79,6 @@ gfx::AcceleratedWidget WaylandWindow::GetWidget() const {
return gfx::kNullAcceleratedWidget;
return surface_.id();
}
-
-void WaylandWindow::CreateShellPopup() {
- if (bounds_px_.IsEmpty())
- return;
-
- // TODO(jkim): Consider how to support DropArrow window on tabstrip.
- // When it starts dragging, as described the protocol, https://goo.gl/1Mskq3,
- // the client must have an active implicit grab. If we try to create a popup
- // window while dragging is executed, it gets 'popup_done' directly from
- // Wayland compositor and it's destroyed through 'popup_done'. It causes
- // a crash when aura::Window is destroyed.
- // https://crbug.com/875164
- if (connection_->IsDragInProgress()) {
- surface_.reset();
- LOG(ERROR) << "Wayland can't create a popup window during dragging.";
- return;
- }
-
- DCHECK(parent_window_ && !shell_popup_);
-
- auto bounds_px = AdjustPopupWindowPosition();
-
- shell_popup_ =
- xdg_shell_objects_factory_->CreateXDGPopup(connection_, this, bounds_px);
-
- if (!shell_popup_) {
- CHECK(false) << "Failed to create Wayland shell popup";
- }
-
- parent_window_->set_child_window(this);
-}
-
-void WaylandWindow::CreateShellSurface() {
- std::unique_ptr<XDGSurfaceWrapperImpl> xdg_surface =
- std::make_unique<XDGSurfaceWrapperImpl>(this);
- if (!xdg_surface) {
- CHECK(false) << "Failed to create Wayland shell surface";
- return;
- }
-
- if (connection_->shell()) {
- if (!xdg_surface->InitializeStable(connection_, surface_.get())) {
- CHECK(false) << "Failed to initialize Wayland shell surface";
- }
- } else {
- DCHECK(connection_->shell_v6());
- if (!xdg_surface->InitializeV6(connection_, surface_.get())) {
- CHECK(false) << "Failed to initialize Wayland shell surface";
- }
- }
- shell_surface_ = std::move(xdg_surface);
-}
-
-void WaylandWindow::CreateAndShowTooltipSubSurface() {
- // Since Aura does not not provide a reference parent window, needed by
- // Wayland, we get the current focused window to place and show the tooltips.
- auto* parent_window =
- connection_->wayland_window_manager()->GetCurrentFocusedWindow();
-
- // Tooltip creation is an async operation. By the time Aura actually creates
- // the tooltip, it is possible that the user has already moved the
- // mouse/pointer out of the window that triggered the tooptip. In this case,
- // parent_window is NULL.
- if (!parent_window)
- return;
-
- wl_subcompositor* subcompositor = connection_->subcompositor();
- DCHECK(subcompositor);
- tooltip_subsurface_.reset(wl_subcompositor_get_subsurface(
- subcompositor, surface_.get(), parent_window->surface()));
-
- // Chromium positions tooltip windows in screen coordinates, but Wayland
- // requires them to be in local surface coordinates aka relative to parent
- // window.
- const auto parent_bounds_dip =
- gfx::ScaleToRoundedRect(parent_window->GetBounds(), 1.0 / ui_scale_);
- auto new_bounds_dip =
- TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_dip);
- auto bounds_px =
- gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale_ / buffer_scale_);
-
- DCHECK(tooltip_subsurface_);
- // Convert position to DIP.
- wl_subsurface_set_position(tooltip_subsurface_.get(),
- bounds_px.x() / buffer_scale_,
- bounds_px.y() / buffer_scale_);
- wl_subsurface_set_desync(tooltip_subsurface_.get());
- wl_surface_commit(parent_window->surface());
- connection_->ScheduleFlush();
-}
-
-void WaylandWindow::ApplyPendingBounds() {
- if (pending_bounds_dip_.IsEmpty())
- return;
- DCHECK(shell_surface_);
-
- SetBoundsDip(pending_bounds_dip_);
- shell_surface_->SetWindowGeometry(pending_bounds_dip_);
- pending_bounds_dip_ = gfx::Rect();
- connection_->ScheduleFlush();
-
- // Opaque region is based on the size of the window. Thus, update the region
- // on each update.
- MaybeUpdateOpaqueRegion();
-}
-
void WaylandWindow::SetPointerFocus(bool focus) {
has_pointer_focus_ = focus;
@@ -338,71 +89,12 @@ void WaylandWindow::SetPointerFocus(bool focus) {
connection_->SetCursorBitmap(bitmap_->bitmaps(), bitmap_->hotspot());
}
-void WaylandWindow::DispatchHostWindowDragMovement(
- int hittest,
- const gfx::Point& pointer_location_in_px) {
- DCHECK(shell_surface_);
-
- connection_->ResetPointerFlags();
- if (hittest == HTCAPTION)
- shell_surface_->SurfaceMove(connection_);
- else
- shell_surface_->SurfaceResize(connection_, hittest);
-
- connection_->ScheduleFlush();
-}
-
-void WaylandWindow::StartDrag(const ui::OSExchangeData& data,
- int operation,
- gfx::NativeCursor cursor,
- base::OnceCallback<void(int)> callback) {
- DCHECK(!drag_closed_callback_);
- drag_closed_callback_ = std::move(callback);
- connection_->StartDrag(data, operation);
-}
-
void WaylandWindow::Show(bool inactive) {
- if (!is_tooltip_) // Tooltip windows should not get keyboard focus
- set_keyboard_focus(true);
-
- if (shell_surface_)
- return;
-
- if (is_tooltip_) {
- CreateAndShowTooltipSubSurface();
- return;
- }
-
- if (!shell_popup_) {
- // When showing a sub-menu after it has been previously shown and hidden,
- // Wayland sends SetBounds prior to Show, and |bounds_px| takes the pixel
- // bounds. This makes a difference against the normal flow when the
- // window is created (see |Initialize|). To equalize things, rescale
- // |bounds_px_| to DIP. It will be adjusted while creating the popup.
- bounds_px_ = gfx::ScaleToRoundedRect(bounds_px_, 1.0 / ui_scale_);
- CreateShellPopup();
- connection_->ScheduleFlush();
- }
-
- UpdateBufferScale(false);
+ NOTREACHED();
}
void WaylandWindow::Hide() {
- if (!is_tooltip_) {
- tooltip_subsurface_.reset();
- } else {
- if (child_window_)
- child_window_->Hide();
- if (shell_popup_) {
- parent_window_->set_child_window(nullptr);
- shell_popup_.reset();
- }
- }
-
- // Detach buffer from surface in order to completely shutdown popups and
- // tooltips, and release resources.
- if (!shell_surface())
- connection_->buffer_manager_host()->ResetSurfaceContents(GetWidget());
+ NOTREACHED();
}
void WaylandWindow::Close() {
@@ -410,9 +102,8 @@ void WaylandWindow::Close() {
}
bool WaylandWindow::IsVisible() const {
- // X and Windows return true if the window is minimized. For consistency, do
- // the same.
- return (!!shell_surface_ || !!shell_popup_) || IsMinimized();
+ NOTREACHED();
+ return false;
}
void WaylandWindow::PrepareForShutdown() {}
@@ -422,6 +113,10 @@ void WaylandWindow::SetBounds(const gfx::Rect& bounds_px) {
return;
bounds_px_ = bounds_px;
+ // Opaque region is based on the size of the window. Thus, update the region
+ // on each update.
+ MaybeUpdateOpaqueRegion();
+
delegate_->OnBoundsChanged(bounds_px_);
}
@@ -429,16 +124,12 @@ gfx::Rect WaylandWindow::GetBounds() {
return bounds_px_;
}
-void WaylandWindow::SetTitle(const base::string16& title) {
- DCHECK(shell_surface_);
- shell_surface_->SetTitle(title);
- connection_->ScheduleFlush();
-}
+void WaylandWindow::SetTitle(const base::string16& title) {}
void WaylandWindow::SetCapture() {
// Wayland does implicit grabs, and doesn't allow for explicit grabs. The
- // exception to that are popups, but we explicitly send events to a
- // parent popup if such exists.
+ // exception to that are menus, but we explicitly send events to a
+ // parent menu if such exists.
}
void WaylandWindow::ReleaseCapture() {
@@ -446,83 +137,21 @@ void WaylandWindow::ReleaseCapture() {
}
bool WaylandWindow::HasCapture() const {
- // If WaylandWindow is a popup window, assume it has the capture.
- return shell_popup() ? true : has_implicit_grab_;
+ return has_implicit_grab_;
}
-void WaylandWindow::ToggleFullscreen() {
- DCHECK(shell_surface_);
-
- // There are some cases, when Chromium triggers a fullscreen state change
- // before the surface is activated. In such cases, Wayland may ignore state
- // changes and such flags as --kiosk or --start-fullscreen will be ignored.
- // To overcome this, set a pending state, and once the surface is activated,
- // trigger the change.
- if (!is_active_) {
- DCHECK(!IsFullscreen());
- pending_state_ = PlatformWindowState::kFullScreen;
- return;
- }
+void WaylandWindow::ToggleFullscreen() {}
- // TODO(msisov, tonikitoo): add multiscreen support. As the documentation says
- // if shell_surface_set_fullscreen() is not provided with wl_output, it's up
- // to the compositor to choose which display will be used to map this surface.
- if (!IsFullscreen()) {
- // Fullscreen state changes have to be handled manually and then checked
- // against configuration events, which come from a compositor. The reason
- // of manually changing the |state_| is that the compositor answers about
- // state changes asynchronously, which leads to a wrong return value in
- // DesktopWindowTreeHostPlatform::IsFullscreen, for example, and media
- // files can never be set to fullscreen.
- state_ = PlatformWindowState::kFullScreen;
- shell_surface_->SetFullscreen();
- } else {
- // Check the comment above. If it's not handled synchronously, media files
- // may not leave the fullscreen mode.
- state_ = PlatformWindowState::kUnknown;
- shell_surface_->UnSetFullscreen();
- }
+void WaylandWindow::Maximize() {}
- connection_->ScheduleFlush();
-}
+void WaylandWindow::Minimize() {}
-void WaylandWindow::Maximize() {
- DCHECK(shell_surface_);
-
- if (IsFullscreen())
- ToggleFullscreen();
-
- shell_surface_->SetMaximized();
- connection_->ScheduleFlush();
-}
-
-void WaylandWindow::Minimize() {
- DCHECK(shell_surface_);
- DCHECK(!is_minimizing_);
- // Wayland doesn't explicitly say if a window is minimized. Instead, it
- // notifies that the window is not activated. But there are many cases, when
- // the window is not minimized and deactivated. In order to properly record
- // the minimized state, mark this window as being minimized. And as soon as a
- // configuration event comes, check if the window has been deactivated and has
- // |is_minimizing_| set.
- is_minimizing_ = true;
- shell_surface_->SetMinimized();
- connection_->ScheduleFlush();
-}
-
-void WaylandWindow::Restore() {
- DCHECK(shell_surface_);
-
- // Unfullscreen the window if it is fullscreen.
- if (IsFullscreen())
- ToggleFullscreen();
-
- shell_surface_->UnSetMaximized();
- connection_->ScheduleFlush();
-}
+void WaylandWindow::Restore() {}
PlatformWindowState WaylandWindow::GetPlatformWindowState() const {
- return state_;
+ // Remove normal state for all the other types of windows as it's only the
+ // WaylandSurface that supports state changes.
+ return PlatformWindowState::kNormal;
}
void WaylandWindow::Activate() {
@@ -589,32 +218,17 @@ void WaylandWindow::SetWindowIcons(const gfx::ImageSkia& window_icon,
NOTIMPLEMENTED_LOG_ONCE();
}
-void WaylandWindow::SizeConstraintsChanged() {
- // Size constraints only make sense for normal windows.
- if (!shell_surface_)
- return;
-
- DCHECK(delegate_);
- auto min_size = delegate_->GetMinimumSizeForWindow();
- auto max_size = delegate_->GetMaximumSizeForWindow();
-
- if (min_size.has_value())
- shell_surface_->SetMinSize(min_size->width(), min_size->height());
- if (max_size.has_value())
- shell_surface_->SetMaxSize(max_size->width(), max_size->height());
-
- connection_->ScheduleFlush();
-}
+void WaylandWindow::SizeConstraintsChanged() {}
bool WaylandWindow::CanDispatchEvent(const PlatformEvent& event) {
- // This window is a nested popup window, all the events must be forwarded
- // to the main popup window.
- if (child_window_ && child_window_->shell_popup())
- return !!shell_popup_.get();
+ // This window is a nested menu window, all the events must be forwarded
+ // to the main menu window.
+ if (child_window_ && wl::IsMenuType(child_window_->type()))
+ return wl::IsMenuType(type());
// If this is a nested menu window with a parent, it mustn't recieve any
// events.
- if (parent_window_ && parent_window_->shell_popup())
+ if (parent_window_ && wl::IsMenuType(parent_window_->type()))
return false;
// If another window has capture, return early before checking focus.
@@ -632,7 +246,6 @@ bool WaylandWindow::CanDispatchEvent(const PlatformEvent& event) {
uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) {
Event* event = static_cast<Event*>(native_event);
-
if (event->IsLocatedEvent()) {
// Wayland sends locations in DIP so they need to be translated to
// physical pixels.
@@ -643,13 +256,14 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) {
}
// If the window does not have a pointer focus, but received this event, it
- // means the window is a popup window with a child popup window. In this case,
- // the location of the event must be converted from the nested popup to the
- // main popup, which the menu controller needs to properly handle events.
- if (event->IsLocatedEvent() && shell_popup()) {
- // Parent window of the main menu window is not a popup, but rather an
+ // means the window is a menu window with a child menu window. In this case,
+ // the location of the event must be converted from the nested menu to the
+ // main menu, which the menu controller needs to properly handle events.
+ if (event->IsLocatedEvent() && wl::IsMenuType(type())) {
+ // Parent window of the main menu window is not a menu, but rather an
// xdg surface.
- DCHECK(!parent_window_->shell_popup() && parent_window_->shell_surface());
+ DCHECK(!wl::IsMenuType(parent_window_->type()) ||
+ parent_window_->type() != PlatformWindowType::kTooltip);
auto* window =
connection_->wayland_window_manager()->GetCurrentFocusedWindow();
if (window) {
@@ -665,193 +279,77 @@ uint32_t WaylandWindow::DispatchEvent(const PlatformEvent& native_event) {
return POST_DISPATCH_STOP_PROPAGATION;
}
-void WaylandWindow::HandleSurfaceConfigure(int32_t width,
+void WaylandWindow::HandleSurfaceConfigure(int32_t widht,
int32_t height,
bool is_maximized,
bool is_fullscreen,
bool is_activated) {
- DCHECK(!shell_popup());
-
- // Propagate the window state information to the client.
- PlatformWindowState old_state = state_;
-
- // Ensure that manually handled state changes to fullscreen correspond to the
- // configuration events from a compositor.
- DCHECK_EQ(is_fullscreen, IsFullscreen());
-
- // There are two cases, which must be handled for the minimized state.
- // The first one is the case, when the surface goes into the minimized state
- // (check comment in WaylandWindow::Minimize), and the second case is when the
- // surface still has been minimized, but another cofiguration event with
- // !is_activated comes. For this, check if the WaylandWindow has been
- // minimized before and !is_activated is sent.
- if ((is_minimizing_ || IsMinimized()) && !is_activated) {
- is_minimizing_ = false;
- state_ = PlatformWindowState::kMinimized;
- } else if (is_fullscreen) {
- // To ensure the |delegate_| is notified about state changes to fullscreen,
- // assume the old_state is UNKNOWN (check comment in ToggleFullscreen).
- old_state = PlatformWindowState::kUnknown;
- DCHECK(state_ == PlatformWindowState::kFullScreen);
- } else if (is_maximized) {
- state_ = PlatformWindowState::kMaximized;
- } else {
- state_ = PlatformWindowState::kNormal;
- }
- const bool state_changed = old_state != state_;
- const bool is_normal = !IsFullscreen() && !IsMaximized();
-
- // Update state before notifying delegate.
- const bool did_active_change = is_active_ != is_activated;
- is_active_ = is_activated;
-
- // Rather than call SetBounds here for every configure event, just save the
- // most recent bounds, and have WaylandConnection call ApplyPendingBounds
- // when it has finished processing events. We may get many configure events
- // in a row during an interactive resize, and only the last one matters.
- //
- // Width or height set to 0 means that we should decide on width and height by
- // ourselves, but we don't want to set them to anything else. Use restored
- // bounds size or the current bounds iff the current state is normal (neither
- // maximized nor fullscreen).
- //
- // Note: if the browser was started with --start-fullscreen and a user exits
- // the fullscreen mode, wayland may set the width and height to be 1. Instead,
- // explicitly set the bounds to the current desired ones or the previous
- // bounds.
- if (width > 1 && height > 1) {
- pending_bounds_dip_ = gfx::Rect(0, 0, width, height);
- } else if (is_normal) {
- pending_bounds_dip_.set_size(gfx::ScaleToRoundedSize(
- restored_bounds_px_.IsEmpty() ? GetBounds().size()
- : restored_bounds_px_.size(),
-
- 1.0 / buffer_scale_));
- }
-
- if (state_changed) {
- // The |restored_bounds_| are used when the window gets back to normal
- // state after it went maximized or fullscreen. So we reset these if the
- // window has just become normal and store the current bounds if it is
- // either going out of normal state or simply changes the state and we don't
- // have any meaningful value stored.
- if (is_normal) {
- SetRestoredBoundsInPixels({});
- } else if (old_state == PlatformWindowState::kNormal ||
- restored_bounds_px_.IsEmpty()) {
- SetRestoredBoundsInPixels(bounds_px_);
- }
-
- delegate_->OnWindowStateChanged(state_);
- }
-
- ApplyPendingBounds();
-
- if (did_active_change)
- delegate_->OnActivationChanged(is_active_);
-
- MaybeTriggerPendingStateChange();
+ NOTREACHED()
+ << "Only shell surfaces must receive HandleSurfaceConfigure calls.";
}
void WaylandWindow::HandlePopupConfigure(const gfx::Rect& bounds_dip) {
- DCHECK(shell_popup());
- DCHECK(parent_window_);
-
- SetBufferScale(parent_window_->buffer_scale_, true);
-
- gfx::Rect new_bounds_dip = bounds_dip;
-
- // It's not enough to just set new bounds. If it is a menu window, whose
- // parent is a top level window aka browser window, it can be flipped
- // vertically along y-axis and have negative values set. Chromium cannot
- // understand that and starts to position nested menu windows incorrectly. To
- // fix that, we have to bear in mind that Wayland compositor does not share
- // global coordinates for any surfaces, and Chromium assumes the top level
- // window is always located at 0,0 origin. What is more, child windows must
- // always be positioned relative to parent window local surface coordinates.
- // Thus, if the menu window is flipped along y-axis by Wayland and its origin
- // is above the top level parent window, the origin of the top level window
- // has to be shifted by that value on y-axis so that the origin of the menu
- // becomes x,0, and events can be handled normally.
- if (!parent_window_->shell_popup()) {
- gfx::Rect parent_bounds = parent_window_->GetBounds();
- // The menu window is flipped along y-axis and have x,-y origin. Shift the
- // parent top level window instead.
- if (new_bounds_dip.y() < 0) {
- // Move parent bounds along y-axis.
- parent_bounds.set_y(-(new_bounds_dip.y() * buffer_scale_));
- new_bounds_dip.set_y(0);
- } else {
- // If the menu window is located at correct origin from the browser point
- // of view, return the top level window back to 0,0.
- parent_bounds.set_y(0);
- }
- parent_window_->SetBounds(parent_bounds);
- } else {
- // The nested menu windows are located relative to the parent menu windows.
- // Thus, the location must be translated to be relative to the top level
- // window, which automatically becomes the same as relative to an origin of
- // a display.
- new_bounds_dip = gfx::ScaleToRoundedRect(
- TranslateBoundsToTopLevelCoordinates(
- gfx::ScaleToRoundedRect(new_bounds_dip, buffer_scale_),
- parent_window_->GetBounds()),
- 1.0 / buffer_scale_);
- DCHECK(new_bounds_dip.y() >= 0);
- }
-
- SetBoundsDip(new_bounds_dip);
+ NOTREACHED() << "Only shell popups must receive HandlePopupConfigure calls.";
}
void WaylandWindow::OnCloseRequest() {
- // Before calling OnCloseRequest, the |shell_popup_| must become hidden and
- // only then call OnCloseRequest().
- DCHECK(!shell_popup_);
delegate_->OnCloseRequest();
}
void WaylandWindow::OnDragEnter(const gfx::PointF& point,
std::unique_ptr<OSExchangeData> data,
- int operation) {
- WmDropHandler* drop_handler = GetWmDropHandler(*this);
- if (!drop_handler)
- return;
- drop_handler->OnDragEnter(point, std::move(data), operation);
-}
+ int operation) {}
int WaylandWindow::OnDragMotion(const gfx::PointF& point,
uint32_t time,
int operation) {
- WmDropHandler* drop_handler = GetWmDropHandler(*this);
- if (!drop_handler)
- return 0;
-
- return drop_handler->OnDragMotion(point, operation);
+ return -1;
}
-void WaylandWindow::OnDragDrop(std::unique_ptr<OSExchangeData> data) {
- WmDropHandler* drop_handler = GetWmDropHandler(*this);
- if (!drop_handler)
- return;
- drop_handler->OnDragDrop(std::move(data));
-}
+void WaylandWindow::OnDragDrop(std::unique_ptr<OSExchangeData> data) {}
-void WaylandWindow::OnDragLeave() {
- WmDropHandler* drop_handler = GetWmDropHandler(*this);
- if (!drop_handler)
- return;
- drop_handler->OnDragLeave();
-}
+void WaylandWindow::OnDragLeave() {}
-void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) {
- std::move(drag_closed_callback_).Run(dnd_action);
- connection_->ResetPointerFlags();
-}
+void WaylandWindow::OnDragSessionClose(uint32_t dnd_action) {}
void WaylandWindow::SetBoundsDip(const gfx::Rect& bounds_dip) {
SetBounds(gfx::ScaleToRoundedRect(bounds_dip, buffer_scale_));
}
+bool WaylandWindow::Initialize(PlatformWindowInitProperties properties) {
+ // Properties contain DIP bounds but the buffer scale is initially 1 so it's
+ // OK to assign. The bounds will be recalculated when the buffer scale
+ // changes.
+ DCHECK_EQ(buffer_scale_, 1);
+ bounds_px_ = properties.bounds;
+ opacity_ = properties.opacity;
+ type_ = properties.type;
+
+ surface_.reset(wl_compositor_create_surface(connection_->compositor()));
+ if (!surface_) {
+ LOG(ERROR) << "Failed to create wl_surface";
+ return false;
+ }
+ wl_surface_set_user_data(surface_.get(), this);
+ AddSurfaceListener();
+
+ connection_->wayland_window_manager()->AddWindow(GetWidget(), this);
+
+ if (!OnInitialize(std::move(properties)))
+ return false;
+
+ connection_->ScheduleFlush();
+
+ PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
+ delegate_->OnAcceleratedWidgetAvailable(GetWidget());
+
+ // Will do nothing for menus because they have got their scale above.
+ UpdateBufferScale(false);
+
+ MaybeUpdateOpaqueRegion();
+ return true;
+}
+
void WaylandWindow::SetBufferScale(int32_t new_scale, bool update_bounds) {
DCHECK_GT(new_scale, 0);
@@ -868,26 +366,6 @@ void WaylandWindow::SetBufferScale(int32_t new_scale, bool update_bounds) {
connection_->ScheduleFlush();
}
-bool WaylandWindow::IsMinimized() const {
- return state_ == PlatformWindowState::kMinimized;
-}
-
-bool WaylandWindow::IsMaximized() const {
- return state_ == PlatformWindowState::kMaximized;
-}
-
-bool WaylandWindow::IsFullscreen() const {
- return state_ == PlatformWindowState::kFullScreen;
-}
-
-void WaylandWindow::MaybeTriggerPendingStateChange() {
- if (pending_state_ == PlatformWindowState::kUnknown || !is_active_)
- return;
- DCHECK_EQ(pending_state_, PlatformWindowState::kFullScreen);
- pending_state_ = PlatformWindowState::kUnknown;
- ToggleFullscreen();
-}
-
WaylandWindow* WaylandWindow::GetParentWindow(
gfx::AcceleratedWidget parent_widget) {
auto* parent_window =
@@ -913,10 +391,6 @@ WaylandWindow* WaylandWindow::GetRootParentWindow() {
return parent_window_ ? parent_window_->GetRootParentWindow() : this;
}
-WmMoveResizeHandler* WaylandWindow::AsWmMoveResizeHandler() {
- return static_cast<WmMoveResizeHandler*>(this);
-}
-
void WaylandWindow::AddSurfaceListener() {
static struct wl_surface_listener surface_listener = {
&WaylandWindow::Enter,
@@ -926,10 +400,10 @@ void WaylandWindow::AddSurfaceListener() {
}
void WaylandWindow::AddEnteredOutputId(struct wl_output* output) {
- // Wayland does weird things for popups so instead of tracking outputs that
+ // Wayland does weird things for menus so instead of tracking outputs that
// we entered or left, we take that from the parent window and ignore this
// event.
- if (shell_popup())
+ if (wl::IsMenuType(type()))
return;
const uint32_t entered_output_id =
@@ -942,10 +416,10 @@ void WaylandWindow::AddEnteredOutputId(struct wl_output* output) {
}
void WaylandWindow::RemoveEnteredOutputId(struct wl_output* output) {
- // Wayland does weird things for popups so instead of tracking outputs that
+ // Wayland does weird things for menus so instead of tracking outputs that
// we entered or left, we take that from the parent window and ignore this
// event.
- if (shell_popup())
+ if (wl::IsMenuType(type()))
return;
const uint32_t left_output_id =
@@ -1005,51 +479,6 @@ void WaylandWindow::UpdateCursorPositionFromEvent(
}
}
-gfx::Rect WaylandWindow::AdjustPopupWindowPosition() const {
- auto* parent_window = parent_window_->shell_popup()
- ? parent_window_->parent_window_
- : parent_window_;
- DCHECK(parent_window);
- DCHECK(buffer_scale_ == parent_window->buffer_scale_);
- DCHECK(ui_scale_ == parent_window->ui_scale_);
-
- // Chromium positions windows in screen coordinates, but Wayland requires them
- // to be in local surface coordinates aka relative to parent window.
- const gfx::Rect parent_bounds_dip =
- gfx::ScaleToRoundedRect(parent_window_->GetBounds(), 1.0 / ui_scale_);
- gfx::Rect new_bounds_dip =
- TranslateBoundsToParentCoordinates(bounds_px_, parent_bounds_dip);
-
- // Chromium may decide to position nested menu windows on the left side
- // instead of the right side of parent menu windows when the size of the
- // window becomes larger than the display it is shown on. It's correct when
- // the window is located on one display and occupies the whole work area, but
- // as soon as it's moved and there is space on the right side, Chromium
- // continues positioning the nested menus on the left side relative to the
- // parent menu (Wayland does not provide clients with global coordinates).
- // Instead, reposition that window to be on the right side of the parent menu
- // window and let the compositor decide how to position it if it does not fit
- // a single display. However, there is one exception - if the window is
- // maximized, let Chromium position it on the left side as long as the Wayland
- // compositor may decide to position the nested window on the right side of
- // the parent menu window, which results in showing it on a second display if
- // more than one display is used.
- if (parent_window_->shell_popup() && parent_window_->parent_window_ &&
- !parent_window_->parent_window_->IsMaximized()) {
- auto* top_level_window = parent_window_->parent_window_;
- DCHECK(top_level_window && !top_level_window->shell_popup());
- if (new_bounds_dip.x() <= 0 && !top_level_window->IsMaximized()) {
- // Position the child menu window on the right side of the parent window
- // and let the Wayland compositor decide how to do constraint
- // adjustements.
- int new_x = parent_bounds_dip.width() -
- (new_bounds_dip.width() + new_bounds_dip.x());
- new_bounds_dip.set_x(new_x);
- }
- }
- return gfx::ScaleToRoundedRect(new_bounds_dip, ui_scale_ / buffer_scale_);
-}
-
WaylandWindow* WaylandWindow::GetTopLevelWindow() {
return parent_window_ ? parent_window_->GetTopLevelWindow() : this;
}
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_window.h b/chromium/ui/ozone/platform/wayland/host/wayland_window.h
index 2745dde85c3..08658f1df87 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_window.h
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_window.h
@@ -19,8 +19,6 @@
#include "ui/ozone/platform/wayland/common/wayland_object.h"
#include "ui/platform_window/platform_window.h"
#include "ui/platform_window/platform_window_delegate.h"
-#include "ui/platform_window/platform_window_handler/wm_drag_handler.h"
-#include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h"
#include "ui/platform_window/platform_window_init_properties.h"
namespace gfx {
@@ -32,25 +30,19 @@ namespace ui {
class BitmapCursorOzone;
class OSExchangeData;
class WaylandConnection;
-class ShellPopupWrapper;
-class ShellSurfaceWrapper;
-namespace {
-class XDGShellObjectFactory;
-} // namespace
-
-class WaylandWindow : public PlatformWindow,
- public PlatformEventDispatcher,
- public WmMoveResizeHandler,
- public WmDragHandler {
+class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
public:
- WaylandWindow(PlatformWindowDelegate* delegate,
- WaylandConnection* connection);
~WaylandWindow() override;
- static WaylandWindow* FromSurface(wl_surface* surface);
+ // A factory method that can create any of the derived types of WaylandWindow
+ // (WaylandSurface, WaylandPopup and WaylandSubsurface).
+ static std::unique_ptr<WaylandWindow> Create(
+ PlatformWindowDelegate* delegate,
+ WaylandConnection* connection,
+ PlatformWindowInitProperties properties);
- bool Initialize(PlatformWindowInitProperties properties);
+ static WaylandWindow* FromSurface(wl_surface* surface);
// Updates the surface buffer scale of the window. Top level windows take
// scale from the output attached to either their current display or the
@@ -60,17 +52,14 @@ class WaylandWindow : public PlatformWindow,
void UpdateBufferScale(bool update_bounds);
wl_surface* surface() const { return surface_.get(); }
- ShellSurfaceWrapper* shell_surface() const { return shell_surface_.get(); }
- ShellPopupWrapper* shell_popup() const { return shell_popup_.get(); }
+ void set_parent_window(WaylandWindow* parent_window) {
+ parent_window_ = parent_window;
+ }
WaylandWindow* parent_window() const { return parent_window_; }
gfx::AcceleratedWidget GetWidget() const;
- // Apply the bounds specified in the most recent configure event. This should
- // be called after processing all pending events in the wayland connection.
- void ApplyPendingBounds();
-
// Set whether this window has pointer focus and should dispatch mouse events.
void SetPointerFocus(bool focus);
bool has_pointer_focus() const { return has_pointer_focus_; }
@@ -87,6 +76,7 @@ class WaylandWindow : public PlatformWindow,
// Set a child of this window. It is very important in case of nested
// shell_popups as long as they must be destroyed in the back order.
void set_child_window(WaylandWindow* window) { child_window_ = window; }
+ WaylandWindow* child_window() const { return child_window_; }
// Set whether this window has an implicit grab (often referred to as capture
// in Chrome code). Implicit grabs happen while a pointer is down.
@@ -94,23 +84,14 @@ class WaylandWindow : public PlatformWindow,
bool has_implicit_grab() const { return has_implicit_grab_; }
int32_t buffer_scale() const { return buffer_scale_; }
-
- bool is_active() const { return is_active_; }
+ int32_t ui_scale() const { return ui_scale_; }
const base::flat_set<uint32_t>& entered_outputs_ids() const {
return entered_outputs_ids_;
}
- // WmMoveResizeHandler
- void DispatchHostWindowDragMovement(
- int hittest,
- const gfx::Point& pointer_location_in_px) override;
-
- // WmDragHandler
- void StartDrag(const ui::OSExchangeData& data,
- int operation,
- gfx::NativeCursor cursor,
- base::OnceCallback<void(int)> callback) override;
+ // Returns current type of the window.
+ PlatformWindowType type() const { return type_; }
// PlatformWindow
void Show(bool inactive) override;
@@ -148,55 +129,58 @@ class WaylandWindow : public PlatformWindow,
bool CanDispatchEvent(const PlatformEvent& event) override;
uint32_t DispatchEvent(const PlatformEvent& event) override;
- // Handles the configuration events coming from the surface (see
- // |XDGSurfaceWrapperStable::ConfigureTopLevel| and
- // |XDGSurfaceWrapperV6::ConfigureTopLevel|. The width and height come in
- // DIP of the output that the surface is currently bound to.
- void HandleSurfaceConfigure(int32_t widht,
- int32_t height,
- bool is_maximized,
- bool is_fullscreen,
- bool is_activated);
- void HandlePopupConfigure(const gfx::Rect& bounds);
-
- void OnCloseRequest();
-
- void OnDragEnter(const gfx::PointF& point,
- std::unique_ptr<OSExchangeData> data,
- int operation);
- int OnDragMotion(const gfx::PointF& point, uint32_t time, int operation);
- void OnDragDrop(std::unique_ptr<OSExchangeData> data);
- void OnDragLeave();
- void OnDragSessionClose(uint32_t dnd_action);
+ // Handles the configuration events coming from the shell objects.
+ // The width and height come in DIP of the output that the surface is
+ // currently bound to.
+ virtual void HandleSurfaceConfigure(int32_t widht,
+ int32_t height,
+ bool is_maximized,
+ bool is_fullscreen,
+ bool is_activated);
+ virtual void HandlePopupConfigure(const gfx::Rect& bounds);
+
+ // Handles close requests.
+ virtual void OnCloseRequest();
+
+ // Notifies about drag/drop session events.
+ virtual void OnDragEnter(const gfx::PointF& point,
+ std::unique_ptr<OSExchangeData> data,
+ int operation);
+ virtual int OnDragMotion(const gfx::PointF& point,
+ uint32_t time,
+ int operation);
+ virtual void OnDragDrop(std::unique_ptr<OSExchangeData> data);
+ virtual void OnDragLeave();
+ virtual void OnDragSessionClose(uint32_t dnd_action);
+
+ protected:
+ WaylandWindow(PlatformWindowDelegate* delegate,
+ WaylandConnection* connection);
- private:
- FRIEND_TEST_ALL_PREFIXES(WaylandScreenTest, SetBufferScale);
+ WaylandConnection* connection() { return connection_; }
+ PlatformWindowDelegate* delegate() { return delegate_; }
+ // Sets bounds in dip.
void SetBoundsDip(const gfx::Rect& bounds_dip);
- void SetBufferScale(int32_t scale, bool update_bounds);
- bool IsMinimized() const;
- bool IsMaximized() const;
- bool IsFullscreen() const;
+ // Gets a parent window for this window.
+ WaylandWindow* GetParentWindow(gfx::AcceleratedWidget parent_widget);
- void MaybeTriggerPendingStateChange();
+ // Sets the buffer scale.
+ void SetBufferScale(int32_t scale, bool update_bounds);
- // Creates a popup window, which is visible as a menu window.
- void CreateShellPopup();
- // Creates a surface window, which is visible as a main window.
- void CreateShellSurface();
- // Creates (if necessary) and show subsurface window, to host
- // tooltip's content.
- void CreateAndShowTooltipSubSurface();
+ // Sets the ui scale.
+ void set_ui_scale(int32_t ui_scale) { ui_scale_ = ui_scale; }
- // Gets a parent window for this window.
- WaylandWindow* GetParentWindow(gfx::AcceleratedWidget parent_widget);
+ private:
+ FRIEND_TEST_ALL_PREFIXES(WaylandScreenTest, SetBufferScale);
+
+ // Initializes the WaylandWindow with supplied properties.
+ bool Initialize(PlatformWindowInitProperties properties);
// Returns a root parent window.
WaylandWindow* GetRootParentWindow();
- WmMoveResizeHandler* AsWmMoveResizeHandler();
-
// Install a surface listener and start getting wl_output enter/leave events.
void AddSurfaceListener();
@@ -205,9 +189,6 @@ class WaylandWindow : public PlatformWindow,
void UpdateCursorPositionFromEvent(std::unique_ptr<Event> event);
- // Returns bounds with origin relative to parent window's origin.
- gfx::Rect AdjustPopupWindowPosition() const;
-
WaylandWindow* GetTopLevelWindow();
// It's important to set opaque region for opaque windows (provides
@@ -216,6 +197,9 @@ class WaylandWindow : public PlatformWindow,
bool IsOpaqueWindow() const;
+ // Additional initialization of derived classes.
+ virtual bool OnInitialize(PlatformWindowInitProperties properties) = 0;
+
// wl_surface_listener
static void Enter(void* data,
struct wl_surface* wl_surface,
@@ -229,33 +213,11 @@ class WaylandWindow : public PlatformWindow,
WaylandWindow* parent_window_ = nullptr;
WaylandWindow* child_window_ = nullptr;
- // Creates xdg objects based on xdg shell version.
- std::unique_ptr<XDGShellObjectFactory> xdg_shell_objects_factory_;
-
wl::Object<wl_surface> surface_;
- wl::Object<wl_subsurface> tooltip_subsurface_;
-
- // Wrappers around xdg v5 and xdg v6 objects. WaylandWindow doesn't
- // know anything about the version.
- std::unique_ptr<ShellSurfaceWrapper> shell_surface_;
- std::unique_ptr<ShellPopupWrapper> shell_popup_;
// The current cursor bitmap (immutable).
scoped_refptr<BitmapCursorOzone> bitmap_;
- base::OnceCallback<void(int)> drag_closed_callback_;
-
- // These bounds attributes below have suffices that indicate units used.
- // Wayland operates in DIP but the platform operates in physical pixels so
- // our WaylandWindow is the link that has to translate the units. See also
- // comments in the implementation.
- //
- // Bounds that will be applied when the window state is finalized. The window
- // may get several configuration events that update the pending bounds, and
- // only upon finalizing the state is the latest value stored as the current
- // bounds via |ApplyPendingBounds|. Measured in DIP because updated in the
- // handler that receives DIP from Wayland.
- gfx::Rect pending_bounds_dip_;
// Current bounds of the platform window.
gfx::Rect bounds_px_;
// The bounds of the platform window before it went maximized or fullscreen.
@@ -273,20 +235,9 @@ class WaylandWindow : public PlatformWindow,
// We need it to place and size the menus properly.
float ui_scale_ = 1.0;
- // Stores current states of the window.
- PlatformWindowState state_;
- // Stores a pending state of the window, which is used before the surface is
- // activated.
- PlatformWindowState pending_state_;
-
// Stores current opacity of the window. Set on ::Initialize call.
ui::PlatformWindowOpacity opacity_;
- bool is_active_ = false;
- bool is_minimizing_ = false;
-
- bool is_tooltip_ = false;
-
// For top level window, stores IDs of outputs that the window is currently
// rendered at.
//
@@ -297,6 +248,9 @@ class WaylandWindow : public PlatformWindow,
// we ask its parent.
base::flat_set<uint32_t> entered_outputs_ids_;
+ // The type of the current WaylandWindow object.
+ ui::PlatformWindowType type_ = ui::PlatformWindowType::kWindow;
+
DISALLOW_COPY_AND_ASSIGN(WaylandWindow);
};
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_window_factory.cc b/chromium/ui/ozone/platform/wayland/host/wayland_window_factory.cc
new file mode 100644
index 00000000000..16db3567652
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_window_factory.cc
@@ -0,0 +1,57 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/wayland/host/wayland_window.h"
+
+#include <memory>
+
+#include "ui/gfx/native_widget_types.h"
+#include "ui/ozone/platform/wayland/host/wayland_connection.h"
+#include "ui/ozone/platform/wayland/host/wayland_popup.h"
+#include "ui/ozone/platform/wayland/host/wayland_subsurface.h"
+#include "ui/ozone/platform/wayland/host/wayland_surface.h"
+
+namespace ui {
+
+// static
+std::unique_ptr<WaylandWindow> WaylandWindow::Create(
+ PlatformWindowDelegate* delegate,
+ WaylandConnection* connection,
+ PlatformWindowInitProperties properties) {
+ std::unique_ptr<WaylandWindow> window;
+ switch (properties.type) {
+ case PlatformWindowType::kMenu:
+ case PlatformWindowType::kPopup:
+ // We are unable to create a popup or menu window, because they require a
+ // parent window to be set. Thus, create a normal window instead then.
+ if (properties.parent_widget == gfx::kNullAcceleratedWidget &&
+ !connection->wayland_window_manager()->GetCurrentFocusedWindow()) {
+ window.reset(new WaylandSurface(delegate, connection));
+ } else if (connection->IsDragInProgress()) {
+ // We are in the process of drag and requested a popup. Most probably,
+ // it is an arrow window.
+ window.reset(new WaylandSubsurface(delegate, connection));
+ } else {
+ window.reset(new WaylandPopup(delegate, connection));
+ }
+ break;
+ case PlatformWindowType::kTooltip:
+ window.reset(new WaylandSubsurface(delegate, connection));
+ break;
+ case PlatformWindowType::kWindow:
+ case PlatformWindowType::kBubble:
+ case PlatformWindowType::kDrag:
+ // TODO(msisov): Figure out what kind of surface we need to create for
+ // bubble and drag windows.
+ window.reset(new WaylandSurface(delegate, connection));
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ return window && window->Initialize(std::move(properties)) ? std::move(window)
+ : nullptr;
+}
+
+} // namespace ui \ No newline at end of file
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc b/chromium/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc
index 737c7cdd25d..a4b1fc7d943 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc
@@ -36,11 +36,10 @@ class WaylandWindowManagerTest : public WaylandTest {
PlatformWindowInitProperties properties;
properties.bounds = bounds;
properties.type = type;
-
- std::unique_ptr<WaylandWindow> window =
- std::make_unique<WaylandWindow>(delegate, connection_.get());
-
- EXPECT_TRUE(window->Initialize(std::move(properties)));
+ auto window = WaylandWindow::Create(delegate, connection_.get(),
+ std::move(properties));
+ if (window)
+ window->Show(false);
return window;
}
@@ -91,6 +90,9 @@ TEST_P(WaylandWindowManagerTest, GetCurrentFocusedWindow) {
auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
kDefaultBounds, &delegate);
+ // When window is shown, it automatically gets keyboard focus. Reset it.
+ window_->set_keyboard_focus(false);
+ window1->set_keyboard_focus(false);
Sync();
@@ -125,6 +127,9 @@ TEST_P(WaylandWindowManagerTest, GetCurrentKeyboardFocusedWindow) {
auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
kDefaultBounds, &delegate);
+ // When window is shown, it automatically gets keyboard focus. Reset it.
+ window_->set_keyboard_focus(false);
+ window1->set_keyboard_focus(false);
Sync();
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_window_unittest.cc b/chromium/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
index f8dc4429c07..3162fcf30ed 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_window_unittest.cc
@@ -26,6 +26,7 @@
#include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h"
#include "ui/ozone/platform/wayland/test/wayland_test.h"
#include "ui/ozone/test/mock_platform_window_delegate.h"
+#include "ui/platform_window/platform_window_handler/wm_move_resize_handler.h"
#include "ui/platform_window/platform_window_init_properties.h"
using ::testing::_;
@@ -127,11 +128,7 @@ class WaylandWindowTest : public WaylandTest {
}
}
- // Depending on a shell version, xdg_surface_ or xdg_toplevel surface should
- // get the mock calls. This method decided, which surface to use.
- wl::MockXdgSurface* GetXdgSurface() {
- return xdg_surface_->xdg_toplevel();
- }
+ wl::MockXdgTopLevel* GetXdgToplevel() { return xdg_surface_->xdg_toplevel(); }
void AddStateToWlArray(uint32_t state, wl_array* states) {
*static_cast<uint32_t*>(wl_array_add(states, sizeof state)) = state;
@@ -150,20 +147,22 @@ class WaylandWindowTest : public WaylandTest {
return result;
}
- bool CreateWaylandWindowWithParams(PlatformWindowType type,
- gfx::AcceleratedWidget parent_widget,
- const gfx::Rect bounds,
- MockPlatformWindowDelegate* delegate,
- std::unique_ptr<WaylandWindow>* window) {
+ std::unique_ptr<WaylandWindow> CreateWaylandWindowWithParams(
+ PlatformWindowType type,
+ gfx::AcceleratedWidget parent_widget,
+ const gfx::Rect bounds,
+ MockPlatformWindowDelegate* delegate) {
PlatformWindowInitProperties properties;
// TODO(msisov): use a fancy method to calculate position of a popup window.
properties.bounds = bounds;
properties.type = type;
properties.parent_widget = parent_widget;
- *window = std::make_unique<WaylandWindow>(delegate, connection_.get());
-
- return (*window)->Initialize(std::move(properties));
+ auto window = WaylandWindow::Create(delegate, connection_.get(),
+ std::move(properties));
+ if (window)
+ window->Show(false);
+ return window;
}
void InitializeWithSupportedHitTestValues(std::vector<int>* hit_tests) {
@@ -213,7 +212,7 @@ class WaylandWindowTest : public WaylandTest {
};
TEST_P(WaylandWindowTest, SetTitle) {
- EXPECT_CALL(*GetXdgSurface(), SetTitle(StrEq("hello")));
+ EXPECT_CALL(*GetXdgToplevel(), SetTitle(StrEq("hello")));
window_->SetTitle(base::ASCIIToUTF16("hello"));
}
@@ -229,13 +228,12 @@ TEST_P(WaylandWindowTest, MaximizeAndRestore) {
auto active_maximized = MakeStateArray(
{XDG_TOPLEVEL_STATE_ACTIVATED, XDG_TOPLEVEL_STATE_MAXIMIZED});
- EXPECT_CALL(*GetXdgSurface(), SetMaximized());
+ EXPECT_CALL(*GetXdgToplevel(), SetMaximized());
EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kMaximizedBounds.width(),
kMaximizedBounds.height()));
EXPECT_CALL(delegate_, OnActivationChanged(Eq(true)));
EXPECT_CALL(delegate_, OnBoundsChanged(kMaximizedBounds));
- EXPECT_CALL(delegate_,
- OnWindowStateChanged(Eq(PlatformWindowState::kMaximized)));
+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
window_->Maximize();
SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 1,
active_maximized.get());
@@ -250,7 +248,6 @@ TEST_P(WaylandWindowTest, MaximizeAndRestore) {
SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 2,
inactive_maximized.get());
Sync();
- EXPECT_FALSE(window_->is_active());
VerifyAndClearExpectations();
EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kMaximizedBounds.width(),
@@ -260,16 +257,14 @@ TEST_P(WaylandWindowTest, MaximizeAndRestore) {
SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 3,
active_maximized.get());
Sync();
- EXPECT_TRUE(window_->is_active());
VerifyAndClearExpectations();
EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kNormalBounds.width(),
kNormalBounds.height()));
- EXPECT_CALL(delegate_,
- OnWindowStateChanged(Eq(PlatformWindowState::kNormal)));
+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
EXPECT_CALL(delegate_, OnActivationChanged(_)).Times(0);
EXPECT_CALL(delegate_, OnBoundsChanged(kNormalBounds));
- EXPECT_CALL(*GetXdgSurface(), UnsetMaximized());
+ EXPECT_CALL(*GetXdgToplevel(), UnsetMaximized());
window_->Restore();
// Reinitialize wl_array, which removes previous old states.
auto active = InitializeWlArrayWithActivatedState();
@@ -285,20 +280,22 @@ TEST_P(WaylandWindowTest, Minimize) {
SendConfigureEvent(0, 0, 1, states.get());
Sync();
- EXPECT_CALL(*GetXdgSurface(), SetMinimized());
- // Wayland compositor doesn't notify clients about minimized state, but rather
- // if a window is not activated. Thus, a WaylandWindow marks itself as being
- // minimized and as soon as a configuration event with not activated state
- // comes, its state is changed to minimized. This EXPECT_CALL ensures this
- // behaviour.
- EXPECT_CALL(delegate_,
- OnWindowStateChanged(Eq(PlatformWindowState::kMinimized)));
+ EXPECT_CALL(*GetXdgToplevel(), SetMinimized());
+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
window_->Minimize();
+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMinimized);
+
// Reinitialize wl_array, which removes previous old states.
states = ScopedWlArray();
SendConfigureEvent(0, 0, 2, states.get());
Sync();
+ // Wayland compositor doesn't notify clients about minimized state, but rather
+ // if a window is not activated. Thus, a WaylandSurface marks itself as being
+ // minimized and and sets state to minimized. Thus, the state mustn't change
+ // after the configuration event is sent.
+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMinimized);
+
// Send one additional empty configuration event (which means the surface is
// not maximized, fullscreen or activated) to ensure, WaylandWindow stays in
// the same minimized state and doesn't notify its delegate.
@@ -321,9 +318,8 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get());
- EXPECT_CALL(*GetXdgSurface(), SetFullscreen());
- EXPECT_CALL(delegate_,
- OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen)));
+ EXPECT_CALL(*GetXdgToplevel(), SetFullscreen());
+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
window_->ToggleFullscreen();
// Make sure than WaylandWindow manually handles fullscreen states. Check the
// comment in the WaylandWindow::ToggleFullscreen.
@@ -332,52 +328,182 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
SendConfigureEvent(0, 0, 2, states.get());
Sync();
- EXPECT_CALL(*GetXdgSurface(), UnsetFullscreen());
- EXPECT_CALL(delegate_,
- OnWindowStateChanged(Eq(PlatformWindowState::kNormal)));
+ EXPECT_CALL(*GetXdgToplevel(), UnsetFullscreen());
+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
window_->Restore();
- EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kUnknown);
+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kNormal);
// Reinitialize wl_array, which removes previous old states.
states = InitializeWlArrayWithActivatedState();
SendConfigureEvent(0, 0, 3, states.get());
Sync();
+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kNormal);
}
TEST_P(WaylandWindowTest, StartWithFullscreen) {
+ MockPlatformWindowDelegate delegate;
+ PlatformWindowInitProperties properties;
+ properties.bounds = gfx::Rect(0, 0, 100, 100);
+ properties.type = PlatformWindowType::kWindow;
+ // We need to create a window avoid calling Show() on it as it is what upper
+ // views layer does - when Widget initialize DesktopWindowTreeHost, the Show()
+ // is called later down the road, but Maximize may be called earlier. We
+ // cannot process them and set a pending state instead, because ShellSurface
+ // is not created by that moment.
+ auto window = WaylandWindow::Create(&delegate, connection_.get(),
+ std::move(properties));
+
+ Sync();
+
+ // Make sure the window is initialized to normal state from the beginning.
+ EXPECT_EQ(PlatformWindowState::kNormal, window->GetPlatformWindowState());
+
+ // The state must not be changed to the fullscreen before the surface is
+ // activated.
+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget());
+ EXPECT_FALSE(mock_surface->xdg_surface());
+ EXPECT_CALL(delegate, OnWindowStateChanged(_)).Times(0);
+ window->ToggleFullscreen();
+ // The state of the window must already be fullscreen one.
+ EXPECT_EQ(window->GetPlatformWindowState(), PlatformWindowState::kFullScreen);
+
+ Sync();
+
+ // We mustn't receive any state changes if that does not differ from the last
+ // state.
+ EXPECT_CALL(delegate, OnWindowStateChanged(_)).Times(0);
+
+ // Activate the surface.
+ ScopedWlArray states = InitializeWlArrayWithActivatedState();
+ AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get());
+ SendConfigureEvent(0, 0, 1, states.get());
+
+ Sync();
+
+ // It must be still the same state.
+ EXPECT_EQ(window->GetPlatformWindowState(), PlatformWindowState::kFullScreen);
+}
+
+TEST_P(WaylandWindowTest, StartMaximized) {
+ MockPlatformWindowDelegate delegate;
+ PlatformWindowInitProperties properties;
+ properties.bounds = gfx::Rect(0, 0, 100, 100);
+ properties.type = PlatformWindowType::kWindow;
+ // We need to create a window avoid calling Show() on it as it is what upper
+ // views layer does - when Widget initialize DesktopWindowTreeHost, the Show()
+ // is called later down the road, but Maximize may be called earlier. We
+ // cannot process them and set a pending state instead, because ShellSurface
+ // is not created by that moment.
+ auto window = WaylandWindow::Create(&delegate, connection_.get(),
+ std::move(properties));
+
+ Sync();
+
// Make sure the window is initialized to normal state from the beginning.
EXPECT_EQ(PlatformWindowState::kNormal, window_->GetPlatformWindowState());
// The state must not be changed to the fullscreen before the surface is
// activated.
- EXPECT_CALL(*GetXdgSurface(), SetFullscreen()).Times(0);
+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget());
+ EXPECT_FALSE(mock_surface->xdg_surface());
EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
- window_->ToggleFullscreen();
- // The state of the window must still be a normal one.
- EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kNormal);
+
+ window_->Maximize();
+ // The state of the window must already be fullscreen one.
+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMaximized);
Sync();
- // Once the surface will be activated, the window will automatically trigger
- // the state change.
- EXPECT_CALL(*GetXdgSurface(), SetFullscreen());
- EXPECT_CALL(delegate_,
- OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen)));
+ // Once the surface will be activated, the window state mustn't be changed
+ // and retain the same.
+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMaximized);
// Activate the surface.
ScopedWlArray states = InitializeWlArrayWithActivatedState();
+ AddStateToWlArray(XDG_TOPLEVEL_STATE_MAXIMIZED, states.get());
SendConfigureEvent(0, 0, 1, states.get());
Sync();
- // The wayland window manually handles the fullscreen state changes, and it
- // must change to a fullscreen before the state change is confirmed by the
- // wayland. See comment in the WaylandWindow::ToggleFullscreen.
- EXPECT_EQ(window_->GetPlatformWindowState(),
- PlatformWindowState::kFullScreen);
+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMaximized);
+}
- AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get());
+TEST_P(WaylandWindowTest, CompositorSideStateChanges) {
+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kNormal);
+ auto normal_bounds = window_->GetBounds();
+
+ ScopedWlArray states = InitializeWlArrayWithActivatedState();
+ AddStateToWlArray(XDG_TOPLEVEL_STATE_MAXIMIZED, states.get());
+ SendConfigureEvent(2000, 2000, 1, states.get());
+
+ EXPECT_CALL(delegate_,
+ OnWindowStateChanged(Eq(PlatformWindowState::kMaximized)))
+ .Times(1);
+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 2000, 2000));
+
+ Sync();
+
+ EXPECT_EQ(window_->GetPlatformWindowState(), PlatformWindowState::kMaximized);
+
+ // Unmaximize
+ states = InitializeWlArrayWithActivatedState();
SendConfigureEvent(0, 0, 2, states.get());
+ EXPECT_CALL(delegate_, OnWindowStateChanged(Eq(PlatformWindowState::kNormal)))
+ .Times(1);
+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, normal_bounds.width(),
+ normal_bounds.height()));
+
+ // Now, set to fullscreen.
+ AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get());
+ SendConfigureEvent(2005, 2005, 3, states.get());
+ EXPECT_CALL(delegate_,
+ OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen)))
+ .Times(1);
+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 2005, 2005));
+
+ Sync();
+
+ // Unfullscreen
+ states = InitializeWlArrayWithActivatedState();
+ SendConfigureEvent(0, 0, 4, states.get());
+
+ EXPECT_CALL(delegate_, OnWindowStateChanged(Eq(PlatformWindowState::kNormal)))
+ .Times(1);
+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, normal_bounds.width(),
+ normal_bounds.height()));
+
+ Sync();
+
+ // Now, maximize, fullscreen and restore.
+ states = InitializeWlArrayWithActivatedState();
+ AddStateToWlArray(XDG_TOPLEVEL_STATE_MAXIMIZED, states.get());
+ SendConfigureEvent(2000, 2000, 1, states.get());
+
+ EXPECT_CALL(delegate_,
+ OnWindowStateChanged(Eq(PlatformWindowState::kMaximized)))
+ .Times(1);
+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 2000, 2000));
+
+ Sync();
+
+ AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, states.get());
+ SendConfigureEvent(2005, 2005, 1, states.get());
+
+ EXPECT_CALL(delegate_,
+ OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen)))
+ .Times(1);
+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, 2005, 2005));
+
+ // Restore
+ states = InitializeWlArrayWithActivatedState();
+ SendConfigureEvent(0, 0, 4, states.get());
+
+ EXPECT_CALL(delegate_, OnWindowStateChanged(Eq(PlatformWindowState::kNormal)))
+ .Times(1);
+ EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, normal_bounds.width(),
+ normal_bounds.height()));
+
Sync();
}
@@ -393,44 +519,53 @@ TEST_P(WaylandWindowTest, SetMaximizedFullscreenAndRestore) {
auto active_maximized = MakeStateArray(
{XDG_TOPLEVEL_STATE_ACTIVATED, XDG_TOPLEVEL_STATE_MAXIMIZED});
- EXPECT_CALL(*GetXdgSurface(), SetMaximized());
+ EXPECT_CALL(*GetXdgToplevel(), SetMaximized());
EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kMaximizedBounds.width(),
kMaximizedBounds.height()));
EXPECT_CALL(delegate_, OnActivationChanged(Eq(true)));
EXPECT_CALL(delegate_, OnBoundsChanged(kMaximizedBounds));
- EXPECT_CALL(delegate_,
- OnWindowStateChanged(Eq(PlatformWindowState::kMaximized)));
+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
window_->Maximize();
+ // State changes are synchronous.
+ EXPECT_EQ(PlatformWindowState::kMaximized, window_->GetPlatformWindowState());
SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 2,
active_maximized.get());
Sync();
+ // Verify that the state has not been changed.
+ EXPECT_EQ(PlatformWindowState::kMaximized, window_->GetPlatformWindowState());
VerifyAndClearExpectations();
- EXPECT_CALL(*GetXdgSurface(), SetFullscreen());
+ EXPECT_CALL(*GetXdgToplevel(), SetFullscreen());
EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kMaximizedBounds.width(),
kMaximizedBounds.height()));
EXPECT_CALL(delegate_, OnBoundsChanged(_)).Times(0);
- EXPECT_CALL(delegate_,
- OnWindowStateChanged(Eq(PlatformWindowState::kFullScreen)));
+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
window_->ToggleFullscreen();
+ // State changes are synchronous.
+ EXPECT_EQ(PlatformWindowState::kFullScreen,
+ window_->GetPlatformWindowState());
AddStateToWlArray(XDG_TOPLEVEL_STATE_FULLSCREEN, active_maximized.get());
SendConfigureEvent(kMaximizedBounds.width(), kMaximizedBounds.height(), 3,
active_maximized.get());
Sync();
+ // Verify that the state has not been changed.
+ EXPECT_EQ(PlatformWindowState::kFullScreen,
+ window_->GetPlatformWindowState());
VerifyAndClearExpectations();
EXPECT_CALL(*xdg_surface_, SetWindowGeometry(0, 0, kNormalBounds.width(),
kNormalBounds.height()));
- EXPECT_CALL(*GetXdgSurface(), UnsetFullscreen());
- EXPECT_CALL(*GetXdgSurface(), UnsetMaximized());
+ EXPECT_CALL(*GetXdgToplevel(), UnsetFullscreen());
+ EXPECT_CALL(*GetXdgToplevel(), UnsetMaximized());
EXPECT_CALL(delegate_, OnBoundsChanged(kNormalBounds));
- EXPECT_CALL(delegate_,
- OnWindowStateChanged(Eq(PlatformWindowState::kNormal)));
+ EXPECT_CALL(delegate_, OnWindowStateChanged(_)).Times(0);
window_->Restore();
+ EXPECT_EQ(PlatformWindowState::kNormal, window_->GetPlatformWindowState());
// Reinitialize wl_array, which removes previous old states.
auto active = InitializeWlArrayWithActivatedState();
SendConfigureEvent(0, 0, 4, active.get());
Sync();
+ EXPECT_EQ(PlatformWindowState::kNormal, window_->GetPlatformWindowState());
}
TEST_P(WaylandWindowTest, RestoreBoundsAfterMaximize) {
@@ -704,21 +839,17 @@ TEST_P(WaylandWindowTest, ConfigureEventWithNulledSize) {
}
TEST_P(WaylandWindowTest, OnActivationChanged) {
- EXPECT_FALSE(window_->is_active());
-
{
ScopedWlArray states = InitializeWlArrayWithActivatedState();
EXPECT_CALL(delegate_, OnActivationChanged(Eq(true)));
SendConfigureEvent(0, 0, 1, states.get());
Sync();
- EXPECT_TRUE(window_->is_active());
}
ScopedWlArray states;
EXPECT_CALL(delegate_, OnActivationChanged(Eq(false)));
SendConfigureEvent(0, 0, 2, states.get());
Sync();
- EXPECT_FALSE(window_->is_active());
}
TEST_P(WaylandWindowTest, OnAcceleratedWidgetDestroy) {
@@ -736,27 +867,31 @@ TEST_P(WaylandWindowTest, CanCreateMenuWindow) {
ASSERT_TRUE(connection_->pointer() && connection_->touch());
window_->SetPointerFocus(true);
- std::unique_ptr<WaylandWindow> menu_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, gfx::kNullAcceleratedWidget,
- gfx::Rect(0, 0, 10, 10), &menu_window_delegate, &menu_window));
+ gfx::Rect(0, 0, 10, 10), &menu_window_delegate);
+ EXPECT_TRUE(menu_window);
Sync();
window_->SetPointerFocus(false);
window_->set_touch_focus(false);
- EXPECT_FALSE(CreateWaylandWindowWithParams(
+ // Given that there is no parent passed and we don't have any focused windows,
+ // Wayland must still create a window.
+ menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, gfx::kNullAcceleratedWidget,
- gfx::Rect(0, 0, 10, 10), &menu_window_delegate, &menu_window));
+ gfx::Rect(0, 0, 10, 10), &menu_window_delegate);
+ EXPECT_TRUE(menu_window);
Sync();
window_->set_touch_focus(true);
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, gfx::kNullAcceleratedWidget,
- gfx::Rect(0, 0, 10, 10), &menu_window_delegate, &menu_window));
+ gfx::Rect(0, 0, 10, 10), &menu_window_delegate);
+ EXPECT_TRUE(menu_window);
Sync();
}
@@ -767,29 +902,30 @@ TEST_P(WaylandWindowTest, CreateAndDestroyNestedMenuWindow) {
EXPECT_CALL(menu_window_delegate, OnAcceleratedWidgetAvailable(_))
.WillOnce(SaveArg<0>(&menu_window_widget));
- std::unique_ptr<WaylandWindow> menu_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10),
- &menu_window_delegate, &menu_window));
+ &menu_window_delegate);
+ EXPECT_TRUE(menu_window);
ASSERT_NE(menu_window_widget, gfx::kNullAcceleratedWidget);
Sync();
MockPlatformWindowDelegate nested_menu_window_delegate;
- std::unique_ptr<WaylandWindow> nested_menu_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
- PlatformWindowType::kMenu, menu_window_widget, gfx::Rect(20, 0, 10, 10),
- &nested_menu_window_delegate, &nested_menu_window));
+ std::unique_ptr<WaylandWindow> nested_menu_window =
+ CreateWaylandWindowWithParams(
+ PlatformWindowType::kMenu, menu_window_widget,
+ gfx::Rect(20, 0, 10, 10), &nested_menu_window_delegate);
+ EXPECT_TRUE(nested_menu_window);
Sync();
}
TEST_P(WaylandWindowTest, CanDispatchEventToMenuWindowNonNested) {
MockPlatformWindowDelegate menu_window_delegate;
- std::unique_ptr<WaylandWindow> menu_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10),
- &menu_window_delegate, &menu_window));
+ &menu_window_delegate);
+ EXPECT_TRUE(menu_window);
wl_seat_send_capabilities(server_.seat()->resource(),
WL_SEAT_CAPABILITY_POINTER);
@@ -812,18 +948,19 @@ TEST_P(WaylandWindowTest, CanDispatchEventToMenuWindowNested) {
EXPECT_CALL(menu_window_delegate, OnAcceleratedWidgetAvailable(_))
.WillOnce(SaveArg<0>(&menu_window_widget));
- std::unique_ptr<WaylandWindow> menu_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, widget_, gfx::Rect(0, 0, 10, 10),
- &menu_window_delegate, &menu_window));
+ &menu_window_delegate);
+ EXPECT_TRUE(menu_window);
Sync();
MockPlatformWindowDelegate nested_menu_window_delegate;
- std::unique_ptr<WaylandWindow> nested_menu_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
- PlatformWindowType::kMenu, menu_window_widget, gfx::Rect(20, 0, 10, 10),
- &nested_menu_window_delegate, &nested_menu_window));
+ std::unique_ptr<WaylandWindow> nested_menu_window =
+ CreateWaylandWindowWithParams(
+ PlatformWindowType::kMenu, menu_window_widget,
+ gfx::Rect(20, 0, 10, 10), &nested_menu_window_delegate);
+ EXPECT_TRUE(nested_menu_window);
Sync();
@@ -843,8 +980,8 @@ TEST_P(WaylandWindowTest, CanDispatchEventToMenuWindowNested) {
}
TEST_P(WaylandWindowTest, DispatchWindowMove) {
- EXPECT_CALL(*GetXdgSurface(), Move(_));
- window_->DispatchHostWindowDragMovement(HTCAPTION, gfx::Point());
+ EXPECT_CALL(*GetXdgToplevel(), Move(_));
+ ui::GetWmMoveResizeHandler(*window_)->DispatchHostWindowDragMovement(HTCAPTION, gfx::Point());
}
// Makes sure hit tests are converted into right edges.
@@ -852,11 +989,14 @@ TEST_P(WaylandWindowTest, DispatchWindowResize) {
std::vector<int> hit_test_values;
InitializeWithSupportedHitTestValues(&hit_test_values);
+ auto* wm_move_resize_handler = ui::GetWmMoveResizeHandler(*window_);
+
for (const int value : hit_test_values) {
{
uint32_t direction = wl::IdentifyDirection(*(connection_.get()), value);
- EXPECT_CALL(*GetXdgSurface(), Resize(_, Eq(direction)));
- window_->DispatchHostWindowDragMovement(value, gfx::Point());
+ EXPECT_CALL(*GetXdgToplevel(), Resize(_, Eq(direction)));
+ wm_move_resize_handler->DispatchHostWindowDragMovement(value,
+ gfx::Point());
}
}
}
@@ -903,10 +1043,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
MockPlatformWindowDelegate menu_window_delegate;
gfx::Rect menu_window_bounds(gfx::Point(440, 76),
menu_window_positioner.size);
- std::unique_ptr<WaylandWindow> menu_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, toplevel_window->GetWidget(),
- menu_window_bounds, &menu_window_delegate, &menu_window));
+ menu_window_bounds, &menu_window_delegate);
+ EXPECT_TRUE(menu_window);
Sync();
@@ -924,10 +1064,11 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
MockPlatformWindowDelegate nested_menu_window_delegate;
gfx::Rect nested_menu_window_bounds(gfx::Point(723, 156),
nested_menu_window_positioner.size);
- std::unique_ptr<WaylandWindow> nested_menu_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
- PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds,
- &nested_menu_window_delegate, &nested_menu_window));
+ std::unique_ptr<WaylandWindow> nested_menu_window =
+ CreateWaylandWindowWithParams(
+ PlatformWindowType::kMenu, menu_window_widget,
+ nested_menu_window_bounds, &nested_menu_window_delegate);
+ EXPECT_TRUE(nested_menu_window);
Sync();
@@ -985,9 +1126,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
// side. Thus, we have to check that anchor rect is correct.
nested_menu_window.reset();
nested_menu_window_bounds.set_origin({723, 258});
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ nested_menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds,
- &nested_menu_window_delegate, &nested_menu_window));
+ &nested_menu_window_delegate);
+ EXPECT_TRUE(nested_menu_window);
Sync();
@@ -1050,9 +1192,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
window_->SetBounds(gfx::Rect(0, 0, 2493, 1413));
menu_window_bounds.set_origin({2206, 67});
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, toplevel_window->GetWidget(),
- menu_window_bounds, &menu_window_delegate, &menu_window));
+ menu_window_bounds, &menu_window_delegate);
+ EXPECT_TRUE(menu_window);
Sync();
@@ -1066,9 +1209,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
Sync();
nested_menu_window_bounds.set_origin({1905, 147});
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ nested_menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds,
- &nested_menu_window_delegate, &nested_menu_window));
+ &nested_menu_window_delegate);
+ EXPECT_TRUE(nested_menu_window);
Sync();
@@ -1087,7 +1231,7 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
// shown on another display.
auto active_maximized = MakeStateArray(
{XDG_TOPLEVEL_STATE_ACTIVATED, XDG_TOPLEVEL_STATE_MAXIMIZED});
- EXPECT_CALL(*GetXdgSurface(), SetMaximized());
+ EXPECT_CALL(*GetXdgToplevel(), SetMaximized());
window_->Maximize();
SendConfigureEvent(2493, 1413, 1, active_maximized.get());
@@ -1096,9 +1240,10 @@ TEST_P(WaylandWindowTest, AdjustPopupBounds) {
nested_menu_window.reset();
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ nested_menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, menu_window_widget, nested_menu_window_bounds,
- &nested_menu_window_delegate, &nested_menu_window));
+ &nested_menu_window_delegate);
+ EXPECT_TRUE(nested_menu_window);
Sync();
@@ -1170,61 +1315,114 @@ TEST_P(WaylandWindowTest, OnCloseRequest) {
Sync();
}
-TEST_P(WaylandWindowTest, TooltipSimpleParent) {
+TEST_P(WaylandWindowTest, SubsurfaceSimpleParent) {
VerifyAndClearExpectations();
- gfx::Rect tooltip_window_bounds(gfx::Point(15, 15), gfx::Size(10, 10));
- std::unique_ptr<WaylandWindow> tooltip_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
- PlatformWindowType::kTooltip, window_->GetWidget(), tooltip_window_bounds,
- &delegate_, &tooltip_window));
+ std::unique_ptr<WaylandWindow> second_window = CreateWaylandWindowWithParams(
+ PlatformWindowType::kWindow, gfx::kNullAcceleratedWidget,
+ gfx::Rect(0, 0, 640, 480), &delegate_);
+ EXPECT_TRUE(second_window);
- window_->SetPointerFocus(true);
+ // Test case 1: if the subsurface is provided with a parent widget, it must
+ // always use that as a parent.
+ gfx::Rect subsurface_bounds(gfx::Point(15, 15), gfx::Size(10, 10));
+ std::unique_ptr<WaylandWindow> subsuface_window =
+ CreateWaylandWindowWithParams(PlatformWindowType::kTooltip,
+ window_->GetWidget(), subsurface_bounds,
+ &delegate_);
+ EXPECT_TRUE(subsuface_window);
- tooltip_window->Show(false);
+ // The subsurface mustn't take the focused window as a parent, but use the
+ // provided one.
+ second_window->SetPointerFocus(true);
+ subsuface_window->Show(false);
Sync();
- auto* mock_tooltip_surface =
- server_.GetObject<wl::MockSurface>(tooltip_window->GetWidget());
- auto* test_subsurface = mock_tooltip_surface->sub_surface();
+ auto* mock_surface_subsurface =
+ server_.GetObject<wl::MockSurface>(subsuface_window->GetWidget());
+ auto* test_subsurface = mock_surface_subsurface->sub_surface();
- EXPECT_EQ(test_subsurface->position(), tooltip_window_bounds.origin());
+ EXPECT_EQ(test_subsurface->position(), subsurface_bounds.origin());
EXPECT_FALSE(test_subsurface->sync());
+ auto* parent_resource =
+ server_.GetObject<wl::MockSurface>(window_->GetWidget())->resource();
+ EXPECT_EQ(parent_resource, test_subsurface->parent_resource());
+
+ // Test case 2: the subsurface must use the focused window as its parent.
+ subsuface_window = CreateWaylandWindowWithParams(
+ PlatformWindowType::kTooltip, gfx::kNullAcceleratedWidget,
+ subsurface_bounds, &delegate_);
+ EXPECT_TRUE(subsuface_window);
+
+ // The tooltip must take the focused window.
+ second_window->SetPointerFocus(true);
+ subsuface_window->Show(false);
+
+ Sync();
+
+ // Get new surface after recreating the WaylandSubsurface.
+ mock_surface_subsurface =
+ server_.GetObject<wl::MockSurface>(subsuface_window->GetWidget());
+ test_subsurface = mock_surface_subsurface->sub_surface();
+
+ auto* second_parent_resource =
+ server_.GetObject<wl::MockSurface>(second_window->GetWidget())
+ ->resource();
+ EXPECT_EQ(second_parent_resource, test_subsurface->parent_resource());
+
+ subsuface_window->Hide();
+
+ Sync();
+
+ // The subsurface must take the focused window.
+ second_window->SetPointerFocus(false);
+ window_->SetPointerFocus(true);
+ subsuface_window->Show(false);
+
+ Sync();
+
+ // The subsurface is invalidated on each Hide call.
+ test_subsurface = mock_surface_subsurface->sub_surface();
+
+ // The |window_|'s resource must be the parent resource.
+ EXPECT_EQ(parent_resource, test_subsurface->parent_resource());
+
window_->SetPointerFocus(false);
}
-TEST_P(WaylandWindowTest, TooltipNestedParent) {
+TEST_P(WaylandWindowTest, SubsurfaceNestedParent) {
VerifyAndClearExpectations();
gfx::Rect menu_window_bounds(gfx::Point(10, 10), gfx::Size(100, 100));
- std::unique_ptr<WaylandWindow> menu_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
+ std::unique_ptr<WaylandWindow> menu_window = CreateWaylandWindowWithParams(
PlatformWindowType::kMenu, window_->GetWidget(), menu_window_bounds,
- &delegate_, &menu_window));
+ &delegate_);
+ EXPECT_TRUE(menu_window);
VerifyAndClearExpectations();
- gfx::Rect tooltip_window_bounds(gfx::Point(15, 15), gfx::Size(10, 10));
- std::unique_ptr<WaylandWindow> tooltip_window;
- EXPECT_TRUE(CreateWaylandWindowWithParams(
- PlatformWindowType::kTooltip, menu_window->GetWidget(),
- tooltip_window_bounds, &delegate_, &tooltip_window));
+ gfx::Rect subsurface_bounds(gfx::Point(15, 15), gfx::Size(10, 10));
+ std::unique_ptr<WaylandWindow> subsuface_window =
+ CreateWaylandWindowWithParams(PlatformWindowType::kTooltip,
+ menu_window->GetWidget(), subsurface_bounds,
+ &delegate_);
+ EXPECT_TRUE(subsuface_window);
VerifyAndClearExpectations();
menu_window->SetPointerFocus(true);
- tooltip_window->Show(false);
+ subsuface_window->Show(false);
Sync();
- auto* mock_tooltip_surface =
- server_.GetObject<wl::MockSurface>(tooltip_window->GetWidget());
- auto* test_subsurface = mock_tooltip_surface->sub_surface();
+ auto* mock_surface_subsurface =
+ server_.GetObject<wl::MockSurface>(subsuface_window->GetWidget());
+ auto* test_subsurface = mock_surface_subsurface->sub_surface();
- auto new_origin = tooltip_window_bounds.origin() -
+ auto new_origin = subsurface_bounds.origin() -
menu_window_bounds.origin().OffsetFromOrigin();
EXPECT_EQ(test_subsurface->position(), new_origin);
@@ -1246,9 +1444,9 @@ TEST_P(WaylandWindowTest, OnSizeConstraintsChanged) {
EXPECT_CALL(delegate_, GetMaximumSizeForWindow())
.WillOnce(Return(max_size));
- EXPECT_CALL(*GetXdgSurface(), SetMinSize(100, 200))
+ EXPECT_CALL(*GetXdgToplevel(), SetMinSize(100, 200))
.Times(has_min_size ? 1 : 0);
- EXPECT_CALL(*GetXdgSurface(), SetMaxSize(300, 400))
+ EXPECT_CALL(*GetXdgToplevel(), SetMaxSize(300, 400))
.Times(has_max_size ? 1 : 0);
window_->SizeConstraintsChanged();
@@ -1259,6 +1457,129 @@ TEST_P(WaylandWindowTest, OnSizeConstraintsChanged) {
}
}
+TEST_P(WaylandWindowTest, DestroysCreatesSurfaceOnHideShow) {
+ MockPlatformWindowDelegate delegate;
+ auto window = CreateWaylandWindowWithParams(
+ PlatformWindowType::kWindow, gfx::kNullAcceleratedWidget,
+ gfx::Rect(0, 0, 100, 100), &delegate);
+ ASSERT_TRUE(window);
+
+ Sync();
+
+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget());
+ EXPECT_TRUE(mock_surface->xdg_surface());
+ EXPECT_TRUE(mock_surface->xdg_surface()->xdg_toplevel());
+
+ Sync();
+
+ window->Hide();
+
+ Sync();
+
+ EXPECT_FALSE(mock_surface->xdg_surface());
+
+ window->Show(false);
+
+ Sync();
+
+ EXPECT_TRUE(mock_surface->xdg_surface());
+ EXPECT_TRUE(mock_surface->xdg_surface()->xdg_toplevel());
+}
+
+TEST_P(WaylandWindowTest, DestroysCreatesPopupsOnHideShow) {
+ MockPlatformWindowDelegate delegate;
+ auto window = CreateWaylandWindowWithParams(
+ PlatformWindowType::kMenu, window_->GetWidget(), gfx::Rect(0, 0, 50, 50),
+ &delegate);
+ ASSERT_TRUE(window);
+
+ Sync();
+
+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget());
+ EXPECT_TRUE(mock_surface->xdg_surface());
+ EXPECT_TRUE(mock_surface->xdg_surface()->xdg_popup());
+
+ Sync();
+
+ window->Hide();
+
+ Sync();
+
+ EXPECT_FALSE(mock_surface->xdg_surface());
+
+ window->Show(false);
+
+ Sync();
+
+ EXPECT_TRUE(mock_surface->xdg_surface());
+ EXPECT_TRUE(mock_surface->xdg_surface()->xdg_popup());
+}
+
+// Tests that if the window gets hidden and shown again, the title, app id and
+// size constraints remain the same.
+TEST_P(WaylandWindowTest, SetsPropertiesOnShow) {
+ constexpr char kAppId[] = "wayland_test";
+ const base::string16 kTitle(base::UTF8ToUTF16("WaylandWindowTest"));
+
+ PlatformWindowInitProperties properties;
+ properties.bounds = gfx::Rect(0, 0, 100, 100);
+ properties.type = PlatformWindowType::kWindow;
+ properties.wm_class_class = kAppId;
+
+ MockPlatformWindowDelegate delegate;
+ auto window = WaylandWindow::Create(&delegate, connection_.get(),
+ std::move(properties));
+ DCHECK(window);
+ window->Show(false);
+
+ Sync();
+
+ auto* mock_surface = server_.GetObject<wl::MockSurface>(window->GetWidget());
+ auto* mock_xdg_toplevel = mock_surface->xdg_surface()->xdg_toplevel();
+
+ // Only app id must be set now.
+ EXPECT_EQ(std::string(kAppId), mock_xdg_toplevel->app_id());
+ EXPECT_TRUE(mock_xdg_toplevel->title().empty());
+ EXPECT_TRUE(mock_xdg_toplevel->min_size().IsEmpty());
+ EXPECT_TRUE(mock_xdg_toplevel->max_size().IsEmpty());
+
+ // Now, propagate size constraints and title.
+ base::Optional<gfx::Size> min_size(gfx::Size(1, 1));
+ base::Optional<gfx::Size> max_size(gfx::Size(100, 100));
+ EXPECT_CALL(delegate, GetMinimumSizeForWindow()).WillOnce(Return(min_size));
+ EXPECT_CALL(delegate, GetMaximumSizeForWindow()).WillOnce(Return(max_size));
+
+ EXPECT_CALL(*mock_xdg_toplevel,
+ SetMinSize(min_size.value().width(), min_size.value().height()));
+ EXPECT_CALL(*mock_xdg_toplevel,
+ SetMaxSize(max_size.value().width(), max_size.value().height()));
+ EXPECT_CALL(*mock_xdg_toplevel, SetTitle(base::UTF16ToUTF8(kTitle)));
+
+ window->SetTitle(kTitle);
+ window->SizeConstraintsChanged();
+
+ Sync();
+
+ window->Hide();
+
+ Sync();
+
+ window->Show(false);
+
+ Sync();
+
+ mock_xdg_toplevel = mock_surface->xdg_surface()->xdg_toplevel();
+
+ // We can't mock all those methods above as long as the xdg_toplevel is
+ // created and destroyed on each show and hide call. However, it is the same
+ // WaylandSurface object that cached the values we set and must restore them
+ // on Show().
+ EXPECT_EQ(mock_xdg_toplevel->min_size(), min_size.value());
+ EXPECT_EQ(mock_xdg_toplevel->max_size(), max_size.value());
+ EXPECT_EQ(std::string(kAppId), mock_xdg_toplevel->app_id());
+ EXPECT_EQ(mock_xdg_toplevel->title(), base::UTF16ToUTF8(kTitle));
+}
+
INSTANTIATE_TEST_SUITE_P(XdgVersionStableTest,
WaylandWindowTest,
::testing::Values(kXdgShellStable));
diff --git a/chromium/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc b/chromium/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc
index c5fc7a317c7..991ae63fc1c 100644
--- a/chromium/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc
+++ b/chromium/ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.cc
@@ -7,7 +7,7 @@
#include <drm_fourcc.h>
#include <linux-dmabuf-unstable-v1-client-protocol.h>
-#include "ui/ozone/common/linux/drm_util_linux.h"
+#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
namespace ui {
diff --git a/chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc b/chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc
index 0c6683828e7..35ab0875304 100644
--- a/chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc
+++ b/chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.cc
@@ -12,9 +12,11 @@
#include "base/nix/xdg_util.h"
#include "ui/events/event_constants.h"
#include "ui/gfx/geometry/rect.h"
+#include "ui/ozone/platform/wayland/common/wayland_util.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_pointer.h"
-#include "ui/ozone/platform/wayland/host/wayland_window.h"
+#include "ui/ozone/platform/wayland/host/wayland_popup.h"
+#include "ui/ozone/platform/wayland/host/wayland_surface.h"
#include "ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h"
namespace ui {
@@ -260,40 +262,55 @@ XDGPopupWrapperImpl::XDGPopupWrapperImpl(
WaylandWindow* wayland_window)
: wayland_window_(wayland_window), xdg_surface_(std::move(surface)) {
DCHECK(xdg_surface_);
+ DCHECK(wayland_window_ && wayland_window_->parent_window());
}
-XDGPopupWrapperImpl::~XDGPopupWrapperImpl() {}
+XDGPopupWrapperImpl::~XDGPopupWrapperImpl() = default;
-bool XDGPopupWrapperImpl::InitializeStable(WaylandConnection* connection,
- wl_surface* surface,
- WaylandWindow* parent_window,
- const gfx::Rect& bounds) {
- DCHECK(connection && surface && parent_window);
- static const struct xdg_popup_listener xdg_popup_listener = {
- &XDGPopupWrapperImpl::ConfigureStable,
- &XDGPopupWrapperImpl::PopupDoneStable,
- };
-
- if (!xdg_surface_)
+bool XDGPopupWrapperImpl::Initialize(WaylandConnection* connection,
+ const gfx::Rect& bounds) {
+ if (!connection->shell() && !connection->shell_v6()) {
+ NOTREACHED() << "Wrong shell protocol";
return false;
+ }
- XDGSurfaceWrapperImpl* parent_xdg_surface;
+ XDGSurfaceWrapperImpl* parent_xdg_surface = nullptr;
// If the parent window is a popup, the surface of that popup must be used as
// a parent.
- if (parent_window->shell_popup()) {
+ if (wl::IsMenuType(wayland_window_->parent_window()->type())) {
+ auto* wayland_popup =
+ static_cast<WaylandPopup*>(wayland_window_->parent_window());
XDGPopupWrapperImpl* popup =
- reinterpret_cast<XDGPopupWrapperImpl*>(parent_window->shell_popup());
+ static_cast<XDGPopupWrapperImpl*>(wayland_popup->shell_popup());
parent_xdg_surface = popup->xdg_surface();
} else {
- parent_xdg_surface = reinterpret_cast<XDGSurfaceWrapperImpl*>(
- parent_window->shell_surface());
+ WaylandSurface* wayland_surface =
+ static_cast<WaylandSurface*>(wayland_window_->parent_window());
+ parent_xdg_surface =
+ static_cast<XDGSurfaceWrapperImpl*>(wayland_surface->shell_surface());
}
- if (!parent_xdg_surface)
+ if (!xdg_surface_ || !parent_xdg_surface)
return false;
- struct xdg_positioner* positioner =
- CreatePositionerStable(connection, parent_window, bounds);
+ if (connection->shell())
+ return InitializeStable(connection, bounds, parent_xdg_surface);
+ else if (connection->shell_v6())
+ return InitializeV6(connection, bounds, parent_xdg_surface);
+ return false;
+}
+
+bool XDGPopupWrapperImpl::InitializeStable(
+ WaylandConnection* connection,
+ const gfx::Rect& bounds,
+ XDGSurfaceWrapperImpl* parent_xdg_surface) {
+ static const struct xdg_popup_listener xdg_popup_listener = {
+ &XDGPopupWrapperImpl::ConfigureStable,
+ &XDGPopupWrapperImpl::PopupDoneStable,
+ };
+
+ struct xdg_positioner* positioner = CreatePositionerStable(
+ connection, wayland_window_->parent_window(), bounds);
if (!positioner)
return false;
@@ -333,11 +350,17 @@ bool XDGPopupWrapperImpl::InitializeStable(WaylandConnection* connection,
base::nix::DESKTOP_ENVIRONMENT_GNOME) ||
(wayland_window_->parent_window()->has_pointer_focus() ||
wayland_window_->parent_window()->has_keyboard_focus())) {
- xdg_popup_grab(xdg_popup_.get(), connection->seat(), connection->serial());
+ // When drag process starts, as described the protocol -
+ // https://goo.gl/1Mskq3, the client must have an active implicit grab. If
+ // we try to create a popup and grab it, it will be immediately dismissed.
+ // Thus, do not take explicit grab during drag process.
+ if (!connection->IsDragInProgress())
+ xdg_popup_grab(xdg_popup_.get(), connection->seat(),
+ connection->serial());
}
xdg_popup_add_listener(xdg_popup_.get(), &xdg_popup_listener, this);
- wl_surface_commit(surface);
+ wl_surface_commit(wayland_window_->surface());
return true;
}
@@ -361,7 +384,7 @@ struct xdg_positioner* XDGPopupWrapperImpl::CreatePositionerStable(
MenuType menu_type = MenuType::TYPE_UNKNOWN;
if (is_right_click_menu)
menu_type = MenuType::TYPE_RIGHT_CLICK;
- else if (parent_window->shell_popup())
+ else if (wl::IsMenuType(parent_window->type()))
menu_type = MenuType::TYPE_3DOT_CHILD_MENU;
else
menu_type = MenuType::TYPE_3DOT_PARENT_MENU;
@@ -382,36 +405,17 @@ struct xdg_positioner* XDGPopupWrapperImpl::CreatePositionerStable(
return positioner;
}
-bool XDGPopupWrapperImpl::InitializeV6(WaylandConnection* connection,
- wl_surface* surface,
- WaylandWindow* parent_window,
- const gfx::Rect& bounds) {
- DCHECK(connection && surface && parent_window);
+bool XDGPopupWrapperImpl::InitializeV6(
+ WaylandConnection* connection,
+ const gfx::Rect& bounds,
+ XDGSurfaceWrapperImpl* parent_xdg_surface) {
static const struct zxdg_popup_v6_listener zxdg_popup_v6_listener = {
&XDGPopupWrapperImpl::ConfigureV6,
&XDGPopupWrapperImpl::PopupDoneV6,
};
- if (!xdg_surface_)
- return false;
-
- XDGSurfaceWrapperImpl* parent_xdg_surface;
- // If the parent window is a popup, the surface of that popup must be used as
- // a parent.
- if (parent_window->shell_popup()) {
- XDGPopupWrapperImpl* popup =
- reinterpret_cast<XDGPopupWrapperImpl*>(parent_window->shell_popup());
- parent_xdg_surface = popup->xdg_surface();
- } else {
- parent_xdg_surface = reinterpret_cast<XDGSurfaceWrapperImpl*>(
- parent_window->shell_surface());
- }
-
- if (!parent_xdg_surface)
- return false;
-
zxdg_positioner_v6* positioner =
- CreatePositionerV6(connection, parent_window, bounds);
+ CreatePositionerV6(connection, wayland_window_->parent_window(), bounds);
if (!positioner)
return false;
@@ -457,7 +461,7 @@ bool XDGPopupWrapperImpl::InitializeV6(WaylandConnection* connection,
zxdg_popup_v6_add_listener(zxdg_popup_v6_.get(), &zxdg_popup_v6_listener,
this);
- wl_surface_commit(surface);
+ wl_surface_commit(wayland_window_->surface());
return true;
}
@@ -481,7 +485,7 @@ zxdg_positioner_v6* XDGPopupWrapperImpl::CreatePositionerV6(
MenuType menu_type = MenuType::TYPE_UNKNOWN;
if (is_right_click_menu)
menu_type = MenuType::TYPE_RIGHT_CLICK;
- else if (parent_window->shell_popup())
+ else if (wl::IsMenuType(parent_window->type()))
menu_type = MenuType::TYPE_3DOT_CHILD_MENU;
else
menu_type = MenuType::TYPE_3DOT_PARENT_MENU;
diff --git a/chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h b/chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h
index 371f18157d7..c0479cfff7f 100644
--- a/chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h
+++ b/chromium/ui/ozone/platform/wayland/host/xdg_popup_wrapper_impl.h
@@ -23,19 +23,20 @@ class XDGPopupWrapperImpl : public ShellPopupWrapper {
~XDGPopupWrapperImpl() override;
// XDGPopupWrapper:
- bool InitializeStable(WaylandConnection* connection,
- wl_surface* surface,
- WaylandWindow* parent_window,
- const gfx::Rect& bounds);
- bool InitializeV6(WaylandConnection* connection,
- wl_surface* surface,
- WaylandWindow* parent_window,
- const gfx::Rect& bounds);
+ bool Initialize(WaylandConnection* connection,
+ const gfx::Rect& bounds) override;
private:
+ bool InitializeStable(WaylandConnection* connection,
+ const gfx::Rect& bounds,
+ XDGSurfaceWrapperImpl* parent_xdg_surface);
struct xdg_positioner* CreatePositionerStable(WaylandConnection* connection,
WaylandWindow* parent_window,
const gfx::Rect& bounds);
+
+ bool InitializeV6(WaylandConnection* connection,
+ const gfx::Rect& bounds,
+ XDGSurfaceWrapperImpl* parent_xdg_surface);
struct zxdg_positioner_v6* CreatePositionerV6(WaylandConnection* connection,
WaylandWindow* parent_window,
const gfx::Rect& bounds);
@@ -64,9 +65,15 @@ class XDGPopupWrapperImpl : public ShellPopupWrapper {
XDGSurfaceWrapperImpl* xdg_surface();
+ // Non-owned WaylandWindow that uses this popup.
WaylandWindow* const wayland_window_;
+
+ // Ground surface for this popup.
std::unique_ptr<XDGSurfaceWrapperImpl> xdg_surface_;
+
+ // XDG Shell Stable object.
wl::Object<xdg_popup> xdg_popup_;
+ // XDG Shell V6 object.
wl::Object<zxdg_popup_v6> zxdg_popup_v6_;
DISALLOW_COPY_AND_ASSIGN(XDGPopupWrapperImpl);
diff --git a/chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc b/chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc
index d4078e1bc13..e7df772ae47 100644
--- a/chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc
+++ b/chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.cc
@@ -15,84 +15,19 @@
namespace ui {
-XDGSurfaceWrapperImpl::XDGSurfaceWrapperImpl(WaylandWindow* wayland_window)
- : wayland_window_(wayland_window) {}
+XDGSurfaceWrapperImpl::XDGSurfaceWrapperImpl(WaylandWindow* wayland_window,
+ WaylandConnection* connection)
+ : wayland_window_(wayland_window), connection_(connection) {}
XDGSurfaceWrapperImpl::~XDGSurfaceWrapperImpl() {}
-bool XDGSurfaceWrapperImpl::InitializeStable(WaylandConnection* connection,
- wl_surface* surface,
- bool with_toplevel) {
- static const xdg_surface_listener xdg_surface_listener = {
- &XDGSurfaceWrapperImpl::ConfigureStable,
- };
- static const xdg_toplevel_listener xdg_toplevel_listener = {
- &XDGSurfaceWrapperImpl::ConfigureTopLevelStable,
- &XDGSurfaceWrapperImpl::CloseTopLevelStable,
- };
-
- // if this surface is created for the popup role, mark that it requires
- // configuration acknowledgement on each configure event.
- surface_for_popup_ = !with_toplevel;
-
- xdg_surface_.reset(xdg_wm_base_get_xdg_surface(connection->shell(), surface));
- if (!xdg_surface_) {
- LOG(ERROR) << "Failed to create xdg_surface";
- return false;
- }
- xdg_surface_add_listener(xdg_surface_.get(), &xdg_surface_listener, this);
- // XDGPopup requires a separate surface to be created, so this is just a
- // request to get an xdg_surface for it.
- if (surface_for_popup_)
- return true;
-
- xdg_toplevel_.reset(xdg_surface_get_toplevel(xdg_surface_.get()));
- if (!xdg_toplevel_) {
- LOG(ERROR) << "Failed to create xdg_toplevel";
- return false;
- }
- xdg_toplevel_add_listener(xdg_toplevel_.get(), &xdg_toplevel_listener, this);
- wl_surface_commit(surface);
- return true;
-}
-
-bool XDGSurfaceWrapperImpl::InitializeV6(WaylandConnection* connection,
- wl_surface* surface,
- bool with_toplevel) {
- static const zxdg_surface_v6_listener zxdg_surface_v6_listener = {
- &XDGSurfaceWrapperImpl::ConfigureV6,
- };
- static const zxdg_toplevel_v6_listener zxdg_toplevel_v6_listener = {
- &XDGSurfaceWrapperImpl::ConfigureTopLevelV6,
- &XDGSurfaceWrapperImpl::CloseTopLevelV6,
- };
-
- // if this surface is created for the popup role, mark that it requires
- // configuration acknowledgement on each configure event.
- surface_for_popup_ = !with_toplevel;
-
- zxdg_surface_v6_.reset(
- zxdg_shell_v6_get_xdg_surface(connection->shell_v6(), surface));
- if (!zxdg_surface_v6_) {
- LOG(ERROR) << "Failed to create zxdg_surface";
- return false;
- }
- zxdg_surface_v6_add_listener(zxdg_surface_v6_.get(),
- &zxdg_surface_v6_listener, this);
- // XDGPopupV6 requires a separate surface to be created, so this is just a
- // request to get an xdg_surface for it.
- if (surface_for_popup_)
- return true;
-
- zxdg_toplevel_v6_.reset(zxdg_surface_v6_get_toplevel(zxdg_surface_v6_.get()));
- if (!zxdg_toplevel_v6_) {
- LOG(ERROR) << "Failed to create zxdg_toplevel";
- return false;
- }
- zxdg_toplevel_v6_add_listener(zxdg_toplevel_v6_.get(),
- &zxdg_toplevel_v6_listener, this);
- wl_surface_commit(surface);
- return true;
+bool XDGSurfaceWrapperImpl::Initialize(bool with_toplevel) {
+ if (connection_->shell())
+ return InitializeStable(with_toplevel);
+ else if (connection_->shell_v6())
+ return InitializeV6(with_toplevel);
+ NOTREACHED() << "Wrong shell protocol";
+ return false;
}
void XDGSurfaceWrapperImpl::SetMaximized() {
@@ -142,25 +77,25 @@ void XDGSurfaceWrapperImpl::SetMinimized() {
void XDGSurfaceWrapperImpl::SurfaceMove(WaylandConnection* connection) {
if (xdg_toplevel_) {
- xdg_toplevel_move(xdg_toplevel_.get(), connection->seat(),
- connection->serial());
+ xdg_toplevel_move(xdg_toplevel_.get(), connection_->seat(),
+ connection_->serial());
} else {
DCHECK(zxdg_toplevel_v6_);
- zxdg_toplevel_v6_move(zxdg_toplevel_v6_.get(), connection->seat(),
- connection->serial());
+ zxdg_toplevel_v6_move(zxdg_toplevel_v6_.get(), connection_->seat(),
+ connection_->serial());
}
}
void XDGSurfaceWrapperImpl::SurfaceResize(WaylandConnection* connection,
uint32_t hittest) {
if (xdg_toplevel_) {
- xdg_toplevel_resize(xdg_toplevel_.get(), connection->seat(),
- connection->serial(),
+ xdg_toplevel_resize(xdg_toplevel_.get(), connection_->seat(),
+ connection_->serial(),
wl::IdentifyDirection(*connection, hittest));
} else {
DCHECK(zxdg_toplevel_v6_);
- zxdg_toplevel_v6_resize(zxdg_toplevel_v6_.get(), connection->seat(),
- connection->serial(),
+ zxdg_toplevel_v6_resize(zxdg_toplevel_v6_.get(), connection_->seat(),
+ connection_->serial(),
wl::IdentifyDirection(*connection, hittest));
}
}
@@ -317,4 +252,84 @@ xdg_surface* XDGSurfaceWrapperImpl::xdg_surface() const {
return xdg_surface_.get();
}
+bool XDGSurfaceWrapperImpl::InitializeStable(bool with_toplevel) {
+ static const xdg_surface_listener xdg_surface_listener = {
+ &XDGSurfaceWrapperImpl::ConfigureStable,
+ };
+ static const xdg_toplevel_listener xdg_toplevel_listener = {
+ &XDGSurfaceWrapperImpl::ConfigureTopLevelStable,
+ &XDGSurfaceWrapperImpl::CloseTopLevelStable,
+ };
+
+ // if this surface is created for the popup role, mark that it requires
+ // configuration acknowledgement on each configure event.
+ surface_for_popup_ = !with_toplevel;
+
+ xdg_surface_.reset(xdg_wm_base_get_xdg_surface(connection_->shell(),
+ wayland_window_->surface()));
+ if (!xdg_surface_) {
+ LOG(ERROR) << "Failed to create xdg_surface";
+ return false;
+ }
+ xdg_surface_add_listener(xdg_surface_.get(), &xdg_surface_listener, this);
+ // XDGPopup requires a separate surface to be created, so this is just a
+ // request to get an xdg_surface for it.
+ if (surface_for_popup_) {
+ connection_->ScheduleFlush();
+ return true;
+ }
+
+ xdg_toplevel_.reset(xdg_surface_get_toplevel(xdg_surface_.get()));
+ if (!xdg_toplevel_) {
+ LOG(ERROR) << "Failed to create xdg_toplevel";
+ return false;
+ }
+ xdg_toplevel_add_listener(xdg_toplevel_.get(), &xdg_toplevel_listener, this);
+ wl_surface_commit(wayland_window_->surface());
+
+ connection_->ScheduleFlush();
+ return true;
+}
+
+bool XDGSurfaceWrapperImpl::InitializeV6(bool with_toplevel) {
+ static const zxdg_surface_v6_listener zxdg_surface_v6_listener = {
+ &XDGSurfaceWrapperImpl::ConfigureV6,
+ };
+ static const zxdg_toplevel_v6_listener zxdg_toplevel_v6_listener = {
+ &XDGSurfaceWrapperImpl::ConfigureTopLevelV6,
+ &XDGSurfaceWrapperImpl::CloseTopLevelV6,
+ };
+
+ // if this surface is created for the popup role, mark that it requires
+ // configuration acknowledgement on each configure event.
+ surface_for_popup_ = !with_toplevel;
+
+ zxdg_surface_v6_.reset(zxdg_shell_v6_get_xdg_surface(
+ connection_->shell_v6(), wayland_window_->surface()));
+ if (!zxdg_surface_v6_) {
+ LOG(ERROR) << "Failed to create zxdg_surface";
+ return false;
+ }
+ zxdg_surface_v6_add_listener(zxdg_surface_v6_.get(),
+ &zxdg_surface_v6_listener, this);
+ // XDGPopupV6 requires a separate surface to be created, so this is just a
+ // request to get an xdg_surface for it.
+ if (surface_for_popup_) {
+ connection_->ScheduleFlush();
+ return true;
+ }
+
+ zxdg_toplevel_v6_.reset(zxdg_surface_v6_get_toplevel(zxdg_surface_v6_.get()));
+ if (!zxdg_toplevel_v6_) {
+ LOG(ERROR) << "Failed to create zxdg_toplevel";
+ return false;
+ }
+ zxdg_toplevel_v6_add_listener(zxdg_toplevel_v6_.get(),
+ &zxdg_toplevel_v6_listener, this);
+ wl_surface_commit(wayland_window_->surface());
+
+ connection_->ScheduleFlush();
+ return true;
+}
+
} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h b/chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h
index e14956ebe3e..b34f4b2281e 100644
--- a/chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h
+++ b/chromium/ui/ozone/platform/wayland/host/xdg_surface_wrapper_impl.h
@@ -7,11 +7,10 @@
#include "ui/ozone/platform/wayland/host/shell_surface_wrapper.h"
+#include "base/macros.h"
#include "base/strings/string16.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
-#include "base/macros.h"
-
namespace gfx {
class Rect;
}
@@ -24,15 +23,12 @@ class WaylandWindow;
// Surface wrapper for xdg-shell stable and xdg-shell-unstable-v6
class XDGSurfaceWrapperImpl : public ShellSurfaceWrapper {
public:
- XDGSurfaceWrapperImpl(WaylandWindow* wayland_window);
+ XDGSurfaceWrapperImpl(WaylandWindow* wayland_window,
+ WaylandConnection* connection);
~XDGSurfaceWrapperImpl() override;
- bool InitializeV6(WaylandConnection* connection,
- wl_surface* surface,
- bool with_toplevel = true);
- bool InitializeStable(WaylandConnection* connection,
- wl_surface* surface,
- bool with_toplevel = true);
+ // ShellSurfaceWrapper overrides:
+ bool Initialize(bool with_toplevel) override;
void SetMaximized() override;
void UnSetMaximized() override;
void SetFullscreen() override;
@@ -76,8 +72,17 @@ class XDGSurfaceWrapperImpl : public ShellSurfaceWrapper {
zxdg_surface_v6* zxdg_surface() const;
private:
- WaylandWindow* wayland_window_;
- uint32_t pending_configure_serial_;
+ // Initializes using XDG Shell Stable protocol.
+ bool InitializeStable(bool with_toplevel);
+ // Initializes using XDG Shell V6 protocol.
+ bool InitializeV6(bool with_toplevel);
+
+ // Non-owing WaylandWindow that uses this surface wrapper.
+ WaylandWindow* const wayland_window_;
+ WaylandConnection* const connection_;
+
+ uint32_t pending_configure_serial_ = 0;
+
wl::Object<zxdg_surface_v6> zxdg_surface_v6_;
wl::Object<zxdg_toplevel_v6> zxdg_toplevel_v6_;
wl::Object<struct xdg_surface> xdg_surface_;
diff --git a/chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc
index 541d9c4848d..949df2ac040 100644
--- a/chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc
+++ b/chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -18,6 +18,7 @@
#include "ui/base/ime/linux/input_method_auralinux.h"
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/gfx/linux/client_native_pixmap_dmabuf.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/platform/wayland/common/wayland_util.h"
#include "ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.h"
@@ -46,10 +47,15 @@
#if defined(WAYLAND_GBM)
#include "ui/base/ui_base_features.h"
-#include "ui/ozone/common/linux/gbm_wrapper.h"
+#include "ui/gfx/linux/gbm_wrapper.h"
#include "ui/ozone/platform/wayland/gpu/drm_render_node_handle.h"
#endif
+#if BUILDFLAG(USE_GTK)
+#include "ui/gtk/gtk_ui_delegate.h" // nogncheck
+#include "ui/ozone/platform/wayland/host/gtk_ui_delegate_wayland.h" //nogncheck
+#endif
+
namespace ui {
namespace {
@@ -107,10 +113,8 @@ class OzonePlatformWayland : public OzonePlatform {
std::unique_ptr<PlatformWindow> CreatePlatformWindow(
PlatformWindowDelegate* delegate,
PlatformWindowInitProperties properties) override {
- auto window = std::make_unique<WaylandWindow>(delegate, connection_.get());
- if (!window->Initialize(std::move(properties)))
- return nullptr;
- return std::move(window);
+ return WaylandWindow::Create(delegate, connection_.get(),
+ std::move(properties));
}
std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate()
@@ -132,7 +136,18 @@ class OzonePlatformWayland : public OzonePlatform {
}
std::unique_ptr<InputMethod> CreateInputMethod(
- internal::InputMethodDelegate* delegate) override {
+ internal::InputMethodDelegate* delegate,
+ gfx::AcceleratedWidget widget) override {
+ // Instantiate and set LinuxInputMethodContextFactory unless it is already
+ // set (e.g: tests may have already set it).
+ if (!LinuxInputMethodContextFactory::instance() &&
+ !input_method_context_factory_) {
+ input_method_context_factory_ =
+ std::make_unique<WaylandInputMethodContextFactory>(connection_.get());
+ LinuxInputMethodContextFactory::SetInstance(
+ input_method_context_factory_.get());
+ }
+
return std::make_unique<InputMethodAuraLinux>(delegate);
}
@@ -174,16 +189,12 @@ class OzonePlatformWayland : public OzonePlatform {
supported_buffer_formats_ =
connection_->buffer_manager_host()->GetSupportedBufferFormats();
-
- // Instantiate and set LinuxInputMethodContextFactory unless it is already
- // set (e.g: tests may have already set it).
- if (!LinuxInputMethodContextFactory::instance() &&
- !input_method_context_factory_) {
- input_method_context_factory_ =
- std::make_unique<WaylandInputMethodContextFactory>(connection_.get());
- LinuxInputMethodContextFactory::SetInstance(
- input_method_context_factory_.get());
- }
+#if BUILDFLAG(USE_GTK)
+ DCHECK(!GtkUiDelegate::instance());
+ gtk_ui_delegate_ =
+ std::make_unique<GtkUiDelegateWayland>(connection_.get());
+ GtkUiDelegate::SetInstance(gtk_ui_delegate_.get());
+#endif
}
void InitializeGPU(const InitParams& args) override {
@@ -252,6 +263,10 @@ class OzonePlatformWayland : public OzonePlatform {
// render node is available.
DrmRenderNodePathFinder path_finder_;
+#if BUILDFLAG(USE_GTK)
+ std::unique_ptr<GtkUiDelegateWayland> gtk_ui_delegate_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(OzonePlatformWayland);
};
diff --git a/chromium/ui/ozone/platform/wayland/test/mock_surface.cc b/chromium/ui/ozone/platform/wayland/test/mock_surface.cc
index fa53a037669..20557517f99 100644
--- a/chromium/ui/ozone/platform/wayland/test/mock_surface.cc
+++ b/chromium/ui/ozone/platform/wayland/test/mock_surface.cc
@@ -108,6 +108,11 @@ void MockSurface::AttachNewBuffer(wl_resource* buffer_resource,
Attach(buffer_resource, x, y);
}
+void MockSurface::DestroyPrevAttachedBuffer() {
+ DCHECK(prev_attached_buffer_);
+ prev_attached_buffer_ = nullptr;
+}
+
void MockSurface::ReleasePrevAttachedBuffer() {
if (!prev_attached_buffer_)
return;
diff --git a/chromium/ui/ozone/platform/wayland/test/mock_surface.h b/chromium/ui/ozone/platform/wayland/test/mock_surface.h
index 27f7a2c09aa..bbf63e41ea2 100644
--- a/chromium/ui/ozone/platform/wayland/test/mock_surface.h
+++ b/chromium/ui/ozone/platform/wayland/test/mock_surface.h
@@ -42,15 +42,10 @@ class MockSurface : public ServerObject {
MOCK_METHOD4(DamageBuffer,
void(int32_t x, int32_t y, int32_t width, int32_t height));
- void set_xdg_surface(std::unique_ptr<MockXdgSurface> xdg_surface) {
- xdg_surface_ = std::move(xdg_surface);
+ void set_xdg_surface(MockXdgSurface* xdg_surface) {
+ xdg_surface_ = xdg_surface;
}
- MockXdgSurface* xdg_surface() const { return xdg_surface_.get(); }
-
- void set_xdg_popup(std::unique_ptr<MockXdgPopup> xdg_popup) {
- xdg_popup_ = std::move(xdg_popup);
- }
- MockXdgPopup* xdg_popup() const { return xdg_popup_.get(); }
+ MockXdgSurface* xdg_surface() const { return xdg_surface_; }
void set_sub_surface(TestSubSurface* sub_surface) {
sub_surface_ = sub_surface;
@@ -62,17 +57,15 @@ class MockSurface : public ServerObject {
frame_callback_ = callback_resource;
}
- bool has_role() const {
- return !!xdg_surface_ || !!xdg_popup_ || !!sub_surface_;
- }
+ bool has_role() const { return !!xdg_surface_ || !!sub_surface_; }
void AttachNewBuffer(wl_resource* buffer_resource, int32_t x, int32_t y);
+ void DestroyPrevAttachedBuffer();
void ReleasePrevAttachedBuffer();
void SendFrameCallback();
private:
- std::unique_ptr<MockXdgSurface> xdg_surface_;
- std::unique_ptr<MockXdgPopup> xdg_popup_;
+ MockXdgSurface* xdg_surface_ = nullptr;
TestSubSurface* sub_surface_ = nullptr;
wl_resource* frame_callback_ = nullptr;
diff --git a/chromium/ui/ozone/platform/wayland/test/mock_wp_presentation.h b/chromium/ui/ozone/platform/wayland/test/mock_wp_presentation.h
index a1bb344fd5f..616cd6e3fe1 100644
--- a/chromium/ui/ozone/platform/wayland/test/mock_wp_presentation.h
+++ b/chromium/ui/ozone/platform/wayland/test/mock_wp_presentation.h
@@ -30,7 +30,7 @@ class MockWpPresentation : public GlobalObject {
uint32_t callback));
void set_presentation_callback(wl_resource* callback_resource) {
- DCHECK(!presentation_callback_);
+ DCHECK(!presentation_callback_ || callback_resource == nullptr);
presentation_callback_ = callback_resource;
}
diff --git a/chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.cc b/chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.cc
index ebf449ca3e5..4a92c79edab 100644
--- a/chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.cc
+++ b/chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.cc
@@ -4,6 +4,8 @@
#include "ui/ozone/platform/wayland/test/mock_xdg_popup.h"
+#include "ui/ozone/platform/wayland/test/mock_xdg_surface.h"
+
namespace wl {
namespace {
@@ -27,9 +29,11 @@ const struct zxdg_popup_v6_interface kZxdgPopupV6Impl = {
&Grab, // grab
};
-MockXdgPopup::MockXdgPopup(wl_resource* resource, const void* implementation)
- : ServerObject(resource) {
- SetImplementationUnretained(resource, implementation, this);
+MockXdgPopup::MockXdgPopup(wl_resource* resource, wl_resource* surface)
+ : ServerObject(resource), surface_(surface) {
+ auto* mock_xdg_surface = GetUserDataAs<MockXdgSurface>(surface_);
+ if (mock_xdg_surface)
+ mock_xdg_surface->set_xdg_popup(nullptr);
}
MockXdgPopup::~MockXdgPopup() {}
diff --git a/chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.h b/chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.h
index 27b02361d89..61a80513020 100644
--- a/chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.h
+++ b/chromium/ui/ozone/platform/wayland/test/mock_xdg_popup.h
@@ -24,7 +24,7 @@ extern const struct zxdg_popup_v6_interface kZxdgPopupV6Impl;
class MockXdgPopup : public ServerObject {
public:
- MockXdgPopup(wl_resource* resource, const void* implementation);
+ MockXdgPopup(wl_resource* resource, wl_resource* surface);
~MockXdgPopup() override;
MOCK_METHOD1(Grab, void(uint32_t serial));
@@ -42,9 +42,11 @@ class MockXdgPopup : public ServerObject {
}
private:
- // Position of the popup. Used only with V6.
struct TestPositioner::PopupPosition position_;
+ // Ground surface for this popup.
+ wl_resource* surface_ = nullptr;
+
DISALLOW_COPY_AND_ASSIGN(MockXdgPopup);
};
diff --git a/chromium/ui/ozone/platform/wayland/test/mock_xdg_shell.cc b/chromium/ui/ozone/platform/wayland/test/mock_xdg_shell.cc
index 1ba63d43101..cd76626a124 100644
--- a/chromium/ui/ozone/platform/wayland/test/mock_xdg_shell.cc
+++ b/chromium/ui/ozone/platform/wayland/test/mock_xdg_shell.cc
@@ -29,15 +29,16 @@ void GetXdgSurfaceImpl(wl_client* client,
wl_resource_post_error(resource, xdg_error, "surface already has a role");
return;
}
- wl_resource* xdg_surface_resource = wl_resource_create(
- client, interface, wl_resource_get_version(resource), id);
+ wl_resource* xdg_surface_resource =
+ CreateResourceWithImpl<::testing::NiceMock<MockXdgSurface>>(
+ client, interface, wl_resource_get_version(resource), implementation,
+ id, surface_resource);
if (!xdg_surface_resource) {
wl_client_post_no_memory(client);
return;
}
- surface->set_xdg_surface(
- std::make_unique<MockXdgSurface>(xdg_surface_resource, implementation));
+ surface->set_xdg_surface(GetUserDataAs<MockXdgSurface>(xdg_surface_resource));
}
void CreatePositioner(wl_client* client,
diff --git a/chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.cc b/chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.cc
index 35963f84b96..d0bd03add2b 100644
--- a/chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.cc
+++ b/chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.cc
@@ -4,6 +4,7 @@
#include <xdg-shell-unstable-v6-server-protocol.h>
+#include "ui/ozone/platform/wayland/test/mock_surface.h"
#include "ui/ozone/platform/wayland/test/mock_xdg_popup.h"
#include "ui/ozone/platform/wayland/test/mock_xdg_surface.h"
#include "ui/ozone/platform/wayland/test/test_positioner.h"
@@ -11,18 +12,26 @@
namespace wl {
void SetTitle(wl_client* client, wl_resource* resource, const char* title) {
- GetUserDataAs<MockXdgSurface>(resource)->SetTitle(title);
+ auto* toplevel = GetUserDataAs<MockXdgTopLevel>(resource);
+ // As it this can be envoked during construction of the XdgSurface, cache the
+ // result so that tests are able to access that information.
+ toplevel->set_title(title);
+ toplevel->SetTitle(toplevel->title());
}
void SetAppId(wl_client* client, wl_resource* resource, const char* app_id) {
- GetUserDataAs<MockXdgSurface>(resource)->SetAppId(app_id);
+ auto* toplevel = GetUserDataAs<MockXdgTopLevel>(resource);
+ toplevel->SetAppId(app_id);
+ // As it this can be envoked during construction of the XdgSurface, cache the
+ // result so that tests are able to access that information.
+ toplevel->set_app_id(app_id);
}
void Move(wl_client* client,
wl_resource* resource,
wl_resource* seat,
uint32_t serial) {
- GetUserDataAs<MockXdgSurface>(resource)->Move(serial);
+ GetUserDataAs<MockXdgTopLevel>(resource)->Move(serial);
}
void Resize(wl_client* client,
@@ -30,7 +39,7 @@ void Resize(wl_client* client,
wl_resource* seat,
uint32_t serial,
uint32_t edges) {
- GetUserDataAs<MockXdgSurface>(resource)->Resize(serial, edges);
+ GetUserDataAs<MockXdgTopLevel>(resource)->Resize(serial, edges);
}
void AckConfigure(wl_client* client, wl_resource* resource, uint32_t serial) {
@@ -48,25 +57,47 @@ void SetWindowGeometry(wl_client* client,
}
void SetMaximized(wl_client* client, wl_resource* resource) {
- GetUserDataAs<MockXdgSurface>(resource)->SetMaximized();
+ GetUserDataAs<MockXdgTopLevel>(resource)->SetMaximized();
}
void UnsetMaximized(wl_client* client, wl_resource* resource) {
- GetUserDataAs<MockXdgSurface>(resource)->UnsetMaximized();
+ GetUserDataAs<MockXdgTopLevel>(resource)->UnsetMaximized();
}
void SetFullscreen(wl_client* client,
wl_resource* resource,
wl_resource* output) {
- GetUserDataAs<MockXdgSurface>(resource)->SetFullscreen();
+ GetUserDataAs<MockXdgTopLevel>(resource)->SetFullscreen();
}
void UnsetFullscreen(wl_client* client, wl_resource* resource) {
- GetUserDataAs<MockXdgSurface>(resource)->UnsetFullscreen();
+ GetUserDataAs<MockXdgTopLevel>(resource)->UnsetFullscreen();
}
void SetMinimized(wl_client* client, wl_resource* resource) {
- GetUserDataAs<MockXdgSurface>(resource)->SetMinimized();
+ GetUserDataAs<MockXdgTopLevel>(resource)->SetMinimized();
+}
+
+void SetMaxSize(wl_client* client,
+ wl_resource* resource,
+ int32_t width,
+ int32_t height) {
+ auto* toplevel = GetUserDataAs<MockXdgTopLevel>(resource);
+ toplevel->SetMaxSize(width, height);
+ // As it this can be envoked during construction of the XdgSurface, cache the
+ // result so that tests are able to access that information.
+ toplevel->set_max_size(gfx::Size(width, height));
+}
+
+void SetMinSize(wl_client* client,
+ wl_resource* resource,
+ int32_t width,
+ int32_t height) {
+ auto* toplevel = GetUserDataAs<MockXdgTopLevel>(resource);
+ toplevel->SetMinSize(width, height);
+ // As it this can be envoked during construction of the XdgSurface, cache the
+ // result so that tests are able to access that information.
+ toplevel->set_min_size(gfx::Size(width, height));
}
void GetTopLevel(wl_client* client, wl_resource* resource, uint32_t id) {
@@ -120,13 +151,22 @@ void GetXdgPopup(struct wl_client* client,
return;
}
- wl_resource* xdg_popup_resource = wl_resource_create(
- client, &xdg_popup_interface, wl_resource_get_version(resource), id);
+ wl_resource* xdg_popup_resource =
+ CreateResourceWithImpl<::testing::NiceMock<MockXdgPopup>>(
+ client, &xdg_popup_interface, wl_resource_get_version(resource),
+ &kXdgPopupImpl, id, resource);
+
+ if (!xdg_popup_resource) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ auto* mock_xdg_popup = GetUserDataAs<MockXdgPopup>(xdg_popup_resource);
+ DCHECK(mock_xdg_popup);
+
auto* positioner = GetUserDataAs<TestPositioner>(positioner_resource);
DCHECK(positioner);
- auto mock_xdg_popup =
- std::make_unique<MockXdgPopup>(xdg_popup_resource, &kXdgPopupImpl);
mock_xdg_popup->set_position(positioner->position());
if (mock_xdg_popup->size().IsEmpty() ||
mock_xdg_popup->anchor_rect().IsEmpty()) {
@@ -135,7 +175,7 @@ void GetXdgPopup(struct wl_client* client,
return;
}
- mock_xdg_surface->set_xdg_popup(std::move(mock_xdg_popup));
+ mock_xdg_surface->set_xdg_popup(mock_xdg_popup);
}
void GetZXdgPopupV6(struct wl_client* client,
@@ -156,13 +196,22 @@ void GetZXdgPopupV6(struct wl_client* client,
return;
}
- wl_resource* xdg_popup_resource = wl_resource_create(
- client, &zxdg_popup_v6_interface, wl_resource_get_version(resource), id);
+ wl_resource* xdg_popup_resource =
+ CreateResourceWithImpl<::testing::NiceMock<MockXdgPopup>>(
+ client, &zxdg_popup_v6_interface, wl_resource_get_version(resource),
+ &kZxdgPopupV6Impl, id, resource);
+
+ if (!xdg_popup_resource) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ auto* mock_xdg_popup = GetUserDataAs<MockXdgPopup>(xdg_popup_resource);
+ DCHECK(mock_xdg_popup);
+
auto* positioner = GetUserDataAs<TestPositioner>(positioner_resource);
DCHECK(positioner);
- auto mock_xdg_popup =
- std::make_unique<MockXdgPopup>(xdg_popup_resource, &kZxdgPopupV6Impl);
mock_xdg_popup->set_position(positioner->position());
if (mock_xdg_popup->size().IsEmpty() ||
mock_xdg_popup->anchor_rect().IsEmpty()) {
@@ -171,21 +220,7 @@ void GetZXdgPopupV6(struct wl_client* client,
return;
}
- mock_xdg_surface->set_xdg_popup(std::move(mock_xdg_popup));
-}
-
-void SetMaxSize(wl_client* client,
- wl_resource* resource,
- int32_t width,
- int32_t height) {
- GetUserDataAs<MockXdgSurface>(resource)->SetMaxSize(width, height);
-}
-
-void SetMinSize(wl_client* client,
- wl_resource* resource,
- int32_t width,
- int32_t height) {
- GetUserDataAs<MockXdgSurface>(resource)->SetMinSize(width, height);
+ mock_xdg_surface->set_xdg_popup(mock_xdg_popup);
}
const struct xdg_surface_interface kMockXdgSurfaceImpl = {
@@ -238,17 +273,18 @@ const struct zxdg_toplevel_v6_interface kMockZxdgToplevelV6Impl = {
&SetMinimized, // set_minimized
};
-MockXdgSurface::MockXdgSurface(wl_resource* resource,
- const void* implementation)
- : ServerObject(resource) {
- SetImplementationUnretained(resource, implementation, this);
-}
+MockXdgSurface::MockXdgSurface(wl_resource* resource, wl_resource* surface)
+ : ServerObject(resource), surface_(surface) {}
-MockXdgSurface::~MockXdgSurface() {}
+MockXdgSurface::~MockXdgSurface() {
+ auto* mock_surface = GetUserDataAs<MockSurface>(surface_);
+ if (mock_surface)
+ mock_surface->set_xdg_surface(nullptr);
+}
MockXdgTopLevel::MockXdgTopLevel(wl_resource* resource,
const void* implementation)
- : MockXdgSurface(resource, implementation) {
+ : ServerObject(resource) {
SetImplementationUnretained(resource, implementation, this);
}
diff --git a/chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.h b/chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.h
index 20e0f96bdfc..c41a6ed8fa3 100644
--- a/chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.h
+++ b/chromium/ui/ozone/platform/wayland/test/mock_xdg_surface.h
@@ -30,60 +30,71 @@ class MockXdgTopLevel;
// UI.
class MockXdgSurface : public ServerObject {
public:
- MockXdgSurface(wl_resource* resource, const void* implementation);
+ MockXdgSurface(wl_resource* resource, wl_resource* surface);
~MockXdgSurface() override;
- // These mock methods are shared between xdg_surface and zxdg_toplevel
- // surface.
- MOCK_METHOD1(SetParent, void(wl_resource* parent));
- MOCK_METHOD1(SetTitle, void(const char* title));
- MOCK_METHOD1(SetAppId, void(const char* app_id));
- MOCK_METHOD1(Move, void(uint32_t serial));
- MOCK_METHOD2(Resize, void(uint32_t serial, uint32_t edges));
MOCK_METHOD1(AckConfigure, void(uint32_t serial));
MOCK_METHOD4(SetWindowGeometry,
void(int32_t x, int32_t y, int32_t width, int32_t height));
- MOCK_METHOD0(SetMaximized, void());
- MOCK_METHOD0(UnsetMaximized, void());
- MOCK_METHOD0(SetFullscreen, void());
- MOCK_METHOD0(UnsetFullscreen, void());
- MOCK_METHOD0(SetMinimized, void());
-
- // These methods are for zxdg_toplevel only.
- MOCK_METHOD2(SetMaxSize, void(int32_t width, int32_t height));
- MOCK_METHOD2(SetMinSize, void(int32_t width, int32_t height));
void set_xdg_toplevel(std::unique_ptr<MockXdgTopLevel> xdg_toplevel) {
xdg_toplevel_ = std::move(xdg_toplevel);
}
MockXdgTopLevel* xdg_toplevel() const { return xdg_toplevel_.get(); }
- void set_xdg_popup(std::unique_ptr<MockXdgPopup> xdg_popup) {
- xdg_popup_ = std::move(xdg_popup);
- }
- MockXdgPopup* xdg_popup() const { return xdg_popup_.get(); }
+ void set_xdg_popup(MockXdgPopup* xdg_popup) { xdg_popup_ = xdg_popup; }
+ MockXdgPopup* xdg_popup() const { return xdg_popup_; }
private:
- // Used when xdg v6 is used.
+ // Has either toplevel role..
std::unique_ptr<MockXdgTopLevel> xdg_toplevel_;
+ // Or popup role.
+ MockXdgPopup* xdg_popup_ = nullptr;
- std::unique_ptr<MockXdgPopup> xdg_popup_;
+ // MockSurface that is the ground for this xdg_surface.
+ wl_resource* surface_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(MockXdgSurface);
};
// Manage zxdg_toplevel for providing desktop UI.
-class MockXdgTopLevel : public MockXdgSurface {
+class MockXdgTopLevel : public ServerObject {
public:
- explicit MockXdgTopLevel(wl_resource* resource, const void* implementation);
+ MockXdgTopLevel(wl_resource* resource, const void* implementation);
~MockXdgTopLevel() override;
- // TODO(msisov): mock other zxdg_toplevel specific methods once
- // implementation
- // is done. example: MOCK_METHOD2(SetMaxSize, void(int32_t width, int32_t
- // height());
+ MOCK_METHOD1(SetParent, void(wl_resource* parent));
+ MOCK_METHOD1(SetTitle, void(const std::string& title));
+ MOCK_METHOD1(SetAppId, void(const char* app_id));
+ MOCK_METHOD1(Move, void(uint32_t serial));
+ MOCK_METHOD2(Resize, void(uint32_t serial, uint32_t edges));
+ MOCK_METHOD0(SetMaximized, void());
+ MOCK_METHOD0(UnsetMaximized, void());
+ MOCK_METHOD0(SetFullscreen, void());
+ MOCK_METHOD0(UnsetFullscreen, void());
+ MOCK_METHOD0(SetMinimized, void());
+ MOCK_METHOD2(SetMaxSize, void(int32_t width, int32_t height));
+ MOCK_METHOD2(SetMinSize, void(int32_t width, int32_t height));
+
+ const std::string& app_id() const { return app_id_; }
+ void set_app_id(const char* app_id) { app_id_ = std::string(app_id); }
+
+ std::string title() const { return title_; }
+ void set_title(const char* title) { title_ = std::string(title); }
+
+ const gfx::Size& min_size() const { return min_size_; }
+ void set_min_size(const gfx::Size& min_size) { min_size_ = min_size; }
+
+ const gfx::Size& max_size() const { return max_size_; }
+ void set_max_size(const gfx::Size& max_size) { max_size_ = max_size; }
private:
+ gfx::Size min_size_;
+ gfx::Size max_size_;
+
+ std::string title_;
+ std::string app_id_;
+
DISALLOW_COPY_AND_ASSIGN(MockXdgTopLevel);
};
diff --git a/chromium/ui/ozone/platform/wayland/test/test_data_offer.cc b/chromium/ui/ozone/platform/wayland/test/test_data_offer.cc
index 456945f314c..b830dada81e 100644
--- a/chromium/ui/ozone/platform/wayland/test/test_data_offer.cc
+++ b/chromium/ui/ozone/platform/wayland/test/test_data_offer.cc
@@ -13,6 +13,7 @@
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
#include "ui/ozone/platform/wayland/test/constants.h"
namespace wl {
@@ -65,8 +66,8 @@ const struct wl_data_offer_interface kTestDataOfferImpl = {
TestDataOffer::TestDataOffer(wl_resource* resource)
: ServerObject(resource),
- task_runner_(base::CreateSequencedTaskRunner(
- {base::ThreadPool(), base::MayBlock()})),
+ task_runner_(
+ base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()})),
write_data_weak_ptr_factory_(this) {}
TestDataOffer::~TestDataOffer() {}
diff --git a/chromium/ui/ozone/platform/wayland/test/test_data_source.cc b/chromium/ui/ozone/platform/wayland/test/test_data_source.cc
index 6757ff33750..530a2e443c7 100644
--- a/chromium/ui/ozone/platform/wayland/test/test_data_source.cc
+++ b/chromium/ui/ozone/platform/wayland/test/test_data_source.cc
@@ -14,6 +14,7 @@
#include "base/sequenced_task_runner.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
#include "base/task_runner_util.h"
#include "ui/ozone/platform/wayland/test/constants.h"
@@ -63,8 +64,8 @@ const struct wl_data_source_interface kTestDataSourceImpl = {
TestDataSource::TestDataSource(wl_resource* resource)
: ServerObject(resource),
- task_runner_(base::CreateSequencedTaskRunner(
- {base::ThreadPool(), base::MayBlock()})) {}
+ task_runner_(
+ base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()})) {}
TestDataSource::~TestDataSource() {}
diff --git a/chromium/ui/ozone/platform/wayland/test/test_subcompositor.cc b/chromium/ui/ozone/platform/wayland/test/test_subcompositor.cc
index 7d78fdf7e14..cbb66349ada 100644
--- a/chromium/ui/ozone/platform/wayland/test/test_subcompositor.cc
+++ b/chromium/ui/ozone/platform/wayland/test/test_subcompositor.cc
@@ -33,7 +33,7 @@ void GetSubsurface(struct wl_client* client,
wl_resource* subsurface_resource =
CreateResourceWithImpl<::testing::NiceMock<TestSubSurface>>(
client, &wl_subsurface_interface, wl_resource_get_version(resource),
- &kTestSubSurfaceImpl, id);
+ &kTestSubSurfaceImpl, id, surface, parent);
DCHECK(subsurface_resource);
mock_surface->set_sub_surface(
GetUserDataAs<TestSubSurface>(subsurface_resource));
diff --git a/chromium/ui/ozone/platform/wayland/test/test_subsurface.cc b/chromium/ui/ozone/platform/wayland/test/test_subsurface.cc
index 7d569eab43e..1609bb2012a 100644
--- a/chromium/ui/ozone/platform/wayland/test/test_subsurface.cc
+++ b/chromium/ui/ozone/platform/wayland/test/test_subsurface.cc
@@ -43,10 +43,20 @@ const struct wl_subsurface_interface kTestSubSurfaceImpl = {
DestroyResource, SetPosition, PlaceAbove, PlaceBelow, SetSync, SetDesync,
};
-TestSubSurface::TestSubSurface(wl_resource* resource)
- : ServerObject(resource) {}
+TestSubSurface::TestSubSurface(wl_resource* resource,
+ wl_resource* surface,
+ wl_resource* parent_resource)
+ : ServerObject(resource),
+ surface_(surface),
+ parent_resource_(parent_resource) {
+ DCHECK(surface_);
+}
-TestSubSurface::~TestSubSurface() = default;
+TestSubSurface::~TestSubSurface() {
+ auto* mock_surface = GetUserDataAs<MockSurface>(surface_);
+ if (mock_surface)
+ mock_surface->set_sub_surface(nullptr);
+}
void TestSubSurface::SetPosition(int x, int y) {
position_ = gfx::Point(x, y);
diff --git a/chromium/ui/ozone/platform/wayland/test/test_subsurface.h b/chromium/ui/ozone/platform/wayland/test/test_subsurface.h
index 4f984a5eccd..abf806500ca 100644
--- a/chromium/ui/ozone/platform/wayland/test/test_subsurface.h
+++ b/chromium/ui/ozone/platform/wayland/test/test_subsurface.h
@@ -22,7 +22,9 @@ extern const struct wl_subsurface_interface kTestSubSurfaceImpl;
class TestSubSurface : public ServerObject {
public:
- explicit TestSubSurface(wl_resource* resource);
+ explicit TestSubSurface(wl_resource* resource,
+ wl_resource* surface,
+ wl_resource* parent_resource);
~TestSubSurface() override;
TestSubSurface(const TestSubSurface& rhs) = delete;
TestSubSurface& operator=(const TestSubSurface& rhs) = delete;
@@ -33,9 +35,17 @@ class TestSubSurface : public ServerObject {
void set_sync(bool sync) { sync_ = sync; }
bool sync() const { return sync_; }
+ wl_resource* parent_resource() const { return parent_resource_; }
+
private:
gfx::Point position_;
bool sync_ = false;
+
+ // Surface resource that is the ground for this subsurface.
+ wl_resource* surface_ = nullptr;
+
+ // Parent surface resource.
+ wl_resource* parent_resource_ = nullptr;
};
} // namespace wl
diff --git a/chromium/ui/ozone/platform/wayland/test/wayland_test.cc b/chromium/ui/ozone/platform/wayland/test/wayland_test.cc
index 2bd8c38219c..2866ab6a07f 100644
--- a/chromium/ui/ozone/platform/wayland/test/wayland_test.cc
+++ b/chromium/ui/ozone/platform/wayland/test/wayland_test.cc
@@ -37,7 +37,6 @@ WaylandTest::WaylandTest()
buffer_manager_gpu_ = std::make_unique<WaylandBufferManagerGpu>();
surface_factory_ = std::make_unique<WaylandSurfaceFactory>(
connection_.get(), buffer_manager_gpu_.get());
- window_ = std::make_unique<WaylandWindow>(&delegate_, connection_.get());
}
WaylandTest::~WaylandTest() {}
@@ -52,9 +51,12 @@ void WaylandTest::SetUp() {
PlatformWindowInitProperties properties;
properties.bounds = gfx::Rect(0, 0, 800, 600);
properties.type = PlatformWindowType::kWindow;
- ASSERT_TRUE(window_->Initialize(std::move(properties)));
+ window_ = WaylandWindow::Create(&delegate_, connection_.get(),
+ std::move(properties));
ASSERT_NE(widget_, gfx::kNullAcceleratedWidget);
+ window_->Show(false);
+
// Wait for the client to flush all pending requests from initialization.
base::RunLoop().RunUntilIdle();
diff --git a/chromium/ui/ozone/platform/wayland/wayland.gni b/chromium/ui/ozone/platform/wayland/wayland.gni
index 8cfdc4cc1cb..e9200e6daa8 100644
--- a/chromium/ui/ozone/platform/wayland/wayland.gni
+++ b/chromium/ui/ozone/platform/wayland/wayland.gni
@@ -9,4 +9,7 @@ declare_args() {
# Checks if Wayland must be compiled with dmabuf/gbm feature, which allows a
# multi-process hardware accelerated mode.
use_wayland_gbm = true
+
+ # Checks if Weston must be compiled
+ use_bundled_weston = false
}
diff --git a/chromium/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc b/chromium/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc
index 21b0c3eefd9..de10370fe69 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/wayland_buffer_manager_unittest.cc
@@ -14,7 +14,7 @@
#include "mojo/public/cpp/system/platform_handle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/ozone/common/linux/drm_util_linux.h"
+#include "ui/gfx/linux/drm_util_linux.h"
#include "ui/ozone/platform/wayland/gpu/wayland_surface_gpu.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_zwp_linux_dmabuf.h"
@@ -189,12 +189,12 @@ class WaylandBufferManagerTest : public WaylandTest {
std::unique_ptr<WaylandWindow> CreateWindow() {
testing::Mock::VerifyAndClearExpectations(&delegate_);
- auto new_window =
- std::make_unique<WaylandWindow>(&delegate_, connection_.get());
PlatformWindowInitProperties properties;
properties.bounds = gfx::Rect(0, 0, 800, 600);
properties.type = PlatformWindowType::kWindow;
- EXPECT_TRUE(new_window->Initialize(std::move(properties)));
+ auto new_window = WaylandWindow::Create(&delegate_, connection_.get(),
+ std::move(properties));
+ EXPECT_TRUE(new_window);
Sync();
@@ -537,6 +537,121 @@ TEST_P(WaylandBufferManagerTest, EnsureCorrectOrderOfCallbacks) {
DestroyBufferAndSetTerminateExpectation(widget, kBufferId2, false /*fail*/);
}
+TEST_P(WaylandBufferManagerTest,
+ DestroyedBuffersGeneratePresentationFeedbackFailure) {
+ constexpr uint32_t kBufferId1 = 1;
+ constexpr uint32_t kBufferId2 = 2;
+ constexpr uint32_t kBufferId3 = 3;
+
+ const gfx::AcceleratedWidget widget = window_->GetWidget();
+ const gfx::Rect bounds = gfx::Rect({0, 0}, kDefaultSize);
+ window_->SetBounds(bounds);
+
+ MockSurfaceGpu mock_surface_gpu(buffer_manager_gpu_.get(), widget_);
+
+ auto* linux_dmabuf = server_.zwp_linux_dmabuf_v1();
+ EXPECT_CALL(*linux_dmabuf, CreateParams(_, _, _)).Times(3);
+ CreateDmabufBasedBufferAndSetTerminateExpecation(false /*fail*/, kBufferId1);
+ CreateDmabufBasedBufferAndSetTerminateExpecation(false /*fail*/, kBufferId2);
+ CreateDmabufBasedBufferAndSetTerminateExpecation(false /*fail*/, kBufferId3);
+
+ Sync();
+
+ ProcessCreatedBufferResourcesWithExpectation(3u /* expected size */,
+ false /* fail */);
+
+ auto* mock_surface = server_.GetObject<wl::MockSurface>(widget);
+ auto* mock_wp_presentation = server_.EnsureWpPresentation();
+ ASSERT_TRUE(mock_wp_presentation);
+
+ constexpr uint32_t kNumberOfCommits = 3;
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(kNumberOfCommits);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(kNumberOfCommits);
+ EXPECT_CALL(*mock_surface, Commit()).Times(kNumberOfCommits);
+ EXPECT_CALL(*mock_wp_presentation,
+ Feedback(_, _, mock_surface->resource(), _))
+ .Times(3);
+
+ Sync();
+
+ ::testing::InSequence s;
+
+ // wp_presentation_feedback should work now.
+ ASSERT_TRUE(connection_->presentation());
+
+ // Commit the first buffer and expect OnSubmission immediately.
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(_, _)).Times(0);
+ EXPECT_CALL(mock_surface_gpu,
+ OnSubmission(kBufferId1, gfx::SwapResult::SWAP_ACK))
+ .Times(1);
+ buffer_manager_gpu_->CommitBuffer(widget, kBufferId1, bounds);
+ mock_surface->SendFrameCallback();
+ Sync();
+
+ // Deliberately drop the presentation feedback for the first buffer,
+ // since we will destroy it.
+ mock_wp_presentation->set_presentation_callback(nullptr);
+
+ // Commit second buffer now.
+ buffer_manager_gpu_->CommitBuffer(widget, kBufferId2, bounds);
+ mock_surface->SendFrameCallback();
+ Sync();
+
+ // Destroy the first buffer, which should trigger submission for the second
+ // buffer.
+ EXPECT_CALL(mock_surface_gpu,
+ OnSubmission(kBufferId2, gfx::SwapResult::SWAP_ACK))
+ .Times(1);
+ DestroyBufferAndSetTerminateExpectation(widget, kBufferId1, /*fail=*/false);
+ mock_surface->DestroyPrevAttachedBuffer();
+ mock_surface->SendFrameCallback();
+ Sync();
+
+ // Deliberately drop the presentation feedback for the second buffer,
+ // since we will destroy it.
+ mock_wp_presentation->set_presentation_callback(nullptr);
+
+ // Commit buffer 3 then send the presentation callback for it. This should
+ // not call OnPresentation as OnSubmission hasn't been called yet.
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(_, _)).Times(0);
+ buffer_manager_gpu_->CommitBuffer(widget, kBufferId3, bounds);
+ mock_surface->SendFrameCallback();
+ mock_wp_presentation->SendPresentationCallback();
+ Sync();
+
+ // Destroy buffer 2, which should trigger OnSubmission for buffer 3, and
+ // OnPresentation for buffer 1, 2, and 3.
+ EXPECT_CALL(mock_surface_gpu,
+ OnSubmission(kBufferId3, gfx::SwapResult::SWAP_ACK))
+ .Times(1);
+ EXPECT_CALL(
+ mock_surface_gpu,
+ OnPresentation(
+ kBufferId1,
+ ::testing::Field(
+ &gfx::PresentationFeedback::flags,
+ ::testing::Eq(gfx::PresentationFeedback::Flags::kFailure))))
+ .Times(1);
+ EXPECT_CALL(
+ mock_surface_gpu,
+ OnPresentation(
+ kBufferId2,
+ ::testing::Field(
+ &gfx::PresentationFeedback::flags,
+ ::testing::Eq(gfx::PresentationFeedback::Flags::kFailure))))
+ .Times(1);
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(kBufferId3, _)).Times(1);
+ DestroyBufferAndSetTerminateExpectation(widget, kBufferId2, /*fail=*/false);
+ mock_surface->DestroyPrevAttachedBuffer();
+ mock_surface->SendFrameCallback();
+ mock_wp_presentation->SendPresentationCallback();
+ Sync();
+
+ DestroyBufferAndSetTerminateExpectation(widget, kBufferId3, false /*fail*/);
+}
+
+TEST_P(WaylandBufferManagerTest, MultiplePendingPresentationsForSameBuffer) {}
+
TEST_P(WaylandBufferManagerTest, TestCommitBufferConditions) {
constexpr uint32_t kDmabufBufferId = 1;
constexpr uint32_t kDmabufBufferId2 = 2;
@@ -837,6 +952,166 @@ TEST_P(WaylandBufferManagerTest, DestroyedWindowNoSubmissionMultipleBuffers) {
DestroyBufferAndSetTerminateExpectation(widget, kBufferId2, false /*fail*/);
}
+// This test verifies that submitting the buffer more than once results in
+// OnSubmission callback as Wayland compositor is not supposed to release the
+// buffer committed twice.
+TEST_P(WaylandBufferManagerTest, SubmitSameBufferMultipleTimes) {
+ constexpr uint32_t kBufferId1 = 1;
+ constexpr uint32_t kBufferId2 = 2;
+
+ const gfx::AcceleratedWidget widget = window_->GetWidget();
+ const gfx::Rect bounds = window_->GetBounds();
+
+ MockSurfaceGpu mock_surface_gpu(buffer_manager_gpu_.get(), widget);
+
+ auto* linux_dmabuf = server_.zwp_linux_dmabuf_v1();
+ EXPECT_CALL(*linux_dmabuf, CreateParams(_, _, _)).Times(2);
+ CreateDmabufBasedBufferAndSetTerminateExpecation(false /*fail*/, kBufferId1);
+ CreateDmabufBasedBufferAndSetTerminateExpecation(false /*fail*/, kBufferId2);
+
+ Sync();
+
+ ProcessCreatedBufferResourcesWithExpectation(2u /* expected size */,
+ false /* fail */);
+
+ EXPECT_CALL(mock_surface_gpu,
+ OnSubmission(kBufferId1, gfx::SwapResult::SWAP_ACK))
+ .Times(1);
+ ASSERT_TRUE(!connection_->presentation());
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(kBufferId1, _)).Times(1);
+ auto* mock_surface = server_.GetObject<wl::MockSurface>(widget);
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(1);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*mock_surface,
+ DamageBuffer(0, 0, bounds.width(), bounds.height()))
+ .Times(1);
+ EXPECT_CALL(*mock_surface, Commit()).Times(1);
+
+ buffer_manager_gpu_->CommitBuffer(widget, kBufferId1, bounds);
+
+ Sync();
+
+ testing::Mock::VerifyAndClearExpectations(&mock_surface_gpu);
+ testing::Mock::VerifyAndClearExpectations(mock_surface);
+
+ EXPECT_CALL(mock_surface_gpu, OnSubmission(_, _)).Times(0);
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(_, _)).Times(0);
+
+ mock_surface->SendFrameCallback();
+
+ Sync();
+
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(1);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*mock_surface,
+ DamageBuffer(0, 0, bounds.width(), bounds.height()))
+ .Times(1);
+ EXPECT_CALL(*mock_surface, Commit()).Times(1);
+
+ // Commit second buffer now.
+ buffer_manager_gpu_->CommitBuffer(widget, kBufferId2, bounds);
+
+ Sync();
+
+ testing::Mock::VerifyAndClearExpectations(&mock_surface_gpu);
+ testing::Mock::VerifyAndClearExpectations(mock_surface);
+
+ EXPECT_CALL(mock_surface_gpu,
+ OnSubmission(kBufferId2, gfx::SwapResult::SWAP_ACK))
+ .Times(1);
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(kBufferId2, _)).Times(1);
+
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(0);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(0);
+ EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(0);
+ EXPECT_CALL(*mock_surface, Commit()).Times(0);
+
+ mock_surface->ReleasePrevAttachedBuffer();
+ mock_surface->SendFrameCallback();
+
+ Sync();
+
+ testing::Mock::VerifyAndClearExpectations(&mock_surface_gpu);
+ testing::Mock::VerifyAndClearExpectations(mock_surface);
+
+ // Now, commit the buffer with the |kBufferId2| again and make sure the
+ // manager manually sends the submission callback as long as the compositor is
+ // not going to release a buffer as it was the same buffer submitted more than
+ // once.
+ EXPECT_CALL(mock_surface_gpu,
+ OnSubmission(kBufferId2, gfx::SwapResult::SWAP_ACK))
+ .Times(1);
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(kBufferId2, _)).Times(1);
+
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(0);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*mock_surface,
+ DamageBuffer(0, 0, bounds.width(), bounds.height()))
+ .Times(1);
+ EXPECT_CALL(*mock_surface, Commit()).Times(1);
+
+ // Commit second buffer now.
+ buffer_manager_gpu_->CommitBuffer(widget, kBufferId2, bounds);
+
+ Sync();
+
+ testing::Mock::VerifyAndClearExpectations(&mock_surface_gpu);
+ testing::Mock::VerifyAndClearExpectations(mock_surface);
+
+ EXPECT_CALL(mock_surface_gpu, OnSubmission(_, _)).Times(0);
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(_, _)).Times(0);
+
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(0);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(0);
+ EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(0);
+ EXPECT_CALL(*mock_surface, Commit()).Times(0);
+
+ // It must be ok if Wayland compositor decides to release the buffer at some
+ // point.
+ mock_surface->ReleasePrevAttachedBuffer();
+ mock_surface->SendFrameCallback();
+
+ Sync();
+
+ testing::Mock::VerifyAndClearExpectations(&mock_surface_gpu);
+ testing::Mock::VerifyAndClearExpectations(mock_surface);
+
+ // If we commit another buffer now, the manager host must not automatically
+ // trigger OnSubmission and OnPresentation callbacks.
+ EXPECT_CALL(mock_surface_gpu, OnSubmission(_, _)).Times(0);
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(_, _)).Times(0);
+
+ EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(1);
+ EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*mock_surface,
+ DamageBuffer(0, 0, bounds.width(), bounds.height()))
+ .Times(1);
+ EXPECT_CALL(*mock_surface, Commit()).Times(1);
+
+ buffer_manager_gpu_->CommitBuffer(widget, kBufferId1, bounds);
+
+ Sync();
+
+ testing::Mock::VerifyAndClearExpectations(&mock_surface_gpu);
+ testing::Mock::VerifyAndClearExpectations(mock_surface);
+
+ // Now, they must be triggered once the buffer is released.
+ EXPECT_CALL(mock_surface_gpu,
+ OnSubmission(kBufferId1, gfx::SwapResult::SWAP_ACK))
+ .Times(1);
+ EXPECT_CALL(mock_surface_gpu, OnPresentation(kBufferId1, _)).Times(1);
+
+ mock_surface->ReleasePrevAttachedBuffer();
+ mock_surface->SendFrameCallback();
+
+ Sync();
+
+ testing::Mock::VerifyAndClearExpectations(&mock_surface_gpu);
+
+ DestroyBufferAndSetTerminateExpectation(widget, kBufferId1, false /*fail*/);
+ DestroyBufferAndSetTerminateExpectation(widget, kBufferId2, false /*fail*/);
+}
+
INSTANTIATE_TEST_SUITE_P(XdgVersionStableTest,
WaylandBufferManagerTest,
::testing::Values(kXdgShellStable));
diff --git a/chromium/ui/ozone/platform/windows/ozone_platform_windows.cc b/chromium/ui/ozone/platform/windows/ozone_platform_windows.cc
index 5f3f010241d..d6dee8a511c 100644
--- a/chromium/ui/ozone/platform/windows/ozone_platform_windows.cc
+++ b/chromium/ui/ozone/platform/windows/ozone_platform_windows.cc
@@ -15,6 +15,7 @@
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
#include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/platform/windows/windows_surface_factory.h"
#include "ui/ozone/platform/windows/windows_window.h"
@@ -77,7 +78,8 @@ class OzonePlatformWindows : public OzonePlatform {
return std::make_unique<display::FakeDisplayDelegate>();
}
std::unique_ptr<InputMethod> CreateInputMethod(
- internal::InputMethodDelegate* delegate) override {
+ internal::InputMethodDelegate* delegate,
+ gfx::AcceleratedWidget) override {
NOTREACHED();
return nullptr;
}
diff --git a/chromium/ui/ozone/platform/windows/windows_surface_factory.cc b/chromium/ui/ozone/platform/windows/windows_surface_factory.cc
index 11700e93a2d..83b51fb2dba 100644
--- a/chromium/ui/ozone/platform/windows/windows_surface_factory.cc
+++ b/chromium/ui/ozone/platform/windows/windows_surface_factory.cc
@@ -46,8 +46,8 @@ class GLOzoneEGLWindows : public GLOzoneEGL {
protected:
// GLOzoneEGL:
- HDC GetNativeDisplay() override {
- return GetWindowDC(nullptr);
+ gl::EGLDisplayPlatform GetNativeDisplay() override {
+ return gl::EGLDisplayPlatform(GetWindowDC(nullptr));
}
bool LoadGLES2Bindings(gl::GLImplementation implementation) override {
diff --git a/chromium/ui/ozone/platform/x11/BUILD.gn b/chromium/ui/ozone/platform/x11/BUILD.gn
index daf322b4893..f1941921e42 100644
--- a/chromium/ui/ozone/platform/x11/BUILD.gn
+++ b/chromium/ui/ozone/platform/x11/BUILD.gn
@@ -2,7 +2,9 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//build/config/linux/gtk/gtk.gni")
import("//gpu/vulkan/features.gni")
+import("//ui/base/ui_features.gni")
visibility = [ "//ui/ozone/*" ]
@@ -36,11 +38,15 @@ source_set("x11") {
"x11_window_ozone.h",
]
+ public_deps = [ "//ui/base/mojom:cursor_type" ]
+
deps = [
"//base",
+ "//build:chromecast_buildflags",
"//gpu/vulkan:buildflags",
"//skia",
- "//ui/base",
+ "//ui/base:base",
+ "//ui/base:buildflags",
"//ui/base/clipboard:clipboard_types",
"//ui/base/ime",
"//ui/base/x",
@@ -73,6 +79,14 @@ source_set("x11") {
deps += [ "//gpu/vulkan/x" ]
}
+ if (use_gtk) {
+ deps += [ "//ui/gtk:x" ]
+ }
+
+ if (use_xkbcommon) {
+ configs += [ "//ui/events/ozone/layout:xkbcommon" ]
+ }
+
configs += [
"//build/config/linux:x11",
"//build/config/linux:xrandr",
@@ -97,6 +111,7 @@ source_set("x11_unittests") {
"//ui/events:test_support",
"//ui/events/devices/x11",
"//ui/events/platform/x11",
+ "//ui/events/x:unittests",
"//ui/ozone:platform",
"//ui/ozone:test_support",
"//ui/ozone/common",
diff --git a/chromium/ui/ozone/platform/x11/DEPS b/chromium/ui/ozone/platform/x11/DEPS
index 3b6346a6153..c4251a75884 100644
--- a/chromium/ui/ozone/platform/x11/DEPS
+++ b/chromium/ui/ozone/platform/x11/DEPS
@@ -1,4 +1,6 @@
include_rules = [
"+ui/base/x",
"+ui/base",
+ "+ui/gtk/gtk_ui_delegate.h",
+ "+ui/gtk/gtk_ui_delegate_x11.h",
]
diff --git a/chromium/ui/ozone/platform/x11/gl_ozone_glx.cc b/chromium/ui/ozone/platform/x11/gl_ozone_glx.cc
index 422c58ee776..520c5223457 100644
--- a/chromium/ui/ozone/platform/x11/gl_ozone_glx.cc
+++ b/chromium/ui/ozone/platform/x11/gl_ozone_glx.cc
@@ -67,11 +67,6 @@ bool GLOzoneGLX::InitializeStaticGLBindings(
return true;
}
-void GLOzoneGLX::InitializeLogGLBindings() {
- gl::InitializeLogGLBindingsGL();
- gl::InitializeLogGLBindingsGLX();
-}
-
void GLOzoneGLX::SetDisabledExtensionsPlatform(
const std::string& disabled_extensions) {
gl::SetDisabledExtensionsGLX(disabled_extensions);
diff --git a/chromium/ui/ozone/platform/x11/gl_ozone_glx.h b/chromium/ui/ozone/platform/x11/gl_ozone_glx.h
index 2ffa0f45527..7af963f6a74 100644
--- a/chromium/ui/ozone/platform/x11/gl_ozone_glx.h
+++ b/chromium/ui/ozone/platform/x11/gl_ozone_glx.h
@@ -18,7 +18,6 @@ class GLOzoneGLX : public GLOzone {
bool InitializeGLOneOffPlatform() override;
bool InitializeStaticGLBindings(gl::GLImplementation implementation) override;
- void InitializeLogGLBindings() override;
void SetDisabledExtensionsPlatform(
const std::string& disabled_extensions) override;
bool InitializeExtensionSettingsOneOffPlatform() override;
diff --git a/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.cc b/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.cc
index b33cfb1f6f0..71d50ffa607 100644
--- a/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.cc
+++ b/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.cc
@@ -79,7 +79,7 @@ EGLConfig GLSurfaceEGLOzoneX11::GetConfig() {
bool GLSurfaceEGLOzoneX11::Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) {
if (size == GetSize())
return true;
diff --git a/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.h b/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.h
index dcb419083b9..eab987a95b1 100644
--- a/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.h
+++ b/chromium/ui/ozone/platform/x11/gl_surface_egl_ozone_x11.h
@@ -21,7 +21,7 @@ class GLSurfaceEGLOzoneX11 : public gl::NativeViewGLSurfaceEGL {
EGLConfig GetConfig() override;
bool Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) override;
private:
diff --git a/chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.cc b/chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.cc
index 3a38c4d6996..1806337fff4 100644
--- a/chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.cc
+++ b/chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.cc
@@ -52,7 +52,7 @@ void GLSurfaceEglReadbackX11::Destroy() {
bool GLSurfaceEglReadbackX11::Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) {
if (!GLSurfaceEglReadback::Resize(size, scale_factor, color_space,
has_alpha)) {
diff --git a/chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.h b/chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.h
index 7bd5662cfc5..ed56bcaa4f4 100644
--- a/chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.h
+++ b/chromium/ui/ozone/platform/x11/gl_surface_egl_readback_x11.h
@@ -20,7 +20,7 @@ class GLSurfaceEglReadbackX11 : public GLSurfaceEglReadback {
void Destroy() override;
bool Resize(const gfx::Size& size,
float scale_factor,
- ColorSpace color_space,
+ const gfx::ColorSpace& color_space,
bool has_alpha) override;
private:
diff --git a/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc b/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc
index 67e1e41dc40..78ea2a95e7e 100644
--- a/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc
+++ b/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc
@@ -9,12 +9,15 @@
#include "base/message_loop/message_pump_type.h"
#include "base/strings/utf_string_conversions.h"
+#include "ui/base/buildflags.h"
+#include "ui/base/ime/linux/linux_input_method_context_factory.h"
#include "ui/base/x/x11_util.h"
#include "ui/display/fake/fake_display_delegate.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
-#include "ui/events/platform/x11/x11_event_source_default.h"
+#include "ui/events/platform/x11/x11_event_source.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/x/x11_connection.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/ozone/common/stub_overlay_manager.h"
@@ -36,6 +39,18 @@
#include "ui/base/ime/linux/input_method_auralinux.h"
#endif
+#if BUILDFLAG(USE_GTK)
+#include "ui/gtk/gtk_ui_delegate.h" // nogncheck
+#include "ui/gtk/gtk_ui_delegate_x11.h" // nogncheck
+#endif
+
+#if BUILDFLAG(USE_XKBCOMMON)
+#include "ui/events/ozone/layout/xkb/xkb_evdev_codes.h"
+#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
+#else
+#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
+#endif
+
namespace ui {
namespace {
@@ -108,10 +123,17 @@ class OzonePlatformX11 : public OzonePlatform {
}
std::unique_ptr<InputMethod> CreateInputMethod(
- internal::InputMethodDelegate* delegate) override {
+ internal::InputMethodDelegate* delegate,
+ gfx::AcceleratedWidget) override {
#if defined(OS_CHROMEOS)
return std::make_unique<InputMethodChromeOS>(delegate);
#else
+ // This method is used by upper layer components (e.g: GtkUi) to determine
+ // if the LinuxInputMethodContextFactory instance is provided by the Ozone
+ // platform implementation, so we must consider the case that it is still
+ // not set at this point.
+ if (!ui::LinuxInputMethodContextFactory::instance())
+ return nullptr;
return std::make_unique<InputMethodAuraLinux>(delegate);
#endif
}
@@ -129,12 +151,24 @@ class OzonePlatformX11 : public OzonePlatform {
cursor_factory_ozone_ = std::make_unique<X11CursorFactoryOzone>();
gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
- // TODO(spang): Support XKB.
+#if BUILDFLAG(USE_XKBCOMMON)
+ keyboard_layout_engine_ =
+ std::make_unique<XkbKeyboardLayoutEngine>(xkb_evdev_code_converter_);
+ // TODO(nickdiego): debugging..
+ keyboard_layout_engine_ = std::make_unique<StubKeyboardLayoutEngine>();
+#else
keyboard_layout_engine_ = std::make_unique<StubKeyboardLayoutEngine>();
+#endif
KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
keyboard_layout_engine_.get());
TouchFactory::SetTouchDeviceListFromCommandLine();
+
+#if BUILDFLAG(USE_GTK)
+ DCHECK(!GtkUiDelegate::instance());
+ gtk_ui_delegate_ = std::make_unique<GtkUiDelegateX11>(gfx::GetXDisplay());
+ GtkUiDelegate::SetInstance(gtk_ui_delegate_.get());
+#endif
}
void InitializeGPU(const InitParams& params) override {
@@ -175,11 +209,15 @@ class OzonePlatformX11 : public OzonePlatform {
return;
XDisplay* display = gfx::GetXDisplay();
- event_source_ = std::make_unique<X11EventSourceDefault>(display);
+ event_source_ = std::make_unique<X11EventSource>(display);
}
bool common_initialized_ = false;
+#if BUILDFLAG(USE_XKBCOMMON)
+ XkbEvdevCodes xkb_evdev_code_converter_;
+#endif
+
// Objects in the UI process.
std::unique_ptr<KeyboardLayoutEngine> keyboard_layout_engine_;
std::unique_ptr<OverlayManagerOzone> overlay_manager_;
@@ -192,7 +230,11 @@ class OzonePlatformX11 : public OzonePlatform {
std::unique_ptr<X11SurfaceFactory> surface_factory_ozone_;
// Objects in both UI and GPU process.
- std::unique_ptr<X11EventSourceDefault> event_source_;
+ std::unique_ptr<X11EventSource> event_source_;
+
+#if BUILDFLAG(USE_GTK)
+ std::unique_ptr<GtkUiDelegate> gtk_ui_delegate_;
+#endif
DISALLOW_COPY_AND_ASSIGN(OzonePlatformX11);
};
diff --git a/chromium/ui/ozone/platform/x11/x11_canvas_surface.cc b/chromium/ui/ozone/platform/x11/x11_canvas_surface.cc
index 49afa733b9b..59cd3740d63 100644
--- a/chromium/ui/ozone/platform/x11/x11_canvas_surface.cc
+++ b/chromium/ui/ozone/platform/x11/x11_canvas_surface.cc
@@ -11,25 +11,22 @@
namespace ui {
-X11CanvasSurface::X11CanvasSurface(gfx::AcceleratedWidget widget,
- base::TaskRunner* gpu_task_runner)
+X11CanvasSurface::X11CanvasSurface(
+ gfx::AcceleratedWidget widget,
+ scoped_refptr<base::SequencedTaskRunner> gpu_task_runner)
: task_runner_(base::SequencedTaskRunnerHandle::Get()),
x11_software_bitmap_presenter_(widget,
task_runner_.get(),
- gpu_task_runner) {}
+ std::move(gpu_task_runner)) {}
X11CanvasSurface::~X11CanvasSurface() = default;
-sk_sp<SkSurface> X11CanvasSurface::GetSurface() {
- DCHECK(surface_);
- return surface_;
+SkCanvas* X11CanvasSurface::GetCanvas() {
+ return x11_software_bitmap_presenter_.GetSkCanvas();
}
void X11CanvasSurface::ResizeCanvas(const gfx::Size& viewport_size) {
x11_software_bitmap_presenter_.Resize(viewport_size);
- SkImageInfo info = SkImageInfo::MakeN32(
- viewport_size.width(), viewport_size.height(), kOpaque_SkAlphaType);
- surface_ = x11_software_bitmap_presenter_.GetSkCanvas()->makeSurface(info);
}
void X11CanvasSurface::PresentCanvas(const gfx::Rect& damage) {
diff --git a/chromium/ui/ozone/platform/x11/x11_canvas_surface.h b/chromium/ui/ozone/platform/x11/x11_canvas_surface.h
index b6371f5cf71..a93e22677a0 100644
--- a/chromium/ui/ozone/platform/x11/x11_canvas_surface.h
+++ b/chromium/ui/ozone/platform/x11/x11_canvas_surface.h
@@ -8,6 +8,8 @@
#include <memory>
#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/sequenced_task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -16,6 +18,8 @@
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/public/surface_ozone_canvas.h"
+class SkSurface;
+
namespace ui {
// The platform-specific part of an software output. The class is intended
@@ -25,11 +29,11 @@ namespace ui {
class X11CanvasSurface : public SurfaceOzoneCanvas {
public:
X11CanvasSurface(gfx::AcceleratedWidget widget,
- base::TaskRunner* gpu_task_runner);
+ scoped_refptr<base::SequencedTaskRunner> gpu_task_runner);
~X11CanvasSurface() override;
// SurfaceOzoneCanvas overrides:
- sk_sp<SkSurface> GetSurface() override;
+ SkCanvas* GetCanvas() override;
void ResizeCanvas(const gfx::Size& viewport_size) override;
void PresentCanvas(const gfx::Rect& damage) override;
std::unique_ptr<gfx::VSyncProvider> CreateVSyncProvider() override;
diff --git a/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.cc b/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.cc
index e7d91ab8626..e981ade21b6 100644
--- a/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.cc
+++ b/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.cc
@@ -5,7 +5,9 @@
#include "ui/ozone/platform/x11/x11_cursor_factory_ozone.h"
#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/cursor/cursor_lookup.h"
#include "ui/base/cursor/cursors_aura.h"
+#include "ui/base/mojom/cursor_type.mojom-shared.h"
#include "ui/gfx/geometry/point.h"
namespace ui {
@@ -21,11 +23,11 @@ PlatformCursor ToPlatformCursor(X11CursorOzone* cursor) {
}
// Gets default aura cursor bitmap/hotspot and creates a X11CursorOzone with it.
-scoped_refptr<X11CursorOzone> CreateAuraX11Cursor(CursorType type) {
+scoped_refptr<X11CursorOzone> CreateAuraX11Cursor(mojom::CursorType type) {
Cursor cursor(type);
- cursor.set_device_scale_factor(1);
- SkBitmap bitmap = cursor.GetBitmap();
- gfx::Point hotspot = cursor.GetHotspot();
+ cursor.set_image_scale_factor(1);
+ SkBitmap bitmap = GetCursorBitmap(cursor);
+ gfx::Point hotspot = GetCursorHotspot(cursor);
if (!bitmap.isNull())
return new X11CursorOzone(bitmap, hotspot);
return nullptr;
@@ -38,7 +40,7 @@ X11CursorFactoryOzone::X11CursorFactoryOzone()
X11CursorFactoryOzone::~X11CursorFactoryOzone() {}
-PlatformCursor X11CursorFactoryOzone::GetDefaultCursor(CursorType type) {
+PlatformCursor X11CursorFactoryOzone::GetDefaultCursor(mojom::CursorType type) {
return ToPlatformCursor(GetDefaultCursorInternal(type).get());
}
@@ -83,8 +85,8 @@ void X11CursorFactoryOzone::UnrefImageCursor(PlatformCursor cursor) {
}
scoped_refptr<X11CursorOzone> X11CursorFactoryOzone::GetDefaultCursorInternal(
- CursorType type) {
- if (type == CursorType::kNone)
+ mojom::CursorType type) {
+ if (type == mojom::CursorType::kNone)
return invisible_cursor_;
if (!default_cursors_.count(type)) {
@@ -100,8 +102,8 @@ scoped_refptr<X11CursorOzone> X11CursorFactoryOzone::GetDefaultCursorInternal(
// pointer cursor then invisible cursor if this fails.
cursor = CreateAuraX11Cursor(type);
if (!cursor.get()) {
- if (type != CursorType::kPointer) {
- cursor = GetDefaultCursorInternal(CursorType::kPointer);
+ if (type != mojom::CursorType::kPointer) {
+ cursor = GetDefaultCursorInternal(mojom::CursorType::kPointer);
} else {
NOTREACHED() << "Failed to load default cursor bitmap";
}
diff --git a/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h b/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h
index 48859f4bfd5..05347bd6cd8 100644
--- a/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h
+++ b/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "ui/base/cursor/cursor.h"
+#include "ui/base/mojom/cursor_type.mojom-forward.h"
#include "ui/gfx/x/x11.h"
#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
#include "ui/ozone/public/cursor_factory_ozone.h"
@@ -24,7 +25,7 @@ class X11CursorFactoryOzone : public CursorFactoryOzone {
~X11CursorFactoryOzone() override;
// CursorFactoryOzone:
- PlatformCursor GetDefaultCursor(CursorType type) override;
+ PlatformCursor GetDefaultCursor(mojom::CursorType type) override;
PlatformCursor CreateImageCursor(const SkBitmap& bitmap,
const gfx::Point& hotspot,
float bitmap_dpi) override;
@@ -37,13 +38,14 @@ class X11CursorFactoryOzone : public CursorFactoryOzone {
private:
// Loads/caches default cursor or returns cached version.
- scoped_refptr<X11CursorOzone> GetDefaultCursorInternal(CursorType type);
+ scoped_refptr<X11CursorOzone> GetDefaultCursorInternal(
+ mojom::CursorType type);
// Holds a single instance of the invisible cursor. X11 has no way to hide
// the cursor so an invisible cursor mimics that.
scoped_refptr<X11CursorOzone> invisible_cursor_;
- std::map<CursorType, scoped_refptr<X11CursorOzone>> default_cursors_;
+ std::map<mojom::CursorType, scoped_refptr<X11CursorOzone>> default_cursors_;
DISALLOW_COPY_AND_ASSIGN(X11CursorFactoryOzone);
};
diff --git a/chromium/ui/ozone/platform/x11/x11_screen_ozone.cc b/chromium/ui/ozone/platform/x11/x11_screen_ozone.cc
index 034831fee00..5d5b60fdd1f 100644
--- a/chromium/ui/ozone/platform/x11/x11_screen_ozone.cc
+++ b/chromium/ui/ozone/platform/x11/x11_screen_ozone.cc
@@ -173,6 +173,10 @@ void X11ScreenOzone::RemoveObserver(display::DisplayObserver* observer) {
x11_display_manager_->RemoveObserver(observer);
}
+std::string X11ScreenOzone::GetCurrentWorkspace() {
+ return x11_display_manager_->GetCurrentWorkspace();
+}
+
bool X11ScreenOzone::DispatchXEvent(XEvent* xev) {
return x11_display_manager_->ProcessEvent(xev);
}
@@ -187,7 +191,7 @@ void X11ScreenOzone::OnXDisplayListUpdated() {
gfx::SetFontRenderParamsDeviceScaleFactor(scale_factor);
}
-float X11ScreenOzone::GetXDisplayScaleFactor() {
+float X11ScreenOzone::GetXDisplayScaleFactor() const {
return GetDeviceScaleFactor();
}
diff --git a/chromium/ui/ozone/platform/x11/x11_screen_ozone.h b/chromium/ui/ozone/platform/x11/x11_screen_ozone.h
index fb214b1544f..32493fca0c6 100644
--- a/chromium/ui/ozone/platform/x11/x11_screen_ozone.h
+++ b/chromium/ui/ozone/platform/x11/x11_screen_ozone.h
@@ -45,6 +45,7 @@ class X11ScreenOzone : public PlatformScreen,
const gfx::Rect& match_rect) const override;
void AddObserver(display::DisplayObserver* observer) override;
void RemoveObserver(display::DisplayObserver* observer) override;
+ std::string GetCurrentWorkspace() override;
// Overridden from ui::XEventDispatcher:
bool DispatchXEvent(XEvent* event) override;
@@ -54,7 +55,7 @@ class X11ScreenOzone : public PlatformScreen,
// Overridden from ui::XDisplayManager::Delegate:
void OnXDisplayListUpdated() override;
- float GetXDisplayScaleFactor() override;
+ float GetXDisplayScaleFactor() const override;
gfx::Point GetCursorLocation() const;
diff --git a/chromium/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc b/chromium/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc
index 87ae05c85f2..121a6ccc77c 100644
--- a/chromium/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc
+++ b/chromium/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc
@@ -12,7 +12,7 @@
#include "ui/base/x/x11_display_manager.h"
#include "ui/display/display.h"
#include "ui/display/display_observer.h"
-#include "ui/events/platform/x11/x11_event_source_default.h"
+#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/ozone/platform/x11/x11_window_ozone.h"
#include "ui/ozone/test/mock_platform_window_delegate.h"
#include "ui/platform_window/platform_window_delegate.h"
@@ -56,7 +56,7 @@ class X11ScreenOzoneTest : public testing::Test {
void SetUp() override {
XDisplay* display = gfx::GetXDisplay();
- event_source_ = std::make_unique<X11EventSourceDefault>(display);
+ event_source_ = std::make_unique<X11EventSource>(display);
primary_display_ = std::make_unique<display::Display>(
NextDisplayId(), kPrimaryDisplayBounds);
screen_ = std::make_unique<X11ScreenOzone>();
@@ -112,7 +112,7 @@ class X11ScreenOzoneTest : public testing::Test {
private:
std::unique_ptr<display::Display> primary_display_;
std::unique_ptr<X11ScreenOzone> screen_;
- std::unique_ptr<X11EventSourceDefault> event_source_;
+ std::unique_ptr<X11EventSource> event_source_;
std::unique_ptr<base::test::TaskEnvironment> task_env_;
DISALLOW_COPY_AND_ASSIGN(X11ScreenOzoneTest);
diff --git a/chromium/ui/ozone/platform/x11/x11_surface_factory.cc b/chromium/ui/ozone/platform/x11/x11_surface_factory.cc
index c231ba2964b..fa2289015ef 100644
--- a/chromium/ui/ozone/platform/x11/x11_surface_factory.cc
+++ b/chromium/ui/ozone/platform/x11/x11_surface_factory.cc
@@ -55,8 +55,9 @@ class GLOzoneEGLX11 : public GLOzoneEGL {
protected:
// GLOzoneEGL:
- intptr_t GetNativeDisplay() override {
- return reinterpret_cast<intptr_t>(gfx::GetXDisplay());
+ gl::EGLDisplayPlatform GetNativeDisplay() override {
+ return gl::EGLDisplayPlatform(
+ reinterpret_cast<EGLNativeDisplayType>(gfx::GetXDisplay()));
}
bool LoadGLES2Bindings(gl::GLImplementation implementation) override {
@@ -106,8 +107,8 @@ X11SurfaceFactory::CreateVulkanImplementation(bool allow_protected_memory,
std::unique_ptr<SurfaceOzoneCanvas> X11SurfaceFactory::CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) {
- return std::make_unique<X11CanvasSurface>(widget, task_runner);
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ return std::make_unique<X11CanvasSurface>(widget, std::move(task_runner));
}
} // namespace ui
diff --git a/chromium/ui/ozone/platform/x11/x11_surface_factory.h b/chromium/ui/ozone/platform/x11/x11_surface_factory.h
index 18a2ee788d6..33dbb696253 100644
--- a/chromium/ui/ozone/platform/x11/x11_surface_factory.h
+++ b/chromium/ui/ozone/platform/x11/x11_surface_factory.h
@@ -32,7 +32,7 @@ class X11SurfaceFactory : public SurfaceFactoryOzone {
#endif
std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) override;
+ scoped_refptr<base::SequencedTaskRunner> task_runner) override;
private:
std::unique_ptr<GLOzone> glx_implementation_;
diff --git a/chromium/ui/ozone/platform/x11/x11_window_ozone.cc b/chromium/ui/ozone/platform/x11/x11_window_ozone.cc
index ee9fd3cca72..5334049b13f 100644
--- a/chromium/ui/ozone/platform/x11/x11_window_ozone.cc
+++ b/chromium/ui/ozone/platform/x11/x11_window_ozone.cc
@@ -4,77 +4,19 @@
#include "ui/ozone/platform/x11/x11_window_ozone.h"
-#include <algorithm>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/events/event.h"
-#include "ui/events/event_utils.h"
-#include "ui/events/platform/x11/x11_event_source.h"
-#include "ui/gfx/x/x11.h"
-#include "ui/gfx/x/x11_atom_cache.h"
#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
-#include "ui/platform_window/platform_window_init_properties.h"
+#include "ui/platform_window/platform_window_delegate.h"
namespace ui {
X11WindowOzone::X11WindowOzone(PlatformWindowDelegate* delegate)
: X11Window(delegate) {}
-X11WindowOzone::~X11WindowOzone() {
- PrepareForShutdown();
- Close();
-}
-
-void X11WindowOzone::PrepareForShutdown() {
- DCHECK(X11EventSource::GetInstance());
- X11EventSource::GetInstance()->RemoveXEventDispatcher(this);
-}
+X11WindowOzone::~X11WindowOzone() = default;
void X11WindowOzone::SetCursor(PlatformCursor cursor) {
X11CursorOzone* cursor_ozone = static_cast<X11CursorOzone*>(cursor);
XWindow::SetCursor(cursor_ozone->xcursor());
}
-// CheckCanDispatchNextPlatformEvent is called by X11EventSourceLibevent to
-// determine whether X11WindowOzone instance (XEventDispatcher implementation)
-// is able to process next translated event sent by it. So, it's done through
-// |handle_next_event_| internal flag, used in subsequent CanDispatchEvent
-// call.
-void X11WindowOzone::CheckCanDispatchNextPlatformEvent(XEvent* xev) {
- if (is_shutting_down())
- return;
-
- handle_next_event_ = XWindow::IsTargetedBy(*xev);
-}
-
-void X11WindowOzone::PlatformEventDispatchFinished() {
- handle_next_event_ = false;
-}
-
-PlatformEventDispatcher* X11WindowOzone::GetPlatformEventDispatcher() {
- return this;
-}
-
-bool X11WindowOzone::DispatchXEvent(XEvent* xev) {
- if (!XWindow::IsTargetedBy(*xev))
- return false;
-
- XWindow::ProcessEvent(xev);
- return true;
-}
-
-bool X11WindowOzone::CanDispatchEvent(const PlatformEvent& event) {
- DCHECK_NE(XWindow::window(), x11::None);
- return handle_next_event_;
-}
-
-void X11WindowOzone::SetPlatformEventDispatcher() {
- DCHECK(X11EventSource::GetInstance());
- X11EventSource::GetInstance()->AddXEventDispatcher(this);
-}
-
} // namespace ui
diff --git a/chromium/ui/ozone/platform/x11/x11_window_ozone.h b/chromium/ui/ozone/platform/x11/x11_window_ozone.h
index 352be12dc2b..edf18b39b76 100644
--- a/chromium/ui/ozone/platform/x11/x11_window_ozone.h
+++ b/chromium/ui/ozone/platform/x11/x11_window_ozone.h
@@ -5,49 +5,22 @@
#ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_H_
#define UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_H_
-#include <array>
-#include <memory>
-
-#include "base/containers/flat_set.h"
#include "base/macros.h"
-#include "ui/base/x/x11_window.h"
-#include "ui/events/platform/platform_event_dispatcher.h"
-#include "ui/events/platform/x11/x11_event_source.h"
-#include "ui/events/x/x11_window_event_manager.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/x/x11_types.h"
#include "ui/platform_window/x11/x11_window.h"
namespace ui {
+class PlatformWindowDelegate;
+
// PlatformWindow implementation for X11 Ozone. PlatformEvents are ui::Events.
-class X11WindowOzone : public X11Window, public XEventDispatcher {
+class X11WindowOzone : public X11Window {
public:
explicit X11WindowOzone(PlatformWindowDelegate* delegate);
~X11WindowOzone() override;
// Overridden from PlatformWindow:
- void PrepareForShutdown() override;
void SetCursor(PlatformCursor cursor) override;
- // Overridden from ui::XEventDispatcher:
- void CheckCanDispatchNextPlatformEvent(XEvent* xev) override;
- void PlatformEventDispatchFinished() override;
- PlatformEventDispatcher* GetPlatformEventDispatcher() override;
- bool DispatchXEvent(XEvent* event) override;
-
- private:
- // X11Window overrides:
- void SetPlatformEventDispatcher() override;
-
- // PlatformEventDispatcher:
- bool CanDispatchEvent(const PlatformEvent& event) override;
-
- // Tells if this dispatcher can process next translated event based on a
- // previous check in ::CheckCanDispatchNextPlatformEvent based on a XID
- // target.
- bool handle_next_event_ = false;
-
DISALLOW_COPY_AND_ASSIGN(X11WindowOzone);
};
diff --git a/chromium/ui/ozone/platform/x11/x11_window_ozone_unittest.cc b/chromium/ui/ozone/platform/x11/x11_window_ozone_unittest.cc
index 099e88b847d..e2c5fb1f609 100644
--- a/chromium/ui/ozone/platform/x11/x11_window_ozone_unittest.cc
+++ b/chromium/ui/ozone/platform/x11/x11_window_ozone_unittest.cc
@@ -11,10 +11,10 @@
#include "base/test/task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/display/display.h"
-#include "ui/display/screen.h"
+#include "ui/display/screen_base.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/event.h"
-#include "ui/events/platform/x11/x11_event_source_default.h"
+#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/events/test/events_test_utils_x11.h"
#include "ui/ozone/test/mock_platform_window_delegate.h"
#include "ui/platform_window/platform_window_delegate.h"
@@ -43,41 +43,21 @@ ACTION_P(CloneEvent, event_ptr) {
// ScreenOzone, but it is impossible.
// We are not really interested in sending back real displays. Thus, default one
// is more than enough.
-class TestScreen : public display::Screen {
+class TestScreen : public display::ScreenBase {
public:
- TestScreen() : displays_({}) {}
- ~TestScreen() override = default;
-
- // display::Screen interface.
- gfx::Point GetCursorScreenPoint() override { return {}; }
- bool IsWindowUnderCursor(gfx::NativeWindow window) override { return false; }
- gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override {
- return gfx::NativeWindow();
- }
- int GetNumDisplays() const override { return GetAllDisplays().size(); }
- const std::vector<display::Display>& GetAllDisplays() const override {
- return displays_;
- }
- display::Display GetDisplayNearestWindow(
- gfx::NativeWindow window) const override {
- return {};
- }
- display::Display GetDisplayNearestPoint(
- const gfx::Point& point) const override {
- return {};
+ TestScreen() {
+ ProcessDisplayChanged({}, true);
}
- display::Display GetDisplayMatching(
- const gfx::Rect& match_rect) const override {
- return {};
+ ~TestScreen() override = default;
+ TestScreen(const TestScreen& screen) = delete;
+ TestScreen& operator=(const TestScreen& screen) = delete;
+
+ void SetScaleAndBoundsForPrimaryDisplay(float scale,
+ const gfx::Rect& bounds_in_pixels) {
+ auto display = GetPrimaryDisplay();
+ display.SetScaleAndBounds(scale, bounds_in_pixels);
+ ProcessDisplayChanged(display, true);
}
- display::Display GetPrimaryDisplay() const override { return {}; }
- void AddObserver(display::DisplayObserver* observer) override {}
- void RemoveObserver(display::DisplayObserver* observer) override {}
-
- private:
- std::vector<display::Display> displays_;
-
- DISALLOW_COPY_AND_ASSIGN(TestScreen);
}; // namespace
} // namespace
@@ -92,9 +72,10 @@ class X11WindowOzoneTest : public testing::Test {
void SetUp() override {
XDisplay* display = gfx::GetXDisplay();
- event_source_ = std::make_unique<X11EventSourceDefault>(display);
+ event_source_ = std::make_unique<X11EventSource>(display);
- display::Screen::SetScreenInstance(new TestScreen());
+ test_screen_ = new TestScreen();
+ display::Screen::SetScreenInstance(test_screen_);
TouchFactory::GetInstance()->SetPointerDeviceForTest({kPointerDeviceId});
}
@@ -126,9 +107,11 @@ class X11WindowOzoneTest : public testing::Test {
return window_manager;
}
+ TestScreen* test_screen_ = nullptr;
+
private:
std::unique_ptr<base::test::TaskEnvironment> task_env_;
- std::unique_ptr<X11EventSourceDefault> event_source_;
+ std::unique_ptr<X11EventSource> event_source_;
DISALLOW_COPY_AND_ASSIGN(X11WindowOzoneTest);
};
@@ -198,6 +181,7 @@ TEST_F(X11WindowOzoneTest, SendPlatformEventToCapturedWindow) {
EXPECT_CALL(delegate_2, DispatchEvent(_)).WillOnce(CloneEvent(&event));
DispatchXEvent(xi_event, widget);
+ EXPECT_TRUE(event.get());
EXPECT_EQ(ET_MOUSE_PRESSED, event->type());
EXPECT_EQ(gfx::Point(-277, 215), event->AsLocatedEvent()->location());
}
@@ -267,4 +251,18 @@ TEST_F(X11WindowOzoneTest, MouseEnterAndDelete) {
EXPECT_FALSE(window_manager()->window_mouse_currently_on_for_test());
}
+// Verifies X11Window sets fullscreen bounds in pixels when going to fullscreen.
+TEST_F(X11WindowOzoneTest, ToggleFullscreen) {
+ constexpr gfx::Rect screen_bounds_in_px(640, 480, 1280, 720);
+ test_screen_->SetScaleAndBoundsForPrimaryDisplay(2, screen_bounds_in_px);
+
+ MockPlatformWindowDelegate delegate;
+ gfx::AcceleratedWidget widget;
+ constexpr gfx::Rect bounds(30, 80, 800, 600);
+ auto window = CreatePlatformWindow(&delegate, bounds, &widget);
+
+ EXPECT_CALL(delegate, OnBoundsChanged(screen_bounds_in_px));
+ window->ToggleFullscreen();
+}
+
} // namespace ui
diff --git a/chromium/ui/ozone/public/DEPS b/chromium/ui/ozone/public/DEPS
index ef8ad28d9d4..6d31ede447e 100644
--- a/chromium/ui/ozone/public/DEPS
+++ b/chromium/ui/ozone/public/DEPS
@@ -1,3 +1,4 @@
include_rules = [
"+mojo/public",
+ "+ui/base/mojom/cursor_type.mojom-forward.h",
]
diff --git a/chromium/ui/ozone/public/cursor_factory_ozone.cc b/chromium/ui/ozone/public/cursor_factory_ozone.cc
index 01b80c66d5d..542dce20aaa 100644
--- a/chromium/ui/ozone/public/cursor_factory_ozone.cc
+++ b/chromium/ui/ozone/public/cursor_factory_ozone.cc
@@ -30,7 +30,7 @@ CursorFactoryOzone* CursorFactoryOzone::GetInstance() {
return g_instance;
}
-PlatformCursor CursorFactoryOzone::GetDefaultCursor(CursorType type) {
+PlatformCursor CursorFactoryOzone::GetDefaultCursor(mojom::CursorType type) {
NOTIMPLEMENTED();
return NULL;
}
diff --git a/chromium/ui/ozone/public/cursor_factory_ozone.h b/chromium/ui/ozone/public/cursor_factory_ozone.h
index 7dc9986242c..4492d2404b0 100644
--- a/chromium/ui/ozone/public/cursor_factory_ozone.h
+++ b/chromium/ui/ozone/public/cursor_factory_ozone.h
@@ -8,6 +8,7 @@
#include <vector>
#include "base/component_export.h"
+#include "ui/base/mojom/cursor_type.mojom-forward.h"
#include "ui/gfx/native_widget_types.h"
namespace gfx {
@@ -29,7 +30,7 @@ class COMPONENT_EXPORT(OZONE_BASE) CursorFactoryOzone {
// Return the default cursor of the specified type. The types are listed in
// ui/base/cursor/cursor.h. Default cursors are managed by the implementation
// and must live indefinitely; there's no way to know when to free them.
- virtual PlatformCursor GetDefaultCursor(CursorType type);
+ virtual PlatformCursor GetDefaultCursor(mojom::CursorType type);
// Return a image cursor from the specified image & hotspot. Image cursors
// are referenced counted and have an initial refcount of 1. Therefore, each
diff --git a/chromium/ui/ozone/public/gl_ozone.h b/chromium/ui/ozone/public/gl_ozone.h
index d280011016e..a12283fdd8c 100644
--- a/chromium/ui/ozone/public/gl_ozone.h
+++ b/chromium/ui/ozone/public/gl_ozone.h
@@ -40,9 +40,6 @@ class COMPONENT_EXPORT(OZONE_BASE) GLOzone {
// Performs any one off initialization for GL implementation.
virtual bool InitializeGLOneOffPlatform() = 0;
- // Initializes static debug GL bindings.
- virtual void InitializeLogGLBindings() = 0;
-
// Disables the specified extensions in the window system bindings,
// e.g., GLX, EGL, etc. This is part of the GPU driver bug workarounds
// mechanism.
diff --git a/chromium/ui/ozone/public/gpu_platform_support_host.h b/chromium/ui/ozone/public/gpu_platform_support_host.h
index 4839359e461..af6da1d2879 100644
--- a/chromium/ui/ozone/public/gpu_platform_support_host.h
+++ b/chromium/ui/ozone/public/gpu_platform_support_host.h
@@ -12,7 +12,7 @@
#include "base/single_thread_task_runner.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
-#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/system/message_pipe.h"
namespace ui {
diff --git a/chromium/ui/ozone/public/input_controller.cc b/chromium/ui/ozone/public/input_controller.cc
index 9ea7cb30a1d..2f2bd8688a3 100644
--- a/chromium/ui/ozone/public/input_controller.cc
+++ b/chromium/ui/ozone/public/input_controller.cc
@@ -36,15 +36,19 @@ class StubInputController : public InputController {
NOTIMPLEMENTED_LOG_ONCE();
}
void SetTouchpadSensitivity(int value) override {}
+ void SetTouchpadScrollSensitivity(int value) override {}
void SetTapToClick(bool enabled) override {}
void SetThreeFingerClick(bool enabled) override {}
void SetTapDragging(bool enabled) override {}
void SetNaturalScroll(bool enabled) override {}
void SetMouseSensitivity(int value) override {}
+ void SetMouseScrollSensitivity(int value) override {}
void SetPrimaryButtonRight(bool right) override {}
void SetMouseReverseScroll(bool enabled) override {}
void SetMouseAcceleration(bool enabled) override {}
+ void SetMouseScrollAcceleration(bool enabled) override {}
void SetTouchpadAcceleration(bool enabled) override {}
+ void SetTouchpadScrollAcceleration(bool enabled) override {}
void SetTapToClickPaused(bool state) override {}
void GetTouchDeviceStatus(GetTouchDeviceStatusReply reply) override {
std::move(reply).Run(std::string());
diff --git a/chromium/ui/ozone/public/input_controller.h b/chromium/ui/ozone/public/input_controller.h
index d001a4373a1..cc7c323f683 100644
--- a/chromium/ui/ozone/public/input_controller.h
+++ b/chromium/ui/ozone/public/input_controller.h
@@ -59,17 +59,21 @@ class COMPONENT_EXPORT(OZONE_BASE) InputController {
// Touchpad settings.
virtual void SetTouchpadSensitivity(int value) = 0;
+ virtual void SetTouchpadScrollSensitivity(int value) = 0;
virtual void SetTapToClick(bool enabled) = 0;
virtual void SetThreeFingerClick(bool enabled) = 0;
virtual void SetTapDragging(bool enabled) = 0;
virtual void SetNaturalScroll(bool enabled) = 0;
virtual void SetTouchpadAcceleration(bool enabled) = 0;
+ virtual void SetTouchpadScrollAcceleration(bool enabled) = 0;
// Mouse settings.
virtual void SetMouseSensitivity(int value) = 0;
+ virtual void SetMouseScrollSensitivity(int value) = 0;
virtual void SetPrimaryButtonRight(bool right) = 0;
virtual void SetMouseReverseScroll(bool enabled) = 0;
virtual void SetMouseAcceleration(bool enabled) = 0;
+ virtual void SetMouseScrollAcceleration(bool enabled) = 0;
// Touch log collection.
virtual void GetTouchDeviceStatus(GetTouchDeviceStatusReply reply) = 0;
diff --git a/chromium/ui/ozone/public/mojom/BUILD.gn b/chromium/ui/ozone/public/mojom/BUILD.gn
index 947b207a407..83bb9451364 100644
--- a/chromium/ui/ozone/public/mojom/BUILD.gn
+++ b/chromium/ui/ozone/public/mojom/BUILD.gn
@@ -8,7 +8,6 @@ mojom("mojom") {
sources = [
"device_cursor.mojom",
"drm_device.mojom",
- "overlay_surface_candidate.mojom",
"scenic_gpu_host.mojom",
"scenic_gpu_service.mojom",
]
@@ -23,41 +22,7 @@ mojom("mojom") {
}
mojom("gesture_properties_service") {
- sources = [
- "gesture_properties_service.mojom",
- ]
+ sources = [ "gesture_properties_service.mojom" ]
- public_deps = [
- "//mojo/public/mojom/base",
- ]
-}
-
-source_set("mojom_traits") {
- sources = [
- "overlay_surface_candidate_mojom_traits.h",
- ]
- deps = [
- "//ui/gfx/geometry/mojom",
- "//ui/gfx/mojom",
- ]
- public_deps = [
- ":mojom",
- ":mojom_shared_cpp_sources",
- "//mojo/public/cpp/bindings",
- ]
-}
-
-source_set("mojom_trait_unit_test") {
- testonly = true
-
- sources = [
- "overlay_surface_candidate_mojom_traits_unittest.cc",
- ]
-
- deps = [
- ":mojom",
- ":mojom_traits",
- "//testing/gtest",
- "//ui/gfx/geometry",
- ]
+ public_deps = [ "//mojo/public/mojom/base" ]
}
diff --git a/chromium/ui/ozone/public/mojom/drm_device.mojom b/chromium/ui/ozone/public/mojom/drm_device.mojom
index 56fdb1d180d..c9b31a6c68c 100644
--- a/chromium/ui/ozone/public/mojom/drm_device.mojom
+++ b/chromium/ui/ozone/public/mojom/drm_device.mojom
@@ -13,8 +13,6 @@ import "ui/display/mojom/gamma_ramp_rgb_entry.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/gfx/mojom/accelerated_widget.mojom";
import "ui/ozone/public/mojom/device_cursor.mojom";
-import "ui/ozone/public/mojom/overlay_surface_candidate.mojom";
-
// The viz process on CrOS implements the DrmDevice
// service to let the viz host and clients manage DRM displays.
@@ -78,18 +76,11 @@ interface DrmDevice {
array<display.mojom.GammaRampRGBEntry> degamma_lut,
array<display.mojom.GammaRampRGBEntry> gamma_lut);
- // Verifies if the display controller can successfully scanout the given set
- // of OverlaySurfaceCandidates and return the status associated with each
- // candidate.
- CheckOverlayCapabilities(gfx.mojom.AcceleratedWidget widget,
- array<ui.ozone.mojom.OverlaySurfaceCandidate> candidates) =>
- (gfx.mojom.AcceleratedWidget widget,
- array<ui.ozone.mojom.OverlaySurfaceCandidate> candidates,
- array<ui.ozone.mojom.OverlayStatus> status);
+ // Sets the state of the privacy screen feature.
+ SetPrivacyScreen(int64 display_id, bool enabled);
// Provides a DeviceCursor interface. The provided interface needs to be
// associated because the AcceleratedWidgets referenced by its methods are
// registered via CreateWindow() in this interface.
GetDeviceCursor(pending_associated_receiver<DeviceCursor> cursor);
};
-
diff --git a/chromium/ui/ozone/public/mojom/overlay_surface_candidate.mojom b/chromium/ui/ozone/public/mojom/overlay_surface_candidate.mojom
deleted file mode 100644
index 8dd6b7eb471..00000000000
--- a/chromium/ui/ozone/public/mojom/overlay_surface_candidate.mojom
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module ui.ozone.mojom;
-
-import "ui/gfx/geometry/mojom/geometry.mojom";
-import "ui/gfx/mojom/buffer_types.mojom";
-import "ui/gfx/mojom/overlay_transform.mojom";
-
-// ui::OverlayStatus
-enum OverlayStatus {
- OVERLAY_STATUS_PENDING,
- OVERLAY_STATUS_ABLE,
- OVERLAY_STATUS_NOT,
-};
-
-struct OverlaySurfaceCandidate {
- // Transformation to apply to layer during composition.
- gfx.mojom.OverlayTransform transform;
- // Format of the buffer to composite.
- gfx.mojom.BufferFormat format;
- // Size of the buffer, in pixels.
- gfx.mojom.Size buffer_size;
- // Rect on the display to position the overlay to. Input rectangle may
- // not have integer coordinates, but when accepting for overlay, must
- // be modified by CheckOverlaySupport to output integer values.
- gfx.mojom.RectF display_rect;
- // Crop within the buffer to be placed inside |display_rect|.
- gfx.mojom.RectF crop_rect;
- // Clip rect in the target content space after composition.
- gfx.mojom.Rect clip_rect;
- // If the quad is clipped after composition.
- bool is_clipped;
- // If the quad doesn't require blending.
- bool is_opaque;
- // Stacking order of the overlay plane relative to the main surface,
- // which is 0. Signed to allow for "underlays".
- int32 plane_z_order = 0;
-
- // To be modified by the implementer if this candidate can go into
- // an overlay.
- bool overlay_handled;
-};
diff --git a/chromium/ui/ozone/public/mojom/overlay_surface_candidate.typemap b/chromium/ui/ozone/public/mojom/overlay_surface_candidate.typemap
deleted file mode 100644
index 10d6f6d02d4..00000000000
--- a/chromium/ui/ozone/public/mojom/overlay_surface_candidate.typemap
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//ui/ozone/public/mojom/overlay_surface_candidate.mojom"
-public_headers = [ "//ui/ozone/public/overlay_surface_candidate.h" ]
-public_deps = [
- "//ui/gfx/geometry/mojom:mojom_traits",
- "//ui/ozone:ozone_base",
-]
-traits_headers =
- [ "//ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h" ]
-type_mappings = [
- "ui.ozone.mojom.OverlaySurfaceCandidate=::ui::OverlaySurfaceCandidate",
- "ui.ozone.mojom.OverlayStatus=::ui::OverlayStatus",
-]
diff --git a/chromium/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h b/chromium/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h
deleted file mode 100644
index 26fb433405c..00000000000
--- a/chromium/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_PUBLIC_MOJOM_OVERLAY_SURFACE_CANDIDATE_MOJOM_TRAITS_H_
-#define UI_OZONE_PUBLIC_MOJOM_OVERLAY_SURFACE_CANDIDATE_MOJOM_TRAITS_H_
-
-#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
-#include "ui/gfx/mojom/buffer_types_mojom_traits.h"
-#include "ui/gfx/mojom/overlay_transform_mojom_traits.h"
-#include "ui/ozone/public/mojom/overlay_surface_candidate.mojom.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
-
-namespace mojo {
-
-template <>
-struct EnumTraits<ui::ozone::mojom::OverlayStatus, ui::OverlayStatus> {
- static ui::ozone::mojom::OverlayStatus ToMojom(ui::OverlayStatus format) {
- switch (format) {
- case ui::OverlayStatus::OVERLAY_STATUS_PENDING:
- return ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_PENDING;
- case ui::OverlayStatus::OVERLAY_STATUS_ABLE:
- return ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_ABLE;
- case ui::OverlayStatus::OVERLAY_STATUS_NOT:
- return ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_NOT;
- }
- NOTREACHED();
- return ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_NOT;
- }
-
- static bool FromMojom(ui::ozone::mojom::OverlayStatus input,
- ui::OverlayStatus* out) {
- switch (input) {
- case ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_PENDING:
- *out = ui::OverlayStatus::OVERLAY_STATUS_PENDING;
- return true;
- case ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_ABLE:
- *out = ui::OverlayStatus::OVERLAY_STATUS_ABLE;
- return true;
- case ui::ozone::mojom::OverlayStatus::OVERLAY_STATUS_NOT:
- *out = ui::OverlayStatus::OVERLAY_STATUS_NOT;
- return true;
- }
- NOTREACHED();
- return false;
- }
-};
-
-template <>
-struct StructTraits<ui::ozone::mojom::OverlaySurfaceCandidateDataView,
- ui::OverlaySurfaceCandidate> {
- static const gfx::OverlayTransform& transform(
- const ui::OverlaySurfaceCandidate& osc) {
- return osc.transform;
- }
-
- static const gfx::BufferFormat& format(
- const ui::OverlaySurfaceCandidate& osc) {
- return osc.format;
- }
-
- static const gfx::Size& buffer_size(const ui::OverlaySurfaceCandidate& osc) {
- return osc.buffer_size;
- }
-
- static const gfx::RectF& display_rect(
- const ui::OverlaySurfaceCandidate& osc) {
- return osc.display_rect;
- }
-
- static const gfx::RectF& crop_rect(const ui::OverlaySurfaceCandidate& osc) {
- return osc.crop_rect;
- }
-
- static const gfx::Rect& clip_rect(const ui::OverlaySurfaceCandidate& osc) {
- return osc.clip_rect;
- }
-
- static bool is_clipped(const ui::OverlaySurfaceCandidate& osc) {
- return osc.is_clipped;
- }
-
- static bool is_opaque(const ui::OverlaySurfaceCandidate& osc) {
- return osc.is_opaque;
- }
-
- static int plane_z_order(const ui::OverlaySurfaceCandidate& osc) {
- return osc.plane_z_order;
- }
-
- static bool overlay_handled(const ui::OverlaySurfaceCandidate& osc) {
- return osc.overlay_handled;
- }
-
- static bool Read(ui::ozone::mojom::OverlaySurfaceCandidateDataView data,
- ui::OverlaySurfaceCandidate* out) {
- out->is_clipped = data.is_clipped();
- out->is_opaque = data.is_opaque();
- out->plane_z_order = data.plane_z_order();
- out->overlay_handled = data.overlay_handled();
- return data.ReadTransform(&out->transform) &&
- data.ReadFormat(&out->format) &&
- data.ReadBufferSize(&out->buffer_size) &&
- data.ReadDisplayRect(&out->display_rect) &&
- data.ReadCropRect(&out->crop_rect) &&
- data.ReadClipRect(&out->clip_rect);
- }
-};
-
-} // namespace mojo
-
-#endif // UI_OZONE_PUBLIC_MOJOM_OVERLAY_SURFACE_CANDIDATE_MOJOM_TRAITS_H_
diff --git a/chromium/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits_unittest.cc b/chromium/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits_unittest.cc
deleted file mode 100644
index 823a4e541e9..00000000000
--- a/chromium/ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits_unittest.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/public/mojom/overlay_surface_candidate_mojom_traits.h"
-
-#include <utility>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/ozone/public/mojom/overlay_surface_candidate.mojom.h"
-#include "ui/ozone/public/overlay_surface_candidate.h"
-
-namespace ui {
-
-TEST(OverlaySurfaceCandidateStructTraitsTest, FieldsEqual) {
- ui::OverlaySurfaceCandidate input;
-
- input.transform = gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
- input.format = gfx::BufferFormat::YUV_420_BIPLANAR;
- input.buffer_size = gfx::Size(6, 7);
- input.display_rect = gfx::RectF(1., 2., 3., 4.);
- input.crop_rect = gfx::RectF(10., 20., 30., 40.);
- input.clip_rect = gfx::Rect(11, 21, 31, 41);
- input.is_clipped = true;
- input.is_opaque = true;
- input.plane_z_order = 42;
- input.overlay_handled = true;
-
- ui::OverlaySurfaceCandidate output;
-
- bool success = ui::ozone::mojom::OverlaySurfaceCandidate::Deserialize(
- ui::ozone::mojom::OverlaySurfaceCandidate::Serialize(&input), &output);
-
- EXPECT_TRUE(success);
-
- EXPECT_EQ(input.transform, output.transform);
- EXPECT_EQ(input.format, output.format);
- EXPECT_EQ(input.buffer_size, output.buffer_size);
- EXPECT_EQ(input.display_rect, output.display_rect);
- EXPECT_EQ(input.crop_rect, output.crop_rect);
- EXPECT_EQ(input.clip_rect, output.clip_rect);
- EXPECT_EQ(input.is_clipped, output.is_clipped);
- EXPECT_EQ(input.is_opaque, output.is_opaque);
- EXPECT_EQ(input.plane_z_order, output.plane_z_order);
- EXPECT_EQ(input.overlay_handled, output.overlay_handled);
-}
-
-TEST(OverlaySurfaceCandidateStructTraitsTest, FalseBools) {
- ui::OverlaySurfaceCandidate input;
-
- input.is_clipped = false;
- input.is_opaque = false;
- input.overlay_handled = false;
-
- ui::OverlaySurfaceCandidate output;
-
- bool success = ui::ozone::mojom::OverlaySurfaceCandidate::Deserialize(
- ui::ozone::mojom::OverlaySurfaceCandidate::Serialize(&input), &output);
-
- EXPECT_TRUE(success);
- EXPECT_EQ(input.is_clipped, output.is_clipped);
- EXPECT_EQ(input.is_opaque, output.is_opaque);
- EXPECT_EQ(input.overlay_handled, output.overlay_handled);
-}
-
-TEST(OverlaySurfaceCandidateStructTraitsTest, OverlayStatus) {
- using OverlayStatusTraits =
- mojo::EnumTraits<ui::ozone::mojom::OverlayStatus, ui::OverlayStatus>;
-
- std::vector<OverlayStatus> tests = {OVERLAY_STATUS_PENDING,
- OVERLAY_STATUS_ABLE, OVERLAY_STATUS_NOT};
-
- for (const OverlayStatus& input : tests) {
- ui::OverlayStatus output;
- bool success = OverlayStatusTraits::FromMojom(
- OverlayStatusTraits::ToMojom(input), &output);
-
- EXPECT_TRUE(success);
- EXPECT_EQ(input, output);
- }
-}
-
-} // namespace ui
diff --git a/chromium/ui/ozone/public/mojom/scenic_gpu_host.mojom b/chromium/ui/ozone/public/mojom/scenic_gpu_host.mojom
index 62189435842..a3de21807f1 100644
--- a/chromium/ui/ozone/public/mojom/scenic_gpu_host.mojom
+++ b/chromium/ui/ozone/public/mojom/scenic_gpu_host.mojom
@@ -8,5 +8,5 @@ module ui.mojom;
interface ScenicGpuHost {
// Attaches the surface View identified by |view_holder_token| to the scene
// graph for |window_id|.
- AttachSurfaceToWindow(int32 window_id, handle view_holder_token);
+ AttachSurfaceToWindow(int32 window_id, handle<platform> view_holder_token);
};
diff --git a/chromium/ui/ozone/public/mojom/typemaps.gni b/chromium/ui/ozone/public/mojom/typemaps.gni
deleted file mode 100644
index beff1f5871c..00000000000
--- a/chromium/ui/ozone/public/mojom/typemaps.gni
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-typemaps = [ "//ui/ozone/public/mojom/overlay_surface_candidate.typemap" ]
diff --git a/chromium/ui/ozone/public/mojom/wayland/BUILD.gn b/chromium/ui/ozone/public/mojom/wayland/BUILD.gn
index 280055d2add..fb7f809ebd4 100644
--- a/chromium/ui/ozone/public/mojom/wayland/BUILD.gn
+++ b/chromium/ui/ozone/public/mojom/wayland/BUILD.gn
@@ -5,9 +5,7 @@
import("//mojo/public/tools/bindings/mojom.gni")
mojom("wayland_mojom") {
- sources = [
- "wayland_buffer_manager.mojom",
- ]
+ sources = [ "wayland_buffer_manager.mojom" ]
public_deps = [
"//mojo/public/mojom/base",
diff --git a/chromium/ui/ozone/public/mojom/wayland/wayland_buffer_manager.mojom b/chromium/ui/ozone/public/mojom/wayland/wayland_buffer_manager.mojom
index 3808188bc84..46d6a84e024 100644
--- a/chromium/ui/ozone/public/mojom/wayland/wayland_buffer_manager.mojom
+++ b/chromium/ui/ozone/public/mojom/wayland/wayland_buffer_manager.mojom
@@ -35,7 +35,7 @@ interface WaylandBufferManagerHost {
// very first CommitBuffer request comes from viz to browser process.
// If the buffer has been committed at least once, it is not possible to
// reassign it to another AcceleratedWidget.
- CreateDmabufBasedBuffer(handle dmabuf_fd,
+ CreateDmabufBasedBuffer(handle<platform> dmabuf_fd,
gfx.mojom.Size size,
array<uint32> strides,
array<uint32> offsets,
@@ -52,7 +52,7 @@ interface WaylandBufferManagerHost {
// very first CommitBuffer request comes from viz to browser process. If
// the buffer has been committed at least once, it is not possible to
// reassign it to another AcceleratedWidget.
- CreateShmBasedBuffer(handle shm_fd,
+ CreateShmBasedBuffer(handle<platform> shm_fd,
uint64 length,
gfx.mojom.Size size,
uint32 buffer_id);
diff --git a/chromium/ui/ozone/public/overlay_surface_candidate.cc b/chromium/ui/ozone/public/overlay_surface_candidate.cc
index 40b99ff9346..9a9572ea220 100644
--- a/chromium/ui/ozone/public/overlay_surface_candidate.cc
+++ b/chromium/ui/ozone/public/overlay_surface_candidate.cc
@@ -28,9 +28,10 @@ bool OverlaySurfaceCandidate::operator<(
gfx::Rect rrect = gfx::ToNearestRect(param.display_rect);
return std::tie(plane_z_order, format, lrect, lwidth, lheight, transform,
- crop_rect, is_opaque) <
+ crop_rect, is_opaque, native_pixmap_unique_id) <
std::tie(param.plane_z_order, param.format, rrect, rwidth, rheight,
- param.transform, param.crop_rect, param.is_opaque);
+ param.transform, param.crop_rect, param.is_opaque,
+ param.native_pixmap_unique_id);
}
} // namespace ui
diff --git a/chromium/ui/ozone/public/overlay_surface_candidate.h b/chromium/ui/ozone/public/overlay_surface_candidate.h
index ab0f1b6031f..ebd82e96706 100644
--- a/chromium/ui/ozone/public/overlay_surface_candidate.h
+++ b/chromium/ui/ozone/public/overlay_surface_candidate.h
@@ -12,6 +12,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/native_pixmap.h"
#include "ui/gfx/overlay_transform.h"
namespace ui {
@@ -30,8 +31,8 @@ class COMPONENT_EXPORT(OZONE_BASE) OverlaySurfaceCandidate {
~OverlaySurfaceCandidate();
OverlaySurfaceCandidate& operator=(const OverlaySurfaceCandidate& other);
- // Note that |clip_rect|, |is_clipped| and |overlay_handled| are
- // *not* used as part of the comparison.
+ // Note that |clip_rect|, |is_clipped|, |overlay_handled| and |native_pixmap|
+ // are *not* used as part of the comparison.
bool operator<(const OverlaySurfaceCandidate& other) const;
// Transformation to apply to layer during composition.
@@ -55,6 +56,14 @@ class COMPONENT_EXPORT(OZONE_BASE) OverlaySurfaceCandidate {
bool is_clipped = false;
// If the quad doesn't require blending.
bool is_opaque = false;
+ // Optionally contains a pointer to the NativePixmap corresponding to this
+ // candidate.
+ scoped_refptr<gfx::NativePixmap> native_pixmap = nullptr;
+ // A unique ID corresponding to |native_pixmap|. The ID is not reused even if
+ // |native_pixmap| is destroyed. Zero if |native_pixmap| is null.
+ // TODO(samans): This will not be necessary once Ozone/DRM not longer uses a
+ // cache for overlay testing. https://crbug.com/1034559
+ uint32_t native_pixmap_unique_id = 0;
// To be modified by the implementer if this candidate can go into
// an overlay.
bool overlay_handled = false;
diff --git a/chromium/ui/ozone/public/ozone_platform.h b/chromium/ui/ozone/public/ozone_platform.h
index 80245695a32..c1d82b8ba5c 100644
--- a/chromium/ui/ozone/public/ozone_platform.h
+++ b/chromium/ui/ozone/public/ozone_platform.h
@@ -14,6 +14,7 @@
#include "base/message_loop/message_pump_type.h"
#include "mojo/public/cpp/bindings/binder_map.h"
#include "ui/gfx/buffer_types.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/platform_window/platform_window.h"
#include "ui/platform_window/platform_window_delegate.h"
@@ -77,15 +78,6 @@ class COMPONENT_EXPORT(OZONE) OzonePlatform {
// regardless of this param.
// TODO(crbug.com/806092): Remove after legacy IPC-based Ozone is removed.
bool using_mojo = false;
-
- // Setting this to true indicates the display compositor will run in the GPU
- // process (as part of the viz service). Note this param is currently only
- // checked in Ozone DRM for overlay support. Other Ozone platforms either
- // don't need to change anything or assume that VizDisplayCompositor is
- // always enabled.
- // TODO(crbug.com/936425): Remove after VizDisplayCompositor feature
- // launches.
- bool viz_display_compositor = false;
};
// Struct used to indicate platform properties.
@@ -158,7 +150,8 @@ class COMPONENT_EXPORT(OZONE) OzonePlatform {
virtual std::unique_ptr<PlatformScreen> CreateScreen() = 0;
virtual PlatformClipboard* GetPlatformClipboard();
virtual std::unique_ptr<InputMethod> CreateInputMethod(
- internal::InputMethodDelegate* delegate) = 0;
+ internal::InputMethodDelegate* delegate,
+ gfx::AcceleratedWidget widget) = 0;
// Returns true if the specified buffer format is supported.
virtual bool IsNativePixmapConfigSupported(gfx::BufferFormat format,
diff --git a/chromium/ui/ozone/public/platform_screen.cc b/chromium/ui/ozone/public/platform_screen.cc
new file mode 100644
index 00000000000..af4dc57fcd1
--- /dev/null
+++ b/chromium/ui/ozone/public/platform_screen.cc
@@ -0,0 +1,17 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/public/platform_screen.h"
+
+namespace ui {
+
+PlatformScreen::PlatformScreen() = default;
+PlatformScreen::~PlatformScreen() = default;
+
+std::string PlatformScreen::GetCurrentWorkspace() {
+ NOTIMPLEMENTED_LOG_ONCE();
+ return {};
+}
+
+} // namespace ui
diff --git a/chromium/ui/ozone/public/platform_screen.h b/chromium/ui/ozone/public/platform_screen.h
index d98bed8e901..de464218855 100644
--- a/chromium/ui/ozone/public/platform_screen.h
+++ b/chromium/ui/ozone/public/platform_screen.h
@@ -5,6 +5,7 @@
#ifndef UI_OZONE_PUBLIC_PLATFORM_SCREEN_H_
#define UI_OZONE_PUBLIC_PLATFORM_SCREEN_H_
+#include "base/component_export.h"
#include "ui/gfx/native_widget_types.h"
namespace display {
@@ -22,6 +23,8 @@ namespace ui {
// PlatformScreen is an abstract base class for an interface to an Ozone
// platform's functionality exposed to Chrome via display::Screen.
//
+// Additionally, may notify DisplayObservers with global workspace changes.
+//
// Recall that in Chrome, a |Screen| is the union of all attached |Display|
// instances. The |Screen|'s coordinate system is in DIP pixels (so that
// it can reasonably support |Display|s of differing pixel densities.) The
@@ -29,10 +32,10 @@ namespace ui {
// |Screen|. Coordinates increase down and to the right.
//
// TODO(rjkroege): Add ascii art?
-class PlatformScreen {
+class COMPONENT_EXPORT(OZONE_BASE) PlatformScreen {
public:
- PlatformScreen() = default;
- virtual ~PlatformScreen() = default;
+ PlatformScreen();
+ virtual ~PlatformScreen();
// Provide a |display:;Display| for each physical display available to Chrome.
virtual const std::vector<display::Display>& GetAllDisplays() const = 0;
@@ -68,6 +71,10 @@ class PlatformScreen {
virtual void AddObserver(display::DisplayObserver* observer) = 0;
virtual void RemoveObserver(display::DisplayObserver* observer) = 0;
+ // Returns currently used workspace. If a platform does not support this, the
+ // empty string is returned.
+ virtual std::string GetCurrentWorkspace();
+
private:
DISALLOW_COPY_AND_ASSIGN(PlatformScreen);
};
diff --git a/chromium/ui/ozone/public/surface_factory_ozone.cc b/chromium/ui/ozone/public/surface_factory_ozone.cc
index 3cf24e6b42a..ec4751ef186 100644
--- a/chromium/ui/ozone/public/surface_factory_ozone.cc
+++ b/chromium/ui/ozone/public/surface_factory_ozone.cc
@@ -67,7 +67,7 @@ std::unique_ptr<OverlaySurface> SurfaceFactoryOzone::CreateOverlaySurface(
std::unique_ptr<SurfaceOzoneCanvas> SurfaceFactoryOzone::CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner) {
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
return nullptr;
}
@@ -76,7 +76,8 @@ scoped_refptr<gfx::NativePixmap> SurfaceFactoryOzone::CreateNativePixmap(
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage) {
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size) {
return nullptr;
}
diff --git a/chromium/ui/ozone/public/surface_factory_ozone.h b/chromium/ui/ozone/public/surface_factory_ozone.h
index a721f994b44..fde22b2d998 100644
--- a/chromium/ui/ozone/public/surface_factory_ozone.h
+++ b/chromium/ui/ozone/public/surface_factory_ozone.h
@@ -115,18 +115,31 @@ class COMPONENT_EXPORT(OZONE_BASE) SurfaceFactoryOzone {
// Browser Process using only the handle contained in gfx::AcceleratedWidget.
virtual std::unique_ptr<SurfaceOzoneCanvas> CreateCanvasForWidget(
gfx::AcceleratedWidget widget,
- base::TaskRunner* task_runner);
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
// Create a single native buffer to be used for overlay planes or zero copy
// for |widget| representing a particular display controller or default
- // display controller for kNullAcceleratedWidget.
- // It can be called on any thread.
+ // display controller for kNullAcceleratedWidget. |size| corresponds to the
+ // dimensions used to allocate the buffer. |framebuffer_size| is used to
+ // create a framebuffer for the allocated buffer when the usage requires one.
+ // If |framebuffer_size| is not provided, |size| is used instead. In the
+ // typical case |framebuffer_size| represents a 'visible size', i.e., a buffer
+ // of size |size| may actually contain visible data only in the subregion of
+ // size |framebuffer_size|. In more complex cases, it's possible that the
+ // buffer has a visible rectangle whose origin is not at (0, 0). In this case,
+ // |framebuffer_size| would also include some of the non-visible area. For
+ // example, suppose we need to allocate a buffer of size 100x100 for a
+ // hardware decoder, but the visible rectangle is (10, 10, 80x80). In this
+ // case, |size| would be 100x100 while |framebuffer_size| would be 90x90. If
+ // |framebuffer_size| is not contained by |size|, this method returns nullptr.
+ // This method can be called on any thread.
virtual scoped_refptr<gfx::NativePixmap> CreateNativePixmap(
gfx::AcceleratedWidget widget,
VkDevice vk_device,
gfx::Size size,
gfx::BufferFormat format,
- gfx::BufferUsage usage);
+ gfx::BufferUsage usage,
+ base::Optional<gfx::Size> framebuffer_size = base::nullopt);
// Similar to CreateNativePixmap, but returns the result asynchronously.
using NativePixmapCallback =
diff --git a/chromium/ui/ozone/public/surface_ozone_canvas.h b/chromium/ui/ozone/public/surface_ozone_canvas.h
index c7269ecb39c..7e4143b16e7 100644
--- a/chromium/ui/ozone/public/surface_ozone_canvas.h
+++ b/chromium/ui/ozone/public/surface_ozone_canvas.h
@@ -11,7 +11,7 @@
#include "base/component_export.h"
#include "third_party/skia/include/core/SkRefCnt.h"
-class SkSurface;
+class SkCanvas;
namespace gfx {
class Rect;
@@ -29,8 +29,11 @@ class COMPONENT_EXPORT(OZONE_BASE) SurfaceOzoneCanvas {
public:
virtual ~SurfaceOzoneCanvas();
- // Returns an SkSurface for drawing on the window.
- virtual sk_sp<SkSurface> GetSurface() = 0;
+ // Returns an SkCanvas for drawing on the window. The SurfaceOzoneCanvas keeps
+ // the SkCanvas alive until the client finishes writing contents and calls
+ // PresentCanvas. Additionally, the SkCanvas becomes invalid after
+ // ResizeCanvas is called. See comment at ResizeCanvas.
+ virtual SkCanvas* GetCanvas() = 0;
// Attempts to resize the canvas to match the viewport size. After
// resizing, the compositor must call GetSurface() to get the next
diff --git a/chromium/ui/ozone/testhelpers/BUILD.gn b/chromium/ui/ozone/testhelpers/BUILD.gn
index 3e4412145f4..07b720d9b4d 100644
--- a/chromium/ui/ozone/testhelpers/BUILD.gn
+++ b/chromium/ui/ozone/testhelpers/BUILD.gn
@@ -4,9 +4,7 @@
static_library("mock_gesture_properties_service") {
testonly = true
- sources = [
- "mock_gesture_properties_service.h",
- ]
+ sources = [ "mock_gesture_properties_service.h" ]
public_deps = [
"//testing/gmock",
"//third_party/googletest:gmock",