Store repaint regions per individual screen
AnimationEffect schedules repaints in postPaintWindow() and performs cleanup in preScreenPaint(). With the X11-style rendering, this doesn't have any issues, scheduled repaints will be reset during the next compositing cycle. But with per screen rendering, we might hit the following case - Paint screen 0 - Reset scheduled repaints - AnimationEffect::prePaintScreen(): update the timeline - AnimationEffect::postPaintScreen(): schedule a repaint - Paint screen 1 - Reset scheduled repaints - AnimationEffect::prePaintScreen(): destroy the animation - AnimationEffect::postPaintScreen(): no repaint is scheduled - Return to the event loop In this scenario, the repaint region scheduled by AnimationEffect will be lost when compositing is performed on screen 1. There is no any other way to fix this issue but maintain repaint regions per each individual screen if per screen rendering is enabled. BUG: 428439
This commit is contained in:
parent
3d828d891c
commit
74391e250e
12 changed files with 149 additions and 73 deletions
|
@ -729,7 +729,7 @@ template <class T>
|
||||||
static bool repaintsPending(const QList<T*> &windows)
|
static bool repaintsPending(const QList<T*> &windows)
|
||||||
{
|
{
|
||||||
return std::any_of(windows.begin(), windows.end(),
|
return std::any_of(windows.begin(), windows.end(),
|
||||||
[](T *t) { return !t->repaints().isEmpty(); });
|
[](const T *t) { return t->wantsRepaint(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compositor::windowRepaintsPending() const
|
bool Compositor::windowRepaintsPending() const
|
||||||
|
@ -745,16 +745,16 @@ bool Compositor::windowRepaintsPending() const
|
||||||
}
|
}
|
||||||
if (auto *server = waylandServer()) {
|
if (auto *server = waylandServer()) {
|
||||||
const auto &clients = server->clients();
|
const auto &clients = server->clients();
|
||||||
auto test = [](AbstractClient *c) {
|
auto test = [](const AbstractClient *c) {
|
||||||
return c->readyForPainting() && !c->repaints().isEmpty();
|
return c->readyForPainting() && c->wantsRepaint();
|
||||||
};
|
};
|
||||||
if (std::any_of(clients.begin(), clients.end(), test)) {
|
if (std::any_of(clients.begin(), clients.end(), test)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto &internalClients = workspace()->internalClients();
|
const auto &internalClients = workspace()->internalClients();
|
||||||
auto internalTest = [] (InternalClient *client) {
|
auto internalTest = [] (const InternalClient *client) {
|
||||||
return client->isShown(true) && !client->repaints().isEmpty();
|
return client->isShown(true) && client->wantsRepaint();
|
||||||
};
|
};
|
||||||
if (std::any_of(internalClients.begin(), internalClients.end(), internalTest)) {
|
if (std::any_of(internalClients.begin(), internalClients.end(), internalTest)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -47,11 +47,6 @@ Deleted::Deleted()
|
||||||
|
|
||||||
Deleted::~Deleted()
|
Deleted::~Deleted()
|
||||||
{
|
{
|
||||||
const QRegion dirty = repaints();
|
|
||||||
if (!dirty.isEmpty()) {
|
|
||||||
addWorkspaceRepaint(dirty);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (delete_refcount != 0)
|
if (delete_refcount != 0)
|
||||||
qCCritical(KWIN_CORE) << "Deleted client has non-zero reference count (" << delete_refcount << ")";
|
qCCritical(KWIN_CORE) << "Deleted client has non-zero reference count (" << delete_refcount << ")";
|
||||||
Q_ASSERT(delete_refcount == 0);
|
Q_ASSERT(delete_refcount == 0);
|
||||||
|
|
|
@ -350,6 +350,8 @@ SceneOpenGL::SceneOpenGL(OpenGLBackend *backend, QObject *parent)
|
||||||
qCDebug(KWIN_OPENGL) << "Explicit synchronization with the X command stream disabled by environment variable";
|
qCDebug(KWIN_OPENGL) << "Explicit synchronization with the X command stream disabled by environment variable";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPerScreenRenderingEnabled(m_backend->perScreenRendering());
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneOpenGL::~SceneOpenGL()
|
SceneOpenGL::~SceneOpenGL()
|
||||||
|
@ -633,6 +635,7 @@ qint64 SceneOpenGL::paint(const QRegion &damage, const QList<Toplevel *> &toplev
|
||||||
// trigger start render timer
|
// trigger start render timer
|
||||||
m_backend->prepareRenderingFrame();
|
m_backend->prepareRenderingFrame();
|
||||||
for (int i = 0; i < screens()->count(); ++i) {
|
for (int i = 0; i < screens()->count(); ++i) {
|
||||||
|
painted_screen = i;
|
||||||
const QRect &geo = screens()->geometry(i);
|
const QRect &geo = screens()->geometry(i);
|
||||||
const qreal scaling = screens()->scale(i);
|
const qreal scaling = screens()->scale(i);
|
||||||
QRegion update;
|
QRegion update;
|
||||||
|
@ -663,6 +666,7 @@ qint64 SceneOpenGL::paint(const QRegion &damage, const QList<Toplevel *> &toplev
|
||||||
GLVertexBuffer::streamingBuffer()->framePosted();
|
GLVertexBuffer::streamingBuffer()->framePosted();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
painted_screen = -1;
|
||||||
m_backend->makeCurrent();
|
m_backend->makeCurrent();
|
||||||
QRegion repaint = m_backend->prepareRenderingFrame();
|
QRegion repaint = m_backend->prepareRenderingFrame();
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ SceneQPainter::SceneQPainter(QPainterBackend *backend, QObject *parent)
|
||||||
, m_backend(backend)
|
, m_backend(backend)
|
||||||
, m_painter(new QPainter())
|
, m_painter(new QPainter())
|
||||||
{
|
{
|
||||||
|
setPerScreenRenderingEnabled(m_backend->perScreenRendering());
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneQPainter::~SceneQPainter()
|
SceneQPainter::~SceneQPainter()
|
||||||
|
@ -98,6 +99,7 @@ qint64 SceneQPainter::paint(const QRegion &_damage, const QList<Toplevel *> &top
|
||||||
}
|
}
|
||||||
QRegion overallUpdate;
|
QRegion overallUpdate;
|
||||||
for (int i = 0; i < screens()->count(); ++i) {
|
for (int i = 0; i < screens()->count(); ++i) {
|
||||||
|
painted_screen = i;
|
||||||
const QRect geometry = screens()->geometry(i);
|
const QRect geometry = screens()->geometry(i);
|
||||||
QImage *buffer = m_backend->bufferForScreen(i);
|
QImage *buffer = m_backend->bufferForScreen(i);
|
||||||
if (!buffer || buffer->isNull()) {
|
if (!buffer || buffer->isNull()) {
|
||||||
|
@ -118,6 +120,7 @@ qint64 SceneQPainter::paint(const QRegion &_damage, const QList<Toplevel *> &top
|
||||||
m_backend->showOverlay();
|
m_backend->showOverlay();
|
||||||
m_backend->present(mask, overallUpdate);
|
m_backend->present(mask, overallUpdate);
|
||||||
} else {
|
} else {
|
||||||
|
painted_screen = -1;
|
||||||
m_painter->begin(m_backend->buffer());
|
m_painter->begin(m_backend->buffer());
|
||||||
m_painter->setClipping(true);
|
m_painter->setClipping(true);
|
||||||
m_painter->setClipRegion(damage);
|
m_painter->setClipRegion(damage);
|
||||||
|
|
|
@ -240,6 +240,7 @@ bool SceneXrender::initFailed() const
|
||||||
// the entry point for painting
|
// the entry point for painting
|
||||||
qint64 SceneXrender::paint(const QRegion &damage, const QList<Toplevel *> &toplevels)
|
qint64 SceneXrender::paint(const QRegion &damage, const QList<Toplevel *> &toplevels)
|
||||||
{
|
{
|
||||||
|
painted_screen = -1;
|
||||||
QElapsedTimer renderTimer;
|
QElapsedTimer renderTimer;
|
||||||
renderTimer.start();
|
renderTimer.start();
|
||||||
|
|
||||||
|
|
90
scene.cpp
90
scene.cpp
|
@ -68,8 +68,8 @@
|
||||||
#include "shadow.h"
|
#include "shadow.h"
|
||||||
#include "subsurfacemonitor.h"
|
#include "subsurfacemonitor.h"
|
||||||
#include "wayland_server.h"
|
#include "wayland_server.h"
|
||||||
|
|
||||||
#include "thumbnailitem.h"
|
#include "thumbnailitem.h"
|
||||||
|
#include "composite.h"
|
||||||
|
|
||||||
#include <KWaylandServer/buffer_interface.h>
|
#include <KWaylandServer/buffer_interface.h>
|
||||||
#include <KWaylandServer/subcompositor_interface.h>
|
#include <KWaylandServer/subcompositor_interface.h>
|
||||||
|
@ -93,6 +93,16 @@ Scene::~Scene()
|
||||||
Q_ASSERT(m_windows.isEmpty());
|
Q_ASSERT(m_windows.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Scene::isPerScreenRenderingEnabled() const
|
||||||
|
{
|
||||||
|
return m_isPerScreenRenderingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::setPerScreenRenderingEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
m_isPerScreenRenderingEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
// returns mask and possibly modified region
|
// returns mask and possibly modified region
|
||||||
void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint,
|
void Scene::paintScreen(int* mask, const QRegion &damage, const QRegion &repaint,
|
||||||
QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection, const QRect &outputGeometry, const qreal screenScale)
|
QRegion *updateRegion, QRegion *validRegion, const QMatrix4x4 &projection, const QRect &outputGeometry, const qreal screenScale)
|
||||||
|
@ -197,15 +207,13 @@ void Scene::paintGenericScreen(int orig_mask, const ScreenPaintData &)
|
||||||
QVector<Phase2Data> phase2;
|
QVector<Phase2Data> phase2;
|
||||||
phase2.reserve(stacking_order.size());
|
phase2.reserve(stacking_order.size());
|
||||||
foreach (Window * w, stacking_order) { // bottom to top
|
foreach (Window * w, stacking_order) { // bottom to top
|
||||||
Toplevel* topw = w->window();
|
|
||||||
|
|
||||||
// Let the scene window update the window pixmap tree.
|
// Let the scene window update the window pixmap tree.
|
||||||
w->preprocess();
|
w->preprocess();
|
||||||
|
|
||||||
// Reset the repaint_region.
|
// Reset the repaint_region.
|
||||||
// This has to be done here because many effects schedule a repaint for
|
// This has to be done here because many effects schedule a repaint for
|
||||||
// the next frame within Effects::prePaintWindow.
|
// the next frame within Effects::prePaintWindow.
|
||||||
topw->resetRepaints();
|
w->resetRepaints(painted_screen);
|
||||||
|
|
||||||
WindowPrePaintData data;
|
WindowPrePaintData data;
|
||||||
data.mask = orig_mask | (w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT);
|
data.mask = orig_mask | (w->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT);
|
||||||
|
@ -264,7 +272,7 @@ void Scene::paintSimpleScreen(int orig_mask, const QRegion ®ion)
|
||||||
data.mask = orig_mask | (window->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT);
|
data.mask = orig_mask | (window->isOpaque() ? PAINT_WINDOW_OPAQUE : PAINT_WINDOW_TRANSLUCENT);
|
||||||
window->resetPaintingEnabled();
|
window->resetPaintingEnabled();
|
||||||
data.paint = region;
|
data.paint = region;
|
||||||
data.paint |= toplevel->repaints();
|
data.paint |= window->repaints(painted_screen);
|
||||||
|
|
||||||
// Let the scene window update the window pixmap tree.
|
// Let the scene window update the window pixmap tree.
|
||||||
window->preprocess();
|
window->preprocess();
|
||||||
|
@ -272,7 +280,7 @@ void Scene::paintSimpleScreen(int orig_mask, const QRegion ®ion)
|
||||||
// Reset the repaint_region.
|
// Reset the repaint_region.
|
||||||
// This has to be done here because many effects schedule a repaint for
|
// This has to be done here because many effects schedule a repaint for
|
||||||
// the next frame within Effects::prePaintWindow.
|
// the next frame within Effects::prePaintWindow.
|
||||||
toplevel->resetRepaints();
|
window->resetRepaints(painted_screen);
|
||||||
|
|
||||||
// Clip out the decoration for opaque windows; the decoration is drawn in the second pass
|
// Clip out the decoration for opaque windows; the decoration is drawn in the second pass
|
||||||
opaqueFullscreen = false; // TODO: do we care about unmanged windows here (maybe input windows?)
|
opaqueFullscreen = false; // TODO: do we care about unmanged windows here (maybe input windows?)
|
||||||
|
@ -735,10 +743,22 @@ Scene::Window::Window(Toplevel *client, QObject *parent)
|
||||||
, disable_painting(0)
|
, disable_painting(0)
|
||||||
, cached_quad_list(nullptr)
|
, cached_quad_list(nullptr)
|
||||||
{
|
{
|
||||||
|
const Scene *scene = Compositor::self()->scene();
|
||||||
|
if (scene->isPerScreenRenderingEnabled()) {
|
||||||
|
connect(screens(), &Screens::countChanged, this, &Window::reallocRepaints);
|
||||||
|
}
|
||||||
|
reallocRepaints();
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::Window::~Window()
|
Scene::Window::~Window()
|
||||||
{
|
{
|
||||||
|
for (int i = 0; i < m_repaints.count(); ++i) {
|
||||||
|
const QRegion dirty = repaints(i);
|
||||||
|
if (!dirty.isEmpty()) {
|
||||||
|
Compositor::self()->addRepaint(dirty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete m_shadow;
|
delete m_shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,6 +1129,64 @@ void Scene::Window::preprocess()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scene::Window::addRepaint(const QRegion ®ion)
|
||||||
|
{
|
||||||
|
for (int screen = 0; screen < m_repaints.count(); ++screen) {
|
||||||
|
m_repaints[screen] += region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::Window::addLayerRepaint(const QRegion ®ion)
|
||||||
|
{
|
||||||
|
for (int screen = 0; screen < m_layerRepaints.count(); ++screen) {
|
||||||
|
m_layerRepaints[screen] += region;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegion Scene::Window::repaints(int screen) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(!m_repaints.isEmpty() && !m_layerRepaints.isEmpty());
|
||||||
|
const int index = screen != -1 ? screen : 0;
|
||||||
|
if (m_repaints[index] == infiniteRegion() || m_layerRepaints[index] == infiniteRegion()) {
|
||||||
|
return QRect(QPoint(0, 0), screens()->size());
|
||||||
|
}
|
||||||
|
return m_repaints[index].translated(pos()) + m_layerRepaints[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::Window::resetRepaints(int screen)
|
||||||
|
{
|
||||||
|
Q_ASSERT(!m_repaints.isEmpty() && !m_layerRepaints.isEmpty());
|
||||||
|
const int index = screen != -1 ? screen : 0;
|
||||||
|
m_repaints[index] = QRegion();
|
||||||
|
m_layerRepaints[index] = QRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::Window::reallocRepaints()
|
||||||
|
{
|
||||||
|
const Scene *scene = Compositor::self()->scene();
|
||||||
|
if (scene->isPerScreenRenderingEnabled()) {
|
||||||
|
m_repaints.resize(screens()->count());
|
||||||
|
m_layerRepaints.resize(screens()->count());
|
||||||
|
} else {
|
||||||
|
m_repaints.resize(1);
|
||||||
|
m_layerRepaints.resize(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_repaints.fill(infiniteRegion());
|
||||||
|
m_layerRepaints.fill(infiniteRegion());
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool wantsRepaint_test(const QRegion ®ion)
|
||||||
|
{
|
||||||
|
return !region.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scene::Window::wantsRepaint() const
|
||||||
|
{
|
||||||
|
return std::any_of(m_repaints.begin(), m_repaints.end(), wantsRepaint_test) ||
|
||||||
|
std::any_of(m_layerRepaints.begin(), m_layerRepaints.end(), wantsRepaint_test);
|
||||||
|
}
|
||||||
|
|
||||||
//****************************************
|
//****************************************
|
||||||
// WindowPixmap
|
// WindowPixmap
|
||||||
//****************************************
|
//****************************************
|
||||||
|
|
14
scene.h
14
scene.h
|
@ -136,6 +136,7 @@ public:
|
||||||
virtual bool blocksForRetrace() const;
|
virtual bool blocksForRetrace() const;
|
||||||
virtual bool syncsToVBlank() const;
|
virtual bool syncsToVBlank() const;
|
||||||
virtual OverlayWindow* overlayWindow() const = 0;
|
virtual OverlayWindow* overlayWindow() const = 0;
|
||||||
|
bool isPerScreenRenderingEnabled() const;
|
||||||
|
|
||||||
virtual bool makeOpenGLContextCurrent();
|
virtual bool makeOpenGLContextCurrent();
|
||||||
virtual void doneOpenGLContextCurrent();
|
virtual void doneOpenGLContextCurrent();
|
||||||
|
@ -202,6 +203,7 @@ public Q_SLOTS:
|
||||||
void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted);
|
void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted);
|
||||||
protected:
|
protected:
|
||||||
virtual Window *createWindow(Toplevel *toplevel) = 0;
|
virtual Window *createWindow(Toplevel *toplevel) = 0;
|
||||||
|
void setPerScreenRenderingEnabled(bool enabled);
|
||||||
void createStackingOrder(const QList<Toplevel *> &toplevels);
|
void createStackingOrder(const QList<Toplevel *> &toplevels);
|
||||||
void clearStackingOrder();
|
void clearStackingOrder();
|
||||||
// shared implementation, starts painting the screen
|
// shared implementation, starts painting the screen
|
||||||
|
@ -262,6 +264,8 @@ protected:
|
||||||
// time since last repaint
|
// time since last repaint
|
||||||
int time_diff;
|
int time_diff;
|
||||||
QElapsedTimer last_time;
|
QElapsedTimer last_time;
|
||||||
|
// The screen that is being currently painted
|
||||||
|
int painted_screen = -1;
|
||||||
private:
|
private:
|
||||||
void paintWindowThumbnails(Scene::Window *w, const QRegion ®ion, qreal opacity, qreal brightness, qreal saturation);
|
void paintWindowThumbnails(Scene::Window *w, const QRegion ®ion, qreal opacity, qreal brightness, qreal saturation);
|
||||||
void paintDesktopThumbnails(Scene::Window *w);
|
void paintDesktopThumbnails(Scene::Window *w);
|
||||||
|
@ -270,6 +274,7 @@ private:
|
||||||
QVector< Window* > stacking_order;
|
QVector< Window* > stacking_order;
|
||||||
// how many times finalPaintScreen() has been called
|
// how many times finalPaintScreen() has been called
|
||||||
int m_paintScreenCount = 0;
|
int m_paintScreenCount = 0;
|
||||||
|
bool m_isPerScreenRenderingEnabled = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -354,6 +359,11 @@ public:
|
||||||
void unreferencePreviousPixmap();
|
void unreferencePreviousPixmap();
|
||||||
void discardQuads();
|
void discardQuads();
|
||||||
void preprocess();
|
void preprocess();
|
||||||
|
void addRepaint(const QRegion ®ion);
|
||||||
|
void addLayerRepaint(const QRegion ®ion);
|
||||||
|
QRegion repaints(int screen) const;
|
||||||
|
void resetRepaints(int screen);
|
||||||
|
bool wantsRepaint() const;
|
||||||
|
|
||||||
virtual QSharedPointer<GLTexture> windowTexture() {
|
virtual QSharedPointer<GLTexture> windowTexture() {
|
||||||
return {};
|
return {};
|
||||||
|
@ -391,8 +401,12 @@ protected:
|
||||||
ImageFilterType filter;
|
ImageFilterType filter;
|
||||||
Shadow *m_shadow;
|
Shadow *m_shadow;
|
||||||
private:
|
private:
|
||||||
|
void reallocRepaints();
|
||||||
|
|
||||||
QScopedPointer<WindowPixmap> m_currentPixmap;
|
QScopedPointer<WindowPixmap> m_currentPixmap;
|
||||||
QScopedPointer<WindowPixmap> m_previousPixmap;
|
QScopedPointer<WindowPixmap> m_previousPixmap;
|
||||||
|
QVector<QRegion> m_repaints;
|
||||||
|
QVector<QRegion> m_layerRepaints;
|
||||||
int m_referencePixmapCounter;
|
int m_referencePixmapCounter;
|
||||||
int disable_painting;
|
int disable_painting;
|
||||||
mutable QRegion m_bufferShape;
|
mutable QRegion m_bufferShape;
|
||||||
|
|
79
toplevel.cpp
79
toplevel.cpp
|
@ -113,8 +113,6 @@ void Toplevel::copyToDeleted(Toplevel* c)
|
||||||
ready_for_painting = c->ready_for_painting;
|
ready_for_painting = c->ready_for_painting;
|
||||||
damage_handle = XCB_NONE;
|
damage_handle = XCB_NONE;
|
||||||
damage_region = c->damage_region;
|
damage_region = c->damage_region;
|
||||||
repaints_region = c->repaints_region;
|
|
||||||
layer_repaints_region = c->layer_repaints_region;
|
|
||||||
is_shape = c->is_shape;
|
is_shape = c->is_shape;
|
||||||
effect_window = c->effect_window;
|
effect_window = c->effect_window;
|
||||||
if (effect_window != nullptr)
|
if (effect_window != nullptr)
|
||||||
|
@ -311,7 +309,6 @@ void Toplevel::finishCompositing(ReleaseReason releaseReason)
|
||||||
|
|
||||||
damage_handle = XCB_NONE;
|
damage_handle = XCB_NONE;
|
||||||
damage_region = QRegion();
|
damage_region = QRegion();
|
||||||
repaints_region = QRegion();
|
|
||||||
effect_window = nullptr;
|
effect_window = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +401,7 @@ void Toplevel::getDamageRegionReply()
|
||||||
const QRect frameRect = frameGeometry();
|
const QRect frameRect = frameGeometry();
|
||||||
|
|
||||||
damage_region += region;
|
damage_region += region;
|
||||||
repaints_region += region.translated(bufferRect.topLeft() - frameRect.topLeft());
|
addRepaint(region.translated(bufferRect.topLeft() - frameRect.topLeft()));
|
||||||
|
|
||||||
free(reply);
|
free(reply);
|
||||||
}
|
}
|
||||||
|
@ -423,7 +420,7 @@ void Toplevel::addDamageFull()
|
||||||
const QRect damagedRect(0, 0, bufferRect.width(), bufferRect.height());
|
const QRect damagedRect(0, 0, bufferRect.width(), bufferRect.height());
|
||||||
|
|
||||||
damage_region = damagedRect;
|
damage_region = damagedRect;
|
||||||
repaints_region |= damagedRect.translated(offsetX, offsetY);
|
addRepaint(damagedRect.translated(offsetX, offsetY));
|
||||||
|
|
||||||
emit damaged(this, damage_region);
|
emit damaged(this, damage_region);
|
||||||
}
|
}
|
||||||
|
@ -433,63 +430,47 @@ void Toplevel::resetDamage()
|
||||||
damage_region = QRegion();
|
damage_region = QRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toplevel::addRepaint(const QRect& r)
|
void Toplevel::addRepaint(const QRect &rect)
|
||||||
{
|
{
|
||||||
if (!compositing()) {
|
addRepaint(QRegion(rect));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Toplevel::addRepaint(int x, int y, int width, int height)
|
||||||
|
{
|
||||||
|
addRepaint(QRegion(x, y, width, height));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Toplevel::addRepaint(const QRegion ®ion)
|
||||||
|
{
|
||||||
|
if (!effectWindow() || !effectWindow()->sceneWindow()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
repaints_region += r;
|
effectWindow()->sceneWindow()->addRepaint(region);
|
||||||
emit needsRepaint();
|
emit needsRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toplevel::addRepaint(int x, int y, int w, int h)
|
void Toplevel::addLayerRepaint(const QRect &rect)
|
||||||
{
|
{
|
||||||
QRect r(x, y, w, h);
|
addLayerRepaint(QRegion(rect));
|
||||||
addRepaint(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toplevel::addRepaint(const QRegion& r)
|
void Toplevel::addLayerRepaint(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
if (!compositing()) {
|
addLayerRepaint(QRegion(x, y, width, height));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Toplevel::addLayerRepaint(const QRegion ®ion)
|
||||||
|
{
|
||||||
|
if (!effectWindow() || !effectWindow()->sceneWindow()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
repaints_region += r;
|
effectWindow()->sceneWindow()->addLayerRepaint(region);
|
||||||
emit needsRepaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toplevel::addLayerRepaint(const QRect& r)
|
|
||||||
{
|
|
||||||
if (!compositing()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
layer_repaints_region += r;
|
|
||||||
emit needsRepaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toplevel::addLayerRepaint(int x, int y, int w, int h)
|
|
||||||
{
|
|
||||||
QRect r(x, y, w, h);
|
|
||||||
addLayerRepaint(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toplevel::addLayerRepaint(const QRegion& r)
|
|
||||||
{
|
|
||||||
if (!compositing())
|
|
||||||
return;
|
|
||||||
layer_repaints_region += r;
|
|
||||||
emit needsRepaint();
|
emit needsRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toplevel::addRepaintFull()
|
void Toplevel::addRepaintFull()
|
||||||
{
|
{
|
||||||
repaints_region = visibleRect().translated(-pos());
|
addRepaint(visibleRect().translated(-pos()));
|
||||||
emit needsRepaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Toplevel::resetRepaints()
|
|
||||||
{
|
|
||||||
repaints_region = QRegion();
|
|
||||||
layer_repaints_region = QRegion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Toplevel::addWorkspaceRepaint(int x, int y, int w, int h)
|
void Toplevel::addWorkspaceRepaint(int x, int y, int w, int h)
|
||||||
|
@ -511,6 +492,14 @@ void Toplevel::addWorkspaceRepaint(const QRegion ®ion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Toplevel::wantsRepaint() const
|
||||||
|
{
|
||||||
|
if (!effectWindow() || !effectWindow()->sceneWindow()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return effectWindow()->sceneWindow()->wantsRepaint();
|
||||||
|
}
|
||||||
|
|
||||||
void Toplevel::setReadyForPainting()
|
void Toplevel::setReadyForPainting()
|
||||||
{
|
{
|
||||||
if (!ready_for_painting) {
|
if (!ready_for_painting) {
|
||||||
|
|
10
toplevel.h
10
toplevel.h
|
@ -467,8 +467,7 @@ public:
|
||||||
void addWorkspaceRepaint(const QRect& r);
|
void addWorkspaceRepaint(const QRect& r);
|
||||||
void addWorkspaceRepaint(int x, int y, int w, int h);
|
void addWorkspaceRepaint(int x, int y, int w, int h);
|
||||||
void addWorkspaceRepaint(const QRegion ®ion);
|
void addWorkspaceRepaint(const QRegion ®ion);
|
||||||
QRegion repaints() const;
|
bool wantsRepaint() const;
|
||||||
void resetRepaints();
|
|
||||||
QRegion damage() const;
|
QRegion damage() const;
|
||||||
void resetDamage();
|
void resetDamage();
|
||||||
EffectWindowImpl* effectWindow();
|
EffectWindowImpl* effectWindow();
|
||||||
|
@ -734,8 +733,6 @@ protected:
|
||||||
int bit_depth;
|
int bit_depth;
|
||||||
NETWinInfo* info;
|
NETWinInfo* info;
|
||||||
bool ready_for_painting;
|
bool ready_for_painting;
|
||||||
QRegion repaints_region; // updating, repaint just requires repaint of that area
|
|
||||||
QRegion layer_repaints_region;
|
|
||||||
/**
|
/**
|
||||||
* An FBO object KWin internal windows might render to.
|
* An FBO object KWin internal windows might render to.
|
||||||
*/
|
*/
|
||||||
|
@ -939,11 +936,6 @@ inline QRegion Toplevel::damage() const
|
||||||
return damage_region;
|
return damage_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QRegion Toplevel::repaints() const
|
|
||||||
{
|
|
||||||
return repaints_region.translated(pos()) | layer_repaints_region;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Toplevel::shape() const
|
inline bool Toplevel::shape() const
|
||||||
{
|
{
|
||||||
return is_shape;
|
return is_shape;
|
||||||
|
|
|
@ -165,7 +165,7 @@ bool Unmanaged::isOutline() const
|
||||||
|
|
||||||
void Unmanaged::addDamage(const QRegion &damage)
|
void Unmanaged::addDamage(const QRegion &damage)
|
||||||
{
|
{
|
||||||
repaints_region += damage;
|
addRepaint(damage);
|
||||||
Toplevel::addDamage(damage);
|
Toplevel::addDamage(damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2792,7 +2792,7 @@ void X11Client::addDamage(const QRegion &damage)
|
||||||
setupWindowManagementInterface();
|
setupWindowManagementInterface();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
repaints_region += damage.translated(bufferGeometry().topLeft() - frameGeometry().topLeft());
|
addRepaint(damage.translated(bufferGeometry().topLeft() - frameGeometry().topLeft()));
|
||||||
Toplevel::addDamage(damage);
|
Toplevel::addDamage(damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,7 @@ void XdgSurfaceClient::addDamage(const QRegion &damage)
|
||||||
{
|
{
|
||||||
const int offsetX = bufferGeometry().x() - frameGeometry().x();
|
const int offsetX = bufferGeometry().x() - frameGeometry().x();
|
||||||
const int offsetY = bufferGeometry().y() - frameGeometry().y();
|
const int offsetY = bufferGeometry().y() - frameGeometry().y();
|
||||||
repaints_region += damage.translated(offsetX, offsetY);
|
addRepaint(damage.translated(offsetX, offsetY));
|
||||||
Toplevel::addDamage(damage);
|
Toplevel::addDamage(damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue