Commit d8da0251 authored by Shawn Gallea's avatar Shawn Gallea Committed by Commit Bot

Set vsync parameters during compositor initialization

This will allow for custom framerate, to eventually be
used to lower framerate for headless devices.

Bug: b/139299756
Test: Compile cast_shell for headless device
Change-Id: Ib08559a3101d55c7b004a7356f78a2f01010af4c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1814318
Commit-Queue: Shawn Gallea <sagallea@google.com>
Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Reviewed-by: default avatarMichael Spang <spang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702897}
parent d1e429b7
...@@ -304,6 +304,9 @@ void Compositor::SetLayerTreeFrameSink( ...@@ -304,6 +304,9 @@ void Compositor::SetLayerTreeFrameSink(
sdr_white_level_); sdr_white_level_);
context_factory_private_->SetDisplayColorMatrix(this, context_factory_private_->SetDisplayColorMatrix(this,
display_color_matrix_); display_color_matrix_);
if (has_vsync_params_)
context_factory_private_->SetDisplayVSyncParameters(this, vsync_timebase_,
vsync_interval_);
} }
} }
...@@ -500,6 +503,9 @@ void Compositor::SetDisplayVSyncParameters(base::TimeTicks timebase, ...@@ -500,6 +503,9 @@ void Compositor::SetDisplayVSyncParameters(base::TimeTicks timebase,
if (vsync_timebase_ == timebase && vsync_interval_ == interval) if (vsync_timebase_ == timebase && vsync_interval_ == interval)
return; return;
if (interval != vsync_interval_)
has_vsync_params_ = true;
vsync_timebase_ = timebase; vsync_timebase_ = timebase;
vsync_interval_ = interval; vsync_interval_ = interval;
if (context_factory_private_) { if (context_factory_private_) {
......
...@@ -481,7 +481,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient, ...@@ -481,7 +481,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
// Snapshot of last set vsync parameters, to avoid redundant IPCs. // Snapshot of last set vsync parameters, to avoid redundant IPCs.
base::TimeTicks vsync_timebase_; base::TimeTicks vsync_timebase_;
base::TimeDelta vsync_interval_; base::TimeDelta vsync_interval_ = viz::BeginFrameArgs::DefaultInterval();
bool has_vsync_params_ = false;
const bool use_external_begin_frame_control_; const bool use_external_begin_frame_control_;
const bool force_software_compositor_; const bool force_software_compositor_;
......
...@@ -100,7 +100,7 @@ class CompositorTestWithMessageLoop : public CompositorTest { ...@@ -100,7 +100,7 @@ class CompositorTestWithMessageLoop : public CompositorTest {
} // namespace } // namespace
TEST_F(CompositorTestWithMessageLoop, OutputColorMatrix) { TEST_F(CompositorTestWithMessageLoop, ShouldUpdateDisplayProperties) {
auto root_layer = std::make_unique<Layer>(ui::LAYER_SOLID_COLOR); auto root_layer = std::make_unique<Layer>(ui::LAYER_SOLID_COLOR);
viz::ParentLocalSurfaceIdAllocator allocator; viz::ParentLocalSurfaceIdAllocator allocator;
allocator.GenerateId(); allocator.GenerateId();
...@@ -110,12 +110,20 @@ TEST_F(CompositorTestWithMessageLoop, OutputColorMatrix) { ...@@ -110,12 +110,20 @@ TEST_F(CompositorTestWithMessageLoop, OutputColorMatrix) {
allocator.GetCurrentLocalSurfaceIdAllocation()); allocator.GetCurrentLocalSurfaceIdAllocation());
DCHECK(compositor()->IsVisible()); DCHECK(compositor()->IsVisible());
// Set a non-identity color matrix on the compistor display, and expect it to // Set a non-identity color matrix, color space, sdr white level, vsync
// be set on the context factory. // timebase and vsync interval, and expect it to be set on the context
// factory.
SkMatrix44 color_matrix(SkMatrix44::kIdentity_Constructor); SkMatrix44 color_matrix(SkMatrix44::kIdentity_Constructor);
color_matrix.set(1, 1, 0.7f); color_matrix.set(1, 1, 0.7f);
color_matrix.set(2, 2, 0.4f); color_matrix.set(2, 2, 0.4f);
gfx::ColorSpace color_space(gfx::ColorSpace::CreateDisplayP3D65());
float sdr_white_level(1.0f);
base::TimeTicks vsync_timebase(base::TimeTicks::Now());
base::TimeDelta vsync_interval(base::TimeDelta::FromMilliseconds(250));
compositor()->SetDisplayColorMatrix(color_matrix); compositor()->SetDisplayColorMatrix(color_matrix);
compositor()->SetDisplayColorSpace(color_space, sdr_white_level);
compositor()->SetDisplayVSyncParameters(vsync_timebase, vsync_interval);
InProcessContextFactory* context_factory_private = InProcessContextFactory* context_factory_private =
static_cast<InProcessContextFactory*>( static_cast<InProcessContextFactory*>(
compositor()->context_factory_private()); compositor()->context_factory_private());
...@@ -123,11 +131,20 @@ TEST_F(CompositorTestWithMessageLoop, OutputColorMatrix) { ...@@ -123,11 +131,20 @@ TEST_F(CompositorTestWithMessageLoop, OutputColorMatrix) {
DrawWaiterForTest::WaitForCompositingEnded(compositor()); DrawWaiterForTest::WaitForCompositingEnded(compositor());
EXPECT_EQ(color_matrix, EXPECT_EQ(color_matrix,
context_factory_private->GetOutputColorMatrix(compositor())); context_factory_private->GetOutputColorMatrix(compositor()));
EXPECT_EQ(color_space,
context_factory_private->GetDisplayColorSpace(compositor()));
EXPECT_EQ(sdr_white_level,
context_factory_private->GetSDRWhiteLevel(compositor()));
EXPECT_EQ(vsync_timebase,
context_factory_private->GetDisplayVSyncTimeBase(compositor()));
EXPECT_EQ(vsync_interval,
context_factory_private->GetDisplayVSyncTimeInterval(compositor()));
// Simulate a lost context by releasing the output surface and setting it on // Simulate a lost context by releasing the output surface and setting it on
// the compositor again. Expect that the same color matrix will be set again // the compositor again. Expect that the same color matrix, color space, sdr
// on the context factory. // white level, vsync timebase and vsync interval will be set again on the
context_factory_private->ResetOutputColorMatrixToIdentity(compositor()); // context factory.
context_factory_private->ResetDisplayOutputParameters(compositor());
compositor()->SetVisible(false); compositor()->SetVisible(false);
EXPECT_EQ(gfx::kNullAcceleratedWidget, EXPECT_EQ(gfx::kNullAcceleratedWidget,
compositor()->ReleaseAcceleratedWidget()); compositor()->ReleaseAcceleratedWidget());
...@@ -137,6 +154,14 @@ TEST_F(CompositorTestWithMessageLoop, OutputColorMatrix) { ...@@ -137,6 +154,14 @@ TEST_F(CompositorTestWithMessageLoop, OutputColorMatrix) {
DrawWaiterForTest::WaitForCompositingEnded(compositor()); DrawWaiterForTest::WaitForCompositingEnded(compositor());
EXPECT_EQ(color_matrix, EXPECT_EQ(color_matrix,
context_factory_private->GetOutputColorMatrix(compositor())); context_factory_private->GetOutputColorMatrix(compositor()));
EXPECT_EQ(color_space,
context_factory_private->GetDisplayColorSpace(compositor()));
EXPECT_EQ(sdr_white_level,
context_factory_private->GetSDRWhiteLevel(compositor()));
EXPECT_EQ(vsync_timebase,
context_factory_private->GetDisplayVSyncTimeBase(compositor()));
EXPECT_EQ(vsync_interval,
context_factory_private->GetDisplayVSyncTimeInterval(compositor()));
compositor()->SetRootLayer(nullptr); compositor()->SetRootLayer(nullptr);
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "cc/base/switches.h" #include "cc/base/switches.h"
#include "cc/test/pixel_test_output_surface.h" #include "cc/test/pixel_test_output_surface.h"
#include "components/viz/common/features.h" #include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h" #include "components/viz/common/frame_sinks/delay_based_time_source.h"
#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/gpu/context_provider.h"
...@@ -159,6 +160,10 @@ struct InProcessContextFactory::PerCompositorData { ...@@ -159,6 +160,10 @@ struct InProcessContextFactory::PerCompositorData {
std::unique_ptr<viz::BeginFrameSource> begin_frame_source; std::unique_ptr<viz::BeginFrameSource> begin_frame_source;
std::unique_ptr<viz::Display> display; std::unique_ptr<viz::Display> display;
SkMatrix44 output_color_matrix; SkMatrix44 output_color_matrix;
gfx::ColorSpace color_space;
float sdr_white_level = 0.f;
base::TimeTicks vsync_timebase;
base::TimeDelta vsync_interval;
}; };
InProcessContextFactory::InProcessContextFactory( InProcessContextFactory::InProcessContextFactory(
...@@ -407,6 +412,29 @@ void InProcessContextFactory::SetDisplayColorMatrix(ui::Compositor* compositor, ...@@ -407,6 +412,29 @@ void InProcessContextFactory::SetDisplayColorMatrix(ui::Compositor* compositor,
iter->second->display->SetColorMatrix(matrix); iter->second->display->SetColorMatrix(matrix);
} }
void InProcessContextFactory::SetDisplayColorSpace(
ui::Compositor* compositor,
const gfx::ColorSpace& output_color_space,
float sdr_white_level) {
auto iter = per_compositor_data_.find(compositor);
if (iter == per_compositor_data_.end())
return;
iter->second->color_space = output_color_space;
iter->second->sdr_white_level = sdr_white_level;
}
void InProcessContextFactory::SetDisplayVSyncParameters(
ui::Compositor* compositor,
base::TimeTicks timebase,
base::TimeDelta interval) {
auto iter = per_compositor_data_.find(compositor);
if (iter == per_compositor_data_.end())
return;
iter->second->vsync_timebase = timebase;
iter->second->vsync_interval = interval;
}
void InProcessContextFactory::AddObserver(ContextFactoryObserver* observer) { void InProcessContextFactory::AddObserver(ContextFactoryObserver* observer) {
observer_list_.AddObserver(observer); observer_list_.AddObserver(observer);
} }
...@@ -424,13 +452,49 @@ SkMatrix44 InProcessContextFactory::GetOutputColorMatrix( ...@@ -424,13 +452,49 @@ SkMatrix44 InProcessContextFactory::GetOutputColorMatrix(
return iter->second->output_color_matrix; return iter->second->output_color_matrix;
} }
void InProcessContextFactory::ResetOutputColorMatrixToIdentity( gfx::ColorSpace InProcessContextFactory::GetDisplayColorSpace(
Compositor* compositor) const {
auto iter = per_compositor_data_.find(compositor);
if (iter == per_compositor_data_.end())
return gfx::ColorSpace();
return iter->second->color_space;
}
float InProcessContextFactory::GetSDRWhiteLevel(Compositor* compositor) const {
auto iter = per_compositor_data_.find(compositor);
if (iter == per_compositor_data_.end())
return 0;
return iter->second->sdr_white_level;
}
base::TimeTicks InProcessContextFactory::GetDisplayVSyncTimeBase(
Compositor* compositor) const {
auto iter = per_compositor_data_.find(compositor);
if (iter == per_compositor_data_.end())
return base::TimeTicks();
return iter->second->vsync_timebase;
}
base::TimeDelta InProcessContextFactory::GetDisplayVSyncTimeInterval(
Compositor* compositor) const {
auto iter = per_compositor_data_.find(compositor);
if (iter == per_compositor_data_.end())
return viz::BeginFrameArgs::DefaultInterval();
;
return iter->second->vsync_interval;
}
void InProcessContextFactory::ResetDisplayOutputParameters(
ui::Compositor* compositor) { ui::Compositor* compositor) {
auto iter = per_compositor_data_.find(compositor); auto iter = per_compositor_data_.find(compositor);
if (iter == per_compositor_data_.end()) if (iter == per_compositor_data_.end())
return; return;
iter->second->output_color_matrix.setIdentity(); iter->second->output_color_matrix.setIdentity();
iter->second->color_space = gfx::ColorSpace::CreateSRGB();
iter->second->sdr_white_level = 0;
iter->second->vsync_timebase = base::TimeTicks();
iter->second->vsync_interval = base::TimeDelta();
} }
InProcessContextFactory::PerCompositorData* InProcessContextFactory::PerCompositorData*
......
...@@ -86,10 +86,10 @@ class InProcessContextFactory : public ContextFactory, ...@@ -86,10 +86,10 @@ class InProcessContextFactory : public ContextFactory,
const SkMatrix44& matrix) override; const SkMatrix44& matrix) override;
void SetDisplayColorSpace(ui::Compositor* compositor, void SetDisplayColorSpace(ui::Compositor* compositor,
const gfx::ColorSpace& output_color_space, const gfx::ColorSpace& output_color_space,
float sdr_white_level) override {} float sdr_white_level) override;
void SetDisplayVSyncParameters(ui::Compositor* compositor, void SetDisplayVSyncParameters(ui::Compositor* compositor,
base::TimeTicks timebase, base::TimeTicks timebase,
base::TimeDelta interval) override {} base::TimeDelta interval) override;
void IssueExternalBeginFrame( void IssueExternalBeginFrame(
ui::Compositor* compositor, ui::Compositor* compositor,
const viz::BeginFrameArgs& args, const viz::BeginFrameArgs& args,
...@@ -104,7 +104,11 @@ class InProcessContextFactory : public ContextFactory, ...@@ -104,7 +104,11 @@ class InProcessContextFactory : public ContextFactory,
bool SyncTokensRequiredForDisplayCompositor() override; bool SyncTokensRequiredForDisplayCompositor() override;
SkMatrix44 GetOutputColorMatrix(Compositor* compositor) const; SkMatrix44 GetOutputColorMatrix(Compositor* compositor) const;
void ResetOutputColorMatrixToIdentity(ui::Compositor* compositor); gfx::ColorSpace GetDisplayColorSpace(ui::Compositor* compositor) const;
float GetSDRWhiteLevel(ui::Compositor* compositor) const;
base::TimeTicks GetDisplayVSyncTimeBase(ui::Compositor* compositor) const;
base::TimeDelta GetDisplayVSyncTimeInterval(ui::Compositor* compositor) const;
void ResetDisplayOutputParameters(ui::Compositor* compositor);
private: private:
struct PerCompositorData; struct PerCompositorData;
......
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