aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2021-08-25 18:39:06 +0000
committerJohn Stultz <john.stultz@linaro.org>2021-08-25 18:39:06 +0000
commit38163fdedc8600cb18c1b5dac2e12b3050565290 (patch)
treef710c50bff91decd514af8cd690aceb802a0e231
parent82288efb3a5e9d08eed5f12b852e419f635c1bc9 (diff)
parent8514329f7e98dba60c396a8d0cab72daeb78e65e (diff)
downloaddrm_hwcomposer-android-s-beta-5.tar.gz
drm_hwcomposer: Merge remote-tracking branch 'aosp/upstream-main' into HEADandroid-s-beta-5android-s-beta-5
Just updates the branch to match upstream. This merge contains a number of cleanups as well as some follow-on fixups. * aosp/upstream-main: drm_hwcomposer: Don't close same handle several times. drm_hwcomposer: Quiet noisy errors when planes don't support various attributes drm_hwcomposer: Fix sync_file fd leak from "Rework audofd" drm_hwcomposer: Add links to the HWC2 API description drm_hwcomposer: Rework autofd drm_hwcomposer: cleanup hwcutils drm_hwcomposer: Stop importing native_handle_t into the mapper drm_hwcomposer: Tracking of the DRM FB objects using RAII Signed-off-by: John Stultz <john.stultz@linaro.org> Change-Id: I9f733a6d9adb71b6c8b24d764e881904f66de146
-rw-r--r--.ci/.common.sh4
-rwxr-xr-x.ci/.gitlab-ci-clang-tidy-fine.sh2
-rw-r--r--Android.bp2
-rw-r--r--DrmHwcTwo.cpp61
-rw-r--r--DrmHwcTwo.h45
-rw-r--r--compositor/DrmDisplayComposition.cpp14
-rw-r--r--compositor/DrmDisplayComposition.h12
-rw-r--r--compositor/DrmDisplayCompositor.cpp8
-rw-r--r--compositor/DrmDisplayCompositor.h9
-rw-r--r--compositor/Planner.cpp4
-rw-r--r--drm/DrmDevice.cpp15
-rw-r--r--drm/DrmDevice.h21
-rw-r--r--drm/DrmEventListener.cpp16
-rw-r--r--drm/DrmEventListener.h2
-rw-r--r--drm/DrmFbImporter.cpp154
-rw-r--r--drm/DrmFbImporter.h94
-rw-r--r--drm/DrmGenericImporter.cpp135
-rw-r--r--drm/DrmGenericImporter.h72
-rw-r--r--drm/DrmPlane.cpp2
-rw-r--r--drm/ResourceManager.cpp21
-rw-r--r--drm/ResourceManager.h4
-rw-r--r--include/autofd.h106
-rw-r--r--include/drmhwcgralloc.h3
-rw-r--r--include/drmhwcomposer.h102
-rw-r--r--utils/UniqueFd.h111
-rw-r--r--utils/hwcutils.cpp104
26 files changed, 491 insertions, 632 deletions
diff --git a/.ci/.common.sh b/.ci/.common.sh
index 93f7f95..0183aba 100644
--- a/.ci/.common.sh
+++ b/.ci/.common.sh
@@ -5,7 +5,7 @@ CLANG_TIDY="clang-tidy-11"
CXXARGS="-fPIC -Wall -Werror -DPLATFORM_SDK_VERSION=30 -D__ANDROID_API__=30 -Wsign-promo -Wimplicit-fallthrough"
CXXARGS+=" -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -Wno-gnu-include-next "
-CXXARGS+=" -fvisibility-inlines-hidden -std=gnu++17 -DHWC2_USE_CPP11 -DHWC2_INCLUDE_STRINGIFICATION -fexceptions -fno-rtti"
+CXXARGS+=" -fvisibility-inlines-hidden -std=gnu++17 -DHWC2_USE_CPP11 -DHWC2_INCLUDE_STRINGIFICATION -fno-rtti"
BUILD_FILES=(
backend/BackendClient.cpp
@@ -28,7 +28,7 @@ drm/DrmCrtc.cpp
drm/DrmDevice.cpp
drm/DrmEncoder.cpp
drm/DrmEventListener.cpp
-drm/DrmGenericImporter.cpp
+drm/DrmFbImporter.cpp
drm/DrmMode.cpp
drm/DrmPlane.cpp
drm/DrmProperty.cpp
diff --git a/.ci/.gitlab-ci-clang-tidy-fine.sh b/.ci/.gitlab-ci-clang-tidy-fine.sh
index 644f621..c1805e8 100755
--- a/.ci/.gitlab-ci-clang-tidy-fine.sh
+++ b/.ci/.gitlab-ci-clang-tidy-fine.sh
@@ -3,6 +3,8 @@
. ./.ci/.common.sh
TIDY_FILES=(
+drm/DrmFbImporter.h
+utils/UniqueFd.h
utils/log.h
utils/properties.h
)
diff --git a/Android.bp b/Android.bp
index d3c812d..a4d8e18 100644
--- a/Android.bp
+++ b/Android.bp
@@ -113,7 +113,7 @@ cc_library_static {
"drm/DrmDevice.cpp",
"drm/DrmEncoder.cpp",
"drm/DrmEventListener.cpp",
- "drm/DrmGenericImporter.cpp",
+ "drm/DrmFbImporter.cpp",
"drm/DrmMode.cpp",
"drm/DrmPlane.cpp",
"drm/DrmProperty.cpp",
diff --git a/DrmHwcTwo.cpp b/DrmHwcTwo.cpp
index 8b2abfd..02667cf 100644
--- a/DrmHwcTwo.cpp
+++ b/DrmHwcTwo.cpp
@@ -19,9 +19,11 @@
#include "DrmHwcTwo.h"
+#include <fcntl.h>
#include <hardware/hardware.h>
#include <hardware/hwcomposer2.h>
#include <sync/sync.h>
+#include <unistd.h>
#include <cinttypes>
#include <iostream>
@@ -47,14 +49,13 @@ DrmHwcTwo::DrmHwcTwo() : hwc2_device() {
HWC2::Error DrmHwcTwo::CreateDisplay(hwc2_display_t displ,
HWC2::DisplayType type) {
DrmDevice *drm = resource_manager_.GetDrmDevice(displ);
- std::shared_ptr<Importer> importer = resource_manager_.GetImporter(displ);
- if (!drm || !importer) {
- ALOGE("Failed to get a valid drmresource and importer");
+ if (!drm) {
+ ALOGE("Failed to get a valid drmresource");
return HWC2::Error::NoResources;
}
displays_.emplace(std::piecewise_construct, std::forward_as_tuple(displ),
- std::forward_as_tuple(&resource_manager_, drm, importer,
- displ, type));
+ std::forward_as_tuple(&resource_manager_, drm, displ,
+ type));
DrmCrtc *crtc = drm->GetCrtcForDisplay(static_cast<int>(displ));
if (!crtc) {
@@ -209,12 +210,10 @@ HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
}
DrmHwcTwo::HwcDisplay::HwcDisplay(ResourceManager *resource_manager,
- DrmDevice *drm,
- std::shared_ptr<Importer> importer,
- hwc2_display_t handle, HWC2::DisplayType type)
+ DrmDevice *drm, hwc2_display_t handle,
+ HWC2::DisplayType type)
: resource_manager_(resource_manager),
drm_(drm),
- importer_(std::move(importer)),
handle_(handle),
type_(type),
color_transform_hint_(HAL_COLOR_TRANSFORM_IDENTITY) {
@@ -583,6 +582,9 @@ HWC2::Error DrmHwcTwo::HwcDisplay::GetHdrCapabilities(
return HWC2::Error::None;
}
+/* Find API details at:
+ * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1767
+ */
HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements,
hwc2_layer_t *layers,
int32_t *fences) {
@@ -600,22 +602,22 @@ HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements,
}
layers[num_layers - 1] = l.first;
- fences[num_layers - 1] = l.second.take_release_fence();
+ fences[num_layers - 1] = l.second.release_fence_.Release();
}
*num_elements = num_layers;
return HWC2::Error::None;
}
-void DrmHwcTwo::HwcDisplay::AddFenceToPresentFence(int fd) {
- if (fd < 0)
+void DrmHwcTwo::HwcDisplay::AddFenceToPresentFence(UniqueFd fd) {
+ if (!fd) {
return;
+ }
- if (present_fence_.get() >= 0) {
- int old_fence = present_fence_.get();
- present_fence_.Set(sync_merge("dc_present", old_fence, fd));
- close(fd);
+ if (present_fence_) {
+ present_fence_ = UniqueFd(
+ sync_merge("dc_present", present_fence_.Get(), fd.Get()));
} else {
- present_fence_.Set(fd);
+ present_fence_ = std::move(fd);
}
}
@@ -650,7 +652,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
DrmHwcLayer layer;
l.second->PopulateDrmLayer(&layer);
- int ret = layer.ImportBuffer(importer_.get());
+ int ret = layer.ImportBuffer(drm_);
if (ret) {
ALOGE("Failed to import layer, ret=%d", ret);
return HWC2::Error::NoResources;
@@ -673,7 +675,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
std::vector<DrmPlane *> overlay_planes(overlay_planes_);
ret = composition->Plan(&primary_planes, &overlay_planes);
if (ret) {
- ALOGE("Failed to plan the composition ret=%d", ret);
+ ALOGV("Failed to plan the composition ret=%d", ret);
return HWC2::Error::BadConfig;
}
@@ -701,6 +703,9 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
return HWC2::Error::None;
}
+/* Find API details at:
+ * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1805
+ */
HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *present_fence) {
supported(__func__);
HWC2::Error ret;
@@ -761,15 +766,17 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) {
return HWC2::Error::None;
}
+/* Find API details at:
+ * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=1861
+ */
HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target,
int32_t acquire_fence,
int32_t dataspace,
hwc_region_t /*damage*/) {
supported(__func__);
- UniqueFd uf(acquire_fence);
client_layer_.set_buffer(target);
- client_layer_.set_acquire_fence(uf.get());
+ client_layer_.acquire_fence_ = UniqueFd(acquire_fence);
client_layer_.SetLayerDataspace(dataspace);
/* TODO: Do not update source_crop every call.
@@ -1047,13 +1054,15 @@ HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) {
return HWC2::Error::None;
}
+/* Find API details at:
+ * https://cs.android.com/android/platform/superproject/+/android-11.0.0_r3:hardware/libhardware/include/hardware/hwcomposer2.h;l=2314
+ */
HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer,
int32_t acquire_fence) {
supported(__func__);
- UniqueFd uf(acquire_fence);
set_buffer(buffer);
- set_acquire_fence(uf.get());
+ acquire_fence_ = UniqueFd(acquire_fence);
return HWC2::Error::None;
}
@@ -1144,11 +1153,9 @@ void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
break;
}
- OutputFd release_fence = release_fence_output();
-
layer->sf_handle = buffer_;
- layer->acquire_fence = acquire_fence_.Release();
- layer->release_fence = std::move(release_fence);
+ // TODO(rsglobal): Avoid extra fd duplication
+ layer->acquire_fence = UniqueFd(fcntl(acquire_fence_.Get(), F_DUPFD_CLOEXEC));
layer->display_frame = display_frame_;
layer->alpha = lround(65535.0F * alpha_);
layer->source_crop = source_crop_;
diff --git a/DrmHwcTwo.h b/DrmHwcTwo.h
index a0d8cdd..111c664 100644
--- a/DrmHwcTwo.h
+++ b/DrmHwcTwo.h
@@ -25,7 +25,6 @@
#include "compositor/DrmDisplayCompositor.h"
#include "compositor/Planner.h"
-#include "drm/DrmGenericImporter.h"
#include "drm/ResourceManager.h"
#include "drm/VSyncWorker.h"
#include "drmhwcomposer.h"
@@ -83,27 +82,6 @@ class DrmHwcTwo : public hwc2_device_t {
buffer_ = buffer;
}
- int take_acquire_fence() {
- return acquire_fence_.Release();
- }
- void set_acquire_fence(int acquire_fence) {
- acquire_fence_.Set(dup(acquire_fence));
- }
-
- int release_fence() {
- return release_fence_.get();
- }
- int take_release_fence() {
- return release_fence_.Release();
- }
- void manage_release_fence() {
- release_fence_.Set(release_fence_raw_);
- release_fence_raw_ = -1;
- }
- OutputFd release_fence_output() {
- return OutputFd(&release_fence_raw_);
- }
-
hwc_rect_t display_frame() {
return display_frame_;
}
@@ -139,6 +117,16 @@ class DrmHwcTwo : public hwc2_device_t {
HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
HWC2::Error SetLayerZOrder(uint32_t order);
+ UniqueFd acquire_fence_;
+
+ /*
+ * Release fence is not used.
+ * There is no release fence support available in the DRM/KMS. In case no
+ * release fence provided application will use this buffer for writing when
+ * the next frame present fence is signaled.
+ */
+ UniqueFd release_fence_;
+
private:
// sf_type_ stores the initial type given to us by surfaceflinger,
// validated_type_ stores the type after running ValidateDisplay
@@ -147,9 +135,6 @@ class DrmHwcTwo : public hwc2_device_t {
HWC2::BlendMode blending_ = HWC2::BlendMode::None;
buffer_handle_t buffer_ = NULL;
- UniqueFd acquire_fence_;
- int release_fence_raw_ = -1;
- UniqueFd release_fence_;
hwc_rect_t display_frame_;
float alpha_ = 1.0f;
hwc_frect_t source_crop_;
@@ -164,8 +149,7 @@ class DrmHwcTwo : public hwc2_device_t {
class HwcDisplay {
public:
HwcDisplay(ResourceManager *resource_manager, DrmDevice *drm,
- std::shared_ptr<Importer> importer, hwc2_display_t handle,
- HWC2::DisplayType type);
+ hwc2_display_t handle, HWC2::DisplayType type);
HwcDisplay(const HwcDisplay &) = delete;
HWC2::Error Init(std::vector<DrmPlane *> *planes);
@@ -305,10 +289,6 @@ class DrmHwcTwo : public hwc2_device_t {
return connector_;
}
- const std::shared_ptr<Importer> &importer() const {
- return importer_;
- }
-
ResourceManager *resource_manager() const {
return resource_manager_;
}
@@ -322,14 +302,13 @@ class DrmHwcTwo : public hwc2_device_t {
}
private:
- void AddFenceToPresentFence(int fd);
+ void AddFenceToPresentFence(UniqueFd fd);
constexpr static size_t MATRIX_SIZE = 16;
ResourceManager *resource_manager_;
DrmDevice *drm_;
DrmDisplayCompositor compositor_;
- std::shared_ptr<Importer> importer_;
std::unique_ptr<Planner> planner_;
std::vector<DrmPlane *> primary_planes_;
diff --git a/compositor/DrmDisplayComposition.cpp b/compositor/DrmDisplayComposition.cpp
index 7008e9c..49dff0e 100644
--- a/compositor/DrmDisplayComposition.cpp
+++ b/compositor/DrmDisplayComposition.cpp
@@ -101,7 +101,7 @@ int DrmDisplayComposition::Plan(std::vector<DrmPlane *> *primary_planes,
primary_planes,
overlay_planes);
if (ret) {
- ALOGE("Planner failed provisioning planes ret=%d", ret);
+ ALOGV("Planner failed provisioning planes ret=%d", ret);
return ret;
}
@@ -156,14 +156,10 @@ static const char *DPMSModeToString(int dpms_mode) {
}
}
-static void DumpBuffer(const DrmHwcBuffer &buffer, std::ostringstream *out) {
- if (!buffer) {
- *out << "buffer=<invalid>";
- return;
- }
-
+static void DumpBuffer(const DrmHwcLayer &layer, std::ostringstream *out) {
*out << "buffer[w/h/format]=";
- *out << buffer->width << "/" << buffer->height << "/" << buffer->format;
+ *out << layer.buffer_info.width << "/" << layer.buffer_info.height << "/"
+ << layer.buffer_info.format;
}
static void DumpTransform(uint32_t transform, std::ostringstream *out) {
@@ -249,7 +245,7 @@ void DrmDisplayComposition::Dump(std::ostringstream *out) const {
const DrmHwcLayer &layer = layers_[i];
*out << " [" << i << "] ";
- DumpBuffer(layer.buffer, out);
+ DumpBuffer(layer, out);
if (layer.protected_usage())
*out << " protected";
diff --git a/compositor/DrmDisplayComposition.h b/compositor/DrmDisplayComposition.h
index 27b34f2..1738630 100644
--- a/compositor/DrmDisplayComposition.h
+++ b/compositor/DrmDisplayComposition.h
@@ -127,16 +127,10 @@ class DrmDisplayComposition {
return planner_;
}
- int take_out_fence() {
- return out_fence_.Release();
- }
-
- void set_out_fence(int out_fence) {
- out_fence_.Set(out_fence);
- }
-
void Dump(std::ostringstream *out) const;
+ UniqueFd out_fence_;
+
private:
bool validate_composition_type(DrmCompositionType desired);
@@ -147,8 +141,6 @@ class DrmDisplayComposition {
uint32_t dpms_mode_ = DRM_MODE_DPMS_ON;
DrmMode display_mode_;
- UniqueFd out_fence_ = -1;
-
bool geometry_changed_ = true;
std::vector<DrmHwcLayer> layers_;
std::vector<DrmCompositionPlane> composition_planes_;
diff --git a/compositor/DrmDisplayCompositor.cpp b/compositor/DrmDisplayCompositor.cpp
index 665446e..a1fe50f 100644
--- a/compositor/DrmDisplayCompositor.cpp
+++ b/compositor/DrmDisplayCompositor.cpp
@@ -286,12 +286,12 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
break;
}
DrmHwcLayer &layer = layers[source_layers.front()];
- if (!layer.buffer) {
+ if (!layer.FbIdHandle) {
ALOGE("Expected a valid framebuffer for pset");
break;
}
- fb_id = layer.buffer->fb_id;
- fence_fd = layer.acquire_fence.get();
+ fb_id = layer.FbIdHandle->GetFbId();
+ fence_fd = layer.acquire_fence.Get();
display_frame = layer.display_frame;
source_crop = layer.source_crop;
alpha = layer.alpha;
@@ -540,7 +540,7 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
}
if (crtc->out_fence_ptr_property().id()) {
- display_comp->set_out_fence((int)out_fences[crtc->pipe()]);
+ display_comp->out_fence_ = UniqueFd((int)out_fences[crtc->pipe()]);
}
return ret;
diff --git a/compositor/DrmDisplayCompositor.h b/compositor/DrmDisplayCompositor.h
index aebb6ff..c0eed0c 100644
--- a/compositor/DrmDisplayCompositor.h
+++ b/compositor/DrmDisplayCompositor.h
@@ -72,10 +72,11 @@ class DrmDisplayCompositor {
void Dump(std::ostringstream *out) const;
void Vsync(int display, int64_t timestamp);
void ClearDisplay();
- int TakeOutFence() {
- if (!active_composition_)
- return -1;
- return active_composition_->take_out_fence();
+ UniqueFd TakeOutFence() {
+ if (!active_composition_) {
+ return UniqueFd();
+ }
+ return std::move(active_composition_->out_fence_);
}
FlatteningState GetFlatteningState() const;
diff --git a/compositor/Planner.cpp b/compositor/Planner.cpp
index 42259d1..9db03c3 100644
--- a/compositor/Planner.cpp
+++ b/compositor/Planner.cpp
@@ -60,7 +60,7 @@ std::tuple<int, std::vector<DrmCompositionPlane>> Planner::ProvisionPlanes(
for (auto &i : stages_) {
int ret = i->ProvisionPlanes(&composition, layers, &planes);
if (ret) {
- ALOGE("Failed provision stage with ret %d", ret);
+ ALOGV("Failed provision stage with ret %d", ret);
return std::make_tuple(ret, std::vector<DrmCompositionPlane>());
}
}
@@ -105,7 +105,7 @@ int PlanStageGreedy::ProvisionPlanes(
break;
if (ret) {
- ALOGE("Failed to emplace layer %zu, dropping it", i->first);
+ ALOGV("Failed to emplace layer %zu, dropping it", i->first);
return ret;
}
}
diff --git a/drm/DrmDevice.cpp b/drm/DrmDevice.cpp
index 150aa01..abc8edc 100644
--- a/drm/DrmDevice.cpp
+++ b/drm/DrmDevice.cpp
@@ -112,6 +112,8 @@ static std::vector<DrmConnector *> make_primary_display_candidates(
}
DrmDevice::DrmDevice() : event_listener_(this) {
+ self.reset(this);
+ mDrmFbImporter = std::make_unique<DrmFbImporter>(self);
}
DrmDevice::~DrmDevice() {
@@ -120,7 +122,7 @@ DrmDevice::~DrmDevice() {
std::tuple<int, int> DrmDevice::Init(const char *path, int num_displays) {
/* TODO: Use drmOpenControl here instead */
- fd_.Set(open(path, O_RDWR | O_CLOEXEC));
+ fd_ = UniqueFd(open(path, O_RDWR | O_CLOEXEC));
if (fd() < 0) {
ALOGE("Failed to open dri %s: %s", path, strerror(errno));
return std::make_tuple(-ENODEV, 0);
@@ -146,6 +148,13 @@ std::tuple<int, int> DrmDevice::Init(const char *path, int num_displays) {
}
#endif
+ uint64_t cap_value = 0;
+ if (drmGetCap(fd(), DRM_CAP_ADDFB2_MODIFIERS, &cap_value)) {
+ ALOGW("drmGetCap failed. Fallback to no modifier support.");
+ cap_value = 0;
+ }
+ HasAddFb2ModifiersSupport_ = cap_value != 0;
+
drmSetMaster(fd());
if (!drmIsMaster(fd())) {
ALOGE("DRM/KMS master access required");
@@ -576,9 +585,9 @@ int DrmDevice::GetConnectorProperty(const DrmConnector &connector,
}
std::string DrmDevice::GetName() const {
- auto *ver = drmGetVersion(fd_.get());
+ auto *ver = drmGetVersion(fd());
if (!ver) {
- ALOGW("Failed to get drm version for fd=%d", fd_.get());
+ ALOGW("Failed to get drm version for fd=%d", fd());
return "generic";
}
diff --git a/drm/DrmDevice.h b/drm/DrmDevice.h
index d8f347f..dfca263 100644
--- a/drm/DrmDevice.h
+++ b/drm/DrmDevice.h
@@ -26,10 +26,15 @@
#include "DrmCrtc.h"
#include "DrmEncoder.h"
#include "DrmEventListener.h"
+#include "DrmFbImporter.h"
#include "DrmPlane.h"
+#include "utils/UniqueFd.h"
namespace android {
+class DrmFbImporter;
+class DrmPlane;
+
class DrmDevice {
public:
DrmDevice();
@@ -38,7 +43,7 @@ class DrmDevice {
std::tuple<int, int> Init(const char *path, int num_displays);
int fd() const {
- return fd_.get();
+ return fd_.Get();
}
const std::vector<std::unique_ptr<DrmConnector>> &connectors() const {
@@ -83,6 +88,14 @@ class DrmDevice {
event_listener_.RegisterHotplugHandler(handler);
}
+ bool HasAddFb2ModifiersSupport() const {
+ return HasAddFb2ModifiersSupport_;
+ }
+
+ DrmFbImporter &GetDrmFbImporter() {
+ return *mDrmFbImporter.get();
+ }
+
private:
int TryEncoderForDisplay(int display, DrmEncoder *enc);
int GetProperty(uint32_t obj_id, uint32_t obj_type, const char *prop_name,
@@ -104,6 +117,12 @@ class DrmDevice {
std::pair<uint32_t, uint32_t> min_resolution_;
std::pair<uint32_t, uint32_t> max_resolution_;
std::map<int, int> displays_;
+
+ bool HasAddFb2ModifiersSupport_{};
+
+ std::shared_ptr<DrmDevice> self;
+
+ std::unique_ptr<DrmFbImporter> mDrmFbImporter;
};
} // namespace android
diff --git a/drm/DrmEventListener.cpp b/drm/DrmEventListener.cpp
index a6eee47..b303653 100644
--- a/drm/DrmEventListener.cpp
+++ b/drm/DrmEventListener.cpp
@@ -39,11 +39,11 @@ DrmEventListener::DrmEventListener(DrmDevice *drm)
}
int DrmEventListener::Init() {
- uevent_fd_.Set(
+ uevent_fd_ = UniqueFd(
socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT));
- if (uevent_fd_.get() < 0) {
+ if (!uevent_fd_) {
ALOGE("Failed to open uevent socket: %s", strerror(errno));
- return uevent_fd_.get();
+ return -errno;
}
struct sockaddr_nl addr {};
@@ -51,7 +51,7 @@ int DrmEventListener::Init() {
addr.nl_pid = 0;
addr.nl_groups = 0xFFFFFFFF;
- int ret = bind(uevent_fd_.get(), (struct sockaddr *)&addr, sizeof(addr));
+ int ret = bind(uevent_fd_.Get(), (struct sockaddr *)&addr, sizeof(addr));
if (ret) {
ALOGE("Failed to bind uevent socket: %s", strerror(errno));
return -errno;
@@ -60,8 +60,8 @@ int DrmEventListener::Init() {
// NOLINTNEXTLINE(readability-isolate-declaration)
FD_ZERO(&fds_);
FD_SET(drm_->fd(), &fds_);
- FD_SET(uevent_fd_.get(), &fds_);
- max_fd_ = std::max(drm_->fd(), uevent_fd_.get());
+ FD_SET(uevent_fd_.Get(), &fds_);
+ max_fd_ = std::max(drm_->fd(), uevent_fd_.Get());
return InitWorker();
}
@@ -96,7 +96,7 @@ void DrmEventListener::UEventHandler() {
ALOGE("Failed to get monotonic clock on hotplug %d", ret);
while (true) {
- ret = read(uevent_fd_.get(), &buffer, sizeof(buffer));
+ ret = read(uevent_fd_.Get(), &buffer, sizeof(buffer));
if (ret == 0)
return;
@@ -139,7 +139,7 @@ void DrmEventListener::Routine() {
drmHandleEvent(drm_->fd(), &event_context);
}
- if (FD_ISSET(uevent_fd_.get(), &fds_))
+ if (FD_ISSET(uevent_fd_.Get(), &fds_))
UEventHandler();
}
} // namespace android
diff --git a/drm/DrmEventListener.h b/drm/DrmEventListener.h
index c880a8c..f1f7310 100644
--- a/drm/DrmEventListener.h
+++ b/drm/DrmEventListener.h
@@ -17,7 +17,7 @@
#ifndef ANDROID_DRM_EVENT_LISTENER_H_
#define ANDROID_DRM_EVENT_LISTENER_H_
-#include "autofd.h"
+#include "utils/UniqueFd.h"
#include "utils/Worker.h"
namespace android {
diff --git a/drm/DrmFbImporter.cpp b/drm/DrmFbImporter.cpp
new file mode 100644
index 0000000..8440093
--- /dev/null
+++ b/drm/DrmFbImporter.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 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.
+ */
+
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
+#define LOG_TAG "hwc-platform-drm-generic"
+
+#include "DrmFbImporter.h"
+
+#include <hardware/gralloc.h>
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+
+#include <cinttypes>
+#include <system_error>
+
+#include "utils/log.h"
+#include "utils/properties.h"
+
+namespace android {
+
+auto DrmFbIdHandle::CreateInstance(hwc_drm_bo_t *bo, GemHandle first_gem_handle,
+ const std::shared_ptr<DrmDevice> &drm)
+ -> std::shared_ptr<DrmFbIdHandle> {
+ // NOLINTNEXTLINE(cppcoreguidelines-owning-memory): priv. constructor usage
+ std::shared_ptr<DrmFbIdHandle> local(new DrmFbIdHandle(drm));
+
+ local->gem_handles_[0] = first_gem_handle;
+ int32_t err = 0;
+
+ /* Framebuffer object creation require gem handle for every used plane */
+ for (int 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->fd(), 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],
+ errno);
+ }
+ } else {
+ local->gem_handles_.at(i) = local->gem_handles_[0];
+ }
+ }
+ }
+
+ bool has_modifiers = bo->modifiers[0] != DRM_FORMAT_MOD_NONE &&
+ bo->modifiers[0] != DRM_FORMAT_MOD_INVALID;
+
+ if (!drm->HasAddFb2ModifiersSupport() && has_modifiers) {
+ ALOGE("No ADDFB2 with modifier support. Can't import modifier %" PRIu64,
+ bo->modifiers[0]);
+ local.reset();
+ return local;
+ }
+
+ /* Create framebuffer object */
+ if (!has_modifiers) {
+ err = drmModeAddFB2(drm->fd(), bo->width, bo->height, bo->format,
+ &local->gem_handles_[0], &bo->pitches[0],
+ &bo->offsets[0], &local->fb_id_, 0);
+ } else {
+ err = drmModeAddFB2WithModifiers(drm->fd(), bo->width, bo->height,
+ bo->format, &local->gem_handles_[0],
+ &bo->pitches[0], &bo->offsets[0],
+ &bo->modifiers[0], &local->fb_id_,
+ DRM_MODE_FB_MODIFIERS);
+ }
+ if (err != 0) {
+ ALOGE("could not create drm fb %d", err);
+ local.reset();
+ }
+
+ return local;
+}
+
+DrmFbIdHandle::~DrmFbIdHandle() {
+ /* Destroy framebuffer object */
+ if (drmModeRmFB(drm_->fd(), fb_id_) != 0) {
+ ALOGE("Failed to rm fb");
+ }
+
+ /* Close GEM handles.
+ *
+ * WARNING: TODO(nobody):
+ * From Linux side libweston relies on libgbm to get KMS handle and never
+ * closes it (handle is closed by libgbm on buffer destruction)
+ * Probably we should offer similar approach to users (at least on user
+ * request via system properties)
+ */
+ struct drm_gem_close gem_close {};
+ for (int i = 0; i < gem_handles_.size(); i++) {
+ /* Don't close invalid handle. Close handle only once in cases
+ * where several YUV planes located in the single buffer. */
+ if (gem_handles_[i] == 0 ||
+ (i != 0 && gem_handles_[i] == gem_handles_[0])) {
+ continue;
+ }
+ gem_close.handle = gem_handles_[i];
+ int32_t err = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
+ if (err != 0) {
+ ALOGE("Failed to close gem handle %d, errno: %d", gem_handles_[i], errno);
+ }
+ }
+}
+
+auto DrmFbImporter::GetOrCreateFbId(hwc_drm_bo_t *bo)
+ -> std::shared_ptr<DrmFbIdHandle> {
+ /* Lookup DrmFbIdHandle in cache first. First handle serves as a cache key. */
+ GemHandle first_handle = 0;
+ int32_t err = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[0], &first_handle);
+
+ if (err != 0) {
+ ALOGE("Failed to import prime fd %d ret=%d", bo->prime_fds[0], err);
+ return std::shared_ptr<DrmFbIdHandle>();
+ }
+
+ auto drm_fb_id_cached = drm_fb_id_handle_cache_.find(first_handle);
+
+ if (drm_fb_id_cached != drm_fb_id_handle_cache_.end()) {
+ if (auto drm_fb_id_handle_shared = drm_fb_id_cached->second.lock()) {
+ return drm_fb_id_handle_shared;
+ }
+ drm_fb_id_handle_cache_.erase(drm_fb_id_cached);
+ }
+
+ /* Cleanup cached empty weak pointers */
+ const int minimal_cleanup_size = 128;
+ if (drm_fb_id_handle_cache_.size() > minimal_cleanup_size) {
+ CleanupEmptyCacheElements();
+ }
+
+ /* No DrmFbIdHandle found in cache, create framebuffer object */
+ auto fb_id_handle = DrmFbIdHandle::CreateInstance(bo, first_handle, drm_);
+ if (fb_id_handle) {
+ drm_fb_id_handle_cache_[first_handle] = fb_id_handle;
+ }
+
+ return fb_id_handle;
+}
+
+} // namespace android
diff --git a/drm/DrmFbImporter.h b/drm/DrmFbImporter.h
new file mode 100644
index 0000000..167aa60
--- /dev/null
+++ b/drm/DrmFbImporter.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef DRM_DRMFBIMPORTER_H_
+#define DRM_DRMFBIMPORTER_H_
+
+#include <drm/drm_fourcc.h>
+#include <hardware/gralloc.h>
+
+#include <array>
+#include <map>
+
+#include "drm/DrmDevice.h"
+#include "drmhwcgralloc.h"
+
+#ifndef DRM_FORMAT_INVALID
+#define DRM_FORMAT_INVALID 0
+#endif
+
+using GemHandle = uint32_t;
+
+namespace android {
+
+class DrmFbIdHandle {
+ public:
+ static auto CreateInstance(hwc_drm_bo_t *bo, GemHandle first_gem_handle,
+ const std::shared_ptr<DrmDevice> &drm)
+ -> std::shared_ptr<DrmFbIdHandle>;
+
+ ~DrmFbIdHandle();
+ DrmFbIdHandle(DrmFbIdHandle &&) = delete;
+ DrmFbIdHandle(const DrmFbIdHandle &) = delete;
+ auto operator=(const DrmFbIdHandle &) = delete;
+ auto operator=(DrmFbIdHandle &&) = delete;
+
+ auto GetFbId [[nodiscard]] () const -> uint32_t {
+ return fb_id_;
+ }
+
+ private:
+ explicit DrmFbIdHandle(std::shared_ptr<DrmDevice> drm)
+ : drm_(std::move(drm)){};
+
+ const std::shared_ptr<DrmDevice> drm_;
+
+ uint32_t fb_id_{};
+ std::array<GemHandle, HWC_DRM_BO_MAX_PLANES> gem_handles_{};
+};
+
+class DrmFbImporter {
+ public:
+ explicit DrmFbImporter(std::shared_ptr<DrmDevice> drm)
+ : drm_(std::move(drm)){};
+ ~DrmFbImporter() = default;
+ DrmFbImporter(const DrmFbImporter &) = delete;
+ DrmFbImporter(DrmFbImporter &&) = delete;
+ auto operator=(const DrmFbImporter &) = delete;
+ auto operator=(DrmFbImporter &&) = delete;
+
+ auto GetOrCreateFbId(hwc_drm_bo_t *bo) -> std::shared_ptr<DrmFbIdHandle>;
+
+ private:
+ void CleanupEmptyCacheElements() {
+ for (auto it = drm_fb_id_handle_cache_.begin();
+ it != drm_fb_id_handle_cache_.end();) {
+ if (it->second.expired()) {
+ it = drm_fb_id_handle_cache_.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ const std::shared_ptr<DrmDevice> drm_;
+
+ std::map<GemHandle, std::weak_ptr<DrmFbIdHandle>> drm_fb_id_handle_cache_;
+};
+
+} // namespace android
+
+#endif
diff --git a/drm/DrmGenericImporter.cpp b/drm/DrmGenericImporter.cpp
deleted file mode 100644
index 0cbe601..0000000
--- a/drm/DrmGenericImporter.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#define LOG_TAG "hwc-platform-drm-generic"
-
-#include "DrmGenericImporter.h"
-
-#include <gralloc_handle.h>
-#include <hardware/gralloc.h>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
-
-#include <cinttypes>
-
-#include "utils/log.h"
-#include "utils/properties.h"
-
-namespace android {
-
-DrmGenericImporter::DrmGenericImporter(DrmDevice *drm) : drm_(drm) {
- uint64_t cap_value = 0;
- if (drmGetCap(drm_->fd(), DRM_CAP_ADDFB2_MODIFIERS, &cap_value)) {
- ALOGE("drmGetCap failed. Fallback to no modifier support.");
- cap_value = 0;
- }
- has_modifier_support_ = cap_value != 0;
-}
-
-int DrmGenericImporter::ImportBuffer(hwc_drm_bo_t *bo) {
- int ret = 0;
-
- for (int i = 0; i < HWC_DRM_BO_MAX_PLANES; i++) {
- if (bo->prime_fds[i] > 0) {
- if (i == 0 || bo->prime_fds[i] != bo->prime_fds[0]) {
- ret = drmPrimeFDToHandle(drm_->fd(), bo->prime_fds[i],
- &bo->gem_handles[i]);
- if (ret) {
- ALOGE("failed to import prime fd %d ret=%d", bo->prime_fds[i], ret);
- return ret;
- }
- } else {
- bo->gem_handles[i] = bo->gem_handles[0];
- }
- }
- }
-
- bool has_modifiers = bo->modifiers[0] != DRM_FORMAT_MOD_NONE &&
- bo->modifiers[0] != DRM_FORMAT_MOD_INVALID;
-
- if (!has_modifier_support_ && has_modifiers) {
- ALOGE("No ADDFB2 with modifier support. Can't import modifier %" PRIu64,
- bo->modifiers[0]);
- return -EINVAL;
- }
-
- if (!has_modifiers)
- ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
- bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id,
- 0);
- else
- ret = drmModeAddFB2WithModifiers(drm_->fd(), bo->width, bo->height,
- bo->format, bo->gem_handles, bo->pitches,
- bo->offsets, bo->modifiers, &bo->fb_id,
- DRM_MODE_FB_MODIFIERS);
-
- if (ret) {
- ALOGE("could not create drm fb %d", ret);
- return ret;
- }
-
- for (unsigned int gem_handle : bo->gem_handles) {
- if (!gem_handle)
- continue;
-
- ImportHandle(gem_handle);
- }
-
- return ret;
-}
-
-int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
- if (bo->fb_id)
- if (drmModeRmFB(drm_->fd(), bo->fb_id))
- ALOGE("Failed to rm fb");
-
- for (unsigned int &gem_handle : bo->gem_handles) {
- if (!gem_handle)
- continue;
-
- if (ReleaseHandle(gem_handle))
- ALOGE("Failed to release gem handle %d", gem_handle);
- else
- gem_handle = 0;
- }
- return 0;
-}
-
-int DrmGenericImporter::ImportHandle(uint32_t gem_handle) {
- gem_refcount_[gem_handle]++;
-
- return 0;
-}
-
-int DrmGenericImporter::ReleaseHandle(uint32_t gem_handle) {
- if (--gem_refcount_[gem_handle])
- return 0;
-
- gem_refcount_.erase(gem_handle);
-
- return CloseHandle(gem_handle);
-}
-
-int DrmGenericImporter::CloseHandle(uint32_t gem_handle) {
- struct drm_gem_close gem_close {};
- gem_close.handle = gem_handle;
- int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
- if (ret)
- ALOGE("Failed to close gem handle %d %d", gem_handle, ret);
-
- return ret;
-}
-} // namespace android
diff --git a/drm/DrmGenericImporter.h b/drm/DrmGenericImporter.h
deleted file mode 100644
index 27cfc3b..0000000
--- a/drm/DrmGenericImporter.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#ifndef ANDROID_PLATFORM_DRM_GENERIC_H_
-#define ANDROID_PLATFORM_DRM_GENERIC_H_
-
-#include <drm/drm_fourcc.h>
-#include <hardware/gralloc.h>
-
-#include <map>
-
-#include "drm/DrmDevice.h"
-#include "drmhwcgralloc.h"
-
-#ifndef DRM_FORMAT_INVALID
-#define DRM_FORMAT_INVALID 0
-#endif
-
-namespace android {
-
-class Importer {
- public:
- virtual ~Importer() = default;
-
- // Imports the buffer referred to by handle into bo.
- //
- // Note: This can be called from a different thread than ReleaseBuffer. The
- // implementation is responsible for ensuring thread safety.
- virtual int ImportBuffer(hwc_drm_bo_t *bo) = 0;
-
- // Releases the buffer object (ie: does the inverse of ImportBuffer)
- //
- // Note: This can be called from a different thread than ImportBuffer. The
- // implementation is responsible for ensuring thread safety.
- virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0;
-};
-
-class DrmGenericImporter : public Importer {
- public:
- DrmGenericImporter(DrmDevice *drm);
- ~DrmGenericImporter() override = default;
-
- int ImportBuffer(hwc_drm_bo_t *bo) override;
- int ReleaseBuffer(hwc_drm_bo_t *bo) override;
- int ImportHandle(uint32_t gem_handle);
- int ReleaseHandle(uint32_t gem_handle);
-
- protected:
- DrmDevice *drm_;
-
- private:
- int CloseHandle(uint32_t gem_handle);
- std::map<uint32_t, int> gem_refcount_;
- bool has_modifier_support_;
-};
-
-} // namespace android
-
-#endif
diff --git a/drm/DrmPlane.cpp b/drm/DrmPlane.cpp
index 5443e7e..6433fb6 100644
--- a/drm/DrmPlane.cpp
+++ b/drm/DrmPlane.cpp
@@ -231,7 +231,7 @@ bool DrmPlane::IsValidForLayer(DrmHwcLayer *layer) {
}
}
- uint32_t format = layer->buffer->format;
+ uint32_t format = layer->buffer_info.format;
if (!IsFormatSupported(format)) {
ALOGV("Plane %d does not supports %c%c%c%c format", id_, format,
format >> 8, format >> 16, format >> 24);
diff --git a/drm/ResourceManager.cpp b/drm/ResourceManager.cpp
index f8e9cab..ef44180 100644
--- a/drm/ResourceManager.cpp
+++ b/drm/ResourceManager.cpp
@@ -74,20 +74,11 @@ int ResourceManager::Init() {
(const hw_module_t **)&gralloc_);
}
-int ResourceManager::AddDrmDevice(std::string const &path) {
- std::unique_ptr<DrmDevice> drm = std::make_unique<DrmDevice>();
+int ResourceManager::AddDrmDevice(const std::string &path) {
+ auto drm = std::make_unique<DrmDevice>();
int displays_added = 0;
int ret = 0;
std::tie(ret, displays_added) = drm->Init(path.c_str(), num_displays_);
- if (ret)
- return ret;
- std::shared_ptr<Importer> importer;
- importer = std::make_shared<DrmGenericImporter>(drm.get());
- if (!importer) {
- ALOGE("Failed to create importer instance");
- return -ENODEV;
- }
- importers_.push_back(importer);
drms_.push_back(std::move(drm));
num_displays_ += displays_added;
return ret;
@@ -139,14 +130,6 @@ DrmDevice *ResourceManager::GetDrmDevice(int display) {
return nullptr;
}
-std::shared_ptr<Importer> ResourceManager::GetImporter(int display) {
- for (unsigned int i = 0; i < drms_.size(); i++) {
- if (drms_[i]->HandlesDisplay(display))
- return importers_[i];
- }
- return nullptr;
-}
-
const gralloc_module_t *ResourceManager::gralloc() {
return gralloc_;
}
diff --git a/drm/ResourceManager.h b/drm/ResourceManager.h
index fca6e1f..9b4155b 100644
--- a/drm/ResourceManager.h
+++ b/drm/ResourceManager.h
@@ -20,7 +20,7 @@
#include <string.h>
#include "DrmDevice.h"
-#include "DrmGenericImporter.h"
+#include "DrmFbImporter.h"
namespace android {
@@ -31,7 +31,6 @@ class ResourceManager {
ResourceManager &operator=(const ResourceManager &) = delete;
int Init();
DrmDevice *GetDrmDevice(int display);
- std::shared_ptr<Importer> GetImporter(int display);
const gralloc_module_t *gralloc();
DrmConnector *AvailableWritebackConnector(int display);
const std::vector<std::unique_ptr<DrmDevice>> &getDrmDevices() const {
@@ -50,7 +49,6 @@ class ResourceManager {
int num_displays_;
std::vector<std::unique_ptr<DrmDevice>> drms_;
- std::vector<std::shared_ptr<Importer>> importers_;
const gralloc_module_t *gralloc_;
bool scale_with_gpu_{};
diff --git a/include/autofd.h b/include/autofd.h
deleted file mode 100644
index 9af6c22..0000000
--- a/include/autofd.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#ifndef ANDROID_AUTO_FD_H_
-#define ANDROID_AUTO_FD_H_
-
-#include <unistd.h>
-
-namespace android {
-
-class UniqueFd {
- public:
- UniqueFd() = default;
- UniqueFd(int fd) : fd_(fd) {
- }
- UniqueFd(UniqueFd &&rhs) {
- fd_ = rhs.fd_;
- rhs.fd_ = -1;
- }
-
- UniqueFd &operator=(UniqueFd &&rhs) {
- Set(rhs.Release());
- return *this;
- }
-
- ~UniqueFd() {
- if (fd_ >= 0)
- close(fd_);
- }
-
- int Release() {
- int old_fd = fd_;
- fd_ = -1;
- return old_fd;
- }
-
- int Set(int fd) {
- if (fd_ >= 0)
- close(fd_);
- fd_ = fd;
- return fd_;
- }
-
- void Close() {
- if (fd_ >= 0)
- close(fd_);
- fd_ = -1;
- }
-
- int get() const {
- return fd_;
- }
-
- private:
- int fd_ = -1;
-};
-
-struct OutputFd {
- OutputFd() = default;
- OutputFd(int *fd) : fd_(fd) {
- }
- OutputFd(OutputFd &&rhs) {
- fd_ = rhs.fd_;
- rhs.fd_ = NULL;
- }
-
- OutputFd &operator=(OutputFd &&rhs) {
- fd_ = rhs.fd_;
- rhs.fd_ = NULL;
- return *this;
- }
-
- int Set(int fd) {
- if (*fd_ >= 0)
- close(*fd_);
- *fd_ = fd;
- return fd;
- }
-
- int get() {
- return *fd_;
- }
-
- operator bool() const {
- return fd_ != NULL;
- }
-
- private:
- int *fd_ = NULL;
-};
-} // namespace android
-
-#endif
diff --git a/include/drmhwcgralloc.h b/include/drmhwcgralloc.h
index 05b2cf0..db54802 100644
--- a/include/drmhwcgralloc.h
+++ b/include/drmhwcgralloc.h
@@ -29,11 +29,8 @@ typedef struct hwc_drm_bo {
uint32_t pitches[HWC_DRM_BO_MAX_PLANES];
uint32_t offsets[HWC_DRM_BO_MAX_PLANES];
uint32_t prime_fds[HWC_DRM_BO_MAX_PLANES];
- uint32_t gem_handles[HWC_DRM_BO_MAX_PLANES];
uint64_t modifiers[HWC_DRM_BO_MAX_PLANES];
- uint32_t fb_id;
int acquire_fence_fd;
- void *priv;
} hwc_drm_bo_t;
#endif // ANDROID_DRMHWCGRALLOC_H_
diff --git a/include/drmhwcomposer.h b/include/drmhwcomposer.h
index a04cc29..22af12b 100644
--- a/include/drmhwcomposer.h
+++ b/include/drmhwcomposer.h
@@ -17,99 +17,20 @@
#ifndef ANDROID_DRM_HWCOMPOSER_H_
#define ANDROID_DRM_HWCOMPOSER_H_
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
#include <stdbool.h>
#include <stdint.h>
#include <vector>
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-#include "autofd.h"
+#include "drm/DrmFbImporter.h"
#include "drmhwcgralloc.h"
-
-struct hwc_import_context;
-
-int hwc_import_init(struct hwc_import_context **ctx);
-int hwc_import_destroy(struct hwc_import_context *ctx);
-
-int hwc_import_bo_create(int fd, struct hwc_import_context *ctx,
- buffer_handle_t buf, struct hwc_drm_bo *bo);
-bool hwc_import_bo_release(int fd, struct hwc_import_context *ctx,
- struct hwc_drm_bo *bo);
+#include "utils/UniqueFd.h"
namespace android {
-class Importer;
-
-class DrmHwcBuffer {
- public:
- DrmHwcBuffer() = default;
- DrmHwcBuffer(const hwc_drm_bo &bo, Importer *importer)
- : bo_(bo), importer_(importer) {
- }
- DrmHwcBuffer(DrmHwcBuffer &&rhs) : bo_(rhs.bo_), importer_(rhs.importer_) {
- rhs.importer_ = NULL;
- }
-
- ~DrmHwcBuffer() {
- Clear();
- }
-
- DrmHwcBuffer &operator=(DrmHwcBuffer &&rhs) {
- Clear();
- importer_ = rhs.importer_;
- rhs.importer_ = NULL;
- bo_ = rhs.bo_;
- return *this;
- }
-
- operator bool() const {
- return importer_ != NULL;
- }
-
- const hwc_drm_bo *operator->() const;
-
- void Clear();
-
- int ImportBuffer(buffer_handle_t handle, Importer *importer);
-
- private:
- hwc_drm_bo bo_;
- Importer *importer_ = NULL;
-};
-
-class DrmHwcNativeHandle {
- public:
- DrmHwcNativeHandle() = default;
-
- DrmHwcNativeHandle(native_handle_t *handle) : handle_(handle) {
- }
-
- DrmHwcNativeHandle(DrmHwcNativeHandle &&rhs) {
- handle_ = rhs.handle_;
- rhs.handle_ = NULL;
- }
-
- ~DrmHwcNativeHandle();
-
- DrmHwcNativeHandle &operator=(DrmHwcNativeHandle &&rhs) {
- Clear();
- handle_ = rhs.handle_;
- rhs.handle_ = NULL;
- return *this;
- }
-
- int CopyBufferHandle(buffer_handle_t handle);
-
- void Clear();
-
- buffer_handle_t get() const {
- return handle_;
- }
-
- private:
- native_handle_t *handle_ = NULL;
-};
+class DrmFbIdHandle;
enum DrmHwcTransform {
kIdentity = 0,
@@ -128,9 +49,10 @@ enum class DrmHwcBlending : int32_t {
struct DrmHwcLayer {
buffer_handle_t sf_handle = NULL;
+ hwc_drm_bo_t buffer_info{};
+ std::shared_ptr<DrmFbIdHandle> FbIdHandle;
+
int gralloc_buffer_usage = 0;
- DrmHwcBuffer buffer;
- DrmHwcNativeHandle handle;
uint32_t transform;
DrmHwcBlending blending = DrmHwcBlending::kNone;
uint16_t alpha = 0xffff;
@@ -139,17 +61,11 @@ struct DrmHwcLayer {
android_dataspace_t dataspace;
UniqueFd acquire_fence;
- OutputFd release_fence;
- int ImportBuffer(Importer *importer);
- int InitFromDrmHwcLayer(DrmHwcLayer *layer, Importer *importer);
+ int ImportBuffer(DrmDevice *drmDevice);
void SetTransform(int32_t sf_transform);
- buffer_handle_t get_usable_handle() const {
- return handle.get() != NULL ? handle.get() : sf_handle;
- }
-
bool protected_usage() const {
return (gralloc_buffer_usage & GRALLOC_USAGE_PROTECTED) ==
GRALLOC_USAGE_PROTECTED;
diff --git a/utils/UniqueFd.h b/utils/UniqueFd.h
new file mode 100644
index 0000000..1a390ba
--- /dev/null
+++ b/utils/UniqueFd.h
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+#ifndef UNIQUEFD_H_
+#define UNIQUEFD_H_
+
+#include <unistd.h>
+
+#include <memory>
+
+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_;
+ }
+
+ 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
+
+#endif
diff --git a/utils/hwcutils.cpp b/utils/hwcutils.cpp
index 81097ce..6de6500 100644
--- a/utils/hwcutils.cpp
+++ b/utils/hwcutils.cpp
@@ -22,118 +22,32 @@
#include <ui/GraphicBufferMapper.h>
#include "bufferinfo/BufferInfoGetter.h"
-#include "drm/DrmGenericImporter.h"
+#include "drm/DrmFbImporter.h"
#include "drmhwcomposer.h"
#define UNUSED(x) (void)(x)
namespace android {
-const hwc_drm_bo *DrmHwcBuffer::operator->() const {
- if (importer_ == nullptr) {
- ALOGE("Access of non-existent BO");
- exit(1);
- return nullptr;
- }
- return &bo_;
-}
-
-void DrmHwcBuffer::Clear() {
- if (importer_ != nullptr) {
- importer_->ReleaseBuffer(&bo_);
- importer_ = nullptr;
- }
-}
+int DrmHwcLayer::ImportBuffer(DrmDevice *drmDevice) {
+ buffer_info = hwc_drm_bo_t{};
-int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) {
- hwc_drm_bo tmp_bo{};
-
- int ret = BufferInfoGetter::GetInstance()->ConvertBoInfo(handle, &tmp_bo);
+ int ret = BufferInfoGetter::GetInstance()->ConvertBoInfo(sf_handle,
+ &buffer_info);
if (ret) {
ALOGE("Failed to convert buffer info %d", ret);
return ret;
}
- ret = importer->ImportBuffer(&tmp_bo);
- if (ret) {
- ALOGE("Failed to import buffer %d", ret);
- return ret;
- }
-
- if (importer_ != nullptr) {
- importer_->ReleaseBuffer(&bo_);
+ FbIdHandle = drmDevice->GetDrmFbImporter().GetOrCreateFbId(&buffer_info);
+ if (!FbIdHandle) {
+ ALOGE("Failed to import buffer");
+ return -EINVAL;
}
- importer_ = importer;
-
- bo_ = tmp_bo;
-
return 0;
}
-int DrmHwcNativeHandle::CopyBufferHandle(buffer_handle_t handle) {
- native_handle_t *handle_copy = nullptr;
- GraphicBufferMapper &gm(GraphicBufferMapper::get());
- int ret = 0;
-
- ret = gm.getGrallocMapper().importBuffer(handle,
- (buffer_handle_t *)&handle_copy);
-
- if (ret) {
- ALOGE("Failed to import buffer handle %d", ret);
- return ret;
- }
-
- Clear();
-
- handle_ = handle_copy;
-
- return 0;
-}
-
-DrmHwcNativeHandle::~DrmHwcNativeHandle() {
- Clear();
-}
-
-void DrmHwcNativeHandle::Clear() {
- if (handle_ != nullptr) {
- GraphicBufferMapper &gm(GraphicBufferMapper::get());
- int ret = gm.freeBuffer(handle_);
- if (ret) {
- ALOGE("Failed to free buffer handle %d", ret);
- }
- handle_ = nullptr;
- }
-}
-
-int DrmHwcLayer::ImportBuffer(Importer *importer) {
- int ret = buffer.ImportBuffer(sf_handle, importer);
- if (ret)
- return ret;
-
- const hwc_drm_bo *bo = buffer.operator->();
-
- ret = handle.CopyBufferHandle(sf_handle);
- if (ret)
- return ret;
-
- gralloc_buffer_usage = bo->usage;
-
- return 0;
-}
-
-int DrmHwcLayer::InitFromDrmHwcLayer(DrmHwcLayer *src_layer,
- Importer *importer) {
- blending = src_layer->blending;
- sf_handle = src_layer->sf_handle;
- acquire_fence = -1;
- display_frame = src_layer->display_frame;
- alpha = src_layer->alpha;
- source_crop = src_layer->source_crop;
- transform = src_layer->transform;
- return ImportBuffer(importer);
-}
-
void DrmHwcLayer::SetTransform(int32_t sf_transform) {
transform = 0;
// 270* and 180* cannot be combined with flips. More specifically, they