forked from Pissandshittium/pissandshittium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract non-Mojo bits of GpuCompositorFrameSink to CompositorFrameSin…
…kSupport We would like to have all Chrome clients use a single service-side CompositorFrameSink implementation as an incremental step towards pulling the display compositor into the gpu process. This CL extract non-mojo-specific code from GpuCompositorFrameSink in services/ui to CompositorFrameSinkSupport in a central place: cc/surfaces that can be used by Chrome today. Individual clients can transition to mojo after we carefully measure the performance impact of the transition. BUG=668126, 657959 CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel Review-Url: https://codereview.chromium.org/2543373002 Cr-Commit-Position: refs/heads/master@{#436148}
- Loading branch information
fsamuel
authored and
Commit bot
committed
Dec 3, 2016
1 parent
abbafbc
commit 932aa65
Showing
6 changed files
with
356 additions
and
188 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
// Copyright 2016 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. | ||
|
||
#include "cc/surfaces/compositor_frame_sink_support.h" | ||
|
||
#include "cc/output/compositor_frame.h" | ||
#include "cc/scheduler/begin_frame_source.h" | ||
#include "cc/surfaces/compositor_frame_sink_support_client.h" | ||
#include "cc/surfaces/display.h" | ||
#include "cc/surfaces/surface_manager.h" | ||
|
||
namespace cc { | ||
|
||
CompositorFrameSinkSupport::CompositorFrameSinkSupport( | ||
CompositorFrameSinkSupportClient* client, | ||
SurfaceManager* surface_manager, | ||
const FrameSinkId& frame_sink_id, | ||
std::unique_ptr<Display> display) | ||
: client_(client), | ||
surface_manager_(surface_manager), | ||
frame_sink_id_(frame_sink_id), | ||
display_(std::move(display)), | ||
surface_factory_(frame_sink_id_, surface_manager_, this), | ||
weak_factory_(this) { | ||
surface_manager_->RegisterFrameSinkId(frame_sink_id_); | ||
surface_manager_->RegisterSurfaceFactoryClient(frame_sink_id_, this); | ||
|
||
if (display_) { | ||
display_->Initialize(this, surface_manager_); | ||
display_->SetVisible(true); | ||
} | ||
} | ||
|
||
CompositorFrameSinkSupport::~CompositorFrameSinkSupport() { | ||
// SurfaceFactory's destructor will attempt to return resources which will | ||
// call back into here and access |client_| so we should destroy | ||
// |surface_factory_|'s resources early on. | ||
surface_factory_.EvictSurface(); | ||
surface_manager_->UnregisterSurfaceFactoryClient(frame_sink_id_); | ||
surface_manager_->InvalidateFrameSinkId(frame_sink_id_); | ||
} | ||
|
||
void CompositorFrameSinkSupport::EvictFrame() { | ||
surface_factory_.EvictSurface(); | ||
} | ||
|
||
void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) { | ||
needs_begin_frame_ = needs_begin_frame; | ||
UpdateNeedsBeginFramesInternal(); | ||
} | ||
|
||
void CompositorFrameSinkSupport::SubmitCompositorFrame( | ||
const LocalFrameId& local_frame_id, | ||
CompositorFrame frame) { | ||
if (local_frame_id_ != local_frame_id) { | ||
local_frame_id_ = local_frame_id; | ||
if (display_ && !frame.render_pass_list.empty()) { | ||
gfx::Size frame_size = frame.render_pass_list[0]->output_rect.size(); | ||
// TODO(piman, fsamuel): We will likely want to revisit this because some | ||
// clients may want finer control over the Display sizing - since it | ||
// really means the actual size of the native window (Linux/Win Aura) or | ||
// display (Ozone). We may need to either prevent or gutter Display frames | ||
// until there is a correctly-sized top-level CompositorFrame available | ||
// (see ui::Compositor::DisableSwapUntilResize). We might want to resize | ||
// Display earlier. | ||
display_->Resize(frame_size); | ||
} | ||
} | ||
++ack_pending_count_; | ||
surface_factory_.SubmitCompositorFrame( | ||
local_frame_id_, std::move(frame), | ||
base::Bind(&CompositorFrameSinkSupport::DidReceiveCompositorFrameAck, | ||
weak_factory_.GetWeakPtr())); | ||
if (display_) { | ||
display_->SetLocalFrameId(local_frame_id_, | ||
frame.metadata.device_scale_factor); | ||
} | ||
} | ||
|
||
void CompositorFrameSinkSupport::DidReceiveCompositorFrameAck() { | ||
DCHECK_GT(ack_pending_count_, 0); | ||
ack_pending_count_--; | ||
|
||
if (!client_) | ||
return; | ||
client_->DidReceiveCompositorFrameAck(); | ||
if (!surface_returned_resources_.empty()) { | ||
client_->ReclaimResources(surface_returned_resources_); | ||
surface_returned_resources_.clear(); | ||
} | ||
} | ||
|
||
void CompositorFrameSinkSupport::AddChildFrameSink( | ||
const FrameSinkId& child_frame_sink_id) { | ||
surface_manager_->RegisterFrameSinkHierarchy(frame_sink_id_, | ||
child_frame_sink_id); | ||
} | ||
|
||
void CompositorFrameSinkSupport::RemoveChildFrameSink( | ||
const FrameSinkId& child_frame_sink_id) { | ||
surface_manager_->UnregisterFrameSinkHierarchy(frame_sink_id_, | ||
child_frame_sink_id); | ||
} | ||
|
||
void CompositorFrameSinkSupport::DisplayOutputSurfaceLost() {} | ||
|
||
void CompositorFrameSinkSupport::DisplayWillDrawAndSwap( | ||
bool will_draw_and_swap, | ||
const RenderPassList& render_passes) {} | ||
|
||
void CompositorFrameSinkSupport::DisplayDidDrawAndSwap() {} | ||
|
||
void CompositorFrameSinkSupport::ReturnResources( | ||
const ReturnedResourceArray& resources) { | ||
if (resources.empty()) | ||
return; | ||
|
||
if (!ack_pending_count_ && client_) { | ||
client_->ReclaimResources(resources); | ||
return; | ||
} | ||
|
||
std::copy(resources.begin(), resources.end(), | ||
std::back_inserter(surface_returned_resources_)); | ||
} | ||
|
||
void CompositorFrameSinkSupport::SetBeginFrameSource( | ||
BeginFrameSource* begin_frame_source) { | ||
if (begin_frame_source_ && added_frame_observer_) { | ||
begin_frame_source_->RemoveObserver(this); | ||
added_frame_observer_ = false; | ||
} | ||
begin_frame_source_ = begin_frame_source; | ||
UpdateNeedsBeginFramesInternal(); | ||
} | ||
|
||
void CompositorFrameSinkSupport::WillDrawSurface( | ||
const LocalFrameId& local_frame_id, | ||
const gfx::Rect& damage_rect) { | ||
if (client_) | ||
client_->WillDrawSurface(); | ||
} | ||
|
||
void CompositorFrameSinkSupport::OnBeginFrame(const BeginFrameArgs& args) { | ||
UpdateNeedsBeginFramesInternal(); | ||
last_begin_frame_args_ = args; | ||
if (client_) | ||
client_->OnBeginFrame(args); | ||
} | ||
|
||
const BeginFrameArgs& CompositorFrameSinkSupport::LastUsedBeginFrameArgs() | ||
const { | ||
return last_begin_frame_args_; | ||
} | ||
|
||
void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {} | ||
|
||
void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() { | ||
if (!begin_frame_source_) | ||
return; | ||
|
||
if (needs_begin_frame_ == added_frame_observer_) | ||
return; | ||
|
||
added_frame_observer_ = needs_begin_frame_; | ||
if (needs_begin_frame_) | ||
begin_frame_source_->AddObserver(this); | ||
else | ||
begin_frame_source_->RemoveObserver(this); | ||
} | ||
|
||
} // namespace cc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright 2016 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 CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_H_ | ||
#define CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_H_ | ||
|
||
#include "base/compiler_specific.h" | ||
#include "base/memory/weak_ptr.h" | ||
#include "cc/output/compositor_frame.h" | ||
#include "cc/scheduler/begin_frame_source.h" | ||
#include "cc/surfaces/display.h" | ||
#include "cc/surfaces/display_client.h" | ||
#include "cc/surfaces/surface_factory.h" | ||
#include "cc/surfaces/surface_factory_client.h" | ||
#include "cc/surfaces/surfaces_export.h" | ||
|
||
namespace cc { | ||
|
||
class CompositorFrameSinkSupportClient; | ||
class Display; | ||
class SurfaceManager; | ||
|
||
class CC_SURFACES_EXPORT CompositorFrameSinkSupport | ||
: public NON_EXPORTED_BASE(DisplayClient), | ||
public SurfaceFactoryClient, | ||
public BeginFrameObserver { | ||
public: | ||
CompositorFrameSinkSupport(CompositorFrameSinkSupportClient* client, | ||
SurfaceManager* surface_manager, | ||
const FrameSinkId& frame_sink_id, | ||
std::unique_ptr<Display> display); | ||
|
||
~CompositorFrameSinkSupport() override; | ||
|
||
const FrameSinkId& frame_sink_id() const { return frame_sink_id_; } | ||
|
||
void EvictFrame(); | ||
void SetNeedsBeginFrame(bool needs_begin_frame); | ||
void SubmitCompositorFrame(const LocalFrameId& local_frame_id, | ||
CompositorFrame frame); | ||
void AddChildFrameSink(const FrameSinkId& child_frame_sink_id); | ||
void RemoveChildFrameSink(const FrameSinkId& child_frame_sink_id); | ||
|
||
private: | ||
void DidReceiveCompositorFrameAck(); | ||
|
||
// DisplayClient implementation. | ||
void DisplayOutputSurfaceLost() override; | ||
void DisplayWillDrawAndSwap(bool will_draw_and_swap, | ||
const RenderPassList& render_passes) override; | ||
void DisplayDidDrawAndSwap() override; | ||
|
||
// SurfaceFactoryClient implementation. | ||
void ReturnResources(const ReturnedResourceArray& resources) override; | ||
void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override; | ||
void WillDrawSurface(const LocalFrameId& local_frame_id, | ||
const gfx::Rect& damage_rect) override; | ||
|
||
// BeginFrameObserver implementation. | ||
void OnBeginFrame(const BeginFrameArgs& args) override; | ||
const BeginFrameArgs& LastUsedBeginFrameArgs() const override; | ||
void OnBeginFrameSourcePausedChanged(bool paused) override; | ||
|
||
void UpdateNeedsBeginFramesInternal(); | ||
|
||
CompositorFrameSinkSupportClient* const client_; | ||
|
||
SurfaceManager* const surface_manager_; | ||
|
||
const FrameSinkId frame_sink_id_; | ||
|
||
// GpuCompositorFrameSink holds a Display if it created with | ||
// non-null gpu::SurfaceHandle. In the window server, the display root | ||
// window's CompositorFrameSink will have a valid gpu::SurfaceHandle. | ||
std::unique_ptr<Display> display_; | ||
|
||
LocalFrameId local_frame_id_; | ||
SurfaceFactory surface_factory_; | ||
// Counts the number of CompositorFrames that have been submitted and have not | ||
// yet received an ACK. | ||
int ack_pending_count_ = 0; | ||
ReturnedResourceArray surface_returned_resources_; | ||
|
||
// The begin frame source being observered. Null if none. | ||
BeginFrameSource* begin_frame_source_ = nullptr; | ||
|
||
// The last begin frame args generated by the begin frame source. | ||
BeginFrameArgs last_begin_frame_args_; | ||
|
||
// Whether a request for begin frames has been issued. | ||
bool needs_begin_frame_ = false; | ||
|
||
// Whether or not a frame observer has been added. | ||
bool added_frame_observer_ = false; | ||
|
||
base::WeakPtrFactory<CompositorFrameSinkSupport> weak_factory_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(CompositorFrameSinkSupport); | ||
}; | ||
|
||
} // namespace cc | ||
|
||
#endif // CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright 2016 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 CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_ | ||
#define CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_ | ||
|
||
#include "cc/resources/returned_resource.h" | ||
|
||
namespace cc { | ||
|
||
struct BeginFrameArgs; | ||
|
||
class CompositorFrameSinkSupportClient { | ||
public: | ||
// Notification that the previous CompositorFrame given to | ||
// SubmitCompositorFrame() has been processed and that another frame | ||
// can be submitted. This provides backpressure from the display compositor | ||
// so that frames are submitted only at the rate it can handle them. | ||
// TODO(fsamuel): This method ought not be necessary with unified BeginFrame. | ||
// However, there's a fair amount of cleanup and refactoring necessary to get | ||
// rid of it. | ||
virtual void DidReceiveCompositorFrameAck() = 0; | ||
|
||
// Notification for the client to generate a CompositorFrame. | ||
virtual void OnBeginFrame(const BeginFrameArgs& args) = 0; | ||
|
||
// Returns resources sent to SubmitCompositorFrame to be reused or freed. | ||
virtual void ReclaimResources(const ReturnedResourceArray& resources) = 0; | ||
|
||
// Called when surface is being scheduled for a draw. | ||
virtual void WillDrawSurface() = 0; | ||
|
||
protected: | ||
virtual ~CompositorFrameSinkSupportClient() {} | ||
}; | ||
|
||
} // namespace cc | ||
|
||
#endif // CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_ |
Oops, something went wrong.