Skip to content

Commit

Permalink
Hook up ui::Compositor to Display's BeginFrameSource
Browse files Browse the repository at this point in the history
This hooks up the first SurfaceFactoryClient to the real
BeginFrameSource owned by the OnScreenDisplayClient.  This is done by
adding an OutputSurfaceClient::SetBeginFrameSource method.  As the
SurfaceDisplayOutputSurface is also a SurfaceFactoryClient, it can hand
the real begin frame source directly to ui::Compositor's scheduler.

This allows the removal of some of the browser vsync plumbing, but not
all of it.  Once the renderer compositors have been hooked up to use
this path as well, then this and all of the VSyncObserver code can be
ripped out.

The BeginFrameSource is created by the BrowserCompositorOutputSurface
which updates it based on vsync information that it receives.  This
BeginFrameSource is passed to the Display (via OutputSurfaceClient),
which informs the SurfaceManager that the compositor using
that Display should be driven by that BeginFrameSource.  The
SurfaceManager then informs the SurfaceDisplayOutputSurface about
the BeginFrameSource, which passes it into the single thread proxy's
cc::Scheduler for that ui::Compositor's instance.  Plumbing!

The path from SurfaceManager to SurfaceDisplayOutputSurface was
added in https://codereview.chromium.org/1673783004, but the rest
of the plumbing is new to this patch.

CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel

Review URL: https://codereview.chromium.org/1821863002

Cr-Commit-Position: refs/heads/master@{#387228}
  • Loading branch information
quisquous authored and Commit bot committed Apr 14, 2016
1 parent 825f706 commit 19c1085
Show file tree
Hide file tree
Showing 57 changed files with 482 additions and 294 deletions.
3 changes: 2 additions & 1 deletion android_webview/browser/hardware_renderer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ HardwareRenderer::HardwareRenderer(RenderThreadManager* state)
surface_manager_->RegisterSurfaceFactoryClient(
surface_id_allocator_->id_namespace(), this);
display_.reset(new cc::Display(this, surface_manager_.get(), nullptr, nullptr,
settings));
settings,
surface_id_allocator_->id_namespace()));
}

HardwareRenderer::~HardwareRenderer() {
Expand Down
2 changes: 0 additions & 2 deletions android_webview/browser/hardware_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ class HardwareRenderer : public cc::DisplayClient,

private:
// cc::DisplayClient overrides.
void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) override {}
void OutputSurfaceLost() override {}
void SetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override {}

Expand Down
11 changes: 0 additions & 11 deletions cc/output/output_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -189,17 +189,6 @@ OutputSurface::OutputSurface(
std::move(software_device)) {
}

void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) {
TRACE_EVENT2("cc",
"OutputSurface::CommitVSyncParameters",
"timebase",
(timebase - base::TimeTicks()).InSecondsF(),
"interval",
interval.InSecondsF());
client_->CommitVSyncParameters(timebase, interval);
}

// Forwarded to OutputSurfaceClient
void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
Expand Down
3 changes: 0 additions & 3 deletions cc/output/output_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,6 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider {
bool has_alpha_;
base::ThreadChecker client_thread_checker_;

void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval);

void SetNeedsRedrawRect(const gfx::Rect& damage_rect);
void ReclaimResources(const CompositorFrameAck* ack);
void SetExternalStencilTest(bool enabled);
Expand Down
9 changes: 8 additions & 1 deletion cc/output/output_surface_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@ class Transform;

namespace cc {

class BeginFrameSource;
class CompositorFrameAck;
struct ManagedMemoryPolicy;

class CC_EXPORT OutputSurfaceClient {
public:
// TODO(enne): Remove this in favor of using SetBeginFrameSource.
virtual void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) = 0;
// Pass the begin frame source for the client to observe. Client does not own
// the BeginFrameSource. OutputSurface should call this once after binding to
// the client and then call again with a null while detaching.
virtual void SetBeginFrameSource(BeginFrameSource* source) = 0;

virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) = 0;
virtual void DidSwapBuffers() = 0;
virtual void DidSwapBuffersComplete() = 0;
Expand All @@ -39,7 +46,7 @@ class CC_EXPORT OutputSurfaceClient {
// valid for the lifetime of the OutputSurfaceClient or until unregisted --
// use SetTreeActivationCallback(base::Closure()) to unregister it.
virtual void SetTreeActivationCallback(const base::Closure& callback) = 0;
// This allows the output surface to ask it's client for a draw.
// This allows the output surface to ask its client for a draw.
virtual void OnDraw(const gfx::Transform& transform,
const gfx::Rect& viewport,
const gfx::Rect& clip,
Expand Down
5 changes: 0 additions & 5 deletions cc/output/output_surface_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ class TestOutputSurface : public OutputSurface {
client_->DidSwapBuffersComplete();
}

void CommitVSyncParametersForTesting(base::TimeTicks timebase,
base::TimeDelta interval) {
CommitVSyncParameters(timebase, interval);
}

void DidSwapBuffersForTesting() { client_->DidSwapBuffers(); }

void OnSwapBuffersCompleteForTesting() { client_->DidSwapBuffersComplete(); }
Expand Down
88 changes: 69 additions & 19 deletions cc/surfaces/display.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,50 +24,94 @@
#include "gpu/command_buffer/client/gles2_interface.h"
#include "ui/gfx/buffer_types.h"

namespace {

class EmptyBeginFrameSource : public cc::BeginFrameSource {
public:
void DidFinishFrame(size_t remaining_frames) override{};
void AddObserver(cc::BeginFrameObserver* obs) override{};
void RemoveObserver(cc::BeginFrameObserver* obs) override{};
void AsValueInto(base::trace_event::TracedValue* dict) const override{};
};

} // namespace

namespace cc {

Display::Display(DisplayClient* client,
SurfaceManager* manager,
SharedBitmapManager* bitmap_manager,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
const RendererSettings& settings)
const RendererSettings& settings,
uint32_t compositor_surface_namespace)
: client_(client),
manager_(manager),
surface_manager_(manager),
bitmap_manager_(bitmap_manager),
gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
settings_(settings),
compositor_surface_namespace_(compositor_surface_namespace),
device_scale_factor_(1.f),
swapped_since_resize_(false),
scheduler_(nullptr),
vsync_begin_frame_source_(nullptr),
observed_begin_frame_source_(nullptr),
texture_mailbox_deleter_(new TextureMailboxDeleter(nullptr)) {
manager_->AddObserver(this);
surface_manager_->AddObserver(this);
}

Display::~Display() {
manager_->RemoveObserver(this);
if (observed_begin_frame_source_)
surface_manager_->UnregisterBeginFrameSource(observed_begin_frame_source_);
surface_manager_->RemoveObserver(this);
if (aggregator_) {
for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
Surface* surface = manager_->GetSurfaceForId(id_entry.first);
Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first);
if (surface)
surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED);
}
}
}

void Display::CreateScheduler(base::SingleThreadTaskRunner* task_runner) {
DCHECK(!scheduler_);
if (!task_runner) {
// WebView doesn't have a task runner or a real begin frame source,
// so just create something fake here.
internal_begin_frame_source_.reset(new EmptyBeginFrameSource());
vsync_begin_frame_source_ = internal_begin_frame_source_.get();
observed_begin_frame_source_ = vsync_begin_frame_source_;
} else {
DCHECK(vsync_begin_frame_source_);

observed_begin_frame_source_ = vsync_begin_frame_source_;
if (settings_.disable_display_vsync) {
internal_begin_frame_source_.reset(
new BackToBackBeginFrameSource(task_runner));
observed_begin_frame_source_ = internal_begin_frame_source_.get();
}
}

scheduler_.reset(
new DisplayScheduler(this, observed_begin_frame_source_, task_runner,
output_surface_->capabilities().max_frames_pending));
surface_manager_->RegisterBeginFrameSource(observed_begin_frame_source_,
compositor_surface_namespace_);
}

bool Display::Initialize(std::unique_ptr<OutputSurface> output_surface,
DisplayScheduler* scheduler) {
// TODO(enne): register/unregister BeginFrameSource with SurfaceManager here.
base::SingleThreadTaskRunner* task_runner) {
output_surface_ = std::move(output_surface);
scheduler_ = scheduler;
return output_surface_->BindToClient(this);
if (!output_surface_->BindToClient(this))
return false;
CreateScheduler(task_runner);
return true;
}

void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) {
DCHECK_EQ(id.id_namespace(), compositor_surface_namespace_);
if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor)
return;

TRACE_EVENT0("cc", "Display::SetSurfaceId");

current_surface_id_ = id;
device_scale_factor_ = device_scale_factor;

Expand Down Expand Up @@ -136,8 +180,8 @@ void Display::InitializeRenderer() {
// overlays.
bool output_partial_list = renderer_->Capabilities().using_partial_swap &&
!output_surface_->GetOverlayCandidateValidator();
aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get(),
output_partial_list));
aggregator_.reset(new SurfaceAggregator(
surface_manager_, resource_provider_.get(), output_partial_list));
}

void Display::DidLoseOutputSurface() {
Expand All @@ -149,7 +193,7 @@ void Display::DidLoseOutputSurface() {
}

void Display::UpdateRootSurfaceResourcesLocked() {
Surface* surface = manager_->GetSurfaceForId(current_surface_id_);
Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_);
bool root_surface_resources_locked = !surface || !surface->GetEligibleFrame();
if (scheduler_)
scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked);
Expand Down Expand Up @@ -179,7 +223,7 @@ bool Display::DrawAndSwap() {

// Run callbacks early to allow pipelining.
for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
Surface* surface = manager_->GetSurfaceForId(id_entry.first);
Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first);
if (surface)
surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN);
}
Expand Down Expand Up @@ -277,9 +321,15 @@ void Display::DidSwapBuffersComplete() {
renderer_->SwapBuffersComplete();
}

void Display::CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) {
client_->CommitVSyncParameters(timebase, interval);
void Display::SetBeginFrameSource(BeginFrameSource* source) {
// It's expected that there's only a single source from the
// BrowserCompositorOutputSurface that corresponds to vsync. The BFS is
// passed BrowserCompositorOutputSurface -> Display -> DisplayScheduler as an
// input. DisplayScheduler makes a decision about which BFS to use and
// calls back to Display as DisplaySchedulerClient to register for that
// surface id.
DCHECK(!vsync_begin_frame_source_);
vsync_begin_frame_source_ = source;
}

void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
Expand Down Expand Up @@ -321,7 +371,7 @@ void Display::SetFullRootLayerDamage() {
void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) {
if (aggregator_ &&
aggregator_->previous_contained_surfaces().count(surface_id)) {
Surface* surface = manager_->GetSurfaceForId(surface_id);
Surface* surface = surface_manager_->GetSurfaceForId(surface_id);
if (surface) {
const CompositorFrame* current_frame = surface->GetEligibleFrame();
if (!current_frame || !current_frame->delegated_frame_data ||
Expand Down
25 changes: 19 additions & 6 deletions cc/surfaces/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient,
SurfaceManager* manager,
SharedBitmapManager* bitmap_manager,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
const RendererSettings& settings);
const RendererSettings& settings,
uint32_t compositor_surface_namespace);
~Display() override;

bool Initialize(std::unique_ptr<OutputSurface> output_surface,
DisplayScheduler* scheduler);
base::SingleThreadTaskRunner* task_runner);

// device_scale_factor is used to communicate to the external window system
// what scale this was rendered at.
Expand All @@ -74,7 +75,8 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient,

// OutputSurfaceClient implementation.
void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) override;
base::TimeDelta interval) override {}
void SetBeginFrameSource(BeginFrameSource* source) override;
void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override;
void DidSwapBuffers() override;
void DidSwapBuffersComplete() override;
Expand All @@ -96,28 +98,39 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient,
// SurfaceDamageObserver implementation.
void OnSurfaceDamaged(SurfaceId surface, bool* changed) override;

private:
protected:
// Virtual for tests.
virtual void CreateScheduler(base::SingleThreadTaskRunner* task_runner);

void InitializeRenderer();
void UpdateRootSurfaceResourcesLocked();

DisplayClient* client_;
SurfaceManager* manager_;
SurfaceManager* surface_manager_;
SharedBitmapManager* bitmap_manager_;
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
RendererSettings settings_;
SurfaceId current_surface_id_;
uint32_t compositor_surface_namespace_;
gfx::Size current_surface_size_;
float device_scale_factor_;
bool swapped_since_resize_;
gfx::Rect external_clip_;
std::unique_ptr<OutputSurface> output_surface_;
DisplayScheduler* scheduler_;
// An internal synthetic BFS. May be null when not used.
std::unique_ptr<BeginFrameSource> internal_begin_frame_source_;
// The real BFS tied to vsync provided by the BrowserCompositorOutputSurface.
BeginFrameSource* vsync_begin_frame_source_;
// The current BFS driving the Display/DisplayScheduler.
BeginFrameSource* observed_begin_frame_source_;
std::unique_ptr<DisplayScheduler> scheduler_;
std::unique_ptr<ResourceProvider> resource_provider_;
std::unique_ptr<SurfaceAggregator> aggregator_;
std::unique_ptr<DirectRenderer> renderer_;
std::unique_ptr<TextureMailboxDeleter> texture_mailbox_deleter_;
std::vector<ui::LatencyInfo> stored_latency_info_;

private:
DISALLOW_COPY_AND_ASSIGN(Display);
};

Expand Down
3 changes: 1 addition & 2 deletions cc/surfaces/display_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@

namespace cc {

class BeginFrameSource;
struct ManagedMemoryPolicy;

class DisplayClient {
public:
virtual void CommitVSyncParameters(base::TimeTicks timebase,
base::TimeDelta interval) = 0;
virtual void OutputSurfaceLost() = 0;
virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) = 0;

Expand Down
4 changes: 0 additions & 4 deletions cc/surfaces/display_scheduler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ DisplayScheduler::DisplayScheduler(DisplaySchedulerClient* client,
weak_ptr_factory_(this) {
begin_frame_deadline_closure_ = base::Bind(
&DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr());

// TODO(tansell): Set this to something useful.
begin_frame_source_for_children_.reset(new SyntheticBeginFrameSource(
task_runner, BeginFrameArgs::DefaultInterval()));
}

DisplayScheduler::~DisplayScheduler() {
Expand Down
8 changes: 1 addition & 7 deletions cc/surfaces/display_scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "cc/output/renderer_settings.h"
#include "cc/scheduler/begin_frame_source.h"
#include "cc/surfaces/surface_id.h"
#include "cc/surfaces/surfaces_export.h"
Expand Down Expand Up @@ -50,10 +51,6 @@ class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase {
bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override;
void OnBeginFrameSourcePausedChanged(bool paused) override;

BeginFrameSource* begin_frame_source_for_children() {
return begin_frame_source_for_children_.get();
}

protected:
base::TimeTicks DesiredBeginFrameDeadlineTime();
virtual void ScheduleBeginFrameDeadline();
Expand All @@ -70,9 +67,6 @@ class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase {
base::CancelableClosure begin_frame_deadline_task_;
base::TimeTicks begin_frame_deadline_task_time_;

// TODO(tansell): Set this to something useful.
std::unique_ptr<BeginFrameSource> begin_frame_source_for_children_;

bool output_surface_lost_;
bool root_surface_resources_locked_;

Expand Down
Loading

0 comments on commit 19c1085

Please sign in to comment.