Commit 8c15fc3e authored by eseckler's avatar eseckler Committed by Commit bot

[android] Make RWHVAndroid a BeginFrameObserver.

Instead of directly observing the Window's vsyncs, RWHVAndroid now
observes a BeginFrameSource provided by the DelegatedFrameHost (clank)
or WindowAndroid (webview). To enable this, the BeginFrameSource
originally provided by CompositorImpl moves into WindowAndroid.

The patch also makes some changes to the BeginFrameSource's observer
iteration that are necessary to support
SynchronousBrowserCompositorFilter.

BUG=401336, 675289

Committed: https://crrev.com/1a6bd5037fc10e45646715d675e63146d23fc28d
Review-Url: https://codereview.chromium.org/2564403002
Cr-Original-Commit-Position: refs/heads/master@{#439072}
Cr-Commit-Position: refs/heads/master@{#439877}
parent 4e0ae774
...@@ -45,7 +45,7 @@ void SynchronousCompositorBrowserFilter::SyncStateAfterVSync( ...@@ -45,7 +45,7 @@ void SynchronousCompositorBrowserFilter::SyncStateAfterVSync(
if (window_android_in_vsync_) if (window_android_in_vsync_)
return; return;
window_android_in_vsync_ = window_android; window_android_in_vsync_ = window_android;
window_android_in_vsync_->AddObserver(this); window_android_in_vsync_->GetBeginFrameSource()->AddObserver(this);
} }
bool SynchronousCompositorBrowserFilter::OnMessageReceived( bool SynchronousCompositorBrowserFilter::OnMessageReceived(
...@@ -177,30 +177,13 @@ void SynchronousCompositorBrowserFilter::SignalAllFutures() { ...@@ -177,30 +177,13 @@ void SynchronousCompositorBrowserFilter::SignalAllFutures() {
filter_ready_ = false; filter_ready_ = false;
} }
void SynchronousCompositorBrowserFilter::OnCompositingDidCommit() { void SynchronousCompositorBrowserFilter::OnBeginFrame(
NOTREACHED(); const cc::BeginFrameArgs& args) {
} // This is called after DidSendBeginFrame for all SynchronousCompositorHosts
void SynchronousCompositorBrowserFilter::OnRootWindowVisibilityChanged(
bool visible) {
NOTREACHED();
}
void SynchronousCompositorBrowserFilter::OnAttachCompositor() {
NOTREACHED();
}
void SynchronousCompositorBrowserFilter::OnDetachCompositor() {
NOTREACHED();
}
void SynchronousCompositorBrowserFilter::OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) {
// This is called after DidSendBeginFrame for SynchronousCompositorHosts
// belonging to this WindowAndroid, since this is added as an Observer after // belonging to this WindowAndroid, since this is added as an Observer after
// the observer iteration has started. // the observer iteration has started.
DCHECK(window_android_in_vsync_); DCHECK(window_android_in_vsync_);
window_android_in_vsync_->RemoveObserver(this); window_android_in_vsync_->GetBeginFrameSource()->RemoveObserver(this);
window_android_in_vsync_ = nullptr; window_android_in_vsync_ = nullptr;
std::vector<int> routing_ids; std::vector<int> routing_ids;
...@@ -229,12 +212,18 @@ void SynchronousCompositorBrowserFilter::OnVSync(base::TimeTicks frame_time, ...@@ -229,12 +212,18 @@ void SynchronousCompositorBrowserFilter::OnVSync(base::TimeTicks frame_time,
compositor_host_pending_renderer_state_.clear(); compositor_host_pending_renderer_state_.clear();
} }
void SynchronousCompositorBrowserFilter::OnActivityStopped() { const cc::BeginFrameArgs&
SynchronousCompositorBrowserFilter::LastUsedBeginFrameArgs() const {
// Not called by the source since we add and remove ourselves during a single
// OnVSync() iteration.
NOTREACHED(); NOTREACHED();
return last_used_begin_frame_args_;
} }
void SynchronousCompositorBrowserFilter::OnActivityStarted() { void SynchronousCompositorBrowserFilter::OnBeginFrameSourcePausedChanged(
NOTREACHED(); bool paused) {
// The BeginFrameSources we listen to don't use this.
DCHECK(!paused);
} }
} // namespace content } // namespace content
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "cc/output/begin_frame_args.h"
#include "cc/output/compositor_frame_metadata.h" #include "cc/output/compositor_frame_metadata.h"
#include "cc/scheduler/begin_frame_source.h"
#include "content/public/browser/android/synchronous_compositor.h" #include "content/public/browser/android/synchronous_compositor.h"
#include "content/public/browser/browser_message_filter.h" #include "content/public/browser/browser_message_filter.h"
#include "ui/android/window_android_observer.h" #include "ui/android/window_android_observer.h"
...@@ -25,20 +27,15 @@ namespace content { ...@@ -25,20 +27,15 @@ namespace content {
class RenderProcessHost; class RenderProcessHost;
class SynchronousCompositorHost; class SynchronousCompositorHost;
class SynchronousCompositorBrowserFilter : public ui::WindowAndroidObserver, class SynchronousCompositorBrowserFilter : public cc::BeginFrameObserver,
public BrowserMessageFilter { public BrowserMessageFilter {
public: public:
explicit SynchronousCompositorBrowserFilter(int process_id); explicit SynchronousCompositorBrowserFilter(int process_id);
// WindowAndroidObserver overrides. // cc::BeginFrameObserver overrides.
void OnCompositingDidCommit() override; void OnBeginFrame(const cc::BeginFrameArgs& args) override;
void OnRootWindowVisibilityChanged(bool visible) override; const cc::BeginFrameArgs& LastUsedBeginFrameArgs() const override;
void OnAttachCompositor() override; void OnBeginFrameSourcePausedChanged(bool paused) override;
void OnDetachCompositor() override;
void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) override;
void OnActivityStopped() override;
void OnActivityStarted() override;
// BrowserMessageFilter overrides. // BrowserMessageFilter overrides.
bool OnMessageReceived(const IPC::Message& message) override; bool OnMessageReceived(const IPC::Message& message) override;
...@@ -70,6 +67,7 @@ class SynchronousCompositorBrowserFilter : public ui::WindowAndroidObserver, ...@@ -70,6 +67,7 @@ class SynchronousCompositorBrowserFilter : public ui::WindowAndroidObserver,
ui::WindowAndroid* window_android_in_vsync_ = nullptr; ui::WindowAndroid* window_android_in_vsync_ = nullptr;
std::vector<SynchronousCompositorHost*> std::vector<SynchronousCompositorHost*>
compositor_host_pending_renderer_state_; compositor_host_pending_renderer_state_;
cc::BeginFrameArgs last_used_begin_frame_args_;
// Only accessed on the UI thread. Note this is not a parallel map to // Only accessed on the UI thread. Note this is not a parallel map to
// |future_map_|. // |future_map_|.
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include "cc/output/vulkan_in_process_context_provider.h" #include "cc/output/vulkan_in_process_context_provider.h"
#include "cc/raster/single_thread_task_graph_runner.h" #include "cc/raster/single_thread_task_graph_runner.h"
#include "cc/resources/ui_resource_manager.h" #include "cc/resources/ui_resource_manager.h"
#include "cc/scheduler/begin_frame_source.h"
#include "cc/surfaces/direct_compositor_frame_sink.h" #include "cc/surfaces/direct_compositor_frame_sink.h"
#include "cc/surfaces/display.h" #include "cc/surfaces/display.h"
#include "cc/surfaces/display_scheduler.h" #include "cc/surfaces/display_scheduler.h"
...@@ -138,78 +137,6 @@ gpu::gles2::ContextCreationAttribHelper GetCompositorContextAttributes( ...@@ -138,78 +137,6 @@ gpu::gles2::ContextCreationAttribHelper GetCompositorContextAttributes(
return attributes; return attributes;
} }
class ExternalBeginFrameSource : public cc::BeginFrameSource,
public CompositorImpl::VSyncObserver {
public:
explicit ExternalBeginFrameSource(CompositorImpl* compositor)
: compositor_(compositor) {
compositor_->AddObserver(this);
}
~ExternalBeginFrameSource() override { compositor_->RemoveObserver(this); }
// cc::BeginFrameSource implementation.
void AddObserver(cc::BeginFrameObserver* obs) override;
void RemoveObserver(cc::BeginFrameObserver* obs) override;
void DidFinishFrame(cc::BeginFrameObserver* obs,
size_t remaining_frames) override {}
bool IsThrottled() const override { return true; }
// CompositorImpl::VSyncObserver implementation.
void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) override;
private:
CompositorImpl* const compositor_;
std::unordered_set<cc::BeginFrameObserver*> observers_;
cc::BeginFrameArgs last_begin_frame_args_;
};
void ExternalBeginFrameSource::AddObserver(cc::BeginFrameObserver* obs) {
DCHECK(obs);
DCHECK(observers_.find(obs) == observers_.end());
observers_.insert(obs);
obs->OnBeginFrameSourcePausedChanged(false);
compositor_->OnNeedsBeginFramesChange(true);
if (last_begin_frame_args_.IsValid()) {
// Send a MISSED begin frame if necessary.
cc::BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
if (!last_args.IsValid() ||
(last_begin_frame_args_.frame_time > last_args.frame_time)) {
last_begin_frame_args_.type = cc::BeginFrameArgs::MISSED;
// TODO(crbug.com/602485): A deadline doesn't make too much sense
// for a missed BeginFrame (the intention rather is 'immediately'),
// but currently the retro frame logic is very strict in discarding
// BeginFrames.
last_begin_frame_args_.deadline =
base::TimeTicks::Now() + last_begin_frame_args_.interval;
obs->OnBeginFrame(last_begin_frame_args_);
}
}
}
void ExternalBeginFrameSource::RemoveObserver(cc::BeginFrameObserver* obs) {
DCHECK(obs);
DCHECK(observers_.find(obs) != observers_.end());
observers_.erase(obs);
if (observers_.empty())
compositor_->OnNeedsBeginFramesChange(false);
}
void ExternalBeginFrameSource::OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) {
// frame time is in the past, so give the next vsync period as the deadline.
base::TimeTicks deadline = frame_time + vsync_period;
last_begin_frame_args_ =
cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
vsync_period, cc::BeginFrameArgs::NORMAL);
std::unordered_set<cc::BeginFrameObserver*> observers(observers_);
for (auto* obs : observers)
obs->OnBeginFrame(last_begin_frame_args_);
}
class AndroidOutputSurface : public cc::OutputSurface { class AndroidOutputSurface : public cc::OutputSurface {
public: public:
explicit AndroidOutputSurface( explicit AndroidOutputSurface(
...@@ -406,7 +333,6 @@ CompositorImpl::CompositorImpl(CompositorClient* client, ...@@ -406,7 +333,6 @@ CompositorImpl::CompositorImpl(CompositorClient* client,
pending_swapbuffers_(0U), pending_swapbuffers_(0U),
num_successive_context_creation_failures_(0), num_successive_context_creation_failures_(0),
compositor_frame_sink_request_pending_(false), compositor_frame_sink_request_pending_(false),
needs_begin_frames_(false),
weak_factory_(this) { weak_factory_(this) {
ui::ContextProviderFactory::GetInstance() ui::ContextProviderFactory::GetInstance()
->GetSurfaceManager() ->GetSurfaceManager()
...@@ -726,7 +652,6 @@ void CompositorImpl::InitializeDisplay( ...@@ -726,7 +652,6 @@ void CompositorImpl::InitializeDisplay(
cc::SurfaceManager* manager = cc::SurfaceManager* manager =
ui::ContextProviderFactory::GetInstance()->GetSurfaceManager(); ui::ContextProviderFactory::GetInstance()->GetSurfaceManager();
auto* task_runner = base::ThreadTaskRunnerHandle::Get().get(); auto* task_runner = base::ThreadTaskRunnerHandle::Get().get();
begin_frame_source_.reset(new ExternalBeginFrameSource(this));
std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler( std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
task_runner, display_output_surface->capabilities().max_frames_pending)); task_runner, display_output_surface->capabilities().max_frames_pending));
...@@ -734,7 +659,7 @@ void CompositorImpl::InitializeDisplay( ...@@ -734,7 +659,7 @@ void CompositorImpl::InitializeDisplay(
HostSharedBitmapManager::current(), HostSharedBitmapManager::current(),
BrowserGpuMemoryBufferManager::current(), BrowserGpuMemoryBufferManager::current(),
host_->GetSettings().renderer_settings, frame_sink_id_, host_->GetSettings().renderer_settings, frame_sink_id_,
begin_frame_source_.get(), std::move(display_output_surface), root_window_->GetBeginFrameSource(), std::move(display_output_surface),
std::move(scheduler), std::move(scheduler),
base::MakeUnique<cc::TextureMailboxDeleter>(task_runner))); base::MakeUnique<cc::TextureMailboxDeleter>(task_runner)));
...@@ -753,14 +678,6 @@ void CompositorImpl::InitializeDisplay( ...@@ -753,14 +678,6 @@ void CompositorImpl::InitializeDisplay(
host_->SetCompositorFrameSink(std::move(compositor_frame_sink)); host_->SetCompositorFrameSink(std::move(compositor_frame_sink));
} }
void CompositorImpl::AddObserver(VSyncObserver* observer) {
observer_list_.AddObserver(observer);
}
void CompositorImpl::RemoveObserver(VSyncObserver* observer) {
observer_list_.RemoveObserver(observer);
}
cc::UIResourceId CompositorImpl::CreateUIResource( cc::UIResourceId CompositorImpl::CreateUIResource(
cc::UIResourceClient* client) { cc::UIResourceClient* client) {
TRACE_EVENT0("compositor", "CompositorImpl::CreateUIResource"); TRACE_EVENT0("compositor", "CompositorImpl::CreateUIResource");
...@@ -806,23 +723,6 @@ void CompositorImpl::RequestCopyOfOutputOnRootLayer( ...@@ -806,23 +723,6 @@ void CompositorImpl::RequestCopyOfOutputOnRootLayer(
root_window_->GetLayer()->RequestCopyOfOutput(std::move(request)); root_window_->GetLayer()->RequestCopyOfOutput(std::move(request));
} }
void CompositorImpl::OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) {
for (auto& observer : observer_list_)
observer.OnVSync(frame_time, vsync_period);
if (needs_begin_frames_)
root_window_->RequestVSyncUpdate();
}
void CompositorImpl::OnNeedsBeginFramesChange(bool needs_begin_frames) {
if (needs_begin_frames_ == needs_begin_frames)
return;
needs_begin_frames_ = needs_begin_frames;
if (needs_begin_frames_)
root_window_->RequestVSyncUpdate();
}
void CompositorImpl::SetNeedsAnimate() { void CompositorImpl::SetNeedsAnimate() {
needs_animate_ = true; needs_animate_ = true;
if (!host_->IsVisible()) if (!host_->IsVisible())
......
...@@ -33,7 +33,6 @@ struct ANativeWindow; ...@@ -33,7 +33,6 @@ struct ANativeWindow;
namespace cc { namespace cc {
class AnimationHost; class AnimationHost;
class BeginFrameSource;
class Display; class Display;
class Layer; class Layer;
class LayerTreeHost; class LayerTreeHost;
...@@ -54,21 +53,11 @@ class CONTENT_EXPORT CompositorImpl ...@@ -54,21 +53,11 @@ class CONTENT_EXPORT CompositorImpl
public ui::UIResourceProvider, public ui::UIResourceProvider,
public ui::WindowAndroidCompositor { public ui::WindowAndroidCompositor {
public: public:
class VSyncObserver {
public:
virtual void OnVSync(base::TimeTicks timebase,
base::TimeDelta interval) = 0;
};
CompositorImpl(CompositorClient* client, gfx::NativeWindow root_window); CompositorImpl(CompositorClient* client, gfx::NativeWindow root_window);
~CompositorImpl() override; ~CompositorImpl() override;
static bool IsInitialized(); static bool IsInitialized();
void AddObserver(VSyncObserver* observer);
void RemoveObserver(VSyncObserver* observer);
void OnNeedsBeginFramesChange(bool needs_begin_frames);
// ui::ResourceProvider implementation. // ui::ResourceProvider implementation.
cc::UIResourceId CreateUIResource(cc::UIResourceClient* client) override; cc::UIResourceId CreateUIResource(cc::UIResourceClient* client) override;
void DeleteUIResource(cc::UIResourceId resource_id) override; void DeleteUIResource(cc::UIResourceId resource_id) override;
...@@ -113,8 +102,6 @@ class CONTENT_EXPORT CompositorImpl ...@@ -113,8 +102,6 @@ class CONTENT_EXPORT CompositorImpl
void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) override; void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) override;
void RequestCopyOfOutputOnRootLayer( void RequestCopyOfOutputOnRootLayer(
std::unique_ptr<cc::CopyOutputRequest> request) override; std::unique_ptr<cc::CopyOutputRequest> request) override;
void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) override;
void SetNeedsAnimate() override; void SetNeedsAnimate() override;
cc::FrameSinkId GetFrameSinkId() override; cc::FrameSinkId GetFrameSinkId() override;
...@@ -147,12 +134,10 @@ class CONTENT_EXPORT CompositorImpl ...@@ -147,12 +134,10 @@ class CONTENT_EXPORT CompositorImpl
scoped_refptr<cc::Layer> readback_layer_tree_; scoped_refptr<cc::Layer> readback_layer_tree_;
// Destruction order matters here: // Destruction order matters here:
base::ObserverList<VSyncObserver, true> observer_list_;
std::unique_ptr<cc::AnimationHost> animation_host_; std::unique_ptr<cc::AnimationHost> animation_host_;
std::unique_ptr<cc::LayerTreeHost> host_; std::unique_ptr<cc::LayerTreeHost> host_;
ui::ResourceManagerImpl resource_manager_; ui::ResourceManagerImpl resource_manager_;
std::unique_ptr<cc::BeginFrameSource> begin_frame_source_;
std::unique_ptr<cc::Display> display_; std::unique_ptr<cc::Display> display_;
gfx::Size size_; gfx::Size size_;
...@@ -182,7 +167,6 @@ class CONTENT_EXPORT CompositorImpl ...@@ -182,7 +167,6 @@ class CONTENT_EXPORT CompositorImpl
bool compositor_frame_sink_request_pending_; bool compositor_frame_sink_request_pending_;
gpu::Capabilities gpu_capabilities_; gpu::Capabilities gpu_capabilities_;
bool needs_begin_frames_;
base::WeakPtrFactory<CompositorImpl> weak_factory_; base::WeakPtrFactory<CompositorImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CompositorImpl); DISALLOW_COPY_AND_ASSIGN(CompositorImpl);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "base/process/process.h" #include "base/process/process.h"
#include "cc/input/selection.h" #include "cc/input/selection.h"
#include "cc/output/begin_frame_args.h" #include "cc/output/begin_frame_args.h"
#include "cc/scheduler/begin_frame_source.h"
#include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/android/content_view_core_impl_observer.h" #include "content/browser/android/content_view_core_impl_observer.h"
#include "content/browser/renderer_host/delegated_frame_evictor.h" #include "content/browser/renderer_host/delegated_frame_evictor.h"
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
#include "content/public/browser/readback_types.h" #include "content/public/browser/readback_types.h"
#include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/mailbox.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
#include "ui/android/delegated_frame_host_android.h"
#include "ui/android/view_android.h" #include "ui/android/view_android.h"
#include "ui/android/view_client.h" #include "ui/android/view_client.h"
#include "ui/android/window_android_observer.h" #include "ui/android/window_android_observer.h"
...@@ -47,10 +49,6 @@ namespace ui { ...@@ -47,10 +49,6 @@ namespace ui {
struct DidOverscrollParams; struct DidOverscrollParams;
} }
namespace ui {
class DelegatedFrameHostAndroid;
}
namespace content { namespace content {
class ContentViewCoreImpl; class ContentViewCoreImpl;
class OverscrollControllerAndroid; class OverscrollControllerAndroid;
...@@ -72,7 +70,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid ...@@ -72,7 +70,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
public StylusTextSelectorClient, public StylusTextSelectorClient,
public ui::TouchSelectionControllerClient, public ui::TouchSelectionControllerClient,
public content::ContentViewCoreImplObserver, public content::ContentViewCoreImplObserver,
public content::TextInputManager::Observer { public content::TextInputManager::Observer,
public ui::DelegatedFrameHostAndroid::Client,
public cc::BeginFrameObserver {
public: public:
RenderWidgetHostViewAndroid(RenderWidgetHostImpl* widget, RenderWidgetHostViewAndroid(RenderWidgetHostImpl* widget,
ContentViewCoreImpl* content_view_core); ContentViewCoreImpl* content_view_core);
...@@ -170,8 +170,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid ...@@ -170,8 +170,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void OnRootWindowVisibilityChanged(bool visible) override; void OnRootWindowVisibilityChanged(bool visible) override;
void OnAttachCompositor() override; void OnAttachCompositor() override;
void OnDetachCompositor() override; void OnDetachCompositor() override;
void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) override;
void OnAnimate(base::TimeTicks begin_frame_time) override; void OnAnimate(base::TimeTicks begin_frame_time) override;
void OnActivityStopped() override; void OnActivityStopped() override;
void OnActivityStarted() override; void OnActivityStarted() override;
...@@ -200,6 +198,15 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid ...@@ -200,6 +198,15 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void OnSelectionEvent(ui::SelectionEventType event) override; void OnSelectionEvent(ui::SelectionEventType event) override;
std::unique_ptr<ui::TouchHandleDrawable> CreateDrawable() override; std::unique_ptr<ui::TouchHandleDrawable> CreateDrawable() override;
// DelegatedFrameHostAndroid::Client implementation.
void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) override;
void ReturnResources(const cc::ReturnedResourceArray& resources) override;
// cc::BeginFrameObserver implementation.
void OnBeginFrame(const cc::BeginFrameArgs& args) override;
const cc::BeginFrameArgs& LastUsedBeginFrameArgs() const override;
void OnBeginFrameSourcePausedChanged(bool paused) override;
// Non-virtual methods // Non-virtual methods
void SetContentViewCore(ContentViewCoreImpl* content_view_core); void SetContentViewCore(ContentViewCoreImpl* content_view_core);
SkColor GetCachedBackgroundColor() const; SkColor GetCachedBackgroundColor() const;
...@@ -291,17 +298,16 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid ...@@ -291,17 +298,16 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
void DestroyDelegatedContent(); void DestroyDelegatedContent();
void OnLostResources(); void OnLostResources();
void ReturnResources(const cc::ReturnedResourceArray& resources); enum BeginFrameRequestType {
enum VSyncRequestType {
FLUSH_INPUT = 1 << 0, FLUSH_INPUT = 1 << 0,
BEGIN_FRAME = 1 << 1, BEGIN_FRAME = 1 << 1,
PERSISTENT_BEGIN_FRAME = 1 << 2 PERSISTENT_BEGIN_FRAME = 1 << 2
}; };
void RequestVSyncUpdate(uint32_t requests); void AddBeginFrameRequest(BeginFrameRequestType request);
void ClearBeginFrameRequest(BeginFrameRequestType request);
void StartObservingRootWindow(); void StartObservingRootWindow();
void StopObservingRootWindow(); void StopObservingRootWindow();
void SendBeginFrame(base::TimeTicks frame_time, base::TimeDelta vsync_period); void SendBeginFrame(cc::BeginFrameArgs args);
bool Animate(base::TimeTicks frame_time); bool Animate(base::TimeTicks frame_time);
void RequestDisallowInterceptTouchEvent(); void RequestDisallowInterceptTouchEvent();
...@@ -314,8 +320,13 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid ...@@ -314,8 +320,13 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
// The model object. // The model object.
RenderWidgetHostImpl* host_; RenderWidgetHostImpl* host_;
// Used to control action dispatch at the next |OnVSync()| call. // The begin frame source being observed. Null if none.
uint32_t outstanding_vsync_requests_; cc::BeginFrameSource* begin_frame_source_;
cc::BeginFrameArgs last_begin_frame_args_;
// Indicates whether and for what reason a request for begin frames has been
// issued. Used to control action dispatch at the next |OnBeginFrame()| call.
uint32_t outstanding_begin_frame_requests_;
bool is_showing_; bool is_showing_;
......
...@@ -2,6 +2,7 @@ include_rules = [ ...@@ -2,6 +2,7 @@ include_rules = [
"+cc/layers", "+cc/layers",
"+cc/output", "+cc/output",
"+cc/resources", "+cc/resources",
"+cc/scheduler/begin_frame_source.h",
"+cc/surfaces", "+cc/surfaces",
"+cc/test/stub_layer_tree_host_client.h", "+cc/test/stub_layer_tree_host_client.h",
"+cc/test/test_task_graph_runner.h", "+cc/test/test_task_graph_runner.h",
......
...@@ -51,17 +51,16 @@ void CopyOutputRequestCallback( ...@@ -51,17 +51,16 @@ void CopyOutputRequestCallback(
} // namespace } // namespace
DelegatedFrameHostAndroid::DelegatedFrameHostAndroid( DelegatedFrameHostAndroid::DelegatedFrameHostAndroid(ui::ViewAndroid* view,
ui::ViewAndroid* view, SkColor background_color,
SkColor background_color, Client* client)
ReturnResourcesCallback return_resources_callback)
: frame_sink_id_( : frame_sink_id_(
ui::ContextProviderFactory::GetInstance()->AllocateFrameSinkId()), ui::ContextProviderFactory::GetInstance()->AllocateFrameSinkId()),
view_(view), view_(view),
return_resources_callback_(return_resources_callback), client_(client),
background_layer_(cc::SolidColorLayer::Create()) { background_layer_(cc::SolidColorLayer::Create()) {
DCHECK(view_); DCHECK(view_);
DCHECK(!return_resources_callback_.is_null()); DCHECK(client_);
surface_manager_ = surface_manager_ =
ui::ContextProviderFactory::GetInstance()->GetSurfaceManager(); ui::ContextProviderFactory::GetInstance()->GetSurfaceManager();
...@@ -223,13 +222,12 @@ void DelegatedFrameHostAndroid::UnregisterFrameSinkHierarchy() { ...@@ -223,13 +222,12 @@ void DelegatedFrameHostAndroid::UnregisterFrameSinkHierarchy() {
void DelegatedFrameHostAndroid::ReturnResources( void DelegatedFrameHostAndroid::ReturnResources(
const cc::ReturnedResourceArray& resources) { const cc::ReturnedResourceArray& resources) {
return_resources_callback_.Run(resources); client_->ReturnResources(resources);
} }
void DelegatedFrameHostAndroid::SetBeginFrameSource( void DelegatedFrameHostAndroid::SetBeginFrameSource(
cc::BeginFrameSource* begin_frame_source) { cc::BeginFrameSource* begin_frame_source) {
// TODO(enne): hook this up instead of making RWHVAndroid a client_->SetBeginFrameSource(begin_frame_source);
// WindowAndroidObserver.
} }
void DelegatedFrameHostAndroid::UpdateBackgroundLayer() { void DelegatedFrameHostAndroid::UpdateBackgroundLayer() {
......
...@@ -32,12 +32,16 @@ class WindowAndroidCompositor; ...@@ -32,12 +32,16 @@ class WindowAndroidCompositor;
class UI_ANDROID_EXPORT DelegatedFrameHostAndroid class UI_ANDROID_EXPORT DelegatedFrameHostAndroid
: public cc::SurfaceFactoryClient { : public cc::SurfaceFactoryClient {
public: public:
using ReturnResourcesCallback = class Client {
base::Callback<void(const cc::ReturnedResourceArray&)>; public:
virtual void SetBeginFrameSource(
cc::BeginFrameSource* begin_frame_source) = 0;
virtual void ReturnResources(const cc::ReturnedResourceArray&) = 0;
};
DelegatedFrameHostAndroid(ViewAndroid* view, DelegatedFrameHostAndroid(ViewAndroid* view,
SkColor background_color, SkColor background_color,
ReturnResourcesCallback return_resources_callback); Client* client);
~DelegatedFrameHostAndroid() override; ~DelegatedFrameHostAndroid() override;
...@@ -81,7 +85,7 @@ class UI_ANDROID_EXPORT DelegatedFrameHostAndroid ...@@ -81,7 +85,7 @@ class UI_ANDROID_EXPORT DelegatedFrameHostAndroid
cc::SurfaceManager* surface_manager_; cc::SurfaceManager* surface_manager_;
std::unique_ptr<cc::SurfaceIdAllocator> surface_id_allocator_; std::unique_ptr<cc::SurfaceIdAllocator> surface_id_allocator_;
cc::FrameSinkId registered_parent_frame_sink_id_; cc::FrameSinkId registered_parent_frame_sink_id_;
ReturnResourcesCallback return_resources_callback_; Client* client_;
std::unique_ptr<cc::SurfaceFactory> surface_factory_; std::unique_ptr<cc::SurfaceFactory> surface_factory_;
......
...@@ -4,12 +4,19 @@ ...@@ -4,12 +4,19 @@
#include "ui/android/window_android.h" #include "ui/android/window_android.h"
#include <unordered_set>
#include "base/android/context_utils.h" #include "base/android/context_utils.h"
#include "base/android/jni_android.h" #include "base/android/jni_android.h"
#include "base/android/jni_array.h" #include "base/android/jni_array.h"
#include "base/android/jni_string.h" #include "base/android/jni_string.h"
#include "base/android/jni_weak_ref.h" #include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h" #include "base/android/scoped_java_ref.h"
#include "base/auto_reset.h"
#include "base/observer_list.h"
#include "base/stl_util.h"
#include "cc/output/begin_frame_args.h"
#include "cc/scheduler/begin_frame_source.h"
#include "jni/WindowAndroid_jni.h" #include "jni/WindowAndroid_jni.h"
#include "ui/android/window_android_compositor.h" #include "ui/android/window_android_compositor.h"
#include "ui/android/window_android_observer.h" #include "ui/android/window_android_observer.h"
...@@ -21,8 +28,107 @@ using base::android::JavaParamRef; ...@@ -21,8 +28,107 @@ using base::android::JavaParamRef;
using base::android::JavaRef; using base::android::JavaRef;
using base::android::ScopedJavaLocalRef; using base::android::ScopedJavaLocalRef;
class WindowAndroid::WindowBeginFrameSource : public cc::BeginFrameSource {
public:
explicit WindowBeginFrameSource(WindowAndroid* window)
: window_(window),
observer_count_(0),
in_on_vsync_(false) {}
~WindowBeginFrameSource() override {}
// cc::BeginFrameSource implementation.
void AddObserver(cc::BeginFrameObserver* obs) override;
void RemoveObserver(cc::BeginFrameObserver* obs) override;
void DidFinishFrame(cc::BeginFrameObserver* obs,
size_t remaining_frames) override {}
bool IsThrottled() const override { return true; }
void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period);
private:
WindowAndroid* const window_;
base::ObserverList<cc::BeginFrameObserver> observers_;
int observer_count_;
cc::BeginFrameArgs last_begin_frame_args_;
bool in_on_vsync_;
};
void WindowAndroid::WindowBeginFrameSource::AddObserver(
cc::BeginFrameObserver* obs) {
DCHECK(obs);
DCHECK(!observers_.HasObserver(obs));
observers_.AddObserver(obs);
observer_count_++;
obs->OnBeginFrameSourcePausedChanged(false);
window_->SetNeedsBeginFrames(true);
// Send a MISSED BeginFrame if possible and necessary. If an observer is added
// during OnVSync(), it will get a NORMAL BeginFrame from OnVSync() instead.
if (!in_on_vsync_ && last_begin_frame_args_.IsValid()) {
cc::BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
if (!last_args.IsValid() ||
last_args.frame_time < last_begin_frame_args_.frame_time) {
last_begin_frame_args_.type = cc::BeginFrameArgs::MISSED;
// TODO(crbug.com/602485): A deadline doesn't make too much sense
// for a missed BeginFrame (the intention rather is 'immediately'),
// but currently the retro frame logic is very strict in discarding
// BeginFrames.
last_begin_frame_args_.deadline =
base::TimeTicks::Now() + last_begin_frame_args_.interval;
obs->OnBeginFrame(last_begin_frame_args_);
}
}
}
void WindowAndroid::WindowBeginFrameSource::RemoveObserver(
cc::BeginFrameObserver* obs) {
DCHECK(obs);
DCHECK(observers_.HasObserver(obs));
observers_.RemoveObserver(obs);
observer_count_--;
if (observer_count_ <= 0)
window_->SetNeedsBeginFrames(false);
}
void WindowAndroid::WindowBeginFrameSource::OnVSync(
base::TimeTicks frame_time,
base::TimeDelta vsync_period) {
// frame time is in the past, so give the next vsync period as the deadline.
base::TimeTicks deadline = frame_time + vsync_period;
last_begin_frame_args_ =
cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
vsync_period, cc::BeginFrameArgs::NORMAL);
DCHECK(last_begin_frame_args_.IsValid());
// We support adding/removing observers during observer iteration through
// base::ObserverList. We also prevent observers that are added during
// observer iteration from receiving a MISSED BeginFrame by means of
// |in_on_vsync_| - they will receive the current NORMAL one during the
// iteration instead. Note that SynchronousCompositorBrowserFilter relies on
// this behavior.
// TODO(eseckler): Remove SynchronousCompositorBrowserFilter's dependency on
// this and replace observers_ by a std::unordered_set, iterate on a copy.
base::AutoReset<bool> auto_reset(&in_on_vsync_, true);
std::unordered_set<cc::BeginFrameObserver*> notified_observers;
for (auto& obs : observers_) {
// An observer may remove and add itself during a single OnBeginFrame, in
// which case it'd appear twice during the iteration. To deal with this, we
// keep track of whether we already notified it.
if (!base::ContainsKey(notified_observers, &obs)) {
obs.OnBeginFrame(last_begin_frame_args_);
notified_observers.insert(&obs);
}
}
}
WindowAndroid::WindowAndroid(JNIEnv* env, jobject obj, int display_id) WindowAndroid::WindowAndroid(JNIEnv* env, jobject obj, int display_id)
: display_id_(display_id), compositor_(NULL) { : display_id_(display_id),
compositor_(NULL),
begin_frame_source_(new WindowBeginFrameSource(this)),
needs_begin_frames_(false) {
java_window_.Reset(env, obj); java_window_.Reset(env, obj);
} }
...@@ -69,6 +175,10 @@ void WindowAndroid::RemoveObserver(WindowAndroidObserver* observer) { ...@@ -69,6 +175,10 @@ void WindowAndroid::RemoveObserver(WindowAndroidObserver* observer) {
observer_list_.RemoveObserver(observer); observer_list_.RemoveObserver(observer);
} }
cc::BeginFrameSource* WindowAndroid::GetBeginFrameSource() {
return begin_frame_source_.get();
}
void WindowAndroid::AttachCompositor(WindowAndroidCompositor* compositor) { void WindowAndroid::AttachCompositor(WindowAndroidCompositor* compositor) {
if (compositor_ && compositor != compositor_) if (compositor_ && compositor != compositor_)
DetachCompositor(); DetachCompositor();
...@@ -90,6 +200,15 @@ void WindowAndroid::RequestVSyncUpdate() { ...@@ -90,6 +200,15 @@ void WindowAndroid::RequestVSyncUpdate() {
Java_WindowAndroid_requestVSyncUpdate(env, GetJavaObject()); Java_WindowAndroid_requestVSyncUpdate(env, GetJavaObject());
} }
void WindowAndroid::SetNeedsBeginFrames(bool needs_begin_frames) {
if (needs_begin_frames_ == needs_begin_frames)
return;
needs_begin_frames_ = needs_begin_frames;
if (needs_begin_frames_)
RequestVSyncUpdate();
}
void WindowAndroid::SetNeedsAnimate() { void WindowAndroid::SetNeedsAnimate() {
if (compositor_) if (compositor_)
compositor_->SetNeedsAnimate(); compositor_->SetNeedsAnimate();
...@@ -107,10 +226,9 @@ void WindowAndroid::OnVSync(JNIEnv* env, ...@@ -107,10 +226,9 @@ void WindowAndroid::OnVSync(JNIEnv* env,
base::TimeTicks frame_time(base::TimeTicks::FromInternalValue(time_micros)); base::TimeTicks frame_time(base::TimeTicks::FromInternalValue(time_micros));
base::TimeDelta vsync_period( base::TimeDelta vsync_period(
base::TimeDelta::FromMicroseconds(period_micros)); base::TimeDelta::FromMicroseconds(period_micros));
for (WindowAndroidObserver& observer : observer_list_) begin_frame_source_->OnVSync(frame_time, vsync_period);
observer.OnVSync(frame_time, vsync_period); if (needs_begin_frames_)
if (compositor_) RequestVSyncUpdate();
compositor_->OnVSync(frame_time, vsync_period);
} }
void WindowAndroid::OnVisibilityChanged(JNIEnv* env, void WindowAndroid::OnVisibilityChanged(JNIEnv* env,
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define UI_ANDROID_WINDOW_ANDROID_H_ #define UI_ANDROID_WINDOW_ANDROID_H_
#include <jni.h> #include <jni.h>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -18,9 +19,13 @@ ...@@ -18,9 +19,13 @@
#include "ui/android/view_android.h" #include "ui/android/view_android.h"
#include "ui/gfx/geometry/vector2d_f.h" #include "ui/gfx/geometry/vector2d_f.h"
namespace cc {
class BeginFrameSource;
} // namespace cc
namespace display { namespace display {
class DisplayAndroidManager; class DisplayAndroidManager;
} } // namespace display
namespace ui { namespace ui {
...@@ -59,8 +64,8 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid { ...@@ -59,8 +64,8 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid {
void RemoveObserver(WindowAndroidObserver* observer); void RemoveObserver(WindowAndroidObserver* observer);
WindowAndroidCompositor* GetCompositor() { return compositor_; } WindowAndroidCompositor* GetCompositor() { return compositor_; }
cc::BeginFrameSource* GetBeginFrameSource();
void RequestVSyncUpdate();
void SetNeedsAnimate(); void SetNeedsAnimate();
void Animate(base::TimeTicks begin_frame_time); void Animate(base::TimeTicks begin_frame_time);
void OnVSync(JNIEnv* env, void OnVSync(JNIEnv* env,
...@@ -86,10 +91,15 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid { ...@@ -86,10 +91,15 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid {
void DestroyForTesting(); void DestroyForTesting();
private: private:
class WindowBeginFrameSource;
friend class DisplayAndroidManager; friend class DisplayAndroidManager;
friend class WindowBeginFrameSource;
~WindowAndroid() override; ~WindowAndroid() override;
void SetNeedsBeginFrames(bool needs_begin_frames);
void RequestVSyncUpdate();
// ViewAndroid overrides. // ViewAndroid overrides.
WindowAndroid* GetWindowAndroid() const override; WindowAndroid* GetWindowAndroid() const override;
...@@ -103,6 +113,9 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid { ...@@ -103,6 +113,9 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid {
base::ObserverList<WindowAndroidObserver> observer_list_; base::ObserverList<WindowAndroidObserver> observer_list_;
std::unique_ptr<WindowBeginFrameSource> begin_frame_source_;
bool needs_begin_frames_;
DISALLOW_COPY_AND_ASSIGN(WindowAndroid); DISALLOW_COPY_AND_ASSIGN(WindowAndroid);
}; };
......
...@@ -27,8 +27,6 @@ class UI_ANDROID_EXPORT WindowAndroidCompositor { ...@@ -27,8 +27,6 @@ class UI_ANDROID_EXPORT WindowAndroidCompositor {
virtual void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) = 0; virtual void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) = 0;
virtual void RequestCopyOfOutputOnRootLayer( virtual void RequestCopyOfOutputOnRootLayer(
std::unique_ptr<cc::CopyOutputRequest> request) = 0; std::unique_ptr<cc::CopyOutputRequest> request) = 0;
virtual void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) = 0;
virtual void SetNeedsAnimate() = 0; virtual void SetNeedsAnimate() = 0;
virtual ResourceManager& GetResourceManager() = 0; virtual ResourceManager& GetResourceManager() = 0;
virtual cc::FrameSinkId GetFrameSinkId() = 0; virtual cc::FrameSinkId GetFrameSinkId() = 0;
......
...@@ -15,8 +15,6 @@ class UI_ANDROID_EXPORT WindowAndroidObserver { ...@@ -15,8 +15,6 @@ class UI_ANDROID_EXPORT WindowAndroidObserver {
virtual void OnRootWindowVisibilityChanged(bool visible) = 0; virtual void OnRootWindowVisibilityChanged(bool visible) = 0;
virtual void OnAttachCompositor() = 0; virtual void OnAttachCompositor() = 0;
virtual void OnDetachCompositor() = 0; virtual void OnDetachCompositor() = 0;
virtual void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) = 0;
virtual void OnAnimate(base::TimeTicks frame_begin_time) {} virtual void OnAnimate(base::TimeTicks frame_begin_time) {}
// Note that activity state callbacks will only be made if the WindowAndroid // Note that activity state callbacks will only be made if the WindowAndroid
......
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