1
0
Fork 0

Allow Backend to create DrmDisplayPipeline

Define a PipelineCreator interface which allows Backends to use
Backend-specific heuristics in creating the DrmDisplayPipeline.

Change-Id: I1f929213ce403267b539635ec9d5853cf1a7f18a
This commit is contained in:
Drew Davenport 2025-10-27 14:55:42 -06:00
parent 0f5244ef78
commit 3c2106f064
4 changed files with 77 additions and 47 deletions

View file

@ -262,9 +262,21 @@ std::tuple<size_t, size_t> Backend::GetExtraClientRange(
return std::make_tuple(client_start, client_size);
}
// clang-format off
class GenericBackendPipelineCreator : public BackendManager::PipelineCreator {
public:
GenericBackendPipelineCreator() : BackendManager::PipelineCreator("generic") {
}
std::unique_ptr<DrmDisplayPipeline> CreatePipeline(
DrmConnector& connector) override {
auto pipeline = DrmDisplayPipeline::CreatePipeline(connector);
if (pipeline) {
pipeline->backend = std::make_unique<Backend>();
}
return pipeline;
}
};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables, cert-err58-cpp)
REGISTER_BACKEND("generic", Backend);
// clang-format on
static GenericBackendPipelineCreator generic_backend;
} // namespace android::drm_hwcomposer

View file

@ -27,9 +27,21 @@ auto BackendClient::ValidateDisplay(const HwcDisplay* display) const
FlattenReason::kNone);
}
// clang-format off
class ClientBackendPipelineCreator : public BackendManager::PipelineCreator {
public:
ClientBackendPipelineCreator() : BackendManager::PipelineCreator("client") {
}
std::unique_ptr<DrmDisplayPipeline> CreatePipeline(
DrmConnector& connector) override {
auto pipeline = DrmDisplayPipeline::CreatePipeline(connector);
if (pipeline) {
pipeline->backend = std::make_unique<BackendClient>();
}
return pipeline;
}
};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables, cert-err58-cpp)
REGISTER_BACKEND("client", BackendClient);
// clang-format on
static ClientBackendPipelineCreator client_backend;
} // namespace android::drm_hwcomposer

View file

@ -31,53 +31,53 @@ const std::vector<std::string> BackendManager::kClientDevices = {
"pl111",
};
BackendManager::PipelineCreator::PipelineCreator(const std::string &name)
: name_(name) {
BackendManager::GetInstance().RegisterBackend(name, this);
}
BackendManager::PipelineCreator::~PipelineCreator() {
BackendManager::GetInstance().UnregisterBackend(name_);
}
BackendManager &BackendManager::GetInstance() {
static BackendManager backend_manager;
return backend_manager;
}
int BackendManager::RegisterBackend(const std::string &name,
BackendConstructorT backend_constructor) {
available_backends_[name] = std::move(backend_constructor);
return 0;
void BackendManager::RegisterBackend(const std::string &name,
PipelineCreator *pipeline_creator) {
available_backends_[name] = pipeline_creator;
}
void BackendManager::UnregisterBackend(const std::string &name) {
available_backends_.erase(name);
}
std::unique_ptr<DrmDisplayPipeline> BackendManager::CreatePipelineForConnector(
DrmConnector &connector) {
auto pipeline = DrmDisplayPipeline::CreatePipeline(connector);
if (pipeline) {
pipeline->backend = CreateBackendForConnector(connector);
}
if (!pipeline || !pipeline->backend) {
return nullptr;
}
return pipeline;
}
std::unique_ptr<Backend> BackendManager::CreateBackendForConnector(
const DrmConnector &connector) {
auto driver_name(connector.GetDev().GetName());
std::string backend_name = Properties::GetBackendOverride();
if (backend_name.empty()) {
backend_name = driver_name;
}
auto backend = GetBackendByName(backend_name);
auto *backend = GetBackendByName(backend_name);
if (backend == nullptr) {
ALOGE("Failed to create backend '%s' for '%s' and driver '%s'",
ALOGE("Failed to find backend '%s' for '%s' and driver '%s'",
backend_name.c_str(), connector.GetName().c_str(),
driver_name.c_str());
return nullptr;
}
ALOGI("Found Backend '%s' for '%s' and driver '%s'", backend_name.c_str(),
connector.GetName().c_str(), driver_name.c_str());
ALOGI("Backend '%s' for '%s' and driver '%s' was successfully created",
backend_name.c_str(), connector.GetName().c_str(), driver_name.c_str());
return backend;
return backend->CreatePipeline(connector);
}
std::unique_ptr<Backend> BackendManager::GetBackendByName(std::string &name) {
BackendManager::PipelineCreator *BackendManager::GetBackendByName(
std::string &name) {
if (available_backends_.empty()) {
ALOGE("No backends are specified");
return nullptr;
@ -89,7 +89,7 @@ std::unique_ptr<Backend> BackendManager::GetBackendByName(std::string &name) {
name = it == kClientDevices.end() ? "generic" : "client";
}
return available_backends_[name]();
return available_backends_[name];
}
} // namespace android::drm_hwcomposer

View file

@ -23,38 +23,44 @@
#include "Backend.h"
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define REGISTER_BACKEND(name_str_, backend_) \
static int \
backend = BackendManager::GetInstance() \
.RegisterBackend(name_str_, \
[]() -> std::unique_ptr<Backend> { \
return std::make_unique<backend_>(); \
});
namespace android::drm_hwcomposer {
class BackendManager {
public:
using BackendConstructorT = std::function<std::unique_ptr<Backend>()>;
// PipelineCreator implementations should inherit from this class and provide
// a name that will not collide with other PipelineCreators.
class PipelineCreator {
public:
// PipelineCreator will register a creator called |name| on construction,
// and deregister on destruction.
explicit PipelineCreator(const std::string &name);
virtual ~PipelineCreator();
// Create a DrmDisplayPipeline for the given DrmConnector. The
// implementation will also create the Backend for this DrmDisplayPipeline.
virtual std::unique_ptr<DrmDisplayPipeline> CreatePipeline(
DrmConnector &connector) = 0;
private:
std::string name_;
};
static BackendManager &GetInstance();
int RegisterBackend(const std::string &name,
BackendConstructorT backend_constructor);
void RegisterBackend(const std::string &name,
PipelineCreator *pipeline_creator);
void UnregisterBackend(const std::string &name);
std::unique_ptr<DrmDisplayPipeline> CreatePipelineForConnector(
DrmConnector &connector);
private:
std::unique_ptr<Backend> CreateBackendForConnector(
const DrmConnector &connector);
std::unique_ptr<Backend> GetBackendByName(std::string &name);
PipelineCreator *GetBackendByName(std::string &name);
BackendManager() = default;
static const std::vector<std::string> kClientDevices;
std::map<std::string, BackendConstructorT> available_backends_;
std::map<std::string, PipelineCreator *> available_backends_;
};
} // namespace android::drm_hwcomposer