Commit 0e7b023c authored by dnicoara's avatar dnicoara Committed by Commit bot

[Ozone-Drm] Scan for displays on browser size during startup

During startup, Chrome expects synchronous display configuration, so we
need to present the list of displays before we get a chance to connect
to the GPU process. This patch will populate a list of dummy displays on
startup and the platform will pretend it can configure them until the
connection to the GPU process is established.

BUG=484294

Review URL: https://codereview.chromium.org/1131813003

Cr-Commit-Position: refs/heads/master@{#329786}
parent 0e0e354f
......@@ -175,7 +175,6 @@ action("generate_constructor_list") {
test("ozone_unittests") {
sources = [
"common/display_util_unittest.cc",
"run_all_unittests.cc",
]
......
......@@ -96,50 +96,4 @@ bool CreateSnapshotFromCommandLine(DisplaySnapshot_Params* snapshot_out) {
return true;
}
bool CreateSnapshotFromEDID(bool internal,
const std::vector<uint8_t>& edid,
DisplaySnapshot_Params* snapshot_out) {
uint16_t manufacturer_id = 0;
gfx::Size resolution;
DisplayMode_Params mode_param;
mode_param.refresh_rate = 60.0f;
if (!ParseOutputDeviceData(edid, &manufacturer_id,
&snapshot_out->display_name, &mode_param.size,
&snapshot_out->physical_size) ||
!GetDisplayIdFromEDID(edid, 0, &snapshot_out->display_id)) {
return false;
}
ParseOutputOverscanFlag(edid, &snapshot_out->has_overscan);
snapshot_out->modes.push_back(mode_param);
// Use VGA for external display for now.
// TODO(oshima): frecon should set this value in the display_info.bin file.
snapshot_out->type =
internal ? DISPLAY_CONNECTION_TYPE_INTERNAL : DISPLAY_CONNECTION_TYPE_VGA;
snapshot_out->has_current_mode = true;
snapshot_out->current_mode = mode_param;
snapshot_out->has_native_mode = true;
snapshot_out->native_mode = mode_param;
return true;
}
bool CreateSnapshotFromEDIDFile(const base::FilePath& file,
DisplaySnapshot_Params* snapshot_out) {
std::string raw_display_info;
const int kEDIDMaxSize = 128;
if (!base::ReadFileToString(file, &raw_display_info, kEDIDMaxSize + 1) ||
raw_display_info.size() < 10) {
return false;
}
std::vector<uint8_t> edid;
// The head of the file contains one byte flag that indicates the type of
// display.
bool internal = raw_display_info[0] == 1;
edid.assign(raw_display_info.c_str() + 1,
raw_display_info.c_str() + raw_display_info.size());
return CreateSnapshotFromEDID(internal, edid, snapshot_out);
}
} // namespace ui
......@@ -37,17 +37,6 @@ DisplaySnapshot_Params GetDisplaySnapshotParams(const DisplaySnapshot& display);
// Return false if the command line flags are not specified.
bool CreateSnapshotFromCommandLine(DisplaySnapshot_Params* snapshot_out);
// Create a display snapshot from |file| that contains EDID.
// Return false if the file doesn't exist, or it doesn't contain valid EDID.
bool CreateSnapshotFromEDIDFile(const base::FilePath& file,
DisplaySnapshot_Params* snapshot_out);
// Create a display snaphot from edid.
// Return false if it doesn't contain valid EDID.
OZONE_EXPORT bool CreateSnapshotFromEDID(bool internal,
const std::vector<uint8_t>& edid,
DisplaySnapshot_Params* snapshot_out);
} // namespace ui
#endif // UI_OZONE_COMMON_DISPLAY_UTIL_H_
// Copyright 2015 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/ozone/common/display_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
typedef testing::Test DisplayUtilTest;
namespace ui {
namespace {
// EDID from HP ZR30w
const unsigned char kTestEDID[] =
"\x00\xff\xff\xff\xff\xff\xff\x00\x22\xf0\x6c\x28\x01\x01\x01\x01"
"\x02\x16\x01\x04\xb5\x40\x28\x78\xe2\x8d\x85\xad\x4f\x35\xb1\x25"
"\x0e\x50\x54\x00\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
"\x01\x01\x01\x01\x01\x01\xe2\x68\x00\xa0\xa0\x40\x2e\x60\x30\x20"
"\x36\x00\x81\x90\x21\x00\x00\x1a\xbc\x1b\x00\xa0\x50\x20\x17\x30"
"\x30\x20\x36\x00\x81\x90\x21\x00\x00\x1a\x00\x00\x00\xfc\x00\x48"
"\x50\x20\x5a\x52\x33\x30\x77\x0a\x20\x20\x20\x20\x00\x00\x00\xff"
"\x00\x43\x4e\x34\x32\x30\x32\x31\x33\x37\x51\x0a\x20\x20\x00\x71";
} // namespace
TEST_F(DisplayUtilTest, BasicEDID) {
DisplaySnapshot_Params params;
// -1 to skip NULL byte.
std::vector<uint8_t> edid(kTestEDID, kTestEDID + arraysize(kTestEDID) - 1);
// External Display
EXPECT_TRUE(CreateSnapshotFromEDID(true, edid, &params));
EXPECT_EQ("HP ZR30w", params.display_name);
EXPECT_EQ(1u, params.modes.size());
EXPECT_TRUE(params.has_current_mode);
EXPECT_EQ("2560x1600", params.current_mode.size.ToString());
EXPECT_EQ("641x400", params.physical_size.ToString());
EXPECT_EQ(DISPLAY_CONNECTION_TYPE_INTERNAL, params.type);
// Reset
params = DisplaySnapshot_Params();
// External Display
EXPECT_TRUE(CreateSnapshotFromEDID(false, edid, &params));
EXPECT_EQ("HP ZR30w", params.display_name);
EXPECT_EQ(1u, params.modes.size());
EXPECT_TRUE(params.has_current_mode);
EXPECT_EQ("2560x1600", params.current_mode.size.ToString());
EXPECT_EQ("641x400", params.physical_size.ToString());
EXPECT_EQ(DISPLAY_CONNECTION_TYPE_VGA, params.type);
}
TEST_F(DisplayUtilTest, EmptyEDID) {
DisplaySnapshot_Params params;
std::vector<uint8_t> edid;
EXPECT_FALSE(CreateSnapshotFromEDID(true, std::vector<uint8_t>(), &params));
}
} // namespace ui
......@@ -176,7 +176,6 @@
'target_name': 'ozone_unittests',
'type': '<(gtest_target_type)',
'sources': [
'common/display_util_unittest.cc',
'run_all_unittests.cc',
],
'dependencies': [
......
......@@ -18,6 +18,8 @@ class DrmDeviceHandle {
DrmDeviceHandle();
~DrmDeviceHandle();
int fd() const { return file_.get(); }
bool Initialize(const base::FilePath& path);
bool IsValid() const;
......
......@@ -13,12 +13,12 @@
#include "base/thread_task_runner_handle.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/worker_pool.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/events/ozone/device/device_event.h"
#include "ui/events/ozone/device/device_manager.h"
#include "ui/ozone/common/display_snapshot_proxy.h"
#include "ui/ozone/common/display_util.h"
#include "ui/ozone/common/gpu/ozone_gpu_messages.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
#include "ui/ozone/platform/drm/host/drm_device_handle.h"
#include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
#include "ui/ozone/platform/drm/host/drm_native_display_delegate.h"
......@@ -122,27 +122,13 @@ DrmDisplayHostManager::DrmDisplayHostManager(DrmGpuPlatformSupportHost* proxy,
device_manager_->AddObserver(this);
proxy_->RegisterHandler(this);
DisplaySnapshot_Params params;
bool success = false;
{
// The file generated by frecon that contains EDID for the 1st display.
const base::FilePath kEDIDFile("/tmp/display_info.bin");
// Just read it on current thread as this is necessary information
// to start. This access only tmpfs, which is fast.
// TODO(dnicoara|oshima): crbug.com/450886.
base::ThreadRestrictions::ScopedAllowIO allow_io;
success = CreateSnapshotFromEDIDFile(kEDIDFile, &params);
}
// Fallback to command line if the file doesn't exit or failed to read.
if (success || CreateSnapshotFromCommandLine(&params)) {
LOG_IF(ERROR, !success) << "Failed to read display_info.bin.";
DCHECK_NE(DISPLAY_CONNECTION_TYPE_NONE, params.type);
displays_.push_back(new DisplaySnapshotProxy(params));
has_dummy_display_ = true;
} else {
LOG(ERROR) << "Failed to obtain initial display info";
DrmDeviceHandle* handle = drm_devices_.get(primary_graphics_card_path_);
ScopedVector<HardwareDisplayControllerInfo> display_infos =
GetAvailableDisplayControllerInfos(handle->fd());
has_dummy_display_ = !display_infos.empty();
for (size_t i = 0; i < display_infos.size(); ++i) {
displays_.push_back(new DisplaySnapshotProxy(CreateDisplaySnapshotParams(
display_infos[i], handle->fd(), i, gfx::Point())));
}
}
......
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