eglfs_kms_vsp2: Add support for setting layer alpha
Exposed through QEglFSFunctions::vsp2SetLayerAlpha. Change-Id: I2a600971d5a2aa56d4bf7cde03df3323f17249cd Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
parent
38c6d10bc8
commit
3058e21af0
@ -98,6 +98,15 @@ public:
|
||||
return func && func(screen, id, position);
|
||||
}
|
||||
|
||||
typedef bool (*Vsp2SetLayerAlphaType)(const QScreen *screen, int id, qreal alpha);
|
||||
static QByteArray vsp2SetLayerAlphaTypeIdentifier() { return QByteArrayLiteral("EglFSVsp2SetLayerAlpha"); }
|
||||
|
||||
static bool vsp2SetLayerAlpha(const QScreen *screen, int id, qreal alpha)
|
||||
{
|
||||
auto func = reinterpret_cast<Vsp2SetLayerAlphaType>(QGuiApplication::platformFunction(vsp2SetLayerAlphaTypeIdentifier()));
|
||||
return func && func(screen, id, alpha);
|
||||
}
|
||||
|
||||
typedef void (*Vsp2AddBlendListenerType)(const QScreen *screen, void(*callback)());
|
||||
static QByteArray vsp2AddBlendListenerTypeIdentifier() { return QByteArrayLiteral("EglFSVsp2AddBlendListener"); }
|
||||
|
||||
|
@ -133,6 +133,8 @@ QFunctionPointer QEglFSKmsVsp2Integration::platformFunction(const QByteArray &fu
|
||||
return QFunctionPointer(setLayerBufferStatic);
|
||||
if (function == QEglFSFunctions::vsp2SetLayerPositionTypeIdentifier())
|
||||
return QFunctionPointer(setLayerPositionStatic);
|
||||
if (function == QEglFSFunctions::vsp2SetLayerAlphaTypeIdentifier())
|
||||
return QFunctionPointer(setLayerAlphaStatic);
|
||||
if (function == QEglFSFunctions::vsp2AddBlendListenerTypeIdentifier())
|
||||
return QFunctionPointer(addBlendListenerStatic);
|
||||
|
||||
@ -184,6 +186,12 @@ void QEglFSKmsVsp2Integration::setLayerPositionStatic(const QScreen *screen, int
|
||||
vsp2Screen->setLayerPosition(id, position);
|
||||
}
|
||||
|
||||
void QEglFSKmsVsp2Integration::setLayerAlphaStatic(const QScreen *screen, int id, qreal alpha)
|
||||
{
|
||||
auto vsp2Screen = static_cast<QEglFSKmsVsp2Screen *>(screen->handle());
|
||||
vsp2Screen->setLayerAlpha(id, alpha);
|
||||
}
|
||||
|
||||
void QEglFSKmsVsp2Integration::addBlendListenerStatic(const QScreen *screen, void(*callback)())
|
||||
{
|
||||
auto vsp2Screen = static_cast<QEglFSKmsVsp2Screen *>(screen->handle());
|
||||
|
@ -72,6 +72,7 @@ private:
|
||||
static bool removeLayerStatic(const QScreen *screen, int id);
|
||||
static void setLayerBufferStatic(const QScreen *screen, int id, int dmabufFd);
|
||||
static void setLayerPositionStatic(const QScreen *screen, int id, const QPoint &position);
|
||||
static void setLayerAlphaStatic(const QScreen *screen, int id, qreal alpha);
|
||||
static void addBlendListenerStatic(const QScreen *screen, void(*callback)());
|
||||
};
|
||||
|
||||
|
@ -186,6 +186,12 @@ void QEglFSKmsVsp2Screen::setLayerPosition(int id, const QPoint &position)
|
||||
m_blendDevice->setInputPosition(layerIndex, position);
|
||||
}
|
||||
|
||||
void QEglFSKmsVsp2Screen::setLayerAlpha(int id, qreal alpha)
|
||||
{
|
||||
int layerIndex = id;
|
||||
m_blendDevice->setInputAlpha(layerIndex, alpha);
|
||||
}
|
||||
|
||||
bool QEglFSKmsVsp2Screen::removeLayer(int id)
|
||||
{
|
||||
int layerIndex = id;
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
int addLayer(int dmabufFd, const QSize &size, const QPoint &position, uint drmPixelFormat, uint bytesPerLine);
|
||||
void setLayerBuffer(int id, int dmabufFd);
|
||||
void setLayerPosition(int id, const QPoint &position);
|
||||
void setLayerAlpha(int id, qreal alpha);
|
||||
bool removeLayer(int id);
|
||||
void addBlendListener(void (*callback)());
|
||||
|
||||
|
@ -533,6 +533,14 @@ bool QLinuxMediaDevice::OutputSubDevice::streamOff()
|
||||
return QLinuxMediaDevice::streamOff(m_subdevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
|
||||
}
|
||||
|
||||
int QLinuxMediaDevice::openVideoDevice(media_pad *pad)
|
||||
{
|
||||
const char *deviceName = media_entity_get_devname(pad->entity);
|
||||
int fd = open(deviceName, O_RDWR);
|
||||
qCDebug(qLcEglfsKmsDebug) << "Opened video device:" << deviceName << "with fd" << fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
bool QLinuxMediaDevice::setSubdevFormat(struct media_pad *pad, const QSize &size, uint32_t mbusFormat)
|
||||
{
|
||||
Q_ASSERT(size.isValid());
|
||||
@ -556,6 +564,18 @@ bool QLinuxMediaDevice::setSubdevFormat(struct media_pad *pad, const QSize &size
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QLinuxMediaDevice::setSubdevAlpha(int subdevFd, qreal alpha)
|
||||
{
|
||||
struct v4l2_control control;
|
||||
control.id = V4L2_CID_ALPHA_COMPONENT;
|
||||
control.value = static_cast<__s32>(alpha * 0xff);
|
||||
if (ioctl(subdevFd, VIDIOC_S_CTRL, &control) == -1) {
|
||||
qErrnoWarning("Setting alpha (%d) failed", control.value);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QLinuxMediaDevice::setSubdevSelection(struct media_pad *pad, const QRect &geometry, uint target)
|
||||
{
|
||||
Q_ASSERT(geometry.isValid());
|
||||
|
@ -95,7 +95,10 @@ public:
|
||||
int m_subdevFd = -1;
|
||||
};
|
||||
|
||||
static int openVideoDevice(media_pad *pad);
|
||||
|
||||
static bool setSubdevFormat(struct media_pad *pad, const QSize &size, uint32_t mbusFormat = MEDIA_BUS_FMT_ARGB8888_1X32);
|
||||
static bool setSubdevAlpha(int subdevFd, qreal alpha);
|
||||
|
||||
static bool setSubdevSelection(struct media_pad *pad, const QRect &geometry, uint target);
|
||||
static bool setSubdevCrop(struct media_pad *pad, const QRect &geometry);
|
||||
|
@ -99,6 +99,7 @@ QVsp2BlendingDevice::QVsp2BlendingDevice(const QSize &screenSize)
|
||||
input.linkToBru = md.parseLink(QString("'%1 rpf.%2':1 -> '%1 bru':%2").arg(deviceName).arg(i));
|
||||
input.inputFormatPad = md.parsePad(QString("'%1 rpf.%2':0").arg(deviceName).arg(i));
|
||||
input.outputFormatPad = md.parsePad(QString("'%1 rpf.%2':1").arg(deviceName).arg(i));
|
||||
input.outputFormatFd = QLinuxMediaDevice::openVideoDevice(input.outputFormatPad);
|
||||
input.bruInputFormatPad = md.parsePad(QString("'%1 bru':%2").arg(deviceName).arg(i));
|
||||
input.rpfInput = new QLinuxMediaDevice::OutputSubDevice(&md, QString("%1 rpf.%2 input").arg(deviceName).arg(i));
|
||||
m_inputs.append(input);
|
||||
@ -202,6 +203,17 @@ bool QVsp2BlendingDevice::setInputPosition(int index, const QPoint &position)
|
||||
return QLinuxMediaDevice::setSubdevCompose(input.bruInputFormatPad, input.geometry);
|
||||
}
|
||||
|
||||
bool QVsp2BlendingDevice::setInputAlpha(int index, qreal alpha)
|
||||
{
|
||||
Input &input = m_inputs[index];
|
||||
if (input.alpha == alpha)
|
||||
return true;
|
||||
|
||||
m_dirty = true;
|
||||
input.alpha = alpha;
|
||||
return QLinuxMediaDevice::setSubdevAlpha(input.outputFormatFd, alpha);
|
||||
}
|
||||
|
||||
bool QVsp2BlendingDevice::blend(int outputDmabufFd)
|
||||
{
|
||||
if (!m_dirty)
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
bool disableInput(int i);
|
||||
bool setInputBuffer(int index, int dmabufFd);
|
||||
bool setInputPosition(int index, const QPoint &position);
|
||||
bool setInputAlpha(int index, qreal alpha);
|
||||
bool blend(int outputDmabufFd);
|
||||
int numInputs() const;
|
||||
bool isDirty() const { return m_dirty; }
|
||||
@ -71,6 +72,7 @@ private:
|
||||
struct Input {
|
||||
bool enabled = false;
|
||||
QRect geometry;
|
||||
qreal alpha = 1;
|
||||
struct {
|
||||
int fd = -1;
|
||||
uint bytesUsed = 0;
|
||||
@ -79,6 +81,7 @@ private:
|
||||
struct media_link *linkToBru = nullptr; //rpf.x:1 -> bru:x
|
||||
struct media_pad *inputFormatPad = nullptr; // rpf.x:0
|
||||
struct media_pad *outputFormatPad = nullptr; // rpf.x:1
|
||||
int outputFormatFd = -1; // rpf.x:1 (again, because v4l2_subdev_* doesn't have a way to set alpha)
|
||||
struct media_pad *bruInputFormatPad = nullptr; // bru:x
|
||||
QLinuxMediaDevice::OutputSubDevice *rpfInput = nullptr; // rpf.x input
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user