diff options
Diffstat (limited to 'chromium/ui/ozone/platform/wayland/gpu')
12 files changed, 126 insertions, 317 deletions
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 1b15b1c27f7..827cd1c9b7d 100644 --- a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc +++ b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc @@ -11,6 +11,8 @@ #include "base/task/thread_pool.h" #include "base/trace_event/trace_event.h" #include "ui/gfx/gpu_fence.h" +#include "ui/gfx/gpu_fence_handle.h" +#include "ui/gl/gl_bindings.h" #include "ui/ozone/common/egl_util.h" #include "ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h" #include "ui/ozone/public/mojom/wayland/wayland_overlay_config.mojom.h" @@ -19,12 +21,6 @@ namespace ui { namespace { -void WaitForEGLFence(EGLDisplay display, EGLSyncKHR fence) { - eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, - EGL_FOREVER_KHR); - eglDestroySyncKHR(display, fence); -} - void WaitForGpuFences(std::vector<std::unique_ptr<gfx::GpuFence>> fences) { for (auto& fence : fences) fence->Wait(); @@ -60,9 +56,9 @@ bool GbmSurfacelessWayland::ScheduleOverlayPlane( const gfx::RectF& crop_rect, bool enable_blend, std::unique_ptr<gfx::GpuFence> gpu_fence) { - unsubmitted_frames_.back()->overlays.push_back( - gl::GLSurfaceOverlay(z_order, transform, image, bounds_rect, crop_rect, - enable_blend, std::move(gpu_fence))); + unsubmitted_frames_.back()->overlays.emplace_back( + z_order, transform, image, bounds_rect, crop_rect, enable_blend, + std::move(gpu_fence)); return true; } @@ -115,31 +111,23 @@ void GbmSurfacelessWayland::SwapBuffersAsync( unsubmitted_frames_.push_back(std::make_unique<PendingFrame>()); - if (!use_egl_fence_sync_ || !frame->schedule_planes_succeeded) { + // If Wayland server supports linux_explicit_synchronization_protocol, fences + // should be shipped with buffers. Otherwise, we will wait for fences. + if (buffer_manager_->supports_acquire_fence() || !use_egl_fence_sync_ || + !frame->schedule_planes_succeeded) { frame->ready = true; MaybeSubmitFrames(); return; } + base::OnceClosure fence_wait_task; std::vector<std::unique_ptr<gfx::GpuFence>> fences; - // Uset in-fences provided in the overlays. If there are none, we insert our - // own fence and wait. for (auto& plane : frame->planes) { if (plane.second.gpu_fence) fences.push_back(std::move(plane.second.gpu_fence)); } - base::OnceClosure fence_wait_task; - if (!fences.empty()) { - fence_wait_task = base::BindOnce(&WaitForGpuFences, std::move(fences)); - } else { - // TODO(fangzhoug): the following should be replaced by a per surface flush - // as it gets implemented in GL drivers. - EGLSyncKHR fence = InsertFence(has_implicit_external_sync_); - CHECK_NE(fence, EGL_NO_SYNC_KHR) << "eglCreateSyncKHR failed"; - - fence_wait_task = base::BindOnce(&WaitForEGLFence, GetDisplay(), fence); - } + fence_wait_task = base::BindOnce(&WaitForGpuFences, std::move(fences)); base::OnceClosure fence_retired_callback = base::BindOnce( &GbmSurfacelessWayland::FenceRetired, weak_factory_.GetWeakPtr(), frame); @@ -190,6 +178,14 @@ void GbmSurfacelessWayland::SetRelyOnImplicitSync() { use_egl_fence_sync_ = false; } +bool GbmSurfacelessWayland::SupportsPlaneGpuFences() const { + return true; +} + +bool GbmSurfacelessWayland::SupportsOverridePlatformSize() const { + return true; +} + gfx::SurfaceOrigin GbmSurfacelessWayland::GetOrigin() const { // GbmSurfacelessWayland's y-axis is flipped compare to GL - (0,0) is at top // left corner. @@ -200,9 +196,9 @@ GbmSurfacelessWayland::~GbmSurfacelessWayland() { buffer_manager_->UnregisterSurface(widget_); } -GbmSurfacelessWayland::PendingFrame::PendingFrame() {} +GbmSurfacelessWayland::PendingFrame::PendingFrame() = default; -GbmSurfacelessWayland::PendingFrame::~PendingFrame() {} +GbmSurfacelessWayland::PendingFrame::~PendingFrame() = default; void GbmSurfacelessWayland::PendingFrame::ScheduleOverlayPlanes( gfx::AcceleratedWidget widget) { @@ -238,15 +234,19 @@ void GbmSurfacelessWayland::MaybeSubmitFrames() { } std::vector<ui::ozone::mojom::WaylandOverlayConfigPtr> overlay_configs; - for (const auto& plane : submitted_frame->planes) { + for (auto& plane : submitted_frame->planes) { overlay_configs.push_back( ui::ozone::mojom::WaylandOverlayConfig::From(plane.second)); overlay_configs.back()->buffer_id = plane.first; - if (plane.second.z_order == 0) { + if (plane.second.z_order == 0) overlay_configs.back()->damage_region = submitted_frame->damage_region_; - submitted_frame->buffer_id = plane.first; - } +#if DCHECK_IS_ON() + if (plane.second.z_order == INT32_MIN) + background_buffer_id_ = plane.first; +#endif + plane.second.gpu_fence.reset(); } + buffer_manager_->CommitOverlays(widget_, std::move(overlay_configs)); submitted_frames_.push_back(std::move(submitted_frame)); } @@ -273,7 +273,7 @@ void GbmSurfacelessWayland::OnSubmission(BufferId buffer_id, const gfx::SwapResult& swap_result) { // submitted_frames_ may temporarily have more than one buffer in it if // buffers are released out of order by the Wayland server. - DCHECK(!submitted_frames_.empty()); + DCHECK(!submitted_frames_.empty() || background_buffer_id_ == buffer_id); size_t erased = 0; for (auto& submitted_frame : submitted_frames_) { @@ -320,7 +320,8 @@ void GbmSurfacelessWayland::OnSubmission(BufferId buffer_id, void GbmSurfacelessWayland::OnPresentation( BufferId buffer_id, const gfx::PresentationFeedback& feedback) { - DCHECK(!submitted_frames_.empty() || !pending_presentation_frames_.empty()); + DCHECK(!submitted_frames_.empty() || !pending_presentation_frames_.empty() || + background_buffer_id_ == buffer_id); size_t erased = 0; for (auto& frame : pending_presentation_frames_) { 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 910b9a7056e..8be5c32391f 100644 --- a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h +++ b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h @@ -60,6 +60,8 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL, PresentationCallback presentation_callback) override; EGLConfig GetConfig() override; void SetRelyOnImplicitSync() override; + bool SupportsPlaneGpuFences() const override; + bool SupportsOverridePlatformSize() const override; gfx::SurfaceOrigin GetOrigin() const override; private: @@ -88,9 +90,6 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL, bool ready = false; - // The id of the buffer, which represents this frame. - BufferId buffer_id = 0; - // A region of the updated content in a corresponding frame. It's used to // advice Wayland which part of a buffer is going to be updated. Passing {0, // 0, 0, 0} results in a whole buffer update on the Wayland compositor side. @@ -120,6 +119,12 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL, WaylandBufferManagerGpu* const buffer_manager_; + // |background_buffer_id| is sent to WaylandBufferManagerHost once per + // background_buffer allocation. However WaylandBufferManagerHost may commit + // this buffer more often b/c buffers needs to be re-attached when wl_surface + // is reshown. + BufferId background_buffer_id_; + // The native surface. Deleting this is allowed to free the EGLNativeWindow. gfx::AcceleratedWidget widget_; std::vector<std::unique_ptr<PendingFrame>> unsubmitted_frames_; 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 index 195d061926c..5383fb8209c 100644 --- 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 @@ -116,8 +116,9 @@ void GLSurfaceEglReadbackWayland::SwapBuffersAsync( CHECK(next_buffer->shm_mapping_.memory()); ReadPixels(next_buffer->shm_mapping_.memory()); - buffer_manager_->CommitBuffer(widget_, next_buffer->buffer_id_, - {{0, 0}, GetSize()}); + const auto bounds = gfx::Rect(GetSize()); + buffer_manager_->CommitBuffer(widget_, next_buffer->buffer_id_, bounds, + bounds); } gfx::SurfaceOrigin GLSurfaceEglReadbackWayland::GetOrigin() const { 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 e5cdaf12895..b430a061c26 100644 --- a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc +++ b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc @@ -46,21 +46,21 @@ bool GLSurfaceWayland::Resize(const gfx::Size& size, EGLConfig GLSurfaceWayland::GetConfig() { if (!config_) { - GLint config_attribs[] = {EGL_BUFFER_SIZE, - 32, - EGL_ALPHA_SIZE, - 8, - EGL_BLUE_SIZE, - 8, - EGL_GREEN_SIZE, - 8, - EGL_RED_SIZE, - 8, - EGL_RENDERABLE_TYPE, - EGL_OPENGL_ES2_BIT, - EGL_SURFACE_TYPE, - EGL_WINDOW_BIT, - EGL_NONE}; + EGLint config_attribs[] = {EGL_BUFFER_SIZE, + 32, + EGL_ALPHA_SIZE, + 8, + EGL_BLUE_SIZE, + 8, + EGL_GREEN_SIZE, + 8, + EGL_RED_SIZE, + 8, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES2_BIT, + EGL_SURFACE_TYPE, + EGL_WINDOW_BIT, + EGL_NONE}; config_ = ChooseEGLConfig(GetDisplay(), config_attribs); } return config_; diff --git a/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.cc b/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.cc index 3a2be4275ef..1a3335da4e2 100644 --- a/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.cc +++ b/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.cc @@ -34,8 +34,8 @@ bool InitializeVulkanFunctionPointers( } // namespace -VulkanImplementationWayland::VulkanImplementationWayland() - : gpu::VulkanImplementation(false /* use_swiftshader */) {} +VulkanImplementationWayland::VulkanImplementationWayland(bool use_swiftshader) + : gpu::VulkanImplementation(use_swiftshader) {} VulkanImplementationWayland::~VulkanImplementationWayland() {} @@ -47,14 +47,20 @@ bool VulkanImplementationWayland::InitializeVulkanInstance(bool using_surface) { auto* vulkan_function_pointers = gpu::GetVulkanFunctionPointers(); - base::FilePath path("libvulkan.so.1"); + base::FilePath path; + if (use_swiftshader()) { + if (!base::PathService::Get(base::DIR_MODULE, &path)) + return false; + + path = path.Append("libvk_swiftshader.so"); + } else { + path = base::FilePath("libvulkan.so.1"); + } if (!InitializeVulkanFunctionPointers(path, vulkan_function_pointers)) return false; - if (!vulkan_instance_.Initialize(required_extensions, {})) - return false; - return true; + return vulkan_instance_.Initialize(required_extensions, {}); } gpu::VulkanInstance* VulkanImplementationWayland::GetVulkanInstance() { @@ -77,13 +83,16 @@ bool VulkanImplementationWayland::GetPhysicalDevicePresentationSupport( std::vector<const char*> VulkanImplementationWayland::GetRequiredDeviceExtensions() { - return { - VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME, + std::vector<const char*> result{ VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME, }; + + if (!use_swiftshader()) + result.push_back(VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME); + return result; } std::vector<const char*> diff --git a/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.h b/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.h index e504ac313ef..5acd1e07945 100644 --- a/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.h +++ b/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.h @@ -14,7 +14,7 @@ namespace ui { class VulkanImplementationWayland : public gpu::VulkanImplementation { public: - VulkanImplementationWayland(); + explicit VulkanImplementationWayland(bool use_swiftshader = false); ~VulkanImplementationWayland() override; VulkanImplementationWayland(const VulkanImplementationWayland&) = delete; @@ -56,4 +56,4 @@ class VulkanImplementationWayland : public gpu::VulkanImplementation { } // namespace ui -#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_VULKAN_IMPLEMENTATION_WAYLAND_H_
\ No newline at end of file +#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_VULKAN_IMPLEMENTATION_WAYLAND_H_ 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 5c14a1c918f..da7ce23565e 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 @@ -44,7 +44,8 @@ void WaylandBufferManagerGpu::Initialize( mojo::PendingRemote<ozone::mojom::WaylandBufferManagerHost> remote_host, const base::flat_map<::gfx::BufferFormat, std::vector<uint64_t>>& buffer_formats_with_modifiers, - bool supports_dma_buf) { + bool supports_dma_buf, + bool supports_acquire_fence) { DCHECK(supported_buffer_formats_with_modifiers_.empty()); supported_buffer_formats_with_modifiers_ = buffer_formats_with_modifiers; @@ -52,6 +53,7 @@ void WaylandBufferManagerGpu::Initialize( if (!supports_dma_buf) set_gbm_device(nullptr); #endif + supports_acquire_fence_ = supports_acquire_fence; BindHostInterface(std::move(remote_host)); @@ -182,18 +184,16 @@ void WaylandBufferManagerGpu::CreateShmBasedBuffer( void WaylandBufferManagerGpu::CommitBuffer(gfx::AcceleratedWidget widget, uint32_t buffer_id, + const gfx::Rect& bounds_rect, const gfx::Rect& damage_region) { - if (!remote_host_) { - LOG(ERROR) << "Interface is not bound. Can't request " - "WaylandBufferManagerHost to create/commit/destroy buffers."; - return; - } - - // Do the mojo call on the IO child thread. - io_thread_runner_->PostTask( - FROM_HERE, - base::BindOnce(&WaylandBufferManagerGpu::CommitBufferInternal, - base::Unretained(this), widget, buffer_id, damage_region)); + std::vector<ui::ozone::mojom::WaylandOverlayConfigPtr> overlay_configs; + // This surface only commits one buffer per frame, use INT32_MIN to attach + // the buffer to root_surface of wayland window. + overlay_configs.push_back(ui::ozone::mojom::WaylandOverlayConfig::New( + INT32_MIN, gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE, buffer_id, + bounds_rect, gfx::RectF(), damage_region, false, gfx::GpuFenceHandle())); + + CommitOverlays(widget, std::move(overlay_configs)); } void WaylandBufferManagerGpu::CommitOverlays( @@ -271,14 +271,6 @@ void WaylandBufferManagerGpu::CreateShmBasedBufferInternal( length, size, buffer_id); } -void WaylandBufferManagerGpu::CommitBufferInternal( - gfx::AcceleratedWidget widget, - uint32_t buffer_id, - const gfx::Rect& damage_region) { - DCHECK(io_thread_runner_->BelongsToCurrentThread()); - remote_host_->CommitBuffer(widget, buffer_id, damage_region); -} - void WaylandBufferManagerGpu::CommitOverlaysInternal( gfx::AcceleratedWidget widget, std::vector<ozone::mojom::WaylandOverlayConfigPtr> overlays) { 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 1f451202652..8123ade0306 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 @@ -26,7 +26,6 @@ namespace gfx { enum class SwapResult; -class Rect; } // namespace gfx namespace ui { @@ -51,7 +50,8 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu { mojo::PendingRemote<ozone::mojom::WaylandBufferManagerHost> remote_host, const base::flat_map<::gfx::BufferFormat, std::vector<uint64_t>>& buffer_formats_with_modifiers, - bool supports_dma_buf) override; + bool supports_dma_buf, + bool supports_acquire_fence) override; // These two calls get the surface, which backs the |widget| and notifies it // about the submission and the presentation. After the surface receives the @@ -103,10 +103,13 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu { // logic as well. This call must not be done twice for the same |widget| until // the OnSubmission is called (which actually means the client can continue // sending buffer swap requests). + // + // CommitBuffer() calls CommitOverlays() to commit only a primary plane + // buffer. void CommitBuffer(gfx::AcceleratedWidget widget, uint32_t buffer_id, + const gfx::Rect& bounds_rect, const gfx::Rect& damage_region); - // Send overlay configurations for a frame to a WaylandWindow identified by // |widget|. void CommitOverlays( @@ -124,6 +127,8 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu { } #endif + bool supports_acquire_fence() const { return supports_acquire_fence_; } + // Adds a WaylandBufferManagerGpu binding. void AddBindingWaylandBufferManagerGpu( mojo::PendingReceiver<ozone::mojom::WaylandBufferManagerGpu> receiver); @@ -148,9 +153,6 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu { size_t length, gfx::Size size, uint32_t buffer_id); - void CommitBufferInternal(gfx::AcceleratedWidget widget, - uint32_t buffer_id, - const gfx::Rect& damage_region); void CommitOverlaysInternal( gfx::AcceleratedWidget widget, std::vector<ozone::mojom::WaylandOverlayConfigPtr> overlays); @@ -178,6 +180,8 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu { // A DRM render node based gbm device. std::unique_ptr<GbmDevice> gbm_device_; #endif + // Whether Wayland server allows buffer submission with acquire fence. + bool supports_acquire_fence_ = false; mojo::Receiver<ozone::mojom::WaylandBufferManagerGpu> receiver_{this}; 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 deb43b013e4..bb7029b7d29 100644 --- a/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc +++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc @@ -58,6 +58,7 @@ class WaylandCanvasSurface::SharedMemoryBuffer { // based wl_buffer, which can be attached to a surface and have its contents // shown on a screen. bool Initialize(const gfx::Size& size) { + size_ = size; base::CheckedNumeric<size_t> checked_length(size.width()); checked_length *= size.height(); checked_length *= 4; @@ -92,7 +93,8 @@ class WaylandCanvasSurface::SharedMemoryBuffer { } void CommitBuffer(const gfx::Rect& damage) { - buffer_manager_->CommitBuffer(widget_, buffer_id_, damage); + buffer_manager_->CommitBuffer(widget_, buffer_id_, gfx::Rect(size_), + damage); } void OnUse() { @@ -134,6 +136,9 @@ class WaylandCanvasSurface::SharedMemoryBuffer { } private: + // The size of the buffer. + gfx::Size size_; + // The id of the buffer this surface is backed. const uint32_t buffer_id_; 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 0f20a7c0c39..18f555b2076 100644 --- a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc +++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc @@ -164,9 +164,10 @@ GLOzone* WaylandSurfaceFactory::GetGLOzone( #if BUILDFLAG(ENABLE_VULKAN) std::unique_ptr<gpu::VulkanImplementation> WaylandSurfaceFactory::CreateVulkanImplementation( + bool use_swiftshader, bool allow_protected_memory, bool enforce_protected_memory) { - return std::make_unique<VulkanImplementationWayland>(); + return std::make_unique<VulkanImplementationWayland>(use_swiftshader); } #endif 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 1de11ed0104..18a0319c1d9 100644 --- a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h +++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h @@ -31,6 +31,7 @@ class WaylandSurfaceFactory : public SurfaceFactoryOzone { GLOzone* GetGLOzone(gl::GLImplementation implementation) override; #if BUILDFLAG(ENABLE_VULKAN) std::unique_ptr<gpu::VulkanImplementation> CreateVulkanImplementation( + bool use_swiftshader, bool allow_protected_memory, bool enforce_protected_memory) override; #endif 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 cc71dc65c2b..310d4a9be16 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 @@ -178,7 +178,7 @@ class WaylandSurfaceFactoryTest : public WaylandTest { WaylandTest::SetUp(); auto manager_ptr = connection_->buffer_manager_host()->BindInterface(); - buffer_manager_gpu_->Initialize(std::move(manager_ptr), {}, false); + buffer_manager_gpu_->Initialize(std::move(manager_ptr), {}, false, false); // Wait until initialization and mojo calls go through. base::RunLoop().RunUntilIdle(); @@ -204,221 +204,10 @@ class WaylandSurfaceFactoryTest : public WaylandTest { }; 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>( - window_->root_surface()->GetSurfaceId()); - - 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( - INT32_MIN, gfx::OverlayTransform::OVERLAY_TRANSFORM_FLIP_VERTICAL, - gl_image.get(), window_->GetBounds(), {}, false, nullptr); - - std::vector<scoped_refptr<FakeGLImageNativePixmap>> gl_images; - gl_images.push_back(gl_image); - - // 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_images), - 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->ReleaseBuffer(mock_surface->prev_attached_buffer()); - - 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->ReleaseBuffer(mock_surface->prev_attached_buffer()); - - 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, GbmSurfacelessWaylandCommitOverlaysCallbacksTest) { - // GbmSurfacelessWaylandCheckOrderOfCallbacksTest tests with one buffer per - // frame. This tests multiple buffers per-frame and order of - // SwapCompletionCallbacks. Even when all OnSubmission from later frames are - // called, their SwapCompletionCallbacks should not run until previous frames' + // This tests multiple buffers per-frame and order of SwapCompletionCallbacks. + // Even when all OnSubmission from later frames are called, their + // SwapCompletionCallbacks should not run until previous frames' // SwapCompletionCallbacks run. gl::SetGLImplementation(gl::kGLImplementationEGLGLES2); @@ -493,10 +282,10 @@ TEST_P(WaylandSurfaceFactoryTest, // Also, we expect only one buffer to be committed. EXPECT_CALL(*mock_primary_surface, Attach(_, _, _)).Times(1); - EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(0); + EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(1); EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(1); EXPECT_CALL(*mock_primary_surface, Commit()).Times(1); - EXPECT_CALL(*root_surface, Frame(_)).Times(1); + EXPECT_CALL(*root_surface, Frame(_)).Times(0); EXPECT_CALL(*root_surface, Commit()).Times(1); Sync(); @@ -553,15 +342,15 @@ TEST_P(WaylandSurfaceFactoryTest, // Expect one buffer to be committed. EXPECT_CALL(*mock_primary_surface, Attach(_, _, _)).Times(1); - EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(0); + EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(1); EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(1); EXPECT_CALL(*mock_primary_surface, Commit()).Times(1); - EXPECT_CALL(*root_surface, Frame(_)).Times(1); + EXPECT_CALL(*root_surface, Frame(_)).Times(0); EXPECT_CALL(*root_surface, Commit()).Times(1); // Send the frame callback so that pending buffer for swap id=1u is processed // and swapped. - root_surface->SendFrameCallback(); + mock_primary_surface->SendFrameCallback(); Sync(); @@ -620,12 +409,12 @@ TEST_P(WaylandSurfaceFactoryTest, EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(0); EXPECT_CALL(*mock_primary_surface, Commit()).Times(0); // Expect root surface to be committed. - EXPECT_CALL(*root_surface, Frame(_)).Times(1); + EXPECT_CALL(*root_surface, Frame(_)).Times(0); EXPECT_CALL(*root_surface, Commit()).Times(1); // Send the frame callback so that pending buffer for swap id=2u is processed // and swapped. - root_surface->SendFrameCallback(); + mock_primary_surface->SendFrameCallback(); Sync(); @@ -754,10 +543,10 @@ TEST_P(WaylandSurfaceFactoryTest, // Also, we expect primary buffer to be committed. EXPECT_CALL(*mock_primary_surface, Attach(_, _, _)).Times(1); - EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(0); + EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(1); EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(1); EXPECT_CALL(*mock_primary_surface, Commit()).Times(1); - EXPECT_CALL(*root_surface, Frame(_)).Times(1); + EXPECT_CALL(*root_surface, Frame(_)).Times(0); EXPECT_CALL(*root_surface, Commit()).Times(1); Sync(); @@ -829,23 +618,24 @@ TEST_P(WaylandSurfaceFactoryTest, // Expect primary buffer to be committed. EXPECT_CALL(*mock_primary_surface, Attach(_, _, _)).Times(1); - EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(0); + EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(1); EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(1); EXPECT_CALL(*mock_primary_surface, Commit()).Times(1); // Expect overlay buffer to be committed. EXPECT_CALL(*mock_overlay_surface, Attach(_, _, _)).Times(1); - EXPECT_CALL(*mock_overlay_surface, Frame(_)).Times(0); + EXPECT_CALL(*mock_overlay_surface, Frame(_)).Times(1); EXPECT_CALL(*mock_overlay_surface, DamageBuffer(_, _, _, _)).Times(1); EXPECT_CALL(*mock_overlay_surface, Commit()).Times(1); // Expect root surface to be committed without buffer. - EXPECT_CALL(*root_surface, Frame(_)).Times(1); + EXPECT_CALL(*root_surface, Frame(_)).Times(0); EXPECT_CALL(*root_surface, Commit()).Times(1); // Send the frame callback so that pending buffer for swap id=1u is processed // and swapped. - root_surface->SendFrameCallback(); + mock_overlay_surface->SendFrameCallback(); + mock_primary_surface->SendFrameCallback(); Sync(); |