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