-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
aw: Add RootFrameSink and RootFrameSinkProxy
Both are per-webview objects. RootFrameSink lives on the viz thread, and responsible for per-webview objects that do not require access to the GPU. This is mostly classes involved for sending begin frames. RootFrameSinkProxy straddles UI and Viz thread and provides access to RootFrameSink. Bug: 805739 Change-Id: I4c7e31882d35eb3f772bd81b62a40a47c279de1d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1749527 Commit-Queue: Bo <boliu@chromium.org> Reviewed-by: kylechar <kylechar@chromium.org> Reviewed-by: Eric Karl <ericrk@chromium.org> Cr-Commit-Position: refs/heads/master@{#686597}
- Loading branch information
Bo Liu
authored and
Commit Bot
committed
Aug 13, 2019
1 parent
6381a94
commit 9314061
Showing
9 changed files
with
418 additions
and
1 deletion.
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
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,98 @@ | ||
// Copyright 2019 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 "android_webview/browser/gfx/root_frame_sink.h" | ||
|
||
#include "android_webview/browser/gfx/viz_compositor_thread_runner_webview.h" | ||
#include "base/no_destructor.h" | ||
#include "base/trace_event/trace_event.h" | ||
#include "components/viz/common/surfaces/frame_sink_id_allocator.h" | ||
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" | ||
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" | ||
|
||
namespace android_webview { | ||
|
||
namespace { | ||
|
||
viz::FrameSinkId AllocateParentSinkId() { | ||
static base::NoDestructor<viz::FrameSinkIdAllocator> allocator(0u); | ||
return allocator->NextFrameSinkId(); | ||
} | ||
|
||
} // namespace | ||
|
||
RootFrameSink::RootFrameSink(SetNeedsBeginFrameCallback set_needs_begin_frame) | ||
: root_frame_sink_id_(AllocateParentSinkId()), | ||
set_needs_begin_frame_(set_needs_begin_frame) { | ||
constexpr bool is_root = true; | ||
constexpr bool needs_sync_points = true; | ||
GetFrameSinkManager()->RegisterFrameSinkId(root_frame_sink_id_, | ||
false /* report_activationa */); | ||
support_ = std::make_unique<viz::CompositorFrameSinkSupport>( | ||
this, GetFrameSinkManager(), root_frame_sink_id_, is_root, | ||
needs_sync_points); | ||
begin_frame_source_ = std::make_unique<viz::ExternalBeginFrameSource>(this); | ||
GetFrameSinkManager()->RegisterBeginFrameSource(begin_frame_source_.get(), | ||
root_frame_sink_id_); | ||
} | ||
|
||
RootFrameSink::~RootFrameSink() { | ||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | ||
GetFrameSinkManager()->UnregisterBeginFrameSource(begin_frame_source_.get()); | ||
begin_frame_source_.reset(); | ||
support_.reset(); | ||
GetFrameSinkManager()->InvalidateFrameSinkId(root_frame_sink_id_); | ||
} | ||
|
||
viz::FrameSinkManagerImpl* RootFrameSink::GetFrameSinkManager() { | ||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | ||
// FrameSinkManagerImpl is global and not owned by this class, which is | ||
// per-AwContents. | ||
return VizCompositorThreadRunnerWebView::GetInstance()->GetFrameSinkManager(); | ||
} | ||
|
||
void RootFrameSink::DidReceiveCompositorFrameAck( | ||
const std::vector<viz::ReturnedResource>& resources) { | ||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | ||
ReclaimResources(resources); | ||
} | ||
|
||
void RootFrameSink::ReclaimResources( | ||
const std::vector<viz::ReturnedResource>& resources) { | ||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | ||
// Root surface should have no resources to return. | ||
CHECK(resources.empty()); | ||
} | ||
|
||
void RootFrameSink::OnNeedsBeginFrames(bool needs_begin_frames) { | ||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | ||
TRACE_EVENT_INSTANT1("android_webview", "RootFrameSink::OnNeedsBeginFrames", | ||
TRACE_EVENT_SCOPE_THREAD, "needs_begin_frames", | ||
needs_begin_frames); | ||
needs_begin_frames_ = needs_begin_frames; | ||
set_needs_begin_frame_.Run(needs_begin_frames); | ||
} | ||
|
||
void RootFrameSink::AddChildFrameSinkId(const viz::FrameSinkId& frame_sink_id) { | ||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | ||
GetFrameSinkManager()->RegisterFrameSinkHierarchy(root_frame_sink_id_, | ||
frame_sink_id); | ||
} | ||
|
||
void RootFrameSink::RemoveChildFrameSinkId( | ||
const viz::FrameSinkId& frame_sink_id) { | ||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | ||
GetFrameSinkManager()->UnregisterFrameSinkHierarchy(root_frame_sink_id_, | ||
frame_sink_id); | ||
} | ||
|
||
bool RootFrameSink::BeginFrame(const viz::BeginFrameArgs& args) { | ||
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); | ||
begin_frame_source_->OnBeginFrame(args); | ||
// This is a hack and wrong. Remove this once we have proper frame submission | ||
// tracking. | ||
return needs_begin_frames_; | ||
} | ||
|
||
} // namespace android_webview |
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,77 @@ | ||
// Copyright 2019 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 ANDROID_WEBVIEW_BROWSER_GFX_ROOT_FRAME_SINK_H_ | ||
#define ANDROID_WEBVIEW_BROWSER_GFX_ROOT_FRAME_SINK_H_ | ||
|
||
#include <memory> | ||
|
||
#include "base/callback.h" | ||
#include "base/macros.h" | ||
#include "base/threading/thread_checker.h" | ||
#include "components/viz/common/frame_sinks/begin_frame_source.h" | ||
#include "components/viz/common/frame_timing_details_map.h" | ||
#include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h" | ||
|
||
namespace viz { | ||
class CompositorFrameSinkSupport; | ||
class FrameSinkManagerImpl; | ||
class ExternalBeginFrameSource; | ||
} // namespace viz | ||
|
||
namespace android_webview { | ||
|
||
// This class holds per-AwContents classes on the viz thread that do not need | ||
// access to the GPU. It is single-threaded and refcounted on the viz thread. | ||
// This needs to be separate from classes for rendering which requires GPU | ||
// to enable sending begin frames independently from access to GPU. | ||
class RootFrameSink : public base::RefCounted<RootFrameSink>, | ||
public viz::mojom::CompositorFrameSinkClient, | ||
public viz::ExternalBeginFrameSourceClient { | ||
public: | ||
using SetNeedsBeginFrameCallback = base::RepeatingCallback<void(bool)>; | ||
explicit RootFrameSink(SetNeedsBeginFrameCallback set_needs_begin_frame); | ||
|
||
viz::CompositorFrameSinkSupport* support() const { return support_.get(); } | ||
const viz::FrameSinkId& root_frame_sink_id() const { | ||
return root_frame_sink_id_; | ||
} | ||
void AddChildFrameSinkId(const viz::FrameSinkId& frame_sink_id); | ||
void RemoveChildFrameSinkId(const viz::FrameSinkId& frame_sink_id); | ||
bool BeginFrame(const viz::BeginFrameArgs& args); | ||
|
||
// viz::mojom::CompositorFrameSinkClient implementation. | ||
void DidReceiveCompositorFrameAck( | ||
const std::vector<viz::ReturnedResource>& resources) override; | ||
void OnBeginFrame(const viz::BeginFrameArgs& args, | ||
const viz::FrameTimingDetailsMap& feedbacks) override {} | ||
void OnBeginFramePausedChanged(bool paused) override {} | ||
void ReclaimResources( | ||
const std::vector<viz::ReturnedResource>& resources) override; | ||
|
||
// viz::ExternalBeginFrameSourceClient overrides. | ||
void OnNeedsBeginFrames(bool needs_begin_frames) override; | ||
|
||
private: | ||
friend class base::RefCounted<RootFrameSink>; | ||
~RootFrameSink() override; | ||
viz::FrameSinkManagerImpl* GetFrameSinkManager(); | ||
|
||
const viz::FrameSinkId root_frame_sink_id_; | ||
std::unique_ptr<viz::CompositorFrameSinkSupport> support_; | ||
std::unique_ptr<viz::ExternalBeginFrameSource> begin_frame_source_; | ||
|
||
bool needs_begin_frames_ = false; | ||
SetNeedsBeginFrameCallback set_needs_begin_frame_; | ||
|
||
THREAD_CHECKER(thread_checker_); | ||
|
||
DISALLOW_COPY_AND_ASSIGN(RootFrameSink); | ||
}; | ||
|
||
using RootFrameSinkGetter = base::OnceCallback<scoped_refptr<RootFrameSink>()>; | ||
|
||
} // namespace android_webview | ||
|
||
#endif // ANDROID_WEBVIEW_BROWSER_GFX_ROOT_FRAME_SINK_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,123 @@ | ||
// Copyright 2019 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 "android_webview/browser/gfx/root_frame_sink_proxy.h" | ||
|
||
#include <utility> | ||
|
||
#include "android_webview/browser/gfx/root_frame_sink.h" | ||
#include "android_webview/browser/gfx/viz_compositor_thread_runner_webview.h" | ||
|
||
namespace android_webview { | ||
|
||
// static | ||
scoped_refptr<RootFrameSink> RootFrameSinkProxy::GetRootFrameSinkHelper( | ||
base::WeakPtr<RootFrameSinkProxy> proxy) { | ||
DCHECK(VizCompositorThreadRunnerWebView::GetInstance() | ||
->task_runner() | ||
->BelongsToCurrentThread()); | ||
if (proxy) | ||
return proxy->without_gpu_; | ||
return nullptr; | ||
} | ||
|
||
RootFrameSinkProxy::RootFrameSinkProxy( | ||
const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, | ||
SetNeedsBeginFrameCallback set_needs_begin_frame_callback) | ||
: ui_task_runner_(ui_task_runner), | ||
viz_task_runner_( | ||
VizCompositorThreadRunnerWebView::GetInstance()->task_runner()), | ||
set_needs_begin_frame_callback_( | ||
std::move(set_needs_begin_frame_callback)) { | ||
DETACH_FROM_THREAD(viz_thread_checker_); | ||
viz_task_runner_->PostTask( | ||
FROM_HERE, base::BindOnce(&RootFrameSinkProxy::InitializeOnViz, | ||
base::Unretained(this))); | ||
} | ||
|
||
void RootFrameSinkProxy::InitializeOnViz() { | ||
DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_); | ||
without_gpu_ = base::MakeRefCounted<RootFrameSink>( | ||
base::BindRepeating(&RootFrameSinkProxy::SetNeedsBeginFramesOnViz, | ||
weak_ptr_factory_on_viz_.GetWeakPtr())); | ||
} | ||
|
||
RootFrameSinkProxy::~RootFrameSinkProxy() { | ||
DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_); | ||
VizCompositorThreadRunnerWebView::GetInstance()->PostTaskAndBlock( | ||
FROM_HERE, base::BindOnce(&RootFrameSinkProxy::DestroyOnViz, | ||
base::Unretained(this))); | ||
} | ||
|
||
void RootFrameSinkProxy::DestroyOnViz() { | ||
DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_); | ||
DCHECK(without_gpu_->HasOneRef()); | ||
without_gpu_.reset(); | ||
weak_ptr_factory_on_viz_.InvalidateWeakPtrs(); | ||
} | ||
|
||
void RootFrameSinkProxy::SetNeedsBeginFramesOnViz(bool needs_begin_frames) { | ||
DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_); | ||
ui_task_runner_->PostTask( | ||
FROM_HERE, | ||
base::BindOnce(&RootFrameSinkProxy::SetNeedsBeginFramesOnUI, | ||
weak_ptr_factory_.GetWeakPtr(), needs_begin_frames)); | ||
} | ||
|
||
void RootFrameSinkProxy::SetNeedsBeginFramesOnUI(bool needs_begin_frames) { | ||
DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_); | ||
set_needs_begin_frame_callback_.Run(needs_begin_frames); | ||
} | ||
|
||
void RootFrameSinkProxy::AddChildFrameSinkId( | ||
const viz::FrameSinkId& frame_sink_id) { | ||
DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_); | ||
viz_task_runner_->PostTask( | ||
FROM_HERE, | ||
base::BindOnce(&RootFrameSinkProxy::AddChildFrameSinkIdOnViz, | ||
weak_ptr_factory_on_viz_.GetWeakPtr(), frame_sink_id)); | ||
} | ||
|
||
void RootFrameSinkProxy::AddChildFrameSinkIdOnViz( | ||
const viz::FrameSinkId& frame_sink_id) { | ||
DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_); | ||
without_gpu_->AddChildFrameSinkId(frame_sink_id); | ||
} | ||
|
||
void RootFrameSinkProxy::RemoveChildFrameSinkId( | ||
const viz::FrameSinkId& frame_sink_id) { | ||
DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_); | ||
viz_task_runner_->PostTask( | ||
FROM_HERE, | ||
base::BindOnce(&RootFrameSinkProxy::RemoveChildFrameSinkIdOnViz, | ||
weak_ptr_factory_on_viz_.GetWeakPtr(), frame_sink_id)); | ||
} | ||
|
||
void RootFrameSinkProxy::RemoveChildFrameSinkIdOnViz( | ||
const viz::FrameSinkId& frame_sink_id) { | ||
DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_); | ||
without_gpu_->RemoveChildFrameSinkId(frame_sink_id); | ||
} | ||
|
||
bool RootFrameSinkProxy::BeginFrame(const viz::BeginFrameArgs& args) { | ||
DCHECK_CALLED_ON_VALID_THREAD(ui_thread_checker_); | ||
bool invalidate = false; | ||
VizCompositorThreadRunnerWebView::GetInstance()->PostTaskAndBlock( | ||
FROM_HERE, base::BindOnce(&RootFrameSinkProxy::BeginFrameOnViz, | ||
base::Unretained(this), args, &invalidate)); | ||
return invalidate; | ||
} | ||
|
||
void RootFrameSinkProxy::BeginFrameOnViz(const viz::BeginFrameArgs& args, | ||
bool* invalidate) { | ||
DCHECK_CALLED_ON_VALID_THREAD(viz_thread_checker_); | ||
*invalidate = without_gpu_->BeginFrame(args); | ||
} | ||
|
||
RootFrameSinkGetter RootFrameSinkProxy::GetRootFrameSinkCallback() { | ||
return base::BindOnce(&RootFrameSinkProxy::GetRootFrameSinkHelper, | ||
weak_ptr_factory_on_viz_.GetWeakPtr()); | ||
} | ||
|
||
} // namespace android_webview |
Oops, something went wrong.