qtquick-profiler.qdoc 24.9 KB
Newer Older
1 2
/****************************************************************************
**
3 4
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
5
**
6
** This file is part of the Qt Creator documentation.
7
**
8 9 10 11 12 13 14
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
15
**
16
** GNU Free Documentation License Usage
17 18
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
19 20 21 22
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
23 24 25 26 27 28 29 30 31 32
**
****************************************************************************/

// **********************************************************************
// NOTE: the sections are not ordered by their logical order to avoid
// reshuffling the file each time the index order changes (i.e., often).
// Run the fixnavi.pl script to adjust the links to the index order.
// **********************************************************************

/*!
33
    \contentspage {Qt Creator Manual}
34 35
    \previouspage creator-analyze-mode.html
    \page creator-qml-performance-monitor.html
36
    \nextpage creator-valgrind-overview.html
37 38 39

    \title Profiling QML Applications

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
    You can use the QML Profiler to find causes for typical performance problems
    in your applications, such as slowness and unresponsive, stuttering user
    interfaces. Typical causes include executing too much JavaScript in too few
    frames. All JavaScript must return before the GUI thread can proceed, and
    frames are delayed or dropped if the GUI thread is not ready.

    Another typical cause for similar performance problems is creating,
    painting, or updating invisible items, which takes time in the GUI thread.

    Triggering long-running C++ functions, such as paint methods and signal
    handlers, also takes time in the GUI thread, but is more difficult to see in
    the QML Profiler, because it does not profile C++ code.

    To find excessive use of JavaScript, check the frame rate in animations and
    Scene Graph events, look for gaps, and check whether the application behaves
    as expected. The JavaScript category displays the run time of functions,
    which you should try to keep below 16 ms per frame.

    To find problems caused by handling invisible items, look for dropped
    frames and check that you are not using too many short bindings or signal
    handlers that are updated per frame. You can also \l{Visualizing Overdraw}
    {visualize Scene Graph overdraw} to check scene layout and find items that
    are never visible to the users, because they are located outside the screen
    or hidden beneath other, visible elements.

    If frames get dropped even though JavaScript is not being run, and there are
    large, unexplained gaps in the timeline, check your custom QQuickItem
    implementations. You can use \l{Using Valgrind Code Analysis Tools}
    {Valgrind} or other general purpose profilers to analyze C++ code.

    \section1 Using QML Profiler

72 73 74 75
    To monitor the performance of an application in the QML Profiler:

    \list 1

76
        \li To be able to profile an application, you must set up QML debugging
77 78 79
            for the project. For more information, see
            \l{Setting Up QML Debugging}.

80
        \li In the \uicontrol Projects mode, select a \l{glossary-buildandrun-kit}
81
            {kit} with Qt version 4.7.4 or later.
82

83 84
            \note To profile applications on \l{glossary-device}{devices}, you
            must install Qt 4.7.4 or later libraries on them.
85

86
        \li Select \uicontrol {Analyze > QML Profiler} to profile the current
87 88
            application.

89
        \li Select the
Leena Miettinen's avatar
Leena Miettinen committed
90
            \inlineimage qtcreator-analyze-start-button.png
91
            (\uicontrol Start) button to start the application from the
Leena Miettinen's avatar
Leena Miettinen committed
92
            QML Profiler.
93 94

            \note If data collection does not start automatically, select the
95
            \inlineimage recordfill.png
96
            (\uicontrol {Enable Profiling}) button.
97 98 99 100 101

    \endlist

    When you start analyzing an application, the application is launched, and
    the QML Profiler immediately begins to collect data. This is indicated by
102
    the time running in the \uicontrol Elapsed field.
103

104
    Data is collected until you select the \uicontrol {Enable Profiling} button. Data
105
    collection
Leena Miettinen's avatar
Leena Miettinen committed
106
    takes time, and therefore, there might be a delay
107 108 109
    before the data is displayed.

    Do not use application commands to exit the application, because data is
110
    sent to the QML Profiler when you select the \uicontrol {Enable Profiling} button.
111 112 113
    The application continues to run for some seconds, after which it is stopped
    automatically. If you exit the application, the data is not sent.

114
    Select the \uicontrol {Disable Profiling} button to disable the automatic
Leena Miettinen's avatar
Leena Miettinen committed
115
    start of the data collection when an
116 117 118
    application is launched. Data collection starts when you select the button
    again.

Leena Miettinen's avatar
Leena Miettinen committed
119
    To save all the collected data, right-click any QML Profiler view to open
120 121
    the context menu, and then select \uicontrol {Save QML Trace}. To view the saved
    data, select \uicontrol {Load QML Trace}. You can also deliver the saved data to
Leena Miettinen's avatar
Leena Miettinen committed
122
    other developers for examination or load data saved by them.
123 124 125 126 127 128 129 130

    \section1 Specifying Flushing Settings

    You can specify flushing settings for the QML Profiler either globally for
    all projects or separately for each project. To specify global settings,
    select \uicontrol Tools > \uicontrol Options > \uicontrol Analyzer.

    To specify custom QML Profiler settings for a particular project, select
131 132 133
    \uicontrol Projects > \uicontrol Run and then select \uicontrol Custom in
    \uicontrol {QML Profiler Settings}. To restore the global settings for the
    project, select \uicontrol {Restore Global}.
134 135 136 137 138 139 140 141 142 143 144 145 146

    \image qml-profiler-settings.png "QML Profiler Settings"

    Select the \uicontrol {Flush data while profiling} check box to flush the
    data periodically instead of flushing all data when profiling stops. This
    saves memory on the target device and shortens the wait between the
    profiling being stopped and the data being displayed.

    In the \uicontrol {Flush interval} field, set the flush interval in
    milliseconds. The shorter the interval, the more often the data is flushed.
    The longer the interval, the more data has to be buffered in the target
    application, potentially wasting memory. However, the flushing itself takes
    time, which can distort the profiling results.
Leena Miettinen's avatar
Leena Miettinen committed
147

148 149 150 151 152
    If you have multiple QML engines and you want to aggregate the data produced
    by all of them into one trace, select the \uicontrol {Process data only when
    process ends} check box. Otherwise, the profiling stops when one of the
    engines stops.

153 154 155
    \section1 Attaching to Running Qt Quick Applications

    To profile Qt Quick applications that are not launched by \QC, select
156
    \uicontrol {Analyze > QML Profiler (External)}. You must enable QML debugging and profiling for
157 158 159
    the application in the project build settings. For more information, see
    \l{Setting Up QML Debugging}.

160
    In the \uicontrol {QML Profiler} dialog, \uicontrol Port field, specify the port to
161 162
    listen to.

163 164
    \section1 Analyzing Collected Data

165
    The \uicontrol Timeline view displays graphical representations of QML and
166
    JavaScript execution and a condensed view of all recorded events.
167 168 169

    \image qtcreator-qml-performance-monitor.png "QML Profiler"

Leena Miettinen's avatar
Leena Miettinen committed
170 171 172
    Each row in the timeline (6) describes a type of QML events that were
    recorded. Move the cursor on an event on a row to see how long it takes and
    where in the source it is being called. To display the information only when
173
    an event is selected, disable the \uicontrol {View Event Information on Mouseover}
174
    button (4).
Leena Miettinen's avatar
Leena Miettinen committed
175 176 177

    The outline (10) summarizes the period for which data was collected. Drag
    the zoom range (8) or click the outline to move on the outline. You can
178 179
    also move between events by selecting the \uicontrol {Jump to Previous Event}
    and \uicontrol {Jump to Next Event} buttons (1).
Leena Miettinen's avatar
Leena Miettinen committed
180

181
    Select the \uicontrol {Show Zoom Slider} button (2) to open a slider that you can
Leena Miettinen's avatar
Leena Miettinen committed
182 183
    use to set the zoom level. You can also drag the zoom handles (9). To reset
    the default zoom level, right-click the timeline to open the context menu,
184
    and select \uicontrol {Reset Zoom}.
Leena Miettinen's avatar
Leena Miettinen committed
185

186 187
    Click the time ruler to add vertical orientation lines (5) to the timeline.

Leena Miettinen's avatar
Leena Miettinen committed
188 189 190 191
    \section2 Selecting Event Ranges

    You can select an event range (7) to view the frame rate of events and to
    compare it with the frame rate of similar events. Select the
192
    \uicontrol {Select Range} button (3) to activate the selection tool. Then click in
Leena Miettinen's avatar
Leena Miettinen committed
193 194 195 196 197 198
    the timeline to specify the beginning of the event range. Drag the selection
    handle to define the end of the range. The length of the range indicates the
    frame rate of the event.

    You can use event ranges also to measure delays between two subsequent
    events. Place a range between the end of the first event and the beginning
199
    of the second event. The \uicontrol Duration field displays the delay between the
Leena Miettinen's avatar
Leena Miettinen committed
200
    events in milliseconds.
201

Leena Miettinen's avatar
Leena Miettinen committed
202
    To zoom into an event range, double-click it.
203

204
    To remove an event range, close the \uicontrol Selection dialog.
205

206 207 208 209 210 211 212 213 214 215 216 217
    \section2 Understanding the Data

    Generally, events in the timeline view indicate how long QML or JavaScript
    execution took. Move the mouse over them to see details. For most events,
    they include location in source code, duration and some relevant parts of
    the source code itself.

    You can click on an event to move the cursor in the code editor to the part
    of the code the event is associated with.

    The following types of events are displayed in the timeline view on one or
    several rows. The availability of event types depends on the version of Qt
218
    the application was compiled with and the version of Qt Quick it is using.
219 220 221 222

    \table

    \header
223
        \li Event Category
224 225 226 227 228
        \li Description
        \li Minimum Qt Version
        \li Qt Quick Version

    \row
229
        \li \uicontrol {Pixmap Cache}
230 231 232 233 234 235 236
        \li Displays the general amount of pixmap data cached, in pixels. In
            addition, displays a separate event for each picture being loaded,
            with specifics about its file name and size.
        \li Qt 5.1
        \li Qt Quick 2

    \row
237
        \li \uicontrol {Scene Graph}
238 239 240 241 242
        \li Displays the time when scene graph frames are rendered and some
            additional timing information for the various stages executed to do
            so.
        \li Qt 5.1
        \li Qt Quick 2
243

244
    \row
245
        \li \uicontrol {Memory Usage}
246 247 248 249 250 251 252 253 254 255 256 257 258
        \li Displays block allocations of the JavaScript memory manager.
            Generally, the memory manager will reserve larger blocks of memory
            in one piece and later hand them out to the application in smaller
            bits. If the application requests single blocks of memory
            surpassing a certain size, the memory manager will allocate those
            separately. Those two modes of operation are shown as events of
            different colors.
            The second row displays the actual usage of the allocated memory.
            This is the amount of JavaScript heap the application has actually
            requested.
        \li Qt 5.4
        \li Qt Quick 2

259
    \row
260
        \li \uicontrol {Input Events}
261 262 263 264
        \li Displays mouse and keyboard events.
        \li Qt 4.7.4
        \li Qt Quick 1 or Qt Quick 2

265
    \row
266
        \li \uicontrol Painting
267 268 269 270 271
        \li Displays the time spent painting the scene for each frame.
        \li Qt 4.7.4
        \li Qt Quick 1

    \row
272
        \li \uicontrol Animations
273 274 275 276 277 278 279 280 281
        \li Displays the amount of animations that are active and the frame
            rate that they are running at.
            Information about render thread animations is displayed for
            applications that are built with Qt 5.3 or later. Render thread
            animations are shown in a separate row then.
        \li Qt 5.0 (Qt 5.3)
        \li Qt Quick 2

    \row
282
        \li \uicontrol Compiling
283 284 285 286 287
        \li Displays the time spent compiling the QML files.
        \li Qt 4.7.4
        \li Qt Quick 1 or Qt Quick 2

    \row
288
        \li \uicontrol Creating
289 290 291 292 293 294 295 296 297 298 299 300 301
        \li Displays the time spent creating the elements in the scene. In Qt
            Quick 2, creation of elements takes place in two stages. The first
            stage is for the creation of the data structures, including child
            elements. The second stage represents the completion callbacks. Not
            all elements trigger completion callbacks, though. The stages are
            shown as separate events in the timeline.
            For Qt Quick 2 applications compiled with versions of Qt before
            5.2.1 only the creation of top-level elements is shown, as single
            events.
        \li Qt 4.7.4 (Qt 5.2.1)
        \li Qt Quick 1 or Qt Quick 2

    \row
302
        \li \uicontrol Binding
303 304 305 306 307 308
        \li Displays the time when a binding is evaluated and how long the
            evaluation takes.
        \li Qt 4.7.4
        \li Qt Quick 1 or Qt Quick 2

    \row
309
        \li \uicontrol {Handling Signal}
310 311 312 313 314 315
        \li Displays the time when a signal is handled and how long the
            handling takes.
        \li Qt 4.7.4
        \li Qt Quick 1 or Qt Quick 2

    \row
316
        \li \uicontrol JavaScript
317 318 319 320 321 322 323
        \li Displays the time spent executing the actual JavaScript behind
            bindings and signal handlers. It lists all the JavaScript functions
            you may be using to evaluate bindings or handle signals.
        \li Qt 5.3
        \li Qt Quick 2

    \endtable
324

325 326 327 328 329 330
    \section2 Analyzing Scene Graph Events

    In order to understand the scene graph category, it's important to
    understand how the Qt Quick scene graph works. See
    \l {Qt Quick Scene Graph} and \l {Qt Quick Scene Graph Renderer} for a
    detailed description. The following events are reported in the
331
    \uicontrol {Scene Graph} category. Not all events are generated by all render
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
    loops. In the Windows and Basic render loops everything runs in the same
    thread and the distinction between GUI thread and render thread is
    meaningless.

    If you set the environment variable QSG_RENDER_TIMING, you get a textual
    output of similar, but slightly different timings from the application
    being profiled. For easier orientation, the differences are listed below.

    \table
    \header
        \li Event Type
        \li Thread
        \li Render Loop Types
        \li Label in output of QSG_RENDER_TIMING
        \li Description
        \li Caveats
    \row
349
        \li \uicontrol {Polish}
350 351 352 353 354 355 356 357
        \li GUI
        \li Threaded, Basic, Windows
        \li polish
        \li Final touch-up of items before they are rendered using
            QQuickItem::updatePolish().
        \li Versions of Qt prior to Qt 5.4 record no polish times for the basic
            render loop and incorrect ones for the windows render loop.
    \row
358
        \li \uicontrol {GUI Thread Wait}
359 360 361 362 363
        \li GUI
        \li Threaded
        \li lock
        \li Executing slots connected to the QQuickWindow::afterAnimating()
            signal and then locking the render thread's mutex before waiting on
364 365
            the same mutex at \uicontrol {GUI Thread Sync}. If this starts long
            before \uicontrol {Render Thread Sync}, there is \e free  time in the GUI
366 367 368
            thread you could be using for running additional QML or JavaScript.
        \li None
    \row
369
        \li \uicontrol {GUI Thread Sync}
370 371 372
        \li GUI
        \li Threaded
        \li blockedForSync
373
        \li The time the GUI thread is blocked, waiting for the render thread.
374 375
        \li None
    \row
376
        \li \uicontrol {Animations}
377 378 379 380 381 382
        \li GUI
        \li Threaded, Windows
        \li animations
        \li Advancing animations in the GUI thread. The basic render loop does
            not drive animations in sync with the rendering. This is why no
            animation events will be shown when using the basic render loop.
383
            Watch the \uicontrol {Animations} category to see animation timing in
384 385 386
            this case.
        \li None
    \row
387
        \li \uicontrol {Render Thread Sync}
388 389 390 391 392 393 394
        \li Render
        \li Threaded, Basic, Windows
        \li Frame rendered ... sync
        \li Synchronizing the QML state into the scene graph using
            QQuickItem::updatePaintNode().
        \li None
    \row
395
        \li \uicontrol {Render}
396 397 398 399 400
        \li Render
        \li Threaded, Basic, Windows
        \li Frame rendered ... render
        \li Total time spent rendering the frame, including preparing and
            uploading all the necessary data to the GPU. This is the \e gross
401
            render time. Do not confuse it with the \e net \uicontrol{Render Render}
402 403 404 405
            time below.
        \li With versions of Qt prior to Qt 5.5, the gross render time and the
            below breakup of render times may be misaligned by some
            microseconds due to different, unsynchronized timers being used to
406 407
            measure them. For example \uicontrol {Render Preprocess} might seem to
            start before \uicontrol {Render Thread Sync} is finished.
408
    \row
409
        \li \uicontrol {Swap}
410 411 412 413 414 415 416 417
        \li Render
        \li Threaded, Basic, Windows
        \li Frame rendered ... swap
        \li Swapping frames after rendering.
        \li The output of swap times triggered by setting QSG_RENDER_TIMING is
            incorrect for the basic render loop and versions of Qt prior to
            Qt 5.4. The QML profiler shows the correct swap times.
    \row
418
        \li \uicontrol {Render Preprocess}
419 420 421 422
        \li Render
        \li Threaded, Basic, Windows
        \li time in renderer ... preprocess
        \li Calling QSGNode::preprocess() on all nodes that need to be
423 424
            preprocessed. This is part of the gross \uicontrol {Render} step.
        \li May not be properly aligned with \uicontrol {Render} with versions of Qt
425 426
            prior to Qt 5.5.
    \row
427
        \li \uicontrol {Render Update}
428 429 430 431 432
        \li Render
        \li Threaded, Basic, Windows
        \li time in renderer ... updates
        \li Iterating and processing all the nodes in the scene graph to update
            their geometry, transformations, opacity, and other state. In the
433 434
            \uicontrol {Render Thread Sync} stage, each node is updated separately
            with state from the GUI thread. In \uicontrol {Render Update}, all the
435
            nodes are combined to create the final scene. This is part of the
436 437
            gross \uicontrol {Render} step.
        \li May not be properly aligned with \uicontrol {Render} with versions of Qt
438 439
            prior to Qt 5.5.
    \row
440
        \li \uicontrol {Render Bind}
441 442 443 444
        \li Render
        \li Threaded, Basic, Windows
        \li time in renderer ... binding
        \li Binding the correct framebuffer for OpenGL rendering. This is part
445 446
            of the gross \uicontrol {Render} step.
        \li May not be properly aligned with \uicontrol {Render} with versions of Qt
447 448
            prior to Qt 5.5.
    \row
449
        \li \uicontrol {Render Render}
450 451 452 453
        \li Render
        \li Threaded, Basic, Windows
        \li time in renderer ... rendering
        \li The actual process of sending all the data to the GPU via OpenGL.
454 455
            This is part of the gross \uicontrol {Render} step.
        \li May not be properly aligned with \uicontrol {Render} with versions of Qt
456 457
            prior to Qt 5.5.
    \row
458
        \li \uicontrol {Material Compile}
459 460 461 462 463 464
        \li Render
        \li Threaded, Basic, Windows
        \li shader compiled
        \li Compiling GLSL shader programs.
        \li None
    \row
465
        \li \uicontrol {Glyph Render}
466 467 468 469 470 471 472
        \li Render
        \li Threaded, Basic, Windows
        \li glyphs ... rendering
        \li Rendering of font glyphs into textures.
        \li Versions of Qt prior to Qt 5.4 report incorrect times for these
            events.
    \row
473
        \li \uicontrol {Glyph Upload}
474 475 476 477 478 479 480
        \li Render
        \li Threaded, Basic, Windows
        \li glyphs ... upload
        \li Uploading of glyph textures to the GPU.
        \li Versions of Qt prior to Qt 5.4 report incorrect times for these
            events.
    \row
481
        \li \uicontrol {Texture Bind}
482 483 484 485 486 487
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... bind
        \li Binding a texture in the OpenGL context using glBindTextures.
        \li None
    \row
488
        \li \uicontrol {Texture Convert}
489 490 491 492 493 494 495
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... convert
        \li Converting the format and downscaling an image to make it suitable
            for usage as a texture.
        \li None
    \row
496
        \li \uicontrol {Texture Swizzle}
497 498 499 500 501 502
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... swizzle
        \li Swizzling the texture data on the CPU if necessary.
        \li None
    \row
503
        \li \uicontrol {Texture Upload}
504 505 506 507 508 509
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... upload / atlastexture uploaded
        \li Uploading the texture data to the GPU.
        \li None
    \row
510
        \li \uicontrol {Texture Mipmap}
511 512 513 514 515 516
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture ... mipmap
        \li Mipmapping a texture on the GPU.
        \li None
    \row
517
        \li \uicontrol {Texture Delete}
518 519 520 521 522 523 524
        \li Render
        \li Threaded, Basic, Windows
        \li plain texture deleted
        \li Deleting a texture from the GPU that became unnecessary.
        \li None
    \endtable

525
    \section1 Viewing Statistics
526

527
    The \uicontrol Statistics view displays the number of times each binding, create,
528 529 530 531
    compile, JavaScript, or signal event is triggered and the average time it
    takes. This allows you to examine which events you need to optimize. A high
    number of occurrences might indicate that an event is triggered
    unnecessarily. To view the median, longest, and shortest time for the
532
    occurrences, select \uicontrol {Extended Event Statistics} in the context menu.
533 534

    Click on an event to move to it in the source code
535 536
    in the code editor.

537
    \image qml-profiler-statistics.png "Statistics view"
538

539
    The \uicontrol Callers and \uicontrol Callees panes show dependencies between events.
540
    They allow you to examine the internal functions of the application.
541
    The \uicontrol Callers pane summarizes the QML events that trigger a binding.
Leena Miettinen's avatar
Leena Miettinen committed
542
    This tells you what caused a change in a binding.
543
    The \uicontrol Callees pane summarizes the QML events that a binding triggers.
544 545
    This tells you which QML events are affected if you change a binding.

546
    Click on an event to move to it in the source code in the code editor.
547

548
    When you select an event in the \uicontrol Timeline view, information about it is
549
    displayed in the \uicontrol Statistics view. To view an event range in the
550
    \uicontrol Statistics view, select \uicontrol {Analyze Current Range}
551
    in the context menu in the \uicontrol Timeline view.
552

Leena Miettinen's avatar
Leena Miettinen committed
553
    To copy the contents of one view or row to the clipboard, select
554
    \uicontrol {Copy Table} or \uicontrol {Copy Row} in the context menu.
555

556
    JavaScript events are shown in the \uicontrol Statistics view only for applications
Ulf Hermann's avatar
Ulf Hermann committed
557
    that use Qt Quick 2 and are compiled with Qt 5.3 or later.
558 559 560

    \section2 Visualizing Statistics as Flame Graphs

561
    The \uicontrol {Flame Graph} view shows a more concise statistical overview
562 563
    of QML and JavaScript execution. In the \uicontrol {Visualize Total Time}
    view, the horizontal bars show the amount of
564 565
    time all invocations of a certain function took together, relative to the
    total runtime of all JavaScript and QML events. The nesting shows which
566 567 568 569 570 571 572 573 574 575 576 577 578
    functions were called by which other ones.

    \image qml-profiler-flamegraph.png "Flame Graph View"

    To view the total amount of memory allocated by the functions in the
    \uicontrol {Visualize Memory} view, select \uicontrol Memory in the
    drop-down menu (1).

    To view the the number of memory allocations performed by the functions in
    the \uicontrol {Visualize Allocations} view, select \uicontrol Allocations
    in the drop-down menu.

    Unlike the
579
    \uicontrol Timeline view, the \uicontrol {Flame Graph} view does not show the
580 581 582 583
    time spans when no QML or JavaScript is running at all. Thus, it is not
    suitable for analyzing per frame execution times. However, it is very easy
    to see the total impact of the various QML and JavaScript events there.

584
*/