diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 6d9e485447e40..c7047cfc22901 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -43,6 +43,7 @@ Rasterizer::Rasterizer( : delegate_(delegate), task_runners_(std::move(task_runners)), compositor_context_(std::move(compositor_context)), + user_override_resource_cache_bytes_(false), weak_factory_(this) { FML_DCHECK(compositor_context_); } @@ -405,7 +406,15 @@ void Rasterizer::FireNextFrameCallbackIfPresent() { callback(); } -void Rasterizer::SetResourceCacheMaxBytes(int max_bytes) { +void Rasterizer::SetResourceCacheMaxBytes(size_t max_bytes, bool from_user) { + user_override_resource_cache_bytes_ |= from_user; + + if (!from_user && user_override_resource_cache_bytes_) { + // We should not update the setting here if a user has explicitly set a + // value for this over the flutter/skia channel. + return; + } + GrContext* context = surface_->GetContext(); if (context) { int max_resources; @@ -414,6 +423,16 @@ void Rasterizer::SetResourceCacheMaxBytes(int max_bytes) { } } +size_t Rasterizer::GetResourceCacheMaxBytes() const { + GrContext* context = surface_->GetContext(); + if (context) { + size_t max_bytes; + context->getResourceCacheLimits(nullptr, &max_bytes); + return max_bytes; + } + return 0; +} + Rasterizer::Screenshot::Screenshot() {} Rasterizer::Screenshot::Screenshot(sk_sp p_data, SkISize p_size) diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index bc2df2d0d83b8..ffeb0488f87e9 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -92,7 +92,13 @@ class Rasterizer final : public SnapshotDelegate { return compositor_context_.get(); } - void SetResourceCacheMaxBytes(int max_bytes); + // Sets the max size in bytes of the Skia resource cache. If this call is + // originating from the user, e.g. over the flutter/skia system channel, + // set from_user to true and the value will take precedence over system + // generated values, e.g. from a display resolution change. + void SetResourceCacheMaxBytes(size_t max_bytes, bool from_user); + + size_t GetResourceCacheMaxBytes() const; private: Delegate& delegate_; @@ -101,6 +107,7 @@ class Rasterizer final : public SnapshotDelegate { std::unique_ptr compositor_context_; std::unique_ptr last_layer_tree_; fml::closure next_frame_callback_; + bool user_override_resource_cache_bytes_; fml::WeakPtrFactory weak_factory_; // |SnapshotDelegate| diff --git a/shell/common/shell.cc b/shell/common/shell.cc index ba38f792e12d0..a50ef70afb0ab 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -610,6 +610,16 @@ void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + // This is the formula Android uses. + // https://android.googlesource.com/platform/frameworks/base/+/master/libs/hwui/renderthread/CacheManager.cpp#41 + int max_bytes = metrics.physical_width * metrics.physical_height * 12 * 4; + task_runners_.GetGPUTaskRunner()->PostTask( + [rasterizer = rasterizer_->GetWeakPtr(), max_bytes] { + if (rasterizer) { + rasterizer->SetResourceCacheMaxBytes(max_bytes, false); + } + }); + task_runners_.GetUITaskRunner()->PostTask( [engine = engine_->GetWeakPtr(), metrics]() { if (engine) { @@ -863,7 +873,8 @@ void Shell::HandleEngineSkiaMessage(fml::RefPtr message) { [rasterizer = rasterizer_->GetWeakPtr(), max_bytes = args->value.GetInt()] { if (rasterizer) { - rasterizer->SetResourceCacheMaxBytes(max_bytes); + rasterizer->SetResourceCacheMaxBytes(static_cast(max_bytes), + true); } }); } diff --git a/shell/gpu/gpu_surface_gl.cc b/shell/gpu/gpu_surface_gl.cc index d344e7225a595..6ddbcde23b3c3 100644 --- a/shell/gpu/gpu_surface_gl.cc +++ b/shell/gpu/gpu_surface_gl.cc @@ -28,7 +28,10 @@ static const int kGrCacheMaxCount = 8192; // Default maximum number of bytes of GPU memory of budgeted resources in the // cache. -static const size_t kGrCacheMaxByteSize = 512 * (1 << 20); +// The shell will dynamically increase or decrease this cache based on the +// viewport size, unless a user has specifically requested a size on the Skia +// system channel. +static const size_t kGrCacheMaxByteSize = 24 * (1 << 20); GPUSurfaceGL::GPUSurfaceGL(GPUSurfaceGLDelegate* delegate) : delegate_(delegate), weak_factory_(this) {