1
0
Fork 0

drm_hwcomposer: Add drm object fakes for DrmDisplayPipelineTest

Change-Id: I1ffbf45a787bac8ce414ef03701bc544835da3a7
This commit is contained in:
Andrew Wolfers 2025-09-30 17:04:10 +00:00
parent ec00b3dc25
commit 086a6f1fc4
6 changed files with 152 additions and 12 deletions

View file

@ -36,6 +36,8 @@ class DrmDevice;
using EdidWrapperUnique = std::unique_ptr<EdidWrapper>;
class DrmConnector : public PipelineBindable<DrmConnector> {
friend class FakeDrmConnector;
public:
static auto CreateInstance(DrmDevice &dev, uint32_t connector_id,
uint32_t index) -> std::unique_ptr<DrmConnector>;
@ -43,6 +45,8 @@ class DrmConnector : public PipelineBindable<DrmConnector> {
DrmConnector(const DrmProperty &) = delete;
DrmConnector &operator=(const DrmProperty &) = delete;
virtual ~DrmConnector() = default;
int UpdateEdidProperty();
auto GetEdidBlob() -> DrmModePropertyBlobUnique;
auto GetParsedEdid() -> EdidWrapperUnique & {
@ -61,7 +65,7 @@ class DrmConnector : public PipelineBindable<DrmConnector> {
return index_in_res_array_;
}
auto GetCurrentEncoderId() const {
virtual uint32_t GetCurrentEncoderId() const {
return connector_->encoder_id;
}

View file

@ -30,6 +30,8 @@ namespace android::drm_hwcomposer {
class DrmDevice;
class DrmCrtc : public PipelineBindable<DrmCrtc> {
friend class FakeDrmCrtc;
public:
static auto CreateInstance(DrmDevice &dev, uint32_t crtc_id, uint32_t index)
-> std::unique_ptr<DrmCrtc>;
@ -38,7 +40,9 @@ class DrmCrtc : public PipelineBindable<DrmCrtc> {
DrmCrtc(const DrmCrtc &) = delete;
DrmCrtc &operator=(const DrmCrtc &) = delete;
auto GetId() const {
virtual ~DrmCrtc() = default;
virtual uint32_t GetId() const {
return crtc_->crtc_id;
}

View file

@ -34,6 +34,8 @@ class DrmPlane;
class ResourceManager;
class DrmDevice {
friend class FakeDrmDevice;
public:
~DrmDevice() = default;

View file

@ -14,20 +14,142 @@
* limitations under the License.
*/
#include <cstdint>
#include <memory>
#include <gtest/gtest.h>
#include <xf86drmMode.h>
#include "DrmConnector.h"
#include "DrmCrtc.h"
#include "DrmDevice.h"
#include "DrmDisplayPipeline.h"
#include "DrmEncoder.h"
#include "DrmPlane.h"
namespace android::drm_hwcomposer {
class NoOpBindable : public PipelineBindable<NoOpBindable> {};
class DrmDisplayPipelineTest : public ::testing::Test {};
class FakeDrmConnector : public DrmConnector {
public:
FakeDrmConnector(DrmDevice* dev, uint32_t encoder_id)
: DrmConnector(nullptr, dev, 0), encoder_id_(encoder_id) {
}
uint32_t GetCurrentEncoderId() const override {
return encoder_id_;
}
private:
const uint32_t encoder_id_;
};
class FakeDrmEncoder : public DrmEncoder {
public:
FakeDrmEncoder(uint32_t id, uint32_t crtc_id)
: DrmEncoder(nullptr, 0), id_(id), crtc_id_(crtc_id) {
}
uint32_t GetId() const override {
return id_;
}
uint32_t GetCurrentCrtcId() const override {
return crtc_id_;
}
private:
const uint32_t id_;
const uint32_t crtc_id_;
};
class FakeDrmCrtc : public DrmCrtc {
public:
explicit FakeDrmCrtc(uint32_t id) : DrmCrtc(nullptr, 0), id_(id) {
}
uint32_t GetId() const override {
return id_;
}
private:
const uint32_t id_;
};
class FakeDrmPlane : public DrmPlane {
public:
FakeDrmPlane(DrmDevice& dev, uint32_t type) : DrmPlane(dev, nullptr) {
type_ = type;
}
bool IsCrtcSupported(const DrmCrtc& crtc) const override {
return true;
}
};
class FakeDrmDevice : public DrmDevice {
public:
FakeDrmDevice() : DrmDevice(nullptr, 0) {
}
void AddConnector(std::unique_ptr<DrmConnector> connector) {
connectors_.emplace_back(std::move(connector));
}
void AddEncoder(std::unique_ptr<DrmEncoder> encoder) {
encoders_.emplace_back(std::move(encoder));
}
void AddCrtc(std::unique_ptr<DrmCrtc> crtc) {
crtcs_.emplace_back(std::move(crtc));
}
void AddPlane(std::unique_ptr<DrmPlane> plane) {
planes_.emplace_back(std::move(plane));
}
void AddPipelineResources() {
AddEncoder(std::make_unique<FakeDrmEncoder>(/*id=*/next_id_,
/*crtc_id=*/next_id_));
AddCrtc(std::make_unique<FakeDrmCrtc>(/*id=*/next_id_));
AddConnector(std::make_unique<FakeDrmConnector>(this,
/*encoder_id=*/next_id_));
AddPlane(std::make_unique<FakeDrmPlane>(*this, DRM_PLANE_TYPE_PRIMARY));
++next_id_;
}
private:
uint32_t next_id_ = 0;
};
class DrmDisplayPipelineTest : public ::testing::Test {
public:
void SetUp() override {
fake_device_ = std::make_unique<FakeDrmDevice>();
}
void TearDown() override {
fake_device_.reset();
}
std::unique_ptr<DrmDisplayPipeline> CreatePipeline() {
fake_device_->AddPipelineResources();
return DrmDisplayPipeline::CreatePipeline(
*fake_device_->GetConnectors().back());
}
void AddPlane(uint32_t type) {
fake_device_->AddPlane(std::make_unique<FakeDrmPlane>(*fake_device_, type));
}
private:
std::unique_ptr<FakeDrmDevice> fake_device_ = nullptr;
};
TEST_F(DrmDisplayPipelineTest, BindPipeline_Success) {
const auto pipeline = std::make_unique<DrmDisplayPipeline>();
const auto pipeline = CreatePipeline();
NoOpBindable bindable;
const auto binding = bindable.BindPipeline(pipeline.get(),
@ -39,7 +161,7 @@ TEST_F(DrmDisplayPipelineTest, BindPipeline_Success) {
}
TEST_F(DrmDisplayPipelineTest, BindPipeline_SamePipelineReturnsSameBinding) {
const auto pipeline = std::make_unique<DrmDisplayPipeline>();
const auto pipeline = CreatePipeline();
NoOpBindable bindable;
const auto binding1 = bindable.BindPipeline(pipeline.get(),
@ -54,8 +176,8 @@ TEST_F(DrmDisplayPipelineTest, BindPipeline_SamePipelineReturnsSameBinding) {
TEST_F(DrmDisplayPipelineTest,
BindPipeline_DifferentPipelineReturnsNullBinding) {
const auto pipeline1 = std::make_unique<DrmDisplayPipeline>();
const auto pipeline2 = std::make_unique<DrmDisplayPipeline>();
const auto pipeline1 = CreatePipeline();
const auto pipeline2 = CreatePipeline();
NoOpBindable bindable;
const auto binding1 = bindable.BindPipeline(pipeline1.get(),
@ -70,8 +192,8 @@ TEST_F(DrmDisplayPipelineTest,
TEST_F(DrmDisplayPipelineTest,
BindPipeline_ReleasedBindingDoesntPreventNewBinding) {
const auto pipeline1 = std::make_unique<DrmDisplayPipeline>();
const auto pipeline2 = std::make_unique<DrmDisplayPipeline>();
const auto pipeline1 = CreatePipeline();
const auto pipeline2 = CreatePipeline();
NoOpBindable bindable;
auto binding1 = bindable.BindPipeline(pipeline1.get(),

View file

@ -28,6 +28,8 @@
namespace android::drm_hwcomposer {
class DrmEncoder : public PipelineBindable<DrmEncoder> {
friend class FakeDrmEncoder;
public:
static auto CreateInstance(DrmDevice &dev, uint32_t encoder_id,
uint32_t index) -> std::unique_ptr<DrmEncoder>;
@ -35,7 +37,9 @@ class DrmEncoder : public PipelineBindable<DrmEncoder> {
DrmEncoder(const DrmEncoder &) = delete;
DrmEncoder &operator=(const DrmEncoder &) = delete;
auto GetId() const {
virtual ~DrmEncoder() = default;
virtual uint32_t GetId() const {
return enc_->encoder_id;
};
@ -51,7 +55,7 @@ class DrmEncoder : public PipelineBindable<DrmEncoder> {
return (enc_->possible_crtcs & (1 << crtc.GetIndexInResArray())) != 0;
}
auto GetCurrentCrtcId() {
virtual uint32_t GetCurrentCrtcId() const {
return enc_->crtc_id;
}

View file

@ -37,14 +37,18 @@ struct drm_plane_size_hint_local {
};
class DrmPlane : public PipelineBindable<DrmPlane> {
friend class FakeDrmPlane;
public:
DrmPlane(const DrmPlane &) = delete;
DrmPlane &operator=(const DrmPlane &) = delete;
virtual ~DrmPlane() = default;
static auto CreateInstance(DrmDevice &dev, uint32_t plane_id)
-> std::unique_ptr<DrmPlane>;
bool IsCrtcSupported(const DrmCrtc &crtc) const;
virtual bool IsCrtcSupported(const DrmCrtc &crtc) const;
bool IsValidForLayer(const LayerData *layer);
auto GetType() const {