Commit e9baad7a authored by Sean Gilhuly's avatar Sean Gilhuly Committed by Commit Bot

Cache the results of ColorSpace::Contains()

ColorSpace::Contains() can be called a few times per frame for tile
operations. The result of the call is deterministic, and called
consistently on a small set of color spaces in gfx::DisplayColorSpaces,
so store the results in a small MRUCache.

Bug: 1073962
Change-Id: I61e2a8ff34291b686ed79ae4c301adb1c0792b35
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2504051Reviewed-by: default avatarccameron <ccameron@chromium.org>
Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Commit-Queue: Sean Gilhuly <sgilhuly@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826509}
parent d507c5fa
......@@ -149,6 +149,13 @@ const float kMobileViewportWidthEpsilon = 0.15f;
// kHitTestAsk after the threshold is reached.
const size_t kAssumeOverlapThreshold = 100;
// gfx::DisplayColorSpaces stores up to 3 different color spaces. This should be
// updated to match any size changes in DisplayColorSpaces.
constexpr size_t kContainsSrgbCacheSize = 3;
static_assert(kContainsSrgbCacheSize ==
gfx::DisplayColorSpaces::kConfigCount / 2,
"sRGB cache must match the size of DisplayColorSpaces");
bool HasFixedPageScale(LayerTreeImpl* active_tree) {
return active_tree->min_page_scale_factor() ==
active_tree->max_page_scale_factor();
......@@ -425,7 +432,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(
frame_trackers_(settings.single_thread_proxy_scheduler,
compositor_frame_reporting_controller_.get()),
lcd_text_metrics_reporter_(LCDTextMetricsReporter::CreateIfNeeded(this)),
frame_rate_estimator_(GetTaskRunner()) {
frame_rate_estimator_(GetTaskRunner()),
contains_srgb_cache_(kContainsSrgbCacheSize) {
DCHECK(mutator_host_);
mutator_host_->SetMutatorHostClient(this);
mutator_events_ = mutator_host_->CreateEvents();
......@@ -1800,12 +1808,30 @@ gfx::ColorSpace LayerTreeHostImpl::GetRasterColorSpace(
// The raster color space should contain sRGB to avoid artifacts during
// rasterization.
if (!result.Contains(srgb))
if (!CheckColorSpaceContainsSrgb(result))
return srgb;
return result;
}
bool LayerTreeHostImpl::CheckColorSpaceContainsSrgb(
const gfx::ColorSpace& color_space) const {
constexpr gfx::ColorSpace srgb = gfx::ColorSpace::CreateSRGB();
// Color spaces without a custom primary matrix are cheap to compute, so the
// cache can be bypassed.
if (color_space.GetPrimaryID() != gfx::ColorSpace::PrimaryID::CUSTOM)
return color_space.Contains(srgb);
auto it = contains_srgb_cache_.Get(color_space);
if (it != contains_srgb_cache_.end())
return it->second;
bool result = color_space.Contains(srgb);
contains_srgb_cache_.Put(color_space, result);
return result;
}
float LayerTreeHostImpl::GetSDRWhiteLevel() const {
// If we are likely to software composite the resource, we use sRGB because
// software compositing is unable to perform color conversion.
......
......@@ -17,6 +17,7 @@
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/containers/mru_cache.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/shared_memory_mapping.h"
#include "base/optional.h"
......@@ -954,6 +955,9 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
// Notifies client about the custom tracker results.
void NotifyThroughputTrackerResults(const CustomTrackerResults& results);
// Wrapper for checking and updating |contains_srgb_cache_|.
bool CheckColorSpaceContainsSrgb(const gfx::ColorSpace& color_space) const;
// Once bound, this instance owns the InputHandler. However, an InputHandler
// need not be bound so this should be null-checked before dereferencing.
std::unique_ptr<InputDelegateForCompositor> input_delegate_;
......@@ -1197,6 +1201,12 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
base::WritableSharedMemoryMapping ukm_smoothness_mapping_;
// Cache for the results of calls to gfx::ColorSpace::Contains() on sRGB. This
// computation is deterministic for a given color space, can be called
// multiple times per frame, and incurs a non-trivial cost.
// mutable because |contains_srgb_cache_| is accessed in a const method.
mutable base::MRUCache<gfx::ColorSpace, bool> contains_srgb_cache_;
// Must be the last member to ensure this is destroyed first in the
// destruction order and invalidates all weak pointers.
base::WeakPtrFactory<LayerTreeHostImpl> weak_factory_{this};
......
......@@ -38,6 +38,8 @@ enum class ContentColorUsage : uint8_t {
// opposed to in ui/display because it is used directly by components/viz.
class COLOR_SPACE_EXPORT DisplayColorSpaces {
public:
static constexpr size_t kConfigCount = 6;
// Initialize as sRGB-only.
DisplayColorSpaces();
......@@ -111,7 +113,6 @@ class COLOR_SPACE_EXPORT DisplayColorSpaces {
friend struct mojo::StructTraits<gfx::mojom::DisplayColorSpacesDataView,
gfx::DisplayColorSpaces>;
static constexpr size_t kConfigCount = 6;
gfx::ColorSpace color_spaces_[kConfigCount];
gfx::BufferFormat buffer_formats_[kConfigCount];
float sdr_white_level_ = ColorSpace::kDefaultSDRWhiteLevel;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment