未验证 提交 bef5ac61 编写于 作者: G gaaclarke 提交者: GitHub

Made the Rasterizer avoid GPU calls when backgrounded (#18563)

上级 a298f564
......@@ -58,7 +58,9 @@ TEST_F(ShellTest, VSyncTargetTime) {
ShellTestPlatformView::BackendType::kDefaultBackend, nullptr);
},
[](Shell& shell) {
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
return std::make_unique<Rasterizer>(
shell, shell.GetTaskRunners(),
shell.GetIsGpuDisabledSyncSwitch());
});
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
......
......@@ -28,26 +28,34 @@ static constexpr std::chrono::milliseconds kSkiaCleanupExpiration(15000);
static Rasterizer::DummyDelegate dummy_delegate_;
Rasterizer::Rasterizer(
TaskRunners task_runners,
std::unique_ptr<flutter::CompositorContext> compositor_context)
std::unique_ptr<flutter::CompositorContext> compositor_context,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch)
: Rasterizer(dummy_delegate_,
std::move(task_runners),
std::move(compositor_context)) {}
std::move(compositor_context),
is_gpu_disabled_sync_switch) {}
Rasterizer::Rasterizer(Delegate& delegate, TaskRunners task_runners)
Rasterizer::Rasterizer(
Delegate& delegate,
TaskRunners task_runners,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch)
: Rasterizer(delegate,
std::move(task_runners),
std::make_unique<flutter::CompositorContext>(
delegate.GetFrameBudget())) {}
delegate.GetFrameBudget()),
is_gpu_disabled_sync_switch) {}
Rasterizer::Rasterizer(
Delegate& delegate,
TaskRunners task_runners,
std::unique_ptr<flutter::CompositorContext> compositor_context)
std::unique_ptr<flutter::CompositorContext> compositor_context,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch)
: delegate_(delegate),
task_runners_(std::move(task_runners)),
compositor_context_(std::move(compositor_context)),
user_override_resource_cache_bytes_(false),
weak_factory_(this) {
weak_factory_(this),
is_gpu_disabled_sync_switch_(is_gpu_disabled_sync_switch) {
FML_DCHECK(compositor_context_);
}
......@@ -168,31 +176,10 @@ void Rasterizer::Draw(fml::RefPtr<Pipeline<flutter::LayerTree>> pipeline) {
}
}
sk_sp<SkImage> Rasterizer::DoMakeRasterSnapshot(
SkISize size,
std::function<void(SkCanvas*)> draw_callback) {
TRACE_EVENT0("flutter", __FUNCTION__);
sk_sp<SkSurface> surface;
SkImageInfo image_info = SkImageInfo::MakeN32Premul(
size.width(), size.height(), SkColorSpace::MakeSRGB());
if (surface_ == nullptr || surface_->GetContext() == nullptr) {
// Raster surface is fine if there is no on screen surface. This might
// happen in case of software rendering.
surface = SkSurface::MakeRaster(image_info);
} else {
if (!surface_->MakeRenderContextCurrent()) {
return nullptr;
}
// When there is an on screen surface, we need a render target SkSurface
// because we want to access texture backed images.
surface = SkSurface::MakeRenderTarget(surface_->GetContext(), // context
SkBudgeted::kNo, // budgeted
image_info // image info
);
}
namespace {
sk_sp<SkImage> DrawSnapshot(
sk_sp<SkSurface> surface,
const std::function<void(SkCanvas*)>& draw_callback) {
if (surface == nullptr || surface->getCanvas() == nullptr) {
return nullptr;
}
......@@ -219,6 +206,45 @@ sk_sp<SkImage> Rasterizer::DoMakeRasterSnapshot(
return nullptr;
}
} // namespace
sk_sp<SkImage> Rasterizer::DoMakeRasterSnapshot(
SkISize size,
std::function<void(SkCanvas*)> draw_callback) {
TRACE_EVENT0("flutter", __FUNCTION__);
sk_sp<SkImage> result;
SkImageInfo image_info = SkImageInfo::MakeN32Premul(
size.width(), size.height(), SkColorSpace::MakeSRGB());
if (surface_ == nullptr || surface_->GetContext() == nullptr) {
// Raster surface is fine if there is no on screen surface. This might
// happen in case of software rendering.
sk_sp<SkSurface> surface = SkSurface::MakeRaster(image_info);
result = DrawSnapshot(surface, draw_callback);
} else {
is_gpu_disabled_sync_switch_->Execute(
fml::SyncSwitch::Handlers()
.SetIfTrue([&] {
sk_sp<SkSurface> surface = SkSurface::MakeRaster(image_info);
result = DrawSnapshot(surface, draw_callback);
})
.SetIfFalse([&] {
if (!surface_->MakeRenderContextCurrent()) {
return;
}
// When there is an on screen surface, we need a render target
// SkSurface because we want to access texture backed images.
sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
surface_->GetContext(), // context
SkBudgeted::kNo, // budgeted
image_info // image info
);
result = DrawSnapshot(surface, draw_callback);
}));
}
return result;
}
sk_sp<SkImage> Rasterizer::MakeRasterSnapshot(sk_sp<SkPicture> picture,
SkISize picture_size) {
......
......@@ -15,6 +15,7 @@
#include "flutter/fml/closure.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/fml/raster_thread_merger.h"
#include "flutter/fml/synchronization/sync_switch.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/time/time_delta.h"
#include "flutter/fml/time/time_point.h"
......@@ -101,9 +102,13 @@ class Rasterizer final : public SnapshotDelegate {
/// @param[in] task_runners The task runners used by the shell.
/// @param[in] compositor_context The compositor context used to hold all
/// the GPU state used by the rasterizer.
/// @param[in] is_gpu_disabled_sync_switch
/// A `SyncSwitch` for handling disabling of the GPU (typically happens
/// when an app is backgrounded)
///
Rasterizer(TaskRunners task_runners,
std::unique_ptr<flutter::CompositorContext> compositor_context);
std::unique_ptr<flutter::CompositorContext> compositor_context,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch);
//----------------------------------------------------------------------------
/// @brief Creates a new instance of a rasterizer. Rasterizers may only
......@@ -116,8 +121,13 @@ class Rasterizer final : public SnapshotDelegate {
///
/// @param[in] delegate The rasterizer delegate.
/// @param[in] task_runners The task runners used by the shell.
/// @param[in] is_gpu_disabled_sync_switch
/// A `SyncSwitch` for handling disabling of the GPU (typically happens
/// when an app is backgrounded)
///
Rasterizer(Delegate& delegate, TaskRunners task_runners);
Rasterizer(Delegate& delegate,
TaskRunners task_runners,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch);
//----------------------------------------------------------------------------
/// @brief Creates a new instance of a rasterizer. Rasterizers may only
......@@ -132,10 +142,14 @@ class Rasterizer final : public SnapshotDelegate {
/// @param[in] task_runners The task runners used by the shell.
/// @param[in] compositor_context The compositor context used to hold all
/// the GPU state used by the rasterizer.
/// @param[in] is_gpu_disabled_sync_switch
/// A `SyncSwitch` for handling disabling of the GPU (typically happens
/// when an app is backgrounded)
///
Rasterizer(Delegate& delegate,
TaskRunners task_runners,
std::unique_ptr<flutter::CompositorContext> compositor_context);
std::unique_ptr<flutter::CompositorContext> compositor_context,
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch);
//----------------------------------------------------------------------------
/// @brief Destroys the rasterizer. This must happen on the GPU task
......@@ -432,6 +446,7 @@ class Rasterizer final : public SnapshotDelegate {
std::optional<size_t> max_cache_bytes_;
fml::TaskRunnerAffineWeakPtrFactory<Rasterizer> weak_factory_;
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger_;
std::shared_ptr<fml::SyncSwitch> is_gpu_disabled_sync_switch_;
// |SnapshotDelegate|
sk_sp<SkImage> MakeRasterSnapshot(sk_sp<SkPicture> picture,
......
......@@ -58,7 +58,9 @@ static void StartupAndShutdownShell(benchmark::State& state,
return std::make_unique<PlatformView>(shell, shell.GetTaskRunners());
},
[](Shell& shell) {
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
return std::make_unique<Rasterizer>(
shell, shell.GetTaskRunners(),
shell.GetIsGpuDisabledSyncSwitch());
});
}
......
......@@ -298,7 +298,8 @@ std::unique_ptr<Shell> ShellTest::CreateShell(
shell_test_external_view_embedder);
},
[](Shell& shell) {
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners(),
shell.GetIsGpuDisabledSyncSwitch());
});
}
void ShellTest::DestroyShell(std::unique_ptr<Shell> shell) {
......
......@@ -143,7 +143,8 @@ TEST_F(ShellTest,
ShellTestPlatformView::BackendType::kDefaultBackend, nullptr);
},
[](Shell& shell) {
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners(),
shell.GetIsGpuDisabledSyncSwitch());
});
ASSERT_TRUE(ValidateShell(shell.get()));
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
......
......@@ -79,7 +79,8 @@ AndroidShellHolder::AndroidShellHolder(
};
Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners(),
shell.GetIsGpuDisabledSyncSwitch());
};
// The current thread will be used as the platform thread. Ensure that the
......
......@@ -475,7 +475,8 @@ static constexpr int kNumProfilerSamplesPerSec = 5;
flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
[](flutter::Shell& shell) {
return std::make_unique<flutter::Rasterizer>(shell, shell.GetTaskRunners());
return std::make_unique<flutter::Rasterizer>(shell, shell.GetTaskRunners(),
shell.GetIsGpuDisabledSyncSwitch());
};
if (flutter::IsIosEmbeddedViewsPreviewEnabled()) {
......
......@@ -935,8 +935,8 @@ FlutterEngineResult FlutterEngineInitialize(size_t version,
flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer =
[](flutter::Shell& shell) {
return std::make_unique<flutter::Rasterizer>(shell,
shell.GetTaskRunners());
return std::make_unique<flutter::Rasterizer>(
shell, shell.GetTaskRunners(), shell.GetIsGpuDisabledSyncSwitch());
};
// TODO(chinmaygarde): This is the wrong spot for this. It belongs in the
......
......@@ -202,9 +202,9 @@ Engine::Engine(Delegate& delegate,
}
return std::make_unique<flutter::Rasterizer>(
shell.GetTaskRunners(), // task runners
std::move(compositor_context) // compositor context
);
/*task_runners=*/shell.GetTaskRunners(),
/*compositor_context=*/std::move(compositor_context),
/*is_gpu_disabled_sync_switch=*/shell.GetIsGpuDisabledSyncSwitch());
});
UpdateNativeThreadLabelNames(thread_label_, task_runners);
......
......@@ -139,7 +139,8 @@ int RunTester(const flutter::Settings& settings,
};
Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners());
return std::make_unique<Rasterizer>(shell, shell.GetTaskRunners(),
shell.GetIsGpuDisabledSyncSwitch());
};
auto shell = Shell::Create(task_runners, //
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册