Commit 26aab43f authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧 Committed by Aleix Pol Gonzalez
Browse files

pipewire: Fix downloading software-rotated textures

At the moment we'll be setting the YInverted setting, but in practice
that won't have any effect as it only changes the render matrix and
we'll end up streaming inverted textures.
This change addresses it by rendering it into another texture first to
resolve this situation and then download that new texture instead.


(cherry picked from commit c0718249)
parent ef6a9c47
......@@ -721,6 +721,7 @@ GLPlatform::GLPlatform()
m_limitedGLSL(false),
m_textureNPOT(false),
m_limitedNPOT(false),
m_packInvert(false),
m_virtualMachine(false),
m_preferBufferSubData(false),
m_platformInterface(NoOpenGLPlatformInterface),
......@@ -801,6 +802,7 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface)
m_chipset = QByteArrayLiteral("Unknown");
m_preferBufferSubData = false;
m_packInvert = m_extensions.contains("GL_MESA_pack_invert");
// Mesa classic drivers
......@@ -1200,6 +1202,9 @@ bool GLPlatform::supports(GLFeature feature) const
case LimitedNPOT:
return m_limitedNPOT;
case PackInvert:
return m_packInvert;
default:
return false;
}
......
......@@ -72,6 +72,11 @@ enum GLFeature {
* - GL_CLAMP_TO_BORDER
*/
LimitedNPOT,
/**
* Set if the extension GL_MESA_pack_invert is present
*/
PackInvert,
};
enum Driver {
......@@ -444,6 +449,7 @@ private:
bool m_limitedGLSL: 1;
bool m_textureNPOT: 1;
bool m_limitedNPOT: 1;
bool m_packInvert: 1;
bool m_virtualMachine: 1;
bool m_preferBufferSubData: 1;
OpenGLPlatformInterface m_platformInterface;
......
......@@ -328,6 +328,19 @@ static GLTexture *copyTexture(GLTexture *texture)
return copy;
}
// in-place vertical mirroring
static void mirrorVertically(uchar *data, int height, int stride)
{
const int halfHeight = height / 2;
std::vector<uchar> temp(stride);
for (int y = 0; y < halfHeight; ++y) {
auto cur = &data[y * stride], dest = &data[(height - y - 1) * stride];
memcpy(temp.data(), cur, stride);
memcpy(cur, dest, stride);
memcpy(dest, temp.data(), stride);
}
}
void PipeWireStream::recordFrame(GLTexture *frameTexture, const QRegion &damagedRegion)
{
Q_ASSERT(!m_stopped);
......@@ -384,6 +397,12 @@ void PipeWireStream::recordFrame(GLTexture *frameTexture, const QRegion &damaged
spa_data->chunk->size = bufferSize;
spa_data->chunk->stride = stride;
const bool invertNeededAndSupported = frameTexture->isYInverted() && GLPlatform::instance()->supports(PackInvert);
GLboolean prev;
if (invertNeededAndSupported) {
glGetBooleanv(GL_PACK_INVERT_MESA, &prev);
glPixelStorei(GL_PACK_INVERT_MESA, GL_TRUE);
}
frameTexture->bind();
if (GLPlatform::instance()->isGLES()) {
......@@ -393,6 +412,14 @@ void PipeWireStream::recordFrame(GLTexture *frameTexture, const QRegion &damaged
} else {
glGetTexImage(frameTexture->target(), 0, m_hasAlpha ? GL_BGRA : GL_BGR, GL_UNSIGNED_BYTE, data);
}
if (invertNeededAndSupported) {
if (!prev) {
glPixelStorei(GL_PACK_INVERT_MESA, prev);
}
} else if (frameTexture->isYInverted()) {
mirrorVertically(data, size.height(), stride);
}
auto cursor = Cursors::self()->currentCursor();
if (m_cursor.mode == KWaylandServer::ScreencastV1Interface::Embedded && m_cursor.viewport.contains(cursor->pos())) {
QImage dest(data, size.width(), size.height(), QImage::Format_RGBA8888_Premultiplied);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment