drm_hwcomposer: Rework CreateLayer/DestroyLayer
- Make HwcDisplay CreateLayer/DestroyLayer frontend-agnostic. - Provide LayerId as an input for CreateLayer. It is necessary to add the HWC3 LayerLifecycleBatchCommand feature, where layer ID is generated by the client. Change-Id: I317dcf22461fe4390ced9f0c0c780cffaa3b8f5d Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com>
This commit is contained in:
parent
67b85a625a
commit
ee6d843ef8
7 changed files with 76 additions and 56 deletions
|
|
@ -30,6 +30,8 @@ namespace android {
|
|||
|
||||
class DrmFbIdHandle;
|
||||
|
||||
using ILayerId = int64_t;
|
||||
|
||||
/* Rotation is defined in the clockwise direction */
|
||||
/* The flip is done before rotation */
|
||||
struct LayerTransform {
|
||||
|
|
|
|||
|
|
@ -330,8 +330,8 @@ auto HwcDisplay::GetDisplayBoundsMm() -> std::pair<int32_t, int32_t> {
|
|||
}
|
||||
|
||||
auto HwcDisplay::AcceptValidatedComposition() -> void {
|
||||
for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
|
||||
l.second.AcceptTypeChange();
|
||||
for (auto &[_, layer] : layers_) {
|
||||
layer.AcceptTypeChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -480,20 +480,18 @@ HWC2::Error HwcDisplay::ChosePreferredConfig() {
|
|||
return SetActiveConfig(configs_.preferred_config_id);
|
||||
}
|
||||
|
||||
HWC2::Error HwcDisplay::CreateLayer(hwc2_layer_t *layer) {
|
||||
layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer(this));
|
||||
*layer = static_cast<hwc2_layer_t>(layer_idx_);
|
||||
++layer_idx_;
|
||||
return HWC2::Error::None;
|
||||
auto HwcDisplay::CreateLayer(ILayerId new_layer_id) -> bool {
|
||||
if (layers_.count(new_layer_id) > 0)
|
||||
return false;
|
||||
|
||||
layers_.emplace(new_layer_id, HwcLayer(this));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
HWC2::Error HwcDisplay::DestroyLayer(hwc2_layer_t layer) {
|
||||
if (!get_layer(layer)) {
|
||||
return HWC2::Error::BadLayer;
|
||||
}
|
||||
|
||||
layers_.erase(layer);
|
||||
return HWC2::Error::None;
|
||||
auto HwcDisplay::DestroyLayer(ILayerId layer_id) -> bool {
|
||||
auto count = layers_.erase(layer_id);
|
||||
return count != 0;
|
||||
}
|
||||
|
||||
HWC2::Error HwcDisplay::GetActiveConfig(hwc2_config_t *config) const {
|
||||
|
|
@ -742,15 +740,15 @@ HWC2::Error HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) {
|
|||
bool use_client_layer = false;
|
||||
uint32_t client_z_order = UINT32_MAX;
|
||||
std::map<uint32_t, HwcLayer *> z_map;
|
||||
for (std::pair<const hwc2_layer_t, HwcLayer> &l : layers_) {
|
||||
switch (l.second.GetValidatedType()) {
|
||||
for (auto &[_, layer] : layers_) {
|
||||
switch (layer.GetValidatedType()) {
|
||||
case HWC2::Composition::Device:
|
||||
z_map.emplace(l.second.GetZOrder(), &l.second);
|
||||
z_map.emplace(layer.GetZOrder(), &layer);
|
||||
break;
|
||||
case HWC2::Composition::Client:
|
||||
// Place it at the z_order of the lowest client layer
|
||||
use_client_layer = true;
|
||||
client_z_order = std::min(client_z_order, l.second.GetZOrder());
|
||||
client_z_order = std::min(client_z_order, layer.GetZOrder());
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class HwcDisplay {
|
|||
// To be called after SetDisplayProperties. Returns an empty vector if the
|
||||
// requested layers have been validated, otherwise the vector describes
|
||||
// the requested composition type changes.
|
||||
using ChangedLayer = std::pair<hwc2_layer_t, HWC2::Composition>;
|
||||
using ChangedLayer = std::pair<ILayerId, HWC2::Composition>;
|
||||
auto ValidateStagedComposition() -> std::vector<ChangedLayer>;
|
||||
|
||||
// Mark previously validated properties as ready to present.
|
||||
|
|
@ -110,7 +110,7 @@ class HwcDisplay {
|
|||
// Present previously staged properties, and return fences to indicate when
|
||||
// the new content has been presented, and when the previous buffers have
|
||||
// been released.
|
||||
using ReleaseFence = std::pair<hwc2_layer_t, SharedFd>;
|
||||
using ReleaseFence = std::pair<ILayerId, SharedFd>;
|
||||
auto PresentStagedComposition(SharedFd &out_present_fence,
|
||||
std::vector<ReleaseFence> &out_release_fences)
|
||||
-> bool;
|
||||
|
|
@ -123,9 +123,10 @@ class HwcDisplay {
|
|||
frontend_private_data_ = std::move(data);
|
||||
}
|
||||
|
||||
auto CreateLayer(ILayerId new_layer_id) -> bool;
|
||||
auto DestroyLayer(ILayerId layer_id) -> bool;
|
||||
|
||||
// HWC2 Hooks - these should not be used outside of the hwc2 device.
|
||||
HWC2::Error CreateLayer(hwc2_layer_t *layer);
|
||||
HWC2::Error DestroyLayer(hwc2_layer_t layer);
|
||||
HWC2::Error GetActiveConfig(hwc2_config_t *config) const;
|
||||
HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes);
|
||||
HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute,
|
||||
|
|
@ -168,7 +169,7 @@ class HwcDisplay {
|
|||
HWC2::Error SetColorTransform(const float *matrix, int32_t hint);
|
||||
HWC2::Error SetPowerMode(int32_t mode);
|
||||
HWC2::Error SetVsyncEnabled(int32_t enabled);
|
||||
HwcLayer *get_layer(hwc2_layer_t layer) {
|
||||
HwcLayer *get_layer(ILayerId layer) {
|
||||
auto it = layers_.find(layer);
|
||||
if (it == layers_.end())
|
||||
return nullptr;
|
||||
|
|
@ -201,7 +202,7 @@ class HwcDisplay {
|
|||
return hwc_;
|
||||
}
|
||||
|
||||
std::map<hwc2_layer_t, HwcLayer> &layers() {
|
||||
auto layers() -> std::map<ILayerId, HwcLayer> & {
|
||||
return layers_;
|
||||
}
|
||||
|
||||
|
|
@ -269,9 +270,7 @@ class HwcDisplay {
|
|||
const hwc2_display_t handle_;
|
||||
HWC2::DisplayType type_;
|
||||
|
||||
uint32_t layer_idx_{};
|
||||
|
||||
std::map<hwc2_layer_t, HwcLayer> layers_;
|
||||
std::map<ILayerId, HwcLayer> layers_;
|
||||
HwcLayer client_layer_;
|
||||
std::unique_ptr<HwcLayer> writeback_layer_;
|
||||
uint16_t virtual_disp_width_{};
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ class Hwc2DeviceDisplay : public FrontendDisplayBase {
|
|||
public:
|
||||
std::vector<HwcDisplay::ReleaseFence> release_fences;
|
||||
std::vector<HwcDisplay::ChangedLayer> changed_layers;
|
||||
|
||||
int64_t next_layer_id = 1;
|
||||
};
|
||||
|
||||
static auto GetHwc2DeviceDisplay(HwcDisplay &display)
|
||||
|
|
@ -267,6 +269,37 @@ static BufferSampleRange Hwc2ToSampleRange(int32_t dataspace) {
|
|||
}
|
||||
|
||||
/* Display functions */
|
||||
static int32_t CreateLayer(hwc2_device_t *device, hwc2_display_t display,
|
||||
hwc2_layer_t *out_layer) {
|
||||
ALOGV("CreateLayer");
|
||||
LOCK_COMPOSER(device);
|
||||
GET_DISPLAY(display);
|
||||
|
||||
auto hwc2display = GetHwc2DeviceDisplay(*idisplay);
|
||||
|
||||
if (!idisplay->CreateLayer(hwc2display->next_layer_id)) {
|
||||
return static_cast<int32_t>(HWC2::Error::BadDisplay);
|
||||
}
|
||||
|
||||
*out_layer = (hwc2_layer_t)hwc2display->next_layer_id;
|
||||
hwc2display->next_layer_id++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t DestroyLayer(hwc2_device_t *device, hwc2_display_t display,
|
||||
hwc2_layer_t layer) {
|
||||
ALOGV("DestroyLayer");
|
||||
LOCK_COMPOSER(device);
|
||||
GET_DISPLAY(display);
|
||||
|
||||
if (!idisplay->DestroyLayer((ILayerId)layer)) {
|
||||
return static_cast<int32_t>(HWC2::Error::BadLayer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t GetDisplayRequests(hwc2_device_t * /*device*/,
|
||||
hwc2_display_t /*display*/,
|
||||
int32_t * /* out_display_requests */,
|
||||
|
|
@ -763,13 +796,9 @@ static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device * /*dev*/,
|
|||
case HWC2::FunctionDescriptor::AcceptDisplayChanges:
|
||||
return (hwc2_function_pointer_t)AcceptDisplayChanges;
|
||||
case HWC2::FunctionDescriptor::CreateLayer:
|
||||
return ToHook<HWC2_PFN_CREATE_LAYER>(
|
||||
DisplayHook<decltype(&HwcDisplay::CreateLayer),
|
||||
&HwcDisplay::CreateLayer, hwc2_layer_t *>);
|
||||
return (hwc2_function_pointer_t)CreateLayer;
|
||||
case HWC2::FunctionDescriptor::DestroyLayer:
|
||||
return ToHook<HWC2_PFN_DESTROY_LAYER>(
|
||||
DisplayHook<decltype(&HwcDisplay::DestroyLayer),
|
||||
&HwcDisplay::DestroyLayer, hwc2_layer_t>);
|
||||
return (hwc2_function_pointer_t)DestroyLayer;
|
||||
case HWC2::FunctionDescriptor::GetActiveConfig:
|
||||
return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>(
|
||||
DisplayHook<decltype(&HwcDisplay::GetActiveConfig),
|
||||
|
|
|
|||
|
|
@ -494,13 +494,16 @@ ndk::ScopedAStatus ComposerClient::createLayer(int64_t display_id,
|
|||
return ToBinderStatus(hwc3::Error::kBadDisplay);
|
||||
}
|
||||
|
||||
hwc2_layer_t hwc2_layer_id = 0;
|
||||
auto err = Hwc2toHwc3Error(display->CreateLayer(&hwc2_layer_id));
|
||||
if (err != hwc3::Error::kNone) {
|
||||
return ToBinderStatus(err);
|
||||
auto hwc3display = DrmHwcThree::GetHwc3Display(*display);
|
||||
|
||||
if (!display->CreateLayer(hwc3display->next_layer_id)) {
|
||||
return ToBinderStatus(hwc3::Error::kBadDisplay);
|
||||
}
|
||||
|
||||
*layer_id = Hwc2LayerToHwc3(hwc2_layer_id);
|
||||
*layer_id = hwc3display->next_layer_id;
|
||||
|
||||
hwc3display->next_layer_id++;
|
||||
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
|
|
@ -534,12 +537,11 @@ ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t display_id,
|
|||
return ToBinderStatus(hwc3::Error::kBadDisplay);
|
||||
}
|
||||
|
||||
auto err = Hwc2toHwc3Error(display->DestroyLayer(Hwc3LayerToHwc2(layer_id)));
|
||||
if (err != hwc3::Error::kNone) {
|
||||
return ToBinderStatus(err);
|
||||
if (!display->DestroyLayer(layer_id)) {
|
||||
return ToBinderStatus(hwc3::Error::kBadLayer);
|
||||
}
|
||||
|
||||
return ToBinderStatus(err);
|
||||
return ToBinderStatus(hwc3::Error::kNone);
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus ComposerClient::destroyVirtualDisplay(int64_t display_id) {
|
||||
|
|
@ -698,8 +700,7 @@ void ComposerClient::ExecuteDisplayCommand(const DisplayCommand& command) {
|
|||
changed_layers = display->ValidateStagedComposition();
|
||||
DisplayChanges changes{};
|
||||
for (auto [layer_id, composition_type] : changed_layers) {
|
||||
changes.AddLayerCompositionChange(command.display,
|
||||
Hwc2LayerToHwc3(layer_id),
|
||||
changes.AddLayerCompositionChange(command.display, layer_id,
|
||||
static_cast<Composition>(
|
||||
composition_type));
|
||||
}
|
||||
|
|
@ -743,8 +744,7 @@ void ComposerClient::ExecuteDisplayCommand(const DisplayCommand& command) {
|
|||
|
||||
std::unordered_map<int64_t, unique_fd> hal_release_fences;
|
||||
for (const auto& [layer_id, release_fence] : release_fences) {
|
||||
hal_release_fences[Hwc2LayerToHwc3(layer_id)] = //
|
||||
unique_fd(::android::DupFd(release_fence));
|
||||
hal_release_fences[layer_id] = unique_fd(::android::DupFd(release_fence));
|
||||
}
|
||||
cmd_result_writer_->AddReleaseFence(display_id, hal_release_fences);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ namespace aidl::android::hardware::graphics::composer3::impl {
|
|||
class Hwc3Display : public ::android::FrontendDisplayBase {
|
||||
public:
|
||||
bool must_validate = false;
|
||||
|
||||
int64_t next_layer_id = 1;
|
||||
};
|
||||
|
||||
class DrmHwcThree : public ::android::DrmHwc {
|
||||
|
|
|
|||
10
hwc3/Utils.h
10
hwc3/Utils.h
|
|
@ -57,12 +57,6 @@ inline ndk::ScopedAStatus ToBinderStatus(HWC2::Error error) {
|
|||
return ToBinderStatus(Hwc2toHwc3Error(error));
|
||||
}
|
||||
|
||||
// ID conversion. HWC2 uses typedef'd unsigned integer types while HWC3 uses
|
||||
// signed integer types. static_cast in between these.
|
||||
inline int64_t Hwc2LayerToHwc3(hwc2_layer_t layer) {
|
||||
return static_cast<int64_t>(layer);
|
||||
}
|
||||
|
||||
inline int64_t Hwc2DisplayToHwc3(hwc2_display_t display) {
|
||||
return static_cast<int64_t>(display);
|
||||
}
|
||||
|
|
@ -71,10 +65,6 @@ inline int32_t Hwc2ConfigIdToHwc3(hwc2_config_t config_id) {
|
|||
return static_cast<int32_t>(config_id);
|
||||
}
|
||||
|
||||
inline hwc2_layer_t Hwc3LayerToHwc2(int64_t layer) {
|
||||
return static_cast<hwc2_layer_t>(layer);
|
||||
}
|
||||
|
||||
inline hwc2_display_t Hwc3DisplayToHwc2(int64_t display) {
|
||||
return static_cast<hwc2_display_t>(display);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue