├── .gitignore ├── LICENSE.GPL3-EXCEPT ├── LICENSE.GPLv3 ├── README.md ├── benchmarks ├── auto │ ├── animations │ │ └── comparison │ │ │ ├── README.md │ │ │ ├── moving-images-animations.qml │ │ │ ├── moving-images-animators.qml │ │ │ ├── moving-images-script.qml │ │ │ └── moving-images-simple.qml │ ├── bindings │ │ └── compositesingleton.qml │ ├── canvas │ │ └── canvas_text_simple.qml │ ├── changes │ │ ├── README.md │ │ ├── changing_over_isolated.qml │ │ ├── changing_over_isolated_with_clip.qml │ │ ├── changing_over_isolated_with_clip_rotated.qml │ │ ├── changing_text_oneofmany.qml │ │ └── changing_texts.qml │ ├── creation │ │ ├── README.md │ │ ├── layouts │ │ │ ├── delegates_column.qml │ │ │ ├── delegates_columnlayout.qml │ │ │ ├── delegates_flow.qml │ │ │ ├── delegates_grid.qml │ │ │ ├── delegates_gridlayout.qml │ │ │ ├── delegates_row.qml │ │ │ └── delegates_rowlayout.qml │ │ ├── qml.basictypes │ │ │ ├── delegates_basictype_bool.qml │ │ │ ├── delegates_basictype_double.qml │ │ │ ├── delegates_basictype_int.qml │ │ │ ├── delegates_basictype_real.qml │ │ │ ├── delegates_basictype_string.qml │ │ │ ├── delegates_basictype_url.qml │ │ │ ├── delegates_basictype_var_array.qml │ │ │ ├── delegates_basictype_var_bool.qml │ │ │ ├── delegates_basictype_var_int.qml │ │ │ ├── delegates_basictype_var_object.qml │ │ │ ├── delegates_basictype_var_string.qml │ │ │ ├── delegates_basictype_variant_array.qml │ │ │ ├── delegates_basictype_variant_bool.qml │ │ │ ├── delegates_basictype_variant_int.qml │ │ │ ├── delegates_basictype_variant_object.qml │ │ │ └── delegates_basictype_variant_string.qml │ │ ├── qml.modelaccess │ │ │ ├── modelaccess_bool.qml │ │ │ ├── modelaccess_bytearray.qml │ │ │ ├── modelaccess_color.qml │ │ │ ├── modelaccess_datetime.qml │ │ │ ├── modelaccess_int.qml │ │ │ ├── modelaccess_jsvalue.qml │ │ │ ├── modelaccess_point.qml │ │ │ ├── modelaccess_real.qml │ │ │ ├── modelaccess_rect.qml │ │ │ ├── modelaccess_size.qml │ │ │ ├── modelaccess_string.qml │ │ │ └── modelaccess_url.qml │ │ ├── qtgraphicaleffects │ │ │ ├── delegates_dropshadow.qml │ │ │ └── delegates_lineargradient.qml │ │ ├── quick.basictypes │ │ │ ├── delegates_basictype_color.qml │ │ │ ├── delegates_basictype_color_argb.qml │ │ │ ├── delegates_basictype_color_name.qml │ │ │ ├── delegates_basictype_date.qml │ │ │ ├── delegates_basictype_date_object.qml │ │ │ ├── delegates_basictype_matrix4x4.qml │ │ │ ├── delegates_basictype_point.qml │ │ │ ├── delegates_basictype_quaternion.qml │ │ │ ├── delegates_basictype_rect.qml │ │ │ ├── delegates_basictype_size.qml │ │ │ ├── delegates_basictype_var_size.qml │ │ │ ├── delegates_basictype_variant_size.qml │ │ │ ├── delegates_basictype_vector2d.qml │ │ │ ├── delegates_basictype_vector3d.qml │ │ │ └── delegates_basictype_vector4d.qml │ │ ├── quick.canvas │ │ │ ├── delegates_canvas_fbo_cooperative.qml │ │ │ ├── delegates_canvas_fbo_immediate.qml │ │ │ ├── delegates_canvas_fbo_threaded.qml │ │ │ ├── delegates_canvas_image_cooperative.qml │ │ │ ├── delegates_canvas_image_immediate.qml │ │ │ └── delegates_canvas_image_threaded.qml │ │ ├── quick.controls2 │ │ │ ├── delegates_busyindicator.qml │ │ │ ├── delegates_button.qml │ │ │ ├── delegates_checkbox.qml │ │ │ ├── delegates_combobox.qml │ │ │ ├── delegates_dial.qml │ │ │ ├── delegates_itemdelegate.qml │ │ │ ├── delegates_label.qml │ │ │ ├── delegates_menu_custom.qml │ │ │ ├── delegates_menuitem.qml │ │ │ ├── delegates_progressbar.qml │ │ │ ├── delegates_radiobutton.qml │ │ │ ├── delegates_scrollbar.qml │ │ │ ├── delegates_scrollview.qml │ │ │ ├── delegates_slider.qml │ │ │ ├── delegates_spinbox.qml │ │ │ ├── delegates_switch.qml │ │ │ ├── delegates_tabbar.qml │ │ │ ├── delegates_textarea.qml │ │ │ ├── delegates_textfield.qml │ │ │ └── delegates_tumbler.qml │ │ ├── quick.image │ │ │ ├── delegates_image.qml │ │ │ ├── delegates_image_alpha.qml │ │ │ ├── delegates_image_antialiased.qml │ │ │ ├── delegates_image_async.qml │ │ │ └── delegates_image_solid.qml │ │ ├── quick.item │ │ │ ├── delegates_item.qml │ │ │ ├── delegates_item_bindings.qml │ │ │ ├── delegates_item_childrenRect.qml │ │ │ ├── delegates_item_empty.qml │ │ │ ├── delegates_item_empty_jscreation.qml │ │ │ ├── delegates_item_script.qml │ │ │ ├── delegates_item_states.qml │ │ │ ├── delegates_item_z.qml │ │ │ ├── item_anchors.qml │ │ │ └── item_size.qml │ │ ├── quick.rectangle │ │ │ ├── delegates_rect.qml │ │ │ ├── delegates_rect_blended.qml │ │ │ ├── delegates_rect_border.qml │ │ │ ├── delegates_rect_gradient.qml │ │ │ └── delegates_rect_radius.qml │ │ ├── quick.text │ │ │ ├── comparison │ │ │ │ ├── delegates_kerning.qml │ │ │ │ ├── delegates_nokerning.qml │ │ │ │ └── delegates_noshaping.qml │ │ │ ├── delegates_longtext.qml │ │ │ ├── delegates_longtext_arabic.qml │ │ │ ├── delegates_longtext_chinese.qml │ │ │ ├── delegates_longtext_hindi.qml │ │ │ ├── delegates_text.qml │ │ │ ├── delegates_text_arabic.qml │ │ │ ├── delegates_text_chinese.qml │ │ │ ├── delegates_text_decoration_bold.qml │ │ │ ├── delegates_text_decoration_italic.qml │ │ │ ├── delegates_text_decoration_strikeout.qml │ │ │ ├── delegates_text_decoration_underline.qml │ │ │ ├── delegates_text_elide.qml │ │ │ ├── delegates_text_hindi.qml │ │ │ ├── delegates_text_nativerendering.qml │ │ │ ├── delegates_text_plain.qml │ │ │ ├── delegates_text_richtext.qml │ │ │ ├── delegates_text_styled.qml │ │ │ ├── delegates_textedit.qml │ │ │ └── delegates_textinput.qml │ │ ├── quick.transforms │ │ │ ├── delegates_item_rotated.qml │ │ │ ├── delegates_item_rotated_transform.qml │ │ │ ├── delegates_item_scaled.qml │ │ │ ├── delegates_item_scaled_transform.qml │ │ │ └── delegates_item_translated.qml │ │ ├── quick.validators │ │ │ ├── delegates_doublevalidator.qml │ │ │ ├── delegates_intvalidator.qml │ │ │ └── delegates_regexpvalidator.qml │ │ └── quick │ │ │ ├── compile.bat │ │ │ ├── delegates_flickable.qml │ │ │ ├── delegates_flipable.qml │ │ │ ├── delegates_focusscope.qml │ │ │ ├── delegates_fontloader.qml │ │ │ ├── delegates_fontmetrics.qml │ │ │ ├── delegates_gridview.qml │ │ │ ├── delegates_listview.qml │ │ │ ├── delegates_loader.qml │ │ │ ├── delegates_mousearea.qml │ │ │ ├── delegates_multipointtoucharea.qml │ │ │ ├── delegates_pathview.qml │ │ │ ├── delegates_pincharea.qml │ │ │ ├── delegates_qobject.qml │ │ │ ├── delegates_qobject_large_array.qml │ │ │ ├── delegates_shadereffect.qml │ │ │ ├── delegates_shadereffect_props.qml │ │ │ ├── delegates_shadereffectsource.qml │ │ │ ├── delegates_textmetrics.qml │ │ │ ├── red.frag │ │ │ └── red.frag.qsb │ ├── js │ │ ├── date_getYear.qml │ │ ├── fib10.qml │ │ ├── sum10k.qml │ │ └── sum10k_fixed.qml │ └── layouts │ │ └── gridlayout_large.qml ├── benchmarks.md └── manual │ ├── gputhroughput │ ├── README.md │ ├── blendedrect.qml │ ├── blendedtexture.qml │ ├── drawcalls.qml │ ├── gaussblur.qml │ ├── grapes.jpg │ ├── opaquerect.qml │ └── opaquetexture.qml │ └── v8bench │ ├── README.md │ ├── v8-Crypto.qml │ ├── v8-DeltaBlue.qml │ ├── v8-EarleyBoyer.qml │ ├── v8-RayTrace.qml │ ├── v8-RegExp.qml │ ├── v8-Richards.qml │ └── v8-Splay.qml ├── qmlbench.pro ├── shared ├── Globals.qml ├── alpha.png ├── butterfly-collapsed.png ├── butterfly-half.png ├── butterfly-wide.png ├── qmldir └── solid.png ├── src ├── 3rdparty │ ├── 0001-Adaptations-to-run-v8-bench.js-in-qmlbench.patch │ └── v8-bench.js ├── Benchmark.qml ├── CreationBenchmark.qml ├── Shell_SustainedFpsWithCount.qml ├── Shell_SustainedFpsWithStaticCount.qml ├── Shell_TotalFramesWithStaticCount.qml ├── V8Benchmark.qml ├── benchmark.h ├── benchmarkrunner.cpp ├── benchmarkrunner.h ├── compat │ ├── qcommandlineoption.cpp │ ├── qcommandlineoption.h │ ├── qcommandlineparser.cpp │ └── qcommandlineparser.h ├── main.cpp ├── options.h ├── qmlbench.cpp ├── qmlbench.h ├── qmlbench.qrc ├── resultrecorder.cpp ├── resultrecorder.h ├── src.pro ├── testmodel.cpp └── testmodel.h └── tools ├── compareresults ├── compareresults.pro └── main.cpp ├── decidefps ├── decidefps.pro └── main.cpp └── tools.pro /.gitignore: -------------------------------------------------------------------------------- 1 | *.qmlc 2 | *.o 3 | *.moc 4 | moc_*.cpp 5 | moc_predefs.h 6 | qrc_qmlbench.cpp 7 | src/qmlbench 8 | tools/decidefps/decidefps 9 | tools/compareresults/compareresults 10 | .qmake.stash 11 | Makefile 12 | *.pro.user 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # qmlbench 2 | 3 | qmlbench is a tool for benchmarking Qt, QML and QtQuick as a whole stack rather 4 | than in isolation. The benchmarks it provides exercise a very large part of 5 | Quick, QML, Gui, Core, and as a result can be considered a decent metric for 6 | overall Qt performance. 7 | 8 | As with any benchmarking, if you want reliable results, the first thing you must 9 | attend to is ensuring that the system under test is doing the absolute minimum 10 | possible. "Typical" operating systems (OS X, Ubuntu, ...) all have a lot of 11 | "background noise" in the form of file indexing, automatic updates. All of this 12 | should be disabled if possible. You may want to consider disabling networking 13 | for the duration of the benchmarking run to help keep things "quiet". 14 | 15 | In terms of running applications, you should have the bare minimum if at all 16 | possible. No email clients, no IRC, no media players. Only your terminal, and 17 | qmlbench should be running. If possible (e.g. on Linux), you may want to even 18 | look into setting up a custom desktop environment session that doesn't launch 19 | anything else (so no gnome-session etc). 20 | 21 | Remember: Any background process that might pop up will cause instability in 22 | the results! 23 | 24 | # shells 25 | 26 | qmlbench provides a number of "shells", which are the containers for the 27 | benchmarking logic. Different shells work in different ways, and might measure 28 | different things. 29 | 30 | ## frame-count shell 31 | 32 | The frame-count shell constantly performs a set number of operations each frame, 33 | for a given amount of (real world) time, and counts the number of frames the 34 | window is able to generate. If the GL drivers & OS support it, vsync will be 35 | disabled. 36 | 37 | The frame-count shell is used for automated benchmark runs, as it is less 38 | susceptible to variance than the sustained-fps shell. 39 | 40 | ## sustained-fps shell 41 | 42 | The sustained-fps shell provides a measure of how many times a certain operation 43 | can be performed per frame while sustaining a velvet smooth framerate matching the 44 | host's screen refresh rate. 45 | 46 | Summarized, it can be looked at as a test of: 47 | *How much stuff can I do before things start to fall apart.*. 48 | 49 | Note that the sustained-fps shell _requires_ a stable frame rate (see the 50 | prerequisites section), which is often hard for systems to provide, so this 51 | shell may not be a good choice for you, and may not be appropriate for automated 52 | regression testing. 53 | 54 | ### prerequisites 55 | 56 | As already mentioned, the goal of the sustained-fps shell is to find how much is 57 | possible while hitting a perfect framerate. So the first goal is to verify 58 | that your system is capable of hitting a perfect framerate at all. This is 59 | called the swap test. Test it by running the following, and observing the screen: 60 | 61 | > ./tools/decidefps/decidefps 62 | 63 | If you see a pulsating purple rectangle you are in good shape. If you see 64 | flashes of red and/or blue or if the purple rectangle has horizontal regions 65 | of red and blue, your system is not able to hit a perfect framerate. 66 | 67 | Fix that first, or you will not get stable/sensible results from the 68 | sustained-fps shell. 69 | 70 | Lastly, check if your system is running with the 'basic' render loop 71 | (QSG_INFO=1 in the environment will tell you). If you are, you will most likely 72 | not be able to get velvet FPS because the animations are timer driven and will 73 | skip once or twice per frame by default. If threaded is not an option for 74 | whatever reason, try with QSG_RENDER_LOOP=windows (which uses vsync driven 75 | animations). 76 | 77 | ## static-count shell 78 | 79 | The static-count shell constantly performs a set number of operations (the 80 | staticCount property in benchmarks) each frame. It is useful for profiling. 81 | 82 | You can override the staticCount value by passing a `--count N` command line 83 | argument, where N is the staticCount you want to use instead. 84 | 85 | The static-count shell is most useful for profiling, as it will repeat the same 86 | operation continuously. 87 | 88 | ## the qmlbench tool 89 | 90 | It comes with a number of default settings which aim to help give stable numbers: 91 | 92 | * ``--fps-override``: This one may be very important when using the 93 | sustained-fps shell. When you ran decidefps, 94 | it told you a fairly accurate FPS. If QScreen reports something different 95 | through refreshRate() the calibration won't work and the resulting numbers 96 | won't mean anything. On OSX, we should be mostly good. On Linux, it is not 97 | uncommon that the QScreen value is wrong so this option is needed as an 98 | override to make the tests stable. The tool has not been tested on Windows at 99 | the time when this is written. 100 | * ``--delay [ms]``: defaults to 2 seconds. An idle time after showing the window 101 | before starting the benchmark. Especially useful on OSX where the system 102 | specific to-fullscreen animation takes a while. And that to-fullscreen will 103 | severly damage the benchmarks. 104 | * ``--help``: Tells you the other options. 105 | 106 | ## the actual benchmarks 107 | 108 | Benchmarks are divided into two types, automated, and manual. The automated 109 | tests are useful for regression testing, and the manual tests are useful for 110 | determining the capabilities of a new piece of hardware. 111 | 112 | To run all the automated tests, simply run this, and go have lunch (it is not a 113 | fast process): 114 | 115 | > ./src/qmlbench benchmarks/auto/ 116 | 117 | You can also run a subset of them by providing that directory instead: 118 | 119 | > ./src/qmlbench benchmarks/auto/creation/quick.item/ 120 | 121 | Or even individual tests, by passing the filenames directly. 122 | 123 | ## the results 124 | 125 | Here's an example of running `src/qmlbench --shell frame-count /Users/mitch/dev/qmlbench/benchmarks/auto/creation/quick.controls2/delegates_tumbler.qml` on macOS: 126 | 127 | ID: 128 | OS: macOS High Sierra (10.13) 129 | QPA: cocoa 130 | GL_VENDOR: ATI Technologies Inc. 131 | GL_RENDERER: AMD Radeon Pro 460 OpenGL Engine 132 | GL_VERSION: 2.1 ATI-1.60.24 133 | running: /Users/mitch/dev/qmlbench/benchmarks/auto/creation/quick.controls2/delegates_tumbler.qml 134 | 153 frames 135 | 152 frames 136 | 154 frames 137 | 154 frames 138 | 153 frames 139 | Average: 153.2 frames; MedianAll=153; StdDev=0.83666, CoV=0.00546123 140 | All done... 141 | 142 | The test was repeated 5 times, and for each run, the frames are printed. For the frame-count shell, the higher the number of frames is, the better. 143 | 144 | - "Average: 153.2 frames" - this is the average of each run. 145 | - "MedianAll=153" - the [median](https://en.wikipedia.org/wiki/Median) of all of the runs: 146 | (152, 153, 153, 154, 154) 147 | ^ 148 | - "StdDev=0.83666" - the [standard deviation](https://en.wikipedia.org/wiki/Standard_deviation). The lower the better. 149 | - "CoV=0.00546123" - the [coefficient of variation](https://en.wikipedia.org/wiki/Coefficient_of_variation). The lower the better; a general guide is to aim for less than 5% CoV. 150 | 151 | ## Creating benchmarks 152 | 153 | See [Benchmarks/benchmarks.md](./benchmarks/benchmarks.md) 154 | -------------------------------------------------------------------------------- /benchmarks/auto/animations/comparison/README.md: -------------------------------------------------------------------------------- 1 | # comparison 2 | 3 | These benchmarks compare a number of different ways of moving images around, and 4 | are help validate the casual gaming idea which should be very viable with QML. 5 | 6 | The benchmarks give an indication of how many animated items can run 7 | simultaneously in the UI. It should be in the thousands. 8 | 9 | One quirk if you run these is that on a threaded renderloop, the animation one 10 | runs faster than animators. This is because the work is broken into two major 11 | chunks. One is doing the animation while the other is doing the batching in the 12 | renderer and scheduling the rendering. If those happen on separate threads, we 13 | get better parallelization so 'animation' comes out better. 14 | 15 | However, if you try again with QSG_RENDER_LOOP=windows in the environment, 16 | you'll see that if it all happens on the same thread, then animators are a bit 17 | cheaper (because they are simpler). 18 | -------------------------------------------------------------------------------- /benchmarks/auto/animations/comparison/moving-images-animations.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QmlBench 1.0 3 | 4 | // Move images around using Animation types, to be compared with a number of 5 | // other similar ways to move them around. 6 | Benchmark { 7 | id: root; 8 | 9 | count: 500 10 | staticCount: 20000 11 | 12 | Repeater { 13 | model: root.count 14 | Image { 15 | source: "../../../../shared/butterfly-wide.png" 16 | x: QmlBench.getRandom() * (root.width - width) 17 | y: QmlBench.getRandom() * (root.height - height) 18 | width: 40 19 | height: 40 20 | 21 | SequentialAnimation on rotation { 22 | NumberAnimation { from: -10; to: 10; duration: 500; easing.type: Easing.InOutCubic } 23 | NumberAnimation { from: 10; to: -10; duration: 500; easing.type: Easing.InOutCubic } 24 | loops: Animation.Infinite 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /benchmarks/auto/animations/comparison/moving-images-animators.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QmlBench 1.0 3 | 4 | // Move images around using Animator types, to be compared with a number of 5 | // other similar ways to move them around. 6 | Benchmark { 7 | id: root; 8 | 9 | count: 500 10 | staticCount: 20000 11 | 12 | Repeater { 13 | model: root.count 14 | Image { 15 | source: "../../../../shared/butterfly-wide.png" 16 | x: QmlBench.getRandom() * (root.width - width) 17 | y: QmlBench.getRandom() * (root.height - height) 18 | width: 40 19 | height: 40 20 | 21 | SequentialAnimation on rotation { 22 | RotationAnimator { from: -10; to: 10; duration: 500; easing.type: Easing.InOutCubic } 23 | RotationAnimator { from: 10; to: -10; duration: 500; easing.type: Easing.InOutCubic } 24 | loops: Animation.Infinite 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /benchmarks/auto/animations/comparison/moving-images-script.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QmlBench 1.0 3 | 4 | // Move images around using a property binding, to be compared with a number of 5 | // other similar ways to move them around. 6 | Benchmark { 7 | id: root; 8 | 9 | count: 500 10 | staticCount: 20000 11 | 12 | Repeater { 13 | model: root.count 14 | Image { 15 | source: "../../../../shared/butterfly-wide.png" 16 | x: QmlBench.getRandom() * (root.width - width) 17 | y: QmlBench.getRandom() * (root.height - height) 18 | width: 40 19 | height: 40 20 | 21 | property real t; 22 | rotation: 10 * Math.sin(t * Math.PI * 2 + Math.PI); 23 | 24 | SequentialAnimation on t { 25 | NumberAnimation { from: 0; to: 1; duration: 1000; } 26 | loops: Animation.Infinite 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /benchmarks/auto/animations/comparison/moving-images-simple.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.2 2 | import QmlBench 1.0 3 | 4 | // Move images around using a global property binding, to be compared with a 5 | // number of other similar ways to move them around. 6 | Benchmark { 7 | id: root; 8 | 9 | count: 500 10 | staticCount: 20000 11 | 12 | property int frameCount 13 | onTChanged: { 14 | frameCount++ 15 | } 16 | 17 | Repeater { 18 | model: root.count 19 | Image { 20 | source: "../../../../shared/butterfly-wide.png" 21 | x: QmlBench.getRandom() * (root.width - width) 22 | y: QmlBench.getRandom() * (root.height - height) 23 | width: 40 24 | height: 40 25 | rotation: index + frameCount 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /benchmarks/auto/bindings/compositesingleton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import "../../../shared" 4 | 5 | // Tests the creation of Items bound to a QML-defined singleton 6 | CreationBenchmark { 7 | id: root; 8 | count: 50; 9 | staticCount: 2500; 10 | delegate: Item { 11 | x: Globals.realProp 12 | y: Globals.intProp 13 | smooth: Globals.boolProp 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/auto/canvas/canvas_text_simple.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Testing the performance of canvas-based text rendering 5 | Item { 6 | id: root; 7 | property int count: 100; 8 | property int staticCount: 1000; 9 | 10 | property real t; 11 | NumberAnimation on t { from: 0; to: 1; duration: 2347; loops: Animation.Infinite } 12 | 13 | Canvas { 14 | anchors.fill: parent 15 | 16 | property real t: root.t; 17 | onTChanged: requestPaint(); 18 | 19 | onPaint: { 20 | var ctx = getContext("2d"); 21 | ctx.clearRect(0, 0, width, height); 22 | var str = "" + Math.floor( t * 1000 ) / 1000; 23 | 24 | for (var i = 0; i < root.count; ++i) { 25 | ctx.fillText(str, QmlBench.getRandom() * root.width, QmlBench.getRandom() * root.height); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /benchmarks/auto/changes/README.md: -------------------------------------------------------------------------------- 1 | # changes 2 | 3 | These benchmarks help measure the impact of various types of changes in a scene 4 | (for instance, changing one text item out of many, changing all text items at 5 | once). 6 | -------------------------------------------------------------------------------- /benchmarks/auto/changes/changing_over_isolated.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // This benchmark determines if clipping two subtrees isolates them, 5 | // such that one changing subtree won't affect performance because 6 | // of the other. 7 | CreationBenchmark { 8 | id: root; 9 | count: 1000; 10 | staticCount: 2000 11 | 12 | // Boolean because: isolating via clip either keeps performance good, or 13 | // performance is awful if we break it. 14 | isBooleanResult: true; 15 | 16 | // Create a static subtree of items. This tree does not change. 17 | Item { 18 | anchors.fill: parent 19 | clip: true 20 | Repeater { 21 | id: repeater 22 | model: root.count 23 | 24 | Rectangle { 25 | color: Qt.hsla(QmlBench.getRandom(), 0.9, 0.4) 26 | width: 20 27 | height: 20 28 | x: QmlBench.getRandom() * root.width 29 | y: QmlBench.getRandom() * root.height 30 | 31 | Text { 32 | color: "white" 33 | text: "X" 34 | anchors.centerIn: parent 35 | font.pixelSize: 10 36 | } 37 | } 38 | } 39 | } 40 | 41 | // Create a subtree containing a single item. This tree does change. 42 | Item { 43 | anchors.fill: parent 44 | clip: true 45 | Text { 46 | anchors.centerIn: parent 47 | text: "test: " + root.t; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /benchmarks/auto/changes/changing_over_isolated_with_clip.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests that a single item changing in one subtree, and many items in another 5 | // tree, do not have bad performance when both subtrees are isolated with 6 | // "clip: true". 7 | Item { 8 | id: root; 9 | property int count: 100; 10 | property int staticCount: 2000 11 | 12 | property real t; 13 | NumberAnimation on t { from: 0; to: 1; duration: 2347; loops: Animation.Infinite } 14 | 15 | Item { 16 | anchors.fill: parent 17 | clip: true 18 | Repeater { 19 | id: repeater 20 | model: root.count 21 | 22 | Rectangle { 23 | color: Qt.hsla(QmlBench.getRandom(), 0.9, 0.4) 24 | width: 20 25 | height: 20 26 | x: QmlBench.getRandom() * root.width 27 | y: QmlBench.getRandom() * root.height 28 | clip: true 29 | 30 | Text { 31 | color: "white" 32 | text: "X" 33 | anchors.centerIn: parent 34 | font.pixelSize: 10 35 | } 36 | } 37 | } 38 | } 39 | 40 | Item { 41 | anchors.fill: parent 42 | clip: true 43 | Text { 44 | anchors.centerIn: parent 45 | text: "test: " + root.t; 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /benchmarks/auto/changes/changing_over_isolated_with_clip_rotated.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests that a single item changing in one subtree, and many items in another 5 | // tree, do not have bad performance when both subtrees are isolated with 6 | // "clip: true". 7 | // 8 | // Different from changing_over_isolated_with_clip, we also rotate, as this 9 | // can't just be clipped with scissoring. 10 | // 11 | // TODO: consider whether it makes sense to test this as a specific render 12 | // test, changing_over_isolated_with_clip covers the clipping part well enough 13 | // that perhaps we don't need this approach. Useful for now, though. 14 | Item { 15 | id: root; 16 | property int count: 1000; 17 | property int staticCount: 2000 18 | 19 | property real t; 20 | NumberAnimation on t { from: 0; to: 1; duration: 2347; loops: Animation.Infinite } 21 | 22 | Item { 23 | anchors.fill: parent 24 | clip: true 25 | Repeater { 26 | id: repeater 27 | model: root.count 28 | 29 | Rectangle { 30 | color: Qt.hsla(QmlBench.getRandom(), 0.9, 0.4) 31 | width: 20 32 | height: 20 33 | x: QmlBench.getRandom() * root.width 34 | y: QmlBench.getRandom() * root.height 35 | clip: true 36 | rotation: 10 37 | 38 | Text { 39 | color: "white" 40 | text: "X" 41 | anchors.centerIn: parent 42 | font.pixelSize: 10 43 | } 44 | } 45 | } 46 | } 47 | 48 | Item { 49 | anchors.fill: parent 50 | clip: true 51 | Text { 52 | anchors.centerIn: parent 53 | text: "test: " + root.t; 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /benchmarks/auto/changes/changing_text_oneofmany.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Testing the performance of changing 1 Text in a scene vs all (changing_texts) 5 | Item { 6 | id: root; 7 | property int count: 100 8 | property int staticCount: 1000; 9 | 10 | property real t; 11 | NumberAnimation on t { from: 0; to: 1000; duration: 1000; loops: Animation.Infinite } 12 | 13 | Repeater { 14 | id: repeater 15 | model: root.count 16 | Text { 17 | x: QmlBench.getRandom() * root.width 18 | y: QmlBench.getRandom() * root.height 19 | text: index == 0 ? Math.round(t) : index; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /benchmarks/auto/changes/changing_texts.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Testing the performance of changing all texts in a scene vs 1 (text_oneofmany) 5 | Item { 6 | id: root; 7 | property int count: 100; 8 | property int staticCount: 1000; 9 | 10 | property real t; 11 | NumberAnimation on t { from: 0; to: 1; duration: 2347; loops: Animation.Infinite } 12 | 13 | Repeater { 14 | id: repeater 15 | model: root.count 16 | Text { 17 | x: QmlBench.getRandom() * root.width 18 | y: QmlBench.getRandom() * root.height 19 | text: Math.floor( root.t * 1000 ) / 1000; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/README.md: -------------------------------------------------------------------------------- 1 | # creation 2 | 3 | This is a suite of tests to find out how good we are with creation, rendering 4 | and destruction of objects. Some of the tests are also written in such a way 5 | that they can be compared between each other -- these are usually noted in the 6 | descriptive comment at the top of the test. 7 | 8 | Creation is an important factor: our items should be light, as creating a dialog 9 | or page of UI can often creating a few hundred different items (especially Text, 10 | Item, Rectangle, etc). In addition to this, there's code outside of our control 11 | on the application end: JS logic, model interaction, database or file I/O all 12 | comes in addition - so we need to leave plenty of performance left over for the 13 | end user. 14 | 15 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/layouts/delegates_column.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of a Column, to be compared with ColumnLayout. 5 | CreationBenchmark { 6 | id: root; 7 | count: 20; 8 | staticCount: 1000; 9 | delegate: Column { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | Rectangle { 13 | width: 50 14 | height: 10 15 | color: "red" 16 | } 17 | Rectangle { 18 | width: 50 19 | height: 10 20 | color: "red" 21 | } 22 | Rectangle { 23 | width: 50 24 | height: 10 25 | color: "red" 26 | } 27 | Rectangle { 28 | width: 50 29 | height: 10 30 | color: "red" 31 | } 32 | Rectangle { 33 | width: 50 34 | height: 10 35 | color: "red" 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/layouts/delegates_columnlayout.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Layouts 1.0 4 | 5 | // Tests the creation of a ColumnLayout, to be compared with Column. 6 | CreationBenchmark { 7 | id: root; 8 | count: 20; 9 | staticCount: 1000; 10 | delegate: ColumnLayout { 11 | x: QmlBench.getRandom() * (root.width - width) 12 | y: QmlBench.getRandom() * (root.height - height) 13 | Rectangle { 14 | width: 50 15 | height: 10 16 | color: "red" 17 | } 18 | Rectangle { 19 | width: 50 20 | height: 10 21 | color: "red" 22 | } 23 | Rectangle { 24 | width: 50 25 | height: 10 26 | color: "red" 27 | } 28 | Rectangle { 29 | width: 50 30 | height: 10 31 | color: "red" 32 | } 33 | Rectangle { 34 | width: 50 35 | height: 10 36 | color: "red" 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/layouts/delegates_flow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of a Flow layout 5 | CreationBenchmark { 6 | id: root; 7 | count: 20; 8 | staticCount: 1000; 9 | delegate: Flow { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | Rectangle { 13 | width: 50 14 | height: 10 15 | color: "red" 16 | } 17 | Rectangle { 18 | width: 50 19 | height: 10 20 | color: "red" 21 | } 22 | Rectangle { 23 | width: 50 24 | height: 10 25 | color: "red" 26 | } 27 | Rectangle { 28 | width: 50 29 | height: 10 30 | color: "red" 31 | } 32 | Rectangle { 33 | width: 50 34 | height: 10 35 | color: "red" 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/layouts/delegates_grid.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of a Grid, to be compared with GridLayout 5 | CreationBenchmark { 6 | id: root; 7 | count: 20; 8 | staticCount: 1000; 9 | delegate: Grid { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | Rectangle { 13 | width: 50 14 | height: 10 15 | color: "red" 16 | } 17 | Rectangle { 18 | width: 50 19 | height: 10 20 | color: "red" 21 | } 22 | Rectangle { 23 | width: 50 24 | height: 10 25 | color: "red" 26 | } 27 | Rectangle { 28 | width: 50 29 | height: 10 30 | color: "red" 31 | } 32 | Rectangle { 33 | width: 50 34 | height: 10 35 | color: "red" 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/layouts/delegates_gridlayout.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Layouts 1.0 4 | 5 | // Tests the creation of GridLayout, to be compared with Grid 6 | CreationBenchmark { 7 | id: root; 8 | count: 20; 9 | staticCount: 1000; 10 | delegate: GridLayout { 11 | x: QmlBench.getRandom() * (root.width - width) 12 | y: QmlBench.getRandom() * (root.height - height) 13 | columns: 2 14 | Rectangle { 15 | width: 50 16 | height: 10 17 | color: "red" 18 | } 19 | Rectangle { 20 | width: 50 21 | height: 10 22 | color: "red" 23 | } 24 | Rectangle { 25 | width: 50 26 | height: 10 27 | color: "red" 28 | } 29 | Rectangle { 30 | width: 50 31 | height: 10 32 | color: "red" 33 | } 34 | Rectangle { 35 | width: 50 36 | height: 10 37 | color: "red" 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/layouts/delegates_row.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of Row, to be compared with RowLayout 5 | CreationBenchmark { 6 | id: root; 7 | count: 20; 8 | staticCount: 1000; 9 | delegate: Row { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | Rectangle { 13 | width: 50 14 | height: 10 15 | color: "red" 16 | } 17 | Rectangle { 18 | width: 50 19 | height: 10 20 | color: "red" 21 | } 22 | Rectangle { 23 | width: 50 24 | height: 10 25 | color: "red" 26 | } 27 | Rectangle { 28 | width: 50 29 | height: 10 30 | color: "red" 31 | } 32 | Rectangle { 33 | width: 50 34 | height: 10 35 | color: "red" 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/layouts/delegates_rowlayout.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Layouts 1.0 4 | 5 | // Tests the creation of RowLayout, to be compared with Row 6 | CreationBenchmark { 7 | id: root; 8 | count: 20; 9 | staticCount: 1000; 10 | delegate: RowLayout { 11 | x: QmlBench.getRandom() * (root.width - width) 12 | y: QmlBench.getRandom() * (root.height - height) 13 | Rectangle { 14 | width: 50 15 | height: 10 16 | color: "red" 17 | } 18 | Rectangle { 19 | width: 50 20 | height: 10 21 | color: "red" 22 | } 23 | Rectangle { 24 | width: 50 25 | height: 10 26 | color: "red" 27 | } 28 | Rectangle { 29 | width: 50 30 | height: 10 31 | color: "red" 32 | } 33 | Rectangle { 34 | width: 50 35 | height: 10 36 | color: "red" 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_bool.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS bool type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property bool value: true 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_double.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS double type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property double value: 42.0 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_int.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS int type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property int value: 42 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_real.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS real type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property real value: 42.0 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_string.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS string type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property string value: "42" 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_url.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS url type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property url value: "some.url/some.resource" 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_var_array.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS var type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property var value: [42] 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_var_bool.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS var type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property var value: true 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_var_int.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS var type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property var value: 42 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_var_object.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS var type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property var value: { 42: true } 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_var_string.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS var type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property var value: "42" 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_variant_array.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS variant type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property var value: [42] 11 | } 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_variant_bool.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS variant type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property variant value: true 11 | } 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_variant_int.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS variant type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property variant value: 42 11 | } 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_variant_object.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS variant type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property variant value: { 42: true } 11 | } 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.basictypes/delegates_basictype_variant_string.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS variant type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property variant value: "42" 11 | } 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_bool.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of bool properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property bool value: model.boolRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_bytearray.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of bytearray properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property var value: model.byteArrayRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_color.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of color properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property color value: model.colorRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_datetime.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of datetime properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property date value: model.dateTimeRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_int.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of int properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property int value: model.intRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_jsvalue.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of jsvalue properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property var value: model.jsValueRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_point.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of point properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property point value: model.pointRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_real.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of real properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property real value: model.realRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_rect.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of rect properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property rect value: model.rectRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_size.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of size properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property size value: model.sizeRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_string.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of string properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property string value: model.stringRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qml.modelaccess/modelaccess_url.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests access of url properties from a C++ model 5 | Benchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | 10 | onTChanged: { 11 | testModel.rowNumber = 0 12 | testModel.rowNumber = root.count 13 | } 14 | 15 | Repeater { 16 | model: TestModel { 17 | id: testModel 18 | } 19 | delegate: Item { 20 | property url value: model.urlRole 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qtgraphicaleffects/delegates_dropshadow.qml: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2019 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | import QtQuick 2.0 30 | import QtGraphicalEffects 1.0 31 | import QmlBench 1.0 32 | 33 | CreationBenchmark { 34 | id: root 35 | count: 50 36 | staticCount: 100 37 | delegate: Rectangle { 38 | x: QmlBench.getRandom() * (root.width - width) 39 | y: QmlBench.getRandom() * (root.height - height) 40 | width: 30 41 | height: 15 42 | layer.enabled: true 43 | layer.effect: DropShadow { 44 | } 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/qtgraphicaleffects/delegates_lineargradient.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QtGraphicalEffects 1.0 3 | import QmlBench 1.0 4 | 5 | // Tests the creation of LinearGradient. 6 | // The values chosen match those in delegates_rect_gradient, so performance can be directly compared 7 | CreationBenchmark { 8 | id: root; 9 | count: 50; 10 | staticCount: 2500; 11 | delegate: LinearGradient { 12 | x: QmlBench.getRandom() * (root.width - width) 13 | y: QmlBench.getRandom() * (root.height - height) 14 | width: 30 15 | height: 15 16 | gradient: Gradient { 17 | GradientStop { position: 0.0; color: "#ff0000" } 18 | GradientStop { position: 1.0; color: "#0000ff" } 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_color.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS color type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property color value: "#ff0000" 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_color_argb.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS color type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property color value: "#ffff0000" 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_color_name.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS color type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property color value: "red" 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_date.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS Date type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property date value: "2000-01-01" 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_date_object.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS Date type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property date value: new Date() 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_matrix4x4.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS matrix4x4 type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property matrix4x4 value: Qt.matrix4x4(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16); 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_point.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS point type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property point value: Qt.point(0, 20) 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_quaternion.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS quaternion type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property quaternion value: Qt.quaternion(2, 17, 0.9, 0.6) 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_rect.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS rect type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property rect value: Qt.rect(0, 0, 10, 10) 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_size.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS size type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property size value: Qt.size(0, 150) 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_var_size.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS var type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property var value: Qt.size(0, 150) 11 | } 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_variant_size.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS variant type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property variant value: Qt.size(0, 150) 11 | } 12 | } 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_vector2d.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS vector2d type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property vector2d value: Qt.vector2d(1, 2) 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_vector3d.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS vector3d type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property vector3d value: Qt.vector3d(1, 2, 0) 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.basictypes/delegates_basictype_vector4d.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of the JS vector4d type as a property. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 2500 9 | delegate: Item { 10 | property vector4d value: Qt.vector4d(1, 2, 3, 4) 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.canvas/delegates_canvas_fbo_cooperative.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Testing the performance of creating a canvas 5 | CreationBenchmark { 6 | id: root; 7 | count: 50; 8 | staticCount: 2500; 9 | delegate: Canvas { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | width: 30 13 | height: 15 14 | renderTarget: Canvas.FramebufferObject 15 | renderStrategy: Canvas.Cooperative 16 | // *just* measuring canvas creation. nothing else. 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.canvas/delegates_canvas_fbo_immediate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Testing the performance of creating a canvas 5 | CreationBenchmark { 6 | id: root; 7 | count: 50; 8 | staticCount: 2500; 9 | delegate: Canvas { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | width: 30 13 | height: 15 14 | renderTarget: Canvas.FramebufferObject 15 | renderStrategy: Canvas.Immediate 16 | // *just* measuring canvas creation. nothing else. 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.canvas/delegates_canvas_fbo_threaded.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Testing the performance of creating a canvas 5 | CreationBenchmark { 6 | id: root; 7 | count: 50; 8 | staticCount: 2500; 9 | delegate: Canvas { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | width: 30 13 | height: 15 14 | renderTarget: Canvas.FramebufferObject 15 | renderStrategy: Canvas.Threaded 16 | // *just* measuring canvas creation. nothing else. 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.canvas/delegates_canvas_image_cooperative.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Testing the performance of creating a canvas 5 | CreationBenchmark { 6 | id: root; 7 | count: 50; 8 | staticCount: 2500; 9 | delegate: Canvas { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | width: 30 13 | height: 15 14 | renderTarget: Canvas.Image 15 | renderStrategy: Canvas.Cooperative 16 | // *just* measuring canvas creation. nothing else. 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.canvas/delegates_canvas_image_immediate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Testing the performance of creating a canvas 5 | CreationBenchmark { 6 | id: root; 7 | count: 50; 8 | staticCount: 2500; 9 | delegate: Canvas { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | width: 30 13 | height: 15 14 | renderTarget: Canvas.Image 15 | renderStrategy: Canvas.Immediate 16 | // *just* measuring canvas creation. nothing else. 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.canvas/delegates_canvas_image_threaded.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Testing the performance of creating a canvas 5 | CreationBenchmark { 6 | id: root; 7 | count: 50; 8 | staticCount: 2500; 9 | delegate: Canvas { 10 | x: QmlBench.getRandom() * (root.width - width) 11 | y: QmlBench.getRandom() * (root.height - height) 12 | width: 30 13 | height: 15 14 | renderTarget: Canvas.Image 15 | renderStrategy: Canvas.Threaded 16 | // *just* measuring canvas creation. nothing else. 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_busyindicator.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's BusyIndicator type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: BusyIndicator { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | running: index % 2 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_button.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's Button type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: Button { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | text: "Button" 14 | down: index % 2 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_checkbox.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's CheckBox type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: CheckBox { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | text: "CheckBox" 14 | checked: index % 2 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_combobox.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's ComboBox type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 250 10 | delegate: ComboBox { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | model: 5 14 | currentIndex: index % count 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_dial.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's Dial type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 500 10 | delegate: Dial { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | value: index / root.staticCount 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_itemdelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's ItemDelegate type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: ItemDelegate { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | text: "ItemDelegate" 14 | down: index % 2 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_label.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's Label type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: Label { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | text: "Qt Quick!" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_menu_custom.qml: -------------------------------------------------------------------------------- 1 | import QmlBench 1.0 2 | import QtQuick 2.10 3 | import QtQuick.Controls 2.3 4 | 5 | CreationBenchmark { 6 | id: root 7 | count: 2 8 | staticCount: 25 9 | 10 | Component { 11 | id: menuItemComponent 12 | 13 | MenuItem { 14 | contentItem: Text { 15 | text: parent.text 16 | color: "navajowhite" 17 | } 18 | background: Rectangle { 19 | color: "steelblue" 20 | } 21 | } 22 | } 23 | 24 | delegate: Item { 25 | Menu { 26 | id: menu 27 | title: "Root Menu" 28 | delegate: menuItemComponent 29 | visible: true 30 | 31 | Menu { 32 | title: "Sub-menu 1" 33 | delegate: menuItemComponent 34 | 35 | Menu { 36 | title: "Sub-sub-menu" 37 | delegate: menuItemComponent 38 | } 39 | } 40 | 41 | Menu { title: "Sub-menu 2" } 42 | Action { text: "Action 3" } 43 | Action { text: "Action 4" } 44 | Action { text: "Action 5" } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_menuitem.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's MenuItem type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: MenuItem { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | text: "MenuItem" 14 | checkable: index % 2 15 | checked: index % 2 16 | down: index % 3 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_progressbar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's ProgressBar type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: ProgressBar { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | value: index / root.staticCount 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_radiobutton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's RadioButton type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: RadioButton { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | text: "CheckBox" 14 | autoExclusive: false 15 | checked: index % 2 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_scrollbar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's ScrollBar type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: ScrollBar { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | height: 100 14 | size: index / root.staticCount 15 | pressed: index % 2 16 | active: true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_scrollview.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.2 4 | 5 | // Tests the creation of QQC2's ScrollView type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 250 10 | delegate: ScrollView { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | width: 100 14 | height: 100 15 | Item { 16 | implicitWidth: 200 17 | implicitHeight: 200 18 | } 19 | ScrollBar.vertical.active: true 20 | ScrollBar.vertical.pressed: index % 3 === 1 21 | ScrollBar.horizontal.active: true 22 | ScrollBar.horizontal.pressed: index % 3 === 2 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_slider.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's Slider type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: Slider { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | value: index / root.staticCount 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_spinbox.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's SpinBox type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 250 10 | delegate: SpinBox { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | value: index / root.staticCount * to 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_switch.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's Switch type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: Switch { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | text: "Switch" 14 | checked: index % 2 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_tabbar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's TabBar type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 250 10 | delegate: TabBar { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | currentIndex: index / root.staticCount * count 14 | TabButton { 15 | text: "Tab1" 16 | } 17 | TabButton { 18 | text: "Tab2" 19 | } 20 | TabButton { 21 | text: "Tab3" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_textarea.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's TextArea type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 500 10 | delegate: TextArea { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | text: "Text\nArea" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_textfield.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's TextField type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 1000 10 | delegate: TextField { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | text: "TextField" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.controls2/delegates_tumbler.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | import QtQuick.Controls 2.0 4 | 5 | // Tests the creation of QQC2's Tumbler type. 6 | CreationBenchmark { 7 | id: root 8 | count: 20 9 | staticCount: 250 10 | delegate: Tumbler { 11 | x: QmlBench.getRandom() * root.width - width 12 | y: QmlBench.getRandom() * root.height - height 13 | model: 5 14 | currentIndex: index % count 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.image/delegates_image.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Test the creation of an Image with fairly stock settings (synchronous, no AA) 5 | CreationBenchmark { 6 | id: root; 7 | count: 50; 8 | staticCount: 2500; 9 | 10 | property var names: [ 11 | "butterfly-wide.png", 12 | "butterfly-half.png", 13 | "butterfly-collapsed.png" 14 | ]; 15 | 16 | delegate: Image { 17 | x: QmlBench.getRandom() * (root.width - width) 18 | y: QmlBench.getRandom() * (root.height - height) 19 | source: "../../../../shared/" + root.names[index % 3]; 20 | width: 20 21 | height: 20 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.image/delegates_image_alpha.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Test the creation of an Image with an ARGB PNG 5 | // Compare with delegates_image_solid 6 | CreationBenchmark { 7 | id: root; 8 | count: 50; 9 | staticCount: 2500; 10 | 11 | delegate: Image { 12 | x: QmlBench.getRandom() * (root.width - width) 13 | y: QmlBench.getRandom() * (root.height - height) 14 | source: "../../../../shared/alpha.png" 15 | width: 20 16 | height: 20 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.image/delegates_image_antialiased.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Test the creation of an antialiased image. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50; 8 | staticCount: 2500; 9 | 10 | property var names: [ 11 | "butterfly-wide.png", 12 | "butterfly-half.png", 13 | "butterfly-collapsed.png" 14 | ]; 15 | 16 | delegate: Image { 17 | x: QmlBench.getRandom() * (root.width - width) 18 | y: QmlBench.getRandom() * (root.height - height) 19 | source: "../../../../shared/" + root.names[index % 3]; 20 | width: 20 21 | height: 20 22 | antialiasing: true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.image/delegates_image_async.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Test the creation of an asynchronously loaded image. 5 | CreationBenchmark { 6 | id: root; 7 | count: 50; 8 | staticCount: 2500; 9 | 10 | property var names: [ 11 | "butterfly-wide.png", 12 | "butterfly-half.png", 13 | "butterfly-collapsed.png" 14 | ]; 15 | 16 | delegate: Image { 17 | x: QmlBench.getRandom() * (root.width - width) 18 | y: QmlBench.getRandom() * (root.height - height) 19 | source: "../../../../shared/" + root.names[index % 3]; 20 | width: 20 21 | height: 20 22 | asynchronous: true 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.image/delegates_image_solid.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Test the creation of an Image with an RGB PNG 5 | // Compare with delegates_image_alpha 6 | CreationBenchmark { 7 | id: root; 8 | count: 50; 9 | staticCount: 2500; 10 | 11 | delegate: Image { 12 | x: QmlBench.getRandom() * (root.width - width) 13 | y: QmlBench.getRandom() * (root.height - height) 14 | source: "../../../../shared/solid.png" 15 | width: 20 16 | height: 20 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.item/delegates_item.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of Item with a few simple props. 5 | // Compare with delegates_item_empty, and delegates_item_empty_jscreation. 6 | // Compare with delegates_item_script. 7 | CreationBenchmark { 8 | id: root; 9 | count: 50 10 | staticCount: 5000 11 | delegate: Item { 12 | x: QmlBench.getRandom() * (root.width - width) 13 | y: QmlBench.getRandom() * (root.height - height) 14 | width: 30 15 | height: 15 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.item/delegates_item_bindings.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Compare with delegates_item_states 5 | CreationBenchmark { 6 | id: root; 7 | count: 50 8 | staticCount: 5000 9 | delegate: Item { 10 | id: itemInstance 11 | x: QmlBench.getRandom() * (root.width - width) 12 | y: QmlBench.getRandom() * (root.height - height) 13 | width: 30 14 | height: 15 15 | visible: 1 == 1 ? true : false 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.item/delegates_item_childrenRect.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation involving Item's childrenRect property. 5 | // This is an unusually expensive property. 6 | CreationBenchmark { 7 | id: root; 8 | count: 50 9 | staticCount: 5000 10 | delegate: Item { 11 | x: QmlBench.getRandom() * (root.width - width) 12 | y: QmlBench.getRandom() * (root.height - height) 13 | width: childrenRect.width 14 | height: childrenRect.height 15 | 16 | Item { 17 | width: 30 18 | height: 15 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.item/delegates_item_empty.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Tests the creation of an empty Item. 5 | // Compare with delegates_item_empty_jscreation 6 | CreationBenchmark { 7 | id: root 8 | count: 50; 9 | staticCount: 5000; 10 | delegate: Item { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /benchmarks/auto/creation/quick.item/delegates_item_empty_jscreation.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QmlBench 1.0 3 | 4 | // Test allocation of Item, with no Repeater or anything. 5 | // Compare with delegates_qobject & delegates_item_empty. 6 | Benchmark { 7 | id: root; 8 | count: 50; 9 | staticCount: 5000; 10 | 11 | property var items; 12 | onTChanged: { 13 | allocate(); 14 | } 15 | 16 | Component { 17 | id: component; 18 | Item { 19 | } 20 | } 21 | 22 | function allocate() { 23 | if (items && items.length) { 24 | for (var i=0; i 3 | Date: Thu, 4 May 2017 21:07:10 +0200 4 | Subject: [PATCH] Adaptations to run v8-bench.js in qmlbench 5 | 6 | We need to prevent writes to global properties. We also stub out the 7 | BenchmarkSuite running stuff, as we will be doing that ourselves. 8 | 9 | Change-Id: I647556f3d7a4e044db68754ce1f0eb0e35874536 10 | --- 11 | src/3rdparty/v8-bench.js | 26 +++++++++++++------------- 12 | 1 file changed, 13 insertions(+), 13 deletions(-) 13 | 14 | diff --git a/src/3rdparty/v8-bench.js b/src/3rdparty/v8-bench.js 15 | index 41a04fa..406c3cc 100644 16 | --- a/src/3rdparty/v8-bench.js 17 | +++ b/src/3rdparty/v8-bench.js 18 | @@ -1850,7 +1850,7 @@ function am4(i,x,w,j,c,n) { 19 | // IE7 does 9% better with am3/28 than with am4/26. 20 | // Firefox (SM) gets 10% faster with am3/28 than with am4/26. 21 | 22 | -setupEngine = function(fn, bits) { 23 | +function setupEngine(fn, bits) { 24 | BigInteger.prototype.am = fn; 25 | dbits = bits; 26 | 27 | @@ -3371,14 +3371,14 @@ RSAKey.prototype.decrypt = RSADecrypt; 28 | //RSAKey.prototype.b64_decrypt = RSAB64Decrypt; 29 | 30 | 31 | -nValue="a5261939975948bb7a58dffe5ff54e65f0498f9175f5a09288810b8975871e99af3b5dd94057b0fc07535f5f97444504fa35169d461d0d30cf0192e307727c065168c788771c561a9400fb49175e9e6aa4e23fe11af69e9412dd23b0cb6684c4c2429bce139e848ab26d0829073351f4acd36074eafd036a5eb83359d2a698d3"; 32 | -eValue="10001"; 33 | -dValue="8e9912f6d3645894e8d38cb58c0db81ff516cf4c7e5a14c7f1eddb1459d2cded4d8d293fc97aee6aefb861859c8b6a3d1dfe710463e1f9ddc72048c09751971c4a580aa51eb523357a3cc48d31cfad1d4a165066ed92d4748fb6571211da5cb14bc11b6e2df7c1a559e6d5ac1cd5c94703a22891464fba23d0d965086277a161"; 34 | -pValue="d090ce58a92c75233a6486cb0a9209bf3583b64f540c76f5294bb97d285eed33aec220bde14b2417951178ac152ceab6da7090905b478195498b352048f15e7d"; 35 | -qValue="cab575dc652bb66df15a0359609d51d1db184750c00c6698b90ef3465c99655103edbf0d54c56aec0ce3c4d22592338092a126a0cc49f65a4a30d222b411e58f"; 36 | -dmp1Value="1a24bca8e273df2f0e47c199bbf678604e7df7215480c77c8db39f49b000ce2cf7500038acfff5433b7d582a01f1826e6f4d42e1c57f5e1fef7b12aabc59fd25"; 37 | -dmq1Value="3d06982efbbe47339e1f6d36b1216b8a741d410b0c662f54f7118b27b9a4ec9d914337eb39841d8666f3034408cf94f5b62f11c402fc994fe15a05493150d9fd"; 38 | -coeffValue="3a3e731acd8960b7ff9eb81a7ff93bd1cfa74cbd56987db58b4594fb09c09084db1734c8143f98b602b981aaa9243ca28deb69b5b280ee8dcee0fd2625e53250"; 39 | +var nValue="a5261939975948bb7a58dffe5ff54e65f0498f9175f5a09288810b8975871e99af3b5dd94057b0fc07535f5f97444504fa35169d461d0d30cf0192e307727c065168c788771c561a9400fb49175e9e6aa4e23fe11af69e9412dd23b0cb6684c4c2429bce139e848ab26d0829073351f4acd36074eafd036a5eb83359d2a698d3"; 40 | +var eValue="10001"; 41 | +var dValue="8e9912f6d3645894e8d38cb58c0db81ff516cf4c7e5a14c7f1eddb1459d2cded4d8d293fc97aee6aefb861859c8b6a3d1dfe710463e1f9ddc72048c09751971c4a580aa51eb523357a3cc48d31cfad1d4a165066ed92d4748fb6571211da5cb14bc11b6e2df7c1a559e6d5ac1cd5c94703a22891464fba23d0d965086277a161"; 42 | +var pValue="d090ce58a92c75233a6486cb0a9209bf3583b64f540c76f5294bb97d285eed33aec220bde14b2417951178ac152ceab6da7090905b478195498b352048f15e7d"; 43 | +var qValue="cab575dc652bb66df15a0359609d51d1db184750c00c6698b90ef3465c99655103edbf0d54c56aec0ce3c4d22592338092a126a0cc49f65a4a30d222b411e58f"; 44 | +var dmp1Value="1a24bca8e273df2f0e47c199bbf678604e7df7215480c77c8db39f49b000ce2cf7500038acfff5433b7d582a01f1826e6f4d42e1c57f5e1fef7b12aabc59fd25"; 45 | +var dmq1Value="3d06982efbbe47339e1f6d36b1216b8a741d410b0c662f54f7118b27b9a4ec9d914337eb39841d8666f3034408cf94f5b62f11c402fc994fe15a05493150d9fd"; 46 | +var coeffValue="3a3e731acd8960b7ff9eb81a7ff93bd1cfa74cbd56987db58b4594fb09c09084db1734c8143f98b602b981aaa9243ca28deb69b5b280ee8dcee0fd2625e53250"; 47 | 48 | setupEngine(am3, 28); 49 | 50 | @@ -8984,7 +8984,7 @@ SC_ERROR_OUT = SC_DEFAULT_OUT; 51 | 52 | function RunBenchmark(name, count, run, warn) { 53 | for (var n = 0; n < count; ++n) { 54 | - result = run(); 55 | + var result = run(); 56 | if (!warn(result)) { 57 | throw new Error("Earley or Boyer did incorrect number of rewrites"); 58 | } 59 | @@ -11586,6 +11586,6 @@ function PrintScore(score) { 60 | } 61 | 62 | 63 | -BenchmarkSuite.RunSuites({ NotifyResult: PrintResult, 64 | - NotifyError: PrintError, 65 | - NotifyScore: PrintScore }); 66 | +//BenchmarkSuite.RunSuites({ NotifyResult: PrintResult, 67 | +// NotifyError: PrintError, 68 | +// NotifyScore: PrintScore }); 69 | -- 70 | 2.11.0 71 | 72 | -------------------------------------------------------------------------------- /src/Benchmark.qml: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | import QtQuick 2.0 30 | 31 | // The base of all benchmarks. Please be careful with how much you add to this. 32 | // It is not instantiated often (only once per "run"), but it is always present, 33 | // so no low-duration timers etc. 34 | Item { 35 | id: root 36 | 37 | // How many iterations to run "right now"? Note that some shells 38 | // (Shell_SustainedFpsWithCount.qml at least) dynamically alter this value 39 | // while the benchmark is running. 40 | property int count: 0 41 | 42 | // How many iterations to copy to 'count'? The 'static' shells use this 43 | // value. 44 | property int staticCount: 0 45 | 46 | // A boolean benchmark has only two meaningful outputs: good, or bad. An 47 | // contrived example of this would be a benchmark that ensured that we could 48 | // render more than 10 frames in 5 seconds of real-world time (in practice, 49 | // this isn't too useful, but there are real world cases). 50 | // 51 | // This property is simply of use to help mark these tests so they are not 52 | // misinterpreted. 53 | property bool isBooleanResult: false; 54 | 55 | // Used to provide a constant "tick" that benchmarks can hook into. 56 | property real t 57 | NumberAnimation on t { from: 0; to: 1; duration: 1000; loops: Animation.Infinite } 58 | } 59 | -------------------------------------------------------------------------------- /src/CreationBenchmark.qml: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | import QtQuick 2.0 30 | import QmlBench 1.0 31 | 32 | // The base of all *creation* benchmarks. 33 | // A creation benchmark is something that attempts to create 'count' items, and 34 | // render 'count' items, as driven by the shell. 35 | Benchmark { 36 | property alias delegate: internalRepeater.delegate 37 | property alias repeater: internalRepeater 38 | 39 | // Whenever the frame tick happens, force the destruction and recreation of 40 | // all items. 41 | onTChanged: { 42 | internalRepeater.model = 0; 43 | internalRepeater.model = root.count 44 | } 45 | 46 | Component.onCompleted: internalRepeater.model = root.count 47 | 48 | // The thing that makes the magic happen. 49 | Repeater { 50 | id: internalRepeater 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Shell_SustainedFpsWithStaticCount.qml: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | import QtQuick 2.0 30 | 31 | Item { 32 | id: root 33 | width: 320 34 | height: 480 35 | 36 | Component.onCompleted: { 37 | var object 38 | if (benchmark.count != -1) { 39 | object = benchmark.component.createObject(benchmarkRoot, { count: benchmark.count }); 40 | } else { 41 | object = benchmark.component.createObject(benchmarkRoot); 42 | if (!object.hasOwnProperty("count")) { 43 | print(" - error: property 'count' is lacking from: " + benchmark.input); 44 | benchmark.abort(); 45 | } 46 | 47 | if (object.hasOwnProperty("staticCount")) { 48 | object.count = object.staticCount * benchmark.hardwareMultiplier 49 | } 50 | } 51 | object.anchors.fill = benchmarkRoot; 52 | root.targetFrameRate = benchmark.screeRefreshRate; 53 | root.item = object; 54 | label.updateYerself() 55 | } 56 | 57 | property Item item; 58 | property real targetFrameRate; 59 | property real fps: 0 60 | 61 | Item { 62 | id: benchmarkRoot 63 | clip: true 64 | anchors.fill: parent 65 | } 66 | 67 | Rectangle { 68 | id: meter 69 | 70 | clip: true 71 | width: root.width 72 | height: 14 73 | anchors.right: parent.right 74 | anchors.bottom: parent.bottom 75 | 76 | color: Qt.hsla(0, 0, 1, 0.8); 77 | 78 | Rectangle { 79 | id: swapTest 80 | anchors.right: parent.right 81 | width: parent.height 82 | height: parent.height 83 | property real t; 84 | NumberAnimation on t { from: 0; to: 1; duration: 1000; loops: Animation.Infinite } 85 | property bool inv; 86 | onTChanged: { 87 | ++fpsTimer.tick; 88 | inv = !inv; 89 | } 90 | color: inv ? "red" : "blue" 91 | } 92 | 93 | Timer { 94 | id: fpsTimer 95 | running: true; 96 | repeat: true 97 | interval: benchmark.fpsInterval 98 | property var lastFrameTime: new Date(); 99 | property int tick; 100 | 101 | onTriggered: { 102 | var now = new Date(); 103 | var dt = now.getTime() - lastFrameTime.getTime(); 104 | lastFrameTime = now; 105 | var fps = (tick * 1000) / dt; 106 | root.fps = Math.round(fps * 10) / 10; 107 | tick = 0; 108 | 109 | label.updateYerself(); 110 | } 111 | } 112 | 113 | Text { 114 | id: label 115 | anchors.centerIn: parent 116 | font.pixelSize: 10 117 | 118 | function updateYerself() { 119 | var bmName = benchmark.input; 120 | var lastSlash = bmName.lastIndexOf("/"); 121 | if (lastSlash > 0) 122 | bmName = bmName.substr(lastSlash + 1); 123 | text = bmName + "; FPS=" + root.fps + "; Count=" + item.count; 124 | } 125 | } 126 | 127 | 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/Shell_TotalFramesWithStaticCount.qml: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | import QtQuick 2.0 30 | 31 | Item { 32 | id: root 33 | width: 320 34 | height: 480 35 | 36 | Component.onCompleted: { 37 | var object 38 | if (benchmark.count != -1) { 39 | object = benchmark.component.createObject(benchmarkRoot, { count: benchmark.count }); 40 | } else { 41 | object = benchmark.component.createObject(benchmarkRoot); 42 | if (!object.hasOwnProperty("count")) { 43 | print(" - error: property 'count' is lacking from: " + benchmark.input); 44 | benchmark.abort(); 45 | } 46 | 47 | if (object.hasOwnProperty("staticCount")) { 48 | object.count = object.staticCount * benchmark.hardwareMultiplier 49 | } 50 | } 51 | object.anchors.fill = benchmarkRoot; 52 | root.item = object; 53 | root.count = 0; 54 | } 55 | 56 | property Item item; 57 | property int count: 0 58 | 59 | Item { 60 | id: benchmarkRoot 61 | clip: true 62 | anchors.fill: parent 63 | } 64 | 65 | Item { 66 | id: meter 67 | 68 | clip: true 69 | width: root.width 70 | height: 14 71 | anchors.right: parent.right 72 | anchors.bottom: parent.bottom 73 | 74 | Rectangle { 75 | id: swapTest 76 | anchors.right: parent.right 77 | width: parent.height 78 | height: parent.height 79 | property real t; 80 | NumberAnimation on t { 81 | id: swapAnimation 82 | from: 0; 83 | to: 1; 84 | duration: 1000; 85 | loops: Animation.Infinite 86 | } 87 | property bool inv; 88 | property int countDown: 5; 89 | property var startedCounting 90 | onTChanged: { 91 | // Run a small countdown for the first few frames so that 92 | // benchmarks that test animation (without creation) has a 93 | // chance to stabilize before we start measuring 94 | if (countDown > 0) { 95 | --countDown; 96 | return; 97 | } else if (countDown == 0) { 98 | --countDown; 99 | startedCounting = Date.now(); 100 | } 101 | 102 | if (Date.now() - startedCounting >= benchmark.frameCountInterval) { 103 | // Stop the 't' ticker. Otherwise we may accidentally begin one 104 | // more interval, since recordOperationsPerFrame will quit us on 105 | // a queued signal. 106 | swapAnimation.running = false 107 | benchmark.recordOperationsPerFrame(root.count); 108 | } else { 109 | ++root.count; 110 | inv = !inv; 111 | } 112 | } 113 | color: inv ? "red" : "blue" 114 | } 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/V8Benchmark.qml: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | import QtQuick 2.0 30 | import QmlBench 1.0 31 | import "qrc:/3rdparty/v8-bench.js" as V8Bench 32 | 33 | // This is a harness suited for running a V8Bench suite and reporting a number. 34 | // We replace most of V8Bench's BenchmarkSuite (specifically, the step, run, etc 35 | // behavior) and do our own setup, running and teardown. 36 | // 37 | // This is a little unfortunate as it means that we can't report results that 38 | // directly compare with v8-bench.js, but hopefully our results will be more 39 | // stable (as we have less magic in how many iterations we run), and we shall 40 | // still provide useful information if a test regresses. 41 | Benchmark { 42 | id: root 43 | 44 | // The desired suite name (e.g. "Richards"). This is then found, and put 45 | // into suite. 46 | property var suiteName 47 | 48 | // The found suite object 49 | property var suite 50 | 51 | Component.onCompleted: { 52 | var suites = V8Bench.BenchmarkSuite.suites 53 | // Find suite 54 | for (var i = 0; i < suites.length; ++i) { 55 | var potentialSuite = suites[i] 56 | if (potentialSuite.name == root.suiteName) { 57 | root.suite = potentialSuite 58 | break; 59 | } 60 | } 61 | 62 | // Set it up 63 | for (var i = 0; i < suite.benchmarks.length; ++i) { 64 | var benchmark = suite.benchmarks[i] 65 | benchmark.Setup(); 66 | 67 | // And do a warmup iteration 68 | benchmark.run(); 69 | } 70 | } 71 | Component.onDestruction: { 72 | // Tear it down 73 | for (var i = 0; i < suite.benchmarks.length; ++i) { 74 | var benchmark = suite.benchmarks[i] 75 | benchmark.TearDown(); 76 | } 77 | } 78 | 79 | // Run a tick of the test 80 | onTChanged: { 81 | for (var i = 0; i < suite.benchmarks.length; ++i) { 82 | var benchmark = suite.benchmarks[i] 83 | 84 | // Do a few iterations, so we report a meaningful number. 85 | for (var j = 0; j < count; ++j) { 86 | benchmark.run(); 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/benchmark.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #ifndef BENCHMARK_H 30 | #define BENCHMARK_H 31 | 32 | #include 33 | #include 34 | 35 | struct Benchmark 36 | { 37 | Benchmark(const QString &file) 38 | : fileName(file) 39 | { 40 | } 41 | 42 | QString fileName; 43 | 44 | QList operationsPerFrame; 45 | }; 46 | 47 | #endif // BENCHMARK_H 48 | -------------------------------------------------------------------------------- /src/benchmarkrunner.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | #include "resultrecorder.h" 38 | #include "benchmarkrunner.h" 39 | 40 | BenchmarkRunner::BenchmarkRunner() 41 | : m_view(0) 42 | { 43 | } 44 | 45 | BenchmarkRunner::~BenchmarkRunner() 46 | { 47 | } 48 | 49 | void BenchmarkRunner::createView() 50 | { 51 | Q_ASSERT(m_view == 0); 52 | m_view = new QQuickView(); 53 | // Make sure proper fullscreen is possible on OSX 54 | m_view->setFlags(Qt::Window 55 | | Qt::WindowSystemMenuHint 56 | | Qt::WindowTitleHint 57 | | Qt::WindowMinMaxButtonsHint 58 | | Qt::WindowCloseButtonHint 59 | | Qt::WindowFullscreenButtonHint); 60 | m_view->setResizeMode(QQuickView::SizeRootObjectToView); 61 | m_view->rootContext()->setContextProperty("benchmark", this); 62 | 63 | m_view->resize(Options::instance.windowSize); 64 | 65 | if (Options::instance.fullscreen) 66 | m_view->showFullScreen(); 67 | else 68 | m_view->show(); 69 | m_view->raise(); 70 | } 71 | 72 | bool BenchmarkRunner::execute() 73 | { 74 | if (Options::instance.benchmarks.size() == 0) 75 | return false; 76 | 77 | if (Options::instance.destroyViewEachRun) { 78 | qWarning() << "Deleting the view. Remember, you should only do this as a debugging aid!"; 79 | delete m_view; 80 | m_view = 0; 81 | } 82 | createView(); 83 | QTimer::singleShot(Options::instance.delayedStart, this, SLOT(start())); 84 | return true; 85 | } 86 | 87 | void BenchmarkRunner::start() 88 | { 89 | Benchmark &bm = Options::instance.benchmarks.first(); 90 | 91 | if (bm.operationsPerFrame.size() == 0) 92 | std::cerr << "running: " << bm.fileName.toStdString() << std::endl; 93 | 94 | m_component = new QQmlComponent(m_view->engine(), bm.fileName); 95 | if (m_component->status() != QQmlComponent::Ready) { 96 | qWarning() << "component is not ready" << bm.fileName; 97 | foreach (const QQmlError &error, m_component->errors()) { 98 | qWarning() << "ERROR: " << error; 99 | } 100 | abort(); 101 | return; 102 | } 103 | 104 | m_view->setSource(QUrl(Options::instance.bmTemplate)); 105 | if (!m_view->rootObject()) { 106 | qWarning() << "no root object.."; 107 | abort(); 108 | return; 109 | } 110 | } 111 | 112 | void BenchmarkRunner::finished() 113 | { 114 | delete m_view; 115 | m_view = 0; 116 | std::cerr << "All done..." << std::endl; 117 | qApp->quit(); 118 | } 119 | 120 | void BenchmarkRunner::abort() 121 | { 122 | qWarning() << "Aborting..."; 123 | exit(1); 124 | } 125 | 126 | // Returns "corrected sample standard deviation". 127 | qreal stddev(qreal avg, const QList &list) 128 | { 129 | qreal dev = 0; 130 | foreach (qreal v, list) 131 | dev += (v - avg) * (v - avg); 132 | 133 | // Note: - 1 is intentional! 134 | return std::sqrt(dev / (list.size() - 1)); 135 | } 136 | 137 | qreal average(const QList &list) 138 | { 139 | qreal avg = 0; 140 | foreach (qreal r, list) 141 | avg += r; 142 | avg /= list.size(); 143 | return avg; 144 | } 145 | 146 | void BenchmarkRunner::recordOperationsPerFrame(qreal ops) 147 | { 148 | Benchmark &bm = Options::instance.benchmarks.first(); 149 | bm.operationsPerFrame << ops; 150 | ResultRecorder::recordOperationsPerFrame(ops); 151 | 152 | QList results = bm.operationsPerFrame; 153 | qreal avg = average(results); 154 | 155 | if (results.size() >= Options::instance.repeat) { 156 | std::sort(results.begin(), results.end()); 157 | qreal median = results.at(results.size() / 2); 158 | ResultRecorder::recordOperationsPerFrameAverage(avg, bm.operationsPerFrame.size(), stddev(avg, results), median); 159 | } 160 | 161 | m_component->deleteLater(); 162 | m_component = 0; 163 | 164 | bool restart = false; 165 | restart = bm.operationsPerFrame.size() < Options::instance.repeat; 166 | 167 | if (restart) { 168 | if (Options::instance.destroyViewEachRun) 169 | QMetaObject::invokeMethod(this, "execute", Qt::QueuedConnection); // recreates the view too 170 | else 171 | QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection); // recreates the view too 172 | } else { 173 | QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); 174 | } 175 | } 176 | 177 | 178 | -------------------------------------------------------------------------------- /src/benchmarkrunner.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #ifndef BENCHMARKRUNNER_H 30 | #define BENCHMARKRUNNER_H 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include "options.h" 38 | 39 | class BenchmarkRunner : public QObject 40 | { 41 | Q_OBJECT 42 | 43 | // None of these are strictly constant, but for the sake of one QML run, they are 44 | // so flag it for simplicity 45 | Q_PROPERTY(QQuickView *view READ view CONSTANT) 46 | Q_PROPERTY(QQmlComponent *component READ component CONSTANT) 47 | Q_PROPERTY(qreal screeRefreshRate READ screenRefreshRate CONSTANT) 48 | Q_PROPERTY(QString input READ input CONSTANT) 49 | Q_PROPERTY(qreal fpsTolerance READ fpsTolerance CONSTANT) 50 | Q_PROPERTY(qreal fpsInterval READ fpsInterval CONSTANT) 51 | Q_PROPERTY(bool verbose READ verbose CONSTANT) 52 | Q_PROPERTY(int count READ count CONSTANT) 53 | Q_PROPERTY(double hardwareMultiplier READ hardwareMultiplier CONSTANT) 54 | Q_PROPERTY(int frameCountInterval READ frameCountInterval CONSTANT) 55 | 56 | public: 57 | BenchmarkRunner(); 58 | ~BenchmarkRunner(); 59 | 60 | void createView(); 61 | 62 | QQuickView *view() const { return m_view; } 63 | QQmlComponent *component() const { return m_component; } 64 | qreal screenRefreshRate() const { return Options::instance.fpsOverride > 0 ? Options::instance.fpsOverride : m_view->screen()->refreshRate(); } 65 | QString input() const { return Options::instance.benchmarks.first().fileName; } 66 | 67 | qreal fpsTolerance() const { return Options::instance.fpsTolerance / 100.0; } 68 | qreal fpsInterval() const { return Options::instance.fpsInterval; } 69 | 70 | int frameCountInterval() const { return Options::instance.frameCountInterval; } 71 | 72 | bool verbose() const { return Options::instance.verbose; } 73 | 74 | int count() const { return Options::instance.count; } 75 | 76 | double hardwareMultiplier() const { return Options::instance.hardwareMultiplier; } 77 | 78 | public slots: 79 | bool execute(); 80 | void recordOperationsPerFrame(qreal count); 81 | void abort(); 82 | 83 | private slots: 84 | void start(); 85 | void finished(); 86 | 87 | private: 88 | QQuickView *m_view; 89 | QQmlComponent *m_component; 90 | }; 91 | 92 | #endif // BENCHMARKRUNNER_H 93 | 94 | -------------------------------------------------------------------------------- /src/compat/qcommandlineoption.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Laszlo Papp 4 | ** Contact: http://www.qt-project.org/legal 5 | ** 6 | ** This file is part of the QtCore module of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL21$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and Digia. For licensing terms and 14 | ** conditions see http://qt.digia.com/licensing. For further information 15 | ** use the contact form at http://qt.digia.com/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** In addition, as a special exception, Digia gives you certain additional 27 | ** rights. These rights are described in the Digia Qt LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** $QT_END_LICENSE$ 31 | ** 32 | ****************************************************************************/ 33 | 34 | #ifndef QCOMMANDLINEOPTION_H 35 | #define QCOMMANDLINEOPTION_H 36 | 37 | #include 38 | #include 39 | 40 | QT_BEGIN_NAMESPACE 41 | 42 | class QCommandLineOptionPrivate; 43 | 44 | class Q_CORE_EXPORT QCommandLineOption 45 | { 46 | public: 47 | explicit QCommandLineOption(const QString &name); 48 | explicit QCommandLineOption(const QStringList &names); 49 | /*implicit*/ QCommandLineOption(const QString &name, const QString &description, 50 | const QString &valueName = QString(), 51 | const QString &defaultValue = QString()); 52 | /*implicit*/ QCommandLineOption(const QStringList &names, const QString &description, 53 | const QString &valueName = QString(), 54 | const QString &defaultValue = QString()); 55 | QCommandLineOption(const QCommandLineOption &other); 56 | 57 | ~QCommandLineOption(); 58 | 59 | QCommandLineOption &operator=(const QCommandLineOption &other); 60 | #ifdef Q_COMPILER_RVALUE_REFS 61 | inline QCommandLineOption &operator=(QCommandLineOption &&other) 62 | { qSwap(d, other.d); return *this; } 63 | #endif 64 | 65 | inline void swap(QCommandLineOption &other) 66 | { qSwap(d, other.d); } 67 | 68 | QStringList names() const; 69 | 70 | void setValueName(const QString &name); 71 | QString valueName() const; 72 | 73 | void setDescription(const QString &description); 74 | QString description() const; 75 | 76 | void setDefaultValue(const QString &defaultValue); 77 | void setDefaultValues(const QStringList &defaultValues); 78 | QStringList defaultValues() const; 79 | 80 | private: 81 | QSharedDataPointer d; 82 | }; 83 | 84 | Q_DECLARE_SHARED(QCommandLineOption) 85 | 86 | QT_END_NAMESPACE 87 | 88 | #endif // QCOMMANDLINEOPTION_H 89 | -------------------------------------------------------------------------------- /src/compat/qcommandlineparser.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Laszlo Papp 4 | ** Contact: http://www.qt-project.org/legal 5 | ** 6 | ** This file is part of the QtCore module of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:LGPL21$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and Digia. For licensing terms and 14 | ** conditions see http://qt.digia.com/licensing. For further information 15 | ** use the contact form at http://qt.digia.com/contact-us. 16 | ** 17 | ** GNU Lesser General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser 19 | ** General Public License version 2.1 or version 3 as published by the Free 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the 22 | ** following information to ensure the GNU Lesser General Public License 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 25 | ** 26 | ** In addition, as a special exception, Digia gives you certain additional 27 | ** rights. These rights are described in the Digia Qt LGPL Exception 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 29 | ** 30 | ** $QT_END_LICENSE$ 31 | ** 32 | ****************************************************************************/ 33 | 34 | #ifndef QCOMMANDLINEPARSER_H 35 | #define QCOMMANDLINEPARSER_H 36 | 37 | #include 38 | 39 | #include 40 | #include 41 | 42 | QT_BEGIN_NAMESPACE 43 | 44 | class QCommandLineParserPrivate; 45 | class QCoreApplication; 46 | 47 | class Q_CORE_EXPORT QCommandLineParser 48 | { 49 | Q_DECLARE_TR_FUNCTIONS(QCommandLineParser) 50 | public: 51 | QCommandLineParser(); 52 | ~QCommandLineParser(); 53 | 54 | enum SingleDashWordOptionMode { 55 | ParseAsCompactedShortOptions, 56 | ParseAsLongOptions 57 | }; 58 | void setSingleDashWordOptionMode(SingleDashWordOptionMode parsingMode); 59 | 60 | bool addOption(const QCommandLineOption &commandLineOption); 61 | bool addOptions(const QList &options); 62 | 63 | QCommandLineOption addVersionOption(); 64 | QCommandLineOption addHelpOption(); 65 | void setApplicationDescription(const QString &description); 66 | QString applicationDescription() const; 67 | void addPositionalArgument(const QString &name, const QString &description, const QString &syntax = QString()); 68 | void clearPositionalArguments(); 69 | 70 | void process(const QStringList &arguments); 71 | void process(const QCoreApplication &app); 72 | 73 | bool parse(const QStringList &arguments); 74 | QString errorText() const; 75 | 76 | bool isSet(const QString &name) const; 77 | QString value(const QString &name) const; 78 | QStringList values(const QString &name) const; 79 | 80 | bool isSet(const QCommandLineOption &option) const; 81 | QString value(const QCommandLineOption &option) const; 82 | QStringList values(const QCommandLineOption &option) const; 83 | 84 | QStringList positionalArguments() const; 85 | QStringList optionNames() const; 86 | QStringList unknownOptionNames() const; 87 | 88 | Q_NORETURN void showVersion(); 89 | Q_NORETURN void showHelp(int exitCode = 0); 90 | QString helpText() const; 91 | 92 | private: 93 | Q_DISABLE_COPY(QCommandLineParser) 94 | 95 | QCommandLineParserPrivate * const d; 96 | }; 97 | 98 | QT_END_NAMESPACE 99 | 100 | #endif // QCOMMANDLINEPARSER_H 101 | -------------------------------------------------------------------------------- /src/options.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #ifndef OPTIONS_H 30 | #define OPTIONS_H 31 | 32 | #include 33 | #include 34 | 35 | #include "benchmark.h" 36 | 37 | struct Options 38 | { 39 | Options() 40 | : fullscreen(false) 41 | , verbose(false) 42 | , printJsonToStdout(false) 43 | , isSubProcess(false) 44 | , repeat(1) 45 | , delayedStart(0) 46 | , count(-1) 47 | , frameCountInterval(20000) 48 | , fpsTolerance(0.05) 49 | , fpsInterval(1000) 50 | , fpsOverride(0) 51 | , windowSize(800, 600) 52 | , hardwareMultiplier(1.0) 53 | , destroyViewEachRun(false) 54 | , timeout(10*60*1000) 55 | { 56 | } 57 | 58 | QString bmTemplate; 59 | QString id; 60 | bool fullscreen; 61 | bool verbose; 62 | bool printJsonToStdout; 63 | bool isSubProcess; 64 | int repeat; 65 | int delayedStart; 66 | int count; 67 | int frameCountInterval; 68 | qreal fpsTolerance; 69 | qreal fpsInterval; 70 | qreal fpsOverride; 71 | qreal targetFps; 72 | QSize windowSize; 73 | double hardwareMultiplier; 74 | QList benchmarks; 75 | bool destroyViewEachRun; 76 | int timeout; 77 | 78 | static Options instance; 79 | }; 80 | 81 | #endif // OPTIONS_H 82 | -------------------------------------------------------------------------------- /src/qmlbench.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #include "qmlbench.h" 30 | 31 | #define PREGENERATED_COUNT 10001 32 | 33 | QmlBench::QmlBench(QObject *parent) 34 | : QObject(parent) 35 | , m_currentRandomNumberIndex(0) 36 | { 37 | m_pregeneratedRandomNumbers = new qreal[PREGENERATED_COUNT]; 38 | for (int i = 0; i < PREGENERATED_COUNT; ++i) 39 | m_pregeneratedRandomNumbers[i] = qrand() / qreal(RAND_MAX); 40 | } 41 | 42 | QmlBench::~QmlBench() 43 | { 44 | delete[] m_pregeneratedRandomNumbers; 45 | } 46 | 47 | qreal QmlBench::getRandom() 48 | { 49 | return m_pregeneratedRandomNumbers[(m_currentRandomNumberIndex++) % PREGENERATED_COUNT]; 50 | } 51 | -------------------------------------------------------------------------------- /src/qmlbench.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 The Qt Company Ltd. 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #ifndef QMLBENCH_H 30 | #define QMLBENCH_H 31 | 32 | #include 33 | 34 | class QmlBench : public QObject 35 | { 36 | Q_OBJECT 37 | public: 38 | explicit QmlBench(QObject *parent = nullptr); 39 | ~QmlBench(); 40 | 41 | Q_INVOKABLE qreal getRandom(); 42 | 43 | private: 44 | qreal *m_pregeneratedRandomNumbers; 45 | uint m_currentRandomNumberIndex; 46 | }; 47 | 48 | #endif // QMLBENCH_H 49 | -------------------------------------------------------------------------------- /src/qmlbench.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Shell_SustainedFpsWithCount.qml 5 | Shell_SustainedFpsWithStaticCount.qml 6 | Shell_TotalFramesWithStaticCount.qml 7 | Benchmark.qml 8 | CreationBenchmark.qml 9 | V8Benchmark.qml 10 | 3rdparty/v8-bench.js 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/resultrecorder.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #include "resultrecorder.h" 41 | #include "options.h" 42 | 43 | QVariantMap ResultRecorder::m_results; 44 | bool ResultRecorder::opsAreActuallyFrames = false; 45 | 46 | void ResultRecorder::startResults(const QString &id) 47 | { 48 | // sub process will get all this. 49 | // safer that way, as then we keep OpenGL (and QGuiApplication) out of the host 50 | if (!Options::instance.isSubProcess) 51 | return; 52 | 53 | m_results["id"] = id; 54 | 55 | QString prettyProductName = 56 | #if QT_VERSION >= 0x050400 57 | QSysInfo::prettyProductName(); 58 | #else 59 | # if defined(Q_OS_IOS) 60 | QStringLiteral("iOS"); 61 | # elif defined(Q_OS_OSX) 62 | QString::fromLatin1("OSX %d").arg(QSysInfo::macVersion()); 63 | # elif defined(Q_OS_WIN) 64 | QString::fromLatin1("Windows %d").arg(QSysInfo::windowsVersion()); 65 | # elif defined(Q_OS_LINUX) 66 | QStringLiteral("Linux"); 67 | # elif defined(Q_OS_ANDROID) 68 | QStringLiteral("Android"); 69 | # else 70 | QStringLiteral("unknown"); 71 | # endif 72 | #endif 73 | 74 | QVariantMap osMap; 75 | osMap["prettyProductName"] = prettyProductName; 76 | osMap["platformPlugin"] = QGuiApplication::platformName(); 77 | m_results["os"] = osMap; 78 | m_results["qt"] = QT_VERSION_STR; 79 | m_results["command-line"] = qApp->arguments().join(' '); 80 | 81 | // The following code makes the assumption that an OpenGL context the GUI 82 | // thread will get the same capabilities as the render thread's OpenGL 83 | // context. Not 100% accurate, but it works... 84 | QOpenGLContext context; 85 | context.create(); 86 | QOffscreenSurface surface; 87 | // In very odd cases, we can get incompatible configs here unless we pass the 88 | // GL context's format on to the offscreen format. 89 | surface.setFormat(context.format()); 90 | surface.create(); 91 | if (!context.makeCurrent(&surface)) { 92 | qWarning() << "failed to acquire GL context to get version info."; 93 | return; 94 | } 95 | 96 | QOpenGLFunctions *func = context.functions(); 97 | #if QT_VERSION >= 0x050300 98 | const char *vendor = (const char *) func->glGetString(GL_VENDOR); 99 | const char *renderer = (const char *) func->glGetString(GL_RENDERER); 100 | const char *version = (const char *) func->glGetString(GL_VERSION); 101 | #else 102 | Q_UNUSED(func); 103 | const char *vendor = (const char *) glGetString(GL_VENDOR); 104 | const char *renderer = (const char *) glGetString(GL_RENDERER); 105 | const char *version = (const char *) glGetString(GL_VERSION); 106 | #endif 107 | 108 | if (!Options::instance.printJsonToStdout) { 109 | std::cout << "ID: " << id.toStdString() << std::endl; 110 | std::cout << "OS: " << prettyProductName.toStdString() << std::endl; 111 | std::cout << "QPA: " << QGuiApplication::platformName().toStdString() << std::endl; 112 | std::cout << "GL_VENDOR: " << vendor << std::endl; 113 | std::cout << "GL_RENDERER: " << renderer << std::endl; 114 | std::cout << "GL_VERSION: " << version << std::endl; 115 | } 116 | 117 | QVariantMap glInfo; 118 | glInfo["vendor"] = vendor; 119 | glInfo["renderer"] = renderer; 120 | glInfo["version"] = version; 121 | 122 | m_results["opengl"] = glInfo; 123 | 124 | context.doneCurrent(); 125 | } 126 | 127 | void ResultRecorder::recordWindowSize(const QSize &windowSize) 128 | { 129 | m_results["windowSize"] = QString::number(windowSize.width()) + "x" + QString::number(windowSize.height()); 130 | } 131 | 132 | void ResultRecorder::recordOperationsPerFrame(int ops) 133 | { 134 | Q_ASSERT(Options::instance.isSubProcess); 135 | Benchmark &bm = Options::instance.benchmarks.first(); 136 | QVariantMap benchMap = m_results[bm.fileName].toMap(); 137 | QVariantList benchResults = benchMap["results"].toList(); 138 | benchResults.append(ops); 139 | 140 | benchMap["results"] = benchResults; 141 | m_results[bm.fileName] = benchMap; 142 | 143 | if (opsAreActuallyFrames) 144 | std::cerr << " " << ops << " frames" << std::endl; 145 | else 146 | std::cerr << " " << ops << " ops/frame" << std::endl; 147 | } 148 | 149 | void ResultRecorder::recordOperationsPerFrameAverage(qreal ops, int samples, qreal stddev, qreal median) 150 | { 151 | Q_ASSERT(Options::instance.isSubProcess); 152 | Benchmark &bm = Options::instance.benchmarks.first(); 153 | QVariantMap benchMap = m_results[bm.fileName].toMap(); 154 | benchMap["average"] = ops; 155 | benchMap["samples-in-average"] = samples; 156 | benchMap["samples-total"] = samples; // compatibility 157 | benchMap["standard-deviation"] = stddev; 158 | benchMap["standard-deviation-all-samples"] = stddev; // compatibility 159 | benchMap["standard-error"] = stddev / std::sqrt(samples); 160 | benchMap["coefficient-of-variation"] = stddev / ops; 161 | benchMap["median"] = median; 162 | 163 | std::string opsString; 164 | if (opsAreActuallyFrames) 165 | opsString = " frames"; 166 | else 167 | opsString = " ops/frame"; 168 | 169 | std::cerr << " Average: " << ops << " " << opsString << ";" 170 | << "; MedianAll=" << median 171 | << "; StdDev=" << stddev 172 | << ", CoV=" << (stddev / ops) 173 | << std::endl; 174 | 175 | m_results[bm.fileName] = benchMap; 176 | } 177 | 178 | void ResultRecorder::mergeResults(const QJsonObject &o) 179 | { 180 | // Merge the keys from the subprocess in where they should be. 181 | for (auto it = o.constBegin(); it != o.constEnd(); ++it) { 182 | m_results[it.key()] = it.value().toVariant(); 183 | } 184 | } 185 | 186 | void ResultRecorder::finish() 187 | { 188 | if (Options::instance.printJsonToStdout) { 189 | QJsonDocument results = QJsonDocument::fromVariant(m_results); 190 | std::cout << results.toJson().constData(); 191 | } 192 | m_results.clear(); 193 | } 194 | 195 | -------------------------------------------------------------------------------- /src/resultrecorder.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #ifndef RESULTRECORDER_H 30 | #define RESULTRECORDER_H 31 | 32 | #include 33 | #include 34 | 35 | class ResultRecorder 36 | { 37 | static QVariantMap m_results; 38 | 39 | public: 40 | static void startResults(const QString &id); 41 | static void recordWindowSize(const QSize &windowSize); 42 | static void recordOperationsPerFrame(int ops); 43 | static void recordOperationsPerFrameAverage(qreal ops, int samples, qreal stddev, qreal median); 44 | static void mergeResults(const QJsonObject &o); 45 | static void finish(); 46 | 47 | static bool opsAreActuallyFrames; 48 | }; 49 | 50 | #endif // RESULTRECORDER_H 51 | 52 | -------------------------------------------------------------------------------- /src/src.pro: -------------------------------------------------------------------------------- 1 | TARGET = qmlbench 2 | TEMPLATE = app 3 | QT += quick 4 | 5 | lessThan(QT_MAJOR_VERSION, 5): error("This benchmark tool is for QtQuick 2 only, and requires Qt 5.") 6 | 7 | SOURCES += \ 8 | main.cpp \ 9 | resultrecorder.cpp \ 10 | benchmarkrunner.cpp \ 11 | testmodel.cpp \ 12 | qmlbench.cpp 13 | 14 | HEADERS += \ 15 | resultrecorder.h \ 16 | benchmarkrunner.h \ 17 | benchmark.h \ 18 | options.h \ 19 | testmodel.h \ 20 | qmlbench.h 21 | 22 | equals(QT_MAJOR_VERSION, 5): lessThan(QT_MINOR_VERSION, 2) { 23 | SOURCES += \ 24 | compat/qcommandlineoption.cpp \ 25 | compat/qcommandlineparser.cpp 26 | 27 | HEADERS += \ 28 | compat/qcommandlineoption.h \ 29 | compat/qcommandlineparser.h 30 | 31 | INCLUDEPATH += compat 32 | } 33 | 34 | CONFIG += console 35 | CONFIG -= app_bundle 36 | 37 | RESOURCES += qmlbench.qrc 38 | 39 | target.path = /root 40 | INSTALLS += target 41 | -------------------------------------------------------------------------------- /src/testmodel.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #include "testmodel.h" 30 | 31 | #include 32 | #include 33 | 34 | TestModel::TestModel() 35 | : m_rowNumber(0) 36 | { 37 | m_roleNames[StringRole] = "stringRole"; 38 | m_roleNames[ByteArrayRole] = "byteArrayRole"; 39 | m_roleNames[BoolRole] = "boolRole"; 40 | m_roleNames[IntRole] = "intRole"; 41 | m_roleNames[RealRole] = "realRole"; 42 | m_roleNames[UrlRole] = "urlRole"; 43 | m_roleNames[JsValueRole] = "jsValueRole"; 44 | m_roleNames[DateTimeRole] = "dateTimeRole"; 45 | m_roleNames[ColorRole] = "colorRole"; 46 | m_roleNames[SizeRole] = "sizeRole"; 47 | m_roleNames[PointRole] = "pointRole"; 48 | m_roleNames[RectRole] = "rectRole"; 49 | } 50 | 51 | TestModel::~TestModel() 52 | { 53 | 54 | } 55 | 56 | int TestModel::rowNumber() const 57 | { 58 | return m_rowNumber; 59 | } 60 | 61 | void TestModel::setRowNumber(int rowNumber) 62 | { 63 | if (rowNumber == m_rowNumber) 64 | return; 65 | 66 | beginResetModel(); 67 | m_rowNumber = rowNumber; 68 | 69 | // Only create data we don't already have. 70 | for (int i = m_strings.size(); i < m_rowNumber; ++i) { 71 | m_strings.append(QString("Test string %1").arg(i)); 72 | m_byteArrays.append(QByteArray("Test ByteArray ") + QByteArray::number(i)); 73 | m_bools.append(i % 2 == 0 ? true : false); 74 | m_ints.append(i); 75 | m_reals.append(i + 0.5); 76 | m_urls.append(QUrl(QString("http://example.org/some-thing-here/%1").arg(i))); 77 | m_jsValues.append(QJSValue(i)); // TODO: should we test object types (like strings?) 78 | m_dateTimes.append(QDateTime(QDate(1995, 5, 20), QTime(0, 0)).addSecs(i)); 79 | m_colors.append(QColor::fromHslF(std::fmod(0.57 * i, 1.0), 0.5, 0.5)); 80 | m_sizes.append(QSize(i, i)); 81 | m_points.append(QPoint(i, i)); 82 | m_rects.append(QRect(0, 0, i, i)); 83 | } 84 | 85 | emit rowNumberChanged(); 86 | endResetModel(); 87 | } 88 | 89 | QHash TestModel::roleNames() const 90 | { 91 | return m_roleNames; 92 | } 93 | 94 | int TestModel::rowCount(const QModelIndex&) const 95 | { 96 | return m_rowNumber; 97 | } 98 | 99 | QVariant TestModel::data(const QModelIndex &index, int role) const 100 | { 101 | switch (role) { 102 | case StringRole: 103 | return m_strings.at(index.row()); 104 | break; 105 | case ByteArrayRole: 106 | return m_byteArrays.at(index.row()); 107 | break; 108 | case BoolRole: 109 | return m_bools.at(index.row()); 110 | break; 111 | case IntRole: 112 | return m_ints.at(index.row()); 113 | break; 114 | case RealRole: 115 | return m_reals.at(index.row()); 116 | break; 117 | case UrlRole: 118 | return m_urls.at(index.row()); 119 | break; 120 | case JsValueRole: 121 | return QVariant::fromValue(m_jsValues.at(index.row())); 122 | break; 123 | case DateTimeRole: 124 | return m_dateTimes.at(index.row()); 125 | break; 126 | case ColorRole: 127 | return m_colors.at(index.row()); 128 | break; 129 | case SizeRole: 130 | return m_sizes.at(index.row()); 131 | break; 132 | case PointRole: 133 | return m_points.at(index.row()); 134 | break; 135 | case RectRole: 136 | return m_rects.at(index.row()); 137 | break; 138 | } 139 | 140 | return QVariant(); 141 | } 142 | 143 | -------------------------------------------------------------------------------- /src/testmodel.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | class TestModel : public QAbstractListModel 41 | { 42 | Q_OBJECT 43 | public: 44 | TestModel(); 45 | ~TestModel(); 46 | 47 | enum ModelRoles { 48 | StringRole = Qt::UserRole, 49 | ByteArrayRole, 50 | BoolRole, 51 | IntRole, 52 | RealRole, 53 | UrlRole, 54 | JsValueRole, 55 | DateTimeRole, 56 | ColorRole, 57 | SizeRole, 58 | PointRole, 59 | RectRole 60 | }; 61 | 62 | Q_PROPERTY(int rowNumber READ rowNumber WRITE setRowNumber NOTIFY rowNumberChanged) 63 | int rowNumber() const; 64 | void setRowNumber(int rowNumber); 65 | 66 | QHash roleNames() const override; 67 | int rowCount(const QModelIndex&) const override; 68 | QVariant data(const QModelIndex &, int role) const override; 69 | 70 | // TODO: consider testing setData too. 71 | 72 | signals: 73 | void rowNumberChanged(); 74 | 75 | private: 76 | int m_rowNumber; 77 | QHash m_roleNames; 78 | 79 | // model data below here 80 | QVector m_strings; 81 | QVector m_byteArrays; 82 | QVector m_bools; 83 | QVector m_ints; 84 | QVector m_reals; 85 | QVector m_urls; 86 | QVector m_jsValues; 87 | QVector m_dateTimes; 88 | QVector m_colors; 89 | QVector m_sizes; 90 | QVector m_points; 91 | QVector m_rects; 92 | }; 93 | 94 | -------------------------------------------------------------------------------- /tools/compareresults/compareresults.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | QT = core 3 | CONFIG -= app_bundle 4 | SOURCES = \ 5 | main.cpp 6 | 7 | target.path = /root 8 | INSTALLS += target 9 | -------------------------------------------------------------------------------- /tools/decidefps/decidefps.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | CONFIG -= app_bundle 3 | SOURCES = \ 4 | main.cpp 5 | 6 | target.path = /root 7 | INSTALLS += target 8 | -------------------------------------------------------------------------------- /tools/decidefps/main.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2017 Crimson AS 4 | ** Contact: https://www.qt.io/licensing/ 5 | ** 6 | ** This file is part of the qmlbench tool. 7 | ** 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 9 | ** Commercial License Usage 10 | ** Licensees holding valid commercial Qt licenses may use this file in 11 | ** accordance with the commercial license agreement provided with the 12 | ** Software or, alternatively, in accordance with the terms contained in 13 | ** a written agreement between you and The Qt Company. For licensing terms 14 | ** and conditions see https://www.qt.io/terms-conditions. For further 15 | ** information use the contact form at https://www.qt.io/contact-us. 16 | ** 17 | ** GNU General Public License Usage 18 | ** Alternatively, this file may be used under the terms of the GNU 19 | ** General Public License version 3 as published by the Free Software 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 21 | ** included in the packaging of this file. Please review the following 22 | ** information to ensure the GNU General Public License requirements will 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. 24 | ** 25 | ** $QT_END_LICENSE$ 26 | ** 27 | ****************************************************************************/ 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | class FpsDecider : public QWindow 36 | { 37 | public: 38 | FpsDecider() 39 | : gl(0) 40 | , frameCount(0) 41 | { 42 | setSurfaceType(OpenGLSurface); 43 | QSurfaceFormat format; 44 | #if QT_VERSION >= 0x050300 45 | format.setSwapInterval(1); 46 | #endif 47 | setFormat(format); 48 | } 49 | 50 | void exposeEvent(QExposeEvent *) { 51 | if (isExposed()) 52 | render(); 53 | } 54 | 55 | bool event(QEvent *e) 56 | { 57 | if (e->type() == QEvent::UpdateRequest) { 58 | render(); 59 | return true; 60 | } 61 | return QWindow::event(e); 62 | } 63 | 64 | void render() 65 | { 66 | if (!gl) { 67 | gl = new QOpenGLContext(); 68 | gl->setFormat(format()); 69 | gl->create(); 70 | timer.start(); 71 | } 72 | 73 | gl->makeCurrent(this); 74 | QOpenGLFunctions *func = gl->functions(); 75 | 76 | if (frameCount == 0) { 77 | #if QT_VERSION >= 0x050300 78 | std::cout << "GL_VENDOR: " << (const char *) func->glGetString(GL_VENDOR) << std::endl; 79 | std::cout << "GL_RENDERER: " << (const char *) func->glGetString(GL_RENDERER) << std::endl; 80 | std::cout << "GL_VERSION: " << (const char *) func->glGetString(GL_VERSION) << std::endl; 81 | #else 82 | Q_UNUSED(func); 83 | std::cout << "GL_VENDOR: " << (const char *) glGetString(GL_VENDOR) << std::endl; 84 | std::cout << "GL_RENDERER: " << (const char *) glGetString(GL_RENDERER) << std::endl; 85 | std::cout << "GL_VERSION: " << (const char *) glGetString(GL_VERSION) << std::endl; 86 | #endif 87 | } 88 | 89 | ++frameCount; 90 | int c = frameCount % 2; 91 | 92 | #if QT_VERSION >= 0x050300 93 | func->glClearColor(c, 0, 1 - c, 1); 94 | func->glClear(GL_COLOR_BUFFER_BIT); 95 | #else 96 | glClearColor(c, 0, 1 - c, 1); 97 | glClear(GL_COLOR_BUFFER_BIT); 98 | #endif 99 | 100 | gl->swapBuffers(this); 101 | 102 | int time = timer.elapsed(); 103 | if (time > 5000) { 104 | qreal msPerFrame = time / float(frameCount); 105 | qreal screenRate = 1000.0 / screen()->refreshRate(); 106 | std::cout << std::endl 107 | << "FPS: " << frameCount * 1000 / float(time) 108 | << " -- " << frameCount << " frames in " << time << "ms; " 109 | << msPerFrame << " ms/frame" 110 | << "; QScreen says: " << screenRate << std::endl; 111 | if (qAbs(screenRate - msPerFrame) > msPerFrame * 0.1) 112 | std::cout << " (not accurate, run benchmarks with '--fps-override " << int(1000/msPerFrame) << "')" << std::endl << std::endl; 113 | else 114 | std::cout << std::endl << "That should be close enough :)" << std::endl << std::endl; 115 | exit(0); 116 | 117 | } else { 118 | QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); 119 | } 120 | } 121 | 122 | private: 123 | QOpenGLContext *gl; 124 | QElapsedTimer timer; 125 | int frameCount; 126 | }; 127 | 128 | int main(int argc, char **argv) 129 | { 130 | QGuiApplication app(argc, argv); 131 | FpsDecider fpsDecider; 132 | 133 | if (app.arguments().contains("--fullscreen")) 134 | fpsDecider.showFullScreen(); 135 | else 136 | fpsDecider.show(); 137 | 138 | fpsDecider.raise(); 139 | return app.exec(); 140 | } 141 | -------------------------------------------------------------------------------- /tools/tools.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = subdirs 2 | SUBDIRS = \ 3 | decidefps \ 4 | compareresults 5 | --------------------------------------------------------------------------------