drm_hwcomposer: Introduce SharedFd, use standard c++ RAII for UniqueFd
We use too much dup() system calls for present fence propagating. Also when propagating acquire fence we use additional logic for skipping such propagation for the validate/test cycle. Both issues can be solved by introducing SharedFd, which will track reference count of fd object. After that the UniqueFd is used very rarely and can be simplified by wrapping it into std::unique_ptr without caring too much of adding an extra malloc/free operation. Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com>
This commit is contained in:
parent
2bf68c3749
commit
76892784ac
23 changed files with 157 additions and 182 deletions
|
|
@ -27,7 +27,6 @@ TIDY_FILES_OVERRIDE := \
|
|||
hwc2_device/DrmHwcTwo.h:COARSE \
|
||||
hwc2_device/HwcDisplay.cpp:COARSE \
|
||||
hwc2_device/HwcDisplay.h:COARSE \
|
||||
utils/UniqueFd.h:FINE \
|
||||
utils/log.h:FINE \
|
||||
utils/properties.h:FINE \
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ filegroup {
|
|||
"hwc2_device/HwcDisplayConfigs.cpp",
|
||||
"hwc2_device/HwcLayer.cpp",
|
||||
"hwc2_device/hwc2_device.cpp",
|
||||
|
||||
"utils/fd.cpp",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "bufferinfo/BufferInfo.h"
|
||||
#include "drm/DrmFbImporter.h"
|
||||
#include "utils/UniqueFd.h"
|
||||
#include "utils/fd.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ struct LayerData {
|
|||
std::optional<BufferInfo> bi;
|
||||
std::shared_ptr<DrmFbIdHandle> fb;
|
||||
PresentInfo pi;
|
||||
UniqueFd acquire_fence;
|
||||
SharedFd acquire_fence;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ auto DrmAtomicStateManager::CommitFrame(AtomicCommitArgs &args) -> int {
|
|||
uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
|
||||
|
||||
if (args.test_only) {
|
||||
return drmModeAtomicCommit(drm->GetFd(), pset.get(),
|
||||
return drmModeAtomicCommit(*drm->GetFd(), pset.get(),
|
||||
flags | DRM_MODE_ATOMIC_TEST_ONLY, drm);
|
||||
}
|
||||
|
||||
|
|
@ -150,10 +150,10 @@ auto DrmAtomicStateManager::CommitFrame(AtomicCommitArgs &args) -> int {
|
|||
ATRACE_NAME("WaitPriorFramePresented");
|
||||
|
||||
constexpr int kTimeoutMs = 500;
|
||||
const int err = sync_wait(last_present_fence_.Get(), kTimeoutMs);
|
||||
const int err = sync_wait(*last_present_fence_, kTimeoutMs);
|
||||
if (err != 0) {
|
||||
ALOGE("sync_wait(fd=%i) returned: %i (errno: %i)",
|
||||
last_present_fence_.Get(), err, errno);
|
||||
ALOGE("sync_wait(fd=%i) returned: %i (errno: %i)", *last_present_fence_,
|
||||
err, errno);
|
||||
}
|
||||
|
||||
CleanupPriorFrameResources();
|
||||
|
|
@ -163,17 +163,19 @@ auto DrmAtomicStateManager::CommitFrame(AtomicCommitArgs &args) -> int {
|
|||
flags |= DRM_MODE_ATOMIC_NONBLOCK;
|
||||
}
|
||||
|
||||
auto err = drmModeAtomicCommit(drm->GetFd(), pset.get(), flags, drm);
|
||||
auto err = drmModeAtomicCommit(*drm->GetFd(), pset.get(), flags, drm);
|
||||
|
||||
if (err != 0) {
|
||||
ALOGE("Failed to commit pset ret=%d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
args.out_fence = MakeSharedFd(out_fence);
|
||||
|
||||
if (nonblock) {
|
||||
{
|
||||
const std::unique_lock lock(mutex_);
|
||||
last_present_fence_ = UniqueFd::Dup(out_fence);
|
||||
last_present_fence_ = args.out_fence;
|
||||
staged_frame_state_ = std::move(new_frame_state);
|
||||
frames_staged_++;
|
||||
}
|
||||
|
|
@ -182,8 +184,6 @@ auto DrmAtomicStateManager::CommitFrame(AtomicCommitArgs &args) -> int {
|
|||
active_frame_state_ = std::move(new_frame_state);
|
||||
}
|
||||
|
||||
args.out_fence = UniqueFd(out_fence);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ void DrmAtomicStateManager::ThreadFn(
|
|||
auto &main_mutex = pipe_->device->GetResMan().GetMainLock();
|
||||
|
||||
for (;;) {
|
||||
UniqueFd present_fence;
|
||||
SharedFd present_fence;
|
||||
|
||||
{
|
||||
std::unique_lock lk(mutex_);
|
||||
|
|
@ -207,7 +207,7 @@ void DrmAtomicStateManager::ThreadFn(
|
|||
|
||||
tracking_at_the_moment = frames_staged_;
|
||||
|
||||
present_fence = UniqueFd::Dup(last_present_fence_.Get());
|
||||
present_fence = last_present_fence_;
|
||||
if (!present_fence)
|
||||
continue;
|
||||
}
|
||||
|
|
@ -216,10 +216,10 @@ void DrmAtomicStateManager::ThreadFn(
|
|||
// NOLINTNEXTLINE(misc-const-correctness)
|
||||
ATRACE_NAME("AsyncWaitForBuffersSwap");
|
||||
constexpr int kTimeoutMs = 500;
|
||||
auto err = sync_wait(present_fence.Get(), kTimeoutMs);
|
||||
auto err = sync_wait(*present_fence, kTimeoutMs);
|
||||
if (err != 0) {
|
||||
ALOGE("sync_wait(fd=%i) returned: %i (errno: %i)", present_fence.Get(),
|
||||
err, errno);
|
||||
ALOGE("sync_wait(fd=%i) returned: %i (errno: %i)", *present_fence, err,
|
||||
errno);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -272,7 +272,7 @@ auto DrmAtomicStateManager::ExecuteAtomicCommit(AtomicCommitArgs &args) -> int {
|
|||
} // namespace android
|
||||
|
||||
auto DrmAtomicStateManager::ActivateDisplayUsingDPMS() -> int {
|
||||
return drmModeConnectorSetProperty(pipe_->device->GetFd(),
|
||||
return drmModeConnectorSetProperty(*pipe_->device->GetFd(),
|
||||
pipe_->connector->Get()->GetId(),
|
||||
pipe_->connector->Get()
|
||||
->GetDpmsProperty()
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ struct AtomicCommitArgs {
|
|||
std::shared_ptr<DrmKmsPlan> composition;
|
||||
|
||||
/* out */
|
||||
UniqueFd out_fence;
|
||||
SharedFd out_fence;
|
||||
|
||||
/* helpers */
|
||||
auto HasInputs() -> bool {
|
||||
|
|
@ -95,7 +95,7 @@ class DrmAtomicStateManager {
|
|||
void CleanupPriorFrameResources();
|
||||
|
||||
KmsState staged_frame_state_;
|
||||
UniqueFd last_present_fence_;
|
||||
SharedFd last_present_fence_;
|
||||
int frames_staged_{};
|
||||
int frames_tracked_{};
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ static bool GetConnectorProperty(const DrmDevice &dev,
|
|||
auto DrmConnector::CreateInstance(DrmDevice &dev, uint32_t connector_id,
|
||||
uint32_t index)
|
||||
-> std::unique_ptr<DrmConnector> {
|
||||
auto conn = MakeDrmModeConnectorUnique(dev.GetFd(), connector_id);
|
||||
auto conn = MakeDrmModeConnectorUnique(*dev.GetFd(), connector_id);
|
||||
if (!conn) {
|
||||
ALOGE("Failed to get connector %d", connector_id);
|
||||
return {};
|
||||
|
|
@ -109,7 +109,7 @@ auto DrmConnector::GetEdidBlob() -> DrmModePropertyBlobUnique {
|
|||
return {};
|
||||
}
|
||||
|
||||
return MakeDrmModePropertyBlobUnique(drm_->GetFd(), *blob_id);
|
||||
return MakeDrmModePropertyBlobUnique(*drm_->GetFd(), *blob_id);
|
||||
}
|
||||
|
||||
bool DrmConnector::IsInternal() const {
|
||||
|
|
@ -158,7 +158,7 @@ std::string DrmConnector::GetName() const {
|
|||
}
|
||||
|
||||
int DrmConnector::UpdateModes() {
|
||||
auto conn = MakeDrmModeConnectorUnique(drm_->GetFd(), GetId());
|
||||
auto conn = MakeDrmModeConnectorUnique(*drm_->GetFd(), GetId());
|
||||
if (!conn) {
|
||||
ALOGE("Failed to get connector %d", GetId());
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ static int GetCrtcProperty(const DrmDevice &dev, const DrmCrtc &crtc,
|
|||
|
||||
auto DrmCrtc::CreateInstance(DrmDevice &dev, uint32_t crtc_id, uint32_t index)
|
||||
-> std::unique_ptr<DrmCrtc> {
|
||||
auto crtc = MakeDrmModeCrtcUnique(dev.GetFd(), crtc_id);
|
||||
auto crtc = MakeDrmModeCrtcUnique(*dev.GetFd(), crtc_id);
|
||||
if (!crtc) {
|
||||
ALOGE("Failed to get CRTC %d", crtc_id);
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -55,46 +55,46 @@ DrmDevice::DrmDevice(ResourceManager *res_man) : res_man_(res_man) {
|
|||
|
||||
auto DrmDevice::Init(const char *path) -> int {
|
||||
/* TODO: Use drmOpenControl here instead */
|
||||
fd_ = UniqueFd(open(path, O_RDWR | O_CLOEXEC));
|
||||
fd_ = MakeSharedFd(open(path, O_RDWR | O_CLOEXEC));
|
||||
if (!fd_) {
|
||||
// NOLINTNEXTLINE(concurrency-mt-unsafe): Fixme
|
||||
ALOGE("Failed to open dri %s: %s", path, strerror(errno));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int ret = drmSetClientCap(GetFd(), DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
int ret = drmSetClientCap(*GetFd(), DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
if (ret != 0) {
|
||||
ALOGE("Failed to set universal plane cap %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = drmSetClientCap(GetFd(), DRM_CLIENT_CAP_ATOMIC, 1);
|
||||
ret = drmSetClientCap(*GetFd(), DRM_CLIENT_CAP_ATOMIC, 1);
|
||||
if (ret != 0) {
|
||||
ALOGE("Failed to set atomic cap %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DRM_CLIENT_CAP_WRITEBACK_CONNECTORS
|
||||
ret = drmSetClientCap(GetFd(), DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
|
||||
ret = drmSetClientCap(*GetFd(), DRM_CLIENT_CAP_WRITEBACK_CONNECTORS, 1);
|
||||
if (ret != 0) {
|
||||
ALOGI("Failed to set writeback cap %d", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint64_t cap_value = 0;
|
||||
if (drmGetCap(GetFd(), DRM_CAP_ADDFB2_MODIFIERS, &cap_value) != 0) {
|
||||
if (drmGetCap(*GetFd(), DRM_CAP_ADDFB2_MODIFIERS, &cap_value) != 0) {
|
||||
ALOGW("drmGetCap failed. Fallback to no modifier support.");
|
||||
cap_value = 0;
|
||||
}
|
||||
HasAddFb2ModifiersSupport_ = cap_value != 0;
|
||||
|
||||
drmSetMaster(GetFd());
|
||||
if (drmIsMaster(GetFd()) == 0) {
|
||||
drmSetMaster(*GetFd());
|
||||
if (drmIsMaster(*GetFd()) == 0) {
|
||||
ALOGE("DRM/KMS master access required");
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
auto res = MakeDrmModeResUnique(GetFd());
|
||||
auto res = MakeDrmModeResUnique(*GetFd());
|
||||
if (!res) {
|
||||
ALOGE("Failed to get DrmDevice resources");
|
||||
return -ENODEV;
|
||||
|
|
@ -136,7 +136,7 @@ auto DrmDevice::Init(const char *path) -> int {
|
|||
}
|
||||
}
|
||||
|
||||
auto plane_res = MakeDrmModePlaneResUnique(GetFd());
|
||||
auto plane_res = MakeDrmModePlaneResUnique(*GetFd());
|
||||
if (!plane_res) {
|
||||
ALOGE("Failed to get plane resources");
|
||||
return -ENOENT;
|
||||
|
|
@ -161,7 +161,7 @@ auto DrmDevice::RegisterUserPropertyBlob(void *data, size_t length) const
|
|||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
|
||||
create_blob.data = (__u64)data;
|
||||
|
||||
auto ret = drmIoctl(GetFd(), DRM_IOCTL_MODE_CREATEPROPBLOB, &create_blob);
|
||||
auto ret = drmIoctl(*GetFd(), DRM_IOCTL_MODE_CREATEPROPBLOB, &create_blob);
|
||||
if (ret != 0) {
|
||||
ALOGE("Failed to create mode property blob %d", ret);
|
||||
return {};
|
||||
|
|
@ -171,7 +171,7 @@ auto DrmDevice::RegisterUserPropertyBlob(void *data, size_t length) const
|
|||
new uint32_t(create_blob.blob_id), [this](const uint32_t *it) {
|
||||
struct drm_mode_destroy_blob destroy_blob {};
|
||||
destroy_blob.blob_id = (__u32)*it;
|
||||
auto err = drmIoctl(GetFd(), DRM_IOCTL_MODE_DESTROYPROPBLOB,
|
||||
auto err = drmIoctl(*GetFd(), DRM_IOCTL_MODE_DESTROYPROPBLOB,
|
||||
&destroy_blob);
|
||||
if (err != 0) {
|
||||
ALOGE("Failed to destroy mode property blob %" PRIu32 "/%d", *it,
|
||||
|
|
@ -186,7 +186,7 @@ int DrmDevice::GetProperty(uint32_t obj_id, uint32_t obj_type,
|
|||
const char *prop_name, DrmProperty *property) const {
|
||||
drmModeObjectPropertiesPtr props = nullptr;
|
||||
|
||||
props = drmModeObjectGetProperties(GetFd(), obj_id, obj_type);
|
||||
props = drmModeObjectGetProperties(*GetFd(), obj_id, obj_type);
|
||||
if (props == nullptr) {
|
||||
ALOGE("Failed to get properties for %d/%x", obj_id, obj_type);
|
||||
return -ENODEV;
|
||||
|
|
@ -195,7 +195,7 @@ int DrmDevice::GetProperty(uint32_t obj_id, uint32_t obj_type,
|
|||
bool found = false;
|
||||
for (int i = 0; !found && (size_t)i < props->count_props; ++i) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
drmModePropertyPtr p = drmModeGetProperty(GetFd(), props->props[i]);
|
||||
drmModePropertyPtr p = drmModeGetProperty(*GetFd(), props->props[i]);
|
||||
if (strcmp(p->name, prop_name) == 0) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
property->Init(obj_id, p, props->prop_values[i]);
|
||||
|
|
@ -209,9 +209,9 @@ int DrmDevice::GetProperty(uint32_t obj_id, uint32_t obj_type,
|
|||
}
|
||||
|
||||
std::string DrmDevice::GetName() const {
|
||||
auto *ver = drmGetVersion(GetFd());
|
||||
auto *ver = drmGetVersion(*GetFd());
|
||||
if (ver == nullptr) {
|
||||
ALOGW("Failed to get drm version for fd=%d", GetFd());
|
||||
ALOGW("Failed to get drm version for fd=%d", *GetFd());
|
||||
return "generic";
|
||||
}
|
||||
|
||||
|
|
@ -221,12 +221,12 @@ std::string DrmDevice::GetName() const {
|
|||
}
|
||||
|
||||
auto DrmDevice::IsKMSDev(const char *path) -> bool {
|
||||
auto fd = UniqueFd(open(path, O_RDWR | O_CLOEXEC));
|
||||
auto fd = MakeUniqueFd(open(path, O_RDWR | O_CLOEXEC));
|
||||
if (!fd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto res = MakeDrmModeResUnique(fd.Get());
|
||||
auto res = MakeDrmModeResUnique(*fd);
|
||||
if (!res) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include "DrmConnector.h"
|
||||
#include "DrmCrtc.h"
|
||||
#include "DrmEncoder.h"
|
||||
#include "utils/UniqueFd.h"
|
||||
#include "utils/fd.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
|
|
@ -38,8 +38,8 @@ class DrmDevice {
|
|||
static auto CreateInstance(std::string const &path, ResourceManager *res_man)
|
||||
-> std::unique_ptr<DrmDevice>;
|
||||
|
||||
auto GetFd() const {
|
||||
return fd_.Get();
|
||||
auto &GetFd() const {
|
||||
return fd_;
|
||||
}
|
||||
|
||||
auto &GetResMan() {
|
||||
|
|
@ -101,7 +101,7 @@ class DrmDevice {
|
|||
|
||||
static auto IsKMSDev(const char *path) -> bool;
|
||||
|
||||
UniqueFd fd_;
|
||||
SharedFd fd_;
|
||||
|
||||
std::vector<std::unique_ptr<DrmConnector>> connectors_;
|
||||
std::vector<std::unique_ptr<DrmConnector>> writeback_connectors_;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace android {
|
|||
|
||||
auto DrmEncoder::CreateInstance(DrmDevice &dev, uint32_t encoder_id,
|
||||
uint32_t index) -> std::unique_ptr<DrmEncoder> {
|
||||
auto e = MakeDrmModeEncoderUnique(dev.GetFd(), encoder_id);
|
||||
auto e = MakeDrmModeEncoderUnique(*dev.GetFd(), encoder_id);
|
||||
if (!e) {
|
||||
ALOGE("Failed to get encoder %d", encoder_id);
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ auto DrmFbIdHandle::CreateInstance(BufferInfo *bo, GemHandle first_gem_handle,
|
|||
for (size_t i = 1; i < local->gem_handles_.size(); i++) {
|
||||
if (bo->prime_fds[i] > 0) {
|
||||
if (bo->prime_fds[i] != bo->prime_fds[0]) {
|
||||
err = drmPrimeFDToHandle(drm.GetFd(), bo->prime_fds[i],
|
||||
err = drmPrimeFDToHandle(*drm.GetFd(), bo->prime_fds[i],
|
||||
&local->gem_handles_.at(i));
|
||||
if (err != 0) {
|
||||
ALOGE("failed to import prime fd %d errno=%d", bo->prime_fds[i],
|
||||
|
|
@ -74,11 +74,11 @@ auto DrmFbIdHandle::CreateInstance(BufferInfo *bo, GemHandle first_gem_handle,
|
|||
|
||||
/* Create framebuffer object */
|
||||
if (!has_modifiers) {
|
||||
err = drmModeAddFB2(drm.GetFd(), bo->width, bo->height, bo->format,
|
||||
err = drmModeAddFB2(*drm.GetFd(), bo->width, bo->height, bo->format,
|
||||
local->gem_handles_.data(), &bo->pitches[0],
|
||||
&bo->offsets[0], &local->fb_id_, 0);
|
||||
} else {
|
||||
err = drmModeAddFB2WithModifiers(drm.GetFd(), bo->width, bo->height,
|
||||
err = drmModeAddFB2WithModifiers(*drm.GetFd(), bo->width, bo->height,
|
||||
bo->format, local->gem_handles_.data(),
|
||||
&bo->pitches[0], &bo->offsets[0],
|
||||
&bo->modifiers[0], &local->fb_id_,
|
||||
|
|
@ -97,7 +97,7 @@ DrmFbIdHandle::~DrmFbIdHandle() {
|
|||
ATRACE_NAME("Close FB and dmabufs");
|
||||
|
||||
/* Destroy framebuffer object */
|
||||
if (drmModeRmFB(drm_->GetFd(), fb_id_) != 0) {
|
||||
if (drmModeRmFB(*drm_->GetFd(), fb_id_) != 0) {
|
||||
ALOGE("Failed to rm fb");
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ DrmFbIdHandle::~DrmFbIdHandle() {
|
|||
continue;
|
||||
}
|
||||
gem_close.handle = gem_handles_[i];
|
||||
auto err = drmIoctl(drm_->GetFd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
|
||||
auto err = drmIoctl(*drm_->GetFd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
|
||||
if (err != 0) {
|
||||
ALOGE("Failed to close gem handle %d, errno: %d", gem_handles_[i], errno);
|
||||
}
|
||||
|
|
@ -129,7 +129,8 @@ auto DrmFbImporter::GetOrCreateFbId(BufferInfo *bo)
|
|||
-> std::shared_ptr<DrmFbIdHandle> {
|
||||
/* Lookup DrmFbIdHandle in cache first. First handle serves as a cache key. */
|
||||
GemHandle first_handle = 0;
|
||||
auto err = drmPrimeFDToHandle(drm_->GetFd(), bo->prime_fds[0], &first_handle);
|
||||
auto err = drmPrimeFDToHandle(*drm_->GetFd(), bo->prime_fds[0],
|
||||
&first_handle);
|
||||
|
||||
if (err != 0) {
|
||||
ALOGE("Failed to import prime fd %d ret=%d", bo->prime_fds[0], err);
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace android {
|
|||
|
||||
auto DrmPlane::CreateInstance(DrmDevice &dev, uint32_t plane_id)
|
||||
-> std::unique_ptr<DrmPlane> {
|
||||
auto p = MakeDrmModePlaneUnique(dev.GetFd(), plane_id);
|
||||
auto p = MakeDrmModePlaneUnique(*dev.GetFd(), plane_id);
|
||||
if (!p) {
|
||||
ALOGE("Failed to get plane %d", plane_id);
|
||||
return {};
|
||||
|
|
@ -261,7 +261,7 @@ auto DrmPlane::AtomicSetState(drmModeAtomicReq &pset, LayerData &layer,
|
|||
}
|
||||
|
||||
if (layer.acquire_fence &&
|
||||
!in_fence_fd_property_.AtomicSet(pset, layer.acquire_fence.Get())) {
|
||||
!in_fence_fd_property_.AtomicSet(pset, *layer.acquire_fence)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ auto VSyncWorker::CreateInstance(DrmDisplayPipeline *pipe,
|
|||
if (pipe != nullptr) {
|
||||
vsw->high_crtc_ = pipe->crtc->Get()->GetIndexInResArray()
|
||||
<< DRM_VBLANK_HIGH_CRTC_SHIFT;
|
||||
vsw->drm_fd_ = UniqueFd::Dup(pipe->device->GetFd());
|
||||
vsw->drm_fd_ = pipe->device->GetFd();
|
||||
}
|
||||
|
||||
std::thread(&VSyncWorker::ThreadFn, vsw.get(), vsw).detach();
|
||||
|
|
@ -143,7 +143,7 @@ void VSyncWorker::ThreadFn(const std::shared_ptr<VSyncWorker> &vsw) {
|
|||
DRM_VBLANK_HIGH_CRTC_MASK));
|
||||
vblank.request.sequence = 1;
|
||||
|
||||
ret = drmWaitVBlank(drm_fd_.Get(), &vblank);
|
||||
ret = drmWaitVBlank(*drm_fd_, &vblank);
|
||||
if (ret == -EINTR)
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class VSyncWorker {
|
|||
|
||||
VSyncWorkerCallbacks callbacks_;
|
||||
|
||||
UniqueFd drm_fd_;
|
||||
SharedFd drm_fd_;
|
||||
uint32_t high_crtc_ = 0;
|
||||
|
||||
bool enabled_ = false;
|
||||
|
|
|
|||
|
|
@ -452,7 +452,7 @@ HWC2::Error HwcDisplay::GetReleaseFences(uint32_t *num_elements,
|
|||
}
|
||||
|
||||
layers[num_layers - 1] = l.first;
|
||||
fences[num_layers - 1] = UniqueFd::Dup(present_fence_.Get()).Release();
|
||||
fences[num_layers - 1] = DupFd(present_fence_);
|
||||
}
|
||||
*num_elements = num_layers;
|
||||
|
||||
|
|
@ -592,8 +592,8 @@ HWC2::Error HwcDisplay::PresentDisplay(int32_t *out_present_fence) {
|
|||
if (ret != HWC2::Error::None)
|
||||
return ret;
|
||||
|
||||
this->present_fence_ = UniqueFd::Dup(a_args.out_fence.Get());
|
||||
*out_present_fence = a_args.out_fence.Release();
|
||||
this->present_fence_ = a_args.out_fence;
|
||||
*out_present_fence = DupFd(a_args.out_fence);
|
||||
|
||||
++frame_no_;
|
||||
return HWC2::Error::None;
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ class HwcDisplay {
|
|||
|
||||
DrmHwcTwo *const hwc2_;
|
||||
|
||||
UniqueFd present_fence_;
|
||||
SharedFd present_fence_;
|
||||
|
||||
std::optional<DrmMode> staged_mode_;
|
||||
int64_t staged_mode_change_time_{};
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ HWC2::Error HwcLayer::SetLayerBlendMode(int32_t mode) {
|
|||
*/
|
||||
HWC2::Error HwcLayer::SetLayerBuffer(buffer_handle_t buffer,
|
||||
int32_t acquire_fence) {
|
||||
acquire_fence_ = UniqueFd(acquire_fence);
|
||||
acquire_fence_ = MakeUniqueFd(acquire_fence);
|
||||
buffer_handle_ = buffer;
|
||||
buffer_handle_updated_ = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -86,8 +86,7 @@ class HwcLayer {
|
|||
uint32_t z_order_ = 0;
|
||||
LayerData layer_data_;
|
||||
|
||||
/* Should be populated to layer_data_.acquire_fence only before presenting */
|
||||
UniqueFd acquire_fence_;
|
||||
SharedFd acquire_fence_;
|
||||
|
||||
/* The following buffer data can have 2 sources:
|
||||
* 1 - Mapper@4 metadata API
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ src_common = files(
|
|||
'backend/BackendManager.cpp',
|
||||
'backend/Backend.cpp',
|
||||
'backend/BackendClient.cpp',
|
||||
'utils/fd.cpp',
|
||||
)
|
||||
|
||||
deps = [
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "UniqueFd.h"
|
||||
#include "fd.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace android {
|
||||
|
|
@ -32,7 +32,7 @@ namespace android {
|
|||
class UEvent {
|
||||
public:
|
||||
static auto CreateInstance() -> std::unique_ptr<UEvent> {
|
||||
auto fd = UniqueFd(
|
||||
auto fd = MakeUniqueFd(
|
||||
socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT));
|
||||
|
||||
if (!fd) {
|
||||
|
|
@ -46,7 +46,7 @@ class UEvent {
|
|||
addr.nl_groups = UINT32_MAX;
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
|
||||
const int ret = bind(fd.Get(), (struct sockaddr *)&addr, sizeof(addr));
|
||||
const int ret = bind(*fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (ret != 0) {
|
||||
ALOGE("Failed to bind uevent socket: errno=%i", errno);
|
||||
return {};
|
||||
|
|
@ -59,7 +59,7 @@ class UEvent {
|
|||
constexpr int kUEventBufferSize = 1024;
|
||||
char buffer[kUEventBufferSize];
|
||||
ssize_t ret = 0;
|
||||
ret = read(fd_.Get(), &buffer, sizeof(buffer));
|
||||
ret = read(*fd_, &buffer, sizeof(buffer));
|
||||
if (ret == 0)
|
||||
return {};
|
||||
|
||||
|
|
|
|||
115
utils/UniqueFd.h
115
utils/UniqueFd.h
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015, 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* Using UniqueFd:
|
||||
* 1. Create UniqueFd object:
|
||||
* auto fd_obj = UniqueFd(open("SomeFile", xxx));
|
||||
*
|
||||
* 2. Check whether the fd_obj is empty:
|
||||
* if (!fd_obj) { return -errno; }
|
||||
*
|
||||
* 3. Accessing the file descriptor:
|
||||
* int ret = read(fd_obj.Get(), buf, buf_size);
|
||||
*
|
||||
* 4. Closing the file:
|
||||
* FD will be closed once execution leaves fd_obj scope (on any return,
|
||||
* exception, destruction of class/struct where object is member, etc.).
|
||||
* User can also force closing the fd_obj by calling:
|
||||
* fd_obj = UniqueFd();
|
||||
* // fd is closed and fd_obj is empty now.
|
||||
*
|
||||
* 5. File descriptor may be transferred to the code, which will close it after
|
||||
* using. This can be done in 2 ways:
|
||||
* a. Duplicate the fd, in this case both fds should be closed separately:
|
||||
* int out_fd = dup(fd_obj.Get();
|
||||
* ...
|
||||
* close(out_fd);
|
||||
* b. Transfer ownership, use this method if you do not need the fd anymore.
|
||||
* int out_fd = fd_obj.Release();
|
||||
* // fd_obj is empty now.
|
||||
* ...
|
||||
* close(out_fd);
|
||||
*
|
||||
* 6. Transferring fd into another UniqueFD object:
|
||||
* UniqueFd fd_obj_2 = std::move(fd_obj);
|
||||
* // fd_obj empty now
|
||||
*/
|
||||
|
||||
constexpr int kEmptyFd = -1;
|
||||
|
||||
class UniqueFd {
|
||||
public:
|
||||
UniqueFd() = default;
|
||||
explicit UniqueFd(int fd) : fd_(fd){};
|
||||
|
||||
auto Release [[nodiscard]] () -> int {
|
||||
return std::exchange(fd_, kEmptyFd);
|
||||
}
|
||||
|
||||
auto Get [[nodiscard]] () const -> int {
|
||||
return fd_;
|
||||
}
|
||||
|
||||
static auto Dup(int fd) {
|
||||
// NOLINTNEXTLINE(android-cloexec-dup): fcntl has issue (see issue #63)
|
||||
return UniqueFd(dup(fd));
|
||||
}
|
||||
|
||||
explicit operator bool() const {
|
||||
return fd_ != kEmptyFd;
|
||||
}
|
||||
|
||||
~UniqueFd() {
|
||||
Set(kEmptyFd);
|
||||
}
|
||||
|
||||
/* Allow move semantics */
|
||||
UniqueFd(UniqueFd &&rhs) noexcept {
|
||||
Set(rhs.Release());
|
||||
}
|
||||
|
||||
auto operator=(UniqueFd &&rhs) noexcept -> UniqueFd & {
|
||||
Set(rhs.Release());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* Disable copy semantics */
|
||||
UniqueFd(const UniqueFd &) = delete;
|
||||
auto operator=(const UniqueFd &) = delete;
|
||||
|
||||
private:
|
||||
void Set(int new_fd) {
|
||||
if (fd_ != kEmptyFd) {
|
||||
close(fd_);
|
||||
}
|
||||
fd_ = new_fd;
|
||||
}
|
||||
|
||||
int fd_ = kEmptyFd;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
52
utils/fd.cpp
Normal file
52
utils/fd.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "fd.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
static void CloseFd(const int *fd) {
|
||||
if (fd != nullptr) {
|
||||
if (*fd >= 0)
|
||||
close(*fd);
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
|
||||
delete fd;
|
||||
}
|
||||
}
|
||||
|
||||
auto MakeUniqueFd(int fd) -> UniqueFd {
|
||||
if (fd < 0)
|
||||
return {nullptr, CloseFd};
|
||||
|
||||
return {new int(fd), CloseFd};
|
||||
}
|
||||
|
||||
auto MakeSharedFd(int fd) -> SharedFd {
|
||||
if (fd < 0)
|
||||
return {};
|
||||
|
||||
return {new int(fd), CloseFd};
|
||||
}
|
||||
|
||||
auto DupFd(SharedFd const &fd) -> int {
|
||||
if (!fd)
|
||||
return -1;
|
||||
|
||||
return fcntl(*fd, F_DUPFD_CLOEXEC, 0);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
36
utils/fd.h
Normal file
36
utils/fd.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2015 - 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace android {
|
||||
|
||||
using UniqueFd = std::unique_ptr<int, void (*)(const int *)>;
|
||||
using SharedFd = std::shared_ptr<int>;
|
||||
|
||||
auto MakeUniqueFd(int fd) -> UniqueFd;
|
||||
|
||||
auto MakeSharedFd(int fd) -> SharedFd;
|
||||
|
||||
auto DupFd(SharedFd const &fd) -> int;
|
||||
|
||||
} // namespace android
|
||||
Loading…
Add table
Add a link
Reference in a new issue