QWaylandShmBackingStore: Don't clear new buffers in beginPaint
QFile::resize done upon creation of the buffer already ensures the buffer is filled with zeroes, so there is no need to paint it transparent if the buffer had just been created. Change-Id: I73ab297f148987acf52a0e08c7dd1ca57f7255be Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
7de67b2db7
commit
5fb45c9590
@ -71,6 +71,7 @@ QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
|
|||||||
file->open(fd, QIODevice::ReadWrite | QIODevice::Unbuffered, QFile::AutoCloseHandle);
|
file->open(fd, QIODevice::ReadWrite | QIODevice::Unbuffered, QFile::AutoCloseHandle);
|
||||||
filePointer.reset(file);
|
filePointer.reset(file);
|
||||||
}
|
}
|
||||||
|
// NOTE beginPaint assumes a new buffer be all zeroes, which QFile::resize does.
|
||||||
if (!filePointer->isOpen() || !filePointer->resize(alloc)) {
|
if (!filePointer->isOpen() || !filePointer->resize(alloc)) {
|
||||||
qWarning("QWaylandShmBuffer: failed: %s", qUtf8Printable(filePointer->errorString()));
|
qWarning("QWaylandShmBuffer: failed: %s", qUtf8Printable(filePointer->errorString()));
|
||||||
return;
|
return;
|
||||||
@ -144,9 +145,9 @@ QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window, QWaylandDispla
|
|||||||
// contents from the back buffer
|
// contents from the back buffer
|
||||||
mBuffers.clear();
|
mBuffers.clear();
|
||||||
mFrontBuffer = nullptr;
|
mFrontBuffer = nullptr;
|
||||||
// ensureBackBuffer always resets mBackBuffer
|
// recreateBackBufferIfNeeded always resets mBackBuffer
|
||||||
if (mRequestedSize.isValid() && waylandWindow())
|
if (mRequestedSize.isValid() && waylandWindow())
|
||||||
ensureBackBuffer();
|
recreateBackBufferIfNeeded();
|
||||||
qDeleteAll(copy);
|
qDeleteAll(copy);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -181,12 +182,15 @@ void QWaylandShmBackingStore::beginPaint(const QRegion ®ion)
|
|||||||
{
|
{
|
||||||
mPainting = true;
|
mPainting = true;
|
||||||
waylandWindow()->setBackingStore(this);
|
waylandWindow()->setBackingStore(this);
|
||||||
ensureBackBuffer();
|
const bool bufferWasRecreated = recreateBackBufferIfNeeded();
|
||||||
|
|
||||||
const QMargins margins = windowDecorationMargins();
|
const QMargins margins = windowDecorationMargins();
|
||||||
updateDirtyStates(region.translated(margins.left(), margins.top()));
|
updateDirtyStates(region.translated(margins.left(), margins.top()));
|
||||||
|
|
||||||
if (mBackBuffer->image()->hasAlphaChannel()) {
|
// Although undocumented, QBackingStore::beginPaint expects the painted region
|
||||||
|
// to be cleared before use if the window has a surface format with an alpha.
|
||||||
|
// Fresh QWaylandShmBuffer are already cleared, so we don't need to clear those.
|
||||||
|
if (!bufferWasRecreated && mBackBuffer->image()->hasAlphaChannel()) {
|
||||||
QPainter p(paintDevice());
|
QPainter p(paintDevice());
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
const QColor blank = Qt::transparent;
|
const QColor blank = Qt::transparent;
|
||||||
@ -238,8 +242,10 @@ void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &)
|
|||||||
mRequestedSize = size;
|
mRequestedSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandShmBuffer *QWaylandShmBackingStore::getBuffer(const QSize &size)
|
QWaylandShmBuffer *QWaylandShmBackingStore::getBuffer(const QSize &size, bool &bufferWasRecreated)
|
||||||
{
|
{
|
||||||
|
bufferWasRecreated = false;
|
||||||
|
|
||||||
const auto copy = mBuffers; // remove when ported to vector<unique_ptr> + remove_if
|
const auto copy = mBuffers; // remove when ported to vector<unique_ptr> + remove_if
|
||||||
for (QWaylandShmBuffer *b : copy) {
|
for (QWaylandShmBuffer *b : copy) {
|
||||||
if (!b->busy()) {
|
if (!b->busy()) {
|
||||||
@ -258,14 +264,16 @@ QWaylandShmBuffer *QWaylandShmBackingStore::getBuffer(const QSize &size)
|
|||||||
if (mBuffers.size() < MAX_BUFFERS) {
|
if (mBuffers.size() < MAX_BUFFERS) {
|
||||||
QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format();
|
QImage::Format format = QPlatformScreen::platformScreenForWindow(window())->format();
|
||||||
QWaylandShmBuffer *b = new QWaylandShmBuffer(mDisplay, size, format, waylandWindow()->scale());
|
QWaylandShmBuffer *b = new QWaylandShmBuffer(mDisplay, size, format, waylandWindow()->scale());
|
||||||
|
bufferWasRecreated = true;
|
||||||
mBuffers.push_front(b);
|
mBuffers.push_front(b);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandShmBackingStore::ensureBackBuffer()
|
bool QWaylandShmBackingStore::recreateBackBufferIfNeeded()
|
||||||
{
|
{
|
||||||
|
bool bufferWasRecreated = false;
|
||||||
QMargins margins = windowDecorationMargins();
|
QMargins margins = windowDecorationMargins();
|
||||||
qreal scale = waylandWindow()->scale();
|
qreal scale = waylandWindow()->scale();
|
||||||
const QSize sizeWithMargins = (mRequestedSize + QSize(margins.left() + margins.right(), margins.top() + margins.bottom())) * scale;
|
const QSize sizeWithMargins = (mRequestedSize + QSize(margins.left() + margins.right(), margins.top() + margins.bottom())) * scale;
|
||||||
@ -278,12 +286,12 @@ void QWaylandShmBackingStore::ensureBackBuffer()
|
|||||||
// You can exercise the different codepaths with weston, switching between the gl and the
|
// You can exercise the different codepaths with weston, switching between the gl and the
|
||||||
// pixman renderer. With the gl renderer release events are sent early so we can effectively
|
// pixman renderer. With the gl renderer release events are sent early so we can effectively
|
||||||
// run single buffered, while with the pixman renderer we have to use two.
|
// run single buffered, while with the pixman renderer we have to use two.
|
||||||
QWaylandShmBuffer *buffer = getBuffer(sizeWithMargins);
|
QWaylandShmBuffer *buffer = getBuffer(sizeWithMargins, bufferWasRecreated);
|
||||||
while (!buffer) {
|
while (!buffer) {
|
||||||
qCDebug(lcWaylandBackingstore, "QWaylandShmBackingStore: stalling waiting for a buffer to be released from the compositor...");
|
qCDebug(lcWaylandBackingstore, "QWaylandShmBackingStore: stalling waiting for a buffer to be released from the compositor...");
|
||||||
|
|
||||||
mDisplay->blockingReadEvents();
|
mDisplay->blockingReadEvents();
|
||||||
buffer = getBuffer(sizeWithMargins);
|
buffer = getBuffer(sizeWithMargins, bufferWasRecreated);
|
||||||
}
|
}
|
||||||
|
|
||||||
qsizetype oldSizeInBytes = mBackBuffer ? mBackBuffer->image()->sizeInBytes() : 0;
|
qsizetype oldSizeInBytes = mBackBuffer ? mBackBuffer->image()->sizeInBytes() : 0;
|
||||||
@ -325,6 +333,8 @@ void QWaylandShmBackingStore::ensureBackBuffer()
|
|||||||
windowDecoration()->update();
|
windowDecoration()->update();
|
||||||
|
|
||||||
buffer->dirtyRegion() = QRegion();
|
buffer->dirtyRegion() = QRegion();
|
||||||
|
|
||||||
|
return bufferWasRecreated;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage *QWaylandShmBackingStore::entireSurface() const
|
QImage *QWaylandShmBackingStore::entireSurface() const
|
||||||
|
@ -69,7 +69,7 @@ public:
|
|||||||
QMargins windowDecorationMargins() const;
|
QMargins windowDecorationMargins() const;
|
||||||
QImage *entireSurface() const;
|
QImage *entireSurface() const;
|
||||||
QImage *contentSurface() const;
|
QImage *contentSurface() const;
|
||||||
void ensureBackBuffer();
|
bool recreateBackBufferIfNeeded();
|
||||||
|
|
||||||
QWaylandWindow *waylandWindow() const;
|
QWaylandWindow *waylandWindow() const;
|
||||||
void iterateBuffer();
|
void iterateBuffer();
|
||||||
@ -81,7 +81,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void updateDirtyStates(const QRegion ®ion);
|
void updateDirtyStates(const QRegion ®ion);
|
||||||
void updateDecorations();
|
void updateDecorations();
|
||||||
QWaylandShmBuffer *getBuffer(const QSize &size);
|
QWaylandShmBuffer *getBuffer(const QSize &size, bool &bufferWasRecreated);
|
||||||
|
|
||||||
QWaylandDisplay *mDisplay = nullptr;
|
QWaylandDisplay *mDisplay = nullptr;
|
||||||
std::list<QWaylandShmBuffer *> mBuffers;
|
std::list<QWaylandShmBuffer *> mBuffers;
|
||||||
|
@ -92,7 +92,7 @@ void QWaylandWindow::ensureSize()
|
|||||||
{
|
{
|
||||||
if (mBackingStore) {
|
if (mBackingStore) {
|
||||||
setBackingStore(mBackingStore);
|
setBackingStore(mBackingStore);
|
||||||
mBackingStore->ensureBackBuffer();
|
mBackingStore->recreateBackBufferIfNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user