File indexing completed on 2024-05-12 05:31:23

0001 /*
0002     SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 #include "core/renderviewport.h"
0007 #include "core/pixelgrid.h"
0008 #include "core/rendertarget.h"
0009 #include "effect/globals.h"
0010 
0011 namespace KWin
0012 {
0013 
0014 static QMatrix4x4 createProjectionMatrix(const RenderTarget &renderTarget, const QRect &rect)
0015 {
0016     QMatrix4x4 ret;
0017 
0018     ret.scale(1, -1); // flip the y axis back
0019     ret *= renderTarget.transform().toMatrix();
0020     ret.scale(1, -1); // undo ortho() flipping the y axis
0021 
0022     ret.ortho(rect);
0023     return ret;
0024 }
0025 
0026 RenderViewport::RenderViewport(const QRectF &renderRect, double scale, const RenderTarget &renderTarget)
0027     : m_transform(renderTarget.transform())
0028     , m_transformBounds(m_transform.map(renderTarget.size()))
0029     , m_renderRect(renderRect)
0030     , m_deviceRenderRect(snapToPixelGrid(scaledRect(renderRect, scale)))
0031     , m_projectionMatrix(createProjectionMatrix(renderTarget, m_deviceRenderRect))
0032     , m_scale(scale)
0033 {
0034 }
0035 
0036 QMatrix4x4 RenderViewport::projectionMatrix() const
0037 {
0038     return m_projectionMatrix;
0039 }
0040 
0041 QRectF RenderViewport::renderRect() const
0042 {
0043     return m_renderRect;
0044 }
0045 
0046 double RenderViewport::scale() const
0047 {
0048     return m_scale;
0049 }
0050 
0051 QRectF RenderViewport::mapToRenderTarget(const QRectF &logicalGeometry) const
0052 {
0053     const QRectF deviceGeometry = scaledRect(logicalGeometry, m_scale)
0054                                       .translated(-m_deviceRenderRect.topLeft());
0055     return m_transform.map(deviceGeometry, m_transformBounds);
0056 }
0057 
0058 QRect RenderViewport::mapToRenderTarget(const QRect &logicalGeometry) const
0059 {
0060     const QRect deviceGeometry = snapToPixelGrid(scaledRect(logicalGeometry, m_scale))
0061                                      .translated(-m_deviceRenderRect.topLeft());
0062     return m_transform.map(deviceGeometry, m_transformBounds);
0063 }
0064 
0065 QPoint RenderViewport::mapToRenderTarget(const QPoint &logicalGeometry) const
0066 {
0067     const QPoint devicePoint = snapToPixelGrid(QPointF(logicalGeometry) * m_scale) - m_deviceRenderRect.topLeft();
0068     return m_transform.map(devicePoint, m_transformBounds);
0069 }
0070 
0071 QPointF RenderViewport::mapToRenderTarget(const QPointF &logicalGeometry) const
0072 {
0073     const QPointF devicePoint = logicalGeometry * m_scale - m_deviceRenderRect.topLeft();
0074     return m_transform.map(devicePoint, m_transformBounds);
0075 }
0076 
0077 QRegion RenderViewport::mapToRenderTarget(const QRegion &logicalGeometry) const
0078 {
0079     QRegion ret;
0080     for (const auto &rect : logicalGeometry) {
0081         ret += mapToRenderTarget(rect);
0082     }
0083     return ret;
0084 }
0085 
0086 QRectF RenderViewport::mapToRenderTargetTexture(const QRectF &logicalGeometry) const
0087 {
0088     return scaledRect(logicalGeometry, m_scale)
0089         .translated(-m_deviceRenderRect.topLeft());
0090 }
0091 
0092 QRect RenderViewport::mapToRenderTargetTexture(const QRect &logicalGeometry) const
0093 {
0094     return snapToPixelGrid(scaledRect(logicalGeometry, m_scale))
0095         .translated(-m_deviceRenderRect.topLeft());
0096 }
0097 
0098 QPoint RenderViewport::mapToRenderTargetTexture(const QPoint &logicalGeometry) const
0099 {
0100     return snapToPixelGrid(QPointF(logicalGeometry) * m_scale) - m_deviceRenderRect.topLeft();
0101 }
0102 
0103 QPointF RenderViewport::mapToRenderTargetTexture(const QPointF &logicalGeometry) const
0104 {
0105     return logicalGeometry * m_scale - m_deviceRenderRect.topLeft();
0106 }
0107 
0108 QRegion RenderViewport::mapToRenderTargetTexture(const QRegion &logicalGeometry) const
0109 {
0110     QRegion ret;
0111     for (const auto &rect : logicalGeometry) {
0112         ret += mapToRenderTargetTexture(rect);
0113     }
0114     return ret;
0115 }
0116 }