Move Scene::Window handling methods into base class
The pure virtual methods windowAdded, windowClosed, windowDeleted and windowGeometryShapeChanged had identical implementations in both XRender and OpenGL scene. They were accessing the hash with Scene::Windows which is nowhere else used except for creating the stacking order in ::paint. The implementations are moved to the base class, the only Scene specific code is a pure virtual factory method to create the Scene window. This already existed in SceneOpenGL to create either a SceneOpenGL1 or 2 window. Also the hash of windows is a Scene private member now and the creation of the stacking order is provided by a method, so that the Scene sub classes do no longer need to access the stacking order at all. REVIEW: 111207
This commit is contained in:
parent
1a0e586b9c
commit
ef4c32f79a
6 changed files with 88 additions and 126 deletions
61
scene.cpp
61
scene.cpp
|
@ -98,6 +98,9 @@ Scene::Scene(Workspace* ws)
|
|||
|
||||
Scene::~Scene()
|
||||
{
|
||||
foreach (Window *w, m_windows) {
|
||||
delete w;
|
||||
}
|
||||
}
|
||||
|
||||
// returns mask and possibly modified region
|
||||
|
@ -391,6 +394,64 @@ void Scene::paintSimpleScreen(int orig_mask, QRegion region)
|
|||
}
|
||||
}
|
||||
|
||||
void Scene::windowAdded(Toplevel *c)
|
||||
{
|
||||
assert(!m_windows.contains(c));
|
||||
Scene::Window *w = createWindow(c);
|
||||
m_windows[ c ] = w;
|
||||
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), SLOT(windowGeometryShapeChanged(KWin::Toplevel*)));
|
||||
connect(c, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), SLOT(windowClosed(KWin::Toplevel*,KWin::Deleted*)));
|
||||
c->effectWindow()->setSceneWindow(w);
|
||||
c->getShadow();
|
||||
w->updateShadow(c->shadow());
|
||||
}
|
||||
|
||||
void Scene::windowClosed(Toplevel *c, Deleted *deleted)
|
||||
{
|
||||
assert(m_windows.contains(c));
|
||||
if (deleted != NULL) {
|
||||
// replace c with deleted
|
||||
Window* w = m_windows.take(c);
|
||||
w->updateToplevel(deleted);
|
||||
if (w->shadow()) {
|
||||
w->shadow()->setToplevel(deleted);
|
||||
}
|
||||
m_windows[ deleted ] = w;
|
||||
} else {
|
||||
delete m_windows.take(c);
|
||||
c->effectWindow()->setSceneWindow(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::windowDeleted(Deleted *c)
|
||||
{
|
||||
assert(m_windows.contains(c));
|
||||
delete m_windows.take(c);
|
||||
c->effectWindow()->setSceneWindow(NULL);
|
||||
}
|
||||
|
||||
void Scene::windowGeometryShapeChanged(Toplevel *c)
|
||||
{
|
||||
if (!m_windows.contains(c)) // this is ok, shape is not valid by default
|
||||
return;
|
||||
Window *w = m_windows[ c ];
|
||||
w->discardShape();
|
||||
}
|
||||
|
||||
void Scene::createStackingOrder(ToplevelList toplevels)
|
||||
{
|
||||
// TODO: cache the stacking_order in case it has not changed
|
||||
foreach (Toplevel *c, toplevels) {
|
||||
assert(m_windows.contains(c));
|
||||
stacking_order.append(m_windows[ c ]);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::clearStackingOrder()
|
||||
{
|
||||
stacking_order.clear();
|
||||
}
|
||||
|
||||
static Scene::Window *s_recursionCheck = NULL;
|
||||
|
||||
void Scene::paintWindow(Window* w, int mask, QRegion region, WindowQuadList quads)
|
||||
|
|
16
scene.h
16
scene.h
|
@ -65,7 +65,7 @@ public:
|
|||
// Used to mainly discard cached data.
|
||||
|
||||
// a new window has been created
|
||||
virtual void windowAdded(Toplevel*) = 0;
|
||||
void windowAdded(Toplevel*);
|
||||
/**
|
||||
* @brief Creates the Scene backend of an EffectFrame.
|
||||
*
|
||||
|
@ -123,12 +123,15 @@ public:
|
|||
|
||||
public Q_SLOTS:
|
||||
// a window has been destroyed
|
||||
virtual void windowDeleted(KWin::Deleted*) = 0;
|
||||
void windowDeleted(KWin::Deleted*);
|
||||
// shape/size of a window changed
|
||||
virtual void windowGeometryShapeChanged(KWin::Toplevel* c) = 0;
|
||||
void windowGeometryShapeChanged(KWin::Toplevel* c);
|
||||
// a window has been closed
|
||||
virtual void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted) = 0;
|
||||
void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted);
|
||||
protected:
|
||||
virtual Window *createWindow(Toplevel *toplevel) = 0;
|
||||
void createStackingOrder(ToplevelList toplevels);
|
||||
void clearStackingOrder();
|
||||
// shared implementation, starts painting the screen
|
||||
void paintScreen(int *mask, const QRegion &damage, const QRegion &repaint,
|
||||
QRegion *updateRegion, QRegion *validRegion);
|
||||
|
@ -168,8 +171,6 @@ protected:
|
|||
int mask;
|
||||
WindowQuadList quads;
|
||||
};
|
||||
// windows in their stacking order
|
||||
QVector< Window* > stacking_order;
|
||||
// The region which actually has been painted by paintScreen() and should be
|
||||
// copied from the buffer to the screen. I.e. the region returned from Scene::paintScreen().
|
||||
// Since prePaintWindow() can extend areas to paint, these changes would have to propagate
|
||||
|
@ -187,6 +188,9 @@ protected:
|
|||
private:
|
||||
void paintWindowThumbnails(Scene::Window *w, QRegion region, qreal opacity, qreal brightness, qreal saturation);
|
||||
void paintDesktopThumbnails(Scene::Window *w);
|
||||
QHash< Toplevel*, Window* > m_windows;
|
||||
// windows in their stacking order
|
||||
QVector< Window* > stacking_order;
|
||||
};
|
||||
|
||||
// The base class for windows representations in composite backends
|
||||
|
|
|
@ -182,9 +182,6 @@ SceneOpenGL::~SceneOpenGL()
|
|||
// backend might be still needed for a different scene
|
||||
delete m_backend;
|
||||
}
|
||||
foreach (Window * w, windows) {
|
||||
delete w;
|
||||
}
|
||||
// do cleanup after initBuffer()
|
||||
SceneOpenGL::EffectFrame::cleanup();
|
||||
checkGLError("Cleanup");
|
||||
|
@ -360,11 +357,7 @@ void SceneOpenGL::handleGraphicsReset(GLenum status)
|
|||
qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
|
||||
{
|
||||
// actually paint the frame, flushed with the NEXT frame
|
||||
foreach (Toplevel * c, toplevels) {
|
||||
// TODO: cache the stacking_order in case it has not changed
|
||||
assert(windows.contains(c));
|
||||
stacking_order.append(windows[ c ]);
|
||||
}
|
||||
createStackingOrder(toplevels);
|
||||
|
||||
m_backend->makeCurrent();
|
||||
QRegion repaint = m_backend->prepareRenderingFrame();
|
||||
|
@ -409,7 +402,7 @@ qint64 SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
|
|||
m_backend->endRenderingFrame(validRegion, updateRegion);
|
||||
|
||||
// do cleanup
|
||||
stacking_order.clear();
|
||||
clearStackingOrder();
|
||||
checkGLError("PostPaint");
|
||||
return m_backend->renderTime();
|
||||
}
|
||||
|
@ -487,51 +480,6 @@ void SceneOpenGL::extendPaintRegion(QRegion ®ion, bool opaqueFullscreen)
|
|||
}
|
||||
}
|
||||
|
||||
void SceneOpenGL::windowAdded(Toplevel* c)
|
||||
{
|
||||
assert(!windows.contains(c));
|
||||
Window *w = createWindow(c);
|
||||
windows[ c ] = w;
|
||||
w->setScene(this);
|
||||
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), SLOT(windowGeometryShapeChanged(KWin::Toplevel*)));
|
||||
connect(c, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), SLOT(windowClosed(KWin::Toplevel*,KWin::Deleted*)));
|
||||
c->effectWindow()->setSceneWindow(windows[ c ]);
|
||||
c->getShadow();
|
||||
windows[ c ]->updateShadow(c->shadow());
|
||||
}
|
||||
|
||||
void SceneOpenGL::windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted)
|
||||
{
|
||||
assert(windows.contains(c));
|
||||
if (deleted != NULL) {
|
||||
// replace c with deleted
|
||||
Window* w = windows.take(c);
|
||||
w->updateToplevel(deleted);
|
||||
if (w->shadow()) {
|
||||
w->shadow()->setToplevel(deleted);
|
||||
}
|
||||
windows[ deleted ] = w;
|
||||
} else {
|
||||
delete windows.take(c);
|
||||
c->effectWindow()->setSceneWindow(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneOpenGL::windowDeleted(Deleted* c)
|
||||
{
|
||||
assert(windows.contains(c));
|
||||
delete windows.take(c);
|
||||
c->effectWindow()->setSceneWindow(NULL);
|
||||
}
|
||||
|
||||
void SceneOpenGL::windowGeometryShapeChanged(KWin::Toplevel* c)
|
||||
{
|
||||
if (!windows.contains(c)) // this is ok, shape is not valid
|
||||
return; // by default
|
||||
Window* w = windows[ c ];
|
||||
w->discardShape();
|
||||
}
|
||||
|
||||
SceneOpenGL::Texture *SceneOpenGL::createTexture()
|
||||
{
|
||||
return new Texture(m_backend);
|
||||
|
@ -754,9 +702,11 @@ void SceneOpenGL2::doPaintBackground(const QVector< float >& vertices)
|
|||
vbo->render(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
SceneOpenGL::Window *SceneOpenGL2::createWindow(Toplevel *t)
|
||||
Scene::Window *SceneOpenGL2::createWindow(Toplevel *t)
|
||||
{
|
||||
return new SceneOpenGL2Window(t);
|
||||
SceneOpenGL2Window *w = new SceneOpenGL2Window(t);
|
||||
w->setScene(this);
|
||||
return w;
|
||||
}
|
||||
|
||||
void SceneOpenGL2::finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data)
|
||||
|
@ -925,9 +875,11 @@ void SceneOpenGL1::screenGeometryChanged(const QSize &size)
|
|||
m_resetModelViewProjectionMatrix = true;
|
||||
}
|
||||
|
||||
SceneOpenGL::Window *SceneOpenGL1::createWindow(Toplevel *t)
|
||||
Scene::Window *SceneOpenGL1::createWindow(Toplevel *t)
|
||||
{
|
||||
return new SceneOpenGL1Window(t);
|
||||
SceneOpenGL1Window *w = new SceneOpenGL1Window(t);
|
||||
w->setScene(this);
|
||||
return w;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -48,8 +48,6 @@ public:
|
|||
virtual bool initFailed() const;
|
||||
virtual bool hasPendingFlush() const;
|
||||
virtual qint64 paint(QRegion damage, ToplevelList windows);
|
||||
virtual void windowAdded(Toplevel*);
|
||||
virtual void windowDeleted(Deleted*);
|
||||
virtual Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame);
|
||||
virtual Shadow *createShadow(Toplevel *toplevel);
|
||||
virtual void screenGeometryChanged(const QSize &size);
|
||||
|
@ -90,20 +88,15 @@ protected:
|
|||
void handleGraphicsReset(GLenum status);
|
||||
|
||||
virtual void doPaintBackground(const QVector<float> &vertices) = 0;
|
||||
virtual SceneOpenGL::Window *createWindow(Toplevel *t) = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void resetCompositing();
|
||||
|
||||
public Q_SLOTS:
|
||||
virtual void windowGeometryShapeChanged(KWin::Toplevel* c);
|
||||
virtual void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted);
|
||||
protected:
|
||||
bool init_ok;
|
||||
private:
|
||||
bool viewportLimitsMatched(const QSize &size) const;
|
||||
private:
|
||||
QHash< Toplevel*, Window* > windows;
|
||||
bool m_debug;
|
||||
OpenGLBackend *m_backend;
|
||||
};
|
||||
|
@ -125,7 +118,7 @@ public:
|
|||
protected:
|
||||
virtual void paintGenericScreen(int mask, ScreenPaintData data);
|
||||
virtual void doPaintBackground(const QVector< float >& vertices);
|
||||
virtual SceneOpenGL::Window *createWindow(Toplevel *t);
|
||||
virtual Scene::Window *createWindow(Toplevel *t);
|
||||
virtual void finalDrawWindow(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data);
|
||||
virtual void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data);
|
||||
|
||||
|
@ -159,7 +152,7 @@ public:
|
|||
protected:
|
||||
virtual void paintGenericScreen(int mask, ScreenPaintData data);
|
||||
virtual void doPaintBackground(const QVector< float >& vertices);
|
||||
virtual SceneOpenGL::Window *createWindow(Toplevel *t);
|
||||
virtual Scene::Window *createWindow(Toplevel *t);
|
||||
|
||||
private:
|
||||
void setupModelViewProjectionMatrix();
|
||||
|
|
|
@ -120,8 +120,6 @@ SceneXrender::~SceneXrender()
|
|||
xcb_render_free_picture(connection(), buffer);
|
||||
buffer = XCB_RENDER_PICTURE_NONE;
|
||||
m_overlayWindow->destroy();
|
||||
foreach (Window * w, windows)
|
||||
delete w;
|
||||
delete m_overlayWindow;
|
||||
}
|
||||
|
||||
|
@ -185,10 +183,7 @@ qint64 SceneXrender::paint(QRegion damage, ToplevelList toplevels)
|
|||
QElapsedTimer renderTimer;
|
||||
renderTimer.start();
|
||||
|
||||
foreach (Toplevel * c, toplevels) {
|
||||
assert(windows.contains(c));
|
||||
stacking_order.append(windows[ c ]);
|
||||
}
|
||||
createStackingOrder(toplevels);
|
||||
|
||||
int mask = 0;
|
||||
QRegion updateRegion, validRegion;
|
||||
|
@ -199,7 +194,7 @@ qint64 SceneXrender::paint(QRegion damage, ToplevelList toplevels)
|
|||
|
||||
present(mask, updateRegion);
|
||||
// do cleanup
|
||||
stacking_order.clear();
|
||||
clearStackingOrder();
|
||||
|
||||
return renderTimer.nsecsElapsed();
|
||||
}
|
||||
|
@ -245,47 +240,9 @@ void SceneXrender::paintBackground(QRegion region)
|
|||
xcb_render_fill_rectangles(connection(), XCB_RENDER_PICT_OP_SRC, buffer, col, rects.count(), rects.data());
|
||||
}
|
||||
|
||||
void SceneXrender::windowGeometryShapeChanged(KWin::Toplevel* c)
|
||||
Scene::Window *SceneXrender::createWindow(Toplevel *toplevel)
|
||||
{
|
||||
if (!windows.contains(c)) // this is ok, shape is not valid by default
|
||||
return;
|
||||
Window* w = windows[ c ];
|
||||
w->discardShape();
|
||||
}
|
||||
|
||||
void SceneXrender::windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted)
|
||||
{
|
||||
assert(windows.contains(c));
|
||||
if (deleted != NULL) {
|
||||
// replace c with deleted
|
||||
Window* w = windows.take(c);
|
||||
w->updateToplevel(deleted);
|
||||
if (w->shadow()) {
|
||||
w->shadow()->setToplevel(deleted);
|
||||
}
|
||||
windows[ deleted ] = w;
|
||||
} else {
|
||||
delete windows.take(c);
|
||||
c->effectWindow()->setSceneWindow(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneXrender::windowDeleted(Deleted* c)
|
||||
{
|
||||
assert(windows.contains(c));
|
||||
delete windows.take(c);
|
||||
c->effectWindow()->setSceneWindow(NULL);
|
||||
}
|
||||
|
||||
void SceneXrender::windowAdded(Toplevel* c)
|
||||
{
|
||||
assert(!windows.contains(c));
|
||||
windows[ c ] = new Window(c);
|
||||
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), SLOT(windowGeometryShapeChanged(KWin::Toplevel*)));
|
||||
connect(c, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), SLOT(windowClosed(KWin::Toplevel*,KWin::Deleted*)));
|
||||
c->effectWindow()->setSceneWindow(windows[ c ]);
|
||||
c->getShadow();
|
||||
windows[ c ]->updateShadow(c->shadow());
|
||||
return new Window(toplevel);
|
||||
}
|
||||
|
||||
Scene::EffectFrame *SceneXrender::createEffectFrame(EffectFrameImpl *frame)
|
||||
|
|
|
@ -43,8 +43,6 @@ public:
|
|||
return XRenderCompositing;
|
||||
}
|
||||
virtual qint64 paint(QRegion damage, ToplevelList windows);
|
||||
virtual void windowAdded(Toplevel*);
|
||||
virtual void windowDeleted(Deleted*);
|
||||
virtual Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame);
|
||||
virtual Shadow *createShadow(Toplevel *toplevel);
|
||||
virtual void screenGeometryChanged(const QSize &size);
|
||||
|
@ -53,12 +51,10 @@ public:
|
|||
return m_overlayWindow;
|
||||
}
|
||||
protected:
|
||||
virtual Scene::Window *createWindow(Toplevel *toplevel);
|
||||
virtual void paintBackground(QRegion region);
|
||||
virtual void paintGenericScreen(int mask, ScreenPaintData data);
|
||||
virtual void paintDesktop(int desktop, int mask, const QRegion ®ion, ScreenPaintData &data);
|
||||
public Q_SLOTS:
|
||||
virtual void windowGeometryShapeChanged(KWin::Toplevel* c);
|
||||
virtual void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted);
|
||||
private:
|
||||
void createBuffer();
|
||||
void present(int mask, QRegion damage);
|
||||
|
@ -68,7 +64,6 @@ private:
|
|||
static xcb_render_picture_t buffer;
|
||||
static ScreenPaintData screen_paint;
|
||||
class Window;
|
||||
QHash< Toplevel*, Window* > windows;
|
||||
OverlayWindow* m_overlayWindow;
|
||||
bool init_ok;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue