Commit 2af53e7b authored by Dominik Laskowski's avatar Dominik Laskowski Committed by Commit Bot

exo: Compute SurfaceTreeHost bounds recursively

The RenderPass::output_rect and host window bounds for SurfaceTreeHost
were set to the content size of the root surface. Hence, surfaces were
clipped to the viewport (0, 0) × (W, H), where (W, H) is the size of
the root surface. The root surface of ARC windows is sized to match
the Android display.

This CL computes the output_rect as the bounding box of the surface
tree, and resizes the host window to match the output_rect.

Bug: b:64893967
Test: Windows whose bounds exceed the bottom/right edges of the display
      are not clipped in overview mode.

Change-Id: I51ddf7405e703f5c546aec88a01cc004d105b18a
Reviewed-on: https://chromium-review.googlesource.com/639472
Commit-Queue: Dominik Laskowski <domlaskowski@chromium.org>
Reviewed-by: default avatarDavid Reveman <reveman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#505871}
parent 9aead409
...@@ -35,20 +35,14 @@ const gfx::Size& NotificationSurface::GetContentSize() const { ...@@ -35,20 +35,14 @@ const gfx::Size& NotificationSurface::GetContentSize() const {
void NotificationSurface::OnSurfaceCommit() { void NotificationSurface::OnSurfaceCommit() {
SurfaceTreeHost::OnSurfaceCommit(); SurfaceTreeHost::OnSurfaceCommit();
SubmitCompositorFrame();
gfx::Rect bounds = host_window()->bounds();
auto& size = host_window()->bounds().size();
if (bounds.size() != size) {
bounds.set_size(size);
host_window()->SetBounds(bounds);
}
// Defer AddSurface until there are contents to show. // Defer AddSurface until there are contents to show.
if (!added_to_manager_ && !size.IsEmpty()) { if (!added_to_manager_ && !host_window()->bounds().IsEmpty()) {
added_to_manager_ = true; added_to_manager_ = true;
manager_->AddSurface(this); manager_->AddSurface(this);
} }
SubmitCompositorFrame();
} }
void NotificationSurface::OnSurfaceDestroying(Surface* surface) { void NotificationSurface::OnSurfaceDestroying(Surface* surface) {
......
...@@ -156,11 +156,12 @@ gfx::NativeCursor Pointer::GetCursor() { ...@@ -156,11 +156,12 @@ gfx::NativeCursor Pointer::GetCursor() {
void Pointer::OnSurfaceCommit() { void Pointer::OnSurfaceCommit() {
SurfaceTreeHost::OnSurfaceCommit(); SurfaceTreeHost::OnSurfaceCommit();
SubmitCompositorFrame();
// Capture new cursor to reflect result of commit. // Capture new cursor to reflect result of commit.
if (focus_surface_) if (focus_surface_ && !host_window()->bounds().IsEmpty())
CaptureCursor(hotspot_); CaptureCursor(hotspot_);
SubmitCompositorFrame();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
......
...@@ -771,7 +771,7 @@ void ShellSurface::OnSurfaceCommit() { ...@@ -771,7 +771,7 @@ void ShellSurface::OnSurfaceCommit() {
if (enabled() && !widget_) { if (enabled() && !widget_) {
// Defer widget creation until surface contains some contents. // Defer widget creation until surface contains some contents.
if (root_surface()->content_size().IsEmpty()) { if (host_window()->bounds().IsEmpty()) {
Configure(); Configure();
return; return;
} }
...@@ -1623,8 +1623,11 @@ bool ShellSurface::IsResizing() const { ...@@ -1623,8 +1623,11 @@ bool ShellSurface::IsResizing() const {
gfx::Rect ShellSurface::GetVisibleBounds() const { gfx::Rect ShellSurface::GetVisibleBounds() const {
// Use |geometry_| if set, otherwise use the visual bounds of the surface. // Use |geometry_| if set, otherwise use the visual bounds of the surface.
return geometry_.IsEmpty() ? gfx::Rect(host_window()->bounds().size()) if (!geometry_.IsEmpty())
: geometry_; return geometry_;
return root_surface() ? gfx::Rect(root_surface()->content_size())
: gfx::Rect();
} }
gfx::Point ShellSurface::GetSurfaceOrigin() const { gfx::Point ShellSurface::GetSurfaceOrigin() const {
......
...@@ -100,8 +100,6 @@ void SubSurface::OnSurfaceCommit() { ...@@ -100,8 +100,6 @@ void SubSurface::OnSurfaceCommit() {
NOTIMPLEMENTED() << "Async subsurface is not supported!"; NOTIMPLEMENTED() << "Async subsurface is not supported!";
} }
void SubSurface::OnSurfaceContentSizeChanged() {}
bool SubSurface::IsSurfaceSynchronized() const { bool SubSurface::IsSurfaceSynchronized() const {
// A sub-surface is effectively synchronized if either its parent is // A sub-surface is effectively synchronized if either its parent is
// synchronized or itself is in synchronized mode. // synchronized or itself is in synchronized mode.
......
...@@ -50,7 +50,6 @@ class SubSurface : public SurfaceDelegate, public SurfaceObserver { ...@@ -50,7 +50,6 @@ class SubSurface : public SurfaceDelegate, public SurfaceObserver {
// Overridden from SurfaceDelegate: // Overridden from SurfaceDelegate:
void OnSurfaceCommit() override; void OnSurfaceCommit() override;
void OnSurfaceContentSizeChanged() override;
bool IsSurfaceSynchronized() const override; bool IsSurfaceSynchronized() const override;
void OnSetFrame(SurfaceFrameType type) override {} void OnSetFrame(SurfaceFrameType type) override {}
......
...@@ -433,8 +433,7 @@ void Surface::Commit() { ...@@ -433,8 +433,7 @@ void Surface::Commit() {
delegate_->OnSurfaceCommit(); delegate_->OnSurfaceCommit();
} }
void Surface::CommitSurfaceHierarchy( gfx::Rect Surface::CommitSurfaceHierarchy(
const gfx::Point& origin,
std::list<FrameCallback>* frame_callbacks, std::list<FrameCallback>* frame_callbacks,
std::list<PresentationCallback>* presentation_callbacks) { std::list<PresentationCallback>* presentation_callbacks) {
if (needs_commit_surface_) { if (needs_commit_surface_) {
...@@ -517,16 +516,21 @@ void Surface::CommitSurfaceHierarchy( ...@@ -517,16 +516,21 @@ void Surface::CommitSurfaceHierarchy(
pending_damage_.setEmpty(); pending_damage_.setEmpty();
} }
gfx::Rect bounds(content_size_);
// The top most sub-surface is at the front of the RenderPass's quad_list, // The top most sub-surface is at the front of the RenderPass's quad_list,
// so we need composite sub-surface in reversed order. // so we need composite sub-surface in reversed order.
for (const auto& sub_surface_entry : base::Reversed(sub_surfaces_)) { for (const auto& sub_surface_entry : base::Reversed(sub_surfaces_)) {
auto* sub_surface = sub_surface_entry.first; auto* sub_surface = sub_surface_entry.first;
// Synchronsouly commit all pending state of the sub-surface and its gfx::Point origin = sub_surface_entry.second;
// decendents. // Synchronously commit all pending state of the sub-surface and its
sub_surface->CommitSurfaceHierarchy( // descendants.
origin + sub_surface_entry.second.OffsetFromOrigin(), frame_callbacks, bounds.Union(sub_surface->CommitSurfaceHierarchy(frame_callbacks,
presentation_callbacks); presentation_callbacks) +
origin.OffsetFromOrigin());
} }
return bounds;
} }
void Surface::AppendSurfaceHierarchyContentsToFrame( void Surface::AppendSurfaceHierarchyContentsToFrame(
...@@ -762,12 +766,14 @@ void Surface::AppendContentsToFrame(const gfx::Point& origin, ...@@ -762,12 +766,14 @@ void Surface::AppendContentsToFrame(const gfx::Point& origin,
gfx::Rect output_rect(origin, content_size_); gfx::Rect output_rect(origin, content_size_);
gfx::Rect quad_rect(0, 0, 1, 1); gfx::Rect quad_rect(0, 0, 1, 1);
// Surface uses DIP, but the |render_pass->damage_rect| uses pixels, so we // Surface bounds are in DIPs, but |damage_rect| and |output_rect| are in
// need scale it beased on the |device_scale_factor|. // pixels, so we need to scale by the |device_scale_factor|.
gfx::Rect damage_rect = gfx::SkIRectToRect(damage_.getBounds()); gfx::Rect damage_rect = gfx::SkIRectToRect(damage_.getBounds());
damage_rect.Offset(origin.x(), origin.y()); damage_rect.Offset(origin.x(), origin.y());
render_pass->damage_rect.Union( render_pass->damage_rect.Union(
gfx::ConvertRectToPixel(device_scale_factor, damage_rect)); gfx::ConvertRectToPixel(device_scale_factor, damage_rect));
render_pass->output_rect.Union(
gfx::ConvertRectToPixel(device_scale_factor, output_rect));
// Compute the total transformation from post-transform buffer coordinates to // Compute the total transformation from post-transform buffer coordinates to
// target coordinates. // target coordinates.
...@@ -791,8 +797,8 @@ void Surface::AppendContentsToFrame(const gfx::Point& origin, ...@@ -791,8 +797,8 @@ void Surface::AppendContentsToFrame(const gfx::Point& origin,
viz::SharedQuadState* quad_state = viz::SharedQuadState* quad_state =
render_pass->CreateAndAppendSharedQuadState(); render_pass->CreateAndAppendSharedQuadState();
quad_state->SetAll( quad_state->SetAll(
quad_to_target_transform, gfx::Rect(content_size_) /* quad_layer_rect */, quad_to_target_transform, quad_rect /* quad_layer_rect */,
output_rect /* visible_quad_layer_rect */, gfx::Rect() /* clip_rect */, quad_rect /* visible_quad_layer_rect */, gfx::Rect() /* clip_rect */,
false /* is_clipped */, are_contents_opaque, state_.alpha /* opacity */, false /* is_clipped */, are_contents_opaque, state_.alpha /* opacity */,
SkBlendMode::kSrcOver /* blend_mode */, 0 /* sorting_context_id */); SkBlendMode::kSrcOver /* blend_mode */, 0 /* sorting_context_id */);
...@@ -864,8 +870,6 @@ void Surface::UpdateContentSize() { ...@@ -864,8 +870,6 @@ void Surface::UpdateContentSize() {
if (content_size_ != content_size) { if (content_size_ != content_size) {
content_size_ = content_size; content_size_ = content_size;
window_->SetBounds(gfx::Rect(window_->bounds().origin(), content_size_)); window_->SetBounds(gfx::Rect(window_->bounds().origin(), content_size_));
if (delegate_)
delegate_->OnSurfaceContentSizeChanged();
} }
} }
......
...@@ -145,9 +145,9 @@ class Surface final : public ui::PropertyHandler { ...@@ -145,9 +145,9 @@ class Surface final : public ui::PropertyHandler {
// This will synchronously commit all pending state of the surface and its // This will synchronously commit all pending state of the surface and its
// descendants by recursively calling CommitSurfaceHierarchy() for each // descendants by recursively calling CommitSurfaceHierarchy() for each
// sub-surface with pending state. // sub-surface with pending state. Returns the bounding box of the surface
void CommitSurfaceHierarchy( // and its descendants, in the local coordinate space of the surface.
const gfx::Point& origin, gfx::Rect CommitSurfaceHierarchy(
std::list<FrameCallback>* frame_callbacks, std::list<FrameCallback>* frame_callbacks,
std::list<PresentationCallback>* presentation_callbacks); std::list<PresentationCallback>* presentation_callbacks);
......
...@@ -16,9 +16,6 @@ class SurfaceDelegate { ...@@ -16,9 +16,6 @@ class SurfaceDelegate {
// Called when surface was requested to commit all double-buffered state. // Called when surface was requested to commit all double-buffered state.
virtual void OnSurfaceCommit() = 0; virtual void OnSurfaceCommit() = 0;
// Called when surface content size was changed.
virtual void OnSurfaceContentSizeChanged() = 0;
// Returns true if surface is in synchronized mode. ie. commit of // Returns true if surface is in synchronized mode. ie. commit of
// double-buffered state should be synchronized with parent surface. // double-buffered state should be synchronized with parent surface.
virtual bool IsSurfaceSynchronized() const = 0; virtual bool IsSurfaceSynchronized() const = 0;
......
...@@ -143,8 +143,6 @@ void SurfaceTreeHost::SetRootSurface(Surface* root_surface) { ...@@ -143,8 +143,6 @@ void SurfaceTreeHost::SetRootSurface(Surface* root_surface) {
root_surface_ = root_surface; root_surface_ = root_surface;
root_surface_->SetSurfaceDelegate(this); root_surface_->SetSurfaceDelegate(this);
host_window_->AddChild(root_surface_->window()); host_window_->AddChild(root_surface_->window());
host_window_->SetBounds(gfx::Rect(host_window_->bounds().origin(),
root_surface_->content_size()));
root_surface_->window()->Show(); root_surface_->window()->Show();
} }
} }
...@@ -202,13 +200,14 @@ void SurfaceTreeHost::UpdateNeedsBeginFrame() { ...@@ -202,13 +200,14 @@ void SurfaceTreeHost::UpdateNeedsBeginFrame() {
// SurfaceDelegate overrides: // SurfaceDelegate overrides:
void SurfaceTreeHost::OnSurfaceCommit() { void SurfaceTreeHost::OnSurfaceCommit() {
root_surface_->CommitSurfaceHierarchy(gfx::Point(), &frame_callbacks_, gfx::Rect bounds = root_surface_->CommitSurfaceHierarchy(
&presentation_callbacks_); &frame_callbacks_, &presentation_callbacks_);
}
void SurfaceTreeHost::OnSurfaceContentSizeChanged() { host_window_->SetBounds(
host_window_->SetBounds(gfx::Rect(host_window_->bounds().origin(), gfx::Rect(host_window_->bounds().origin(), bounds.size()));
root_surface_->content_size())); host_window_->layer()->SetFillsBoundsOpaquely(
bounds.size() == root_surface_->content_size() &&
root_surface_->FillsBoundsOpaquely());
} }
bool SurfaceTreeHost::IsSurfaceSynchronized() const { bool SurfaceTreeHost::IsSurfaceSynchronized() const {
...@@ -307,24 +306,17 @@ void SurfaceTreeHost::SubmitCompositorFrame() { ...@@ -307,24 +306,17 @@ void SurfaceTreeHost::SubmitCompositorFrame() {
current_begin_frame_ack_.has_damage = true; current_begin_frame_ack_.has_damage = true;
} }
frame.metadata.begin_frame_ack = current_begin_frame_ack_; frame.metadata.begin_frame_ack = current_begin_frame_ack_;
frame.render_pass_list.push_back(viz::RenderPass::Create());
const std::unique_ptr<viz::RenderPass>& render_pass =
frame.render_pass_list.back();
const int kRenderPassId = 1; const int kRenderPassId = 1;
std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create();
render_pass->SetNew(kRenderPassId, gfx::Rect(), gfx::Rect(), render_pass->SetNew(kRenderPassId, gfx::Rect(), gfx::Rect(),
gfx::Transform()); gfx::Transform());
frame.render_pass_list.push_back(std::move(render_pass));
float device_scale_factor = host_window()->layer()->device_scale_factor(); float device_scale_factor = host_window()->layer()->device_scale_factor();
frame.metadata.device_scale_factor = device_scale_factor;
root_surface_->AppendSurfaceHierarchyContentsToFrame( root_surface_->AppendSurfaceHierarchyContentsToFrame(
gfx::Point(), device_scale_factor, layer_tree_frame_sink_holder_.get(), gfx::Point(), device_scale_factor, layer_tree_frame_sink_holder_.get(),
&frame); &frame);
// Surface uses DIP, but the |output_rect| uses pixels, so we need
// scale it beased on the |device_scale_factor|.
frame.render_pass_list.back()->output_rect =
gfx::Rect(gfx::ConvertSizeToPixel(device_scale_factor,
root_surface_->content_size()));
host_window_->layer()->SetFillsBoundsOpaquely(
root_surface_->FillsBoundsOpaquely());
frame.metadata.device_scale_factor = device_scale_factor;
layer_tree_frame_sink_holder_->frame_sink()->SubmitCompositorFrame( layer_tree_frame_sink_holder_->frame_sink()->SubmitCompositorFrame(
std::move(frame)); std::move(frame));
......
...@@ -83,7 +83,6 @@ class SurfaceTreeHost : public SurfaceDelegate, ...@@ -83,7 +83,6 @@ class SurfaceTreeHost : public SurfaceDelegate,
// Overridden from SurfaceDelegate: // Overridden from SurfaceDelegate:
void OnSurfaceCommit() override; void OnSurfaceCommit() override;
void OnSurfaceContentSizeChanged() override;
bool IsSurfaceSynchronized() const override; bool IsSurfaceSynchronized() const override;
void OnSetFrame(SurfaceFrameType type) override {} void OnSetFrame(SurfaceFrameType type) override {}
......
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