Snap for 12587146 from f1494e910b9bff9ae73d19dcbf36c8515f01610f to 25Q1-release
Change-Id: I9cc91eaac4ab0ab01d976cb6862806c2bd6a69ef
diff --git a/.ci/.gitlab-ci-checkcommit.sh b/.ci/.gitlab-ci-checkcommit.sh
index f821595..3f597c3 100755
--- a/.ci/.gitlab-ci-checkcommit.sh
+++ b/.ci/.gitlab-ci-checkcommit.sh
@@ -42,7 +42,7 @@
git log --pretty='%h' FETCH_HEAD..HEAD | while read h; do
subject=$(git show -s --pretty='%s' "$h")
- if [[ $subject != drm_hwcomposer:* ]]; then
+ if [[ $subject != drm_hwcomposer:* ]] && [[ $subject != Revert* ]]; then
echoerr "Invalid subject prefix: $subject"
exit 1
fi
diff --git a/Android.bp b/Android.bp
index 6be50d6..7ff063d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -72,6 +72,8 @@
"-DHWC2_USE_CPP11",
],
+ cpp_std: "gnu++17",
+
relative_install_path: "hw",
vendor: true,
}
diff --git a/compositor/ColorInfo.h b/compositor/DisplayInfo.h
similarity index 81%
rename from compositor/ColorInfo.h
rename to compositor/DisplayInfo.h
index 1afda07..bbcbff8 100644
--- a/compositor/ColorInfo.h
+++ b/compositor/DisplayInfo.h
@@ -36,3 +36,13 @@
kRgbWideFloat,
kBt601Ycc,
};
+
+/**
+ * Display panel orientation property values.
+ */
+enum PanelOrientation {
+ kModePanelOrientationNormal = 0,
+ kModePanelOrientationBottomUp,
+ kModePanelOrientationLeftUp,
+ kModePanelOrientationRightUp
+};
diff --git a/drm/DrmAtomicStateManager.h b/drm/DrmAtomicStateManager.h
index c8736f2..20896ed 100644
--- a/drm/DrmAtomicStateManager.h
+++ b/drm/DrmAtomicStateManager.h
@@ -21,7 +21,7 @@
#include <memory>
#include <optional>
-#include "compositor/ColorInfo.h"
+#include "compositor/DisplayInfo.h"
#include "compositor/DrmKmsPlan.h"
#include "compositor/LayerData.h"
#include "drm/DrmPlane.h"
diff --git a/drm/DrmConnector.cpp b/drm/DrmConnector.cpp
index 5371513..eeec3b1 100644
--- a/drm/DrmConnector.cpp
+++ b/drm/DrmConnector.cpp
@@ -23,10 +23,12 @@
#include <array>
#include <cerrno>
+#include <cinttypes>
#include <cstdint>
#include <sstream>
#include "DrmDevice.h"
+#include "compositor/DisplayInfo.h"
#include "utils/log.h"
#ifndef DRM_MODE_CONNECTOR_SPI
@@ -136,6 +138,26 @@
GetConnectorProperty("content type", &content_type_property_,
/*is_optional=*/true);
+ if (GetConnectorProperty("panel orientation", &panel_orientation_,
+ /*is_optional=*/true)) {
+ panel_orientation_
+ .AddEnumToMapReverse("Normal",
+ PanelOrientation::kModePanelOrientationNormal,
+ panel_orientation_enum_map_);
+ panel_orientation_
+ .AddEnumToMapReverse("Upside Down",
+ PanelOrientation::kModePanelOrientationBottomUp,
+ panel_orientation_enum_map_);
+ panel_orientation_
+ .AddEnumToMapReverse("Left Side Up",
+ PanelOrientation::kModePanelOrientationLeftUp,
+ panel_orientation_enum_map_);
+ panel_orientation_
+ .AddEnumToMapReverse("Right Side Up",
+ PanelOrientation::kModePanelOrientationRightUp,
+ panel_orientation_enum_map_);
+ }
+
return true;
}
@@ -241,4 +263,26 @@
return true;
}
+
+std::optional<PanelOrientation> DrmConnector::GetPanelOrientation() {
+ if (!panel_orientation_.GetValue().has_value()) {
+ ALOGW("No panel orientation property available.");
+ return {};
+ }
+
+ /* The value_or(0) satisfies the compiler warning. However,
+ * panel_orientation_.GetValue() is guaranteed to have a value since we check
+ * has_value() and return early otherwise.
+ */
+ uint64_t panel_orientation_value = panel_orientation_.GetValue().value_or(0);
+
+ if (panel_orientation_enum_map_.count(panel_orientation_value) == 1) {
+ return panel_orientation_enum_map_[panel_orientation_value];
+ }
+
+ ALOGE("Unknown panel orientation: panel_orientation = %" PRIu64,
+ panel_orientation_value);
+ return {};
+}
+
} // namespace android
diff --git a/drm/DrmConnector.h b/drm/DrmConnector.h
index 9186f07..be84ae3 100644
--- a/drm/DrmConnector.h
+++ b/drm/DrmConnector.h
@@ -26,8 +26,7 @@
#include "DrmMode.h"
#include "DrmProperty.h"
#include "DrmUnique.h"
-
-#include "compositor/ColorInfo.h"
+#include "compositor/DisplayInfo.h"
namespace android {
@@ -118,6 +117,10 @@
return writeback_out_fence_;
}
+ auto &GetPanelOrientationProperty() const {
+ return panel_orientation_;
+ }
+
auto IsConnected() const {
return connector_->connection == DRM_MODE_CONNECTED;
}
@@ -130,11 +133,13 @@
return connector_->mmHeight;
};
+ auto GetPanelOrientation() -> std::optional<PanelOrientation>;
+
private:
DrmConnector(DrmModeConnectorUnique connector, DrmDevice *drm, uint32_t index)
: connector_(std::move(connector)),
drm_(drm),
- index_in_res_array_(index){};
+ index_in_res_array_(index) {};
DrmModeConnectorUnique connector_;
DrmDevice *const drm_;
@@ -157,7 +162,9 @@
DrmProperty writeback_pixel_formats_;
DrmProperty writeback_fb_id_;
DrmProperty writeback_out_fence_;
+ DrmProperty panel_orientation_;
std::map<Colorspace, uint64_t> colorspace_enum_map_;
+ std::map<uint64_t, PanelOrientation> panel_orientation_enum_map_;
};
} // namespace android
diff --git a/drm/DrmPlane.cpp b/drm/DrmPlane.cpp
index 310e67b..dbb5ad6 100644
--- a/drm/DrmPlane.cpp
+++ b/drm/DrmPlane.cpp
@@ -155,14 +155,11 @@
if (crtc_prop_val != 0 && crtc_prop_val != crtc.GetId() &&
GetType() == DRM_PLANE_TYPE_PRIMARY) {
// Some DRM driver such as omap_drm allows sharing primary plane between
- // CRTCs, but the primay plane could not be shared if it has been used by
+ // CRTCs, but the primary plane could not be shared if it has been used by
// any CRTC already, which is protected by the plane_switching_crtc function
// in the kernel drivers/gpu/drm/drm_atomic.c file.
// The current drm_hwc design is not ready to support such scenario yet,
// so adding the CRTC status check here to workaorund for now.
- ALOGW("%s: This Plane(id=%d) is activated for Crtc(id=%" PRIu64
- "), could not be used for Crtc (id=%d)",
- __FUNCTION__, GetId(), crtc_prop_val, crtc.GetId());
return false;
}
diff --git a/drm/DrmProperty.cpp b/drm/DrmProperty.cpp
index 031918a..dbd307e 100644
--- a/drm/DrmProperty.cpp
+++ b/drm/DrmProperty.cpp
@@ -22,6 +22,7 @@
#include <xf86drmMode.h>
#include <cerrno>
+#include <cinttypes>
#include <cstdint>
#include <string>
@@ -125,4 +126,22 @@
return true;
}
+std::optional<std::string> DrmProperty::GetEnumNameFromValue(
+ uint64_t value) const {
+ if (enums_.empty()) {
+ ALOGE("No enum values for property: %s", name_.c_str());
+ return {};
+ }
+
+ for (const auto &it : enums_) {
+ if (it.value == value) {
+ return it.name;
+ }
+ }
+
+ ALOGE("Property '%s' has no matching enum for value: %" PRIu64, name_.c_str(),
+ value);
+ return {};
+}
+
} // namespace android
diff --git a/drm/DrmProperty.h b/drm/DrmProperty.h
index 516518b..2683ad8 100644
--- a/drm/DrmProperty.h
+++ b/drm/DrmProperty.h
@@ -64,10 +64,16 @@
auto AddEnumToMap(const std::string &name, E key, std::map<E, uint64_t> &map)
-> bool;
+ template <class E>
+ auto AddEnumToMapReverse(const std::string &name, E value,
+ std::map<uint64_t, E> &map) -> bool;
+
explicit operator bool() const {
return id_ != 0;
}
+ auto GetEnumNameFromValue(uint64_t value) const -> std::optional<std::string>;
+
private:
class DrmPropertyEnum {
public:
@@ -104,4 +110,18 @@
return false;
}
+template <class E>
+auto DrmProperty::AddEnumToMapReverse(const std::string &name, E value,
+ std::map<uint64_t, E> &map) -> bool {
+ uint64_t enum_value = UINT64_MAX;
+ int err = 0;
+ std::tie(enum_value, err) = GetEnumValueWithName(name);
+ if (err == 0) {
+ map[enum_value] = value;
+ return true;
+ }
+
+ return false;
+}
+
} // namespace android
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 7f65e65..6797c56 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -24,10 +24,15 @@
#include "backend/Backend.h"
#include "backend/BackendManager.h"
#include "bufferinfo/BufferInfoGetter.h"
+#include "compositor/DisplayInfo.h"
+#include "drm/DrmConnector.h"
+#include "drm/DrmDisplayPipeline.h"
#include "drm/DrmHwc.h"
#include "utils/log.h"
#include "utils/properties.h"
+using ::android::DrmDisplayPipeline;
+
namespace android {
std::string HwcDisplay::DumpDelta(HwcDisplay::Stats delta) {
@@ -196,6 +201,23 @@
return HWC2::Error::None;
}
+std::optional<PanelOrientation> HwcDisplay::getDisplayPhysicalOrientation() {
+ if (IsInHeadlessMode()) {
+ // The pipeline can be nullptr in headless mode, so return the default
+ // "normal" mode.
+ return PanelOrientation::kModePanelOrientationNormal;
+ }
+
+ DrmDisplayPipeline &pipeline = GetPipe();
+ if (pipeline.connector == nullptr || pipeline.connector->Get() == nullptr) {
+ ALOGW(
+ "No display pipeline present to query the panel orientation property.");
+ return {};
+ }
+
+ return pipeline.connector->Get()->GetPanelOrientation();
+}
+
HWC2::Error HwcDisplay::ChosePreferredConfig() {
HWC2::Error err{};
if (type_ == HWC2::DisplayType::Virtual) {
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index c568a73..4680ca9 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -23,7 +23,7 @@
#include <sstream>
#include "HwcDisplayConfigs.h"
-#include "compositor/ColorInfo.h"
+#include "compositor/DisplayInfo.h"
#include "compositor/FlatteningController.h"
#include "compositor/LayerData.h"
#include "drm/DrmAtomicStateManager.h"
@@ -198,6 +198,8 @@
virtual_disp_height_ = height;
}
+ auto getDisplayPhysicalOrientation() -> std::optional<PanelOrientation>;
+
private:
HwcDisplayConfigs configs_;
diff --git a/hwc2_device/HwcLayer.cpp b/hwc2_device/HwcLayer.cpp
index cd2a319..cb18fdd 100644
--- a/hwc2_device/HwcLayer.cpp
+++ b/hwc2_device/HwcLayer.cpp
@@ -25,6 +25,11 @@
namespace android {
void HwcLayer::SetLayerProperties(const LayerProperties& layer_properties) {
+ if (layer_properties.buffer) {
+ layer_data_.acquire_fence = layer_properties.buffer->acquire_fence;
+ buffer_handle_ = layer_properties.buffer->buffer_handle;
+ buffer_handle_updated_ = true;
+ }
if (layer_properties.blend_mode) {
blend_mode_ = layer_properties.blend_mode.value();
}
diff --git a/hwc2_device/HwcLayer.h b/hwc2_device/HwcLayer.h
index b8fb959..e1d62b7 100644
--- a/hwc2_device/HwcLayer.h
+++ b/hwc2_device/HwcLayer.h
@@ -28,8 +28,13 @@
class HwcLayer {
public:
+ struct Buffer {
+ buffer_handle_t buffer_handle;
+ SharedFd acquire_fence;
+ };
// A set of properties to be validated.
struct LayerProperties {
+ std::optional<Buffer> buffer;
std::optional<BufferBlendMode> blend_mode;
std::optional<BufferColorSpace> color_space;
std::optional<BufferSampleRange> sample_range;
diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
index c980eac..ebe9a1c 100644
--- a/hwc3/ComposerClient.cpp
+++ b/hwc3/ComposerClient.cpp
@@ -43,6 +43,7 @@
#include <hardware/hwcomposer_defs.h>
#include "bufferinfo/BufferInfo.h"
+#include "compositor/DisplayInfo.h"
#include "hwc2_device/HwcDisplay.h"
#include "hwc2_device/HwcDisplayConfigs.h"
#include "hwc2_device/HwcLayer.h"
@@ -191,6 +192,28 @@
}
}
+#if __ANDROID_API__ < 35
+
+class DisplayConfiguration {
+ public:
+ class Dpi {
+ public:
+ float x = 0.000000F;
+ float y = 0.000000F;
+ };
+ // NOLINTNEXTLINE(readability-identifier-naming)
+ int32_t configId = 0;
+ int32_t width = 0;
+ int32_t height = 0;
+ std::optional<Dpi> dpi;
+ // NOLINTNEXTLINE(readability-identifier-naming)
+ int32_t configGroup = 0;
+ // NOLINTNEXTLINE(readability-identifier-naming)
+ int32_t vsyncPeriod = 0;
+};
+
+#endif
+
DisplayConfiguration HwcDisplayConfigToAidlConfiguration(
const HwcDisplayConfigs& configs, const HwcDisplayConfig& config) {
DisplayConfiguration aidl_configuration =
@@ -528,12 +551,20 @@
return;
}
- HwcLayerWrapper layer_wrapper{command.layer, layer};
+ HwcLayer::LayerProperties properties;
if (command.buffer) {
- ExecuteSetLayerBuffer(display_id, layer_wrapper, *command.buffer);
+ HwcLayer::Buffer buffer;
+ auto err = ImportLayerBuffer(display_id, command.layer, *command.buffer,
+ &buffer.buffer_handle);
+ if (err != hwc3::Error::kNone) {
+ cmd_result_writer_->AddError(err);
+ return;
+ }
+ buffer.acquire_fence = ::android::MakeSharedFd(
+ command.buffer->fence.dup().release());
+ properties.buffer.emplace(buffer);
}
- HwcLayer::LayerProperties properties;
properties.blend_mode = AidlToBlendMode(command.blendMode);
properties.color_space = AidlToColorSpace(command.dataspace);
properties.sample_range = AidlToSampleRange(command.dataspace);
@@ -576,9 +607,7 @@
DispatchLayerCommand(command.display, layer_cmd);
}
- if (command.brightness) {
- ExecuteSetDisplayBrightness(command.display, *command.brightness);
- }
+ // TODO: Implement support for display brightness.
if (command.colorTransformMatrix) {
ExecuteSetDisplayColorTransform(command.display,
*command.colorTransformMatrix);
@@ -885,13 +914,40 @@
ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation(
int64_t display_id, common::Transform* orientation) {
DEBUG_FUNC();
+
+ if (orientation == nullptr) {
+ ALOGE("Invalid 'orientation' pointer.");
+ return ToBinderStatus(hwc3::Error::kBadParameter);
+ }
+
const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
HwcDisplay* display = GetDisplay(display_id);
if (display == nullptr) {
return ToBinderStatus(hwc3::Error::kBadDisplay);
}
- *orientation = common::Transform::NONE;
+ PanelOrientation
+ drm_orientation = display->getDisplayPhysicalOrientation().value_or(
+ PanelOrientation::kModePanelOrientationNormal);
+
+ switch (drm_orientation) {
+ case PanelOrientation::kModePanelOrientationNormal:
+ *orientation = common::Transform::NONE;
+ break;
+ case PanelOrientation::kModePanelOrientationBottomUp:
+ *orientation = common::Transform::ROT_180;
+ break;
+ case PanelOrientation::kModePanelOrientationLeftUp:
+ *orientation = common::Transform::ROT_270;
+ break;
+ case PanelOrientation::kModePanelOrientationRightUp:
+ *orientation = common::Transform::ROT_90;
+ break;
+ default:
+ ALOGE("Unknown panel orientation value: %d", drm_orientation);
+ return ToBinderStatus(hwc3::Error::kBadDisplay);
+ }
+
return ndk::ScopedAStatus::ok();
}
@@ -1177,6 +1233,8 @@
return ToBinderStatus(hwc3::Error::kUnsupported);
}
+#if __ANDROID_API__ >= 35
+
ndk::ScopedAStatus ComposerClient::getDisplayConfigurations(
int64_t display_id, int32_t /*max_frame_interval_ns*/,
std::vector<DisplayConfiguration>* configurations) {
@@ -1201,6 +1259,8 @@
return ToBinderStatus(hwc3::Error::kUnsupported);
}
+#endif
+
std::string ComposerClient::Dump() {
uint32_t size = 0;
hwc_->Dump(&size, nullptr);
@@ -1216,43 +1276,18 @@
return binder;
}
-void ComposerClient::ExecuteSetLayerBuffer(int64_t display_id,
- HwcLayerWrapper& layer,
- const Buffer& buffer) {
- buffer_handle_t imported_buffer = nullptr;
+hwc3::Error ComposerClient::ImportLayerBuffer(
+ int64_t display_id, int64_t layer_id, const Buffer& buffer,
+ buffer_handle_t* out_imported_buffer) {
+ *out_imported_buffer = nullptr;
auto releaser = composer_resources_->CreateResourceReleaser(true);
- auto err = composer_resources_->GetLayerBuffer(display_id, layer.layer_id,
- buffer, &imported_buffer,
+ auto err = composer_resources_->GetLayerBuffer(display_id, layer_id, buffer,
+ out_imported_buffer,
releaser.get());
- if (err != hwc3::Error::kNone) {
- cmd_result_writer_->AddError(err);
- return;
- }
-
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
- auto fence_fd = const_cast<ndk::ScopedFileDescriptor&>(buffer.fence)
- .release();
- err = Hwc2toHwc3Error(layer.layer->SetLayerBuffer(imported_buffer, fence_fd));
- if (err != hwc3::Error::kNone) {
- cmd_result_writer_->AddError(err);
- }
+ return err;
}
-void ComposerClient::ExecuteSetDisplayBrightness(
- uint64_t display_id, const DisplayBrightness& command) {
- auto* display = GetDisplay(display_id);
- if (display == nullptr) {
- cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
- return;
- }
-
- auto error = Hwc2toHwc3Error(
- display->SetDisplayBrightness(command.brightness));
- if (error != hwc3::Error::kNone) {
- cmd_result_writer_->AddError(error);
- }
-}
void ComposerClient::ExecuteSetDisplayColorTransform(
uint64_t display_id, const std::vector<float>& matrix) {
auto* display = GetDisplay(display_id);
diff --git a/hwc3/ComposerClient.h b/hwc3/ComposerClient.h
index 5e4949e..91a0be0 100644
--- a/hwc3/ComposerClient.h
+++ b/hwc3/ComposerClient.h
@@ -39,11 +39,6 @@
class DrmHwcThree;
-struct HwcLayerWrapper {
- int64_t layer_id;
- ::android::HwcLayer* layer;
-};
-
class ComposerClient : public BnComposerClient {
public:
ComposerClient();
@@ -145,6 +140,9 @@
common::Hdr* out_hdr) override;
ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(
int64_t display, bool enabled) override;
+
+#if __ANDROID_API__ >= 35
+
ndk::ScopedAStatus getDisplayConfigurations(
int64_t display, int32_t max_frame_interval_ns,
std::vector<DisplayConfiguration>* configurations) override;
@@ -152,19 +150,21 @@
int64_t display, const ClockMonotonicTimestamp& expected_present_time,
int32_t frame_interval_ns) override;
+#endif
+
protected:
::ndk::SpAIBinder createBinder() override;
private:
+ hwc3::Error ImportLayerBuffer(int64_t display_id, int64_t layer_id,
+ const Buffer& buffer,
+ buffer_handle_t* out_imported_buffer);
+
// Layer commands
void DispatchLayerCommand(int64_t display_id, const LayerCommand& command);
- void ExecuteSetLayerBuffer(int64_t display_id, HwcLayerWrapper& layer_id,
- const Buffer& buffer);
// Display commands
void ExecuteDisplayCommand(const DisplayCommand& command);
- void ExecuteSetDisplayBrightness(uint64_t display_id,
- const DisplayBrightness& command);
void ExecuteSetDisplayColorTransform(uint64_t display_id,
const std::vector<float>& matrix);
void ExecuteSetDisplayClientTarget(uint64_t display_id,
diff --git a/hwc3/DrmHwcThree.cpp b/hwc3/DrmHwcThree.cpp
index 2ac307c..fb14bc9 100644
--- a/hwc3/DrmHwcThree.cpp
+++ b/hwc3/DrmHwcThree.cpp
@@ -22,7 +22,9 @@
#include "Utils.h"
#include "aidl/android/hardware/graphics/common/Dataspace.h"
+#if __ANDROID_API__ >= 35
#include "aidl/android/hardware/graphics/common/DisplayHotplugEvent.h"
+#endif
namespace aidl::android::hardware::graphics::composer3::impl {
@@ -61,6 +63,8 @@
static_cast<int32_t>(vsync_period));
}
+#if __ANDROID_API__ >= 35
+
void DrmHwcThree::SendHotplugEventToClient(
hwc2_display_t display_id, DrmHwc::DisplayStatus display_status) {
common::DisplayHotplugEvent event = common::DisplayHotplugEvent::DISCONNECTED;
@@ -80,6 +84,17 @@
composer_callback_->onHotplugEvent(static_cast<int64_t>(display_id), event);
}
+#else
+
+void DrmHwcThree::SendHotplugEventToClient(
+ hwc2_display_t display_id, DrmHwc::DisplayStatus display_status) {
+ bool connected = display_status != DrmHwc::kDisconnected;
+ HandleDisplayHotplugEvent(static_cast<uint64_t>(display_id), connected);
+ composer_callback_->onHotplug(static_cast<int64_t>(display_id), connected);
+}
+
+#endif
+
void DrmHwcThree::CleanDisplayResources(uint64_t display_id) {
DEBUG_FUNC();
HwcDisplay* display = GetDisplay(display_id);
diff --git a/hwc3/meson.build b/hwc3/meson.build
index 2486212..291c71a 100644
--- a/hwc3/meson.build
+++ b/hwc3/meson.build
@@ -14,7 +14,7 @@
cpp_args : common_cpp_flags + hwc2_cpp_flags,
dependencies : deps,
install : true,
- link_with: [drmhwc_common, drmhwc_hwc2_common],
+ link_whole: [drmhwc_common, drmhwc_hwc2_common],
install_dir : get_option('bindir') / 'hw',
include_directories: inc_include,
)