Convert virtual backend to per screen rendering

Summary:
Output scaling can't ever work on a single buffer; especially if they're
different scales and overlapping.

This ports the virtual backend to perScreenRendering so that I can use
it for
tests.

ctest fails here, but it fails on the tests that it failed on before..

Reviewers: #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D3306
remotes/origin/bshah/hwcomposer_testing
David Edmundson 9 years ago
parent 4f4d9d5cfe
commit 1776b5f927
  1. 30
      plugins/platforms/virtual/scene_qpainter_virtual_backend.cpp
  2. 7
      plugins/platforms/virtual/scene_qpainter_virtual_backend.h
  3. 1
      plugins/platforms/virtual/screens_virtual.h
  4. 8
      plugins/platforms/virtual/virtual_backend.h

@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "scene_qpainter_virtual_backend.h"
#include "virtual_backend.h"
#include "cursor.h"
#include "screens.h"
#include <QPainter>
@ -27,16 +28,22 @@ namespace KWin
{
VirtualQPainterBackend::VirtualQPainterBackend(VirtualBackend *backend)
: QPainterBackend()
, m_backBuffer(backend->size(), QImage::Format_RGB32)
, m_backend(backend)
{
connect(screens(), &Screens::changed, this, &VirtualQPainterBackend::createOutputs);
createOutputs();
}
VirtualQPainterBackend::~VirtualQPainterBackend() = default;
QImage *VirtualQPainterBackend::buffer()
{
return &m_backBuffer;
return &m_backBuffers[0];
}
QImage *VirtualQPainterBackend::bufferForScreen(int screen)
{
return &m_backBuffers[screen];
}
bool VirtualQPainterBackend::needsFullRepaint() const
@ -48,11 +55,13 @@ void VirtualQPainterBackend::prepareRenderingFrame()
{
}
void VirtualQPainterBackend::screenGeometryChanged(const QSize &size)
void VirtualQPainterBackend::createOutputs()
{
if (m_backBuffer.size() != size) {
m_backBuffer = QImage(size, QImage::Format_RGB32);
m_backBuffer.fill(Qt::black);
m_backBuffers.clear();
for (int i = 0; i < screens()->count(); ++i) {
QImage buffer(screens()->size(i), QImage::Format_RGB32);
buffer.fill(Qt::black);
m_backBuffers << buffer;
}
}
@ -61,7 +70,9 @@ void VirtualQPainterBackend::present(int mask, const QRegion &damage)
Q_UNUSED(mask)
Q_UNUSED(damage)
if (m_backend->saveFrames()) {
m_backBuffer.save(QStringLiteral("%1/%2.png").arg(m_backend->screenshotDirPath()).arg(QString::number(m_frameCounter++)));
for (int i=0; i < m_backBuffers.size() ; i++) {
m_backBuffers[i].save(QStringLiteral("%1/screen%2-%3.png").arg(m_backend->screenshotDirPath(), QString::number(i), QString::number(m_frameCounter++)));
}
}
}
@ -70,4 +81,9 @@ bool VirtualQPainterBackend::usesOverlayWindow() const
return false;
}
bool VirtualQPainterBackend::perScreenRendering() const
{
return true;
}
}

@ -37,14 +37,17 @@ public:
virtual ~VirtualQPainterBackend();
QImage *buffer() override;
QImage *bufferForScreen(int screenId) override;
bool needsFullRepaint() const override;
bool usesOverlayWindow() const override;
void prepareRenderingFrame() override;
void present(int mask, const QRegion &damage) override;
void screenGeometryChanged(const QSize &size) override;
bool perScreenRendering() const override;
private:
QImage m_backBuffer;
void createOutputs();
QVector<QImage> m_backBuffers;
VirtualBackend *m_backend;
int m_frameCounter = 0;
};

@ -39,6 +39,7 @@ public:
void updateCount() override;
private:
void createOutputs();
VirtualBackend *m_backend;
QVector<QRect> m_geometries;
};

@ -50,6 +50,9 @@ public:
int outputCount() const {
return m_outputCount;
}
qreal outputScale() const {
return m_outputScale;
}
bool saveFrames() const {
return !m_screenshotDir.isNull();
@ -64,6 +67,10 @@ public:
m_outputCount = count;
}
Q_INVOKABLE void setOutputScale(qreal scale) {
m_outputScale = scale;
}
int drmFd() const {
return m_drmFd;
}
@ -85,6 +92,7 @@ Q_SIGNALS:
private:
QSize m_size;
int m_outputCount = 1;
qreal m_outputScale = 1;
QScopedPointer<QTemporaryDir> m_screenshotDir;
int m_drmFd = -1;
gbm_device *m_gbmDevice = nullptr;

Loading…
Cancel
Save