aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.ci/Makefile1
-rw-r--r--Android.bp2
-rw-r--r--compositor/LayerData.h4
-rw-r--r--drm/DrmAtomicStateManager.cpp28
-rw-r--r--drm/DrmAtomicStateManager.h4
-rw-r--r--drm/DrmConnector.cpp6
-rw-r--r--drm/DrmCrtc.cpp2
-rw-r--r--drm/DrmDevice.cpp34
-rw-r--r--drm/DrmDevice.h8
-rw-r--r--drm/DrmEncoder.cpp2
-rw-r--r--drm/DrmFbImporter.cpp13
-rw-r--r--drm/DrmPlane.cpp4
-rw-r--r--drm/VSyncWorker.cpp4
-rw-r--r--drm/VSyncWorker.h2
-rw-r--r--hwc2_device/HwcDisplay.cpp6
-rw-r--r--hwc2_device/HwcDisplay.h2
-rw-r--r--hwc2_device/HwcLayer.cpp2
-rw-r--r--hwc2_device/HwcLayer.h3
-rw-r--r--meson.build1
-rw-r--r--utils/UEvent.h8
-rw-r--r--utils/UniqueFd.h115
-rw-r--r--utils/fd.cpp52
-rw-r--r--utils/fd.h36
23 files changed, 157 insertions, 182 deletions
diff --git a/.ci/Makefile b/.ci/Makefile
index de5196b..9c82fca 100644
--- a/.ci/Makefile
+++ b/.ci/Makefile
@@ -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 \
diff --git a/Android.bp b/Android.bp
index 3ad060c..1e78729 100644
--- a/Android.bp
+++ b/Android.bp
@@ -83,6 +83,8 @@ filegroup {
"hwc2_device/HwcDisplayConfigs.cpp",
"hwc2_device/HwcLayer.cpp",
"hwc2_device/hwc2_device.cpp",
+
+ "utils/fd.cpp",
],
}
diff --git a/compositor/LayerData.h b/compositor/LayerData.h
index 92d4da0..a7e14f9 100644
--- a/compositor/LayerData.h
+++ b/compositor/LayerData.h
@@ -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
diff --git a/drm/DrmAtomicStateManager.cpp b/drm/DrmAtomicStateManager.cpp
index b5e4629..58a5523 100644
--- a/drm/DrmAtomicStateManager.cpp
+++ b/drm/DrmAtomicStateManager.cpp
@@ -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()
diff --git a/drm/DrmAtomicStateManager.h b/drm/DrmAtomicStateManager.h
index 5f19bcc..e456a91 100644
--- a/drm/DrmAtomicStateManager.h
+++ b/drm/DrmAtomicStateManager.h
@@ -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_{};
diff --git a/drm/DrmConnector.cpp b/drm/DrmConnector.cpp
index 07c5d74..f625563 100644
--- a/drm/DrmConnector.cpp
+++ b/drm/DrmConnector.cpp
@@ -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;
diff --git a/drm/DrmCrtc.cpp b/drm/DrmCrtc.cpp
index b54f14b..3b749b1 100644
--- a/drm/DrmCrtc.cpp
+++ b/drm/DrmCrtc.cpp
@@ -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 {};
diff --git a/drm/DrmDevice.cpp b/drm/DrmDevice.cpp
index 33adf2a..1d6b62e 100644
--- a/drm/DrmDevice.cpp
+++ b/drm/DrmDevice.cpp
@@ -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;
}
diff --git a/drm/DrmDevice.h b/drm/DrmDevice.h
index bb515e0..39d0c88 100644
--- a/drm/DrmDevice.h
+++ b/drm/DrmDevice.h
@@ -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_;
diff --git a/drm/DrmEncoder.cpp b/drm/DrmEncoder.cpp
index eed5b5f..21ca693 100644
--- a/drm/DrmEncoder.cpp
+++ b/drm/DrmEncoder.cpp
@@ -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 {};
diff --git a/drm/DrmFbImporter.cpp b/drm/DrmFbImporter.cpp
index f0be32f..a91a52b 100644
--- a/drm/DrmFbImporter.cpp
+++ b/drm/DrmFbImporter.cpp
@@ -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);
diff --git a/drm/DrmPlane.cpp b/drm/DrmPlane.cpp
index 4d03840..228e3dd 100644
--- a/drm/DrmPlane.cpp
+++ b/drm/DrmPlane.cpp
@@ -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;
}
diff --git a/drm/VSyncWorker.cpp b/drm/VSyncWorker.cpp
index 77b9d98..8a251c7 100644
--- a/drm/VSyncWorker.cpp
+++ b/drm/VSyncWorker.cpp
@@ -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;
}
diff --git a/drm/VSyncWorker.h b/drm/VSyncWorker.h
index 2a0b084..031a561 100644
--- a/drm/VSyncWorker.h
+++ b/drm/VSyncWorker.h
@@ -52,7 +52,7 @@ class VSyncWorker {
VSyncWorkerCallbacks callbacks_;
- UniqueFd drm_fd_;
+ SharedFd drm_fd_;
uint32_t high_crtc_ = 0;
bool enabled_ = false;
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 194889e..d957dc3 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -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;
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index 4ad57b7..6cac60f 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -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_{};
diff --git a/hwc2_device/HwcLayer.cpp b/hwc2_device/HwcLayer.cpp
index 589a0a7..d3936b3 100644
--- a/hwc2_device/HwcLayer.cpp
+++ b/hwc2_device/HwcLayer.cpp
@@ -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;
diff --git a/hwc2_device/HwcLayer.h b/hwc2_device/HwcLayer.h
index 627d5ac..7f647a8 100644
--- a/hwc2_device/HwcLayer.h
+++ b/hwc2_device/HwcLayer.h
@@ -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
diff --git a/meson.build b/meson.build
index 266163e..4328a1e 100644
--- a/meson.build
+++ b/meson.build
@@ -14,6 +14,7 @@ src_common = files(
'backend/BackendManager.cpp',
'backend/Backend.cpp',
'backend/BackendClient.cpp',
+ 'utils/fd.cpp',
)
deps = [
diff --git a/utils/UEvent.h b/utils/UEvent.h
index 64992a1..5b9ecea 100644
--- a/utils/UEvent.h
+++ b/utils/UEvent.h
@@ -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 {};
diff --git a/utils/UniqueFd.h b/utils/UniqueFd.h
deleted file mode 100644
index f65bedc..0000000
--- a/utils/UniqueFd.h
+++ /dev/null
@@ -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
diff --git a/utils/fd.cpp b/utils/fd.cpp
new file mode 100644
index 0000000..395d3b2
--- /dev/null
+++ b/utils/fd.cpp
@@ -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
diff --git a/utils/fd.h b/utils/fd.h
new file mode 100644
index 0000000..6bfd0fa
--- /dev/null
+++ b/utils/fd.h
@@ -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