Move paint method from SceneWindow to Scene
That's the next step in allowing to reuse surface painting code between the workspace and the cursor layer.
This commit is contained in:
parent
683a222233
commit
bc1f808f0f
11 changed files with 65 additions and 131 deletions
|
@ -198,6 +198,11 @@ DecorationRenderer *DecorationItem::renderer() const
|
|||
return m_renderer.data();
|
||||
}
|
||||
|
||||
Window *DecorationItem::window() const
|
||||
{
|
||||
return m_window;
|
||||
}
|
||||
|
||||
WindowQuad buildQuad(const QRect &partRect, const QPoint &textureOffset,
|
||||
const qreal devicePixelRatio, bool rotated)
|
||||
{
|
||||
|
|
|
@ -81,6 +81,7 @@ public:
|
|||
explicit DecorationItem(KDecoration2::Decoration *decoration, Window *window, Item *parent = nullptr);
|
||||
|
||||
DecorationRenderer *renderer() const;
|
||||
Window *window() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void handleFrameGeometryChanged();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "windowscreencastsource.h"
|
||||
#include "screencastutils.h"
|
||||
|
||||
#include "composite.h"
|
||||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
#include "kwineffects.h"
|
||||
|
@ -16,6 +17,7 @@
|
|||
#include "renderloop.h"
|
||||
#include "scene.h"
|
||||
#include "window.h"
|
||||
#include "windowitem.h"
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -59,7 +61,7 @@ void WindowScreenCastSource::render(GLFramebuffer *target)
|
|||
GLFramebuffer::pushFramebuffer(target);
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_window->sceneWindow()->performPaint(Scene::PAINT_WINDOW_TRANSFORMED, infiniteRegion(), data);
|
||||
Compositor::self()->scene()->render(m_window->windowItem(), Scene::PAINT_WINDOW_TRANSFORMED, infiniteRegion(), data);
|
||||
GLFramebuffer::popFramebuffer();
|
||||
}
|
||||
|
||||
|
|
|
@ -600,7 +600,7 @@ void Scene::finalPaintWindow(EffectWindowImpl *w, int mask, const QRegion ®io
|
|||
// will be eventually called from drawWindow()
|
||||
void Scene::finalDrawWindow(EffectWindowImpl *w, int mask, const QRegion ®ion, WindowPaintData &data)
|
||||
{
|
||||
w->sceneWindow()->performPaint(mask, region, data);
|
||||
render(w->sceneWindow()->windowItem(), mask, region, data);
|
||||
}
|
||||
|
||||
bool Scene::makeOpenGLContextCurrent()
|
||||
|
|
15
src/scene.h
15
src/scene.h
|
@ -103,17 +103,6 @@ public:
|
|||
void postPaint();
|
||||
virtual void paint(RenderTarget *renderTarget, const QRegion ®ion) = 0;
|
||||
|
||||
/**
|
||||
* Adds the Window to the Scene.
|
||||
*
|
||||
* If the window gets deleted, then the scene will try automatically
|
||||
* to re-bind an underlying scene window to the corresponding Deleted.
|
||||
*
|
||||
* @param window The window to be added.
|
||||
* @note You can add a window to scene only once.
|
||||
*/
|
||||
virtual SceneWindow *createWindow(Window *window) = 0;
|
||||
|
||||
/**
|
||||
* @brief Creates the Scene backend of an EffectFrame.
|
||||
*
|
||||
|
@ -197,6 +186,8 @@ public:
|
|||
|
||||
QRegion mapToRenderTarget(const QRegion ®ion) const;
|
||||
|
||||
virtual void render(Item *item, int mask, const QRegion ®ion, const WindowPaintData &data) = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void frameRendered();
|
||||
|
||||
|
@ -268,8 +259,6 @@ class SceneWindow : public QObject
|
|||
public:
|
||||
explicit SceneWindow(Window *client, QObject *parent = nullptr);
|
||||
~SceneWindow() override;
|
||||
// perform the actual painting of the window
|
||||
virtual void performPaint(int mask, const QRegion ®ion, const WindowPaintData &data) = 0;
|
||||
int x() const;
|
||||
int y() const;
|
||||
int width() const;
|
||||
|
|
|
@ -292,26 +292,7 @@ void SceneOpenGL::doPaintBackground(const QVector<float> &vertices)
|
|||
vbo->render(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
SceneWindow *SceneOpenGL::createWindow(Window *t)
|
||||
{
|
||||
return new OpenGLWindow(t, this);
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// OpenGLWindow
|
||||
//****************************************
|
||||
|
||||
OpenGLWindow::OpenGLWindow(Window *window, SceneOpenGL *scene)
|
||||
: SceneWindow(window)
|
||||
, m_scene(scene)
|
||||
{
|
||||
}
|
||||
|
||||
OpenGLWindow::~OpenGLWindow()
|
||||
{
|
||||
}
|
||||
|
||||
QVector4D OpenGLWindow::modulate(float opacity, float brightness) const
|
||||
QVector4D SceneOpenGL::modulate(float opacity, float brightness) const
|
||||
{
|
||||
const float a = opacity;
|
||||
const float rgb = opacity * brightness;
|
||||
|
@ -319,7 +300,7 @@ QVector4D OpenGLWindow::modulate(float opacity, float brightness) const
|
|||
return QVector4D(rgb, rgb, rgb, a);
|
||||
}
|
||||
|
||||
void OpenGLWindow::setBlendEnabled(bool enabled)
|
||||
void SceneOpenGL::setBlendEnabled(bool enabled)
|
||||
{
|
||||
if (enabled && !m_blendingEnabled) {
|
||||
glEnable(GL_BLEND);
|
||||
|
@ -359,7 +340,7 @@ static GLTexture *bindSurfaceTexture(SurfaceItem *surfaceItem)
|
|||
return platformSurfaceTexture->texture();
|
||||
}
|
||||
|
||||
static WindowQuadList clipQuads(const Item *item, const OpenGLWindow::RenderContext *context)
|
||||
static WindowQuadList clipQuads(const Item *item, const SceneOpenGL::RenderContext *context)
|
||||
{
|
||||
const WindowQuadList quads = item->quads();
|
||||
if (context->clip != infiniteRegion() && !context->hardwareClipping) {
|
||||
|
@ -390,7 +371,7 @@ static WindowQuadList clipQuads(const Item *item, const OpenGLWindow::RenderCont
|
|||
return quads;
|
||||
}
|
||||
|
||||
void OpenGLWindow::createRenderNode(Item *item, RenderContext *context)
|
||||
void SceneOpenGL::createRenderNode(Item *item, RenderContext *context)
|
||||
{
|
||||
const QList<Item *> sortedChildItems = item->sortedChildItems();
|
||||
|
||||
|
@ -466,7 +447,7 @@ void OpenGLWindow::createRenderNode(Item *item, RenderContext *context)
|
|||
context->transforms.pop();
|
||||
}
|
||||
|
||||
QMatrix4x4 OpenGLWindow::modelViewProjectionMatrix(int mask, const WindowPaintData &data) const
|
||||
QMatrix4x4 SceneOpenGL::modelViewProjectionMatrix(int mask, const WindowPaintData &data) const
|
||||
{
|
||||
const QMatrix4x4 pMatrix = data.projectionMatrix();
|
||||
const QMatrix4x4 mvMatrix = data.modelViewMatrix();
|
||||
|
@ -484,10 +465,10 @@ QMatrix4x4 OpenGLWindow::modelViewProjectionMatrix(int mask, const WindowPaintDa
|
|||
// with the default projection matrix. If the effect hasn't specified a
|
||||
// model-view matrix, mvMatrix will be the identity matrix.
|
||||
if (mask & Scene::PAINT_SCREEN_TRANSFORMED) {
|
||||
return m_scene->screenProjectionMatrix() * mvMatrix;
|
||||
return screenProjectionMatrix() * mvMatrix;
|
||||
}
|
||||
|
||||
return m_scene->renderTargetProjectionMatrix() * mvMatrix;
|
||||
return renderTargetProjectionMatrix() * mvMatrix;
|
||||
}
|
||||
|
||||
static QMatrix4x4 transformForPaintData(int mask, const WindowPaintData &data)
|
||||
|
@ -517,7 +498,7 @@ static QMatrix4x4 transformForPaintData(int mask, const WindowPaintData &data)
|
|||
return matrix;
|
||||
}
|
||||
|
||||
void OpenGLWindow::performPaint(int mask, const QRegion ®ion, const WindowPaintData &data)
|
||||
void SceneOpenGL::render(Item *item, int mask, const QRegion ®ion, const WindowPaintData &data)
|
||||
{
|
||||
if (region.isEmpty()) {
|
||||
return;
|
||||
|
@ -531,9 +512,9 @@ void OpenGLWindow::performPaint(int mask, const QRegion ®ion, const WindowPai
|
|||
|
||||
renderContext.transforms.push(QMatrix4x4());
|
||||
|
||||
windowItem()->setTransform(transformForPaintData(mask, data));
|
||||
item->setTransform(transformForPaintData(mask, data));
|
||||
|
||||
createRenderNode(windowItem(), &renderContext);
|
||||
createRenderNode(item, &renderContext);
|
||||
|
||||
int quadCount = 0;
|
||||
for (const RenderNode &node : qAsConst(renderContext.renderNodes)) {
|
||||
|
@ -605,7 +586,7 @@ void OpenGLWindow::performPaint(int mask, const QRegion ®ion, const WindowPai
|
|||
// The scissor region must be in the render target local coordinate system.
|
||||
QRegion scissorRegion = infiniteRegion();
|
||||
if (renderContext.hardwareClipping) {
|
||||
scissorRegion = m_scene->mapToRenderTarget(region);
|
||||
scissorRegion = mapToRenderTarget(region);
|
||||
}
|
||||
|
||||
const QMatrix4x4 modelViewProjection = modelViewProjectionMatrix(mask, data);
|
||||
|
|
|
@ -28,6 +28,27 @@ class KWIN_EXPORT SceneOpenGL
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
struct RenderNode
|
||||
{
|
||||
GLTexture *texture = nullptr;
|
||||
WindowQuadList quads;
|
||||
QMatrix4x4 transformMatrix;
|
||||
int firstVertex = 0;
|
||||
int vertexCount = 0;
|
||||
qreal opacity = 1;
|
||||
bool hasAlpha = false;
|
||||
TextureCoordinateType coordinateType = UnnormalizedCoordinates;
|
||||
};
|
||||
|
||||
struct RenderContext
|
||||
{
|
||||
QVector<RenderNode> renderNodes;
|
||||
QStack<QMatrix4x4> transforms;
|
||||
const QRegion clip;
|
||||
const WindowPaintData &paintData;
|
||||
const bool hardwareClipping;
|
||||
};
|
||||
|
||||
class EffectFrame;
|
||||
explicit SceneOpenGL(OpenGLBackend *backend, QObject *parent = nullptr);
|
||||
~SceneOpenGL() override;
|
||||
|
@ -43,6 +64,7 @@ public:
|
|||
SurfaceTexture *createSurfaceTextureInternal(SurfacePixmapInternal *pixmap) override;
|
||||
SurfaceTexture *createSurfaceTextureX11(SurfacePixmapX11 *pixmap) override;
|
||||
SurfaceTexture *createSurfaceTextureWayland(SurfacePixmapWayland *pixmap) override;
|
||||
void render(Item *item, int mask, const QRegion ®ion, const WindowPaintData &data) override;
|
||||
|
||||
OpenGLBackend *backend() const
|
||||
{
|
||||
|
@ -67,55 +89,18 @@ protected:
|
|||
|
||||
void paintSimpleScreen(int mask, const QRegion ®ion) override;
|
||||
void paintGenericScreen(int mask, const ScreenPaintData &data) override;
|
||||
SceneWindow *createWindow(Window *t) override;
|
||||
|
||||
private:
|
||||
void doPaintBackground(const QVector<float> &vertices);
|
||||
|
||||
bool init_ok = true;
|
||||
OpenGLBackend *m_backend;
|
||||
QMatrix4x4 m_screenProjectionMatrix;
|
||||
GLuint vao = 0;
|
||||
};
|
||||
|
||||
class OpenGLWindow final : public SceneWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
struct RenderNode
|
||||
{
|
||||
GLTexture *texture = nullptr;
|
||||
WindowQuadList quads;
|
||||
QMatrix4x4 transformMatrix;
|
||||
int firstVertex = 0;
|
||||
int vertexCount = 0;
|
||||
qreal opacity = 1;
|
||||
bool hasAlpha = false;
|
||||
TextureCoordinateType coordinateType = UnnormalizedCoordinates;
|
||||
};
|
||||
|
||||
struct RenderContext
|
||||
{
|
||||
QVector<RenderNode> renderNodes;
|
||||
QStack<QMatrix4x4> transforms;
|
||||
const QRegion clip;
|
||||
const WindowPaintData &paintData;
|
||||
const bool hardwareClipping;
|
||||
};
|
||||
|
||||
OpenGLWindow(Window *window, SceneOpenGL *scene);
|
||||
~OpenGLWindow() override;
|
||||
|
||||
void performPaint(int mask, const QRegion ®ion, const WindowPaintData &data) override;
|
||||
|
||||
private:
|
||||
QMatrix4x4 modelViewProjectionMatrix(int mask, const WindowPaintData &data) const;
|
||||
QVector4D modulate(float opacity, float brightness) const;
|
||||
void setBlendEnabled(bool enabled);
|
||||
void createRenderNode(Item *item, RenderContext *context);
|
||||
|
||||
SceneOpenGL *m_scene;
|
||||
bool init_ok = true;
|
||||
OpenGLBackend *m_backend;
|
||||
QMatrix4x4 m_screenProjectionMatrix;
|
||||
GLuint vao = 0;
|
||||
bool m_blendingEnabled = false;
|
||||
};
|
||||
|
||||
|
|
|
@ -98,11 +98,6 @@ void SceneQPainter::paintOffscreenQuickView(OffscreenQuickView *w)
|
|||
painter->restore();
|
||||
}
|
||||
|
||||
SceneWindow *SceneQPainter::createWindow(Window *window)
|
||||
{
|
||||
return new SceneQPainterWindow(this, window);
|
||||
}
|
||||
|
||||
Scene::EffectFrame *SceneQPainter::createEffectFrame(EffectFrameImpl *frame)
|
||||
{
|
||||
return new QPainterEffectFrame(frame, this);
|
||||
|
@ -113,24 +108,11 @@ Shadow *SceneQPainter::createShadow(Window *window)
|
|||
return new SceneQPainterShadow(window);
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// SceneQPainterWindow
|
||||
//****************************************
|
||||
SceneQPainterWindow::SceneQPainterWindow(SceneQPainter *scene, Window *c)
|
||||
: SceneWindow(c)
|
||||
, m_scene(scene)
|
||||
{
|
||||
}
|
||||
|
||||
SceneQPainterWindow::~SceneQPainterWindow()
|
||||
{
|
||||
}
|
||||
|
||||
void SceneQPainterWindow::performPaint(int mask, const QRegion &_region, const WindowPaintData &data)
|
||||
void SceneQPainter::render(Item *item, int mask, const QRegion &_region, const WindowPaintData &data)
|
||||
{
|
||||
QRegion region = _region;
|
||||
|
||||
const QRect boundingRect = windowItem()->mapToGlobal(windowItem()->boundingRect());
|
||||
const QRect boundingRect = item->mapToGlobal(item->boundingRect());
|
||||
if (!(mask & (Scene::PAINT_WINDOW_TRANSFORMED | Scene::PAINT_SCREEN_TRANSFORMED))) {
|
||||
region &= boundingRect;
|
||||
}
|
||||
|
@ -139,8 +121,7 @@ void SceneQPainterWindow::performPaint(int mask, const QRegion &_region, const W
|
|||
return;
|
||||
}
|
||||
|
||||
QPainter *scenePainter = m_scene->scenePainter();
|
||||
QPainter *painter = scenePainter;
|
||||
QPainter *painter = scenePainter();
|
||||
painter->save();
|
||||
painter->setClipRegion(region);
|
||||
painter->setClipping(true);
|
||||
|
@ -163,7 +144,7 @@ void SceneQPainterWindow::performPaint(int mask, const QRegion &_region, const W
|
|||
painter = &tempPainter;
|
||||
}
|
||||
|
||||
renderItem(painter, windowItem());
|
||||
renderItem(painter, item);
|
||||
|
||||
if (!opaque) {
|
||||
tempPainter.restore();
|
||||
|
@ -172,14 +153,14 @@ void SceneQPainterWindow::performPaint(int mask, const QRegion &_region, const W
|
|||
translucent.setAlphaF(data.opacity());
|
||||
tempPainter.fillRect(QRect(QPoint(0, 0), boundingRect.size()), translucent);
|
||||
tempPainter.end();
|
||||
painter = scenePainter;
|
||||
painter = scenePainter();
|
||||
painter->drawImage(boundingRect.topLeft(), tempImage);
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void SceneQPainterWindow::renderItem(QPainter *painter, Item *item) const
|
||||
void SceneQPainter::renderItem(QPainter *painter, Item *item) const
|
||||
{
|
||||
const QList<Item *> sortedChildItems = item->sortedChildItems();
|
||||
|
||||
|
@ -214,7 +195,7 @@ void SceneQPainterWindow::renderItem(QPainter *painter, Item *item) const
|
|||
painter->restore();
|
||||
}
|
||||
|
||||
void SceneQPainterWindow::renderSurfaceItem(QPainter *painter, SurfaceItem *surfaceItem) const
|
||||
void SceneQPainter::renderSurfaceItem(QPainter *painter, SurfaceItem *surfaceItem) const
|
||||
{
|
||||
const SurfacePixmap *surfaceTexture = surfaceItem->pixmap();
|
||||
if (!surfaceTexture || !surfaceTexture->isValid()) {
|
||||
|
@ -241,11 +222,11 @@ void SceneQPainterWindow::renderSurfaceItem(QPainter *painter, SurfaceItem *surf
|
|||
}
|
||||
}
|
||||
|
||||
void SceneQPainterWindow::renderDecorationItem(QPainter *painter, DecorationItem *decorationItem) const
|
||||
void SceneQPainter::renderDecorationItem(QPainter *painter, DecorationItem *decorationItem) const
|
||||
{
|
||||
const auto renderer = static_cast<const SceneQPainterDecorationRenderer *>(decorationItem->renderer());
|
||||
QRect dtr, dlr, drr, dbr;
|
||||
m_window->layoutDecorationRects(dlr, dtr, drr, dbr);
|
||||
decorationItem->window()->layoutDecorationRects(dlr, dtr, drr, dbr);
|
||||
|
||||
painter->drawImage(dtr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Top));
|
||||
painter->drawImage(dlr, renderer->image(SceneQPainterDecorationRenderer::DecorationPart::Left));
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
DecorationRenderer *createDecorationRenderer(Decoration::DecoratedClientImpl *impl) override;
|
||||
SurfaceTexture *createSurfaceTextureInternal(SurfacePixmapInternal *pixmap) override;
|
||||
SurfaceTexture *createSurfaceTextureWayland(SurfacePixmapWayland *pixmap) override;
|
||||
void render(Item *item, int mask, const QRegion ®ion, const WindowPaintData &data) override;
|
||||
|
||||
bool animationsSupported() const override
|
||||
{
|
||||
|
@ -49,29 +50,17 @@ public:
|
|||
|
||||
protected:
|
||||
void paintBackground(const QRegion ®ion) override;
|
||||
SceneWindow *createWindow(Window *window) override;
|
||||
void paintOffscreenQuickView(OffscreenQuickView *w) override;
|
||||
|
||||
private:
|
||||
explicit SceneQPainter(QPainterBackend *backend, QObject *parent = nullptr);
|
||||
QPainterBackend *m_backend;
|
||||
QScopedPointer<QPainter> m_painter;
|
||||
};
|
||||
|
||||
class SceneQPainterWindow : public SceneWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SceneQPainterWindow(SceneQPainter *scene, Window *c);
|
||||
~SceneQPainterWindow() override;
|
||||
void performPaint(int mask, const QRegion ®ion, const WindowPaintData &data) override;
|
||||
|
||||
private:
|
||||
void renderSurfaceItem(QPainter *painter, SurfaceItem *surfaceItem) const;
|
||||
void renderDecorationItem(QPainter *painter, DecorationItem *decorationItem) const;
|
||||
void renderItem(QPainter *painter, Item *item) const;
|
||||
SceneQPainter *m_scene;
|
||||
|
||||
QPainterBackend *m_backend;
|
||||
QScopedPointer<QPainter> m_painter;
|
||||
};
|
||||
|
||||
class QPainterEffectFrame : public Scene::EffectFrame
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "scripting_logging.h"
|
||||
#include "virtualdesktops.h"
|
||||
#include "window.h"
|
||||
#include "windowitem.h"
|
||||
#include "workspace.h"
|
||||
|
||||
#include <kwingltexture.h>
|
||||
|
@ -438,7 +439,7 @@ void WindowThumbnailItem::updateOffscreenTexture()
|
|||
// shared across contexts. Unfortunately, this also introduces a latency of 1
|
||||
// frame, which is not ideal, but it is acceptable for things such as thumbnails.
|
||||
const int mask = Scene::PAINT_WINDOW_TRANSFORMED;
|
||||
m_client->sceneWindow()->performPaint(mask, infiniteRegion(), data);
|
||||
Compositor::self()->scene()->render(m_client->windowItem(), mask, infiniteRegion(), data);
|
||||
GLFramebuffer::popFramebuffer();
|
||||
|
||||
// The fence is needed to avoid the case where qtquick renderer starts using
|
||||
|
|
|
@ -349,7 +349,7 @@ bool Window::setupCompositing()
|
|||
m_effectWindow = new EffectWindowImpl(this);
|
||||
updateShadow();
|
||||
|
||||
m_sceneWindow = Compositor::self()->scene()->createWindow(this);
|
||||
m_sceneWindow = new SceneWindow(this);
|
||||
m_effectWindow->setSceneWindow(m_sceneWindow);
|
||||
|
||||
connect(windowItem(), &WindowItem::positionChanged, this, &Window::visibleGeometryChanged);
|
||||
|
|
Loading…
Reference in a new issue