Commit 3372217a authored by Eric Seckler's avatar Eric Seckler Committed by Commit Bot

[cc] Add a way to control the compositor's BeginFrames externally.

Exposes a setting and an interface for enabling externally-controlled
BeginFrames in ui::Compositor and adds a command line flag for the
full-pipeline scheduling mode.

Bug: 646774
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_site_isolation
Change-Id: I923b5ab66652c65c1384b9fe5075c0a427559fc6
Reviewed-on: https://chromium-review.googlesource.com/558252
Commit-Queue: Eric Seckler <eseckler@chromium.org>
Reviewed-by: default avatarFady Samuel <fsamuel@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Reviewed-by: default avatarSunny Sachanandani <sunnyps@chromium.org>
Cr-Commit-Position: refs/heads/master@{#490719}
parent 16d3c5dc
......@@ -49,6 +49,11 @@ const char kEnableTileCompression[] = "enable-tile-compression";
// Enables the GPU benchmarking extension
const char kEnableGpuBenchmarking[] = "enable-gpu-benchmarking";
// Effectively disables pipelining of compositor frame production stages by
// waiting for each stage to finish before completing a frame.
const char kRunAllCompositorStagesBeforeDraw[] =
"run-all-compositor-stages-before-draw";
// Renders a border around compositor layers to help debug and study
// layer compositing.
const char kShowCompositedLayerBorders[] = "show-composited-layer-borders";
......
......@@ -30,6 +30,7 @@ CC_BASE_EXPORT extern const char kEnableTileCompression[];
// Switches for both the renderer and ui compositors.
CC_BASE_EXPORT extern const char kEnableGpuBenchmarking[];
CC_BASE_EXPORT extern const char kRunAllCompositorStagesBeforeDraw[];
// Debug visualizations.
CC_BASE_EXPORT extern const char kShowCompositedLayerBorders[];
......
......@@ -35,6 +35,8 @@ SchedulerSettings LayerTreeSettings::ToSchedulerSettings() const {
scheduler_settings.enable_latency_recovery = enable_latency_recovery;
scheduler_settings.background_frame_interval =
base::TimeDelta::FromSecondsD(1.0 / background_animation_rate);
scheduler_settings.wait_for_all_pipeline_stages_before_draw =
wait_for_all_pipeline_stages_before_draw;
return scheduler_settings;
}
......
......@@ -115,6 +115,12 @@ class CC_EXPORT LayerTreeSettings {
// in ResourcePool. Only used for layout or pixel tests, as non-deterministic
// resource sizes can lead to floating point error and noise in these tests.
bool disallow_non_exact_resource_reuse = false;
// Whether the Scheduler should wait for all pipeline stages before attempting
// to draw. If |true|, they will block indefinitely until all stages have
// completed the current BeginFrame before triggering their own BeginFrame
// deadlines.
bool wait_for_all_pipeline_stages_before_draw = false;
};
} // namespace cc
......
......@@ -95,6 +95,14 @@ void Display::Initialize(DisplayClient* client,
}
}
void Display::AddObserver(DisplayObserver* observer) {
observers_.AddObserver(observer);
}
void Display::RemoveObserver(DisplayObserver* observer) {
observers_.RemoveObserver(observer);
}
void Display::SetLocalSurfaceId(const LocalSurfaceId& id,
float device_scale_factor) {
if (current_surface_id_.local_surface_id() == id &&
......@@ -422,6 +430,11 @@ bool Display::SurfaceHasUndrawnFrame(const SurfaceId& surface_id) const {
return surface->HasUndrawnActiveFrame();
}
void Display::DidFinishFrame(const BeginFrameAck& ack) {
for (auto& observer : observers_)
observer.OnDisplayDidFinishFrame(ack);
}
const SurfaceId& Display::CurrentSurfaceId() {
return current_surface_id_;
}
......
......@@ -9,6 +9,7 @@
#include <vector>
#include "base/macros.h"
#include "base/observer_list.h"
#include "cc/output/output_surface_client.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/resources/returned_resource.h"
......@@ -44,6 +45,13 @@ namespace viz {
class DisplayClient;
class SharedBitmapManager;
class VIZ_SERVICE_EXPORT DisplayObserver {
public:
virtual ~DisplayObserver() {}
virtual void OnDisplayDidFinishFrame(const BeginFrameAck& ack) = 0;
};
// A Display produces a surface that can be used to draw to a physical display
// (OutputSurface). The client is responsible for creating and sizing the
// surface IDs used to draw into the display and deciding when to draw.
......@@ -64,6 +72,9 @@ class VIZ_SERVICE_EXPORT Display : public DisplaySchedulerClient,
void Initialize(DisplayClient* client, SurfaceManager* surface_manager);
void AddObserver(DisplayObserver* observer);
void RemoveObserver(DisplayObserver* observer);
// device_scale_factor is used to communicate to the external window system
// what scale this was rendered at.
void SetLocalSurfaceId(const LocalSurfaceId& id, float device_scale_factor);
......@@ -81,6 +92,7 @@ class VIZ_SERVICE_EXPORT Display : public DisplaySchedulerClient,
bool SurfaceDamaged(const SurfaceId& surface_id,
const BeginFrameAck& ack) override;
void SurfaceDiscarded(const SurfaceId& surface_id) override;
void DidFinishFrame(const BeginFrameAck& ack) override;
// OutputSurfaceClient implementation.
void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override;
......@@ -106,6 +118,7 @@ class VIZ_SERVICE_EXPORT Display : public DisplaySchedulerClient,
const RendererSettings settings_;
DisplayClient* client_ = nullptr;
base::ObserverList<DisplayObserver> observers_;
SurfaceManager* surface_manager_ = nullptr;
const FrameSinkId frame_sink_id_;
SurfaceId current_surface_id_;
......
......@@ -471,8 +471,11 @@ void DisplayScheduler::OnBeginFrameDeadline() {
void DisplayScheduler::DidFinishFrame(bool did_draw) {
DCHECK(begin_frame_source_);
// TODO(eseckler): Let client know that frame was completed.
begin_frame_source_->DidFinishFrame(this);
BeginFrameAck ack(current_begin_frame_args_.source_id,
current_begin_frame_args_.sequence_number, did_draw);
client_->DidFinishFrame(ack);
}
void DisplayScheduler::DidSwapBuffers() {
......
......@@ -32,6 +32,7 @@ class VIZ_SERVICE_EXPORT DisplaySchedulerClient {
virtual bool SurfaceDamaged(const SurfaceId& surface_id,
const BeginFrameAck& ack) = 0;
virtual void SurfaceDiscarded(const SurfaceId& surface_id) = 0;
virtual void DidFinishFrame(const BeginFrameAck& ack) = 0;
};
class VIZ_SERVICE_EXPORT DisplayScheduler : public BeginFrameObserverBase,
......
......@@ -13,6 +13,7 @@
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/surfaces/surface_info.h"
#include "components/viz/service/display/display.h"
#include "components/viz/test/begin_frame_args_test.h"
#include "components/viz/test/fake_external_begin_frame_source.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -52,6 +53,10 @@ class FakeDisplaySchedulerClient : public DisplaySchedulerClient {
void SurfaceDiscarded(const SurfaceId& surface_id) override {}
void DidFinishFrame(const BeginFrameAck& ack) override {
last_begin_frame_ack_ = ack;
}
int draw_and_swap_count() const { return draw_and_swap_count_; }
void SetNextDrawAndSwapFails() { next_draw_and_swap_fails_ = true; }
......@@ -60,10 +65,13 @@ class FakeDisplaySchedulerClient : public DisplaySchedulerClient {
undrawn_surfaces_.insert(surface_id);
}
const BeginFrameAck& last_begin_frame_ack() { return last_begin_frame_ack_; }
protected:
int draw_and_swap_count_;
bool next_draw_and_swap_fails_;
std::set<SurfaceId> undrawn_surfaces_;
BeginFrameAck last_begin_frame_ack_;
};
class TestDisplayScheduler : public DisplayScheduler {
......@@ -261,9 +269,11 @@ TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
scheduler_.SetVisible(true);
scheduler_.SetNewRootSurface(root_surface_id);
EXPECT_EQ(BeginFrameAck(), client_.last_begin_frame_ack());
// Set surface1 as active via SurfaceDamageExpected().
AdvanceTimeAndBeginFrameForTest({sid1});
EXPECT_EQ(BeginFrameAck(), client_.last_begin_frame_ack());
// Damage only from surface 2 (inactive) does not trigger deadline early.
SurfaceDamaged(sid2);
......@@ -277,6 +287,9 @@ TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
EXPECT_GE(now_src().NowTicks(),
scheduler_.DesiredBeginFrameDeadlineTimeForTest());
scheduler_.BeginFrameDeadlineForTest();
EXPECT_EQ(BeginFrameAck(last_begin_frame_args_.source_id,
last_begin_frame_args_.sequence_number, true),
client_.last_begin_frame_ack());
// Set both surface 1 and 2 as active via SurfaceDamageExpected().
AdvanceTimeAndBeginFrameForTest({sid1, sid2});
......@@ -291,6 +304,9 @@ TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
EXPECT_GE(now_src().NowTicks(),
scheduler_.DesiredBeginFrameDeadlineTimeForTest());
scheduler_.BeginFrameDeadlineForTest();
EXPECT_EQ(BeginFrameAck(last_begin_frame_args_.source_id,
last_begin_frame_args_.sequence_number, true),
client_.last_begin_frame_ack());
// Surface damage with |!has_damage| triggers early deadline if other damage
// exists.
......@@ -318,6 +334,9 @@ TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
EXPECT_LT(now_src().NowTicks(),
scheduler_.DesiredBeginFrameDeadlineTimeForTest());
scheduler_.BeginFrameDeadlineForTest();
EXPECT_EQ(BeginFrameAck(last_begin_frame_args_.source_id,
last_begin_frame_args_.sequence_number, false),
client_.last_begin_frame_ack());
// System should be idle now.
AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
......
......@@ -24,6 +24,7 @@
#include "cc/output/vulkan_in_process_context_provider.h"
#include "cc/raster/single_thread_task_graph_runner.h"
#include "cc/raster/task_graph_runner.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/delay_based_time_source.h"
#include "components/viz/common/gl_helper.h"
......@@ -186,13 +187,44 @@ bool IsCALayersDisabledFromCommandLine() {
namespace content {
class ExternalBeginFrameController : public viz::ExternalBeginFrameSourceClient,
public viz::DisplayObserver {
public:
explicit ExternalBeginFrameController(ui::Compositor* compositor)
: begin_frame_source_(this), compositor_(compositor) {}
~ExternalBeginFrameController() override {}
// Issue a BeginFrame with the given |args|.
void IssueExternalBeginFrame(const viz::BeginFrameArgs& args) {
begin_frame_source_.OnBeginFrame(args);
}
viz::BeginFrameSource* begin_frame_source() { return &begin_frame_source_; }
private:
// viz::ExternalBeginFrameSourceClient implementation.
void OnNeedsBeginFrames(bool needs_begin_frames) override {
compositor_->OnNeedsExternalBeginFrames(needs_begin_frames);
}
// viz::DisplayObserver implementation.
void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) override {
compositor_->OnDisplayDidFinishFrame(ack);
}
viz::ExternalBeginFrameSource begin_frame_source_;
ui::Compositor* compositor_ = nullptr;
};
struct GpuProcessTransportFactory::PerCompositorData {
gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
BrowserCompositorOutputSurface* display_output_surface = nullptr;
// Either |synthetic_begin_frame_source| or |gpu_vsync_begin_frame_source| is
// valid but not both at the same time.
// Exactly one of |synthetic_begin_frame_source|,
// |gpu_vsync_begin_frame_source|, and |external_begin_frame_source| is valid
// at the same time.
std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_begin_frame_source;
std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
std::unique_ptr<ExternalBeginFrameController> external_begin_frame_controller;
ReflectorImpl* reflector = nullptr;
std::unique_ptr<viz::Display> display;
bool output_is_secure = false;
......@@ -220,6 +252,9 @@ GpuProcessTransportFactory::GpuProcessTransportFactory(
}
}
if (command_line->HasSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw))
wait_for_all_pipeline_stages_before_draw_ = true;
task_graph_runner_->Start("CompositorTileWorker1",
base::SimpleThread::Options());
#if defined(OS_WIN)
......@@ -486,7 +521,6 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
BrowserCompositorOutputSurface::UpdateVSyncParametersCallback vsync_callback =
base::Bind(&ui::Compositor::SetDisplayVSyncParameters, compositor);
viz::BeginFrameSource* begin_frame_source = nullptr;
GpuVSyncControl* gpu_vsync_control = nullptr;
std::unique_ptr<BrowserCompositorOutputSurface> display_output_surface;
......@@ -560,27 +594,31 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_begin_frame_source;
std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
std::unique_ptr<ExternalBeginFrameController> external_begin_frame_controller;
if (!begin_frame_source) {
if (!disable_display_vsync_) {
if (gpu_vsync_control && IsGpuVSyncSignalSupported()) {
gpu_vsync_begin_frame_source =
base::MakeUnique<GpuVSyncBeginFrameSource>(gpu_vsync_control);
begin_frame_source = gpu_vsync_begin_frame_source.get();
} else {
synthetic_begin_frame_source =
base::MakeUnique<viz::DelayBasedBeginFrameSource>(
base::MakeUnique<viz::DelayBasedTimeSource>(
compositor->task_runner().get()));
begin_frame_source = synthetic_begin_frame_source.get();
}
viz::BeginFrameSource* begin_frame_source = nullptr;
if (compositor->external_begin_frames_enabled()) {
external_begin_frame_controller =
base::MakeUnique<ExternalBeginFrameController>(compositor.get());
begin_frame_source = external_begin_frame_controller->begin_frame_source();
} else if (!disable_display_vsync_) {
if (gpu_vsync_control && IsGpuVSyncSignalSupported()) {
gpu_vsync_begin_frame_source =
base::MakeUnique<GpuVSyncBeginFrameSource>(gpu_vsync_control);
begin_frame_source = gpu_vsync_begin_frame_source.get();
} else {
synthetic_begin_frame_source =
base::MakeUnique<viz::BackToBackBeginFrameSource>(
base::MakeUnique<viz::DelayBasedBeginFrameSource>(
base::MakeUnique<viz::DelayBasedTimeSource>(
compositor->task_runner().get()));
begin_frame_source = synthetic_begin_frame_source.get();
}
} else {
synthetic_begin_frame_source =
base::MakeUnique<viz::BackToBackBeginFrameSource>(
base::MakeUnique<viz::DelayBasedTimeSource>(
compositor->task_runner().get()));
begin_frame_source = synthetic_begin_frame_source.get();
}
#if defined(OS_WIN)
......@@ -593,11 +631,16 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
} else if (data->gpu_vsync_begin_frame_source) {
GetFrameSinkManager()->UnregisterBeginFrameSource(
data->gpu_vsync_begin_frame_source.get());
} else if (data->external_begin_frame_controller) {
GetFrameSinkManager()->UnregisterBeginFrameSource(
data->external_begin_frame_controller->begin_frame_source());
data->display->RemoveObserver(data->external_begin_frame_controller.get());
}
auto scheduler = base::MakeUnique<viz::DisplayScheduler>(
begin_frame_source, compositor->task_runner().get(),
display_output_surface->capabilities().max_frames_pending);
display_output_surface->capabilities().max_frames_pending,
wait_for_all_pipeline_stages_before_draw_);
// The Display owns and uses the |display_output_surface| created above.
data->display = base::MakeUnique<viz::Display>(
......@@ -612,6 +655,11 @@ void GpuProcessTransportFactory::EstablishedGpuChannel(
// until we have reset |data->display|.
data->synthetic_begin_frame_source = std::move(synthetic_begin_frame_source);
data->gpu_vsync_begin_frame_source = std::move(gpu_vsync_begin_frame_source);
data->external_begin_frame_controller =
std::move(external_begin_frame_controller);
if (data->external_begin_frame_controller)
data->display->AddObserver(data->external_begin_frame_controller.get());
// The |delegated_output_surface| is given back to the compositor, it
// delegates to the Display as its root surface. Importantly, it shares the
......@@ -673,6 +721,10 @@ void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
} else if (data->gpu_vsync_begin_frame_source) {
GetFrameSinkManager()->UnregisterBeginFrameSource(
data->gpu_vsync_begin_frame_source.get());
} else if (data->external_begin_frame_controller) {
GetFrameSinkManager()->UnregisterBeginFrameSource(
data->external_begin_frame_controller->begin_frame_source());
data->display->RemoveObserver(data->external_begin_frame_controller.get());
}
per_compositor_data_.erase(it);
if (per_compositor_data_.empty()) {
......@@ -797,6 +849,18 @@ void GpuProcessTransportFactory::SetDisplayVSyncParameters(
}
}
void GpuProcessTransportFactory::IssueExternalBeginFrame(
ui::Compositor* compositor,
const viz::BeginFrameArgs& args) {
PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
if (it == per_compositor_data_.end())
return;
PerCompositorData* data = it->second.get();
DCHECK(data);
if (data->external_begin_frame_controller)
data->external_begin_frame_controller->IssueExternalBeginFrame(args);
}
void GpuProcessTransportFactory::SetOutputIsSecure(ui::Compositor* compositor,
bool secure) {
PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
......
......@@ -81,6 +81,8 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
void SetDisplayVSyncParameters(ui::Compositor* compositor,
base::TimeTicks timebase,
base::TimeDelta interval) override;
void IssueExternalBeginFrame(ui::Compositor* compositor,
const viz::BeginFrameArgs& args) override;
void SetOutputIsSecure(ui::Compositor* compositor, bool secure) override;
// ImageTransportFactory implementation.
......@@ -135,6 +137,7 @@ class GpuProcessTransportFactory : public ui::ContextFactory,
shared_worker_context_provider_;
bool disable_display_vsync_ = false;
bool wait_for_all_pipeline_stages_before_draw_ = false;
bool shared_vulkan_context_provider_initialized_ = false;
scoped_refptr<cc::VulkanInProcessContextProvider>
shared_vulkan_context_provider_;
......
......@@ -2598,6 +2598,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
cc::switches::kSlowDownRasterScaleFactor,
cc::switches::kBrowserControlsHideThreshold,
cc::switches::kBrowserControlsShowThreshold,
cc::switches::kRunAllCompositorStagesBeforeDraw,
switches::kEnableSurfaceReferences,
switches::kEnableSurfaceSynchronization,
......
......@@ -551,6 +551,9 @@ cc::LayerTreeSettings RenderWidgetCompositor::GenerateLayerTreeSettings(
settings.disallow_non_exact_resource_reuse =
cmd.HasSwitch(cc::switches::kDisallowNonExactResourceReuse);
settings.wait_for_all_pipeline_stages_before_draw =
cmd.HasSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw);
return settings;
}
......
......@@ -35,6 +35,7 @@ component("compositor") {
"debug_utils.h",
"dip_util.cc",
"dip_util.h",
"external_begin_frame_client.h",
"float_animation_curve_adapter.cc",
"float_animation_curve_adapter.h",
"layer.cc",
......
......@@ -43,6 +43,7 @@
#include "ui/compositor/compositor_switches.h"
#include "ui/compositor/compositor_vsync_manager.h"
#include "ui/compositor/dip_util.h"
#include "ui/compositor/external_begin_frame_client.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animator_collection.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
......@@ -58,12 +59,14 @@ Compositor::Compositor(const viz::FrameSinkId& frame_sink_id,
ui::ContextFactory* context_factory,
ui::ContextFactoryPrivate* context_factory_private,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
bool enable_surface_synchronization)
bool enable_surface_synchronization,
bool external_begin_frames_enabled)
: context_factory_(context_factory),
context_factory_private_(context_factory_private),
frame_sink_id_(frame_sink_id),
task_runner_(task_runner),
vsync_manager_(new CompositorVSyncManager()),
external_begin_frames_enabled_(external_begin_frames_enabled),
layer_animator_collection_(this),
scheduled_timeout_(base::TimeTicks()),
allow_locks_to_extend_timeout_(false),
......@@ -165,6 +168,9 @@ Compositor::Compositor(const viz::FrameSinkId& frame_sink_id,
settings.disallow_non_exact_resource_reuse =
command_line->HasSwitch(cc::switches::kDisallowNonExactResourceReuse);
settings.wait_for_all_pipeline_stages_before_draw =
command_line->HasSwitch(cc::switches::kRunAllCompositorStagesBeforeDraw);
base::TimeTicks before_create = base::TimeTicks::Now();
animation_host_ = cc::AnimationHost::CreateMainInstance();
......@@ -438,6 +444,34 @@ scoped_refptr<CompositorVSyncManager> Compositor::vsync_manager() const {
return vsync_manager_;
}
void Compositor::IssueExternalBeginFrame(const viz::BeginFrameArgs& args) {
DCHECK(external_begin_frames_enabled_);
if (context_factory_private_)
context_factory_private_->IssueExternalBeginFrame(this, args);
}
void Compositor::SetExternalBeginFrameClient(ExternalBeginFrameClient* client) {
DCHECK(external_begin_frames_enabled_);
external_begin_frame_client_ = client;
if (needs_external_begin_frames_)
external_begin_frame_client_->OnNeedsExternalBeginFrames(true);
}
void Compositor::OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) {
DCHECK(external_begin_frames_enabled_);
if (external_begin_frame_client_)
external_begin_frame_client_->OnDisplayDidFinishFrame(ack);
}
void Compositor::OnNeedsExternalBeginFrames(bool needs_begin_frames) {
DCHECK(external_begin_frames_enabled_);
if (external_begin_frame_client_) {
external_begin_frame_client_->OnNeedsExternalBeginFrames(
needs_begin_frames);
}
needs_external_begin_frames_ = needs_begin_frames;
}
void Compositor::AddObserver(CompositorObserver* observer) {
observer_list_.AddObserver(observer);
}
......
......@@ -69,6 +69,7 @@ namespace ui {
class Compositor;
class CompositorVSyncManager;
class ExternalBeginFrameClient;
class LatencyInfo;
class Layer;
class Reflector;
......@@ -133,6 +134,8 @@ class COMPOSITOR_EXPORT ContextFactoryPrivate {
virtual void SetDisplayVSyncParameters(ui::Compositor* compositor,
base::TimeTicks timebase,
base::TimeDelta interval) = 0;
virtual void IssueExternalBeginFrame(ui::Compositor* compositor,
const viz::BeginFrameArgs& args) = 0;
virtual void SetOutputIsSecure(Compositor* compositor, bool secure) = 0;
};
......@@ -188,7 +191,8 @@ class COMPOSITOR_EXPORT Compositor
ui::ContextFactory* context_factory,
ui::ContextFactoryPrivate* context_factory_private,
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
bool enable_surface_synchronization);
bool enable_surface_synchronization,
bool external_begin_frames_enabled = false);
~Compositor() override;
ui::ContextFactory* context_factory() { return context_factory_; }
......@@ -291,6 +295,24 @@ class COMPOSITOR_EXPORT Compositor
// Returns the vsync manager for this compositor.
scoped_refptr<CompositorVSyncManager> vsync_manager() const;
bool external_begin_frames_enabled() {
return external_begin_frames_enabled_;
}
void SetExternalBeginFrameClient(ExternalBeginFrameClient* client);
// The ExternalBeginFrameClient calls this to issue a BeginFrame with the
// given |args|.
void IssueExternalBeginFrame(const viz::BeginFrameArgs& args);
// Called by the ContextFactory when a BeginFrame was completed by the Display
// if the enable_external_begin_frames setting is true.
void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack);
// Called by the ContextFactory to signal whether BeginFrames are needed by
// the compositor if the enable_external_begin_frames setting is true.
void OnNeedsExternalBeginFrames(bool needs_begin_frames);
// Returns the main thread task runner this compositor uses. Users of the
// compositor generally shouldn't use this.
scoped_refptr<base::SingleThreadTaskRunner> task_runner() const {
......@@ -421,6 +443,10 @@ class COMPOSITOR_EXPORT Compositor
// The manager of vsync parameters for this compositor.
scoped_refptr<CompositorVSyncManager> vsync_manager_;
bool external_begin_frames_enabled_;
ExternalBeginFrameClient* external_begin_frame_client_ = nullptr;
bool needs_external_begin_frames_ = false;
// The device scale factor of the monitor that this compositor is compositing
// layers on.
float device_scale_factor_ = 0.f;
......
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CLIENT_H_
#define UI_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CLIENT_H_
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "ui/compositor/compositor_export.h"
namespace ui {
class COMPOSITOR_EXPORT ExternalBeginFrameClient {
public:
virtual ~ExternalBeginFrameClient() {}
virtual void OnDisplayDidFinishFrame(const viz::BeginFrameAck& ack) = 0;
virtual void OnNeedsExternalBeginFrames(bool needs_begin_frames) = 0;
};
} // namespace ui
#endif // UI_COMPOSITOR_EXTERNAL_BEGIN_FRAME_CLIENT_H_
......@@ -83,6 +83,8 @@ class InProcessContextFactory : public ContextFactory,
void SetDisplayVSyncParameters(ui::Compositor* compositor,
base::TimeTicks timebase,
base::TimeDelta interval) override {}
void IssueExternalBeginFrame(ui::Compositor* compositor,
const viz::BeginFrameArgs& args) override {}
void SetOutputIsSecure(ui::Compositor* compositor, bool secure) override {}
const viz::ResourceSettings& GetResourceSettings() const override;
void AddObserver(ContextFactoryObserver* observer) override;
......
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