Commit c1a826ab authored by Malay Keshav's avatar Malay Keshav Committed by Commit Bot

Set correct pixel size for the compositor

Right now we clip(GL_SCISSOR) the display buffer based on the physical
pixel size of the display. The pixel size we send to the ui compositor
is the size we receive from the platform window(the display in Chrome
OS). However, this may not be what we want if the platform has some
fractional scale applied.

UI elements have their sizes set in DIP. If some UI element (ui::Layer)
has its size set to the DIP size of the display, their scaled size
(the pixel size after applying device scale factor) after rounding may
not match the physical pixel size of the display. This difference may
lead to 1px lines left unclipped. This happens in the case of the shelf
whose width is set to the width of the display. For a device like eve
where the internal display has a physical resolution width of 2400px,
if a device scale of 1.8 is applied, the DIP width of the display
becomes 1333. We set the bounds of the shelf to this. Now when we do
the actual paint, we scale the shelf to its physical pixel size which
is ROUND(1333*1.8) = 2399. At the same time the compositor will clip
things at width 2400. This difference is what gives the shelf a 1px
gap.

A proper way to fix this is to scale ui::Layer bounds such that it
snaps to the parent's or displays edge similar to what pixel canvas
does in views::View. However, that is a large change. In the meantime
this patch sets the correct physical pixel size for the compositor so
that correct clipping happens.

Bug: 843354
Change-Id: Ic9e055c0ba39d85a7297809baf946398bf09f40a
Component: UI compositor, pixel canvas, scaling, HiDPI
Reviewed-on: https://chromium-review.googlesource.com/1130495Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarNico Weber <thakis@chromium.org>
Commit-Queue: Malay Keshav <malaykeshav@chromium.org>
Cr-Commit-Position: refs/heads/master@{#575402}
parent 39c09663
...@@ -54,7 +54,10 @@ void AshWindowTreeHostPlatform::ConfineCursorToRootWindow() { ...@@ -54,7 +54,10 @@ void AshWindowTreeHostPlatform::ConfineCursorToRootWindow() {
if (!allow_confine_cursor()) if (!allow_confine_cursor())
return; return;
gfx::Rect confined_bounds(GetBoundsInPixels().size()); // We want to limit the cursor to what is visible, which is the size of the
// compositor. |GetBoundsInPixels()| may include pixels that are not used.
// See https://crbug.com/843354
gfx::Rect confined_bounds(GetCompositorSizeInPixels());
confined_bounds.Inset(transformer_helper_.GetHostInsets()); confined_bounds.Inset(transformer_helper_.GetHostInsets());
last_cursor_confine_bounds_in_pixels_ = confined_bounds; last_cursor_confine_bounds_in_pixels_ = confined_bounds;
platform_window()->ConfineCursorToBounds(confined_bounds); platform_window()->ConfineCursorToBounds(confined_bounds);
...@@ -162,6 +165,33 @@ void AshWindowTreeHostPlatform::SetBoundsInPixels( ...@@ -162,6 +165,33 @@ void AshWindowTreeHostPlatform::SetBoundsInPixels(
ConfineCursorToRootWindow(); ConfineCursorToRootWindow();
} }
gfx::Size AshWindowTreeHostPlatform::GetCompositorSizeInPixels() const {
// For Chrome OS, the platform window size may be slightly different from the
// compositor pixel size. This is to prevent any trailing 1px line at the
// right or bottom edge due to rounding. This means we may not be using ALL
// the pixels on a display, however this is a temporary fix until we figure
// out a way to prevent these rounding artifacts.
// See https://crbug.com/843354 and https://crbug.com/862424 for more info.
if (device_scale_factor() == 1.f)
return GetBoundsInPixels().size();
return gfx::ScaleToRoundedSize(
gfx::ScaleToFlooredSize(GetBoundsInPixels().size(),
1.f / device_scale_factor()),
device_scale_factor());
}
void AshWindowTreeHostPlatform::OnBoundsChanged(const gfx::Rect& new_bounds) {
// We need to recompute the bounds in pixels based on the DIP size. This is a
// temporary fix needed because the root layer has the bounds in DIP which
// when scaled by the compositor does not match the display bounds in pixels.
// So we need to change the display bounds to match the root layer's scaled
// size.
// See https://crbug.com/843354 for more info.
const float new_scale = ui::GetScaleFactorForNativeView(window());
WindowTreeHostPlatform::OnBoundsChanged(gfx::ScaleToRoundedRect(
gfx::ScaleToEnclosedRect(new_bounds, 1.f / new_scale), new_scale));
}
void AshWindowTreeHostPlatform::DispatchEvent(ui::Event* event) { void AshWindowTreeHostPlatform::DispatchEvent(ui::Event* event) {
TRACE_EVENT0("input", "AshWindowTreeHostPlatform::DispatchEvent"); TRACE_EVENT0("input", "AshWindowTreeHostPlatform::DispatchEvent");
if (event->IsLocatedEvent()) if (event->IsLocatedEvent())
......
...@@ -61,6 +61,8 @@ class ASH_EXPORT AshWindowTreeHostPlatform ...@@ -61,6 +61,8 @@ class ASH_EXPORT AshWindowTreeHostPlatform
void OnCursorVisibilityChangedNative(bool show) override; void OnCursorVisibilityChangedNative(bool show) override;
void SetBoundsInPixels(const gfx::Rect& bounds, void SetBoundsInPixels(const gfx::Rect& bounds,
const viz::LocalSurfaceId& local_surface_id) override; const viz::LocalSurfaceId& local_surface_id) override;
gfx::Size GetCompositorSizeInPixels() const override;
void OnBoundsChanged(const gfx::Rect& new_bounds) override;
void DispatchEvent(ui::Event* event) override; void DispatchEvent(ui::Event* event) override;
// aura::InputMethodMusDelegate: // aura::InputMethodMusDelegate:
......
...@@ -277,6 +277,10 @@ void WindowTreeHost::Hide() { ...@@ -277,6 +277,10 @@ void WindowTreeHost::Hide() {
compositor()->SetVisible(false); compositor()->SetVisible(false);
} }
gfx::Size WindowTreeHost::GetCompositorSizeInPixels() const {
return GetBoundsInPixels().size();
}
std::unique_ptr<ScopedKeyboardHook> WindowTreeHost::CaptureSystemKeyEvents( std::unique_ptr<ScopedKeyboardHook> WindowTreeHost::CaptureSystemKeyEvents(
base::Optional<base::flat_set<ui::DomCode>> dom_codes) { base::Optional<base::flat_set<ui::DomCode>> dom_codes) {
// TODO(joedow): Remove the simple hook class/logic once this flag is removed. // TODO(joedow): Remove the simple hook class/logic once this flag is removed.
...@@ -359,7 +363,8 @@ void WindowTreeHost::CreateCompositor(const viz::FrameSinkId& frame_sink_id, ...@@ -359,7 +363,8 @@ void WindowTreeHost::CreateCompositor(const viz::FrameSinkId& frame_sink_id,
void WindowTreeHost::InitCompositor() { void WindowTreeHost::InitCompositor() {
DCHECK(!compositor_->root_layer()); DCHECK(!compositor_->root_layer());
compositor_->SetScaleAndSize(device_scale_factor_, GetBoundsInPixels().size(), compositor_->SetScaleAndSize(device_scale_factor_,
GetCompositorSizeInPixels(),
window()->GetLocalSurfaceId()); window()->GetLocalSurfaceId());
compositor_->SetRootLayer(window()->layer()); compositor_->SetRootLayer(window()->layer());
......
...@@ -197,6 +197,7 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, ...@@ -197,6 +197,7 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
const gfx::Rect& bounds_in_pixels, const gfx::Rect& bounds_in_pixels,
const viz::LocalSurfaceId& local_surface_id = viz::LocalSurfaceId()) = 0; const viz::LocalSurfaceId& local_surface_id = viz::LocalSurfaceId()) = 0;
virtual gfx::Rect GetBoundsInPixels() const = 0; virtual gfx::Rect GetBoundsInPixels() const = 0;
virtual gfx::Size GetCompositorSizeInPixels() const;
// Sets the OS capture to the root window. // Sets the OS capture to the root window.
virtual void SetCapture() = 0; virtual void SetCapture() = 0;
......
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