Commit effd312e authored by achaulk's avatar achaulk Committed by Commit bot

ozone: Add atomic initialization path

Atomic is only selected if the kernel indicates support (SetCapability
succeeds), the platform wants to use it and DRM is new enough to support it (define)

Also fixes up the atomic page flip path, callbacks weren't being handled properly

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

Cr-Commit-Position: refs/heads/master@{#330614}
parent 2905d303
...@@ -290,7 +290,7 @@ DrmDevice::~DrmDevice() { ...@@ -290,7 +290,7 @@ DrmDevice::~DrmDevice() {
watcher_->Shutdown(); watcher_->Shutdown();
} }
bool DrmDevice::Initialize() { bool DrmDevice::Initialize(bool use_atomic) {
// Ignore devices that cannot perform modesetting. // Ignore devices that cannot perform modesetting.
if (!CanQueryForResources(file_.GetPlatformFile())) { if (!CanQueryForResources(file_.GetPlatformFile())) {
VLOG(2) << "Cannot query for resources for '" << device_path_.value() VLOG(2) << "Cannot query for resources for '" << device_path_.value()
...@@ -299,10 +299,13 @@ bool DrmDevice::Initialize() { ...@@ -299,10 +299,13 @@ bool DrmDevice::Initialize() {
} }
#if defined(USE_DRM_ATOMIC) #if defined(USE_DRM_ATOMIC)
plane_manager_.reset(new HardwareDisplayPlaneManagerAtomic()); // Use atomic only if the build, kernel & flags all allow it.
#else if (use_atomic && SetCapability(DRM_CLIENT_CAP_ATOMIC, 1))
plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy()); plane_manager_.reset(new HardwareDisplayPlaneManagerAtomic());
#endif // defined(USE_DRM_ATOMIC) #endif // defined(USE_DRM_ATOMIC)
if (!plane_manager_)
plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy());
if (!plane_manager_->Initialize(this)) { if (!plane_manager_->Initialize(this)) {
LOG(ERROR) << "Failed to initialize the plane manager for " LOG(ERROR) << "Failed to initialize the plane manager for "
<< device_path_.value(); << device_path_.value();
...@@ -563,11 +566,9 @@ bool DrmDevice::CommitProperties(drmModePropertySet* properties, ...@@ -563,11 +566,9 @@ bool DrmDevice::CommitProperties(drmModePropertySet* properties,
const PageFlipCallback& callback) { const PageFlipCallback& callback) {
#if defined(USE_DRM_ATOMIC) #if defined(USE_DRM_ATOMIC)
flags |= DRM_MODE_PAGE_FLIP_EVENT; flags |= DRM_MODE_PAGE_FLIP_EVENT;
scoped_ptr<PageFlipPayload> payload(
new PageFlipPayload(base::ThreadTaskRunnerHandle::Get(), callback));
uint64_t id = page_flip_manager_->GetNextId(); uint64_t id = page_flip_manager_->GetNextId();
if (!drmModePropertySetCommit(file_.GetPlatformFile(), flags, payload.get(), if (!drmModePropertySetCommit(file_.GetPlatformFile(), flags,
properties)) { reinterpret_cast<void*>(id), properties)) {
page_flip_manager_->RegisterCallback(id, callback); page_flip_manager_->RegisterCallback(id, callback);
// If the flip was requested synchronous or if no watcher has been installed // If the flip was requested synchronous or if no watcher has been installed
......
...@@ -49,7 +49,7 @@ class OZONE_EXPORT DrmDevice : public base::RefCountedThreadSafe<DrmDevice> { ...@@ -49,7 +49,7 @@ class OZONE_EXPORT DrmDevice : public base::RefCountedThreadSafe<DrmDevice> {
DrmDevice(const base::FilePath& device_path, base::File file); DrmDevice(const base::FilePath& device_path, base::File file);
// Open device. // Open device.
virtual bool Initialize(); virtual bool Initialize(bool use_atomic);
// |task_runner| will be used to asynchronously page flip. // |task_runner| will be used to asynchronously page flip.
virtual void InitializeTaskRunner( virtual void InitializeTaskRunner(
......
...@@ -18,7 +18,7 @@ scoped_refptr<DrmDevice> DrmDeviceGenerator::CreateDevice( ...@@ -18,7 +18,7 @@ scoped_refptr<DrmDevice> DrmDeviceGenerator::CreateDevice(
const base::FilePath& device_path, const base::FilePath& device_path,
base::File file) { base::File file) {
scoped_refptr<DrmDevice> drm = new DrmDevice(device_path, file.Pass()); scoped_refptr<DrmDevice> drm = new DrmDevice(device_path, file.Pass());
if (drm->Initialize()) if (drm->Initialize(false))
return drm; return drm;
return nullptr; return nullptr;
......
...@@ -21,8 +21,8 @@ GbmDevice::~GbmDevice() { ...@@ -21,8 +21,8 @@ GbmDevice::~GbmDevice() {
gbm_device_destroy(device_); gbm_device_destroy(device_);
} }
bool GbmDevice::Initialize() { bool GbmDevice::Initialize(bool use_atomic) {
if (!DrmDevice::Initialize()) if (!DrmDevice::Initialize(use_atomic))
return false; return false;
device_ = gbm_create_device(get_fd()); device_ = gbm_create_device(get_fd());
......
...@@ -19,7 +19,7 @@ class GbmDevice : public DrmDevice { ...@@ -19,7 +19,7 @@ class GbmDevice : public DrmDevice {
gbm_device* device() const { return device_; } gbm_device* device() const { return device_; }
// DrmDevice implementation: // DrmDevice implementation:
bool Initialize() override; bool Initialize(bool use_atomic) override;
private: private:
~GbmDevice() override; ~GbmDevice() override;
......
...@@ -50,7 +50,7 @@ bool HardwareDisplayPlaneAtomic::Property::Initialize( ...@@ -50,7 +50,7 @@ bool HardwareDisplayPlaneAtomic::Property::Initialize(
HardwareDisplayPlaneAtomic::HardwareDisplayPlaneAtomic(uint32_t plane_id, HardwareDisplayPlaneAtomic::HardwareDisplayPlaneAtomic(uint32_t plane_id,
uint32_t possible_crtcs) uint32_t possible_crtcs)
: HardwareDisplayPlane(plane_id, possible_crtcs) { : HardwareDisplayPlane(plane_id, possible_crtcs), crtc_(nullptr) {
} }
HardwareDisplayPlaneAtomic::~HardwareDisplayPlaneAtomic() { HardwareDisplayPlaneAtomic::~HardwareDisplayPlaneAtomic() {
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
namespace ui { namespace ui {
class CrtcController;
class DrmDevice; class DrmDevice;
class HardwareDisplayPlaneAtomic : public HardwareDisplayPlane { class HardwareDisplayPlaneAtomic : public HardwareDisplayPlane {
...@@ -27,6 +28,9 @@ class HardwareDisplayPlaneAtomic : public HardwareDisplayPlane { ...@@ -27,6 +28,9 @@ class HardwareDisplayPlaneAtomic : public HardwareDisplayPlane {
// HardwareDisplayPlane: // HardwareDisplayPlane:
bool Initialize(DrmDevice* drm) override; bool Initialize(DrmDevice* drm) override;
void set_crtc(CrtcController* crtc) { crtc_ = crtc; }
CrtcController* crtc() const { return crtc_; }
private: private:
struct Property { struct Property {
Property(); Property();
...@@ -46,6 +50,7 @@ class HardwareDisplayPlaneAtomic : public HardwareDisplayPlane { ...@@ -46,6 +50,7 @@ class HardwareDisplayPlaneAtomic : public HardwareDisplayPlane {
Property src_y_prop_; Property src_y_prop_;
Property src_w_prop_; Property src_w_prop_;
Property src_h_prop_; Property src_h_prop_;
CrtcController* crtc_;
}; };
} // namespace ui } // namespace ui
......
...@@ -25,7 +25,11 @@ const float kFixedPointScaleValue = 65536.0f; ...@@ -25,7 +25,11 @@ const float kFixedPointScaleValue = 65536.0f;
} // namespace } // namespace
HardwareDisplayPlaneList::HardwareDisplayPlaneList() : committed(false) { HardwareDisplayPlaneList::HardwareDisplayPlaneList() : committed(false) {
#if defined(USE_DRM_ATOMIC)
atomic_property_set.reset(drmModePropertySetAlloc());
#endif // defined(USE_DRM_ATOMIC)
} }
HardwareDisplayPlaneList::~HardwareDisplayPlaneList() { HardwareDisplayPlaneList::~HardwareDisplayPlaneList() {
for (auto* plane : plane_list) { for (auto* plane : plane_list) {
plane->set_in_use(false); plane->set_in_use(false);
......
...@@ -5,15 +5,23 @@ ...@@ -5,15 +5,23 @@
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_atomic.h"
#include "base/bind.h" #include "base/bind.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h" #include "ui/ozone/platform/drm/gpu/drm_device.h"
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h" #include "ui/ozone/platform/drm/gpu/hardware_display_plane_atomic.h"
#include "ui/ozone/platform/drm/gpu/scanout_buffer.h" #include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
namespace ui { namespace ui {
static void AtomicPageFlipCallback(unsigned int /* frame */, static void AtomicPageFlipCallback(
unsigned int /* seconds */, std::vector<base::WeakPtr<CrtcController>> crtcs,
unsigned int /* useconds */) { unsigned int frame,
unsigned int seconds,
unsigned int useconds) {
for (auto& crtc : crtcs) {
auto* crtc_ptr = crtc.get();
if (crtc_ptr)
crtc_ptr->OnPageFlipEvent(frame, seconds, useconds);
}
} }
HardwareDisplayPlaneManagerAtomic::HardwareDisplayPlaneManagerAtomic() { HardwareDisplayPlaneManagerAtomic::HardwareDisplayPlaneManagerAtomic() {
...@@ -39,28 +47,25 @@ bool HardwareDisplayPlaneManagerAtomic::Commit( ...@@ -39,28 +47,25 @@ bool HardwareDisplayPlaneManagerAtomic::Commit(
} }
} }
std::vector<base::WeakPtr<CrtcController>> crtcs;
for (HardwareDisplayPlane* plane : plane_list->plane_list) {
HardwareDisplayPlaneAtomic* atomic_plane =
static_cast<HardwareDisplayPlaneAtomic*>(plane);
if (crtcs.empty() || crtcs.back().get() != atomic_plane->crtc())
crtcs.push_back(atomic_plane->crtc()->AsWeakPtr());
}
plane_list->plane_list.swap(plane_list->old_plane_list); plane_list->plane_list.swap(plane_list->old_plane_list);
plane_list->plane_list.clear(); plane_list->plane_list.clear();
if (!drm_->CommitProperties(plane_list->atomic_property_set.get(), 0, is_sync, if (!drm_->CommitProperties(plane_list->atomic_property_set.get(), 0, is_sync,
base::Bind(&AtomicPageFlipCallback))) { base::Bind(&AtomicPageFlipCallback, crtcs))) {
PLOG(ERROR) << "Failed to commit properties"; PLOG(ERROR) << "Failed to commit properties";
return false; return false;
} }
plane_list->committed = true;
return true; return true;
} }
bool HardwareDisplayPlaneManagerAtomic::AssignOverlayPlanes(
HardwareDisplayPlaneList* plane_list,
const OverlayPlaneList& overlay_list,
uint32_t crtc_id,
CrtcController* crtc) {
// Lazy-initialize the atomic property set.
if (!plane_list->atomic_property_set)
plane_list->atomic_property_set.reset(drmModePropertySetAlloc());
return HardwareDisplayPlaneManager::AssignOverlayPlanes(
plane_list, overlay_list, crtc_id, crtc);
}
bool HardwareDisplayPlaneManagerAtomic::SetPlaneData( bool HardwareDisplayPlaneManagerAtomic::SetPlaneData(
HardwareDisplayPlaneList* plane_list, HardwareDisplayPlaneList* plane_list,
HardwareDisplayPlane* hw_plane, HardwareDisplayPlane* hw_plane,
...@@ -76,7 +81,7 @@ bool HardwareDisplayPlaneManagerAtomic::SetPlaneData( ...@@ -76,7 +81,7 @@ bool HardwareDisplayPlaneManagerAtomic::SetPlaneData(
LOG(ERROR) << "Failed to set plane properties"; LOG(ERROR) << "Failed to set plane properties";
return false; return false;
} }
plane_list->plane_list.push_back(hw_plane); atomic_plane->set_crtc(crtc);
return true; return true;
} }
......
...@@ -17,10 +17,6 @@ class OZONE_EXPORT HardwareDisplayPlaneManagerAtomic ...@@ -17,10 +17,6 @@ class OZONE_EXPORT HardwareDisplayPlaneManagerAtomic
~HardwareDisplayPlaneManagerAtomic() override; ~HardwareDisplayPlaneManagerAtomic() override;
// HardwareDisplayPlaneManager: // HardwareDisplayPlaneManager:
bool AssignOverlayPlanes(HardwareDisplayPlaneList* plane_list,
const OverlayPlaneList& overlay_list,
uint32_t crtc_id,
CrtcController* crtc) override;
bool Commit(HardwareDisplayPlaneList* plane_list, bool is_sync) override; bool Commit(HardwareDisplayPlaneList* plane_list, bool is_sync) override;
private: private:
......
...@@ -88,20 +88,22 @@ class GbmBufferGenerator : public ScanoutBufferGenerator { ...@@ -88,20 +88,22 @@ class GbmBufferGenerator : public ScanoutBufferGenerator {
class GbmDeviceGenerator : public DrmDeviceGenerator { class GbmDeviceGenerator : public DrmDeviceGenerator {
public: public:
GbmDeviceGenerator() {} GbmDeviceGenerator(bool use_atomic) : use_atomic_(use_atomic) {}
~GbmDeviceGenerator() override {} ~GbmDeviceGenerator() override {}
// DrmDeviceGenerator: // DrmDeviceGenerator:
scoped_refptr<DrmDevice> CreateDevice(const base::FilePath& path, scoped_refptr<DrmDevice> CreateDevice(const base::FilePath& path,
base::File file) override { base::File file) override {
scoped_refptr<DrmDevice> drm = new GbmDevice(path, file.Pass()); scoped_refptr<DrmDevice> drm = new GbmDevice(path, file.Pass());
if (drm->Initialize()) if (drm->Initialize(use_atomic_))
return drm; return drm;
return nullptr; return nullptr;
} }
private: private:
bool use_atomic_;
DISALLOW_COPY_AND_ASSIGN(GbmDeviceGenerator); DISALLOW_COPY_AND_ASSIGN(GbmDeviceGenerator);
}; };
...@@ -169,9 +171,10 @@ class OzonePlatformGbm : public OzonePlatform { ...@@ -169,9 +171,10 @@ class OzonePlatformGbm : public OzonePlatform {
} }
void InitializeGPU() override { void InitializeGPU() override {
bool use_atomic = false;
gl_api_loader_.reset(new GlApiLoader()); gl_api_loader_.reset(new GlApiLoader());
drm_device_manager_.reset(new DrmDeviceManager( drm_device_manager_.reset(new DrmDeviceManager(
scoped_ptr<DrmDeviceGenerator>(new GbmDeviceGenerator()))); scoped_ptr<DrmDeviceGenerator>(new GbmDeviceGenerator(use_atomic))));
buffer_generator_.reset(new GbmBufferGenerator()); buffer_generator_.reset(new GbmBufferGenerator());
screen_manager_.reset(new ScreenManager(buffer_generator_.get())); screen_manager_.reset(new ScreenManager(buffer_generator_.get()));
if (!surface_factory_ozone_) if (!surface_factory_ozone_)
......
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