friction2d / friction

Friction Graphics
https://friction.graphics
GNU General Public License v3.0
233 stars 12 forks source link

Canvas does not render properly in edit mode #22

Closed sanjuchopracool closed 1 year ago

sanjuchopracool commented 1 year ago

Hi, I am using 4k display with kde desktop environment and 200% scaling. Canvas does not render properly. It is always on bottom left corner with almost 1/4th of canvas area. Resize to fit also does not change anything. When timeline is playing it renders correctly. Looks like scaling is not handled properly or view transformation.

BUG

https://youtu.be/Cx4xKeqmuvQ

rodlie commented 1 year ago

Hi,

I'm currently working on the wip branch, the ui has changed a bit compared to main.

It's probably a scaling issue, I have not tested how the ui works with scaling. Will check this weekend.

Thanks for the feedback :)

sanjuchopracool commented 1 year ago

I can always help with testing after your fix. thanks for resurrecting the project.

rodlie commented 1 year ago

Did a quick test on my laptop (1080p) using the wip branch:

100%

friction-wip-1080p-scale-100

125%

friction-wip-1080p-scale-125

150%

friction-wip-1080p-scale-150


Not good, but the canvas works.

sanjuchopracool commented 1 year ago

Let me check wip branch.

rodlie commented 1 year ago

Ok, thanks for testing. Will need to test on a different machine to replicate.

I use Ubuntu 22.04 with default gnome.

sanjuchopracool commented 1 year ago

I am still getting same result with wip branch. BUG

rodlie commented 1 year ago

btw, wayland? I use X11.

sanjuchopracool commented 1 year ago

x11

sanjuchopracool commented 1 year ago

I managed to render properly with this diff. But there were still some errors with mouse events position. Perhaps it can give you more hints :)

diff --git a/src/app/GUI/canvaswindow.cpp b/src/app/GUI/canvaswindow.cpp
index 9d8108a6..bc603962 100755
--- a/src/app/GUI/canvaswindow.cpp
+++ b/src/app/GUI/canvaswindow.cpp
@@ -145,10 +145,13 @@ bool CanvasWindow::hasNoCanvas() {
 #include "glhelpers.h"

 void CanvasWindow::renderSk(SkCanvas * const canvas) {
+    qreal pixelRatio = this->devicePixelRatioF();
     if(mCurrentCanvas) {
         canvas->save();
+        QMatrix m = mViewTransform;
+        m.scale(pixelRatio, pixelRatio);
         mCurrentCanvas->renderSk(canvas, rect(),
-                                 mViewTransform, mMouseGrabber);
+                                 m, mMouseGrabber);
         canvas->restore();
     }

@@ -157,7 +160,7 @@ void CanvasWindow::renderSk(SkCanvas * const canvas) {
         paint.setColor(SK_ColorRED);
         paint.setStrokeWidth(4);
         paint.setStyle(SkPaint::kStroke_Style);
-        canvas->drawRect(SkRect::MakeWH(width(), height()), paint);
+        canvas->drawRect(SkRect::MakeWH(width()*pixelRatio, height()*pixelRatio), paint);
     }
 }

diff --git a/src/app/GUI/glwindow.cpp b/src/app/GUI/glwindow.cpp
index ac5bc497..6e064aa4 100755
--- a/src/app/GUI/glwindow.cpp
+++ b/src/app/GUI/glwindow.cpp
@@ -26,11 +26,14 @@ GLWindow::GLWindow(QWidget * const parent)
 }

 void GLWindow::bindSkia(const int w, const int h) {
+    qreal pixelRatio = this->devicePixelRatioF();
+    int scaledWidth = pixelRatio*w;
+    int scaledHeight = pixelRatio*h;
     GrGLFramebufferInfo fbInfo;
     fbInfo.fFBOID = context()->defaultFramebufferObject();//buffer;
     fbInfo.fFormat = GR_GL_RGBA8;//buffer;
     GrBackendRenderTarget backendRT = GrBackendRenderTarget(
-                                        w, h,
+                                        scaledWidth, scaledHeight,
                                         0, 8, // (optional) 4, 8,
                                         fbInfo
                                         /*kRGBA_half_GrPixelConfig*/
rodlie commented 1 year ago

btw, if you uncomment //QApplication::setAttribute(Qt::AA_DisableHighDpiScaling); in main.cpp (any branch) does the canvas work? (this will probably break other things)

EDIT: will check your diff, thanks :)

rodlie commented 1 year ago

KDE probably sets the attribute Qt::AA_EnableHighDpiScaling, Friction will inherit this setting (since it's either on/off in the code). If I force Qt::AA_EnableHighDpiScaling in main.cpp then I can replicate the issue.

sanjuchopracool commented 1 year ago

I think Qt::AA_EnableHighDpiScaling true by default for high density display. To test hidpi on standard display,use QT_SCALE_FACTOR=2 environment variable.

rodlie commented 1 year ago

Does this work?

diff --git a/src/app/GUI/canvaswindow.cpp b/src/app/GUI/canvaswindow.cpp
index 9d8108a6..9f708f21 100755
--- a/src/app/GUI/canvaswindow.cpp
+++ b/src/app/GUI/canvaswindow.cpp
@@ -145,6 +145,7 @@ bool CanvasWindow::hasNoCanvas() {
 #include "glhelpers.h"

 void CanvasWindow::renderSk(SkCanvas * const canvas) {
+    qreal pixelRatio = this->devicePixelRatioF();
     if(mCurrentCanvas) {
         canvas->save();
         mCurrentCanvas->renderSk(canvas, rect(),
@@ -157,7 +158,7 @@ void CanvasWindow::renderSk(SkCanvas * const canvas) {
         paint.setColor(SK_ColorRED);
         paint.setStrokeWidth(4);
         paint.setStyle(SkPaint::kStroke_Style);
-        canvas->drawRect(SkRect::MakeWH(width(), height()), paint);
+        canvas->drawRect(SkRect::MakeWH(width()*pixelRatio, height()*pixelRatio), paint);
     }
 }

diff --git a/src/app/GUI/canvaswindowevents.cpp b/src/app/GUI/canvaswindowevents.cpp
index 84e9a447..f69f5fbf 100755
--- a/src/app/GUI/canvaswindowevents.cpp
+++ b/src/app/GUI/canvaswindowevents.cpp
@@ -20,11 +20,17 @@
 #include "Private/document.h"

 QPointF CanvasWindow::mapToCanvasCoord(const QPointF& windowCoord) {
-    return mViewTransform.inverted().map(windowCoord);
+    qreal pixelRatio = this->devicePixelRatioF();
+    QPointF coord;
+    coord.setX(windowCoord.x()*pixelRatio);
+    coord.setY(windowCoord.y()*pixelRatio);
+    return mViewTransform.inverted().map(coord);
 }

 void CanvasWindow::translateView(const QPointF &trans) {
     if(!mCurrentCanvas) return;
+    qreal pixelRatio = this->devicePixelRatioF();
+    mViewTransform.scale(pixelRatio, pixelRatio);
     mViewTransform.translate(trans.x(), trans.y());
 }

diff --git a/src/app/GUI/glwindow.cpp b/src/app/GUI/glwindow.cpp
index ac5bc497..6e064aa4 100755
--- a/src/app/GUI/glwindow.cpp
+++ b/src/app/GUI/glwindow.cpp
@@ -26,11 +26,14 @@ GLWindow::GLWindow(QWidget * const parent)
 }

 void GLWindow::bindSkia(const int w, const int h) {
+    qreal pixelRatio = this->devicePixelRatioF();
+    int scaledWidth = pixelRatio*w;
+    int scaledHeight = pixelRatio*h;
     GrGLFramebufferInfo fbInfo;
     fbInfo.fFBOID = context()->defaultFramebufferObject();//buffer;
     fbInfo.fFormat = GR_GL_RGBA8;//buffer;
     GrBackendRenderTarget backendRT = GrBackendRenderTarget(
-                                        w, h,
+                                        scaledWidth, scaledHeight,
                                         0, 8, // (optional) 4, 8,
                                         fbInfo
                                         /*kRGBA_half_GrPixelConfig*/
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 84684bfe..2a89a617 100755
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -105,7 +105,7 @@ int main(int argc, char *argv[]) {
     QApplication::setOrganizationDomain(AppSupport::getAppDomain());
     QApplication::setApplicationVersion(AppSupport::getAppVersion());

-    //QApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
+    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
     QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
     QApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
sanjuchopracool commented 1 year ago

There were two issues

  1. initial scaling was not working at all. After first reset render was proper
  2. panning with mouse was not working, it scaled exponentially.

I was debugging and fixed the issue except the initial scaling. Something external is changing initial scaling(I will debug it tomorrow)

diff --git a/src/app/GUI/canvaswindow.cpp b/src/app/GUI/canvaswindow.cpp
index 9d8108a6..527ec729 100755
--- a/src/app/GUI/canvaswindow.cpp
+++ b/src/app/GUI/canvaswindow.cpp
@@ -145,8 +145,14 @@ bool CanvasWindow::hasNoCanvas() {
 #include "glhelpers.h"

 void CanvasWindow::renderSk(SkCanvas * const canvas) {
+//    qDebug() << "rect: " << rect();
+    qreal pixelRatio = this->devicePixelRatioF();
+//    qDebug() << "PixelRation: " << pixelRatio;
+//    qDebug() << "SCALE SK: " << mViewTransform.m11() << "," << mViewTransform.m22();
     if(mCurrentCanvas) {
         canvas->save();
+//        QMatrix m = mViewTransform;
+//        m.scale(pixelRatio, pixelRatio);
         mCurrentCanvas->renderSk(canvas, rect(),
                                  mViewTransform, mMouseGrabber);
         canvas->restore();
@@ -155,9 +161,9 @@ void CanvasWindow::renderSk(SkCanvas * const canvas) {
     if(KFT_hasFocus()) {
         SkPaint paint;
         paint.setColor(SK_ColorRED);
-        paint.setStrokeWidth(4);
+        paint.setStrokeWidth(pixelRatio*4);
         paint.setStyle(SkPaint::kStroke_Style);
-        canvas->drawRect(SkRect::MakeWH(width(), height()), paint);
+        canvas->drawRect(SkRect::MakeWH(width()*pixelRatio, height()*pixelRatio), paint);
     }
 }

@@ -214,7 +220,9 @@ void CanvasWindow::mouseReleaseEvent(QMouseEvent *event) {
         return;
     }
     if(!mCurrentCanvas || mBlockInput) return;
+    qDebug() << "Windows pos: " << event->pos();
     const auto pos = mapToCanvasCoord(event->pos());
+    qDebug() << "Canvas pos: " << pos;
     mCurrentCanvas->mouseReleaseEvent(
                 eMouseEvent(pos, mPrevMousePos, mPrevPressPos,
                            mMouseGrabber, mViewTransform.m11(),
diff --git a/src/app/GUI/canvaswindowevents.cpp b/src/app/GUI/canvaswindowevents.cpp
index 84e9a447..dd0600c5 100755
--- a/src/app/GUI/canvaswindowevents.cpp
+++ b/src/app/GUI/canvaswindowevents.cpp
@@ -20,7 +20,8 @@
 #include "Private/document.h"

 QPointF CanvasWindow::mapToCanvasCoord(const QPointF& windowCoord) {
-    return mViewTransform.inverted().map(windowCoord);
+    qreal pixelRatio = devicePixelRatioF();
+    return mViewTransform.inverted().scale(pixelRatio, pixelRatio).map(windowCoord);
 }

 void CanvasWindow::translateView(const QPointF &trans) {
@@ -59,15 +60,18 @@ void CanvasWindow::fitCanvasToSize() {
     }
     if(!mCurrentCanvas) return;
     mViewTransform.reset();
+    qreal pixelRatio = devicePixelRatioF();
+//    mViewTransform.scale(pixelRatio, pixelRatio);
     const auto canvasSize = mCurrentCanvas->getCanvasSize();
-    const qreal widWidth = width();
-    const qreal widHeight = height();
-    const qreal widthScale = (widWidth - eSizesUI::widget)/canvasSize.width();
-    const qreal heightScale = (widHeight - eSizesUI::widget)/canvasSize.height();
+    const qreal widWidth = width()*pixelRatio;
+    const qreal widHeight = height()*pixelRatio;
+    const qreal widthScale = (widWidth /*- eSizesUI::widget*/)/canvasSize.width();
+    const qreal heightScale = (widHeight /*- eSizesUI::widget*/)/canvasSize.height();
     const qreal minScale = qMin(widthScale, heightScale);
     translateView({(widWidth - canvasSize.width()*minScale)*0.5,
                    (widHeight - canvasSize.height()*minScale)*0.5});
     mViewTransform.scale(minScale, minScale);
+    qDebug() << "SCALE: " << mViewTransform.m11() << "," << mViewTransform.m22();
 }

 void CanvasWindow::zoomInView() {
diff --git a/src/app/GUI/glwindow.cpp b/src/app/GUI/glwindow.cpp
index ac5bc497..f432327f 100755
--- a/src/app/GUI/glwindow.cpp
+++ b/src/app/GUI/glwindow.cpp
@@ -26,11 +26,16 @@ GLWindow::GLWindow(QWidget * const parent)
 }

 void GLWindow::bindSkia(const int w, const int h) {
+    qreal pixelRatio = devicePixelRatioF();
+    int scaledWidth = pixelRatio*w;
+    int scaledHeight = pixelRatio*h;
+    qDebug() << w << 'x' << h;
+    qDebug() << scaledWidth << 'x' << scaledHeight;
     GrGLFramebufferInfo fbInfo;
     fbInfo.fFBOID = context()->defaultFramebufferObject();//buffer;
     fbInfo.fFormat = GR_GL_RGBA8;//buffer;
     GrBackendRenderTarget backendRT = GrBackendRenderTarget(
-                                        w, h,
+                                        scaledWidth, scaledHeight,
                                         0, 8, // (optional) 4, 8,
                                         fbInfo
                                         /*kRGBA_half_GrPixelConfig*/
rodlie commented 1 year ago

CanvasWindow::readState sets initial mViewTransform.

rodlie commented 1 year ago

close as completed, thanks.