blob: b1ab4c11d2e6c12153fe65dd3dd16d385001f167 [file] [log] [blame]
// 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/platform/drm/gpu/hardware_display_plane_atomic.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
namespace ui {
namespace {
// TODO(dcastagna): Remove the following defines once they're in libdrm headers.
#if !defined(DRM_ROTATE_0)
#define BIT(n) (1 << (n))
#define DRM_ROTATE_0 BIT(0)
#define DRM_ROTATE_90 BIT(1)
#define DRM_ROTATE_180 BIT(2)
#define DRM_ROTATE_270 BIT(3)
#define DRM_REFLECT_X BIT(4)
#define DRM_REFLECT_Y BIT(5)
#endif
uint32_t OverlayTransformToDrmRotationPropertyValue(
gfx::OverlayTransform transform) {
switch (transform) {
case gfx::OVERLAY_TRANSFORM_NONE:
return DRM_ROTATE_0;
case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
return DRM_REFLECT_X;
case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
return DRM_REFLECT_Y;
case gfx::OVERLAY_TRANSFORM_ROTATE_90:
return DRM_ROTATE_90;
case gfx::OVERLAY_TRANSFORM_ROTATE_180:
return DRM_ROTATE_180;
case gfx::OVERLAY_TRANSFORM_ROTATE_270:
return DRM_ROTATE_270;
default:
NOTREACHED();
}
return 0;
}
bool AddProperty(drmModeAtomicReqPtr property_set,
uint32_t object_id,
const DrmDevice::Property& property) {
int ret = drmModeAtomicAddProperty(property_set, object_id, property.id,
property.value);
if (ret < 0) {
LOG(ERROR) << "Failed to set property object_id=" << object_id
<< " property_id=" << property.id
<< " property_value=" << property.value << " error=" << -ret;
return false;
}
return true;
}
} // namespace
HardwareDisplayPlaneAtomic::HardwareDisplayPlaneAtomic(uint32_t id)
: HardwareDisplayPlane(id) {}
HardwareDisplayPlaneAtomic::~HardwareDisplayPlaneAtomic() {}
bool HardwareDisplayPlaneAtomic::Initialize(DrmDevice* drm) {
if (!HardwareDisplayPlane::Initialize(drm))
return false;
// Check that all the required properties have been found.
bool ret = properties_.crtc_id.id && properties_.crtc_x.id &&
properties_.crtc_y.id && properties_.crtc_w.id &&
properties_.crtc_h.id && properties_.fb_id.id &&
properties_.src_x.id && properties_.src_y.id &&
properties_.src_w.id && properties_.src_h.id;
LOG_IF(ERROR, !ret) << "Failed to find all required properties for plane="
<< id_;
return ret;
}
bool HardwareDisplayPlaneAtomic::SetPlaneData(
drmModeAtomicReq* property_set,
uint32_t crtc_id,
uint32_t framebuffer,
const gfx::Rect& crtc_rect,
const gfx::Rect& src_rect,
const gfx::OverlayTransform transform,
int in_fence_fd) {
if (transform != gfx::OVERLAY_TRANSFORM_NONE && !properties_.rotation.id)
return false;
properties_.crtc_id.value = crtc_id;
properties_.crtc_x.value = crtc_rect.x();
properties_.crtc_y.value = crtc_rect.y();
properties_.crtc_w.value = crtc_rect.width();
properties_.crtc_h.value = crtc_rect.height();
properties_.fb_id.value = framebuffer;
properties_.src_x.value = src_rect.x();
properties_.src_y.value = src_rect.y();
properties_.src_w.value = src_rect.width();
properties_.src_h.value = src_rect.height();
bool plane_set_succeeded =
AddProperty(property_set, id_, properties_.crtc_id) &&
AddProperty(property_set, id_, properties_.crtc_x) &&
AddProperty(property_set, id_, properties_.crtc_y) &&
AddProperty(property_set, id_, properties_.crtc_w) &&
AddProperty(property_set, id_, properties_.crtc_h) &&
AddProperty(property_set, id_, properties_.fb_id) &&
AddProperty(property_set, id_, properties_.src_x) &&
AddProperty(property_set, id_, properties_.src_y) &&
AddProperty(property_set, id_, properties_.src_w) &&
AddProperty(property_set, id_, properties_.src_h);
if (properties_.rotation.id) {
properties_.rotation.value =
OverlayTransformToDrmRotationPropertyValue(transform);
plane_set_succeeded = plane_set_succeeded &&
AddProperty(property_set, id_, properties_.rotation);
}
if (properties_.in_fence_fd.id && in_fence_fd >= 0) {
properties_.in_fence_fd.value = in_fence_fd;
plane_set_succeeded =
plane_set_succeeded &&
AddProperty(property_set, id_, properties_.in_fence_fd);
}
if (!plane_set_succeeded) {
LOG(ERROR) << "Failed to set plane data";
return false;
}
return true;
}
bool HardwareDisplayPlaneAtomic::SetPlaneCtm(drmModeAtomicReq* property_set,
uint32_t ctm_blob_id) {
if (!properties_.plane_ctm.id)
return false;
properties_.plane_ctm.value = ctm_blob_id;
return AddProperty(property_set, id_, properties_.plane_ctm);
}
} // namespace ui