Commit 8b7c94c6 authored by fsamuel's avatar fsamuel Committed by Commit Bot

Aura-Mus: Fix high-DPI gutter

Previously, gutter did not take into account high-DPIness and didn't
convert from DIP to pixels and back correctly. This CL corrects this.

BUG=672962

Review-Url: https://codereview.chromium.org/2873473002
Cr-Commit-Position: refs/heads/master@{#475712}
parent ca7526ef
......@@ -6,6 +6,7 @@
#include "cc/surfaces/surface_reference_factory.h"
#include "ui/aura/window.h"
#include "ui/gfx/geometry/dip_util.h"
namespace aura {
namespace {
......@@ -65,22 +66,26 @@ void ClientSurfaceEmbedder::SetFallbackSurfaceInfo(
void ClientSurfaceEmbedder::UpdateSizeAndGutters() {
surface_layer_->SetBounds(gfx::Rect(window_->bounds().size()));
// TODO(fsamuel): Fix this for high DPI.
gfx::Size fallback_surface_size(
surface_layer_->GetFallbackSurfaceInfo()
? surface_layer_->GetFallbackSurfaceInfo()->size_in_pixels()
: gfx::Size());
gfx::Size fallback_surface_size_in_dip;
const cc::SurfaceInfo* fallback_surface_info =
surface_layer_->GetFallbackSurfaceInfo();
if (fallback_surface_info) {
float fallback_device_scale_factor =
fallback_surface_info->device_scale_factor();
fallback_surface_size_in_dip = gfx::ConvertSizeToDIP(
fallback_device_scale_factor, fallback_surface_info->size_in_pixels());
}
gfx::Rect window_bounds(window_->bounds());
if (fallback_surface_size.width() < window_bounds.width()) {
if (fallback_surface_size_in_dip.width() < window_bounds.width()) {
right_gutter_ = base::MakeUnique<ui::Layer>(ui::LAYER_SOLID_COLOR);
// TODO(fsamuel): Use the embedded client's background color.
right_gutter_->SetColor(SK_ColorWHITE);
int width = window_bounds.width() - fallback_surface_size.width();
int width = window_bounds.width() - fallback_surface_size_in_dip.width();
// The right gutter also includes the bottom-right corner, if necessary.
int height = window_bounds.height() - client_area_insets_.height();
right_gutter_->SetBounds(
gfx::Rect(client_area_insets_.left() + fallback_surface_size.width(),
client_area_insets_.top(), width, height));
right_gutter_->SetBounds(gfx::Rect(
client_area_insets_.left() + fallback_surface_size_in_dip.width(),
client_area_insets_.top(), width, height));
window_->layer()->Add(right_gutter_.get());
} else {
right_gutter_.reset();
......@@ -88,15 +93,15 @@ void ClientSurfaceEmbedder::UpdateSizeAndGutters() {
// Only create a bottom gutter if a fallback surface is available. Otherwise,
// the right gutter will fill the whole window until a fallback is available.
if (!fallback_surface_size.IsEmpty() &&
fallback_surface_size.height() < window_bounds.height()) {
if (!fallback_surface_size_in_dip.IsEmpty() &&
fallback_surface_size_in_dip.height() < window_bounds.height()) {
bottom_gutter_ = base::MakeUnique<ui::Layer>(ui::LAYER_SOLID_COLOR);
// TODO(fsamuel): Use the embedded client's background color.
bottom_gutter_->SetColor(SK_ColorWHITE);
int width = fallback_surface_size.width();
int height = window_bounds.height() - fallback_surface_size.height();
int width = fallback_surface_size_in_dip.width();
int height = window_bounds.height() - fallback_surface_size_in_dip.height();
bottom_gutter_->SetBounds(
gfx::Rect(0, fallback_surface_size.height(), width, height));
gfx::Rect(0, fallback_surface_size_in_dip.height(), width, height));
window_->layer()->Add(bottom_gutter_.get());
} else {
bottom_gutter_.reset();
......
......@@ -17,6 +17,7 @@
#include "ui/base/class_property.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/dip_util.h"
namespace aura {
......@@ -230,7 +231,9 @@ void WindowPortMus::SetBoundsFromServer(
ServerChangeData data;
data.bounds_in_dip = bounds;
ScopedServerChange change(this, ServerChangeType::BOUNDS, data);
last_surface_size_ = bounds.size();
float device_scale_factor = ScaleFactorForDisplay(window_);
last_surface_size_in_pixels_ =
gfx::ConvertSizeToPixel(device_scale_factor, bounds.size());
if (local_surface_id)
local_surface_id_ = *local_surface_id;
else
......@@ -284,12 +287,14 @@ void WindowPortMus::SetFrameSinkIdFromServer(
}
const cc::LocalSurfaceId& WindowPortMus::GetOrAllocateLocalSurfaceId(
const gfx::Size& surface_size) {
if (last_surface_size_ == surface_size && local_surface_id_.is_valid())
const gfx::Size& surface_size_in_pixels) {
if (last_surface_size_in_pixels_ == surface_size_in_pixels &&
local_surface_id_.is_valid()) {
return local_surface_id_;
}
local_surface_id_ = local_surface_id_allocator_.GenerateId();
last_surface_size_ = surface_size;
last_surface_size_in_pixels_ = surface_size_in_pixels;
// If the FrameSinkId is available, then immediately embed the SurfaceId.
// The newly generated frame by the embedder will block in the display
......@@ -533,9 +538,9 @@ void WindowPortMus::UpdatePrimarySurfaceInfo() {
if (!frame_sink_id_.is_valid() || !local_surface_id_.is_valid())
return;
SetPrimarySurfaceInfo(
cc::SurfaceInfo(cc::SurfaceId(frame_sink_id_, local_surface_id_),
ScaleFactorForDisplay(window_), last_surface_size_));
SetPrimarySurfaceInfo(cc::SurfaceInfo(
cc::SurfaceId(frame_sink_id_, local_surface_id_),
ScaleFactorForDisplay(window_), last_surface_size_in_pixels_));
}
void WindowPortMus::UpdateClientSurfaceEmbedder() {
......
......@@ -222,7 +222,7 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
const std::vector<uint8_t>* property_data) override;
void SetFrameSinkIdFromServer(const cc::FrameSinkId& frame_sink_id) override;
const cc::LocalSurfaceId& GetOrAllocateLocalSurfaceId(
const gfx::Size& surface_size) override;
const gfx::Size& surface_size_in_pixels) override;
void SetPrimarySurfaceInfo(const cc::SurfaceInfo& surface_info) override;
void SetFallbackSurfaceInfo(const cc::SurfaceInfo& surface_info) override;
void DestroyFromServer() override;
......@@ -281,7 +281,7 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
cc::LocalSurfaceId local_surface_id_;
cc::LocalSurfaceIdAllocator local_surface_id_allocator_;
gfx::Size last_surface_size_;
gfx::Size last_surface_size_in_pixels_;
ui::CursorData cursor_;
......
......@@ -104,16 +104,19 @@ std::vector<uint8_t> ConvertToPropertyTransportValue(int64_t value) {
using WindowTreeClientWmTest = test::AuraMusWmTestBase;
using WindowTreeClientClientTest = test::AuraMusClientTestBase;
// WindowTreeClientWmTest with --enable-surface-synchronization.
class WindowTreeClientWmTestSurfaceSync : public WindowTreeClientWmTest {
class WindowTreeClientWmTestSurfaceSync
: public WindowTreeClientWmTest,
public ::testing::WithParamInterface<bool> {
public:
WindowTreeClientWmTestSurfaceSync() {}
~WindowTreeClientWmTestSurfaceSync() override {}
// WindowTreeClientWmTest:
void SetUp() override {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
cc::switches::kEnableSurfaceSynchronization);
if (GetParam()) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kForceDeviceScaleFactor, "2");
}
WindowTreeClientWmTest::SetUp();
}
......@@ -204,9 +207,13 @@ TEST_F(WindowTreeClientWmTest, SetBoundsFailedLocalSurfaceId) {
EXPECT_FALSE(window_mus->GetLocalSurfaceId().is_valid());
}
INSTANTIATE_TEST_CASE_P(/* no prefix */,
WindowTreeClientWmTestSurfaceSync,
::testing::Bool());
// Verifies that a ClientSurfaceEmbedder is created for a window once it has
// a bounds, and a valid FrameSinkId.
TEST_F(WindowTreeClientWmTestSurfaceSync,
TEST_P(WindowTreeClientWmTestSurfaceSync,
ClientSurfaceEmbedderOnValidEmbedding) {
Window window(nullptr);
// TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate cc::LocalSurfaceIds
......@@ -219,7 +226,7 @@ TEST_F(WindowTreeClientWmTestSurfaceSync,
WindowMus* window_mus = WindowMus::Get(&window);
ASSERT_NE(nullptr, window_mus);
EXPECT_FALSE(window_mus->GetLocalSurfaceId().is_valid());
const gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
gfx::Rect new_bounds(gfx::Rect(0, 0, 100, 100));
ASSERT_NE(new_bounds, window.bounds());
window.SetBounds(new_bounds);
EXPECT_EQ(new_bounds, window.bounds());
......@@ -240,12 +247,14 @@ TEST_F(WindowTreeClientWmTestSurfaceSync,
ASSERT_NE(nullptr, client_surface_embedder);
// Until the fallback surface fills the window, we will have gutter.
ui::Layer* right_gutter = client_surface_embedder->RightGutterForTesting();
ASSERT_NE(nullptr, right_gutter);
EXPECT_EQ(gfx::Rect(100, 100), right_gutter->bounds());
// We don't have a bottom gutter if the fallback surface size is (0, 0) as the
// right gutter will fill the whole area.
ASSERT_EQ(nullptr, client_surface_embedder->BottomGutterForTesting());
{
ui::Layer* right_gutter = client_surface_embedder->RightGutterForTesting();
ASSERT_NE(nullptr, right_gutter);
EXPECT_EQ(gfx::Rect(100, 100), right_gutter->bounds());
// We don't have a bottom gutter if the fallback surface size is (0, 0) as
// the right gutter will fill the whole area.
ASSERT_EQ(nullptr, client_surface_embedder->BottomGutterForTesting());
}
// When a SurfaceInfo arrives from the window server, we use it as the
// fallback SurfaceInfo. Here we issue the PrimarySurfaceInfo back to the
......@@ -256,11 +265,30 @@ TEST_F(WindowTreeClientWmTestSurfaceSync,
// The gutter is gone.
ASSERT_EQ(nullptr, client_surface_embedder->BottomGutterForTesting());
ASSERT_EQ(nullptr, client_surface_embedder->RightGutterForTesting());
// Resize again: we should have gutter.
new_bounds.SetRect(0, 0, 150, 150);
ASSERT_NE(new_bounds, window.bounds());
window.SetBounds(new_bounds);
ASSERT_NE(nullptr, client_surface_embedder->BottomGutterForTesting());
ASSERT_NE(nullptr, client_surface_embedder->RightGutterForTesting());
// Until the fallback surface fills the window, we will have gutter.
{
ui::Layer* right_gutter = client_surface_embedder->RightGutterForTesting();
ASSERT_NE(nullptr, right_gutter);
EXPECT_EQ(gfx::Rect(100, 0, 50, 150), right_gutter->bounds());
ui::Layer* bottom_gutter =
client_surface_embedder->BottomGutterForTesting();
ASSERT_NE(nullptr, bottom_gutter);
EXPECT_EQ(gfx::Rect(0, 100, 100, 50), bottom_gutter->bounds());
}
}
// Verifies that the cc::LocalSurfaceId generated by an embedder changes when
// the size changes, but not when the position changes.
TEST_F(WindowTreeClientWmTest, SetBoundsLocalSurfaceIdChanges) {
TEST_P(WindowTreeClientWmTestSurfaceSync, SetBoundsLocalSurfaceIdChanges) {
ASSERT_EQ(base::nullopt, window_tree()->last_local_surface_id());
Window window(nullptr);
// TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate cc::LocalSurfaceIds
......
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