Commit 3b2bde2e authored by dnicoara's avatar dnicoara Committed by Commit bot

[Ozone-Dri] Gracefully handle DRM devices with no resources

DRM devices such as VGEM do not have resources, so we want to ignore
them rather than crash.

BUG=460982

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

Cr-Commit-Position: refs/heads/master@{#317687}
parent 511f02da
......@@ -88,6 +88,14 @@ void HandlePageFlipEventOnUI(int fd,
payload->callback.Run(frame, seconds, useconds);
}
bool CanQueryForResources(int fd) {
drm_mode_card_res resources;
memset(&resources, 0, sizeof(resources));
// If there is no error getting DRM resources then assume this is a
// modesetting device.
return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources);
}
} // namespace
class DriWrapper::IOWatcher
......@@ -163,10 +171,23 @@ DriWrapper::~DriWrapper() {
watcher_->Shutdown();
}
void DriWrapper::Initialize() {
bool DriWrapper::Initialize() {
// Ignore devices that cannot perform modesetting.
if (!CanQueryForResources(file_.GetPlatformFile())) {
VLOG(2) << "Cannot query for resources for '" << device_path_.value()
<< "'";
return false;
}
plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy());
if (!plane_manager_->Initialize(this))
LOG(ERROR) << "Failed to initialize the plane manager";
if (!plane_manager_->Initialize(this)) {
LOG(ERROR) << "Failed to initialize the plane manager for "
<< device_path_.value();
plane_manager_.reset();
return false;
}
return true;
}
void DriWrapper::InitializeTaskRunner(
......
......@@ -48,7 +48,7 @@ class OZONE_EXPORT DriWrapper : public base::RefCountedThreadSafe<DriWrapper> {
DriWrapper(const base::FilePath& device_path, base::File file);
// Open device.
virtual void Initialize();
virtual bool Initialize();
// |task_runner| will be used to asynchronously page flip.
virtual void InitializeTaskRunner(
......
......@@ -18,8 +18,10 @@ scoped_refptr<DriWrapper> DrmDeviceGenerator::CreateDevice(
const base::FilePath& device_path,
base::File file) {
scoped_refptr<DriWrapper> drm = new DriWrapper(device_path, file.Pass());
drm->Initialize();
return drm;
if (drm->Initialize())
return drm;
return nullptr;
}
} // namespace ui
......@@ -21,11 +21,17 @@ GbmWrapper::~GbmWrapper() {
gbm_device_destroy(device_);
}
void GbmWrapper::Initialize() {
DriWrapper::Initialize();
bool GbmWrapper::Initialize() {
if (!DriWrapper::Initialize())
return false;
device_ = gbm_create_device(get_fd());
if (!device_)
LOG(FATAL) << "Unable to initialize GBM";
if (!device_) {
LOG(ERROR) << "Unable to initialize GBM";
return false;
}
return true;
}
} // namespace ui
......@@ -19,7 +19,7 @@ class GbmWrapper : public DriWrapper {
gbm_device* device() const { return device_; }
// DriWrapper implementation:
void Initialize() override;
bool Initialize() override;
private:
~GbmWrapper() override;
......
......@@ -69,7 +69,7 @@ bool HardwareDisplayPlaneManager::Initialize(DriWrapper* drm) {
drm_ = drm;
ScopedDrmResourcesPtr resources(drmModeGetResources(drm->get_fd()));
if (!resources) {
LOG(ERROR) << "Failed to get resources.";
PLOG(ERROR) << "Failed to get resources";
return false;
}
......
......@@ -219,13 +219,17 @@ void NativeDisplayDelegateDri::AddGraphicsDevice(
auto it =
std::find_if(devices_.begin(), devices_.end(), FindByDevicePath(path));
if (it != devices_.end()) {
LOG(WARNING) << "Got request to add existing device '" << path.value()
<< "'";
VLOG(2) << "Got request to add existing device '" << path.value() << "'";
return;
}
scoped_refptr<DriWrapper> device =
drm_device_generator_->CreateDevice(path, file.Pass());
if (!device) {
VLOG(2) << "Could not initialize DRM device for '" << path.value() << "'";
return;
}
devices_.push_back(device);
if (io_task_runner_)
device->InitializeTaskRunner(io_task_runner_);
......@@ -236,8 +240,8 @@ void NativeDisplayDelegateDri::RemoveGraphicsDevice(
auto it =
std::find_if(devices_.begin(), devices_.end(), FindByDevicePath(path));
if (it == devices_.end()) {
LOG(ERROR) << "Got request to remove non-existent device '" << path.value()
<< "'";
VLOG(2) << "Got request to remove non-existent device '" << path.value()
<< "'";
return;
}
......
......@@ -91,7 +91,9 @@ class OzonePlatformDri : public OzonePlatform {
display_manager_.get()));
}
void InitializeUI() override {
dri_->Initialize();
if (!dri_->Initialize())
LOG(FATAL) << "Failed to initialize primary DRM device";
// This makes sure that simple targets that do not handle display
// configuration can still use the primary display.
ForceInitializationOfPrimaryDisplay(dri_, screen_manager_.get());
......
......@@ -96,8 +96,10 @@ class GbmDeviceGenerator : public DrmDeviceGenerator {
scoped_refptr<DriWrapper> CreateDevice(const base::FilePath& path,
base::File file) override {
scoped_refptr<DriWrapper> drm = new GbmWrapper(path, file.Pass());
drm->Initialize();
return drm;
if (drm->Initialize())
return drm;
return nullptr;
}
private:
......@@ -173,7 +175,9 @@ class OzonePlatformGbm : public OzonePlatform {
gl_api_loader_.reset(new GlApiLoader());
// Async page flips are supported only on surfaceless mode.
gbm_ = new GbmWrapper(GetFirstDisplayCardPath());
gbm_->Initialize();
if (!gbm_->Initialize())
LOG(FATAL) << "Failed to initialize primary DRM device";
drm_device_manager_.reset(new DrmDeviceManager(gbm_));
buffer_generator_.reset(new GbmBufferGenerator());
screen_manager_.reset(new ScreenManager(buffer_generator_.get()));
......
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