Commit 8b89390b authored by Bo Liu's avatar Bo Liu Committed by Commit Bot

aw: Manually generate LocalSurfaceId

Currently viz is using the LocalSurfaceId in RenderWidgetHostViewAndroid
as the surface to submit a root renderer frame to. This doesn't always
work because renderer side change to LocalSurfaceId may not have been
committed yet for that frame, which then can cause a mismatch in viz.

Due to webview having a shortcut to resize the root renderer compositor
viewport without commit [1], it's also not ok to use the LocalSurfaceId
of the renderer compositor, since renderer can resize before the new Id
is committed. This technically breaks surface sync, though it doesn't
matter to webview in practice. However this does need to be solved for
IsUsingVizFrameSubmissionForWebView.

Instead, just generate LocalSurfaceId in HardwareRendererViz and check
the frame size and scale to generate new Ids instead.

[1]
https://source.chromium.org/chromium/chromium/src/+/master:cc/trees/layer_tree_frame_sink_client.h;drc=7cfc49943853b0c361223b47ddeb01f7e9fa7ff3;l=73

Bug: 1145412
Change-Id: I0ac5934e214ca2667bf71fc610dceddc343d0e1d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2551788
Commit-Queue: Bo <boliu@chromium.org>
Reviewed-by: default avatarVasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#829873}
parent 4807a9ac
......@@ -159,7 +159,8 @@ void HardwareRendererViz::OnViz::DrawAndSwapOnViz(
if (child_frame->frame) {
DCHECK(!viz_frame_submission_);
without_gpu_->SubmitChildCompositorFrame(child_frame);
without_gpu_->SubmitChildCompositorFrame(child_id.local_surface_id(),
child_frame);
}
gfx::Size frame_size = without_gpu_->GetChildFrameSize();
......@@ -275,7 +276,9 @@ HardwareRendererViz::HardwareRendererViz(
RenderThreadManager* state,
RootFrameSinkGetter root_frame_sink_getter,
AwVulkanContextProvider* context_provider)
: HardwareRenderer(state), output_surface_provider_(context_provider) {
: HardwareRenderer(state),
viz_frame_submission_(features::IsUsingVizFrameSubmissionForWebView()),
output_surface_provider_(context_provider) {
DCHECK_CALLED_ON_VALID_THREAD(render_thread_checker_);
DCHECK(output_surface_provider_.renderer_settings().use_skia_renderer);
......@@ -336,9 +339,42 @@ void HardwareRendererViz::DrawAndSwap(HardwareRendererDrawParams* params) {
if (!child_frame_)
return;
viz::SurfaceId child_surface_id = child_frame_->GetSurfaceId();
// Two problems currently can cause the content-generated LocalSurfaceId
// to remain the same even if a frame of a new size is submitted:
// * The content LocalSurfaceId is currently copied from browser, not
// the renderer when the renderer submits a frame
// * Synchronous compositor can resize the viewport in LTHI::OnDraw before
// a new LocalSurfaceId is committed.
// Therefore we do not use the LocalSurfaceId allocated by content, and
// instead generate our own LocalSurfaceId here for the root renderer frame.
if (!renderer_root_local_surface_id_allocator_ ||
child_frame_->frame_sink_id != surface_id_.frame_sink_id() ||
layer_tree_frame_sink_id_ != child_frame_->layer_tree_frame_sink_id) {
renderer_root_local_surface_id_allocator_ =
std::make_unique<viz::ParentLocalSurfaceIdAllocator>();
layer_tree_frame_sink_id_ = child_frame_->layer_tree_frame_sink_id;
renderer_root_local_surface_id_ = viz::LocalSurfaceId();
}
if (!viz_frame_submission_ && child_frame_->frame) {
if (!renderer_root_local_surface_id_.is_valid() ||
child_frame_->frame->size_in_pixels() != frame_size_ ||
child_frame_->frame->device_scale_factor() != device_scale_factor_) {
renderer_root_local_surface_id_allocator_->GenerateId();
renderer_root_local_surface_id_ =
renderer_root_local_surface_id_allocator_->GetCurrentLocalSurfaceId();
frame_size_ = child_frame_->frame->size_in_pixels();
device_scale_factor_ = child_frame_->frame->device_scale_factor();
}
}
viz::SurfaceId child_surface_id =
viz_frame_submission_ ? child_frame_->GetSurfaceId()
: viz::SurfaceId(child_frame_->frame_sink_id,
renderer_root_local_surface_id_);
if (child_surface_id.is_valid() && child_surface_id != surface_id_) {
surface_id_ = child_surface_id;
if (viz_frame_submission_)
device_scale_factor_ = child_frame_->device_scale_factor;
}
......
......@@ -35,14 +35,19 @@ class HardwareRendererViz : public HardwareRenderer {
void DestroyOnViz();
bool IsUsingVulkan() const;
// Information about last delegated frame.
float device_scale_factor_ = 0;
const bool viz_frame_submission_;
viz::SurfaceId surface_id_;
// Used to create viz::OutputSurface and gl::GLSurface
OutputSurfaceProviderWebview output_surface_provider_;
std::unique_ptr<viz::ParentLocalSurfaceIdAllocator>
renderer_root_local_surface_id_allocator_;
uint32_t layer_tree_frame_sink_id_ = 0u;
viz::LocalSurfaceId renderer_root_local_surface_id_;
float device_scale_factor_ = 1.0f;
gfx::Size frame_size_;
// These are accessed on the viz thread.
std::unique_ptr<OnViz> on_viz_;
......
......@@ -195,7 +195,9 @@ void RootFrameSink::DettachClient() {
client_ = nullptr;
}
void RootFrameSink::SubmitChildCompositorFrame(ChildFrame* child_frame) {
void RootFrameSink::SubmitChildCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
ChildFrame* child_frame) {
DCHECK(child_frame->frame);
if (!child_sink_support_ ||
child_sink_support_->frame_sink_id() != child_frame->frame_sink_id ||
......@@ -209,7 +211,7 @@ void RootFrameSink::SubmitChildCompositorFrame(ChildFrame* child_frame) {
}
child_sink_support_->SubmitCompositorFrame(
child_frame->local_surface_id, std::move(*child_frame->frame),
local_surface_id, std::move(*child_frame->frame),
std::move(child_frame->hit_test_region_list));
child_frame->frame.reset();
}
......
......@@ -58,7 +58,8 @@ class RootFrameSink : public base::RefCounted<RootFrameSink>,
bool IsChildSurface(const viz::FrameSinkId& frame_sink_id);
void DettachClient();
void SubmitChildCompositorFrame(ChildFrame* child_frame);
void SubmitChildCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
ChildFrame* child_frame);
viz::FrameTimingDetailsMap TakeChildFrameTimingDetailsMap();
gfx::Size GetChildFrameSize();
......
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