bd689ef76c
With RenderTarget, CursorView and CursorDelegate can be merged.
80 lines
2.4 KiB
C++
80 lines
2.4 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2022 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include "cursordelegate_opengl.h"
|
|
#include "cursor.h"
|
|
#include "kwingltexture.h"
|
|
#include "kwinglutils.h"
|
|
#include "renderlayer.h"
|
|
#include "rendertarget.h"
|
|
|
|
namespace KWin
|
|
{
|
|
|
|
CursorDelegateOpenGL::CursorDelegateOpenGL(QObject *parent)
|
|
: RenderLayerDelegate(parent)
|
|
{
|
|
}
|
|
|
|
CursorDelegateOpenGL::~CursorDelegateOpenGL()
|
|
{
|
|
}
|
|
|
|
void CursorDelegateOpenGL::paint(RenderTarget *renderTarget, const QRegion ®ion)
|
|
{
|
|
if (!region.intersects(layer()->mapToGlobal(layer()->rect()))) {
|
|
return;
|
|
}
|
|
|
|
auto allocateTexture = [this]() {
|
|
const QImage img = Cursors::self()->currentCursor()->image();
|
|
if (img.isNull()) {
|
|
m_cursorTextureDirty = false;
|
|
return;
|
|
}
|
|
m_cursorTexture.reset(new GLTexture(img));
|
|
m_cursorTexture->setWrapMode(GL_CLAMP_TO_EDGE);
|
|
m_cursorTextureDirty = false;
|
|
};
|
|
|
|
// lazy init texture cursor only in case we need software rendering
|
|
if (!m_cursorTexture) {
|
|
allocateTexture();
|
|
|
|
// handle shape update on case cursor image changed
|
|
connect(Cursors::self(), &Cursors::currentCursorChanged, this, [this]() {
|
|
m_cursorTextureDirty = true;
|
|
});
|
|
} else if (m_cursorTextureDirty) {
|
|
const QImage image = Cursors::self()->currentCursor()->image();
|
|
if (image.size() == m_cursorTexture->size()) {
|
|
m_cursorTexture->update(image);
|
|
m_cursorTextureDirty = false;
|
|
} else {
|
|
allocateTexture();
|
|
}
|
|
}
|
|
|
|
const QRect cursorRect = layer()->mapToGlobal(layer()->rect());
|
|
|
|
QMatrix4x4 mvp;
|
|
mvp.ortho(QRect(QPoint(0, 0), renderTarget->size() / renderTarget->devicePixelRatio()));
|
|
mvp.translate(cursorRect.x(), cursorRect.y());
|
|
|
|
// Don't need to call GLVertexBuffer::beginFrame() and GLVertexBuffer::endOfFrame() because
|
|
// the GLVertexBuffer::streamingBuffer() is not being used when painting cursor.
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
m_cursorTexture->bind();
|
|
ShaderBinder binder(ShaderTrait::MapTexture);
|
|
binder.shader()->setUniform(GLShader::ModelViewProjectionMatrix, mvp);
|
|
m_cursorTexture->render(region, QRect(0, 0, cursorRect.width(), cursorRect.height()));
|
|
m_cursorTexture->unbind();
|
|
glDisable(GL_BLEND);
|
|
}
|
|
|
|
} // namespace KWin
|