Announcement

Collapse
No announcement yet.

KDAB Working On Embedding Servo Web Engine Within Qt

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #31
    Dear anda_skoa , let me do that again - a little bit more obvious - in the hopes you understand it this time.

    Originally posted by anda_skoa View Post
    I know, I have been using it for at least a decade.
    I retract my condolences. Obviously you like the language. I'm not trying to deprive you of the fun or demean the language in any way. I just have the impression you are a bit blue-eyed on its consequences.

    Originally posted by anda_skoa View Post
    Nope

    A QML program looks strikingly similar to a mixture between JavaScript and CSS. Wikipedia writes: "It is a declarative language (similar to CSS and JSON)​"
    Code:
    import QtQuick
    
    Rectangle {
        id: page
        width: 320; height: 480
        color: "lightgray"
    
       Text {
          id: helloText
          text: "Hello world!"
          y: 30
          anchors.horizontalCenter: page.horizontalCenter
          font.pointSize: 24; font.bold: true
       }
    }​
    The QML language runs in an "engine" which is started at the beginning of the application and is stopped when the application is stopped. That is an obvious reminder (more like a hint with a fencing post) that there is a QML engine running in the background. (looking from the QML code point of view, it would be the foreground).
    Code:
    QQmlApplicationEngine engine("main.qml");​
    Originally posted by anda_skoa View Post

    The QML engine creates a tree of instances of QObject based classes.

    The "tree of QObject instances" is the corresponding equivalent of the DOM object in an e.g. HTML web application.

    Originally posted by anda_skoa View Post

    If those classes don't have any GUI dependencies then the application does not have one either. Let alone a web stack.

    An obvious general statement that is true for most programming languages "If you don't use it you don't pay for it". But for a web stack, there is `WebSocket` QML type.

    Originally posted by anda_skoa View Post
    ​​
    If those classes are QWidget derived, then it is just like any other Qt widget application, it just has created the widget tree differently.

    It's not that simple.
    QML makes heavy use of QObject's property system. At run-time, connections are handled by the QML- or the JavaScript interpreter. There is a performance penalty to pay for that. In simple GUI applications that penalty is usually not that visible. But it gets more visible as the application grows more complex. A direct comparison between a bare Qt application and a QML application will reveal it.

    While it is possible to improve the performance by compiling (most of) QML to C++, this is not possible by default. It needs careful configuration and there are licensing issues making that case usually impossible. But I'm only talking about the default case here.

    Originally posted by anda_skoa View Post
    ​​
    If those classes are QQuickItem derived, then the application has a dependency on Qt hardware accelerated render infrastructure.

    An interesting point. Qt Quick Scene Graph makes heavy use of hardware acceleration. So it "sort of" requires it. QWidget applications do not have that limitation and do work without graphics acceleration.

    But there is a way to do even that: On hardware that dearly lacks graphic acceleration, windows OS may fall back to Direct3D's software rasterizer (WARP) by default. Within Qt, it is possible to force the use of the software rasterizer by setting the environment variable QSG_RHI_PREFER_SOFTWARE_RENDERER to 1​. Of course, there will be less performance.

    Originally posted by anda_skoa View Post

    Nope.
    Only if the QML code refers to a type that uses a web engine, e.g. the Qt Web View.
    Call it whatever you will. A QML application has essentially the same things running as any other web application.

    Nothing prevents anyone to create a Qt application that simultaneously utilizes a QtWebEngine and QML and Qt WebView in the QML code. I would advise against it but as long as there is enough CPU and RAM it will run smooth - sort of.

    Comment


    • #32
      Originally posted by lowflyer View Post
      A QML program looks strikingly similar to a mixture between JavaScript and CSS. Wikipedia writes: "It is a declarative language (similar to CSS and JSON)​"
      Indeed, meant to make it easier to learn.
      Yet it has none of the mechanism of CSS or web engine technologies.

      Originally posted by lowflyer View Post
      The QML language runs in an "engine" which is started at the beginning of the application and is stopped when the application is stopped.
      Depends on how long it is needed.
      For usages such as QtQuick for UI that is often the case, for usages such as application scripting it will often be limited to the execution time of the loaded script.

      In neither of the two cases will it instantiate a web engine unless the code loaded into it explicitly requests one.

      The simple example you've given doesn't.

      In a project targeting Qt for MCU it would even be translated into C++ and compiled into the application.

      Originally posted by lowflyer View Post

      The "tree of QObject instances" is the corresponding equivalent of the DOM object in an e.g. HTML web application.
      There are similarities and these are shared with essentially all UI frameworks, at least all of those I've worked with (for Qt both QtQuick and QtWidgets, GKT+, Java Swing and ATK).

      None of these require a web engine.

      Originally posted by lowflyer View Post

      An obvious general statement that is true for most programming languages "If you don't use it you don't pay for it".
      Exactly.
      There is only a web engine inside the process if the QML code explicitly instantiated one.
      Either by using Qt's WebView or the ServoWebView that is the subject of this article.

      Code:
      import QtQml
      
      QtObject {
      }
      Just a single QObject node, no web engine. Not even any UI code being initialized.

      Code:
      import QtQuick
      
      Item {
      }
      Just a single QQuickItem node, no web engine. QGuiApplication needed to initialize the integration with the system's display stack.

      Code:
      import QtWebView
      
      WebView {
      }
      A single QQuickWebView node, one web engine

      Code:
      import QtQuick
      import QtWebView
      import com.kdab.servo
      
      Item {
          WebView {
          }
          ServoWebView {
          }
      }
      Three nodes: one QQuickItem instance, one QQuickWeb instance and one instance of whatever the class name of the servo web view is.
      Two web engines.

      Originally posted by lowflyer View Post
      But for a web stack, there is `WebSocket` QML type.
      Very bad example as this does not have anything to do with a web engine either.
      A web socket is essentially a data stream over HTTP implementation.
      Qt can handle that with just the capabilities of its network module.


      Originally posted by lowflyer View Post
      QML makes heavy use of QObject's property system.
      It does indeed.
      Based on good experience with other use cases such as the Qt Widget Designer application, the Qt D-Bus classes, Qt Remote Objects, Qt Web Channel and the now deprecated Qt Script facilities.

      Originally posted by lowflyer View Post
      At run-time, connections are handled by the QML- or the JavaScript interpreter.
      Originally this was true when QML used the script engine from the WebKit dependency.
      But that has since long been replaced with a custom engine which tries to minimize delegation into the script interpreter.

      Bindings like the ones in your example can be trivially handled by C++ binding expressions and do not need any script code to run.
      Even slightly more complex bindings like those containing arithmetic or logical operators can usually be handled that way.

      This subset works on Qt for MCU which does not even have a script engine in its QML engine due to memory constraints.

      Anyway we are getting into details irrelevant for the misunderstanding that somehow using QML would require a web engine.

      Comment


      • #33
        Dear anda_skoa,

        You give away the impression of a language purist. You only accept the term "web engine" for your specific definition of what a web engine is, something like QtWebView - Even if it does *exactly* the same thing but only carries a different name - your classification is: "No! it is *NOT* a web engine".

        I see you bending arguments. When I talk about `WebSocket` and `web stack` you say it has nothing to do with a web enigne - but further up in the discussion state something like "It cannot be a web engine because it lacks a web stack".

        And here, you use "Qt for MCU", a non-default case as an argument - while you (further up) claim to care only about default cases.

        But let's leave the in-fighting and move to the metal:

        You claim to have good experience with QtQuick - I don't deny that. But when you say thing like this:
        Originally posted by anda_skoa View Post
        Bindings like the ones in your example can be trivially handled by C++ binding expressions and do not need any script code to run.
        Even slightly more complex bindings like those containing arithmetic or logical operators can usually be handled that way.
        ... I have the impression of "theoretical knowledge only".

        Question (please answer honestly): Did you ever make a one-to-one performance comparision between a QtQuick and a "classical" Qt Widgets application?

        Would you be ready to do one here? We can post code here.

        Comment


        • #34
          Originally posted by lowflyer View Post
          You only accept the term "web engine" for your specific definition of what a web engine is, something like QtWebView
          Exactly.
          There is neither HTML nor CSS involved in QML.

          By your definition any UI framework is a web engine because they work on trees of objects.

          Originally posted by lowflyer View Post
          Even if it does *exactly* the same thing
          But it does not the exactly the same thing.
          It is incapable of processing content intended for a web engine.

          Originally posted by lowflyer View Post
          I see you bending arguments. When I talk about `WebSocket` and `web stack` you say it has nothing to do with a web enigne
          How is that bending the argument.
          The Qt WebSocket implementation simply doesn't need access to a web engine.

          The technology is called Web Sockets because it originated from the need of web engine based apps to have a data stream connection to their server.
          Even in a browser it is a non-UI object with API accessible for the web engine, it doesn't need the web engine itself.
          The server side does not need one either.

          Qt's web socket is available as a C++ class without any dependency on QML or any web engine.
          Its QML type is just that C++ type registered with QML.

          Originally posted by lowflyer View Post
          further up in the discussion state something like "It cannot be a web engine because it lacks a web stack".
          Exactly.

          Originally posted by lowflyer View Post
          And here, you use "Qt for MCU", a non-default case as an argument - while you (further up) claim to care only about default cases.
          I am sorry, but not having scripting capability is the default for Qt for MCU.
          Not an optional choice like forcing software rendering into Qt Scene Graph or Qt RHI.

          Originally posted by lowflyer View Post
          You claim to have good experience with QtQuick - I don't deny that.
          Same for you but you seem not to be up to date.
          Originally the engine was built around WebKit's V8 engine but that got replaced by a custom implementation called V4.
          They put a lot of effort into minimizing transitions between the C++ and script domains.

          To the point that a lot of binding expressions can be handled directly in C++.

          Mostly to work around restrictive platforms such as iOS which don't allow just-in-time compiling, but also giving a nice peformance improvement on others.
          This can both be done either at runtime or compile time. In case of Qt for MCU it is always at compile time.

          Originally posted by lowflyer View Post
          Question (please answer honestly): Did you ever make a one-to-one performance comparision between a QtQuick and a "classical" Qt Widgets application?
          If I wanted to get numbers on the overhead for the QML engine I would not compare two different UI technologies, but the same objects.
          For example non-UI classes or using Qt Widgets from QML and C++.

          Let's say we had two classes
          Code:
          class Source : public QObject
          {
              Q_OBJECT
              Q_PROPERTY(int value READ value NOTIFY valueChanged)
          
          public:
              Source() {
                  QTimer *timer = new QTimer(this);
                  timer->callOnTimeout(this, [this](){
                      emit valueChanged(0);
                  });
                  timer->start(10);
              }
          
              int value() const { return 0; }
          
          Q_SIGNALS:
              void valueChanged(int value);
          };
          
          class Sink : public QObject
          {
              Q_OBJECT
              Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged)
          
          public:
              void setValue(int newValue) { emit valueChanged(newValue); }
              int value() const { return 0; }
          
          Q_SIGNALS:
              void valueChanged(int value);
          };
          In C++ we would connect them like this
          Code:
          auto source = new Source;
          auto sink = new Sink;
          connect(source, &Source::valueChanged, sink, &Sink::setValue);
          In QML we would be using a property binding
          Code:
          Source {
              id: source
          }
          Sink {
              value: source.value
          }​​​​​​​
          Then we could measure, e.g. 1 million time cycles and see how much the binding overhead was compared to the C++ connect
          ​​​​​​​

          Comment


          • #35
            Dear anda_skoa ,

            Your personal iron-clad definition of what a web engine is makes it impossible to get the slightest point through to you. It makes it *very* difficult to even communicate with you. It is not helpful to assume the other extreme if you disagree.

            You contradict yourself:
            Originally posted by anda_skoa View Post
            Originally the engine was built around WebKit's V8 engine but that got replaced by a custom implementation called V4.
            You say QML got WebKit's V8? ... A web engine? -- This is *exactly* my initial point.
            The replacement V4 - you even call it "engine" - per definition has to replicate its predecessor.

            While lowlevel comparisions have their value, I was thinking of directly comparing two "as similar as possible" GUI applications. My whole aim in this discussion is to point out that the QML engine is burning up your precious CPU cycles. It is interesting to see that you outright dismiss an overall compare between UI technologies. Do you fear that this would directly shine a light on your claims?

            If you're not willing to soften up in your argumentation I might loose interest in continuing this discussion.

            Comment


            • #36
              Originally posted by lowflyer View Post
              Dear anda_skoa ,

              Your personal iron-clad definition of what a web engine is makes it impossible to get the slightest point through to you. It makes it *very* difficult to even communicate with you. It is not helpful to assume the other extreme if you disagree.

              You contradict yourself:

              You say QML got WebKit's V8? ... A web engine? -- This is *exactly* my initial point.
              The replacement V4 - you even call it "engine" - per definition has to replicate its predecessor.

              While lowlevel comparisions have their value, I was thinking of directly comparing two "as similar as possible" GUI applications. My whole aim in this discussion is to point out that the QML engine is burning up your precious CPU cycles. It is interesting to see that you outright dismiss an overall compare between UI technologies. Do you fear that this would directly shine a light on your claims?
              There is Qt for MCU which is using a QML dialect to directly create structs. So no heap allocations for QObject anymore. They should have gone that route from the beginning. Slint is using actually the same approach(it is done actually be the same people who started Qt for MCU).

              Comment


              • #37
                Originally posted by patrick1946 View Post

                There is Qt for MCU which is using a QML dialect to directly create structs. So no heap allocations for QObject anymore. They should have gone that route from the beginning. Slint is using actually the same approach(it is done actually be the same people who started Qt for MCU).
                Side note: even structs need to be allocated somewhere.

                "Qt for MCU" is a different animal entirely. anda_skoa tried to divert the discussion there. It's a rather limited subset of QML and Qt Quick despite having some interoperability. There are quite stringent limitations on the hardware and don't forget the vendor-lock-in situation.

                Comment


                • #38
                  Originally posted by lowflyer View Post

                  Side note: even structs need to be allocated somewhere.

                  "Qt for MCU" is a different animal entirely. anda_skoa tried to divert the discussion there. It's a rather limited subset of QML and Qt Quick despite having some interoperability. There are quite stringent limitations on the hardware and don't forget the vendor-lock-in situation.
                  If you make the root struct a global variable there is no need for a heap. That is why it loads so fast. There are not myriad of heap allocations. Especially because there is no PIMPL. Most of the limitations comes from the low end hardware and the design scope. The principle iis much more powerful.

                  Comment


                  • #39
                    Originally posted by patrick1946 View Post

                    If you make the root struct a global variable there is no need for a heap. That is why it loads so fast. There are not myriad of heap allocations. Especially because there is no PIMPL. Most of the limitations comes from the low end hardware and the design scope. The principle iis much more powerful.
                    So, like anda_skoa , you also divert the discussion away from the original topic "KDAB embedding Servo engine into Qt".

                    Well then, lets discuss "Qt for MCU" now.

                    Unless you put the whole object tree statically into that global variable, you will have heap allocations. Depending on how you code you will probably also want to make it const to further prevent allocations.

                    Side notes:
                    1. using global variables is bad style
                    2. heap allocations are usually not the main driver of bad performance
                    3. making the object tree static and/or const will significantly reduce its flexibility
                    4. PIMPL has nothing to do with any of that
                    5. big global objects are not "for free". You'll pay for it with either bigger binaries or longer initialization time or bigger memory usage or all three combined.

                    Comment


                    • #40
                      Originally posted by lowflyer View Post
                      You say QML got WebKit's V8? ... A web engine? -- This is *exactly* my initial point.
                      V8 was WebKit's JavaScript engine and is not a web engine.
                      It is also used by NodeJs, and probably other projects that needed JavaScript capabilities.

                      In any case not relevant anymore since QML not has a new engine implementation that does not use anything from WebKit anymore.

                      Originally posted by lowflyer View Post
                      The replacement V4 - you even call it "engine" - per definition has to replicate its predecessor.
                      The concept of an engine is used in various contexts, in software and hardware.
                      It does not imply web engine.

                      V4 was specifically created as a QML engine, to avoid going into the script part as much as possible.

                      Partially due to limitations on certain platforms regarding non-system JS interpretation (or the absence of JIT compiling).
                      Partially to improve performance and avoid type conversions.
                      Partially to enable use cases in which scripting is not possible at all, for example Qt for MCU.

                      Getting rid of any remnants of things V8 might have had for web work is a nice bonus. Reduced the memory consumption quite considerably.

                      Originally posted by lowflyer View Post
                      While lowlevel comparisions have their value, I was thinking of directly comparing two "as similar as possible" GUI applications.
                      In such a case it would be very difficult, if not impossible, to attribute any differences to each of the involved parts.
                      Better to have otherwise identical objects and measure really the overhead of the QML bindings.

                      Originally posted by lowflyer View Post
                      My whole aim in this discussion is to point out that the QML engine is burning up your precious CPU cycles.
                      And to measure that one needs to compare with otherwise equal code.

                      Originally posted by lowflyer View Post
                      It is interesting to see that you outright dismiss an overall compare between UI technologies.
                      Not at all.
                      Comparison of UI technologies can also be done without mixing other things into the evalutaion.

                      If one were to compare QtQuick and QtWidgets one would either create the QtQuick object tree in C++ or create the QtWidget tree through QML.

                      Comment

                      Working...
                      X