[libcamera-devel,v4] cam: kms_sink: Remove limitation that camera and display must match
diff mbox series

Message ID 20220617094126.6781-1-ecurtin@redhat.com
State Accepted
Headers show
Series
  • [libcamera-devel,v4] cam: kms_sink: Remove limitation that camera and display must match
Related show

Commit Message

Eric Curtin June 17, 2022, 9:41 a.m. UTC
There is a limitation that requires input and output to be pixel
for pixel identical in terms of height and width. Remove this
limitation to enable more hardware that doesn't match. Just start
drawing from top left 0, 0 corner.

Signed-off-by: Eric Curtin <ecurtin@redhat.com>
---
Changes in v4:
- Change commit message to say top left
- Spaces to tabs

Changes in v3:
- Much simplified version of the patch where we just attempt to
  draw from point 0, 0. Only in the case where we do not find a
  matching mode. Can expand to do centralization, scaling, etc.
  in further patches if needs be.

Changes in v2:
- Tested and support drawing from negative pixel range
  kernel parameter (video=960x540@60) was useful here
---
 src/cam/kms_sink.cpp | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

Patch
diff mbox series

diff --git a/src/cam/kms_sink.cpp b/src/cam/kms_sink.cpp
index 7add81a6..985b5f2e 100644
--- a/src/cam/kms_sink.cpp
+++ b/src/cam/kms_sink.cpp
@@ -119,15 +119,20 @@  int KMSSink::configure(const libcamera::CameraConfiguration &config)
 						      mode.vdisplay == cfg.size.height;
 				       });
 	if (iter == modes.end()) {
-		std::cerr << "No mode matching " << cfg.size << std::endl;
-		return -EINVAL;
+		if (modes.empty()) {
+			std::cerr << "No modes\n";
+			return -EINVAL;
+		}
+
+		mode_ = &modes[0];
+	} else {
+		mode_ = &*iter;
 	}
 
 	int ret = configurePipeline(cfg.pixelFormat);
 	if (ret < 0)
 		return ret;
 
-	mode_ = &*iter;
 	size_ = cfg.size;
 	stride_ = cfg.stride;
 
@@ -295,12 +300,12 @@  bool KMSSink::processRequest(libcamera::Request *camRequest)
 		drmRequest->addProperty(plane_, "CRTC_ID", crtc_->id());
 		drmRequest->addProperty(plane_, "SRC_X", 0 << 16);
 		drmRequest->addProperty(plane_, "SRC_Y", 0 << 16);
-		drmRequest->addProperty(plane_, "SRC_W", mode_->hdisplay << 16);
-		drmRequest->addProperty(plane_, "SRC_H", mode_->vdisplay << 16);
+		drmRequest->addProperty(plane_, "SRC_W", size_.width << 16);
+		drmRequest->addProperty(plane_, "SRC_H", size_.height << 16);
 		drmRequest->addProperty(plane_, "CRTC_X", 0);
 		drmRequest->addProperty(plane_, "CRTC_Y", 0);
-		drmRequest->addProperty(plane_, "CRTC_W", mode_->hdisplay);
-		drmRequest->addProperty(plane_, "CRTC_H", mode_->vdisplay);
+		drmRequest->addProperty(plane_, "CRTC_W", size_.width);
+		drmRequest->addProperty(plane_, "CRTC_H", size_.height);
 
 		flags |= DRM::AtomicRequest::FlagAllowModeset;
 	}