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:
parent
0f5244ef78
commit
3c2106f064
4 changed files with 77 additions and 47 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue