8#include <QtCore/QLoggingCategory>
10#include <drm_fourcc.h>
19 Q_ASSERT(DRM_FORMAT_ARGB8888 == V4L2_PIX_FMT_ABGR32);
27 return MEDIA_BUS_FMT_RGB888_1X24;
29 return MEDIA_BUS_FMT_BGR888_1X24;
30 case DRM_FORMAT_XRGB8888:
31 case DRM_FORMAT_XBGR8888:
33 case DRM_FORMAT_RGBX8888:
34 case DRM_FORMAT_BGRX8888:
35 case DRM_FORMAT_ARGB8888:
38 case DRM_FORMAT_BGRA8888:
39 return MEDIA_BUS_FMT_ARGB8888_1X32;
42 return MEDIA_BUS_FMT_ARGB8888_1X32;
47 : m_mediaDevice(
"/dev/media0")
48 , m_screenSize(screenSize)
51 QString deviceName = md.deviceName();
53 if (md.model() !=
QString(
"VSP2"))
54 qWarning() <<
"Unsupported media device model:" << md.model();
56 if (deviceName !=
"fe960000.vsp")
57 qWarning() <<
"Unknown media device name:" << deviceName;
63 input.linkToBru = md.parseLink(
QString(
"'%1 rpf.%2':1 -> '%1 bru':%2").
arg(deviceName).
arg(
i));
75 md.enableLink(md.parseLink(
QString(
"'%1 bru':5 -> '%1 wpf.0':0").
arg(deviceName)));
76 md.enableLink(md.parseLink(
QString(
"'%1 wpf.0':1 -> '%1 wpf.0 output':0").
arg(deviceName)));
79 auto bruOutputFormatPad = md.parsePad(
QString(
"'%1 bru':5").
arg(deviceName));
80 auto wpfInputFormatPad = md.parsePad(
QString(
"'%1 wpf.0':0").
arg(deviceName));
81 auto wpfOutputFormatPad = md.parsePad(
QString(
"'%1 wpf.0':1").
arg(deviceName));
93 qCDebug(qLcEglfsKmsDebug) <<
"Blend unit: Enabling input" <<
i;
95 qWarning(
"Vsp2: Input %d already enabled",
i);
99 if (!bufferGeometry.isValid()) {
100 qWarning() <<
"Vsp2: Invalid buffer geometry";
104 Input &
input = m_inputs[
i];
109 if (!setInputFormat(
i, bufferGeometry, pixelFormat, bytesPerLine)) {
114 input.rpfInput->requestBuffer();
120 for (
int i = 0;
i < m_inputs.
size(); ++
i) {
122 return enableInput(
i, bufferGeometry, drmFormat, bytesPerLine) ?
i : -1;
124 qWarning() <<
"Vsp2: No more inputs available in blend unit";
130 qCDebug(qLcEglfsKmsDebug) <<
"Vsp2: disabling input" <<
i;
132 qWarning(
"Vsp2: Input %d already disabled",
i);
136 m_inputs[
i].rpfInput->clearBuffers();
137 m_inputs[
i].enabled =
false;
145 if (!
input.enabled) {
146 qWarning() <<
"Vsp2: Can't queue on disabled input" <<
index;
151 if (
input.dmabuf.fd != dmabufFd) {
153 input.dmabuf.fd = dmabufFd;
184 qWarning(
"Blending without being dirty, should not be necessary");
187 qWarning(
"Vsp2: Can't blend when layers are not enabled in order from 0 without gaps.");
191 bool queueingFailed =
false;
193 for (
int i=0;
i < m_inputs.
size(); ++
i) {
194 auto &
input = m_inputs[
i];
196 if (!
input.rpfInput->queueBuffer(
input.dmabuf.fd,
input.dmabuf.bytesUsed,
input.dmabuf.length)) {
197 qWarning() <<
"Vsp2: Failed to queue buffer for input" <<
i
198 <<
"with dmabuf" <<
input.dmabuf.fd
199 <<
"and size" <<
input.geometry.size();
201 queueingFailed =
true;
206 if (queueingFailed) {
207 qWarning() <<
"Vsp2: Trying to clean up queued buffers";
208 for (
auto &
input : std::as_const(m_inputs)) {
210 if (!
input.rpfInput->clearBuffers())
211 qWarning() <<
"Vsp2: Failed to remove buffers after an aborted blend";
217 if (!m_wpfOutput->
queueBuffer(outputDmabufFd, m_screenSize)) {
218 qWarning() <<
"Vsp2: Failed to queue blending output buffer" << outputDmabufFd << m_screenSize;
223 qWarning() <<
"Vsp2: Failed to start streaming";
228 qWarning() <<
"Vsp2: Failed to dequeue blending output buffer";
230 qWarning() <<
"Vsp2: Failed to stop streaming when recovering after a broken blend.";
235 qWarning() <<
"Vsp2: Failed to stop streaming";
245 return m_inputs.
size();
250 bool seenDisabled =
false;
251 for (
auto &
input : std::as_const(m_inputs)) {
252 if (seenDisabled &&
input.enabled)
254 seenDisabled |= !
input.enabled;
256 return m_inputs[0].enabled;
259bool QVsp2BlendingDevice::streamOn()
261 for (
auto &
input : m_inputs) {
263 if (!
input.rpfInput->streamOn()) {
273bool QVsp2BlendingDevice::streamOff()
275 bool succeeded = m_wpfOutput->
streamOff();
276 for (
auto &
input : m_inputs) {
278 succeeded &=
input.rpfInput->streamOff();
283bool QVsp2BlendingDevice::setInputFormat(
int i,
const QRect &bufferGeometry,
uint pixelFormat,
uint bytesPerLine)
290 input.enabled =
true;
291 input.geometry = bufferGeometry;
292 input.dmabuf.bytesUsed = bpp *
static_cast<uint>(bufferGeometry.width()) *
static_cast<uint>(bufferGeometry.height());
293 input.dmabuf.length =
static_cast<uint>(bufferGeometry.height()) * bytesPerLine;
295 const QSize size = bufferGeometry.size();
297 if (!
input.rpfInput->setFormat(
size, pixelFormat, bytesPerLine))
qsizetype size() const noexcept
void append(parameter_type t)
\inmodule QtCore\reentrant
\inmodule QtCore\reentrant
\macro QT_RESTRICTED_CAST_FROM_ASCII
QVsp2BlendingDevice(const QSize &screenSize)
bool blend(int outputDmabufFd)
bool hasContinuousLayers() const
bool setInputBuffer(int index, int dmabufFd)
bool enableInput(int i, const QRect &bufferGeometry, uint drmFormat, uint bytesPerLine)
bool setInputPosition(int index, const QPoint &position)
bool setInputAlpha(int index, qreal alpha)
Combined button and popup list for selecting options.
QT_BEGIN_NAMESPACE QString q_fourccToString(uint code)
#define DRM_FORMAT_BGR888
#define DRM_FORMAT_RGB888
#define DRM_FORMAT_ABGR8888
#define DRM_FORMAT_RGBA8888
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLfloat GLfloat GLfloat alpha
GLenum GLenum GLenum input
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static QT_BEGIN_NAMESPACE uint drmFormatToV4l2PixelFormat(uint drmFormat)
static uint drmFormatToMediaBusFormat(uint drmFormat)