Skip to content

Commit

Permalink
[Ozone-Dri] Gracefully handle DRM devices with no resources
Browse files Browse the repository at this point in the history
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}
  • Loading branch information
dnicoara authored and Commit bot committed Feb 24, 2015
1 parent 511f02d commit 3b2bde2
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 20 deletions.
27 changes: 24 additions & 3 deletions ui/ozone/platform/dri/dri_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion ui/ozone/platform/dri/dri_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
6 changes: 4 additions & 2 deletions ui/ozone/platform/dri/drm_device_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
14 changes: 10 additions & 4 deletions ui/ozone/platform/dri/gbm_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion ui/ozone/platform/dri/gbm_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion ui/ozone/platform/dri/hardware_display_plane_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
12 changes: 8 additions & 4 deletions ui/ozone/platform/dri/native_display_delegate_dri.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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_);
Expand All @@ -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;
}

Expand Down
4 changes: 3 additions & 1 deletion ui/ozone/platform/dri/ozone_platform_dri.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
10 changes: 7 additions & 3 deletions ui/ozone/platform/dri/ozone_platform_gbm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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()));
Expand Down

0 comments on commit 3b2bde2

Please sign in to comment.