diff --git a/src/server/compositor/basic_screen_shooter.cpp b/src/server/compositor/basic_screen_shooter.cpp index 4353648b9a6..570c75d69c7 100644 --- a/src/server/compositor/basic_screen_shooter.cpp +++ b/src/server/compositor/basic_screen_shooter.cpp @@ -217,13 +217,16 @@ auto mc::BasicScreenShooter::Self::renderer_for_buffer(std::shared_ptr> const& providers) + std::span> const& providers, + std::shared_ptr const& buffer_allocator) -> std::shared_ptr { auto display_provider = std::make_shared(); OffscreenDisplaySink temp_db{display_provider, geom::Size{640, 480}}; - for (auto const& render_provider : providers) + std::pair> best_provider = std::make_pair( + mg::probe::unsupported, nullptr); + for (auto const& provider: providers) { /* TODO: There might be more sensible ways to select a provider * (one in use by at least one DisplaySink, the only one in use, the lowest-powered one,...) @@ -231,12 +234,20 @@ auto mc::BasicScreenShooter::select_provider( * * For now, just use the first that claims to work. */ - if (render_provider->suitability_for_display(temp_db) >= mg::probe::supported) + auto suitability = provider->suitability_for_display(temp_db); + // We also need to make sure that the GLRenderingProvider can access client buffers... + if (provider->suitability_for_allocator(buffer_allocator) > mg::probe::unsupported && + suitability > best_provider.first) { - return render_provider; + best_provider = std::make_pair(suitability, provider); } } - BOOST_THROW_EXCEPTION((std::runtime_error{"No rendering provider claims to support a CPU addressable target"})); + if (best_provider.first == mg::probe::unsupported) + { + BOOST_THROW_EXCEPTION((std::runtime_error{"No rendering provider claims to support a CPU addressable target"})); + } + + return best_provider.second; } mc::BasicScreenShooter::BasicScreenShooter( @@ -245,8 +256,9 @@ mc::BasicScreenShooter::BasicScreenShooter( Executor& executor, std::span> const& providers, std::shared_ptr render_factory, + std::shared_ptr const& buffer_allocator, std::shared_ptr const& config) - : self{std::make_shared(scene, clock, select_provider(providers), std::move(render_factory), config)}, + : self{std::make_shared(scene, clock, select_provider(providers, buffer_allocator), std::move(render_factory), config)}, executor{executor} { } diff --git a/src/server/compositor/basic_screen_shooter.h b/src/server/compositor/basic_screen_shooter.h index 77392338fb3..48ae530525f 100644 --- a/src/server/compositor/basic_screen_shooter.h +++ b/src/server/compositor/basic_screen_shooter.h @@ -46,6 +46,7 @@ class BasicScreenShooter: public ScreenShooter Executor& executor, std::span> const& providers, std::shared_ptr render_factory, + std::shared_ptr const& buffer_allocator, std::shared_ptr const& config); void capture( @@ -92,7 +93,9 @@ class BasicScreenShooter: public ScreenShooter std::shared_ptr const self; Executor& executor; - static auto select_provider(std::span> const& providers) + static auto select_provider( + std::span> const& providers, + std::shared_ptr const& buffer_allocator) -> std::shared_ptr; }; } diff --git a/src/server/compositor/default_configuration.cpp b/src/server/compositor/default_configuration.cpp index 5d00a8f75a1..09ec094f863 100644 --- a/src/server/compositor/default_configuration.cpp +++ b/src/server/compositor/default_configuration.cpp @@ -120,6 +120,7 @@ auto mir::DefaultServerConfiguration::the_screen_shooter() -> std::shared_ptr @@ -98,6 +99,8 @@ struct BasicScreenShooter : Test } BOOST_THROW_EXCEPTION((std::runtime_error{"CPU output support not available?!"})); }); + ON_CALL(*gl_provider, suitability_for_allocator(_)) + .WillByDefault(Return(mg::probe::supported)); ON_CALL(*gl_provider, suitability_for_display(_)) .WillByDefault(Return(mg::probe::supported)); @@ -107,6 +110,7 @@ struct BasicScreenShooter : Test executor, gl_providers, renderer_factory, + buffer_allocator, std::make_shared()); } @@ -135,6 +139,7 @@ struct BasicScreenShooter : Test std::shared_ptr gl_provider{std::make_shared>()}; std::vector> gl_providers{gl_provider}; std::shared_ptr renderer_factory{std::make_shared>()}; + std::shared_ptr buffer_allocator; std::shared_ptr clock{std::make_shared()}; mtd::ExplicitExecutor executor; std::unique_ptr shooter; @@ -249,6 +254,7 @@ TEST_F(BasicScreenShooter, ensures_renderer_is_current_on_only_one_thread) mir::thread_pool_executor, gl_providers, renderer_factory, + buffer_allocator, std::make_shared()); ON_CALL(*next_renderer, render(_))