Commit 42e95965 authored by Matvii Zorin's avatar Matvii Zorin
Browse files

drm_hwcomposer: Add backend-dependent validation for ValidateDisplay function



Different DRM/KMS backends have a variable set of limitations, which is
not always exposed via DRM ioctls.

This implementation of backend-dependent validation provides a register
of platform-specific inherited backend class to the map.

The map key is a string that contains the corresponding DRM driver name.
During DrmHwcTwo class initialization the driver name will be checked and
a backend will be chosen. If the map does not have any backend for the
named driver, generic display backend will be used.

Signed-off-by: Matvii Zorin's avatarMatvii Zorin <matvii.zorin@globallogic.com>
parent ef753bfc
Pipeline #184169 failed with stage
in 26 seconds
......@@ -94,6 +94,10 @@ cc_library_static {
"utils/autolock.cpp",
"utils/hwcutils.cpp",
"backend/backendmanager.cpp",
"backend/backend.cpp",
"backend/backendclient.cpp",
],
}
......
#include "backend.h"
#include "backendmanager.h"
#include "drmhwctwo.h"
namespace android {
HWC2::Error Backend::ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
uint32_t *num_types,
uint32_t *num_requests) {
ALOGE("Validate generic");
return display->ValidateDisplayGeneric(num_types, num_requests);
}
REGISTER_BACKEND("generic", Backend);
} // namespace android
#include "backendclient.h"
#include "backendmanager.h"
#include "drmhwctwo.h"
namespace android {
HWC2::Error BackendClient::ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
uint32_t *num_types,
uint32_t * /*num_requests*/) {
ALOGE("Skip Composition");
for (auto &[std::ignore, layer] : display->GetLayers()) {
layer.set_validated_type(HWC2::Composition::Client);
++*num_types;
}
return HWC2::Error::HasChanges;
}
REGISTER_BACKEND("client", BackendClient);
} // namespace android
#define LOG_TAG "hwc-backend"
#include "backendmanager.h"
#include "backend.h"
#include "drmhwctwo.h"
#include <log/log.h>
namespace android {
BackendManager &BackendManager::GetInstance() {
static BackendManager backend_manager;
return backend_manager;
}
int BackendManager::RegisterBackend(const std::string &name,
std::unique_ptr<Backend> backend) {
GetInstance().backends_[name] = std::move(backend);
return 0;
}
HWC2::Error BackendManager::ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
uint32_t *num_types,
uint32_t *num_requests) {
if (!backend_) {
ALOGE("Backend is not set");
return HWC2::Error::Unsupported;
}
return backend_->ValidateDisplay(display, num_types, num_requests);
}
HWC2::Error BackendManager::SetBackend(const std::string &name) {
if (!backends_.size()) {
ALOGE("No backends are specified");
return HWC2::Error::Unsupported;
}
backend_ = backends_[name].get();
if (!backend_)
backend_ = backends_["generic"].get();
return HWC2::Error::None;
}
} // namespace android
......@@ -18,10 +18,12 @@
#define LOG_TAG "hwc-drm-two"
#include "drmhwctwo.h"
#include "backendmanager.h"
#include "drmdisplaycomposition.h"
#include "drmhwcomposer.h"
#include "platform.h"
#include "vsyncworker.h"
#include "xf86drm.h"
#include <inttypes.h>
#include <string>
......@@ -103,6 +105,17 @@ HWC2::Error DrmHwcTwo::Init() {
for (auto &device : drmDevices) {
device->RegisterHotplugHandler(new DrmHotplugHandler(this, device.get()));
}
auto ver = drmGetVersion(drmDevices.front()->fd());
std::string name = ver ? ver->name : "generic";
drmFreeVersion(ver);
ret = BackendManager::GetInstance().SetBackend("client");
if (ret != HWC2::Error::None) {
ALOGE("Failed to set backend for module %s with error %d", ver->name,
ret);
}
return ret;
}
......@@ -898,6 +911,11 @@ void DrmHwcTwo::HwcDisplay::MarkValidated(
HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
uint32_t *num_requests) {
return BackendManager::GetInstance().ValidateDisplay(this, num_types, num_requests);
}
HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplayGeneric(
uint32_t *num_types, uint32_t *num_requests) {
supported(__func__);
*num_types = 0;
*num_requests = 0;
......
#ifndef ANDROID_BACKEND_H
#define ANDROID_BACKEND_H
#include "drmhwctwo.h"
namespace android {
class Backend {
public:
virtual ~Backend(){};
virtual HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
uint32_t *num_types,
uint32_t *num_requests);
};
} // namespace android
#endif
#ifndef ANDROID_BACKEND_CLIENT_H
#define ANDROID_BACKEND_CLIENT_H
#include "backend.h"
#include "drmhwctwo.h"
namespace android {
class BackendClient : public Backend {
public:
HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
uint32_t *num_types,
uint32_t *num_requests) override;
};
} // namespace android
#endif
#ifndef ANDROID_BACKEND_MANAGER_H
#define ANDROID_BACKEND_MANAGER_H
#include "backend.h"
#include "drmhwctwo.h"
#include <map>
#include <string>
#define REGISTER_BACKEND(name_str_, backend_) \
static int \
backend = BackendManager::RegisterBackend(name_str_, std::unique_ptr<Backend>(new backend_()));
namespace android {
class BackendManager {
public:
static BackendManager &GetInstance();
static int RegisterBackend(const std::string &name,
std::unique_ptr<Backend> backend);
HWC2::Error SetBackend(const std::string &name);
HWC2::Error ValidateDisplay(DrmHwcTwo::HwcDisplay *display,
uint32_t *num_types,
uint32_t *num_requests);
private:
BackendManager(){};
Backend *backend_;
std::map<std::string, std::unique_ptr<Backend>> backends_;
};
} // namespace android
#endif
......@@ -224,12 +224,17 @@ class DrmHwcTwo : public hwc2_device_t {
HWC2::Error SetPowerMode(int32_t mode);
HWC2::Error SetVsyncEnabled(int32_t enabled);
HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests);
HWC2::Error ValidateDisplayGeneric(uint32_t *num_types,
uint32_t *num_requests);
HwcLayer *get_layer(hwc2_layer_t layer) {
auto it = layers_.find(layer);
if (it == layers_.end())
return nullptr;
return &it->second;
}
std::map<hwc2_layer_t, HwcLayer> &GetLayers() {
return layers_;
}
private:
HWC2::Error CreateComposition(bool test);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment