[PATCH 1/2] qcam: viewfinder_qt: Draw the letterbox background black
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Mon Sep 9 18:03:31 CEST 2024
On Mon, Sep 09, 2024 at 01:33:54PM +0100, Kieran Bingham wrote:
> Quoting Laurent Pinchart (2024-09-05 17:25:07)
> > When the widget's aspect ratio doesn't match the camera aspect ratio,
> > the viewfinder is rendered letter-boxed. The side rectangles are not
> > painted by the viewfinder, and Qt thus renders the parent widget
> > background to fill that space.
> >
> > To make it black, we have two options:
> >
> > - The simplest option is to set the widget's autoFillBackground property
> > to true. This causes Qt to paint the whole widget with its background
> > colour before calling paintEvent(). As the camera image typically
> > covers most (if not all) of the viewfinder widget, this is less
> > efficient.
> >
> > - The more complicated option is to pain the letterbox rectangles
>
> s/pain/paint/
>
> > manually. We can additionally set the widget's WA_OpaquePaintEvent
> > attribute to instruct Qt to skip painting the parent widget. This
> > reduces CPU usage by about 1% (and may reduce GPU usage as well).
> >
> > Note that the WA_OpaquePaintEvent attribute has to be disabled when we
> > render the stopped icon, as the icon has a transparent background.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > ---
> > src/apps/qcam/viewfinder_qt.cpp | 23 +++++++++++++++++++++--
> > 1 file changed, 21 insertions(+), 2 deletions(-)
> >
> > diff --git a/src/apps/qcam/viewfinder_qt.cpp b/src/apps/qcam/viewfinder_qt.cpp
> > index 492648cfa2ff..62b6f27fa23e 100644
> > --- a/src/apps/qcam/viewfinder_qt.cpp
> > +++ b/src/apps/qcam/viewfinder_qt.cpp
> > @@ -44,6 +44,10 @@ ViewFinderQt::ViewFinderQt(QWidget *parent)
> > : QWidget(parent), place_(rect()), buffer_(nullptr)
> > {
> > icon_ = QIcon(":camera-off.svg");
> > +
> > + QPalette pal = palette();
> > + pal.setColor(QPalette::Window, Qt::black);
> > + setPalette(pal);
> > }
> >
> > ViewFinderQt::~ViewFinderQt()
> > @@ -118,6 +122,7 @@ void ViewFinderQt::render(libcamera::FrameBuffer *buffer, Image *image)
> > }
> > }
> >
>
> I would probably have a comment here ...
>
> > + setAttribute(Qt::WA_OpaquePaintEvent, true);
> > update();
> >
> > if (buffer)
> > @@ -133,6 +138,7 @@ void ViewFinderQt::stop()
> > buffer_ = nullptr;
> > }
> >
>
> and here ...
>
> to say why we are starting and sotpping the paint attributes.
>
> > + setAttribute(Qt::WA_OpaquePaintEvent, false);
> > update();
> > }
> >
> > @@ -147,8 +153,22 @@ void ViewFinderQt::paintEvent(QPaintEvent *)
> > {
> > QPainter painter(this);
> >
> > - /* If we have an image, draw it. */
> > + painter.setBrush(palette().window());
> > +
> > + /* If we have an image, draw it, with black letterbox rectangles. */
> > if (!image_.isNull()) {
> > + if (place_.width() < width()) {
> > + QRect rect{ 0, 0, (width() - place_.width()) / 2, height() };
> > + painter.drawRect(rect);
> > + rect.moveLeft(place_.right());
> > + painter.drawRect(rect);
> > + } else {
> > + QRect rect{ 0, 0, width(), (height() - place_.height()) / 2 };
> > + painter.drawRect(rect);
> > + rect.moveTop(place_.bottom());
> > + painter.drawRect(rect);
> > + }
>
> Seems easy enough.
>
>
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
>
> And tested on my X13s
>
> However, I can't currently test qcam -r gles it seems which is crashing
> but that's on mainline too so not this series.
It doesn't crash for me, but it doesn't work either :-( The move to Qt6
apparently introduced an issue.
> > +
> > painter.drawImage(place_, image_, image_.rect());
> > return;
> > }
> > @@ -174,7 +194,6 @@ void ViewFinderQt::paintEvent(QPaintEvent *)
> > else
> > point.setY((height() - pixmap_.height()) / 2);
> >
> > - painter.setBackgroundMode(Qt::OpaqueMode);
> > painter.drawPixmap(point, pixmap_);
> > }
> >
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list