Commit 339f50e1 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

Fix exo startup crash with OOPD

For OOPD, the display compositor is in the viz process.
The LayerTreeFrameSinkLocal used by exo is for submitting frames to
a local display compositor, so it will not work with OOPD. To make it
work, we need use the AsyncLayerTreeFrameSink which can submit frames
to the remote display compositor in viz process via mojo IPC. And the
AsyncLayerTreeFrameSink also works with a local display compositor, so
we will use it for non-OOPD case as well.


Bug: 866898
Change-Id: I2003c8a6744547ee0c62c38667727c594ccb4537
Reviewed-on: https://chromium-review.googlesource.com/1153404Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Reviewed-by: default avatarFady Samuel <fsamuel@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#581311}
parent 0f0674af
......@@ -5,6 +5,7 @@
#include <GLES2/gl2extchromium.h>
#include "base/bind.h"
#include "base/run_loop.h"
#include "components/exo/buffer.h"
#include "components/exo/surface_tree_host.h"
#include "components/exo/test/exo_test_base.h"
......@@ -28,6 +29,17 @@ void Release(int* release_call_count) {
(*release_call_count)++;
}
void VerifySyncTokensInCompositorFrame(viz::CompositorFrame* frame) {
std::vector<GLbyte*> sync_tokens;
for (auto& resource : frame->resource_list)
sync_tokens.push_back(resource.mailbox_holder.sync_token.GetData());
gpu::gles2::GLES2Interface* gles2 = aura::Env::GetInstance()
->context_factory()
->SharedMainThreadContextProvider()
->ContextGL();
gles2->VerifySyncTokensCHROMIUM(sync_tokens.data(), sync_tokens.size());
}
TEST_F(BufferTest, ReleaseCallback) {
gfx::Size buffer_size(256, 256);
auto buffer = std::make_unique<Buffer>(
......@@ -36,7 +48,7 @@ TEST_F(BufferTest, ReleaseCallback) {
LayerTreeFrameSinkHolder* frame_sink_holder =
surface_tree_host->layer_tree_frame_sink_holder();
// This is needed to ensure that RunAllPendingInMessageLoop() call below
// This is needed to ensure that base::RunLoop().RunUntilIdle() call below
// is always sufficient for buffer to be released.
buffer->set_wait_for_release_delay_for_testing(base::TimeDelta());
......@@ -60,7 +72,7 @@ TEST_F(BufferTest, ReleaseCallback) {
std::vector<viz::ReturnedResource> resources = {returned_resource};
frame_sink_holder->ReclaimResources(resources);
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
ASSERT_EQ(release_call_count, 0);
buffer->OnDetach();
......@@ -102,7 +114,7 @@ TEST_F(BufferTest, IsLost) {
returned_resource.lost = is_lost;
std::vector<viz::ReturnedResource> resources = {returned_resource};
frame_sink_holder->ReclaimResources(resources);
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
// Producing a new texture transferable resource for the contents of the
// buffer.
......@@ -118,7 +130,7 @@ TEST_F(BufferTest, IsLost) {
returned_resource2.lost = false;
std::vector<viz::ReturnedResource> resources2 = {returned_resource2};
frame_sink_holder->ReclaimResources(resources2);
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
}
// Buffer::Texture::OnLostResources is called when the gpu crashes. This test
......@@ -152,7 +164,7 @@ TEST_F(BufferTest, SurfaceTreeHostDestruction) {
LayerTreeFrameSinkHolder* frame_sink_holder =
surface_tree_host->layer_tree_frame_sink_holder();
// This is needed to ensure that RunAllPendingInMessageLoop() call below
// This is needed to ensure that base::RunLoop().RunUntilIdle() call below
// is always sufficient for buffer to be released.
buffer->set_wait_for_release_delay_for_testing(base::TimeDelta());
......@@ -182,13 +194,16 @@ TEST_F(BufferTest, SurfaceTreeHostDestruction) {
gfx::Transform());
frame.render_pass_list.push_back(std::move(pass));
frame.resource_list.push_back(resource);
VerifySyncTokensInCompositorFrame(&frame);
frame_sink_holder->SubmitCompositorFrame(std::move(frame));
}
buffer->OnDetach();
base::RunLoop().RunUntilIdle();
ASSERT_EQ(release_call_count, 0);
surface_tree_host.reset();
base::RunLoop().RunUntilIdle();
ASSERT_EQ(release_call_count, 1);
}
......@@ -200,7 +215,7 @@ TEST_F(BufferTest, SurfaceTreeHostLastFrame) {
LayerTreeFrameSinkHolder* frame_sink_holder =
surface_tree_host->layer_tree_frame_sink_holder();
// This is needed to ensure that RunAllPendingInMessageLoop() call below
// This is needed to ensure that base::RunLoop().RunUntilIdle() call below
// is always sufficient for buffer to be released.
buffer->set_wait_for_release_delay_for_testing(base::TimeDelta());
......@@ -230,6 +245,7 @@ TEST_F(BufferTest, SurfaceTreeHostLastFrame) {
gfx::Transform());
frame.render_pass_list.push_back(std::move(pass));
frame.resource_list.push_back(resource);
VerifySyncTokensInCompositorFrame(&frame);
frame_sink_holder->SubmitCompositorFrame(std::move(frame));
// Try to release buffer in last frame. This can happen during a resize
......@@ -238,11 +254,12 @@ TEST_F(BufferTest, SurfaceTreeHostLastFrame) {
returned_resource.id = resource.id;
returned_resource.sync_token = resource.mailbox_holder.sync_token;
returned_resource.lost = false;
std::vector<viz::ReturnedResource> resources = {returned_resource};
frame_sink_holder->ReclaimResources(resources);
}
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
buffer->OnDetach();
// Release() should not have been called as resource is used by last frame.
......@@ -264,6 +281,7 @@ TEST_F(BufferTest, SurfaceTreeHostLastFrame) {
frame_sink_holder->SubmitCompositorFrame(std::move(frame));
}
base::RunLoop().RunUntilIdle();
// Release() should have been called exactly once.
ASSERT_EQ(release_call_count, 1);
}
......
......@@ -248,16 +248,14 @@ void SurfaceTreeHost::SubmitCompositorFrame() {
root_surface_origin_, device_scale_factor,
layer_tree_frame_sink_holder_.get(), &frame);
if (WMHelper::GetInstance()->AreVerifiedSyncTokensNeeded()) {
std::vector<GLbyte*> sync_tokens;
for (auto& resource : frame.resource_list)
sync_tokens.push_back(resource.mailbox_holder.sync_token.GetData());
ui::ContextFactory* context_factory =
aura::Env::GetInstance()->context_factory();
gpu::gles2::GLES2Interface* gles2 =
context_factory->SharedMainThreadContextProvider()->ContextGL();
gles2->VerifySyncTokensCHROMIUM(sync_tokens.data(), sync_tokens.size());
}
std::vector<GLbyte*> sync_tokens;
for (auto& resource : frame.resource_list)
sync_tokens.push_back(resource.mailbox_holder.sync_token.GetData());
ui::ContextFactory* context_factory =
aura::Env::GetInstance()->context_factory();
gpu::gles2::GLES2Interface* gles2 =
context_factory->SharedMainThreadContextProvider()->ContextGL();
gles2->VerifySyncTokensCHROMIUM(sync_tokens.data(), sync_tokens.size());
layer_tree_frame_sink_holder_->SubmitCompositorFrame(std::move(frame));
}
......
......@@ -96,7 +96,7 @@ TEST_P(SurfaceTest, Attach) {
// CompositorFrameSinkClient interface. We need to wait here for the mojo
// call to finish so that the release callback finishes running before
// the assertion below.
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
ASSERT_EQ(1, release_buffer_call_count);
}
......@@ -133,7 +133,7 @@ TEST_P(SurfaceTest, Damage) {
// Check that damage larger than contents is handled correctly at commit.
surface->Damage(gfx::Rect(gfx::ScaleToCeiledSize(buffer_size, 2.0f)));
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -148,7 +148,7 @@ TEST_P(SurfaceTest, Damage) {
// Check that damage is correct for a non-square rectangle not at the origin.
surface->Damage(surface_damage);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
// Adjust damage for DSF filtering and verify it below.
if (device_scale_factor() > 1.f)
......@@ -202,7 +202,7 @@ TEST_P(SurfaceTest, MAYBE_SetOpaqueRegion) {
// draw with blending.
surface->SetOpaqueRegion(gfx::Rect(256, 256));
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -219,7 +219,7 @@ TEST_P(SurfaceTest, MAYBE_SetOpaqueRegion) {
// Setting an empty opaque region requires draw with blending.
surface->SetOpaqueRegion(gfx::Rect());
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -241,7 +241,7 @@ TEST_P(SurfaceTest, MAYBE_SetOpaqueRegion) {
// blending.
surface->Attach(buffer_without_alpha.get());
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -367,7 +367,7 @@ TEST_P(SurfaceTest, SetBufferScale) {
gfx::ScaleToFlooredSize(buffer_size, 1.0f / kBufferScale).ToString(),
surface->content_size().ToString());
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
ASSERT_EQ(1u, frame.render_pass_list.size());
......@@ -398,7 +398,7 @@ TEST_P(SurfaceTest, MAYBE_SetBufferTransform) {
EXPECT_EQ(gfx::Size(buffer_size.height(), buffer_size.width()),
surface->content_size());
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -440,7 +440,7 @@ TEST_P(SurfaceTest, MAYBE_SetBufferTransform) {
gfx::ScaleToRoundedSize(child_buffer_size, 1.0f / kChildBufferScale),
child_surface->content_size());
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -468,6 +468,8 @@ TEST_P(SurfaceTest, MirrorLayers) {
surface->Attach(buffer.get());
surface->Commit();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(buffer_size, surface->window()->bounds().size());
EXPECT_EQ(buffer_size, surface->window()->layer()->bounds().size());
std::unique_ptr<ui::LayerTreeOwner> old_layer_owner =
......@@ -503,7 +505,7 @@ TEST_P(SurfaceTest, SetViewport) {
surface->window()->bounds().size().ToString());
EXPECT_EQ(viewport2.ToString(), surface->content_size().ToString());
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
ASSERT_EQ(1u, frame.render_pass_list.size());
......@@ -526,7 +528,7 @@ TEST_P(SurfaceTest, SetCrop) {
surface->window()->bounds().size().ToString());
EXPECT_EQ(crop_size.ToString(), surface->content_size().ToString());
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
ASSERT_EQ(1u, frame.render_pass_list.size());
......@@ -564,7 +566,7 @@ TEST_P(SurfaceTest, MAYBE_SetCropAndBufferTransform) {
surface->SetBufferTransform(Transform::NORMAL);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -585,7 +587,7 @@ TEST_P(SurfaceTest, MAYBE_SetCropAndBufferTransform) {
surface->SetBufferTransform(Transform::ROTATE_90);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -606,7 +608,7 @@ TEST_P(SurfaceTest, MAYBE_SetCropAndBufferTransform) {
surface->SetBufferTransform(Transform::ROTATE_180);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -627,7 +629,7 @@ TEST_P(SurfaceTest, MAYBE_SetCropAndBufferTransform) {
surface->SetBufferTransform(Transform::ROTATE_270);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -649,7 +651,7 @@ TEST_P(SurfaceTest, MAYBE_SetCropAndBufferTransform) {
surface->SetBufferTransform(Transform::NORMAL);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -670,7 +672,7 @@ TEST_P(SurfaceTest, MAYBE_SetCropAndBufferTransform) {
surface->SetBufferTransform(Transform::ROTATE_90);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -691,7 +693,7 @@ TEST_P(SurfaceTest, MAYBE_SetCropAndBufferTransform) {
surface->SetBufferTransform(Transform::ROTATE_180);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -712,7 +714,7 @@ TEST_P(SurfaceTest, MAYBE_SetCropAndBufferTransform) {
surface->SetBufferTransform(Transform::ROTATE_270);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
{
const viz::CompositorFrame& frame =
......@@ -741,7 +743,7 @@ TEST_P(SurfaceTest, SetBlendMode) {
surface->Attach(buffer.get());
surface->SetBlendMode(SkBlendMode::kSrc);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
ASSERT_EQ(1u, frame.render_pass_list.size());
......@@ -761,7 +763,7 @@ TEST_P(SurfaceTest, OverlayCandidate) {
surface->Attach(buffer.get());
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
const viz::CompositorFrame& frame = GetFrameFromSurface(shell_surface.get());
ASSERT_EQ(1u, frame.render_pass_list.size());
......@@ -786,7 +788,7 @@ TEST_P(SurfaceTest, SetAlpha) {
surface->Attach(buffer.get());
surface->SetAlpha(0.5f);
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
const viz::CompositorFrame& frame =
GetFrameFromSurface(shell_surface.get());
......@@ -801,6 +803,8 @@ TEST_P(SurfaceTest, SetAlpha) {
{
surface->SetAlpha(0.f);
surface->Commit();
base::RunLoop().RunUntilIdle();
const viz::CompositorFrame& frame =
GetFrameFromSurface(shell_surface.get());
ASSERT_EQ(1u, frame.render_pass_list.size());
......@@ -814,6 +818,8 @@ TEST_P(SurfaceTest, SetAlpha) {
{
surface->SetAlpha(1.f);
surface->Commit();
base::RunLoop().RunUntilIdle();
const viz::CompositorFrame& frame =
GetFrameFromSurface(shell_surface.get());
ASSERT_EQ(1u, frame.render_pass_list.size());
......@@ -852,7 +858,7 @@ TEST_P(SurfaceTest, RemoveSubSurface) {
child_surface->Attach(child_buffer.get());
child_surface->Commit();
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
// Remove the subsurface by destroying it. This should not damage |surface|.
// TODO(penghuang): Make the damage more precise for sub surface changes.
......@@ -870,7 +876,7 @@ TEST_P(SurfaceTest, DestroyAttachedBuffer) {
surface->Attach(buffer.get());
surface->Commit();
RunAllPendingInMessageLoop();
base::RunLoop().RunUntilIdle();
// Make sure surface size is still valid after buffer is destroyed.
buffer.reset();
......
......@@ -4,9 +4,7 @@
#include "components/exo/wm_helper.h"
#include "ash/public/cpp/config.h"
#include "ash/shell.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/memory/singleton.h"
#include "ui/aura/client/drag_drop_delegate.h"
......@@ -220,11 +218,4 @@ double WMHelper::GetDefaultDeviceScaleFactor() const {
return 1.0f;
}
bool WMHelper::AreVerifiedSyncTokensNeeded() const {
// For mus and mash, the compositor isn't sharing GPU the channel with
// exo, so it cannot consume unverified sync token generated by exo.
// We need verify sync tokens before sending them to the compositor.
return ash::Shell::GetAshConfig() != ash::Config::CLASSIC;
}
} // namespace exo
......@@ -97,7 +97,6 @@ class WMHelper : public aura::client::DragDropDelegate {
void RemovePostTargetHandler(ui::EventHandler* handler);
bool IsTabletModeWindowManagerEnabled() const;
double GetDefaultDeviceScaleFactor() const;
bool AreVerifiedSyncTokensNeeded() const;
// Overridden from aura::client::DragDropDelegate:
void OnDragEntered(const ui::DropTargetEvent& event) override;
......
......@@ -36,7 +36,6 @@ jumbo_component("aura") {
"input_state_lookup.h",
"input_state_lookup_win.h",
"layout_manager.h",
"local/layer_tree_frame_sink_local.h",
"local/window_port_local.h",
"mus/capture_synchronizer.h",
"mus/capture_synchronizer_delegate.h",
......@@ -109,7 +108,6 @@ jumbo_component("aura") {
"input_state_lookup.cc",
"input_state_lookup_win.cc",
"layout_manager.cc",
"local/layer_tree_frame_sink_local.cc",
"local/window_port_local.cc",
"mouse_location_manager.cc",
"mouse_location_manager.h",
......
include_rules = [
"+cc/mojo_embedder",
"+cc/output",
"+cc/scheduler",
"+components/viz/service/frame_sinks",
......
// Copyright 2017 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 "ui/aura/local/layer_tree_frame_sink_local.h"
#include "cc/trees/layer_tree_frame_sink_client.h"
#include "components/viz/common/surfaces/surface_info.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
namespace aura {
LayerTreeFrameSinkLocal::LayerTreeFrameSinkLocal(
const viz::FrameSinkId& frame_sink_id,
viz::HostFrameSinkManager* host_frame_sink_manager,
const std::string& debug_label)
: cc::LayerTreeFrameSink(nullptr, nullptr, nullptr, nullptr),
frame_sink_id_(frame_sink_id),
host_frame_sink_manager_(host_frame_sink_manager) {
host_frame_sink_manager_->RegisterFrameSinkId(frame_sink_id_, this);
host_frame_sink_manager_->SetFrameSinkDebugLabel(frame_sink_id_, debug_label);
}
LayerTreeFrameSinkLocal::~LayerTreeFrameSinkLocal() {
host_frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id_);
}
bool LayerTreeFrameSinkLocal::BindToClient(
cc::LayerTreeFrameSinkClient* client) {
if (!cc::LayerTreeFrameSink::BindToClient(client))
return false;
DCHECK(!thread_checker_);
thread_checker_ = std::make_unique<base::ThreadChecker>();
support_ = host_frame_sink_manager_->CreateCompositorFrameSinkSupport(
this, frame_sink_id_, false /* is_root */,
true /* needs_sync_points */);
begin_frame_source_ = std::make_unique<viz::ExternalBeginFrameSource>(this);
client->SetBeginFrameSource(begin_frame_source_.get());
return true;
}
void LayerTreeFrameSinkLocal::SetSurfaceChangedCallback(
const SurfaceChangedCallback& callback) {
DCHECK(!surface_changed_callback_);
surface_changed_callback_ = callback;
}
void LayerTreeFrameSinkLocal::DetachFromClient() {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
client_->SetBeginFrameSource(nullptr);
begin_frame_source_.reset();
support_.reset();
thread_checker_.reset();
cc::LayerTreeFrameSink::DetachFromClient();
}
void LayerTreeFrameSinkLocal::SetLocalSurfaceId(
const viz::LocalSurfaceId& local_surface_id) {
DCHECK(local_surface_id.is_valid());
local_surface_id_ = local_surface_id;
}
void LayerTreeFrameSinkLocal::SubmitCompositorFrame(
viz::CompositorFrame frame) {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
DCHECK(frame.metadata.begin_frame_ack.has_damage);
DCHECK_LE(viz::BeginFrameArgs::kStartingFrameNumber,
frame.metadata.begin_frame_ack.sequence_number);
DCHECK(local_surface_id_.is_valid());
support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
}
void LayerTreeFrameSinkLocal::DidNotProduceFrame(
const viz::BeginFrameAck& ack) {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
DCHECK(!ack.has_damage);
DCHECK_LE(viz::BeginFrameArgs::kStartingFrameNumber, ack.sequence_number);
support_->DidNotProduceFrame(ack);
}
void LayerTreeFrameSinkLocal::DidAllocateSharedBitmap(
mojo::ScopedSharedBufferHandle buffer,
const viz::SharedBitmapId& id) {
// No software compositing used with this implementation.
NOTIMPLEMENTED();
}
void LayerTreeFrameSinkLocal::DidDeleteSharedBitmap(
const viz::SharedBitmapId& id) {
// No software compositing used with this implementation.
NOTIMPLEMENTED();
}
void LayerTreeFrameSinkLocal::DidReceiveCompositorFrameAck(
const std::vector<viz::ReturnedResource>& resources) {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
if (!client_)
return;
if (!resources.empty())
client_->ReclaimResources(resources);
client_->DidReceiveCompositorFrameAck();
}
void LayerTreeFrameSinkLocal::DidPresentCompositorFrame(
uint32_t presentation_token,
const gfx::PresentationFeedback& feedback) {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
client_->DidPresentCompositorFrame(presentation_token, feedback);
}
void LayerTreeFrameSinkLocal::OnBeginFrame(const viz::BeginFrameArgs& args) {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
begin_frame_source_->OnBeginFrame(args);
}
void LayerTreeFrameSinkLocal::OnBeginFramePausedChanged(bool paused) {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
begin_frame_source_->OnSetBeginFrameSourcePaused(paused);
}
void LayerTreeFrameSinkLocal::ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
if (!client_)
return;
client_->ReclaimResources(resources);
}
void LayerTreeFrameSinkLocal::OnNeedsBeginFrames(bool needs_begin_frames) {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
support_->SetNeedsBeginFrame(needs_begin_frames);
}
void LayerTreeFrameSinkLocal::OnFirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
surface_changed_callback_.Run(surface_info);
}
void LayerTreeFrameSinkLocal::OnFrameTokenChanged(uint32_t frame_token) {
// TODO(yiyix, fsamuel): Implement frame token propagation for
// LayerTreeFrameSinkLocal.
NOTREACHED();
}
} // namespace aura
// Copyright 2017 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 UI_AURA_LOCAL_LAYER_TREE_FRAME_SINK_LOCAL_H_
#define UI_AURA_LOCAL_LAYER_TREE_FRAME_SINK_LOCAL_H_
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/host/host_frame_sink_client.h"
#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h"
#include "ui/aura/window_port.h"
#include "ui/base/property_data.h"
namespace viz {
class CompositorFrameSinkSupport;
class HostFrameSinkManager;
}
namespace aura {
// cc::LayerTreeFrameSink implementation for classic aura, e.g. not mus.
// aura::Window::CreateLayerTreeFrameSink creates this class for a given
// aura::Window, and then the sink can be used for submitting frames to the
// aura::Window's ui::Layer.
class LayerTreeFrameSinkLocal : public cc::LayerTreeFrameSink,
public viz::mojom::CompositorFrameSinkClient,
public viz::ExternalBeginFrameSourceClient,
public viz::HostFrameSinkClient {
public:
LayerTreeFrameSinkLocal(const viz::FrameSinkId& frame_sink_id,
viz::HostFrameSinkManager* host_frame_sink_manager,
const std::string& debug_label);
~LayerTreeFrameSinkLocal() override;
using SurfaceChangedCallback = base::Callback<void(const viz::SurfaceInfo&)>;
// Set a callback which will be called when the surface is changed.
void SetSurfaceChangedCallback(const SurfaceChangedCallback& callback);
const viz::LocalSurfaceId& local_surface_id() const {
return local_surface_id_;
}
// cc::LayerTreeFrameSink:
bool BindToClient(cc::LayerTreeFrameSinkClient* client) override;
void DetachFromClient() override;
void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) override;
void SubmitCompositorFrame(viz::CompositorFrame frame) override;
void DidNotProduceFrame(const viz::BeginFrameAck& ack) override;
void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
const viz::SharedBitmapId& id) override;
void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override;
// viz::mojom::CompositorFrameSinkClient:
void DidReceiveCompositorFrameAck(
const std::vector<viz::ReturnedResource>& resources) override;
void DidPresentCompositorFrame(
uint32_t presentation_token,
const gfx::PresentationFeedback& feedback) override;
void OnBeginFrame(const viz::BeginFrameArgs& args) override;
void ReclaimResources(
const std::vector<viz::ReturnedResource>& resources) override;
void OnBeginFramePausedChanged(bool paused) override;
// viz::ExternalBeginFrameSourceClient:
void OnNeedsBeginFrames(bool needs_begin_frames) override;
private:
// public viz::HostFrameSinkClient:
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
void OnFrameTokenChanged(uint32_t frame_token) override;
const viz::FrameSinkId frame_sink_id_;
viz::HostFrameSinkManager* const host_frame_sink_manager_;
std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
gfx::Size surface_size_;
viz::LocalSurfaceId local_surface_id_;
std::unique_ptr<viz::ExternalBeginFrameSource> begin_frame_source_;
std::unique_ptr<base::ThreadChecker> thread_checker_;
SurfaceChangedCallback surface_changed_callback_;
DISALLOW_COPY_AND_ASSIGN(LayerTreeFrameSinkLocal);
};
} // namespace aura
#endif // UI_AURA_LOCAL_LAYER_TREE_FRAME_SINK_LOCAL_H_
......@@ -4,10 +4,14 @@
#include "ui/aura/local/window_port_local.h"
#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
#include "components/viz/client/hit_test_data_provider_draw_quad.h"
#include "components/viz/client/local_surface_id_provider.h"
#include "components/viz/common/features.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
#include "ui/aura/hit_test_data_provider_aura.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/layout.h"
......@@ -61,7 +65,15 @@ class ScopedCursorHider {
WindowPortLocal::WindowPortLocal(Window* window)
: window_(window), weak_factory_(this) {}
WindowPortLocal::~WindowPortLocal() {}
WindowPortLocal::~WindowPortLocal() {
if (frame_sink_id_.is_valid()) {
auto* context_factory_private =
aura::Env::GetInstance()->context_factory_private();
auto* host_frame_sink_manager =
context_factory_private->GetHostFrameSinkManager();
host_frame_sink_manager->InvalidateFrameSinkId(frame_sink_id_);
}
}
void WindowPortLocal::OnPreInit(Window* window) {}
......@@ -120,15 +132,44 @@ void WindowPortLocal::OnPropertyChanged(
std::unique_ptr<cc::LayerTreeFrameSink>
WindowPortLocal::CreateLayerTreeFrameSink() {
DCHECK(!frame_sink_id_.is_valid());
auto* context_factory_private =
aura::Env::GetInstance()->context_factory_private();
auto frame_sink_id = context_factory_private->AllocateFrameSinkId();
auto frame_sink = std::make_unique<LayerTreeFrameSinkLocal>(
frame_sink_id, context_factory_private->GetHostFrameSinkManager(),
window_->GetName());
window_->SetEmbedFrameSinkId(frame_sink_id);
frame_sink->SetSurfaceChangedCallback(base::Bind(
&WindowPortLocal::OnSurfaceChanged, weak_factory_.GetWeakPtr()));
auto* host_frame_sink_manager =
context_factory_private->GetHostFrameSinkManager();
frame_sink_id_ = context_factory_private->AllocateFrameSinkId();
// For creating a async frame sink which connects to the viz display
// compositor.
viz::mojom::CompositorFrameSinkPtrInfo sink_info;
viz::mojom::CompositorFrameSinkRequest sink_request =
mojo::MakeRequest(&sink_info);
viz::mojom::CompositorFrameSinkClientPtr client;
viz::mojom::CompositorFrameSinkClientRequest client_request =
mojo::MakeRequest(&client);
host_frame_sink_manager->RegisterFrameSinkId(frame_sink_id_, this);
window_->SetEmbedFrameSinkId(frame_sink_id_);
host_frame_sink_manager->CreateCompositorFrameSink(
frame_sink_id_, std::move(sink_request), std::move(client));
cc::mojo_embedder::AsyncLayerTreeFrameSink::InitParams params;
params.gpu_memory_buffer_manager =
aura::Env::GetInstance()->context_factory()->GetGpuMemoryBufferManager();
params.pipes.compositor_frame_sink_info = std::move(sink_info);
params.pipes.client_request = std::move(client_request);
params.enable_surface_synchronization = true;
if (features::IsVizHitTestingDrawQuadEnabled()) {
params.hit_test_data_provider =
std::make_unique<viz::HitTestDataProviderDrawQuad>(
true /* should_ask_for_child_region */);
} else {
params.hit_test_data_provider =
std::make_unique<HitTestDataProviderAura>(window_);
}
auto frame_sink =
std::make_unique<cc::mojo_embedder::AsyncLayerTreeFrameSink>(
nullptr /* context_provider */, nullptr /* worker_context_provider */,
&params);
frame_sink_ = frame_sink->GetWeakPtr();
AllocateLocalSurfaceId();
return std::move(frame_sink);
......@@ -136,7 +177,7 @@ WindowPortLocal::CreateLayerTreeFrameSink() {
void WindowPortLocal::AllocateLocalSurfaceId() {
if (!parent_local_surface_id_allocator_)
parent_local_surface_id_allocator_ = viz::ParentLocalSurfaceIdAllocator();
parent_local_surface_id_allocator_.emplace();
else
parent_local_surface_id_allocator_->GenerateId();
UpdateLocalSurfaceId();
......@@ -168,9 +209,13 @@ const viz::LocalSurfaceId& WindowPortLocal::GetLocalSurfaceId() {
void WindowPortLocal::OnEventTargetingPolicyChanged() {}
void WindowPortLocal::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
bool WindowPortLocal::ShouldRestackTransientChildren() {
return true;
}
void WindowPortLocal::OnFirstSurfaceActivation(
const viz::SurfaceInfo& surface_info) {
DCHECK_EQ(surface_info.id().frame_sink_id(), window_->GetFrameSinkId());
DCHECK_EQ(surface_info.id().local_surface_id(), GetCurrentLocalSurfaceId());
window_->layer()->SetShowPrimarySurface(
surface_info.id(), window_->bounds().size(), SK_ColorWHITE,
cc::DeadlinePolicy::UseDefaultDeadline(),
......@@ -178,9 +223,7 @@ void WindowPortLocal::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
window_->layer()->SetFallbackSurfaceId(surface_info.id());
}
bool WindowPortLocal::ShouldRestackTransientChildren() {
return true;
}
void WindowPortLocal::OnFrameTokenChanged(uint32_t frame_token) {}
void WindowPortLocal::UpdateLocalSurfaceId() {
last_device_scale_factor_ = ui::GetScaleFactorForNativeView(window_);
......
......@@ -10,7 +10,7 @@
#include "base/optional.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
#include "components/viz/host/host_frame_sink_client.h"
#include "ui/aura/window_port.h"
#include "ui/base/property_data.h"
#include "ui/gfx/geometry/size.h"
......@@ -24,7 +24,8 @@ namespace aura {
class Window;
// WindowPort implementation for classic aura, e.g. not mus.
class AURA_EXPORT WindowPortLocal : public WindowPort {
class AURA_EXPORT WindowPortLocal : public WindowPort,
public viz::HostFrameSinkClient {
public:
explicit WindowPortLocal(Window* window);
~WindowPortLocal() override;
......@@ -57,8 +58,11 @@ class AURA_EXPORT WindowPortLocal : public WindowPort {
void OnEventTargetingPolicyChanged() override;
bool ShouldRestackTransientChildren() override;
// viz::HostFrameSinkClient:
void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override;
void OnFrameTokenChanged(uint32_t frame_token) override;
private:
void OnSurfaceChanged(const viz::SurfaceInfo& surface_info);
void UpdateLocalSurfaceId();
const viz::LocalSurfaceId& GetCurrentLocalSurfaceId() const;
bool IsEmbeddingExternalContent() const;
......@@ -69,6 +73,7 @@ class AURA_EXPORT WindowPortLocal : public WindowPort {
base::Optional<viz::ParentLocalSurfaceIdAllocator>
parent_local_surface_id_allocator_;
base::WeakPtr<cc::LayerTreeFrameSink> frame_sink_;
viz::FrameSinkId frame_sink_id_;
base::WeakPtrFactory<WindowPortLocal> weak_factory_;
......
......@@ -628,10 +628,4 @@ void WindowPortMus::UpdateClientSurfaceEmbedder() {
client_surface_embedder_->SetFallbackSurfaceInfo(fallback_surface_info_);
}
void WindowPortMus::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
// TODO(fsamuel): Rename OnFirstSurfaceActivation() and set primary earlier
// based on feedback from LayerTreeFrameSinkLocal.
NOTREACHED();
}
} // namespace aura
......@@ -20,7 +20,6 @@
#include "services/ui/public/interfaces/window_tree.mojom.h"
#include "services/ui/public/interfaces/window_tree_constants.mojom.h"
#include "ui/aura/aura_export.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
#include "ui/aura/mus/mus_types.h"
#include "ui/aura/mus/window_mus.h"
#include "ui/aura/window_port.h"
......@@ -33,6 +32,14 @@ class AsyncLayerTreeFrameSink;
}
}
namespace gpu {
class GpuMemoryBufferManager;
}
namespace viz {
class ContextProvider;
}
namespace aura {
class ClientSurfaceEmbedder;
......@@ -282,8 +289,6 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
void UpdatePrimarySurfaceId();
void UpdateClientSurfaceEmbedder();
void OnSurfaceChanged(const viz::SurfaceInfo& surface_info);
WindowTreeClient* window_tree_client_;
Window* window_ = nullptr;
......
......@@ -6,7 +6,6 @@
#include "cc/mojo_embedder/async_layer_tree_frame_sink.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
#include "ui/aura/mus/client_surface_embedder.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window.h"
......
......@@ -10,7 +10,6 @@
#include "ui/aura/client/focus_client.h"
#include "ui/aura/env.h"
#include "ui/aura/input_state_lookup.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
#include "ui/aura/mus/capture_synchronizer.h"
#include "ui/aura/mus/focus_synchronizer.h"
#include "ui/aura/mus/window_port_mus.h"
......
......@@ -30,7 +30,6 @@
#include "ui/aura/client/window_stacking_client.h"
#include "ui/aura/env.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
#include "ui/aura/scoped_keyboard_hook.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_event_dispatcher.h"
......
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