From 9d2dfdbbc8ff0d5df4daaf379168c2239d4c2400 Mon Sep 17 00:00:00 2001 From: Said Abou-Hallawa Date: Tue, 18 Jun 2024 14:03:15 -0700 Subject: [PATCH] Refactor MotionMark code https://github.com/WebKit/MotionMark/issues/59 Decouple the benchmark workflow from the score calculation. Fix some bugs in the two segments regression algorithm. --- MotionMark/about.html | 8 +- MotionMark/debug/complexity-graph.js | 132 +++ .../debug-runner => debug}/d3.min.js | 0 MotionMark/debug/debug-fixed-results.js | 77 ++ .../debug-motionmark.css} | 188 ++-- MotionMark/debug/debug-motionmark.js | 77 ++ MotionMark/debug/debug-results.js | 132 +++ .../multiply.js => debug/debug-tests.js} | 40 +- MotionMark/debug/debug-wave-results.js | 103 ++ MotionMark/debug/graph-container.js | 71 ++ MotionMark/debug/graph.js | 81 ++ MotionMark/debug/suites-tree.js | 189 ++++ MotionMark/debug/time-graph.js | 161 +++ MotionMark/developer.html | 131 ++- MotionMark/extensions/bootstrap.js | 75 ++ MotionMark/extensions/document.js | 58 + MotionMark/extensions/insets.js | 59 ++ MotionMark/extensions/math.js | 55 + MotionMark/extensions/point.js | 133 +++ MotionMark/extensions/random.js | 85 ++ MotionMark/extensions/range.js | 56 + MotionMark/extensions/rect.js | 121 +++ MotionMark/extensions/regression.js | 187 ++++ MotionMark/extensions/rotator.js | 44 + MotionMark/extensions/size.js | 128 +++ MotionMark/extensions/spiral-iterator.js | 100 ++ MotionMark/extensions/unit-bezier.js | 97 ++ MotionMark/index.html | 67 +- .../{resources/runner => release}/crystal.svg | 0 .../{resources/runner => release}/lines.svg | 0 .../{resources/runner => release}/logo.svg | 0 .../release-motionmark.css} | 217 ++-- MotionMark/release/release-motionmark.js | 40 + MotionMark/release/release-wave-results.js | 74 ++ .../resources/debug-runner/debug-runner.js | 742 ------------- MotionMark/resources/debug-runner/graph.js | 699 ------------ MotionMark/resources/debug-runner/tests.js | 458 -------- MotionMark/resources/extensions.js | 698 ------------ .../resources/runner/benchmark-runner.js | 179 ---- MotionMark/resources/runner/motionmark.js | 769 -------------- MotionMark/resources/runner/tests.js | 77 -- MotionMark/resources/statistics.js | 421 -------- .../template-css.js => shared/animator.js} | 71 +- MotionMark/shared/benchmark.js | 103 ++ MotionMark/shared/controller.js | 66 ++ MotionMark/shared/core-tests.js | 72 ++ MotionMark/shared/exponential-controller.js | 127 +++ MotionMark/shared/fixed-controller.js | 43 + .../fixed-statistics.js} | 65 +- MotionMark/shared/frame-rate-detector.js | 77 ++ MotionMark/shared/motionmark.js | 174 +++ MotionMark/shared/ramp-controller.js | 73 ++ .../results.js} | 60 +- MotionMark/shared/runs-drop-target.js | 95 ++ MotionMark/shared/runs-overlay.js | 104 ++ MotionMark/shared/settings.js | 142 +++ .../{tests/resources => shared}/stage.css | 12 +- MotionMark/shared/stage.js | 47 + MotionMark/{resources => shared}/strings.js | 69 +- MotionMark/shared/suites-collection.js | 75 ++ MotionMark/shared/timeline.js | 107 ++ MotionMark/shared/wave-controller.js | 55 + MotionMark/shared/wave-statistics.js | 117 ++ MotionMark/tests/3d/resources/webgl.js | 208 ---- MotionMark/tests/3d/resources/webgpu.js | 334 ------ MotionMark/tests/3d/triangles-webgl.html | 93 -- .../bouncing-css-images.html | 46 - .../bouncing-css-shapes.html | 57 - .../bouncing-svg-images.html | 42 - .../bouncing-svg-shapes.html | 42 - .../bouncing-tagged-images.html | 46 - .../resources/bouncing-canvas-images.js | 71 -- .../resources/bouncing-canvas-particles.js | 112 -- .../resources/bouncing-canvas-shapes.js | 111 -- .../resources/bouncing-css-images.js | 85 -- .../resources/bouncing-css-shapes.js | 110 -- .../resources/bouncing-particles.js | 147 --- .../resources/bouncing-svg-particles.js | 91 -- .../resources/bouncing-svg-shapes.js | 125 --- .../resources/bouncing-tagged-images.js | 130 --- .../bouncing-particles/resources/image1.jpg | Bin 64004 -> 0 bytes .../bouncing-particles/resources/image2.jpg | Bin 71981 -> 0 bytes .../bouncing-particles/resources/image3.jpg | Bin 71319 -> 0 bytes .../bouncing-particles/resources/image4.jpg | Bin 96373 -> 0 bytes .../bouncing-particles/resources/image5.jpg | Bin 135674 -> 0 bytes .../canvas-arcs.html} | 41 +- .../canvas-lines.html} | 36 +- MotionMark/tests/core/canvas-stage.html | 41 - MotionMark/tests/core/design.html | 34 +- .../leaves.html => core/image-canvases.html} | 40 +- MotionMark/tests/core/image-data.html | 52 - .../core/{resources => images}/compass100.png | Bin .../core/{resources => images}/console100.png | Bin .../{resources => images}/contribute100.png | Bin .../{resources => images}/debugger100.png | Bin .../{resources => images}/inspector100.png | Bin .../core/{resources => images}/layout100.png | Bin .../{resources => images}/performance100.png | Bin .../core/{resources => images}/script100.png | Bin .../{resources => images}/shortcuts100.png | Bin .../{resources => images}/standards100.png | Bin .../core/{resources => images}/storage100.png | Bin .../core/{resources => images}/styles100.png | Bin .../{resources => images}/timeline100.png | Bin MotionMark/tests/core/leaves.html | 35 +- MotionMark/tests/core/multiply.html | 87 +- .../paths.html} | 33 +- .../tests/core/resources/canvas-arcs.js | 128 +++ .../tests/core/resources/canvas-lines.js | 174 +++ .../tests/core/resources/canvas-stage.js | 76 -- .../tests/core/resources/canvas-tests.js | 335 ------ MotionMark/tests/core/resources/compass.svg | 7 - MotionMark/tests/core/resources/console.svg | 6 - .../tests/core/resources/contribute.svg | 6 - MotionMark/tests/core/resources/debugger.svg | 5 - MotionMark/tests/core/resources/design.js | 195 ++-- MotionMark/tests/core/resources/focus.js | 153 --- .../tests/core/resources/image-canvases.js | 161 +++ MotionMark/tests/core/resources/image-data.js | 205 ---- MotionMark/tests/core/resources/inspector.svg | 6 - MotionMark/tests/core/resources/layout.svg | 6 - MotionMark/tests/core/resources/leaves.js | 224 ++-- MotionMark/tests/core/resources/multiply.js | 242 ++--- MotionMark/tests/core/resources/particles.js | 136 --- MotionMark/tests/core/resources/paths.js | 177 ++++ .../tests/core/resources/performance.svg | 6 - MotionMark/tests/core/resources/script.svg | 5 - MotionMark/tests/core/resources/shortcuts.svg | 5 - MotionMark/tests/core/resources/standards.svg | 6 - MotionMark/tests/core/resources/storage.svg | 5 - MotionMark/tests/core/resources/styles.svg | 5 - MotionMark/tests/core/resources/suits.js | 253 +++-- MotionMark/tests/core/resources/timeline.svg | 6 - .../tests/core/shared/disposable-particles.js | 60 ++ .../tests/core/shared/resettable-particle.js | 47 + .../tests/core/shared/reusable-particles.js | 73 ++ .../shared/reusable-segments.js} | 62 +- MotionMark/tests/core/suits.html | 33 +- .../tests/dom/compositing-transforms.html | 48 - MotionMark/tests/dom/focus.html | 75 -- MotionMark/tests/dom/multiply.html | 78 -- MotionMark/tests/dom/particles.html | 48 - .../dom/resources/compositing-transforms.js | 90 -- .../tests/dom/resources/dom-particles.js | 97 -- MotionMark/tests/dom/resources/focus.js | 190 ---- MotionMark/tests/dom/resources/leaves.js | 99 -- MotionMark/tests/resources/main.js | 998 ------------------ MotionMark/tests/resources/math.js | 292 ----- MotionMark/tests/resources/star.svg | 8 - MotionMark/tests/resources/yin-yang.png | Bin 4082 -> 0 bytes MotionMark/tests/resources/yin-yang.svg | 17 - .../simple/resources/simple-canvas-paths.js | 477 --------- .../simple/resources/tiled-canvas-image.js | 143 --- .../tests/simple/simple-canvas-paths.html | 42 - .../tests/simple/tiled-canvas-image.html | 40 - MotionMark/tests/svg/suits.html | 68 -- MotionMark/tests/svg/suits.js | 129 --- .../template/resources/template-canvas.js | 113 -- .../tests/template/template-canvas.html | 40 - MotionMark/tests/template/template-css.html | 40 - MotionMark/tests/template/template-svg.html | 40 - MotionMark/tests/text/design-6.html | 117 -- MotionMark/tests/text/design-6.js | 82 -- MotionMark/tests/text/design.html | 107 -- MotionMark/tests/text/design.js | 100 -- MotionMark/unit-tests/resources/js-test.js | 968 +++++++++++++++++ MotionMark/unit-tests/test-animator.html | 72 ++ .../unit-tests/test-fixed-controller.html | 59 ++ .../unit-tests/test-ramp-controller.html | 10 + MotionMark/unit-tests/test-regression.html | 272 +++++ .../unit-tests/test-spiral-iterator.html | 29 + 171 files changed, 7234 insertions(+), 11594 deletions(-) create mode 100644 MotionMark/debug/complexity-graph.js rename MotionMark/{resources/debug-runner => debug}/d3.min.js (100%) create mode 100644 MotionMark/debug/debug-fixed-results.js rename MotionMark/{resources/debug-runner/motionmark.css => debug/debug-motionmark.css} (86%) create mode 100644 MotionMark/debug/debug-motionmark.js create mode 100644 MotionMark/debug/debug-results.js rename MotionMark/{tests/dom/resources/multiply.js => debug/debug-tests.js} (65%) create mode 100644 MotionMark/debug/debug-wave-results.js create mode 100644 MotionMark/debug/graph-container.js create mode 100644 MotionMark/debug/graph.js create mode 100644 MotionMark/debug/suites-tree.js create mode 100644 MotionMark/debug/time-graph.js create mode 100644 MotionMark/extensions/bootstrap.js create mode 100644 MotionMark/extensions/document.js create mode 100644 MotionMark/extensions/insets.js create mode 100644 MotionMark/extensions/math.js create mode 100644 MotionMark/extensions/point.js create mode 100644 MotionMark/extensions/random.js create mode 100644 MotionMark/extensions/range.js create mode 100644 MotionMark/extensions/rect.js create mode 100644 MotionMark/extensions/regression.js create mode 100644 MotionMark/extensions/rotator.js create mode 100644 MotionMark/extensions/size.js create mode 100644 MotionMark/extensions/spiral-iterator.js create mode 100644 MotionMark/extensions/unit-bezier.js rename MotionMark/{resources/runner => release}/crystal.svg (100%) rename MotionMark/{resources/runner => release}/lines.svg (100%) rename MotionMark/{resources/runner => release}/logo.svg (100%) rename MotionMark/{resources/runner/motionmark.css => release/release-motionmark.css} (95%) create mode 100644 MotionMark/release/release-motionmark.js create mode 100644 MotionMark/release/release-wave-results.js delete mode 100644 MotionMark/resources/debug-runner/debug-runner.js delete mode 100644 MotionMark/resources/debug-runner/graph.js delete mode 100644 MotionMark/resources/debug-runner/tests.js delete mode 100644 MotionMark/resources/extensions.js delete mode 100644 MotionMark/resources/runner/benchmark-runner.js delete mode 100644 MotionMark/resources/runner/motionmark.js delete mode 100644 MotionMark/resources/runner/tests.js delete mode 100644 MotionMark/resources/statistics.js rename MotionMark/{tests/template/resources/template-css.js => shared/animator.js} (51%) create mode 100644 MotionMark/shared/benchmark.js create mode 100644 MotionMark/shared/controller.js create mode 100644 MotionMark/shared/core-tests.js create mode 100644 MotionMark/shared/exponential-controller.js create mode 100644 MotionMark/shared/fixed-controller.js rename MotionMark/{tests/template/resources/template-svg.js => shared/fixed-statistics.js} (51%) create mode 100644 MotionMark/shared/frame-rate-detector.js create mode 100644 MotionMark/shared/motionmark.js create mode 100644 MotionMark/shared/ramp-controller.js rename MotionMark/{tests/bouncing-particles/resources/bouncing-svg-images.js => shared/results.js} (53%) create mode 100644 MotionMark/shared/runs-drop-target.js create mode 100644 MotionMark/shared/runs-overlay.js create mode 100644 MotionMark/shared/settings.js rename MotionMark/{tests/resources => shared}/stage.css (90%) create mode 100644 MotionMark/shared/stage.js rename MotionMark/{resources => shared}/strings.js (53%) create mode 100644 MotionMark/shared/suites-collection.js create mode 100644 MotionMark/shared/timeline.js create mode 100644 MotionMark/shared/wave-controller.js create mode 100644 MotionMark/shared/wave-statistics.js delete mode 100644 MotionMark/tests/3d/resources/webgl.js delete mode 100644 MotionMark/tests/3d/resources/webgpu.js delete mode 100644 MotionMark/tests/3d/triangles-webgl.html delete mode 100644 MotionMark/tests/bouncing-particles/bouncing-css-images.html delete mode 100644 MotionMark/tests/bouncing-particles/bouncing-css-shapes.html delete mode 100644 MotionMark/tests/bouncing-particles/bouncing-svg-images.html delete mode 100644 MotionMark/tests/bouncing-particles/bouncing-svg-shapes.html delete mode 100644 MotionMark/tests/bouncing-particles/bouncing-tagged-images.html delete mode 100644 MotionMark/tests/bouncing-particles/resources/bouncing-canvas-images.js delete mode 100644 MotionMark/tests/bouncing-particles/resources/bouncing-canvas-particles.js delete mode 100644 MotionMark/tests/bouncing-particles/resources/bouncing-canvas-shapes.js delete mode 100644 MotionMark/tests/bouncing-particles/resources/bouncing-css-images.js delete mode 100644 MotionMark/tests/bouncing-particles/resources/bouncing-css-shapes.js delete mode 100644 MotionMark/tests/bouncing-particles/resources/bouncing-particles.js delete mode 100644 MotionMark/tests/bouncing-particles/resources/bouncing-svg-particles.js delete mode 100644 MotionMark/tests/bouncing-particles/resources/bouncing-svg-shapes.js delete mode 100644 MotionMark/tests/bouncing-particles/resources/bouncing-tagged-images.js delete mode 100644 MotionMark/tests/bouncing-particles/resources/image1.jpg delete mode 100644 MotionMark/tests/bouncing-particles/resources/image2.jpg delete mode 100644 MotionMark/tests/bouncing-particles/resources/image3.jpg delete mode 100644 MotionMark/tests/bouncing-particles/resources/image4.jpg delete mode 100644 MotionMark/tests/bouncing-particles/resources/image5.jpg rename MotionMark/tests/{bouncing-particles/bouncing-canvas-images.html => core/canvas-arcs.html} (52%) rename MotionMark/tests/{3d/triangles-webgpu.html => core/canvas-lines.html} (51%) delete mode 100644 MotionMark/tests/core/canvas-stage.html rename MotionMark/tests/{dom/leaves.html => core/image-canvases.html} (50%) delete mode 100644 MotionMark/tests/core/image-data.html rename MotionMark/tests/core/{resources => images}/compass100.png (100%) rename MotionMark/tests/core/{resources => images}/console100.png (100%) rename MotionMark/tests/core/{resources => images}/contribute100.png (100%) rename MotionMark/tests/core/{resources => images}/debugger100.png (100%) rename MotionMark/tests/core/{resources => images}/inspector100.png (100%) rename MotionMark/tests/core/{resources => images}/layout100.png (100%) rename MotionMark/tests/core/{resources => images}/performance100.png (100%) rename MotionMark/tests/core/{resources => images}/script100.png (100%) rename MotionMark/tests/core/{resources => images}/shortcuts100.png (100%) rename MotionMark/tests/core/{resources => images}/standards100.png (100%) rename MotionMark/tests/core/{resources => images}/storage100.png (100%) rename MotionMark/tests/core/{resources => images}/styles100.png (100%) rename MotionMark/tests/core/{resources => images}/timeline100.png (100%) rename MotionMark/tests/{bouncing-particles/bouncing-canvas-shapes.html => core/paths.html} (52%) create mode 100644 MotionMark/tests/core/resources/canvas-arcs.js create mode 100644 MotionMark/tests/core/resources/canvas-lines.js delete mode 100644 MotionMark/tests/core/resources/canvas-stage.js delete mode 100644 MotionMark/tests/core/resources/canvas-tests.js delete mode 100644 MotionMark/tests/core/resources/compass.svg delete mode 100644 MotionMark/tests/core/resources/console.svg delete mode 100644 MotionMark/tests/core/resources/contribute.svg delete mode 100644 MotionMark/tests/core/resources/debugger.svg delete mode 100644 MotionMark/tests/core/resources/focus.js create mode 100644 MotionMark/tests/core/resources/image-canvases.js delete mode 100644 MotionMark/tests/core/resources/image-data.js delete mode 100644 MotionMark/tests/core/resources/inspector.svg delete mode 100644 MotionMark/tests/core/resources/layout.svg delete mode 100644 MotionMark/tests/core/resources/particles.js create mode 100644 MotionMark/tests/core/resources/paths.js delete mode 100644 MotionMark/tests/core/resources/performance.svg delete mode 100644 MotionMark/tests/core/resources/script.svg delete mode 100644 MotionMark/tests/core/resources/shortcuts.svg delete mode 100644 MotionMark/tests/core/resources/standards.svg delete mode 100644 MotionMark/tests/core/resources/storage.svg delete mode 100644 MotionMark/tests/core/resources/styles.svg delete mode 100644 MotionMark/tests/core/resources/timeline.svg create mode 100644 MotionMark/tests/core/shared/disposable-particles.js create mode 100644 MotionMark/tests/core/shared/resettable-particle.js create mode 100644 MotionMark/tests/core/shared/reusable-particles.js rename MotionMark/tests/{simple/resources/simple-canvas.js => core/shared/reusable-segments.js} (54%) delete mode 100644 MotionMark/tests/dom/compositing-transforms.html delete mode 100644 MotionMark/tests/dom/focus.html delete mode 100644 MotionMark/tests/dom/multiply.html delete mode 100644 MotionMark/tests/dom/particles.html delete mode 100644 MotionMark/tests/dom/resources/compositing-transforms.js delete mode 100644 MotionMark/tests/dom/resources/dom-particles.js delete mode 100644 MotionMark/tests/dom/resources/focus.js delete mode 100644 MotionMark/tests/dom/resources/leaves.js delete mode 100644 MotionMark/tests/resources/main.js delete mode 100644 MotionMark/tests/resources/math.js delete mode 100644 MotionMark/tests/resources/star.svg delete mode 100644 MotionMark/tests/resources/yin-yang.png delete mode 100644 MotionMark/tests/resources/yin-yang.svg delete mode 100644 MotionMark/tests/simple/resources/simple-canvas-paths.js delete mode 100644 MotionMark/tests/simple/resources/tiled-canvas-image.js delete mode 100644 MotionMark/tests/simple/simple-canvas-paths.html delete mode 100644 MotionMark/tests/simple/tiled-canvas-image.html delete mode 100644 MotionMark/tests/svg/suits.html delete mode 100644 MotionMark/tests/svg/suits.js delete mode 100644 MotionMark/tests/template/resources/template-canvas.js delete mode 100644 MotionMark/tests/template/template-canvas.html delete mode 100644 MotionMark/tests/template/template-css.html delete mode 100644 MotionMark/tests/template/template-svg.html delete mode 100644 MotionMark/tests/text/design-6.html delete mode 100644 MotionMark/tests/text/design-6.js delete mode 100644 MotionMark/tests/text/design.html delete mode 100644 MotionMark/tests/text/design.js create mode 100644 MotionMark/unit-tests/resources/js-test.js create mode 100644 MotionMark/unit-tests/test-animator.html create mode 100644 MotionMark/unit-tests/test-fixed-controller.html create mode 100644 MotionMark/unit-tests/test-ramp-controller.html create mode 100644 MotionMark/unit-tests/test-regression.html create mode 100644 MotionMark/unit-tests/test-spiral-iterator.html diff --git a/MotionMark/about.html b/MotionMark/about.html index 0a8ee10..56ae406 100644 --- a/MotionMark/about.html +++ b/MotionMark/about.html @@ -1,5 +1,5 @@ - - - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/bouncing-particles/bouncing-css-images.html b/MotionMark/tests/bouncing-particles/bouncing-css-images.html deleted file mode 100644 index b52a2b9..0000000 --- a/MotionMark/tests/bouncing-particles/bouncing-css-images.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - -
- - - - - - - - - diff --git a/MotionMark/tests/bouncing-particles/bouncing-css-shapes.html b/MotionMark/tests/bouncing-particles/bouncing-css-shapes.html deleted file mode 100644 index 00df8d6..0000000 --- a/MotionMark/tests/bouncing-particles/bouncing-css-shapes.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - -
- - - - - - - - - diff --git a/MotionMark/tests/bouncing-particles/bouncing-svg-images.html b/MotionMark/tests/bouncing-particles/bouncing-svg-images.html deleted file mode 100644 index 351cd6b..0000000 --- a/MotionMark/tests/bouncing-particles/bouncing-svg-images.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/bouncing-particles/bouncing-svg-shapes.html b/MotionMark/tests/bouncing-particles/bouncing-svg-shapes.html deleted file mode 100644 index 233f649..0000000 --- a/MotionMark/tests/bouncing-particles/bouncing-svg-shapes.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/bouncing-particles/bouncing-tagged-images.html b/MotionMark/tests/bouncing-particles/bouncing-tagged-images.html deleted file mode 100644 index fc0e2f9..0000000 --- a/MotionMark/tests/bouncing-particles/bouncing-tagged-images.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - -
- - diff --git a/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-images.js b/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-images.js deleted file mode 100644 index 733f28f..0000000 --- a/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-images.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2015-2023 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -BouncingCanvasImage = Utilities.createSubclass(BouncingCanvasParticle, - function(stage) - { - BouncingCanvasParticle.call(this, stage, "image"); - this._imageElement = stage.imageElement; - }, { - - _draw: function() - { - this.context.save(); - this.applyRotation(); - this.context.drawImage(this._imageElement, 0, 0, this.size.x, this.size.y); - this.context.restore(); - } -}); - -BouncingCanvasImagesStage = Utilities.createSubclass(BouncingCanvasParticlesStage, - function() - { - BouncingCanvasParticlesStage.call(this); - }, { - - initialize: function(benchmark, options) - { - BouncingCanvasParticlesStage.prototype.initialize.call(this, benchmark, options); - var imageSrc = options["imageSrc"] || "../resources/yin-yang.svg"; - this.imageElement = document.querySelector(".hidden[src=\"" + imageSrc + "\"]"); - }, - - createParticle: function() - { - return new BouncingCanvasImage(this); - } -}); - -BouncingCanvasImagesBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new BouncingCanvasImagesStage(), options); - } -); - -window.benchmarkClass = BouncingCanvasImagesBenchmark; - -})(); diff --git a/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-particles.js b/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-particles.js deleted file mode 100644 index ce12c72..0000000 --- a/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-particles.js +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -BouncingCanvasParticle = Utilities.createSubclass(BouncingParticle, - function(stage, shape) - { - BouncingParticle.call(this, stage); - this.context = stage.context; - this._shape = shape; - this._clip = stage.clip; - }, { - - applyRotation: function() - { - if (this._shape == "circle") - return; - - this.context.translate(this.size.x / 2, this.size.y / 2); - this.context.rotate(this.rotater.degree() * Math.PI / 180); - this.context.translate(-this.size.x / 2, -this.size.y / 2); - }, - - applyClipping: function() - { - var clipPoints = BouncingCanvasParticle.clips[this._clip]; - if (!clipPoints) - return; - - this.context.beginPath(); - clipPoints.forEach(function(point, index) { - var point = this.size.multiply(point); - if (!index) - this.context.moveTo(point.x, point.y); - else - this.context.lineTo(point.x, point.y); - }, this); - - this.context.closePath(); - this.context.clip(); - }, - - _draw: function() - { - throw "Not implemented"; - }, - - animate: function(timeDelta) - { - BouncingParticle.prototype.animate.call(this, timeDelta); - this.context.save(); - this.context.translate(this.position.x, this.position.y); - this._draw(); - this.context.restore(); - } -}); - -BouncingCanvasParticle.clips = { - star: [ - new Point(0.50, 0.00), - new Point(0.38, 0.38), - new Point(0.00, 0.38), - new Point(0.30, 0.60), - new Point(0.18, 1.00), - new Point(0.50, 0.75), - new Point(0.82, 1.00), - new Point(0.70, 0.60), - new Point(1.00, 0.38), - new Point(0.62, 0.38) - ] -}; - -BouncingCanvasParticlesStage = Utilities.createSubclass(BouncingParticlesStage, - function() - { - BouncingParticlesStage.call(this); - }, { - - initialize: function(benchmark, options) - { - BouncingParticlesStage.prototype.initialize.call(this, benchmark, options); - this.context = this.element.getContext("2d"); - }, - - animate: function(timeDelta) - { - this.context.clearRect(0, 0, this.size.x, this.size.y); - this.particles.forEach(function(particle) { - particle.animate(timeDelta); - }); - } -}); diff --git a/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-shapes.js b/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-shapes.js deleted file mode 100644 index f3d0d81..0000000 --- a/MotionMark/tests/bouncing-particles/resources/bouncing-canvas-shapes.js +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -BouncingCanvasShape = Utilities.createSubclass(BouncingCanvasParticle, - function(stage) - { - BouncingCanvasParticle.call(this, stage, stage.shape); - this._fill = stage.fill; - this._color0 = Stage.randomColor(); - this._color1 = Stage.randomColor(); - }, { - - _applyFill: function() - { - switch (this._fill) { - case "gradient": - var gradient = this.context.createLinearGradient(0, 0, this.size.width, 0); - gradient.addColorStop(0, this._color0); - gradient.addColorStop(1, this._color1); - this.context.fillStyle = gradient; - break; - - case "solid": - default: - this.context.fillStyle = this._color0; - break; - } - }, - - _drawShape: function() - { - this.context.beginPath(); - - switch (this._shape) { - case "rect": - this.context.rect(0, 0, this.size.width, this.size.height); - break; - - case "circle": - default: - var center = this.size.center; - var radius = Math.min(this.size.x, this.size.y) / 2; - this.context.arc(center.x, center.y, radius, 0, Math.PI * 2, true); - break; - } - - this.context.fill(); - }, - - _draw: function() - { - this.context.save(); - this._applyFill(); - this.applyRotation(); - this.applyClipping(); - this._drawShape(); - this.context.restore(); - } -}); - -BouncingCanvasShapesStage = Utilities.createSubclass(BouncingCanvasParticlesStage, - function () - { - BouncingCanvasParticlesStage.call(this); - }, { - - initialize: function(benchmark, options) - { - BouncingCanvasParticlesStage.prototype.initialize.call(this, benchmark, options); - this.parseShapeParameters(options); - }, - - createParticle: function() - { - return new BouncingCanvasShape(this); - } -}); - -BouncingCanvasShapesBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new BouncingCanvasShapesStage(), options); - } -); - -window.benchmarkClass = BouncingCanvasShapesBenchmark; - -})(); \ No newline at end of file diff --git a/MotionMark/tests/bouncing-particles/resources/bouncing-css-images.js b/MotionMark/tests/bouncing-particles/resources/bouncing-css-images.js deleted file mode 100644 index 2f3fa53..0000000 --- a/MotionMark/tests/bouncing-particles/resources/bouncing-css-images.js +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -BouncingCssImage = Utilities.createSubclass(BouncingParticle, - function(stage) - { - BouncingParticle.call(this, stage); - - this.element = document.createElement("img"); - this.element.style.width = this.size.x + "px"; - this.element.style.height = this.size.y + "px"; - this.element.setAttribute("src", stage.imageSrc); - - stage.element.appendChild(this.element); - this._move(); - }, { - - _move: function() - { - this.element.style.transform = "translate(" + this.position.x + "px," + this.position.y + "px) " + this.rotater.rotateZ(); - }, - - animate: function(timeDelta) - { - BouncingParticle.prototype.animate.call(this, timeDelta); - this._move(); - } -}); - -BouncingCssImagesStage = Utilities.createSubclass(BouncingParticlesStage, - function() - { - BouncingParticlesStage.call(this); - }, { - - initialize: function(benchmark, options) - { - BouncingParticlesStage.prototype.initialize.call(this, benchmark, options); - this.imageSrc = options["imageSrc"] || "../resources/yin-yang.svg"; - }, - - createParticle: function() - { - return new BouncingCssImage(this); - }, - - particleWillBeRemoved: function(particle) - { - particle.element.remove(); - } -}); - -BouncingCssImagesBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new BouncingCssImagesStage(), options); - } -); - -window.benchmarkClass = BouncingCssImagesBenchmark; - -})(); diff --git a/MotionMark/tests/bouncing-particles/resources/bouncing-css-shapes.js b/MotionMark/tests/bouncing-particles/resources/bouncing-css-shapes.js deleted file mode 100644 index d3048d4..0000000 --- a/MotionMark/tests/bouncing-particles/resources/bouncing-css-shapes.js +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -BouncingCssShape = Utilities.createSubclass(BouncingParticle, - function(stage) - { - BouncingParticle.call(this, stage); - - this.element = this._createSpan(stage); - - switch (stage.fill) { - case "solid": - default: - this.element.style.backgroundColor = Stage.randomColor(); - break; - - case "gradient": - this.element.style.background = "linear-gradient(" + Stage.randomColor() + ", " + Stage.randomColor() + ")"; - break; - } - - if (stage.blend) - this.element.style.mixBlendMode = Stage.randomStyleMixBlendMode(); - - // Some browsers have not un-prefixed the css filter yet. - if (stage.filter) - Utilities.setElementPrefixedProperty(this.element, "filter", Stage.randomStyleFilter()); - - this._move(); - }, { - - _createSpan: function(stage) - { - var span = document.createElement("span"); - span.className = stage.shape + " " + stage.clip; - span.style.width = this.size.x + "px"; - span.style.height = this.size.y + "px"; - stage.element.appendChild(span); - return span; - }, - - _move: function() - { - this.element.style.transform = "translate(" + this.position.x + "px," + this.position.y + "px)" + this.rotater.rotateZ(); - }, - - animate: function(timeDelta) - { - BouncingParticle.prototype.animate.call(this, timeDelta); - this.rotater.next(timeDelta); - this._move(); - } -}); - -BouncingCssShapesStage = Utilities.createSubclass(BouncingParticlesStage, - function() - { - BouncingParticlesStage.call(this); - }, { - - initialize: function(benchmark, options) - { - BouncingParticlesStage.prototype.initialize.call(this, benchmark, options); - this.parseShapeParameters(options); - }, - - createParticle: function() - { - return new BouncingCssShape(this); - }, - - particleWillBeRemoved: function(particle) - { - particle.element.remove(); - } -}); - -BouncingCssShapesBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new BouncingCssShapesStage(), options); - } -); - -window.benchmarkClass = BouncingCssShapesBenchmark; - -})(); diff --git a/MotionMark/tests/bouncing-particles/resources/bouncing-particles.js b/MotionMark/tests/bouncing-particles/resources/bouncing-particles.js deleted file mode 100644 index 393d4b2..0000000 --- a/MotionMark/tests/bouncing-particles/resources/bouncing-particles.js +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -function BouncingParticle(stage) -{ - this._stageSize = stage.size; - this.size = stage.particleSize; - - this.position = Stage.randomPosition(stage.size.subtract(stage.particleSize)); - this._angle = Stage.randomAngle(); - this._velocity = Stage.randomVelocity(stage.maxVelocity); - this.rotater = Stage.randomRotater(); -} - -BouncingParticle.prototype = -{ - get center() - { - return this.position.add(this.size.center); - }, - - animate: function(timeDelta) - { - this.position = this.position.move(this._angle, this._velocity, timeDelta); - this.rotater.next(timeDelta); - - // If particle is going to move off right side - if (this.position.x + this.size.x > this._stageSize.x) { - // If direction is East-South, go West-South. - if (this._angle >= 0 && this._angle < Math.PI / 2) - this._angle = Math.PI - this._angle; - // If angle is East-North, go West-North. - else if (this._angle > Math.PI / 2 * 3) - this._angle = this._angle - (this._angle - Math.PI / 2 * 3) * 2; - // Make sure the particle does not go outside the stage boundaries. - this.position.x = this._stageSize.x - this.size.x; - } - - // If particle is going to move off left side - if (this.position.x < 0) { - // If angle is West-South, go East-South. - if (this._angle > Math.PI / 2 && this._angle < Math.PI) - this._angle = Math.PI - this._angle; - // If angle is West-North, go East-North. - else if (this._angle > Math.PI && this._angle < Math.PI / 2 * 3) - this._angle = this._angle + (Math.PI / 2 * 3 - this._angle) * 2; - // Make sure the particle does not go outside the stage boundaries. - this.position.x = 0; - } - - // If particle is going to move off bottom side - if (this.position.y + this.size.y > this._stageSize.y) { - // If direction is South, go North. - if (this._angle > 0 && this._angle < Math.PI) - this._angle = Math.PI * 2 - this._angle; - // Make sure the particle does not go outside the stage boundaries. - this.position.y = this._stageSize.y - this.size.y; - } - - // If particle is going to move off top side - if (this.position.y < 0) { - // If direction is North, go South. - if (this._angle > Math.PI && this._angle < Math.PI * 2) - this._angle = this._angle - (this._angle - Math.PI) * 2; - // Make sure the particle does not go outside the stage boundaries. - this.position.y = 0; - } - } -} - -BouncingParticlesStage = Utilities.createSubclass(Stage, - function() - { - Stage.call(this); - this.particles = []; - }, { - - initialize: function(benchmark, options) - { - Stage.prototype.initialize.call(this, benchmark, options); - this.particleSize = new Point(parseInt(options["particleWidth"]) || 10, parseInt(options["particleHeight"]) || 10); - this.maxVelocity = Math.max(parseInt(options["maxVelocity"]) || 500, 100); - }, - - parseShapeParameters: function(options) - { - this.shape = options["shape"] || "circle"; - this.fill = options["fill"] || "solid"; - this.clip = options["clip"] || ""; - this.blend = options["blend"] || false; - this.filter = options["filter"] || false; - }, - - animate: function(timeDelta) - { - this.particles.forEach(function(particle) { - particle.animate(timeDelta); - }); - }, - - tune: function(count) - { - if (count == 0) - return; - - if (count > 0) { - for (var i = 0; i < count; ++i) - this.particles.push(this.createParticle()); - return; - } - - count = Math.min(-count, this.particles.length); - - if (typeof(this.particleWillBeRemoved) == "function") { - for (var i = 0; i < count; ++i) - this.particleWillBeRemoved(this.particles[this.particles.length - 1 - i]); - } - - this.particles.splice(-count, count); - }, - - complexity: function() - { - return this.particles.length; - } -}); diff --git a/MotionMark/tests/bouncing-particles/resources/bouncing-svg-particles.js b/MotionMark/tests/bouncing-particles/resources/bouncing-svg-particles.js deleted file mode 100644 index ae10dfd..0000000 --- a/MotionMark/tests/bouncing-particles/resources/bouncing-svg-particles.js +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -BouncingSvgParticle = Utilities.createSubclass(BouncingParticle, - function(stage, shape) - { - BouncingParticle.call(this, stage); - this._shape = shape; - }, { - - _applyClipping: function(stage) - { - if (stage.clip != "star") - return; - - stage.ensureClipStarIsCreated(); - this.element.setAttribute("clip-path", "url(#star-clip)"); - }, - - _move: function() - { - var transform = "translate(" + this.position.x + ", " + this.position.y + ")"; - if (this._shape != "circle") - transform += this.rotater.rotate(this.size.center); - this.element.setAttribute("transform", transform); - }, - - animate: function(timeDelta) - { - BouncingParticle.prototype.animate.call(this, timeDelta); - this._move(); - } -}); - -BouncingSvgParticlesStage = Utilities.createSubclass(BouncingParticlesStage, - function() - { - BouncingParticlesStage.call(this); - }, { - - _createDefs: function() - { - return Utilities.createSVGElement("defs", {}, {}, this.element); - }, - - _ensureDefsIsCreated: function() - { - return this.element.querySelector("defs") || this._createDefs(); - }, - - _createClipStar: function() - { - var attrs = { id: "star-clip", clipPathUnits: "objectBoundingBox" }; - var clipPath = Utilities.createSVGElement("clipPath", attrs, {}, this._ensureDefsIsCreated()); - - attrs = { d: "M.50,0L.38,.38L0,.38L.30,.60L.18,1L.50,.75L.82,1L.70,.60L1,.38L.62,.38z" }; - Utilities.createSVGElement("path", attrs, {}, clipPath); - return clipPath; - }, - - ensureClipStarIsCreated: function() - { - return this.element.querySelector("#star-clip") || this._createClipStar(); - }, - - particleWillBeRemoved: function(particle) - { - particle.element.remove(); - } -}); diff --git a/MotionMark/tests/bouncing-particles/resources/bouncing-svg-shapes.js b/MotionMark/tests/bouncing-particles/resources/bouncing-svg-shapes.js deleted file mode 100644 index 91be977..0000000 --- a/MotionMark/tests/bouncing-particles/resources/bouncing-svg-shapes.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -BouncingSvgShape = Utilities.createSubclass(BouncingSvgParticle, - function(stage) - { - BouncingSvgParticle.call(this, stage, stage.shape); - this._fill = stage.fill; - - this._createShape(stage); - this._applyClipping(stage); - this._applyFill(stage); - - this._move(); - }, { - - _createShape: function(stage) - { - switch (this._shape) { - case "rect": - var attrs = { x: 0, y: 0, width: this.size.x, height: this.size.y }; - this.element = Utilities.createSVGElement("rect", attrs, {}, stage.element); - break; - - case "circle": - default: - var attrs = { cx: this.size.x / 2, cy: this.size.y / 2, r: Math.min(this.size.x, this.size.y) / 2 }; - this.element = Utilities.createSVGElement("circle", attrs, {}, stage.element); - break; - } - }, - - _applyFill: function(stage) - { - switch (this._fill) { - case "gradient": - var gradient = stage.createGradient(2); - this.element.setAttribute("fill", "url(#" + gradient.getAttribute("id") + ")"); - break; - - case "solid": - default: - this.element.setAttribute("fill", Stage.randomColor()); - break; - } - } -}); - -BouncingSvgShapesStage = Utilities.createSubclass(BouncingSvgParticlesStage, - function() - { - BouncingSvgParticlesStage.call(this); - }, { - - initialize: function(benchmark, options) - { - BouncingSvgParticlesStage.prototype.initialize.call(this, benchmark, options); - this.parseShapeParameters(options); - this._gradientsCount = 0; - }, - - createGradient: function(stops) - { - var attrs = { id: "gradient-" + ++this._gradientsCount }; - var gradient = Utilities.createSVGElement("linearGradient", attrs, {}, this._ensureDefsIsCreated()); - - for (var i = 0; i < stops; ++i) { - attrs = { offset: i * 100 / (stops - 1) + "%", 'stop-color': Stage.randomColor() }; - Utilities.createSVGElement("stop", attrs, {}, gradient); - } - - return gradient; - }, - - createParticle: function() - { - return new BouncingSvgShape(this); - }, - - particleWillBeRemoved: function(particle) - { - BouncingSvgParticlesStage.prototype.particleWillBeRemoved.call(this, particle); - - var fill = particle.element.getAttribute("fill"); - if (fill.indexOf("url(#") != 0) - return; - - var gradient = this.element.querySelector(fill.substring(4, fill.length - 1)); - this._ensureDefsIsCreated().removeChild(gradient); - } -}); - -BouncingSvgShapesBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new BouncingSvgShapesStage(), options); - } -); - -window.benchmarkClass = BouncingSvgShapesBenchmark; - -})(); diff --git a/MotionMark/tests/bouncing-particles/resources/bouncing-tagged-images.js b/MotionMark/tests/bouncing-particles/resources/bouncing-tagged-images.js deleted file mode 100644 index d8be60f..0000000 --- a/MotionMark/tests/bouncing-particles/resources/bouncing-tagged-images.js +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -BouncingTaggedImage = Utilities.createSubclass(BouncingParticle, - function(stage) - { - BouncingParticle.call(this, stage); - - this.element = document.createElement("img"); - this.element.style.width = this.size.x + "px"; - this.element.style.height = this.size.y + "px"; - this.element.setAttribute("src", Stage.randomElementInArray(stage.images).src); - - stage.element.appendChild(this.element); - this._move(); - }, { - - _move: function() - { - this.element.style.transform = "translate(" + this.position.x + "px," + this.position.y + "px) " + this.rotater.rotateZ(); - }, - - animate: function(timeDelta) - { - BouncingParticle.prototype.animate.call(this, timeDelta); - this._move(); - } -}); - -BouncingTaggedImagesStage = Utilities.createSubclass(BouncingParticlesStage, - - function() - { - BouncingParticlesStage.call(this); - }, { - - imageSrcs: [ - "image1", - "image2", - "image3", - "image4", - "image5", - ], - images: [], - - initialize: function(benchmark, options) - { - BouncingParticlesStage.prototype.initialize.call(this, benchmark, options); - - var lastPromise; - var images = this.images; - this.imageSrcs.forEach(function(imageSrc) { - var promise = this._loadImage("resources/" + imageSrc + ".jpg"); - if (!lastPromise) - lastPromise = promise; - else { - lastPromise = lastPromise.then(function(img) { - images.push(img); - return promise; - }); - } - }, this); - - lastPromise.then(function(img) { - images.push(img); - benchmark.readyPromise.resolve(); - }); - }, - - _loadImage: function(src) { - var img = new Image; - var promise = new SimplePromise; - - img.onload = function(e) { - promise.resolve(e.target); - }; - - img.src = src; - return promise; - }, - - createParticle: function() - { - return new BouncingTaggedImage(this); - }, - - particleWillBeRemoved: function(particle) - { - particle.element.remove(); - } -}); - -BouncingTaggedImagesBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new BouncingTaggedImagesStage(), options); - }, { - - waitUntilReady: function() { - this.readyPromise = new SimplePromise; - return this.readyPromise; - } -}); - -window.benchmarkClass = BouncingTaggedImagesBenchmark; - -})(); diff --git a/MotionMark/tests/bouncing-particles/resources/image1.jpg b/MotionMark/tests/bouncing-particles/resources/image1.jpg deleted file mode 100644 index ea7a4c13036853caf37e38e546179222b320d2c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64004 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�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 diff --git a/MotionMark/tests/bouncing-particles/resources/image2.jpg b/MotionMark/tests/bouncing-particles/resources/image2.jpg deleted file mode 100644 index 697272dcb09395d2e3fb0247d60686f0960efd26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71981 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%0ATDpEhLe1%A;>W)@yZzvF0`-NSr*_1? zG8k|M6TUQjTKsxbL4R0c3w;3`!i-45O5L@jgmn+)00nsU7cVMV#q7rr2|ox3Q}*f0 z3@ah8TT8@Pl080+LzXLnb4? zYMRC`n^|>!8;od+V5K0IL>0-ErSsPVV{pl7bPX?Zt(fPh`s~-q_;Icmio;bKIvrs* zwEc4v>^^ISTxho|-R&|-*;9>sVC-UHtUY-}h^@8sY}duTE=zsvX$a8tn94-DB?(W8 z8dprQ1=WGW`&Y>We8ztj)bd5(6R+_%w;4noRf1hO!0`QNfGe5>F?t1VO$_4EsUp1^ zvKv~Tq5m}eQ+xSknU_Jf`IxBM6MQw&>?Vyxjf#lmc5@?nAHuJ4)I?#-m*3MRj}^Sq z=1-0rc$yNgt=y}i9-0+f8|te8Vfmh|)H-mddWNE*l)Z`>K0I;zUPPA}@%`0hD9iRh z>}@-dqkJM-6*54r$xw=4k|TqT6E2w6^=wj3Niljtv%gvX2$K+&eJiqNkYvkvn*aNU zYypn!cq5@nm&G1&-j^aOasDTs`^qhE#`R3J{g!QJi=XsVeuBGz&4!-B`-<)-H1sC@ zsR{v0S#Nnazl+?BntbE$I-<&Kbv_{B_lmJ9&1(j=s#;Tpn=Qvx+x^!s1&#W2cg zEusJUdX`Hc#W-Fo86ME9$*o4TYzd6Zd-vf&`ss(JFNWQ77IX2Fs-@k|PlKV7ci#67oI3RQK*Hk3p%rVl(>Fz)`9AqG zut-vBej2%fJ%#+SaKoTL%$GKgzOg?vgYn!(Tl=~i#wjk-@__6GwI%SB3uJDmDQ_Hf z4yqP=;Ae%FHc$?R6!+0XYD8y545Sz`4#whOGt?yBHGbqR5AQ?klclN9K?f-f;EsJf z9?Ewy(l%ovTaa%|xrO6gH|Ds%`YYAhw&bDb^V1h5)^h6$G`N_F)CnImZtEQ|Jp>2b zXY;OgHTV&L5YWHS5fqUTz6=eYN<$~UsNJmeAUGxSRl_@r3bMS>d4ah3xWx@@5!ayc$3@9r=2mCjN>_2Fo zo)B zAS>nf4l+825sWAQ#xF8_L)jpZ9M<%5_$ z9S@Jfmv7xI_i}6D_1zD44dc=AZ(v;0$ypS4*8OTUZsuiBda*0IZS7_Sb-N*rv#r+9=2BvJ}3UZI%XpM7=!;a@}q&#^i_59#r@qm7`^3D4I*z zZnJiGpjjUsHmxLYzT3( zt59HE@y&m(ydOSd8hL8vPyvzBnnKYxudT1EI=sriM5kC=7*gCTMpDZv_# z=ylXwCu^5@v?bE&xHC5%C^)Yz-hUEYeBARv9CI93+;culjw+yf5QmQbdBaM*Yu@`KjZ5sp#OdA5?vxwCOmQUG060EaVZc~{DtqE`h&dXvqol1 zMTH^8bV3#)(cA#wQR5PAlI?E%48#fMm@O6h)eendjum*Up;H3AGk(TikadA34|0>~ z>U-VvFAw+@jj2}CWw;mBj#dr_K;g9k2G_+T=8*h-q$g#1bCfbo#;&aFKKHsnavKG! zE~>bodD)(lbjKhCJ#KH^RQ3b8Z_mV(xB>5(7%K}TX<Uq%thIwz%rNi$NsXu)y!4~dfuWg{{*U3MbTnE<%`M^Ys%Y` zr{YY@`EYkw*JhZsv*Prvtgned$)VK%2~h9_Ls+T}LVPrQ5Bm06XvUngLQ?D$NvkXS zP{#*M5;^?`5(ZIq7mmlRclivmci>;p3$eCa*hXXHdR1%~Rjy-$h%UuQm|gQ(LRvE^+!&~0 z@8s}b#ZCYl-E0tghn|jjjFzaC_WIDGj2-l<1wkS^^Cxxi0?La6C2E*R7cz)=0CS5V zdr!!wQ1BzFgh2LV8w%D#Ykmh=c{Vg z@7D?i31ilK%7|;8ILt@unS4l(`@RPW*yuHWMc;sFk@k@$S=bNCo~kvAUk$g(5I5=N z;}+eMnrA#n2~liB2o2v!5TuD82h6vhNV@q#EtTWJz#=EEB~QU zK}Ro=vdO+*SV*RC<^2u<(Ou2xMftTkxo2mxT;*5aaB_K>^2ir;FNd7h?>S$9Euh9v{~vD)9HsyO diff --git a/MotionMark/tests/bouncing-particles/resources/image3.jpg b/MotionMark/tests/bouncing-particles/resources/image3.jpg deleted file mode 100644 index 6e5964e7a98f6db41ac0e52618ee2ff20dc7c077..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71319 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 diff --git a/MotionMark/tests/bouncing-particles/resources/image5.jpg b/MotionMark/tests/bouncing-particles/resources/image5.jpg deleted file mode 100644 index d7971f6bcbaf0674c9006a7fb8c7e4929a5f44f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135674 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

G3<-|x|NJ~m7Ng|}gr4Y&pDP?IX zft8;iC=HKtRyNbpSt$#oR0UUz^7HeP@RO0i;$0*WN=izSQqq#r(&B(aoN&U6=;$x* zMG#t*poJzN@fgyY1_4+in6LLCstN*4NhY9>Yf^DwzKtXkg_J~lpgqxEL;`RZ0=9~5 zt|xAdc|*UhGCKMI¨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%0Ak-Pn{iVVxoIwaSB=(QE>eL*PE-_e3O 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

- - - - - - - - diff --git a/MotionMark/tests/core/resources/compass100.png b/MotionMark/tests/core/images/compass100.png similarity index 100% rename from MotionMark/tests/core/resources/compass100.png rename to MotionMark/tests/core/images/compass100.png diff --git a/MotionMark/tests/core/resources/console100.png b/MotionMark/tests/core/images/console100.png similarity index 100% rename from MotionMark/tests/core/resources/console100.png rename to MotionMark/tests/core/images/console100.png diff --git a/MotionMark/tests/core/resources/contribute100.png b/MotionMark/tests/core/images/contribute100.png similarity index 100% rename from MotionMark/tests/core/resources/contribute100.png rename to MotionMark/tests/core/images/contribute100.png diff --git a/MotionMark/tests/core/resources/debugger100.png b/MotionMark/tests/core/images/debugger100.png similarity index 100% rename from MotionMark/tests/core/resources/debugger100.png rename to MotionMark/tests/core/images/debugger100.png diff --git a/MotionMark/tests/core/resources/inspector100.png b/MotionMark/tests/core/images/inspector100.png similarity index 100% rename from MotionMark/tests/core/resources/inspector100.png rename to MotionMark/tests/core/images/inspector100.png diff --git a/MotionMark/tests/core/resources/layout100.png b/MotionMark/tests/core/images/layout100.png similarity index 100% rename from MotionMark/tests/core/resources/layout100.png rename to MotionMark/tests/core/images/layout100.png diff --git a/MotionMark/tests/core/resources/performance100.png b/MotionMark/tests/core/images/performance100.png similarity index 100% rename from MotionMark/tests/core/resources/performance100.png rename to MotionMark/tests/core/images/performance100.png diff --git a/MotionMark/tests/core/resources/script100.png b/MotionMark/tests/core/images/script100.png similarity index 100% rename from MotionMark/tests/core/resources/script100.png rename to MotionMark/tests/core/images/script100.png diff --git a/MotionMark/tests/core/resources/shortcuts100.png b/MotionMark/tests/core/images/shortcuts100.png similarity index 100% rename from MotionMark/tests/core/resources/shortcuts100.png rename to MotionMark/tests/core/images/shortcuts100.png diff --git a/MotionMark/tests/core/resources/standards100.png b/MotionMark/tests/core/images/standards100.png similarity index 100% rename from MotionMark/tests/core/resources/standards100.png rename to MotionMark/tests/core/images/standards100.png diff --git a/MotionMark/tests/core/resources/storage100.png b/MotionMark/tests/core/images/storage100.png similarity index 100% rename from MotionMark/tests/core/resources/storage100.png rename to MotionMark/tests/core/images/storage100.png diff --git a/MotionMark/tests/core/resources/styles100.png b/MotionMark/tests/core/images/styles100.png similarity index 100% rename from MotionMark/tests/core/resources/styles100.png rename to MotionMark/tests/core/images/styles100.png diff --git a/MotionMark/tests/core/resources/timeline100.png b/MotionMark/tests/core/images/timeline100.png similarity index 100% rename from MotionMark/tests/core/resources/timeline100.png rename to MotionMark/tests/core/images/timeline100.png diff --git a/MotionMark/tests/core/leaves.html b/MotionMark/tests/core/leaves.html index 7d9bd3f..31d515c 100644 --- a/MotionMark/tests/core/leaves.html +++ b/MotionMark/tests/core/leaves.html @@ -1,5 +1,5 @@ - - - - - diff --git a/MotionMark/tests/core/resources/console.svg b/MotionMark/tests/core/resources/console.svg deleted file mode 100644 index e3c7611..0000000 --- a/MotionMark/tests/core/resources/console.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/MotionMark/tests/core/resources/contribute.svg b/MotionMark/tests/core/resources/contribute.svg deleted file mode 100644 index 68860ef..0000000 --- a/MotionMark/tests/core/resources/contribute.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/MotionMark/tests/core/resources/debugger.svg b/MotionMark/tests/core/resources/debugger.svg deleted file mode 100644 index 646ddf4..0000000 --- a/MotionMark/tests/core/resources/debugger.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/MotionMark/tests/core/resources/design.js b/MotionMark/tests/core/resources/design.js index ff09468..7e3ed31 100644 --- a/MotionMark/tests/core/resources/design.js +++ b/MotionMark/tests/core/resources/design.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,122 +22,107 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ -(function() { - -var TextStage = Utilities.createSubclass(Stage, - function() - { - Stage.call(this); - - this.testElements = []; - this._offsetIndex = 0; - }, { - - shadowFalloff: new UnitBezier(new Point(0.015, 0.750), new Point(0.755, 0.235)), - shimmerAverage: 0, - shimmerMax: 0.5, - millisecondsPerRotation: 1000 / (.26 * Math.PI * 2), - particleDistanceX: 1.5, - particleDistanceY: .5, - lightnessMin: 13, - lightnessMax: 94, - gradients: [ - [10, 176, 176, 209, 148, 140], - [171, 120, 154, 245, 196, 154], - [224, 99, 99, 71, 134, 148], - [101, 100, 117, 80, 230, 175], - [232, 165, 30, 69, 186, 172] - ], - - initialize: function(benchmark) - { - Stage.prototype.initialize.call(this, benchmark); - - this._template = document.getElementById("template"); - - const templateSize = Point.elementClientSize(this._template); - this._offset = this.size.subtract(templateSize).multiply(.5); - this._maxOffset = templateSize.height / 4; - - this._template.style.left = this._offset.width + "px"; - this._template.style.top = this._offset.height + "px"; - - this._stepProgress = 0; - }, - - tune: function(count) - { - if (count == 0) - return; - if (count < 0) { - this._offsetIndex = Math.max(this._offsetIndex + count, 0); - for (let i = this._offsetIndex; i < this.testElements.length; ++i) - this.testElements[i].style.visibility = "hidden"; +class TextTable { + static shimmerAverage = 0; + static shimmerMax = 0.5; + static shadowFalloff = new UnitBezier(new Point(0.015, 0.750), new Point(0.755, 0.235)); + table; - this._stepProgress = 1 / this._offsetIndex; - return; - } + constructor(table) { + this.table = table; + } - this._offsetIndex = this._offsetIndex + count; - this._stepProgress = 1 / this._offsetIndex; + show() { + this.table.style.visibility = "visible"; + } - const index = Math.min(this._offsetIndex, this.testElements.length); - for (let i = 0; i < index; ++i) - this.testElements[i].style.visibility = "visible"; + hide() { + this.table.style.visibility = "hidden"; + } - if (this._offsetIndex <= this.testElements.length) - return; + move(progress, maxPosition) { + let x = Math.lerp(progress, 0, maxPosition.x); + let y = Math.lerp(progress, 0, maxPosition.y); + this.table.style.transform = "translate(" + Math.floor(x) + "px," + Math.floor(y) + "px)"; + } - for (let i = this.testElements.length; i < this._offsetIndex; ++i) { - const clone = this._template.cloneNode(true); - this.testElements.push(clone); - this.element.insertBefore(clone, this.element.firstChild); - } - }, + setColor(progress, offset, gradient) { + let colorProgress = TextTable.shadowFalloff.solve(progress); + const shimmer = Math.sin(offset - colorProgress); + colorProgress = Math.max(Math.min(colorProgress + Math.lerp(shimmer, TextTable.shimmerAverage, TextTable.shimmerMax), 1), 0); - animate: function(timeDelta) - { - const angle = Stage.dateCounterValue(this.millisecondsPerRotation); + let r = Math.round(Math.lerp(colorProgress, gradient[0], gradient[3])); + let g = Math.round(Math.lerp(colorProgress, gradient[1], gradient[4])); + let b = Math.round(Math.lerp(colorProgress, gradient[2], gradient[5])); + this.table.style.color = "rgb(" + r + "," + g + "," + b + ")"; + } - const gradient = this.gradients[Math.floor(angle / (Math.PI * 2)) % this.gradients.length]; - const offset = Stage.dateCounterValue(200); - const maxX = Math.sin(angle) * this._maxOffset; - const maxY = Math.cos(angle) * this._maxOffset; + animate(progress, maxPosition, offset, gradient) { + this.move(progress, maxPosition); + this.setColor(progress, offset, gradient); + } +} - let progress = 0; - for (let i = 0; i < this._offsetIndex; ++i) { - const element = this.testElements[i]; - - let colorProgress = this.shadowFalloff.solve(progress); - const shimmer = Math.sin(offset - colorProgress); - colorProgress = Math.max(Math.min(colorProgress + Utilities.lerp(shimmer, this.shimmerAverage, this.shimmerMax), 1), 0); - const r = Math.round(Utilities.lerp(colorProgress, gradient[0], gradient[3])); - const g = Math.round(Utilities.lerp(colorProgress, gradient[1], gradient[4])); - const b = Math.round(Utilities.lerp(colorProgress, gradient[2], gradient[5])); - element.style.color = "rgb(" + r + "," + g + "," + b + ")"; - - const x = Utilities.lerp(i / this._offsetIndex, 0, maxX); - const y = Utilities.lerp(i / this._offsetIndex, 0, maxY); - element.style.transform = "translate(" + Math.floor(x) + "px," + Math.floor(y) + "px)"; - - progress += this._stepProgress; - } - }, +class TextTablesStage extends ReusableParticlesStage { + gradients = [ + [ 10, 176, 176, 209, 148, 140], + [171, 120, 154, 245, 196, 154], + [224, 99, 99, 71, 134, 148], + [101, 100, 117, 80, 230, 175], + [232, 165, 30, 69, 186, 172] + ]; + millisecondsPerRotation = 1000 / (.26 * Math.PI * 2); + template; + templateSize; + offset; + shadowFalloff; + + constructor() { + super(); + + this.template = document.getElementById("template"); + this.templateSize = Size.elementClientSize(this.template); + + this.offset = new Size(this.size); + this.offset.subtract(this.templateSize); + this.offset.divideBy(2); + + this.template.style.left = this.offset.width + "px"; + this.template.style.top = this.offset.height + "px"; + } - complexity: function() - { - return 1 + this._offsetIndex; + createParticle() { + let table = this.template.cloneNode(true); + this.element.insertBefore(table, this.element.firstChild); + return new TextTable(table); } -}); -var TextBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new TextStage(), options); + animate(timestamp, lastFrameLength) { + let activeParticles = this.activeParticles(); + if (activeParticles.length == 0) + return; + + let angle = Random.dateCounterValue(this.millisecondsPerRotation); + let gradient = this.gradients[Math.floor(angle / (Math.PI * 2)) % this.gradients.length]; + let offset = Random.dateCounterValue(200); + let magnitude = Math.min(this.templateSize.height / 4, activeParticles.length * 2); + let maxPosition = Point.fromVector(magnitude, angle); + + let step = 1 / activeParticles.length; + let progress = 0; + + for (let particle of activeParticles) { + particle.animate(progress, maxPosition, offset, gradient); + progress += step; + } } -); +} -window.benchmarkClass = TextBenchmark; +class TextTableAnimator extends Animator { + constructor(test, settings) { + super(new TextTablesStage(), test, settings); + } +} -}()); +window.animatorClass = TextTableAnimator; diff --git a/MotionMark/tests/core/resources/focus.js b/MotionMark/tests/core/resources/focus.js deleted file mode 100644 index ae51e5d..0000000 --- a/MotionMark/tests/core/resources/focus.js +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -var minimumDiameter = 30; -var sizeVariance = 20; -var travelDistance = 50; - -var minBlurValue = 1; -var maxBlurValue = 10; - -var opacityMultiplier = 30; -var focusDuration = 1000; -var movementDuration = 2500; - -var FocusElement = Utilities.createClass( - function(stage) - { - var size = minimumDiameter + sizeVariance; - - // Size and blurring are a function of depth. - this._depth = Pseudo.random(); - var distance = Utilities.lerp(this._depth, 0, sizeVariance); - size -= distance; - - var top = Stage.random(0, stage.size.height - size); - var left = Stage.random(0, stage.size.width - size); - - this.particle = document.createElement("div"); - this.particle.style.width = size + "px"; - this.particle.style.height = size + "px"; - this.particle.style.top = top + "px"; - this.particle.style.left = left + "px"; - this.particle.style.zIndex = Math.round((1 - this._depth) * 10); - - var depthMultiplier = Utilities.lerp(1 - this._depth, 0.8, 1); - this._sinMultiplier = Pseudo.random() * Stage.randomSign() * depthMultiplier * travelDistance; - this._cosMultiplier = Pseudo.random() * Stage.randomSign() * depthMultiplier * travelDistance; - - this.animate(stage, 0, 0); - }, { - - hide: function() - { - this.particle.style.display = "none"; - }, - - show: function() - { - this.particle.style.display = "block"; - }, - - animate: function(stage, sinFactor, cosFactor) - { - var top = sinFactor * this._sinMultiplier; - var left = cosFactor * this._cosMultiplier; - var distance = Math.abs(this._depth - stage.focalPoint); - var blur = Utilities.lerp(distance, minBlurValue, maxBlurValue); - var opacity = Math.max(5, opacityMultiplier * (1 - distance)); - - Utilities.setElementPrefixedProperty(this.particle, "filter", "blur(" + blur + "px) opacity(" + opacity + "%)"); - this.particle.style.transform = "translate3d(" + left + "%, " + top + "%, 0)"; - } -}); - -var FocusStage = Utilities.createSubclass(Stage, - function() - { - Stage.call(this); - }, { - - initialize: function(benchmark, options) - { - Stage.prototype.initialize.call(this, benchmark, options); - - this._testElements = []; - this._offsetIndex = 0; - this.focalPoint = 0.5; - }, - - complexity: function() - { - return this._offsetIndex; - }, - - tune: function(count) - { - if (count == 0) - return; - - if (count < 0) { - this._offsetIndex = Math.max(0, this._offsetIndex + count); - for (var i = this._offsetIndex; i < this._testElements.length; ++i) - this._testElements[i].hide(); - return; - } - - var newIndex = this._offsetIndex + count; - for (var i = this._testElements.length; i < newIndex; ++i) { - var obj = new FocusElement(this); - this._testElements.push(obj); - this.element.appendChild(obj.particle); - } - for (var i = this._offsetIndex; i < newIndex; ++i) - this._testElements[i].show(); - this._offsetIndex = newIndex; - }, - - animate: function() - { - var time = this._benchmark.timestamp; - var sinFactor = Math.sin(time / movementDuration); - var cosFactor = Math.cos(time / movementDuration); - - this.focalPoint = 0.5 + 0.5 * Math.sin(time / focusDuration); - - for (var i = 0; i < this._offsetIndex; ++i) - this._testElements[i].animate(this, sinFactor, cosFactor); - } -}); - -var FocusBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new FocusStage(), options); - } -); - -window.benchmarkClass = FocusBenchmark; - -}()); diff --git a/MotionMark/tests/core/resources/image-canvases.js b/MotionMark/tests/core/resources/image-canvases.js new file mode 100644 index 0000000..0f4fe73 --- /dev/null +++ b/MotionMark/tests/core/resources/image-canvases.js @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +class ImageCanvas { + static size = new Size(50, 50); + static pixelStride = 4; + static rowStride = ImageCanvas.size.width * ImageCanvas.pixelStride; + static weightNegativeThreshold = 0.04; + static weightPositiveThreshold = 0.96; + stage; + image; + canvas; + + constructor(stage) { + this.stage = stage; + this.image = Random.itemInArray(stage.images); + + this.canvas = document.createElement('canvas'); + this.canvas.width = ImageCanvas.size.width; + this.canvas.height = ImageCanvas.size.height; + this.canvas.style.width = ImageCanvas.size.width + 'px'; + this.canvas.style.height = ImageCanvas.size.height + 'px'; + this.stage.element.appendChild(this.canvas); + + this.reset(); + } + + show() { + this.canvas.style.display = "block"; + this.reset(); + } + + hide() { + this.canvas.style.display = "none"; + } + + reset() { + let tiles = this.stage.size.dividedBy(ImageCanvas.size); + let left = Random.integer(0, Math.floor(tiles.width) - 1) * ImageCanvas.size.width; + let top = Random.integer(0, Math.floor(tiles.height) - 1) * ImageCanvas.size.height; + + this.canvas.style.top = top + 'px'; + this.canvas.style.left = left + 'px'; + } + + randomDistance() + { + let factor = ImageCanvas.weightPositiveThreshold - ImageCanvas.weightNegativeThreshold; + let xOffset = Math.floor((Pseudo.random() - ImageCanvas.weightNegativeThreshold) / factor); + let yOffset = Math.floor((Pseudo.random() - ImageCanvas.weightNegativeThreshold) / factor); + return yOffset * ImageCanvas.rowStride + xOffset * ImageCanvas.pixelStride; + } + + animate(timestamp, lastFrameLength) { + let context = this.canvas.getContext("2d"); + + let imageData = context.getImageData(0, 0, ImageCanvas.size.width, ImageCanvas.size.height); + let dataLength = imageData.data.length; + let didDraw = false; + + for (let j = 0; j < dataLength; j += ImageCanvas.pixelStride) { + if (imageData.data[j + 3] === 0) + continue; + + // Get random neighboring pixel color. + let neighbor = (j + this.randomDistance()) % dataLength; + + // Update the RGB data + imageData.data[j] = imageData.data[neighbor]; + imageData.data[j + 1] = imageData.data[neighbor + 1]; + imageData.data[j + 2] = imageData.data[neighbor + 2]; + imageData.data[j + 3] = imageData.data[neighbor + 3]; + didDraw = true; + } + + if (didDraw) + context.putImageData(imageData, 0, 0); + else { + this.reset(); + context.drawImage(this.image, 0, 0, ImageCanvas.size.width, ImageCanvas.size.height); + } + } +} + +class ImageCanvasesStage extends ReusableParticlesStage { + imageSources; + images; + + constructor() { + super(); + + this.imageSources = [ + "compass", + "console", + "contribute", + "debugger", + "inspector", + "layout", + "performance", + "script", + "shortcuts", + "standards", + "storage", + "styles", + "timeline" + ]; + this.images = []; + } + + loadImages() { + return this.imageSources.map((imageSource) => { + return new Promise((resolve) => { + let image = new Image; + image.onload = (e) => { + resolve({ width: image.width, height: image.height }); + }; + image.src = "../core/images/" + imageSource + "100.png"; + this.images.push(image); + }); + }); + } + + createParticle() { + return new ImageCanvas(this); + } +} + +class ImageCanvasesAnimator extends Animator { + constructor(test, settings) { + super(new ImageCanvasesStage(), test, settings); + } + + async run() { + await Promise.all(this.stage.loadImages()); + return super.run(); + } +} + +window.animatorClass = ImageCanvasesAnimator; diff --git a/MotionMark/tests/core/resources/image-data.js b/MotionMark/tests/core/resources/image-data.js deleted file mode 100644 index 1940c3a..0000000 --- a/MotionMark/tests/core/resources/image-data.js +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -var ImageDataStage = Utilities.createSubclass(Stage, - function() { - Stage.call(this); - - this.testElements = []; - this._offsetIndex = 0; - }, { - - imageWidth: 50, - imageHeight: 50, - pixelStride: 4, - rowStride: 200, - weightNegativeThreshold: 0.04, - weightPositiveThreshold: 0.96, - imageSrcs: [ - "compass", - "console", - "contribute", - "debugger", - "inspector", - "layout", - "performance", - "script", - "shortcuts", - "standards", - "storage", - "styles", - "timeline" - ], - images: [], - - initialize: function(benchmark) - { - Stage.prototype.initialize.call(this, benchmark); - - var lastPromise; - var images = this.images; - this.imageSrcs.forEach(function(imageSrc) { - var promise = this._loadImage("resources/" + imageSrc + ".svg"); - if (!lastPromise) - lastPromise = promise; - else { - lastPromise = lastPromise.then(function(img) { - images.push(img); - return promise; - }); - } - }, this); - - lastPromise.then(function(img) { - images.push(img); - benchmark.readyPromise.resolve(); - }.bind(this)); - }, - - _loadImage: function(src) { - var img = new Image; - var promise = new SimplePromise; - - img.addEventListener('load', function onImageLoad(e) { - img.removeEventListener('load', onImageLoad); - promise.resolve(img); - }); - - img.src = src; - return promise; - }, - - tune: function(count) - { - if (count == 0) - return; - - if (count < 0) { - this._offsetIndex = Math.max(this._offsetIndex + count, 0); - for (var i = this._offsetIndex; i < this.testElements.length; ++i) - this.testElements[i].style.display = "none"; - return; - } - - this._offsetIndex = this._offsetIndex + count; - var index = Math.min(this._offsetIndex, this.testElements.length); - for (var i = 0; i < index; ++i) { - this.testElements[i].style.display = "block"; - this._refreshElement(this.testElements[i]); - } - if (this._offsetIndex <= this.testElements.length) - return; - - index = this._offsetIndex - this.testElements.length; - for (var i = 0; i < index; ++i) { - var element = this._createTestElement(); - this.testElements.push(element); - this.element.appendChild(element); - } - }, - - _createTestElement: function() { - var element = document.createElement('canvas'); - element.width = this.imageWidth; - element.height = this.imageHeight; - element.style.width = this.imageWidth + 'px'; - element.style.height = this.imageHeight + 'px'; - - this._refreshElement(element); - return element; - }, - - _refreshElement: function(element) { - var top = Stage.randomInt(0, Math.floor((this.size.height - this.imageHeight) / this.imageHeight)) * this.imageHeight; - var left = Stage.randomInt(0, Math.floor((this.size.width - this.imageWidth) / this.imageWidth)) * this.imageWidth; - - element.style.top = top + 'px'; - element.style.left = left + 'px'; - }, - - animate: function(timeDelta) { - for (var i = 0; i < this._offsetIndex; ++i) { - var element = this.testElements[i]; - var context = element.getContext("2d"); - - // Get image data - var imageData = context.getImageData(0, 0, this.imageWidth, this.imageHeight); - - var didDraw = false, - neighborPixelIndex, - dataLen = imageData.data.length; - for (var j = 0; j < dataLen; j += this.pixelStride) { - if (imageData.data[j + 3] === 0) - continue; - - // get random neighboring pixel color - neighborPixelIndex = this._getRandomNeighboringPixelIndex(j, dataLen); - - // Update the RGB data - imageData.data[j] = imageData.data[neighborPixelIndex]; - imageData.data[j + 1] = imageData.data[neighborPixelIndex + 1]; - imageData.data[j + 2] = imageData.data[neighborPixelIndex + 2]; - imageData.data[j + 3] = imageData.data[neighborPixelIndex + 3]; - didDraw = true; - } - - if (didDraw) - context.putImageData(imageData, 0, 0); - else { - this._refreshElement(element); - element.getContext("2d").drawImage(Stage.randomElementInArray(this.images), 0, 0, this.imageWidth, this.imageHeight); - } - } - }, - - _getRandomNeighboringPixelIndex: function(pixelIdx, pixelArrayLength) - { - var xOffset = Math.floor((Pseudo.random() - this.weightNegativeThreshold) / (this.weightPositiveThreshold - this.weightNegativeThreshold)); - var yOffset = Math.floor((Pseudo.random() - this.weightNegativeThreshold) / (this.weightPositiveThreshold - this.weightNegativeThreshold)); - return (pixelIdx + this.pixelStride * xOffset + this.rowStride * yOffset) % pixelArrayLength; - }, - - complexity: function() - { - return this._offsetIndex; - } -}); - -var ImageDataBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new ImageDataStage(), options); - }, { - - waitUntilReady: function() { - this.readyPromise = new SimplePromise; - return this.readyPromise; - } -}); - -window.benchmarkClass = ImageDataBenchmark; - -}()); diff --git a/MotionMark/tests/core/resources/inspector.svg b/MotionMark/tests/core/resources/inspector.svg deleted file mode 100644 index 68cc413..0000000 --- a/MotionMark/tests/core/resources/inspector.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/MotionMark/tests/core/resources/layout.svg b/MotionMark/tests/core/resources/layout.svg deleted file mode 100644 index 73db97e..0000000 --- a/MotionMark/tests/core/resources/layout.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/MotionMark/tests/core/resources/leaves.js b/MotionMark/tests/core/resources/leaves.js index e23e383..7f03d83 100644 --- a/MotionMark/tests/core/resources/leaves.js +++ b/MotionMark/tests/core/resources/leaves.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 Apple Inc. All rights reserved. + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,73 +22,77 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ -(function() { - -window.Leaf = Utilities.createSubclass(Particle, - function(stage) - { - this.element = document.createElement("img"); - this.element.setAttribute("src", Stage.randomElementInArray(stage.images).src); - stage.element.appendChild(this.element); - - Particle.call(this, stage); - }, { - - sizeMinimum: 20, - sizeRange: 30, - usesOpacity: true, - - reset: function() - { - Particle.prototype.reset.call(this); - this.element.style.width = this.size.x + "px"; - this.element.style.height = this.size.y + "px"; - - if (this.usesOpacity) { - this._opacity = .01; - this._opacityRate = 0.02 * Stage.random(1, 6); - } else - this._life = Stage.randomInt(20, 100); - - this._position = new Point(Stage.random(0, this.maxPosition.x), Stage.random(-this.size.height, this.maxPosition.y)); - this._velocity = new Point(Stage.random(-6, -2), .1 * this.size.y + Stage.random(-1, 1)); - }, - - animate: function(timeDelta) - { - this.rotater.next(timeDelta); - - this._position.x += this._velocity.x + 8 * this.stage.focusX; - this._position.y += this._velocity.y; - - if (this.usesOpacity) { - this._opacity += this._opacityRate; - if (this._opacity > 1) { - this._opacity = 1; - this._opacityRate *= -1; - } else if (this._opacity < 0 || this._position.y > this.stage.size.height) - this.reset(); - } else { - this._life--; - if (!this._life || this._position.y > this.stage.size.height) - this.reset(); - } - if (this._position.x < -this.size.width || this._position.x > this.stage.size.width) - this._position.x = this._position.x - Math.sign(this._position.x) * (this.size.width + this.stage.size.width); - this.move(); - }, +class Leaf extends ResettableParticle { + static minSide = 20; + static maxSide = 50; + image; + position; + velocity; + opacity; + opacityRate; + + constructor(stage) { + super(stage, Leaf.minSide, Leaf.maxSide); + + // Create the element and set its source. + this.image = document.createHTMLElement('img', { + src: Random.itemInArray(stage.images).src + }, stage.element); + + // Move it to some initial position. + this.reset(); + this.resize(); + this.move(0); + } - move: function() - { - this.element.style.transform = "translate(" + this._position.x + "px, " + this._position.y + "px)" + this.rotater.rotateZ(); - this.element.style.opacity = this._opacity; + remove() { + this.image.remove(); } -}); -Utilities.extendObject(ParticlesStage.prototype, { + reset() { + super.reset(); + + this.opacity = .01; + this.opacityRate = 0.02 * Random.number(1, 6); - imageSrcs: [ + this.position = new Point(Random.number(0, this.bouncingRect.maxX), Random.number(-this.size.height, this.bouncingRect.maxY)); + this.velocity = new Point(Random.number(-6, -2), .1 * this.size.height + Random.number(-1, 1)); + } + + move(timestamp) { + this.image.style.transform = "translate(" + this.position.x + "px, " + this.position.y + "px)" + this.rotator.rotateZ(timestamp); + this.image.style.opacity = this.opacity; + } + + resize() { + this.image.style.width = this.size.width + "px"; + this.image.style.height = this.size.height + "px"; + + } + + animate(timestamp, lastFrameLength) { + this.position.x += this.velocity.x + 8; // * this.stage.focusX; + this.position.y += this.velocity.y; + + this.opacity += this.opacityRate; + if (this.opacity > 1) { + this.opacity = 1; + this.opacityRate *= -1; + } else if (this.opacity < 0 || this.position.y > this.stage.size.height) { + this.reset(); + this.resize(); + } + + if (this.position.x < -this.size.width || this.position.x > this.stage.size.width) + this.position.x = this.position.x - Math.sign(this.position.x) * (this.size.width + this.stage.size.width); + + this.move(timestamp); + } +} + +class LeavesStage extends DisposableParticlesStage { + imageSources = [ "compass", "console", "contribute", @@ -102,78 +106,40 @@ Utilities.extendObject(ParticlesStage.prototype, { "storage", "styles", "timeline" - ], - images: [], - - initialize: function(benchmark) - { - Stage.prototype.initialize.call(this, benchmark); - - var lastPromise; - var images = this.images; - this.imageSrcs.forEach(function(imageSrc) { - var promise = this._loadImage("../core/resources/" + imageSrc + "100.png"); - if (!lastPromise) - lastPromise = promise; - else { - lastPromise = lastPromise.then(function(img) { - images.push(img); - return promise; - }); - } - }, this); - - lastPromise.then(function(img) { - images.push(img); - benchmark.readyPromise.resolve(); - }); - }, - - _loadImage: function(src) { - var img = new Image; - var promise = new SimplePromise; - - img.onload = function(e) { - promise.resolve(e.target); - }; - - img.src = src; - return promise; - }, - - animate: function(timeDelta) - { - this.focusX = 0.5 + 0.5 * Math.sin(Stage.dateFractionalValue(10000) * Math.PI * 2); - timeDelta /= 4; - this.particles.forEach(function(particle) { - particle.animate(timeDelta); + ]; + images = []; + + loadImages() { + return this.imageSources.map((imageSource) => { + return new Promise((resolve) => { + let image = new Image; + image.onload = (e) => { + resolve({ width: image.width, height: image.height }); + }; + image.src = "../core/images/" + imageSource + "100.png"; + this.images.push(image); + }); }); - }, + } - createParticle: function() - { + createParticle() { return new Leaf(this); - }, - - willRemoveParticle: function(particle) - { - particle.element.remove(); } -}); - -var LeavesBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new ParticlesStage(), options); - }, { - waitUntilReady: function() { - this.readyPromise = new SimplePromise; - return this.readyPromise; + removeParticle(leaf) { + leaf.remove(); } +} -}); +class LeavesAnimator extends Animator { + constructor(test, settings) { + super(new LeavesStage(), test, settings); + } -window.benchmarkClass = LeavesBenchmark; + async run() { + await Promise.all(this.stage.loadImages()); + return super.run(); + } +} -})(); +window.animatorClass = LeavesAnimator; diff --git a/MotionMark/tests/core/resources/multiply.js b/MotionMark/tests/core/resources/multiply.js index c21febc..555d5e6 100644 --- a/MotionMark/tests/core/resources/multiply.js +++ b/MotionMark/tests/core/resources/multiply.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,132 +22,124 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ -(function() { - -var MultiplyStage = Utilities.createSubclass(Stage, - function() - { - Stage.call(this); - this.tiles = []; - this._offsetIndex = 0; - }, { - - visibleCSS: [ - ["display", "none", "block"] - ], - totalRows: 68, - - initialize: function(benchmark, options) - { - Stage.prototype.initialize.call(this, benchmark, options); - var tileSize = Math.round(this.size.height / this.totalRows); - if (options.visibleCSS) - this.visibleCSS = options.visibleCSS; - - // Fill the scene with elements - var x = Math.round((this.size.width - tileSize) / 2); - var y = Math.round((this.size.height - tileSize) / 2); - var tileStride = tileSize; - var direction = 0; - var spiralCounter = 2; - var nextIndex = 1; - var maxSide = Math.floor(y / tileStride) * 2 + 1; - this._centerSpiralCount = maxSide * maxSide; - for (var i = 0; i < this._centerSpiralCount; ++i) { - this._addTile(x, y, tileSize, Stage.randomInt(0, 359)); - - if (i == nextIndex) { - direction = (direction + 1) % 4; - spiralCounter++; - nextIndex += spiralCounter >> 1; - } - if (direction == 0) - x += tileStride; - else if (direction == 1) - y -= tileStride; - else if (direction == 2) - x -= tileStride; - else - y += tileStride; - } - - this._sidePanelCount = maxSide * Math.floor((this.size.width - x) / tileStride) * 2; - for (var i = 0; i < this._sidePanelCount; ++i) { - var sideX = x + Math.floor(Math.floor(i / maxSide) / 2) * tileStride; - var sideY = y - tileStride * (i % maxSide); - - if (Math.floor(i / maxSide) % 2 == 1) - sideX = this.size.width - sideX - tileSize + 1; - this._addTile(sideX, sideY, tileSize, Stage.randomInt(0, 359)); - } - }, - - _addTile: function(x, y, tileSize, rotateDeg) - { - var tile = Utilities.createElement("div", { class: "div-" + Stage.randomInt(0,6) }, this.element); - var halfTileSize = tileSize / 2; - tile.style.left = x + 'px'; - tile.style.top = y + 'px'; - tile.style.width = tileSize + 'px'; - tile.style.height = tileSize + 'px'; - var visibleCSS = this.visibleCSS[this.tiles.length % this.visibleCSS.length]; - tile.style[visibleCSS[0]] = visibleCSS[1]; - - var distance = 1 / tileSize * this.size.multiply(0.5).subtract(new Point(x + halfTileSize, y + halfTileSize)).length(); - this.tiles.push({ - element: tile, - rotate: rotateDeg, - step: Math.max(3, distance / 1.5), - distance: distance, - active: false, - visibleCSS: visibleCSS, - }); - }, - - complexity: function() - { - return this._offsetIndex; - }, - - tune: function(count) - { - this._offsetIndex = Math.max(0, Math.min(this._offsetIndex + count, this.tiles.length)); - this._distanceFactor = 1.5 * (1 - 0.5 * Math.max(this._offsetIndex - this._centerSpiralCount, 0) / this._sidePanelCount) / Math.sqrt(this._offsetIndex); - }, - - animate: function() - { - var progress = this._benchmark.timestamp % 10000 / 10000; - var bounceProgress = Math.sin(2 * Math.abs( 0.5 - progress)); - var l = Utilities.lerp(bounceProgress, 20, 50); - var hslPrefix = "hsla(" + Utilities.lerp(progress, 0, 360) + ",100%,"; - - for (var i = 0; i < this._offsetIndex; ++i) { - var tile = this.tiles[i]; - tile.active = true; - tile.element.style[tile.visibleCSS[0]] = tile.visibleCSS[2]; - tile.rotate += tile.step; - tile.element.style.transform = "rotate(" + tile.rotate + "deg)"; - - var influence = Math.max(.01, 1 - (tile.distance * this._distanceFactor)); - tile.element.style.backgroundColor = hslPrefix + l * Math.tan(influence / 1.25) + "%," + influence + ")"; - } - - for (var i = this._offsetIndex; i < this.tiles.length && this.tiles[i].active; ++i) { - var tile = this.tiles[i]; - tile.active = false; - tile.element.style[tile.visibleCSS[0]] = tile.visibleCSS[1]; - } + +class Tile { + stage; + coordinate; + roundedRect; + distance; + step; + rotate; + + constructor(stage, coordinate) { + this.stage = stage; + this.coordinate = coordinate; + + this.roundedRect = document.createHTMLElement('div', { + class: "div-" + Random.integer(0, 5) + }, stage.element); + + this.distance = this.coordinate.length(); + this.step = Math.max(3, this.distance / 1.5); + this.rotate = Random.integer(0, 359); + + this.move(); + this.resize(); + this.hide(); + } + + move() { + let tileSize = this.stage.tileSize; + + let location = new Point(this.stage.rect.center()); + location.add(this.coordinate.scaled(tileSize)); + location.subtract(tileSize.scaled(0.5)); + + this.roundedRect.style.left = location.x + 'px'; + this.roundedRect.style.top = location.y + 'px'; + } + + resize() { + let tileSize = this.stage.tileSize; + + this.roundedRect.style.width = tileSize.width + 'px'; + this.roundedRect.style.height = tileSize.height + 'px'; + } + + show() { + this.roundedRect.style.display = "block"; + } + + hide() { + this.roundedRect.style.display = "none"; + } + + backgroundColor() { + let influence = Math.max(.01, 1 - (this.distance * this.stage.distanceFactor)); + let l = this.stage.l * Math.tan(influence); + return this.stage.hslPrefix + l + "%," + influence + ")"; } -}); -var MultiplyBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new MultiplyStage(), options); + animate(timestamp, lastFrameLength) { + this.rotate += this.step; + this.roundedRect.style.transform = "rotate(" + this.rotate + "deg)"; + this.roundedRect.style.backgroundColor = this.backgroundColor(); } -); +} -window.benchmarkClass = MultiplyBenchmark; +class TilesStage extends ReusableParticlesStage { + static rowsCount = 69; + tileSize; + tileGrid; + iterator; + distanceFactor; + + constructor() { + super(); + + let tileSide = Math.floor(this.size.height / TilesStage.rowsCount); + this.tileSize = new Size(tileSide, tileSide); + + let columnsCount = Math.floor(this.size.width / tileSide); + if (columnsCount % 2 == 0) + --columnsCount; + + this.tileGrid = new Size(columnsCount, TilesStage.rowsCount); + this.iterator = new SpiralIterator(this.tileGrid); + + while (!this.iterator.isDone()) + this.particles.push(this.createParticle()); + } + + createParticle() { + if (this.iterator.isDone()) + this.iterator = new SpiralIterator(this.tileGrid); + let tile = new Tile(this, this.iterator.current); + this.iterator.next(); + return tile; + } + + tune(count) { + super.tune(count); + let centerSpiralCount = this.tileGrid.height * this.tileGrid.height; + let sidePanelCount = this.tileGrid.area() - centerSpiralCount; + let activeSidePanelCount = Math.max(this.activeLength - centerSpiralCount, 0); + this.distanceFactor = 1.5 * (1 - 0.5 * activeSidePanelCount / sidePanelCount) / Math.sqrt(this.activeLength); + } + + animate(timestamp, lastFrameLength) { + let progress = timestamp % 10000 / 10000; + let bounceProgress = Math.sin(2 * Math.abs(0.5 - progress)); + this.l = Math.lerp(bounceProgress, 20, 50); + this.hslPrefix = "hsla(" + Math.lerp(progress, 0, 360) + ",100%,"; + super.animate(timestamp, lastFrameLength); + } +} + +class TilesAnimator extends Animator { + constructor(test, settings) { + super(new TilesStage(), test, settings); + } +} -}()); +window.animatorClass = TilesAnimator; diff --git a/MotionMark/tests/core/resources/particles.js b/MotionMark/tests/core/resources/particles.js deleted file mode 100644 index e918e1e..0000000 --- a/MotionMark/tests/core/resources/particles.js +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -function Particle(stage) -{ - this.stage = stage; - this.rotater = Stage.randomRotater(); - this.reset(); - this.move(); -} - -Particle.prototype = -{ - sizeMinimum: 40, - sizeRange: 10, - - reset: function() - { - var randSize = Math.round(Math.pow(Pseudo.random(), 4) * this.sizeRange + this.sizeMinimum); - this.size = new Point(randSize, randSize); - this.minPosition = this.size.center; - this.maxPosition = this.stage.size.subtract(this.minPosition); - }, - - animate: function(timeDelta) - { - this.rotater.next(timeDelta); - - this.position = this.position.add(this.velocity.multiply(timeDelta)); - this.velocity.y += 0.03; - - // If particle is going to move off right side - if (this.position.x > this.maxPosition.x) { - if (this.velocity.x > 0) - this.velocity.x *= -1; - this.position.x = this.maxPosition.x; - } else if (this.position.x < this.minPosition.x) { - // If particle is going to move off left side - if (this.velocity.x < 0) - this.velocity.x *= -1; - this.position.x = this.minPosition.x; - } - - // If particle is going to move off bottom side - if (this.position.y > this.maxPosition.y) { - // Adjust direction but maintain magnitude - var magnitude = this.velocity.length(); - this.velocity.x *= 1.5 + .005 * this.size.x; - this.velocity = this.velocity.normalize().multiply(magnitude); - if (Math.abs(this.velocity.y) < 0.7) - this.reset(); - else { - if (this.velocity.y > 0) - this.velocity.y *= -0.999; - this.position.y = this.maxPosition.y; - } - } else if (this.position.y < this.minPosition.y) { - // If particle is going to move off top side - var magnitude = this.velocity.length(); - this.velocity.x *= 1.5 + .005 * this.size.x; - this.velocity = this.velocity.normalize().multiply(magnitude); - if (this.velocity.y < 0) - this.velocity.y *= -0.998; - this.position.y = this.minPosition.y; - } - - this.move(); - }, - - move: function() - { - } -} - -ParticlesStage = Utilities.createSubclass(Stage, - function() - { - Stage.call(this); - this.particles = []; - }, { - - animate: function(timeDelta) - { - timeDelta /= 4; - this.particles.forEach(function(particle) { - particle.animate(timeDelta); - }); - }, - - tune: function(count) - { - if (count == 0) - return; - - if (count > 0) { - for (var i = 0; i < count; ++i) - this.particles.push(this.createParticle()); - return; - } - - count = Math.min(-count, this.particles.length); - - if (typeof(this.willRemoveParticle) == "function") { - for (var i = 0; i < count; ++i) - this.willRemoveParticle(this.particles[i]); - } - - this.particles.splice(0, count); - }, - - complexity: function() - { - return this.particles.length; - } -}); diff --git a/MotionMark/tests/core/resources/paths.js b/MotionMark/tests/core/resources/paths.js new file mode 100644 index 0000000..a7c2da5 --- /dev/null +++ b/MotionMark/tests/core/resources/paths.js @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +class CanvasSegment { + static strokeColors = [ + "#101010", + "#808080", + "#c0c0c0", + "#101010", + "#808080", + "#c0c0c0", + "#e01040" + ]; + strokeColor; + lineWidth; + isSplit; + + constructor() { + this.strokeColor = Random.itemInArray(CanvasSegment.strokeColors); + this.lineWidth = Math.pow(Pseudo.random(), 5) * 20 + 1; + this.isSplit = Pseudo.random() > 0.5; + } +} + +class CanvasLineToSegment extends CanvasSegment { + point; + + constructor(stage) { + super(); + this.point = stage.randomPoint(); + } + + draw(context) { + context.lineTo(this.point.x, this.point.y); + } +} + +class CanvasQuadraticSegment extends CanvasSegment { + controlPoint; + endPoint; + + constructor(stage) { + super(); + this.controlPoint = stage.randomPoint(); + this.endPoint = stage.randomPoint(); + } + + draw(context) { + context.quadraticCurveTo(this.controlPoint.x, this.controlPoint.y, this.endPoint.x, this.endPoint.y); + } +} + +class CanvasBezierSegment extends CanvasSegment { + controlPoint1; + controlPoint2; + endPoint; + + constructor(stage) { + super(); + this.controlPoint1 = stage.randomPoint(); + this.controlPoint2 = stage.randomPoint(); + this.endPoint = stage.randomPoint(); + } + + draw(context) { + context.bezierCurveTo(this.controlPoint1.x, this.controlPoint1.y, this.controlPoint2.x, this.controlPoint2.y, this.endPoint.x, this.endPoint.y); + } +} + +class PathsStage extends ReusableSegmentsStage { + segmentClasses = [ + CanvasLineToSegment, + CanvasQuadraticSegment, + CanvasBezierSegment + ]; + + gridSize = new Size(80, 40); + offsets = [ + new Point(-4, 0), + new Point(2, 0), + new Point(1, -2), + new Point(1, 2), + ]; + + coordinate; + + constructor() { + super(); + + let context = this.context; + context.lineJoin = "bevel"; + context.lineCap = "butt"; + + this.coordinate = new Point(this.gridSize.width / 2, this.gridSize.height / 2); + } + + randomPoint() { + let offset = Random.itemInArray(this.offsets); + + this.coordinate.add(offset); + if (this.coordinate.x < 0 || this.coordinate.x > this.gridSize.width) + this.coordinate.x -= offset.x * 2; + + if (this.coordinate.y < 0 || this.coordinate.y > this.gridSize.height) + this.coordinate.y -= offset.y * 2; + + let x = (this.coordinate.x + .5) * this.size.width / (this.gridSize.width + 1); + let y = (this.coordinate.y + .5) * this.size.height / (this.gridSize.height + 1); + + return new Point(x, y); + } + + createSegment() { + let segmentClass = Random.itemInArray(this.segmentClasses); + return new segmentClass(this); + } + + beginPath(segment) { + let context = this.context; + context.lineWidth = segment.lineWidth; + context.strokeStyle = segment.strokeColor; + context.beginPath(); + } + + animate() { + let context = this.context; + context.clearRect(0, 0, this.size.width, this.size.height); + + let center = this.rect.center(); + context.beginPath(); + context.moveTo(center.x, center.y); + + for (let segment of this.activeSegments()) { + if (segment.isSplit) { + context.stroke(); + this.beginPath(segment); + } + + segment.draw(context); + + if (Pseudo.random() > 0.995) + segment.isSplit = !segment.isSplit; + } + + context.stroke(); + } +} + +class PathsAnimator extends Animator { + constructor(test, settings) { + super(new PathsStage(), test, settings); + } +} + +window.animatorClass = PathsAnimator; diff --git a/MotionMark/tests/core/resources/performance.svg b/MotionMark/tests/core/resources/performance.svg deleted file mode 100644 index 37c4e95..0000000 --- a/MotionMark/tests/core/resources/performance.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/MotionMark/tests/core/resources/script.svg b/MotionMark/tests/core/resources/script.svg deleted file mode 100644 index 5e3f9c1..0000000 --- a/MotionMark/tests/core/resources/script.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/MotionMark/tests/core/resources/shortcuts.svg b/MotionMark/tests/core/resources/shortcuts.svg deleted file mode 100644 index edaa849..0000000 --- a/MotionMark/tests/core/resources/shortcuts.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/MotionMark/tests/core/resources/standards.svg b/MotionMark/tests/core/resources/standards.svg deleted file mode 100644 index ac1e693..0000000 --- a/MotionMark/tests/core/resources/standards.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/MotionMark/tests/core/resources/storage.svg b/MotionMark/tests/core/resources/storage.svg deleted file mode 100644 index c34a9ed..0000000 --- a/MotionMark/tests/core/resources/storage.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/MotionMark/tests/core/resources/styles.svg b/MotionMark/tests/core/resources/styles.svg deleted file mode 100644 index f50cff7..0000000 --- a/MotionMark/tests/core/resources/styles.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/MotionMark/tests/core/resources/suits.js b/MotionMark/tests/core/resources/suits.js index 526f879..494dded 100644 --- a/MotionMark/tests/core/resources/suits.js +++ b/MotionMark/tests/core/resources/suits.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 Apple Inc. All rights reserved. + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,126 +22,177 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ -(function() { - -window.SuitsParticle = Utilities.createSubclass(Particle, - function(stage) - { - this.isClipPath = stage.particleCounter % 2; - this.initialize(stage); - }, { - - sizeMinimum: 30, - sizeRange: 40, - hasGradient: true, - - initialize: function(stage) - { - var shapeId = "#shape-" + Stage.randomInt(1, stage.particleTypeCount); + +class Suit extends ResettableParticle { + static sideMinimum = 30; + static sideMaximum = 70; + static shapeCounter = 0; + static gradientCounter = 0; + isClipPath; + shape; + gradient; + transformSuffix; + position; + velocity; + + constructor(stage) { + super(stage, Suit.sideMinimum, Suit.sideMaximum); + + this.isClipPath = ++stage.shapeCounter % 2; + + this.createShape(); + this.createGradient(); + + // Move it to some initial position. + this.reset(); + this.move(0); + } + + createShape() { + var shapeId = "#shape-" + Random.integer(1, this.stage.shapesCount); + if (this.isClipPath) { - this.element = Utilities.createSVGElement("rect", { - x: 0, - y: 0, + this.shape = document.createSVGElement("rect", { "clip-path": "url(" + shapeId + ")" - }, {}, stage.element); + }, this.stage.element); } else { var shapePath = document.querySelector(shapeId + " path"); - this.element = shapePath.cloneNode(); - stage.element.appendChild(this.element); + this.shape = shapePath.cloneNode(); + this.stage.element.appendChild(this.shape); } + } - if (this.hasGradient) { - this.gradient = document.getElementById("default-gradient").cloneNode(true); - this.gradient.id = "gradient-" + stage.gradientsCounter++; - stage.gradientsDefs.appendChild(this.gradient); - this.element.setAttribute("fill", "url(#" + this.gradient.id + ")"); - } - Particle.call(this, stage); - }, + createGradient() { + this.gradient = this.stage.defaultGradient.cloneNode(true); + this.gradient.id = "gradient-" + Suit.gradientCounter++; + this.stage.gradientsDefs.appendChild(this.gradient); + this.shape.setAttribute("fill", "url(#" + this.gradient.id + ")"); + } - reset: function() - { - Particle.prototype.reset.call(this); + resetShape() { + if (this.isClipPath) { + this.shape.setAttribute("width", this.size.width); + this.shape.setAttribute("height", this.size.height); + this.transformSuffix = " translate(-" + (this.size.width / 2) + ",-" + (this.size.height / 2) + ")"; + } else + this.transformSuffix = " scale(" + this.size.width + ") translate(-.5,-.5)"; + } - this.position = Stage.randomElementInArray(this.stage.emitLocation); + resetGradient() { + let transform = this.stage.element.createSVGTransform(); + transform.setRotate(Random.integer(0, 359), 0, 0); + this.gradient.gradientTransform.baseVal.initialize(transform); - var velocityMagnitude = Stage.random(.5, 2.5); - var angle = Stage.randomInt(0, this.stage.emitSteps) / this.stage.emitSteps * Math.PI * 2 + Stage.dateCounterValue(1000) * this.stage.emissionSpin + velocityMagnitude; - this.velocity = new Point(Math.sin(angle), Math.cos(angle)) - .multiply(velocityMagnitude); + let stops = this.gradient.querySelectorAll("stop"); + stops[0].setAttribute("stop-color", "hsl(" + this.stage.colorOffset + ", 70%, 45%)"); + stops[1].setAttribute("stop-color", "hsl(" + ((this.stage.colorOffset + Random.integer(50,100)) % 360) + ", 70%, 65%)"); + } - if (this.isClipPath) { - this.element.setAttribute("width", this.size.x); - this.element.setAttribute("height", this.size.y); - this.transformSuffix = " translate(-" + this.size.center.x + ",-" + this.size.center.y + ")"; - } else - this.transformSuffix = " scale(" + this.size.x + ") translate(-.5,-.5)"; + reset() { + super.reset(); + + this.position = new Point(Random.itemInArray(this.stage.emitLocations)); + + var velocityMagnitude = Random.number(.5, 2.5); + var angle = Random.integer(0, this.stage.emitSteps) / this.stage.emitSteps * Math.PI * 2 + Random.dateCounterValue(1000) * this.stage.emissionSpin + velocityMagnitude; + this.velocity = new Point(Math.sin(angle) * velocityMagnitude, Math.cos(angle) * velocityMagnitude); this.stage.colorOffset = (this.stage.colorOffset + .5) % 360; - if (this.hasGradient) { - var transform = this.stage.element.createSVGTransform(); - transform.setRotate(Stage.randomInt(0, 359), 0, 0); - this.gradient.gradientTransform.baseVal.initialize(transform); + this.resetShape(); + this.resetGradient(); + } - var stops = this.gradient.querySelectorAll("stop"); - stops[0].setAttribute("stop-color", "hsl(" + this.stage.colorOffset + ", 70%, 45%)"); - stops[1].setAttribute("stop-color", "hsl(" + ((this.stage.colorOffset + Stage.randomInt(50,100)) % 360) + ", 70%, 65%)"); - } else - this.element.setAttribute("fill", "hsl(" + this.stage.colorOffset + ", 70%, 65%)"); - }, + move(timestamp) { + this.shape.setAttribute("transform", "translate(" + this.position.x + "," + this.position.y + ") " + this.rotator.rotate(timestamp, Point.zero()) + this.transformSuffix); + } + + animate(timestamp, lastFrameLength) { + let timeDelta = lastFrameLength / 4; + + this.position.add(this.velocity.scaled(timeDelta)); + this.velocity.y += 0.03; + + // If particle is going to move off right side + if (this.position.x > this.bouncingRect.maxX) { + if (this.velocity.x > 0) + this.velocity.x *= -1; + this.position.x = this.bouncingRect.maxX; + } else if (this.position.x < this.bouncingRect.x) { + // If particle is going to move off left side + if (this.velocity.x < 0) + this.velocity.x *= -1; + this.position.x = this.bouncingRect.x; + } + + // If particle is going to move off bottom side + if (this.position.y > this.bouncingRect.maxY) { + // Adjust direction but maintain magnitude + var magnitude = this.velocity.length(); + this.velocity.x *= 1.5 + .005 * this.size.width; + this.velocity = this.velocity.normalized().scaled(magnitude); + if (Math.abs(this.velocity.y) < 0.7) + this.reset(); + else { + if (this.velocity.y > 0) + this.velocity.y *= -0.999; + this.position.y = this.bouncingRect.maxY; + } + } else if (this.position.y < this.bouncingRect.y) { + // If particle is going to move off top side + var magnitude = this.velocity.length(); + this.velocity.x *= 1.5 + .005 * this.size.width; + this.velocity = this.velocity.normalized().scaled(magnitude); + if (this.velocity.y < 0) + this.velocity.y *= -0.998; + this.position.y = this.bouncingRect.y; + } - move: function() - { - this.element.setAttribute("transform", "translate(" + this.position.x + "," + this.position.y + ") " + this.rotater.rotate(Point.zero) + this.transformSuffix); + this.move(timestamp); } -}); - -var SuitsStage = Utilities.createSubclass(ParticlesStage, - function() - { - ParticlesStage.call(this); - }, { - - initialize: function(benchmark) - { - ParticlesStage.prototype.initialize.call(this, benchmark); - this.emissionSpin = Stage.random(0, 3); - this.emitSteps = Stage.randomInt(4, 6); - this.emitLocation = [ - new Point(this.size.x * .25, this.size.y * .333), - new Point(this.size.x * .5, this.size.y * .25), - new Point(this.size.x * .75, this.size.y * .333) - ]; - this.colorOffset = Stage.randomInt(0, 359); +} + +class SuitsStage extends DisposableParticlesStage { + gradientsDefs; + defaultGradient; + shapesCount; + emissionSpin; + emitSteps; + emitLocations; + colorOffset; + + constructor() { + super(); - this.particleTypeCount = document.querySelectorAll(".shape").length; this.gradientsDefs = document.getElementById("gradients"); - this.gradientsCounter = 0; - this.particleCounter = 0; - }, - - createParticle: function() - { - this.particleCounter++; - return new SuitsParticle(this); - }, - - willRemoveParticle: function(particle) - { - particle.element.remove(); - if (particle.gradient) - particle.gradient.remove(); + this.defaultGradient = document.getElementById("default-gradient"); + this.shapesCount = document.querySelectorAll(".shape").length; + + this.emissionSpin = Random.number(0, 3); + this.emitSteps = Random.integer(4, 6); + this.emitLocations = [ + new Point(this.size.width * .25, this.size.height * .333), + new Point(this.size.width * .50, this.size.height * .250), + new Point(this.size.width * .75, this.size.height * .333) + ]; + + this.colorOffset = Random.integer(0, 359); } -}); -var SuitsBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new SuitsStage(), options); + createParticle() { + return new Suit(this); } -); -window.benchmarkClass = SuitsBenchmark; + removeParticle(suit) { + suit.shape.remove(); + suit.gradient.remove(); + } +} + +class SuitsAnimator extends Animator { + constructor(test, settings) { + super(new SuitsStage(), test, settings); + } +} -})(); +window.animatorClass = SuitsAnimator; diff --git a/MotionMark/tests/core/resources/timeline.svg b/MotionMark/tests/core/resources/timeline.svg deleted file mode 100644 index cd1e8a4..0000000 --- a/MotionMark/tests/core/resources/timeline.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/MotionMark/tests/core/shared/disposable-particles.js b/MotionMark/tests/core/shared/disposable-particles.js new file mode 100644 index 0000000..986ac3e --- /dev/null +++ b/MotionMark/tests/core/shared/disposable-particles.js @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +class DisposableParticlesStage extends Stage { + particles; + + constructor() { + super(); + this.particles = []; + } + + complexity() { + return this.particles.length; + } + + tune(count) { + if (count == 0) + return; + + if (count > 0) { + for (var i = 0; i < count; ++i) + this.particles.push(this.createParticle()); + return; + } + + count = Math.min(-count, this.particles.length); + + for (var i = 0; i < count; ++i) + this.removeParticle(this.particles[i]); + + this.particles.splice(0, count); + } + + animate(timestamp, lastFrameLength) { + for (let particle of this.particles) + particle.animate(timestamp, lastFrameLength); + } +} diff --git a/MotionMark/tests/core/shared/resettable-particle.js b/MotionMark/tests/core/shared/resettable-particle.js new file mode 100644 index 0000000..614e33b --- /dev/null +++ b/MotionMark/tests/core/shared/resettable-particle.js @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +class ResettableParticle { + stage; + sizeRange; + size; + bouncingRect; + rotator; + + constructor(stage, sideMinimum, sideMaximum) { + this.stage = stage; + this.sizeRange = new Range(sideMinimum, sideMaximum - sideMinimum); + } + + reset() { + let side = Math.round(this.sizeRange.start + Math.pow(Pseudo.random(), 4) * this.sizeRange.length); + this.size = new Size(side, side); + + this.bouncingRect = new Rect(this.stage.rect); + this.bouncingRect.inflate(-side / 2); + + this.rotator = Random.rotator(1000, 10000); + } +} diff --git a/MotionMark/tests/core/shared/reusable-particles.js b/MotionMark/tests/core/shared/reusable-particles.js new file mode 100644 index 0000000..2de38c4 --- /dev/null +++ b/MotionMark/tests/core/shared/reusable-particles.js @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +class ReusableParticlesStage extends Stage { + particles; + activeLength; + + constructor() { + super(); + this.particles = []; + this.activeLength = 0; + } + + complexity() { + return this.activeLength; + } + + activeParticles() { + return this.particles.slice(0, this.activeLength); + } + + inactiveParticles(end) { + return this.particles.slice(this.activeLength, end); + } + + tune(count) { + if (count == 0) + return; + + if (count < 0) { + this.activeLength = Math.max(this.activeLength + count, 0); + for (var i = this.activeLength; i < this.particles.length; ++i) + this.particles[i].hide(); + return; + } + + let inactiveParticles = this.inactiveParticles(this.activeLength + count); + for (let particle of inactiveParticles) + particle.show(); + + for (let i = inactiveParticles.length; i < count; ++i) + this.particles.push(this.createParticle()); + + this.activeLength += count; + } + + animate(timestamp, lastFrameLength) { + for (let particle of this.activeParticles()) + particle.animate(timestamp, lastFrameLength); + } +} diff --git a/MotionMark/tests/simple/resources/simple-canvas.js b/MotionMark/tests/core/shared/reusable-segments.js similarity index 54% rename from MotionMark/tests/simple/resources/simple-canvas.js rename to MotionMark/tests/core/shared/reusable-segments.js index b3810e1..ad867b7 100644 --- a/MotionMark/tests/simple/resources/simple-canvas.js +++ b/MotionMark/tests/core/shared/reusable-segments.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. + * Copyright (C) 2015-2024 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -22,38 +22,44 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ -Utilities.extendObject(SimpleCanvasStage.prototype, { - tune: function(count) - { + +class ReusableSegmentsStage extends Stage { + segments; + inactiveLength; + context; + + constructor() { + super(); + this.segments = []; + this.inactiveLength = 0; + this.context = this.element.getContext("2d"); + } + + get activeLength() { + return this.segments.length - this.inactiveLength; + } + + complexity() { + return this.activeLength; + } + + activeSegments() { + return this.segments.slice(this.inactiveLength, this.segments.length); + } + + tune(count) { if (count == 0) return; if (count < 0) { - this.offsetIndex = Math.max(this.offsetIndex + count, 0); + this.inactiveLength = Math.min(this.inactiveLength - count, this.segments.length); return; } - this.offsetIndex = this.offsetIndex + count; - if (this.offsetIndex > this.objects.length) { - // For some tests, it may be easier to see how well the test is going - // by limiting the range of coordinates in which new objects can reside - var coordinateMaximumFactor = Math.min(this.objects.length, Math.min(this.size.x, this.size.y)) / Math.min(this.size.x, this.size.y); - var newIndex = this.offsetIndex - this.objects.length; - for (var i = 0; i < newIndex; ++i) - this.objects.push(new this._canvasObject(this, coordinateMaximumFactor)); - } - }, - - animate: function() - { - var context = this.context; - context.clearRect(0, 0, this.size.x, this.size.y); - for (var i = 0, length = this.offsetIndex; i < length; ++i) - this.objects[i].draw(context); - }, - - complexity: function() - { - return this.offsetIndex; + let inactiveLength = Math.min(this.inactiveLength, count); + for (let i = inactiveLength; i < count; ++i) + this.segments.push(this.createSegment()); + + this.inactiveLength -= inactiveLength; } -}); +} diff --git a/MotionMark/tests/core/suits.html b/MotionMark/tests/core/suits.html index 72d0872..85b9c28 100644 --- a/MotionMark/tests/core/suits.html +++ b/MotionMark/tests/core/suits.html @@ -1,5 +1,5 @@ - - - - - - - - -
- - - - - - - - - diff --git a/MotionMark/tests/dom/focus.html b/MotionMark/tests/dom/focus.html deleted file mode 100644 index cef614e..0000000 --- a/MotionMark/tests/dom/focus.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - -
-
focus
-
- - - - - - - - diff --git a/MotionMark/tests/dom/multiply.html b/MotionMark/tests/dom/multiply.html deleted file mode 100644 index b5bef91..0000000 --- a/MotionMark/tests/dom/multiply.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - -
-
- - - - - - - - - diff --git a/MotionMark/tests/dom/particles.html b/MotionMark/tests/dom/particles.html deleted file mode 100644 index 02b0786..0000000 --- a/MotionMark/tests/dom/particles.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - -
- - - - - - - - - diff --git a/MotionMark/tests/dom/resources/compositing-transforms.js b/MotionMark/tests/dom/resources/compositing-transforms.js deleted file mode 100644 index c92fadf..0000000 --- a/MotionMark/tests/dom/resources/compositing-transforms.js +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -BouncingCompositedImage = Utilities.createSubclass(BouncingParticle, - function(stage) - { - BouncingParticle.call(this, stage); - - this.element = document.createElement("img"); - this.element.style.width = this.size.x + "px"; - this.element.style.height = this.size.y + "px"; - this.element.setAttribute("src", stage.imageSrc); - - if (stage.useFilters) - this.element.style.filter = "hue-rotate(" + Stage.randomAngle() + "rad)"; - - stage.element.appendChild(this.element); - this._move(); - }, { - - _move: function() - { - this.element.style.transform = "translate3d(" + this.position.x + "px," + this.position.y + "px, 0) " + this.rotater.rotateZ(); - }, - - animate: function(timeDelta) - { - BouncingParticle.prototype.animate.call(this, timeDelta); - this._move(); - } -}); - -CompositingTransformsStage = Utilities.createSubclass(BouncingParticlesStage, - function() - { - BouncingParticlesStage.call(this); - }, { - - initialize: function(benchmark, options) - { - BouncingParticlesStage.prototype.initialize.call(this, benchmark, options); - - this.imageSrc = options["imageSrc"] || "../resources/yin-yang.svg"; - this.useFilters = options["filters"] == "yes"; - }, - - createParticle: function() - { - return new BouncingCompositedImage(this); - }, - - particleWillBeRemoved: function(particle) - { - particle.element.remove(); - } -}); - -CompositedTransformsBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new CompositingTransformsStage(), options); - } -); - -window.benchmarkClass = CompositedTransformsBenchmark; - -})(); diff --git a/MotionMark/tests/dom/resources/dom-particles.js b/MotionMark/tests/dom/resources/dom-particles.js deleted file mode 100644 index 985de3c..0000000 --- a/MotionMark/tests/dom/resources/dom-particles.js +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -DOMParticle = Utilities.createSubclass(Particle, - function(stage) - { - this.element = document.createElement("div"); - stage.element.appendChild(this.element); - - Particle.call(this, stage); - }, { - - reset: function() - { - Particle.prototype.reset.call(this); - - this.position = Stage.randomElementInArray(this.stage.emitLocation); - - var angle = Stage.randomInt(0, this.stage.emitSteps) / this.stage.emitSteps * Math.PI * 2 + Stage.dateCounterValue(100) * this.stage.emissionSpin; - this.velocity = new Point(Math.sin(angle), Math.cos(angle)) - .multiply(Stage.random(.5, 2.5)); - - this.element.style.width = this.size.x + "px"; - this.element.style.height = this.size.y + "px"; - this.stage.colorOffset = (this.stage.colorOffset + 1) % 360; - this.element.style.backgroundColor = "hsl(" + this.stage.colorOffset + ", 70%, 45%)"; - }, - - move: function() - { - this.element.style.transform = "translate(" + this.position.x + "px, " + this.position.y + "px)" + this.rotater.rotateZ(); - } -}); - -DOMParticleStage = Utilities.createSubclass(ParticlesStage, - function() - { - ParticlesStage.call(this); - }, { - - initialize: function(benchmark) - { - ParticlesStage.prototype.initialize.call(this, benchmark); - this.emissionSpin = Stage.random(0, 3); - this.emitSteps = Stage.randomInt(4, 6); - this.emitLocation = [ - new Point(this.size.x * .25, this.size.y * .333), - new Point(this.size.x * .5, this.size.y * .25), - new Point(this.size.x * .75, this.size.y * .333) - ]; - this.colorOffset = Stage.randomInt(0, 359); - }, - - createParticle: function() - { - return new DOMParticle(this); - }, - - willRemoveParticle: function(particle) - { - particle.element.remove(); - } -}); - -DOMParticleBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new DOMParticleStage(), options); - } -); - -window.benchmarkClass = DOMParticleBenchmark; - -})(); diff --git a/MotionMark/tests/dom/resources/focus.js b/MotionMark/tests/dom/resources/focus.js deleted file mode 100644 index c268d98..0000000 --- a/MotionMark/tests/dom/resources/focus.js +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -var maxVerticalOffset = 50; -var minimumDiameter = 30; -var centerDiameter = 90; -var sizeVariance = 60; -var travelDistance = 50; - -var opacityMultiplier = 30; - -var FocusElement = Utilities.createClass( - function(stage) - { - var size = minimumDiameter + sizeVariance; - - // Size and blurring are a function of depth. - this._depth = Pseudo.random(); - var distance = Utilities.lerp(this._depth, 0, sizeVariance); - size -= distance; - - var top = Stage.random(0, stage.size.height - size) - stage.maxBlurValue * 3; - var left = Stage.random(0, stage.size.width - size) - stage.maxBlurValue * 3; - - this.container = document.createElement('div'); - this.container.style.width = (size + stage.maxBlurValue * 6) + "px"; - this.container.style.height = (size + stage.maxBlurValue * 6) + "px"; - this.container.style.top = top + "px"; - this.container.style.left = left + "px"; - this.container.style.zIndex = Math.round((1 - this._depth) * 10); - - this.particle = Utilities.createElement("div", {}, this.container); - this.particle.style.width = size + "px"; - this.particle.style.height = size + "px"; - this.particle.style.top = (stage.maxBlurValue * 3) + "px"; - this.particle.style.left = (stage.maxBlurValue * 3) + "px"; - - var depthMultiplier = Utilities.lerp(1 - this._depth, 0.8, 1); - this._sinMultiplier = Pseudo.random() * Stage.randomSign() * depthMultiplier * travelDistance; - this._cosMultiplier = Pseudo.random() * Stage.randomSign() * depthMultiplier * travelDistance; - }, { - - hide: function() - { - this.container.style.display = "none"; - }, - - show: function() - { - this.container.style.display = "block"; - }, - - animate: function(stage, sinFactor, cosFactor) - { - var top = sinFactor * this._sinMultiplier; - var left = cosFactor * this._cosMultiplier; - - Utilities.setElementPrefixedProperty(this.container, "filter", "blur(" + stage.getBlurValue(this._depth) + "px) opacity(" + stage.getOpacityValue(this._depth) + "%)"); - this.container.style.transform = "translate3d(" + left + "%, " + top + "%, 0)"; - } -}); - -var FocusStage = Utilities.createSubclass(Stage, - function() - { - Stage.call(this); - }, { - - movementDuration: 2500, - focusDuration: 1000, - - centerObjectDepth: 0.0, - - minBlurValue: 1.5, - maxBlurValue: 15, - maxCenterObjectBlurValue: 5, - - initialize: function(benchmark, options) - { - Stage.prototype.initialize.call(this, benchmark, options); - - this._testElements = []; - this._focalPoint = 0.5; - this._offsetIndex = 0; - - this._centerElement = document.getElementById("center-text"); - this._centerElement.style.width = (centerDiameter + this.maxCenterObjectBlurValue * 6) + "px"; - this._centerElement.style.height = (centerDiameter + this.maxCenterObjectBlurValue * 6) + "px"; - this._centerElement.style.zIndex = Math.round(10 * this.centerObjectDepth); - - var particle = document.querySelector("#center-text div"); - particle.style.width = centerDiameter + "px"; - particle.style.height = centerDiameter + "px"; - particle.style.top = (this.maxCenterObjectBlurValue * 3) + "px"; - particle.style.left = (this.maxCenterObjectBlurValue * 3) + "px"; - - var blur = this.getBlurValue(this.centerObjectDepth, true); - Utilities.setElementPrefixedProperty(this._centerElement, "filter", "blur(" + blur + "px)"); - }, - - complexity: function() - { - return 1 + this._offsetIndex; - }, - - tune: function(count) - { - if (count == 0) - return; - - if (count < 0) { - this._offsetIndex = Math.max(0, this._offsetIndex + count); - for (var i = this._offsetIndex; i < this._testElements.length; ++i) - this._testElements[i].hide(); - return; - } - - var newIndex = this._offsetIndex + count; - for (var i = this._testElements.length; i < newIndex; ++i) { - var obj = new FocusElement(this); - this._testElements.push(obj); - this.element.appendChild(obj.container); - } - for (var i = this._offsetIndex; i < newIndex; ++i) - this._testElements[i].show(); - this._offsetIndex = newIndex; - }, - - animate: function() - { - var time = this._benchmark.timestamp; - var sinFactor = Math.sin(time / this.movementDuration); - var cosFactor = Math.cos(time / this.movementDuration); - - var focusProgress = 0.5 + 0.5 * Math.sin(time / this.focusDuration); - this._focalPoint = focusProgress; - - Utilities.setElementPrefixedProperty(this._centerElement, "filter", "blur(" + this.getBlurValue(this.centerObjectDepth, true) + "px)"); - - for (var i = 0; i < this._offsetIndex; ++i) - this._testElements[i].animate(this, sinFactor, cosFactor); - }, - - getBlurValue: function(depth, isCenter) - { - if (isCenter) - return 1 + Math.abs(depth - this._focalPoint) * (this.maxCenterObjectBlurValue - 1); - - return Utilities.lerp(Math.abs(depth - this._focalPoint), this.minBlurValue, this.maxBlurValue); - }, - - getOpacityValue: function(depth) - { - return Math.max(1, opacityMultiplier * (1 - Math.abs(depth - this._focalPoint))); - }, -}); - -var FocusBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new FocusStage(), options); - } -); - -window.benchmarkClass = FocusBenchmark; - -}()); diff --git a/MotionMark/tests/dom/resources/leaves.js b/MotionMark/tests/dom/resources/leaves.js deleted file mode 100644 index a0bb633..0000000 --- a/MotionMark/tests/dom/resources/leaves.js +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2015-2018 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -var SuperLeaf = window.Leaf; -var SimpleLeaf = Utilities.createSubclass(SuperLeaf, - function(stage) - { - SuperLeaf.call(this, stage); - }, { - - sizeMinimum: 25, - sizeRange: 0, - usesOpacity: false, - - move: function() - { - this.element.style.transform = "translate(" + this._position.x + "px, " + this._position.y + "px)" + this.rotater.rotateZ(); - } -}); - -var ScaleLeaf = Utilities.createSubclass(SuperLeaf, - function(stage) - { - SuperLeaf.call(this, stage); - }, { - - sizeMinimum: 20, - sizeRange: 30, - usesOpacity: false, - - move: function() - { - this.element.style.transform = "translate(" + this._position.x + "px, " + this._position.y + "px)" + this.rotater.rotateZ(); - } -}); - -var OpacityLeaf = Utilities.createSubclass(SuperLeaf, - function(stage) - { - SuperLeaf.call(this, stage); - }, { - - sizeMinimum: 25, - sizeRange: 0, - usesOpacity: true, - - move: function() - { - this.element.style.transform = "translate(" + this._position.x + "px, " + this._position.y + "px)" + this.rotater.rotateZ(); - this.element.style.opacity = this._opacity; - } -}); - - -var LeavesBenchmark = window.benchmarkClass; -var LeavesDerivedBenchmark = Utilities.createSubclass(LeavesBenchmark, - function(options) - { - switch (options["style"]) { - case "simple": - window.Leaf = SimpleLeaf; - break; - case "scale": - window.Leaf = ScaleLeaf; - break; - case "opacity": - window.Leaf = OpacityLeaf; - break; - } - LeavesBenchmark.call(this, options); - } -); - -window.benchmarkClass = LeavesDerivedBenchmark; - -})(); diff --git a/MotionMark/tests/resources/main.js b/MotionMark/tests/resources/main.js deleted file mode 100644 index ca7f2a9..0000000 --- a/MotionMark/tests/resources/main.js +++ /dev/null @@ -1,998 +0,0 @@ -/* - * Copyright (C) 2015-2021 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -Sampler = Utilities.createClass( - function(seriesCount, expectedSampleCount, processor) - { - this._processor = processor; - - this.samples = []; - for (var i = 0; i < seriesCount; ++i) { - var array = new Array(expectedSampleCount); - array.fill(0); - this.samples[i] = array; - } - this.sampleCount = 0; - }, { - - record: function() - { - // Assume that arguments.length == this.samples.length - for (var i = 0; i < arguments.length; i++) { - this.samples[i][this.sampleCount] = arguments[i]; - } - ++this.sampleCount; - }, - - processSamples: function() - { - var results = {}; - - // Remove unused capacity - this.samples = this.samples.map(function(array) { - return array.slice(0, this.sampleCount); - }, this); - - this._processor.processSamples(results); - - return results; - } -}); - -const sampleTypeIndex = 0; -const sampleTimeIndex = 1; -const sampleComplexityIndex = 2; -const sampleFrameLengthEstimateIndex = 3; - -Controller = Utilities.createClass( - function(benchmark, options) - { - // Initialize timestamps relative to the start of the benchmark - // In start() the timestamps are offset by the start timestamp - this._startTimestamp = 0; - this._endTimestamp = options["test-interval"]; - this._targetFrameRate = options["frame-rate"]; - // Default data series: timestamp, complexity, estimatedFrameLength - var sampleSize = options["sample-capacity"] || (this._targetFrameRate * options["test-interval"] / 1000); - this._sampler = new Sampler(options["series-count"] || 4, sampleSize, this); - this._marks = {}; - - this._frameLengthEstimator = new SimpleKalmanEstimator(options["kalman-process-error"], options["kalman-measurement-error"]); - this._isFrameLengthEstimatorEnabled = true; - - // Length of subsequent intervals; a value of 0 means use no intervals - this.intervalSamplingLength = 100; - - this.initialComplexity = 1; - }, { - - set isFrameLengthEstimatorEnabled(enabled) - { - this._isFrameLengthEstimatorEnabled = enabled; - }, - - start: function(startTimestamp, stage) - { - this._startTimestamp = startTimestamp; - this._endTimestamp += startTimestamp; - this._previousTimestamp = startTimestamp; - this._measureAndResetInterval(startTimestamp); - this.recordFirstSample(startTimestamp, stage); - }, - - recordFirstSample: function(startTimestamp, stage) - { - this._sampler.record(Strings.json.mutationFrameType, startTimestamp, stage.complexity(), -1); - this.mark(Strings.json.samplingStartTimeOffset, startTimestamp); - }, - - mark: function(comment, timestamp, data) - { - data = data || {}; - data.time = timestamp; - data.index = this._sampler.sampleCount; - this._marks[comment] = data; - }, - - containsMark: function(comment) - { - return comment in this._marks; - }, - - filterOutOutliers: function(array) - { - if (array.length == 0) - return []; - - array.sort((a, b) => a - b); - var q1 = array[Math.min(Math.round(array.length * 1 / 4), array.length - 1)]; - var q3 = array[Math.min(Math.round(array.length * 3 / 4), array.length - 1)]; - var interquartileRange = q3 - q1; - var minimum = q1 - interquartileRange * 1.5; - var maximum = q3 + interquartileRange * 1.5; - return array.filter(x => x >= minimum && x <= maximum); - }, - - _measureAndResetInterval: function(currentTimestamp) - { - var sampleCount = this._sampler.sampleCount; - var averageFrameLength = 0; - - if (this._intervalEndTimestamp) { - var durations = []; - for (var i = Math.max(this._intervalStartIndex, 1); i < sampleCount; ++i) { - durations.push(this._sampler.samples[sampleTimeIndex][i] - this._sampler.samples[sampleTimeIndex][i - 1]); - } - var filteredDurations = this.filterOutOutliers(durations); - if (filteredDurations.length > 0) - averageFrameLength = filteredDurations.reduce((a, b) => a + b, 0) / filteredDurations.length; - } - - this._intervalStartIndex = sampleCount; - this._intervalEndTimestamp = currentTimestamp + this.intervalSamplingLength; - - return averageFrameLength; - }, - - _getFrameType: function(samples, i) - { - return samples[sampleTypeIndex][i]; - }, - - _getComplexity: function(samples, i) - { - return samples[sampleComplexityIndex][i]; - }, - - _getFrameLength: function(samples, i) - { - return samples[sampleTimeIndex][i] - samples[sampleTimeIndex][i - 1]; - }, - - _previousFrameComplexity: function(samples, i) - { - if (i > 0) - return this._getComplexity(samples, i - 1); - - return 0; - }, - - update: function(timestamp, stage) - { - const frameType = this._previousFrameComplexity(this._sampler.samples, this._sampler.sampleCount) != stage.complexity() ? Strings.json.mutationFrameType : Strings.json.animationFrameType - var lastFrameLength = timestamp - this._previousTimestamp; - this._previousTimestamp = timestamp; - - var frameLengthEstimate = -1, intervalAverageFrameLength = -1; - var didFinishInterval = false; - if (!this.intervalSamplingLength) { - if (this._isFrameLengthEstimatorEnabled) { - this._frameLengthEstimator.sample(lastFrameLength); - frameLengthEstimate = this._frameLengthEstimator.estimate; - } - this._sampler.record(frameType, timestamp, stage.complexity(), frameLengthEstimate); - } else { - this.registerFrameTime(lastFrameLength); - if (this.intervalHasConcluded(timestamp)) { - var intervalStartTimestamp = this._sampler.samples[sampleTimeIndex][this._intervalStartIndex]; - intervalAverageFrameLength = this._measureAndResetInterval(timestamp); - if (this._isFrameLengthEstimatorEnabled) { - this._frameLengthEstimator.sample(intervalAverageFrameLength); - frameLengthEstimate = this._frameLengthEstimator.estimate; - } - this._sampler.record(frameType, timestamp, stage.complexity(), frameLengthEstimate); - - didFinishInterval = true; - this.didFinishInterval(timestamp, stage, intervalAverageFrameLength); - this._frameLengthEstimator.reset(); - } else - this._sampler.record(frameType, timestamp, stage.complexity(), frameLengthEstimate); - } - - this.tune(timestamp, stage, lastFrameLength, didFinishInterval, intervalAverageFrameLength); - }, - - registerFrameTime: function(lastFrameLength) - { - }, - - intervalHasConcluded: function(timestamp) - { - return timestamp >= this._intervalEndTimestamp; - }, - - didFinishInterval: function(timestamp, stage, intervalAverageFrameLength) - { - }, - - tune: function(timestamp, stage, lastFrameLength, didFinishInterval, intervalAverageFrameLength) - { - }, - - shouldStop: function(timestamp) - { - return timestamp > this._endTimestamp; - }, - - results: function() - { - return this._sampler.processSamples(); - }, - - _processComplexitySamples: function(complexitySamples) - { - complexitySamples.sort(function(a, b) { - return complexitySamples.getFieldInDatum(a, Strings.json.complexity) - complexitySamples.getFieldInDatum(b, Strings.json.complexity); - }); - }, - - _processMarks: function() - { - for (var markName in this._marks) - this._marks[markName].time -= this._startTimestamp; - return this._marks; - }, - - _processControllerSamples: function() - { - const processedSampleTypeIndex = 0; - const processedSampleTimeIndex = 1; - const processedSampleComplexityIndex = 2; - const processedSampleFrameLengthIndex = 3; - const processedSampleSmoothedFrameLengthIndex = 4; - - var controllerSamples = new SampleData; - controllerSamples.addField(Strings.json.frameType, processedSampleTypeIndex); - controllerSamples.addField(Strings.json.time, processedSampleTimeIndex); - controllerSamples.addField(Strings.json.complexity, processedSampleComplexityIndex); - - controllerSamples.addField(Strings.json.frameLength, processedSampleFrameLengthIndex); - controllerSamples.addField(Strings.json.smoothedFrameLength, processedSampleSmoothedFrameLengthIndex); - - var samples = this._sampler.samples; - samples[sampleTimeIndex].forEach(function(timestamp, i) { - var sample = controllerSamples.createDatum(); - controllerSamples.push(sample); - - // Represent time in milliseconds - controllerSamples.setFieldInDatum(sample, Strings.json.frameType, samples[sampleTypeIndex][i]); - controllerSamples.setFieldInDatum(sample, Strings.json.time, timestamp - this._startTimestamp); - controllerSamples.setFieldInDatum(sample, Strings.json.complexity, samples[sampleComplexityIndex][i]); - - if (i == 0) - controllerSamples.setFieldInDatum(sample, Strings.json.frameLength, 1000/this._targetFrameRate); - else - controllerSamples.setFieldInDatum(sample, Strings.json.frameLength, timestamp - samples[sampleTimeIndex][i - 1]); - - if (samples[sampleFrameLengthEstimateIndex][i] != -1) - controllerSamples.setFieldInDatum(sample, Strings.json.smoothedFrameLength, samples[sampleFrameLengthEstimateIndex][i]); - }, this); - - return controllerSamples; - }, - - processSamples: function(results) - { - results[Strings.json.marks] = this._processMarks(); - - var controllerSamples = this._processControllerSamples(); - var complexitySamples = new SampleData(controllerSamples.fieldMap); - - results[Strings.json.samples] = {}; - results[Strings.json.samples][Strings.json.controller] = controllerSamples; - results[Strings.json.samples][Strings.json.complexity] = complexitySamples; - controllerSamples.forEach(function (sample) { - complexitySamples.push(sample); - }); - this._processComplexitySamples(complexitySamples); - } -}); - -FixedController = Utilities.createSubclass(Controller, - function(benchmark, options) - { - Controller.call(this, benchmark, options); - this.initialComplexity = options["complexity"]; - this.intervalSamplingLength = 0; - } -); - -AdaptiveController = Utilities.createSubclass(Controller, - function(benchmark, options) - { - // Data series: timestamp, complexity, estimatedIntervalFrameLength - Controller.call(this, benchmark, options); - - // All tests start at 0, so we expect to see the target fps quickly. - this._samplingTimestamp = options["test-interval"] / 2; - this._startedSampling = false; - this._targetFrameRate = options["frame-rate"]; - this._pid = new PIDController(this._targetFrameRate); - - this._intervalFrameCount = 0; - this._numberOfFramesToMeasurePerInterval = 4; - }, { - - start: function(startTimestamp, stage) - { - Controller.prototype.start.call(this, startTimestamp, stage); - - this._samplingTimestamp += startTimestamp; - this._intervalTimestamp = startTimestamp; - }, - - recordFirstSample: function(startTimestamp, stage) - { - this._sampler.record(Strings.json.mutationFrameType, startTimestamp, stage.complexity(), -1); - }, - - update: function(timestamp, stage) - { - if (!this._startedSampling && timestamp >= this._samplingTimestamp) { - this._startedSampling = true; - this.mark(Strings.json.samplingStartTimeOffset, this._samplingTimestamp); - } - - // Start the work for the next frame. - ++this._intervalFrameCount; - - if (this._intervalFrameCount < this._numberOfFramesToMeasurePerInterval) { - this._sampler.record(Strings.json.animationFrameType, timestamp, stage.complexity(), -1); - return; - } - - // Adjust the test to reach the desired FPS. - var intervalLength = timestamp - this._intervalTimestamp; - this._frameLengthEstimator.sample(intervalLength / this._numberOfFramesToMeasurePerInterval); - var intervalEstimatedFrameRate = 1000 / this._frameLengthEstimator.estimate; - var tuneValue = -this._pid.tune(timestamp - this._startTimestamp, intervalLength, intervalEstimatedFrameRate); - tuneValue = tuneValue > 0 ? Math.floor(tuneValue) : Math.ceil(tuneValue); - stage.tune(tuneValue); - - this._sampler.record(Strings.json.mutationFrameType, timestamp, stage.complexity(), this._frameLengthEstimator.estimate); - - // Start the next interval. - this._intervalFrameCount = 0; - this._intervalTimestamp = timestamp; - } -}); - -RampController = Utilities.createSubclass(Controller, - function(benchmark, options) - { - this.targetFPS = options["frame-rate"]; - - // The tier warmup takes at most 5 seconds - options["sample-capacity"] = (options["test-interval"] / 1000 + 5) * this.targetFPS; - Controller.call(this, benchmark, options); - - // Initially start with a tier test to find the bounds - // The number of objects in a tier test is 10^|_tier| - this._tier = -.5; - // The timestamp is first set after the first interval completes - this._tierStartTimestamp = 0; - this._minimumComplexity = 1; - this._maximumComplexity = 1; - - this._testLength = options["test-interval"]; - - // After the tier range is determined, figure out the number of ramp iterations - var minimumRampLength = 3000; - var totalRampIterations = Math.max(1, Math.floor(this._endTimestamp / minimumRampLength)); - // Give a little extra room to run since the ramps won't be exactly this length - this._rampLength = Math.floor((this._endTimestamp - totalRampIterations * this.intervalSamplingLength) / totalRampIterations); - this._rampDidWarmup = false; - this._rampRegressions = []; - - this._finishedTierSampling = false; - this._changePointEstimator = new Experiment; - this._minimumComplexityEstimator = new Experiment; - // Estimates all frames within an interval - this._intervalFrameLengthEstimator = new Experiment; - - // Used for regression calculations in the ramps - this.frameLengthDesired = 1000/this.targetFPS; - // Add some tolerance; frame lengths shorter than this are considered to be @ the desired frame length - this.frameLengthDesiredThreshold = 1000/(this.targetFPS - 2); - // During tier sampling get at least this slow to find the right complexity range - this.frameLengthTierThreshold = 1000/(this.targetFPS * 0.5); - // Try to make each ramp get this slow so that we can cross the break point - this.frameLengthRampLowerThreshold = 1000/(this.targetFPS * 0.75); - // Do not let the regression calculation at the maximum complexity of a ramp get slower than this threshold - this.frameLengthRampUpperThreshold = 1000/(this.targetFPS / 3); - }, { - - // If the engine can handle the tier's complexity at the desired frame rate, test for a short - // period, then move on to the next tier - tierFastTestLength: 250, - // If the engine is under stress, let the test run a little longer to let the measurement settle - tierSlowTestLength: 750, - // Tier intervals must have this number of non-outlier frames in order to end. - numberOfFramesRequiredInInterval: 9, - - rampWarmupLength: 200, - - start: function(startTimestamp, stage) - { - Controller.prototype.start.call(this, startTimestamp, stage); - this._rampStartTimestamp = 0; - this.intervalSamplingLength = 100; - this._frameTimeHistory = []; - }, - - registerFrameTime: function(lastFrameLength) - { - this._frameTimeHistory.push(lastFrameLength); - }, - - intervalHasConcluded: function(timestamp) - { - if (!Controller.prototype.intervalHasConcluded.call(this, timestamp)) - return false; - - return this._finishedTierSampling || this.filterOutOutliers(this._frameTimeHistory).length > this.numberOfFramesRequiredInInterval; - }, - - didFinishInterval: function(timestamp, stage, intervalAverageFrameLength) - { - this._frameTimeHistory = []; - if (!this._finishedTierSampling) { - if (this._tierStartTimestamp > 0 && timestamp < this._tierStartTimestamp + this.tierFastTestLength) - return; - - var currentComplexity = stage.complexity(); - var currentFrameLength = this._frameLengthEstimator.estimate; - if (currentFrameLength < this.frameLengthTierThreshold) { - var isAnimatingAtTargetFPS = currentFrameLength < this.frameLengthDesiredThreshold; - var hasFinishedSlowTierTest = timestamp > this._tierStartTimestamp + this.tierSlowTestLength; - - if (!isAnimatingAtTargetFPS && !hasFinishedSlowTierTest) - return; - - // We're measuring at the target fps, so quickly move on to the next tier, or - // we're slower than the target fps, but we've let this tier run long enough to - // get an estimate - this._lastTierComplexity = currentComplexity; - this._lastTierFrameLength = currentFrameLength; - - if (currentComplexity <= 50) - this._tier += 1/2; - else if (currentComplexity <= 10000) - this._tier += 1/4; - else - this._tier += 1/8; - this._endTimestamp = timestamp + this._testLength; - var nextTierComplexity = Math.max(Math.round(Math.pow(10, this._tier)), currentComplexity + 1); - stage.tune(nextTierComplexity - currentComplexity); - - // Some tests may be unable to go beyond a certain capacity. If so, don't keep moving up tiers - if (stage.complexity() - currentComplexity > 0 || nextTierComplexity == 1) { - this._tierStartTimestamp = timestamp; - this.mark("Complexity: " + nextTierComplexity, timestamp); - return; - } - } else if (timestamp < this._tierStartTimestamp + this.tierSlowTestLength) - return; - - this._finishedTierSampling = true; - this.isFrameLengthEstimatorEnabled = false; - this.intervalSamplingLength = 120; - - // Extend the test length so that the full test length is made of the ramps - this._endTimestamp = timestamp + this._testLength; - this.mark(Strings.json.samplingStartTimeOffset, timestamp); - - this._minimumComplexity = 1; - this._possibleMinimumComplexity = this._minimumComplexity; - this._minimumComplexityEstimator.sample(this._minimumComplexity); - - // Sometimes this last tier will drop the frame length well below the threshold. - // Avoid going down that far since it means fewer measurements are taken in the target fps area. - // Interpolate a maximum complexity that gets us around the lowest threshold. - // Avoid doing this calculation if we never get out of the first tier (where this._lastTierComplexity is undefined). - if (this._lastTierComplexity && this._lastTierComplexity != currentComplexity) - this._maximumComplexity = Math.floor(Utilities.lerp(Utilities.progressValue(this.frameLengthTierThreshold, this._lastTierFrameLength, currentFrameLength), this._lastTierComplexity, currentComplexity)); - else { - // If the browser is capable of handling the most complex version of the test, use that - this._maximumComplexity = currentComplexity; - } - this._possibleMaximumComplexity = this._maximumComplexity; - - // If we get ourselves onto a ramp where the maximum complexity does not yield slow enough FPS, - // We'll use this as a boundary to find a higher maximum complexity for the next ramp - this._lastTierComplexity = currentComplexity; - this._lastTierFrameLength = currentFrameLength; - - // First ramp - stage.tune(this._maximumComplexity - currentComplexity); - this._rampDidWarmup = false; - // Start timestamp represents start of ramp iteration and warm up - this._rampStartTimestamp = timestamp; - return; - } - - if ((timestamp - this._rampStartTimestamp) < this.rampWarmupLength) - return; - - if (this._rampDidWarmup) - return; - - this._rampDidWarmup = true; - this._currentRampLength = this._rampStartTimestamp + this._rampLength - timestamp; - // Start timestamp represents start of ramp down, after warm up - this._rampStartTimestamp = timestamp; - this._rampStartIndex = this._sampler.sampleCount; - }, - - tune: function(timestamp, stage, lastFrameLength, didFinishInterval, intervalAverageFrameLength) - { - if (!this._rampDidWarmup) - return; - - this._intervalFrameLengthEstimator.sample(lastFrameLength); - if (!didFinishInterval) - return; - - var currentComplexity = stage.complexity(); - var intervalFrameLengthMean = this._intervalFrameLengthEstimator.mean(); - var intervalFrameLengthStandardDeviation = this._intervalFrameLengthEstimator.standardDeviation(); - - if (intervalFrameLengthMean < this.frameLengthDesiredThreshold && this._intervalFrameLengthEstimator.cdf(this.frameLengthDesiredThreshold) > .9) { - this._possibleMinimumComplexity = Math.max(this._possibleMinimumComplexity, currentComplexity); - } else if (intervalFrameLengthStandardDeviation > 2) { - // In the case where we might have found a previous interval where the target fps was reached. We hit a significant blip, - // so we should resample this area in the next ramp. - this._possibleMinimumComplexity = 1; - } - if (intervalFrameLengthMean - intervalFrameLengthStandardDeviation > this.frameLengthRampLowerThreshold) - this._possibleMaximumComplexity = Math.min(this._possibleMaximumComplexity, currentComplexity); - this._intervalFrameLengthEstimator.reset(); - - var progress = (timestamp - this._rampStartTimestamp) / this._currentRampLength; - - if (progress < 1) { - // Reframe progress percentage so that the last interval of the ramp can sample at minimum complexity - progress = (timestamp - this._rampStartTimestamp) / (this._currentRampLength - this.intervalSamplingLength); - stage.tune(Math.max(this._minimumComplexity, Math.floor(Utilities.lerp(progress, this._maximumComplexity, this._minimumComplexity))) - currentComplexity); - return; - } - - var regressionData = []; - for (var i = this._rampStartIndex; i < this._sampler.sampleCount; ++i) { - if (this._getFrameType(this._sampler.samples, i) == Strings.json.mutationFrameType) - continue; - regressionData.push([ this._getComplexity(this._sampler.samples, i), this._getFrameLength(this._sampler.samples, i) ]); - } - - var regression = new Regression(regressionData, this._sampler.sampleCount - 1, this._rampStartIndex, { desiredFrameLength: this.frameLengthDesired }); - this._rampRegressions.push(regression); - - var frameLengthAtMaxComplexity = regression.valueAt(this._maximumComplexity); - if (frameLengthAtMaxComplexity < this.frameLengthRampLowerThreshold) - this._possibleMaximumComplexity = Math.floor(Utilities.lerp(Utilities.progressValue(this.frameLengthRampLowerThreshold, frameLengthAtMaxComplexity, this._lastTierFrameLength), this._maximumComplexity, this._lastTierComplexity)); - // If the regression doesn't fit the first segment at all, keep the minimum bound at 1 - if ((timestamp - this._sampler.samples[sampleTimeIndex][this._sampler.sampleCount - regression.n1]) / this._currentRampLength < .25) - this._possibleMinimumComplexity = 1; - - this._minimumComplexityEstimator.sample(this._possibleMinimumComplexity); - this._minimumComplexity = Math.round(this._minimumComplexityEstimator.mean()); - - if (frameLengthAtMaxComplexity < this.frameLengthRampUpperThreshold) { - this._changePointEstimator.sample(regression.complexity); - // Ideally we'll target the change point in the middle of the ramp. If the range of the ramp is too small, there isn't enough - // range along the complexity (x) axis for a good regression calculation to be made, so force at least a range of 5 - // particles. Make it possible to increase the maximum complexity in case unexpected noise caps the regression too low. - this._maximumComplexity = Math.round(this._minimumComplexity + - Math.max(5, - this._possibleMaximumComplexity - this._minimumComplexity, - (this._changePointEstimator.mean() - this._minimumComplexity) * 2)); - } else { - // The slowest samples weighed the regression too heavily - this._maximumComplexity = Math.max(Math.round(.8 * this._maximumComplexity), this._minimumComplexity + 5); - } - - // Next ramp - stage.tune(this._maximumComplexity - stage.complexity()); - this._rampDidWarmup = false; - // Start timestamp represents start of ramp iteration and warm up - this._rampStartTimestamp = timestamp; - this._possibleMinimumComplexity = 1; - this._possibleMaximumComplexity = this._maximumComplexity; - }, - - processSamples: function(results) - { - results[Strings.json.marks] = this._processMarks(); - // Have samplingTimeOffset represent time 0 - var startTimestamp = this._marks[Strings.json.samplingStartTimeOffset].time; - for (var markName in results[Strings.json.marks]) { - results[Strings.json.marks][markName].time -= startTimestamp; - } - - results[Strings.json.samples] = {}; - - var controllerSamples = this._processControllerSamples(); - results[Strings.json.samples][Strings.json.controller] = controllerSamples; - controllerSamples.forEach(function(timeSample) { - controllerSamples.setFieldInDatum(timeSample, Strings.json.time, controllerSamples.getFieldInDatum(timeSample, Strings.json.time) - startTimestamp); - }); - - // Aggregate all of the ramps into one big complexity-frameLength dataset - var complexitySamples = new SampleData(controllerSamples.fieldMap); - results[Strings.json.samples][Strings.json.complexity] = complexitySamples; - - results[Strings.json.controller] = []; - this._rampRegressions.forEach(function(ramp) { - var startIndex = ramp.startIndex, endIndex = ramp.endIndex; - var startTime = controllerSamples.getFieldInDatum(startIndex, Strings.json.time); - var endTime = controllerSamples.getFieldInDatum(endIndex, Strings.json.time); - var startComplexity = controllerSamples.getFieldInDatum(startIndex, Strings.json.complexity); - var endComplexity = controllerSamples.getFieldInDatum(endIndex, Strings.json.complexity); - - var regression = {}; - results[Strings.json.controller].push(regression); - - var percentage = (ramp.complexity - startComplexity) / (endComplexity - startComplexity); - var inflectionTime = startTime + percentage * (endTime - startTime); - - regression[Strings.json.regressions.segment1] = [ - [startTime, ramp.s2 + ramp.t2 * startComplexity], - [inflectionTime, ramp.s2 + ramp.t2 * ramp.complexity] - ]; - regression[Strings.json.regressions.segment2] = [ - [inflectionTime, ramp.s1 + ramp.t1 * ramp.complexity], - [endTime, ramp.s1 + ramp.t1 * endComplexity] - ]; - regression[Strings.json.complexity] = ramp.complexity; - regression[Strings.json.regressions.startIndex] = startIndex; - regression[Strings.json.regressions.endIndex] = endIndex; - regression[Strings.json.regressions.profile] = ramp.profile; - - for (var j = startIndex; j <= endIndex; ++j) - complexitySamples.push(controllerSamples.at(j)); - }); - - this._processComplexitySamples(complexitySamples); - } -}); - -Stage = Utilities.createClass( - function() - { - }, { - - initialize: function(benchmark) - { - this._benchmark = benchmark; - this._element = document.getElementById("stage"); - this._element.setAttribute("width", document.body.offsetWidth); - this._element.setAttribute("height", document.body.offsetHeight); - this._size = Point.elementClientSize(this._element).subtract(Insets.elementPadding(this._element).size); - }, - - get element() - { - return this._element; - }, - - get size() - { - return this._size; - }, - - complexity: function() - { - return 0; - }, - - tune: function() - { - throw "Not implemented"; - }, - - animate: function() - { - throw "Not implemented"; - }, - - clear: function() - { - return this.tune(-this.tune(0)); - } -}); - -Utilities.extendObject(Stage, { - random: function(min, max) - { - return (Pseudo.random() * (max - min)) + min; - }, - - randomBool: function() - { - return !!Math.round(Pseudo.random()); - }, - - randomSign: function() - { - return Pseudo.random() >= .5 ? 1 : -1; - }, - - randomInt: function(min, max) - { - return Math.floor(this.random(min, max + 1)); - }, - - randomPosition: function(maxPosition) - { - return new Point(this.randomInt(0, maxPosition.x), this.randomInt(0, maxPosition.y)); - }, - - randomSquareSize: function(min, max) - { - var side = this.random(min, max); - return new Point(side, side); - }, - - randomVelocity: function(maxVelocity) - { - return this.random(maxVelocity / 8, maxVelocity); - }, - - randomAngle: function() - { - return this.random(0, Math.PI * 2); - }, - - randomColor: function() - { - var min = 32; - var max = 256 - 32; - return "#" - + this.randomInt(min, max).toString(16) - + this.randomInt(min, max).toString(16) - + this.randomInt(min, max).toString(16); - }, - - randomStyleMixBlendMode: function() - { - var mixBlendModeList = [ - 'normal', - 'multiply', - 'screen', - 'overlay', - 'darken', - 'lighten', - 'color-dodge', - 'color-burn', - 'hard-light', - 'soft-light', - 'difference', - 'exclusion', - 'hue', - 'saturation', - 'color', - 'luminosity' - ]; - - return mixBlendModeList[this.randomInt(0, mixBlendModeList.length)]; - }, - - randomStyleFilter: function() - { - var filterList = [ - 'grayscale(50%)', - 'sepia(50%)', - 'saturate(50%)', - 'hue-rotate(180)', - 'invert(50%)', - 'opacity(50%)', - 'brightness(50%)', - 'contrast(50%)', - 'blur(10px)', - 'drop-shadow(10px 10px 10px gray)' - ]; - - return filterList[this.randomInt(0, filterList.length)]; - }, - - randomElementInArray: function(array) - { - return array[Stage.randomInt(0, array.length - 1)]; - }, - - rotatingColor: function(cycleLengthMs, saturation, lightness) - { - return "hsl(" - + Stage.dateFractionalValue(cycleLengthMs) * 360 + ", " - + ((saturation || .8) * 100).toFixed(0) + "%, " - + ((lightness || .35) * 100).toFixed(0) + "%)"; - }, - - // Returns a fractional value that wraps around within [0,1] - dateFractionalValue: function(cycleLengthMs) - { - return (Date.now() / (cycleLengthMs || 2000)) % 1; - }, - - // Returns an increasing value slowed down by factor - dateCounterValue: function(factor) - { - return Date.now() / factor; - }, - - randomRotater: function() - { - return new Rotater(this.random(1000, 10000)); - } -}); - -Rotater = Utilities.createClass( - function(rotateInterval) - { - this._timeDelta = 0; - this._rotateInterval = rotateInterval; - this._isSampling = false; - }, { - - get interval() - { - return this._rotateInterval; - }, - - next: function(timeDelta) - { - this._timeDelta = (this._timeDelta + timeDelta) % this._rotateInterval; - }, - - degree: function() - { - return (360 * this._timeDelta) / this._rotateInterval; - }, - - rotateZ: function() - { - return "rotateZ(" + Math.floor(this.degree()) + "deg)"; - }, - - rotate: function(center) - { - return "rotate(" + Math.floor(this.degree()) + ", " + center.x + "," + center.y + ")"; - } -}); - -Benchmark = Utilities.createClass( - function(stage, options) - { - this._animateLoop = this._animateLoop.bind(this); - this._warmupLength = options["warmup-length"]; - this._frameCount = 0; - this._warmupFrameCount = options["warmup-frame-count"]; - this._firstFrameMinimumLength = options["first-frame-minimum-length"]; - - this._stage = stage; - this._stage.initialize(this, options); - - switch (options["time-measurement"]) - { - case "performance": - if (window.performance && window.performance.now) - this._getTimestamp = performance.now.bind(performance); - else - this._getTimestamp = null; - break; - case "raf": - this._getTimestamp = null; - break; - case "date": - this._getTimestamp = Date.now; - break; - } - - options["test-interval"] *= 1000; - switch (options["controller"]) - { - case "fixed": - this._controller = new FixedController(this, options); - break; - case "adaptive": - this._controller = new AdaptiveController(this, options); - break; - case "ramp": - this._controller = new RampController(this, options); - break; - } - }, { - - get stage() - { - return this._stage; - }, - - get timestamp() - { - return this._currentTimestamp - this._benchmarkStartTimestamp; - }, - - backgroundColor: function() - { - var stage = window.getComputedStyle(document.getElementById("stage")); - return stage["background-color"]; - }, - - run: function() - { - return this.waitUntilReady().then(function() { - this._finishPromise = new SimplePromise; - this._previousTimestamp = undefined; - this._didWarmUp = false; - this._stage.tune(this._controller.initialComplexity - this._stage.complexity()); - this._animateLoop(); - return this._finishPromise; - }.bind(this)); - }, - - // Subclasses should override this if they have setup to do prior to commencing. - waitUntilReady: function() - { - var promise = new SimplePromise; - promise.resolve(); - return promise; - }, - - _animateLoop: function(timestamp) - { - timestamp = (this._getTimestamp && this._getTimestamp()) || timestamp; - this._currentTimestamp = timestamp; - - if (this._controller.shouldStop(timestamp)) { - this._finishPromise.resolve(this._controller.results()); - return; - } - - if (!this._didWarmUp) { - if (!this._previousTimestamp) { - this._previousTimestamp = timestamp; - this._benchmarkStartTimestamp = timestamp; - } else if (timestamp - this._previousTimestamp >= this._warmupLength && this._frameCount >= this._warmupFrameCount) { - this._didWarmUp = true; - this._benchmarkStartTimestamp = timestamp; - this._controller.start(timestamp, this._stage); - this._previousTimestamp = timestamp; - - while (this._getTimestamp && this._getTimestamp() - timestamp < this._firstFrameMinimumLength) { - } - } - - this._stage.animate(0); - ++this._frameCount; - requestAnimationFrame(this._animateLoop); - return; - } - - this._controller.update(timestamp, this._stage); - this._stage.animate(timestamp - this._previousTimestamp); - this._previousTimestamp = timestamp; - requestAnimationFrame(this._animateLoop); - } -}); diff --git a/MotionMark/tests/resources/math.js b/MotionMark/tests/resources/math.js deleted file mode 100644 index e96a517..0000000 --- a/MotionMark/tests/resources/math.js +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -SimpleKalmanEstimator = Utilities.createSubclass(Experiment, - function(processError, measurementError) { - Experiment.call(this, false); - var error = .5 * (Math.sqrt(processError * processError + 4 * processError * measurementError) - processError); - this._gain = error / (error + measurementError); - }, { - - sample: function(newMeasurement) - { - if (!this._initialized) { - this._initialized = true; - this.estimate = newMeasurement; - return; - } - - this.estimate = this.estimate + this._gain * (newMeasurement - this.estimate); - }, - - reset: function() - { - Experiment.prototype.reset.call(this); - this._initialized = false; - this.estimate = 0; - } -}); - -PIDController = Utilities.createClass( - function(ysp) - { - this._ysp = ysp; - this._out = 0; - - this._Kp = 0; - this._stage = PIDController.stages.WARMING; - - this._eold = 0; - this._I = 0; - }, { - - // Determines whether the current y is - // before ysp => (below ysp if ysp > y0) || (above ysp if ysp < y0) - // after ysp => (above ysp if ysp > y0) || (below ysp if ysp < y0) - _yPosition: function(y) - { - return (y < this._ysp) == (this._y0 < this._ysp) - ? PIDController.yPositions.BEFORE_SETPOINT - : PIDController.yPositions.AFTER_SETPOINT; - }, - - // Calculate the ultimate distance from y0 after time t. We want to move very - // slowly at the beginning to see how adding few items to the test can affect - // its output. The complexity of a single item might be big enough to keep the - // proportional gain very small but achieves the desired progress. But if y does - // not change significantly after adding few items, that means we need a much - // bigger gain. So we need to move over a cubic curve which increases very - // slowly with small t values but moves very fast with larger t values. - // The basic formula is: y = t^3 - // Change the formula to reach y=1 after 1000 ms: y = (t/1000)^3 - // Change the formula to reach y=(ysp - y0) after 1000 ms: y = (ysp - y0) * (t/1000)^3 - _distanceUltimate: function(t) - { - return (this._ysp - this._y0) * Math.pow(t / 1000, 3); - }, - - // Calculates the distance of y relative to y0. It also ensures we do not return - // zero by returning a epsilon value in the same direction as ultimate distance. - _distance: function(y, du) - { - const epsilon = 0.0001; - var d = y - this._y0; - return du < 0 ? Math.min(d, -epsilon) : Math.max(d, epsilon); - }, - - // Decides how much the proportional gain should be increased during the manual - // gain stage. We choose to use the ratio of the ultimate distance to the current - // distance as an indication of how much the system is responsive. We want - // to keep the increment under control so it does not cause the system instability - // So we choose to take the natural logarithm of this ratio. - _gainIncrement: function(t, y, e) - { - var du = this._distanceUltimate(t); - var d = this._distance(y, du); - return Math.log(du / d) * 0.1; - }, - - // Update the stage of the controller based on its current stage and the system output - _updateStage: function(y) - { - var yPosition = this._yPosition(y); - - switch (this._stage) { - case PIDController.stages.WARMING: - if (yPosition == PIDController.yPositions.AFTER_SETPOINT) - this._stage = PIDController.stages.OVERSHOOT; - break; - - case PIDController.stages.OVERSHOOT: - if (yPosition == PIDController.yPositions.BEFORE_SETPOINT) - this._stage = PIDController.stages.UNDERSHOOT; - break; - - case PIDController.stages.UNDERSHOOT: - if (yPosition == PIDController.yPositions.AFTER_SETPOINT) - this._stage = PIDController.stages.SATURATE; - break; - } - }, - - // Manual tuning is used before calculating the PID controller gains. - _tuneP: function(e) - { - // The output is the proportional term only. - return this._Kp * e; - }, - - // PID tuning function. Kp, Ti and Td were already calculated - _tunePID: function(h, y, e) - { - // Proportional term. - var P = this._Kp * e; - - // Integral term is the area under the curve starting from the beginning - // till the current time. - this._I += (this._Kp / this._Ti) * ((e + this._eold) / 2) * h; - - // Derivative term is the slope of the curve at the current time. - var D = (this._Kp * this._Td) * (e - this._eold) / h; - - // The ouput is a PID function. - return P + this._I + D; - }, - - // Apply different strategies for the tuning based on the stage of the controller. - _tune: function(t, h, y, e) - { - switch (this._stage) { - case PIDController.stages.WARMING: - // This is the first stage of the Zieglerâ€Nichols method. It increments - // the proportional gain till the system output passes the set-point value. - if (typeof this._y0 == "undefined") { - // This is the first time a tuning value is required. We want the test - // to add only one item. So we need to return -1 which forces us to - // choose the initial value of Kp to be = -1 / e - this._y0 = y; - this._Kp = -1 / e; - } else { - // Keep incrementing the Kp as long as we have not reached the - // set-point yet - this._Kp += this._gainIncrement(t, y, e); - } - - return this._tuneP(e); - - case PIDController.stages.OVERSHOOT: - // This is the second stage of the Zieglerâ€Nichols method. It measures the - // oscillation period. - if (typeof this._t0 == "undefined") { - // t is the time of the begining of the first overshot - this._t0 = t; - this._Kp /= 2; - } - - return this._tuneP(e); - - case PIDController.stages.UNDERSHOOT: - // This is the end of the Zieglerâ€Nichols method. We need to calculate the - // integral and derivative periods. - if (typeof this._Ti == "undefined") { - // t is the time of the end of the first overshot - var Tu = t - this._t0; - - // Calculate the system parameters from Kp and Tu assuming - // a "some overshoot" control type. See: - // https://en.wikipedia.org/wiki/Ziegler%E2%80%93Nichols_method - this._Ti = Tu / 2; - this._Td = Tu / 3; - this._Kp = 0.33 * this._Kp; - - // Calculate the tracking time. - this._Tt = Math.sqrt(this._Ti * this._Td); - } - - return this._tunePID(h, y, e); - - case PIDController.stages.SATURATE: - return this._tunePID(h, y, e); - } - - return 0; - }, - - // Ensures the system does not fluctuates. - _saturate: function(v, e) - { - var u = v; - - switch (this._stage) { - case PIDController.stages.OVERSHOOT: - case PIDController.stages.UNDERSHOOT: - // Calculate the min-max values of the saturation actuator. - if (typeof this._min == "undefined") - this._min = this._max = this._out; - else { - this._min = Math.min(this._min, this._out); - this._max = Math.max(this._max, this._out); - } - break; - - case PIDController.stages.SATURATE: - const limitPercentage = 0.90; - var min = this._min > 0 ? Math.min(this._min, this._max * limitPercentage) : this._min; - var max = this._max < 0 ? Math.max(this._max, this._min * limitPercentage) : this._max; - var out = this._out + u; - - // Clip the controller output to the min-max values - out = Math.max(Math.min(max, out), min); - u = out - this._out; - - // Apply the back-calculation and tracking - if (u != v) - u += (this._Kp * this._Tt / this._Ti) * e; - break; - } - - this._out += u; - return u; - }, - - // Called from the benchmark to tune its test. It uses Ziegler-Nichols method - // to calculate the controller parameters. It then returns a PID tuning value. - tune: function(t, h, y) - { - this._updateStage(y); - - // Current error. - var e = this._ysp - y; - var v = this._tune(t, h, y, e); - - // Save e for the next call. - this._eold = e; - - // Apply back-calculation and tracking to avoid integrator windup - return this._saturate(v, e); - } -}); - -Utilities.extendObject(PIDController, { - // This enum will be used to tell whether the system output (or the controller input) - // is moving towards the set-point or away from it. - yPositions: { - BEFORE_SETPOINT: 0, - AFTER_SETPOINT: 1 - }, - - // The Ziegler-Nichols method for is used tuning the PID controller. The workflow of - // the tuning is split into four stages. The first two stages determine the values - // of the PID controller gains. During these two stages we return the proportional - // term only. The third stage is used to determine the min-max values of the - // saturation actuator. In the last stage back-calculation and tracking are applied - // to avoid integrator windup. During the last two stages, we return a PID control - // value. - stages: { - WARMING: 0, // Increase the value of the Kp until the system output reaches ysp. - OVERSHOOT: 1, // Measure the oscillation period and the overshoot value - UNDERSHOOT: 2, // Return PID value and measure the undershoot value - SATURATE: 3 // Return PID value and apply back-calculation and tracking. - } -}); diff --git a/MotionMark/tests/resources/star.svg b/MotionMark/tests/resources/star.svg deleted file mode 100644 index 3c46ae0..0000000 --- a/MotionMark/tests/resources/star.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/MotionMark/tests/resources/yin-yang.png b/MotionMark/tests/resources/yin-yang.png deleted file mode 100644 index 3162f6ec003cd017f88d5f87d7ee6df02a6e59bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4082 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 P{j)~i(1Vw0VnY58iT`JJ diff --git a/MotionMark/tests/resources/yin-yang.svg b/MotionMark/tests/resources/yin-yang.svg deleted file mode 100644 index 4412626..0000000 --- a/MotionMark/tests/resources/yin-yang.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/simple/resources/simple-canvas-paths.js b/MotionMark/tests/simple/resources/simple-canvas-paths.js deleted file mode 100644 index 143630d..0000000 --- a/MotionMark/tests/simple/resources/simple-canvas-paths.js +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -// === PAINT OBJECTS === - -CanvasLineSegment = Utilities.createClass( - function(stage) { - var radius = Stage.randomInt(10, 100); - var center = Stage.randomPosition(stage.size); - var delta = Point.pointOnCircle(Stage.randomAngle(), radius/2); - - this._point1 = center.add(delta); - this._point2 = center.subtract(delta); - this._color = Stage.randomColor(); - this._lineWidth = Stage.randomInt(1, 100); - }, { - - draw: function(context) { - context.strokeStyle = this._color; - context.lineWidth = this._lineWidth; - context.beginPath(); - context.moveTo(this._point1.x, this._point1.y); - context.lineTo(this._point2.x, this._point2.y); - context.stroke(); - } -}); - -CanvasLinePoint = Utilities.createClass( - function(stage, coordinateMaximumFactor) { - var pointMaximum = new Point(Math.min(stage.size.x, coordinateMaximumFactor * stage.size.x), Math.min(stage.size.y, coordinateMaximumFactor * stage.size.y)); - this._point = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2)); - }, { - - draw: function(context) { - context.lineTo(this._point.x, this._point.y); - } -}) - -CanvasQuadraticSegment = Utilities.createClass( - function(stage) { - var maxSize = Stage.randomInt(20, 200); - var toCenter = Stage.randomPosition(stage.size).subtract(new Point(maxSize/2, maxSize/2)); - - this._point1 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._point2 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._point3 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._color = Stage.randomColor(); - this._lineWidth = Stage.randomInt(1, 50); - }, { - - draw: function(context) { - context.strokeStyle = this._color; - context.lineWidth = this._lineWidth; - context.beginPath(); - context.moveTo(this._point1.x, this._point1.y); - context.quadraticCurveTo(this._point2.x, this._point2.y, this._point3.x, this._point3.y); - context.stroke(); - } -}); - -CanvasQuadraticPoint = Utilities.createClass( - function(stage, coordinateMaximumFactor) { - var pointMaximum = Stage.randomPosition(new Point(Math.min(stage.size.x, coordinateMaximumFactor * stage.size.x), Math.min(stage.size.y, coordinateMaximumFactor * stage.size.y))); - this._point1 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2)); - this._point2 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2)); - }, { - - draw: function(context) { - context.quadraticCurveTo(this._point1.x, this._point1.y, this._point2.x, this._point2.y); - } -}); - -CanvasBezierSegment = Utilities.createClass( - function(stage) { - var maxSize = Stage.randomInt(20, 200); - var toCenter = Stage.randomPosition(stage.size).subtract(new Point(maxSize/2, maxSize/2)); - - this._point1 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._point2 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._point3 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._point4 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._color = Stage.randomColor(); - this._lineWidth = Stage.randomInt(1, 50); - }, { - - draw: function(context) { - context.strokeStyle = this._color; - context.lineWidth = this._lineWidth; - context.beginPath(); - context.moveTo(this._point1.x, this._point1.y); - context.bezierCurveTo(this._point2.x, this._point2.y, this._point3.x, this._point3.y, this._point4.x, this._point4.y); - context.stroke(); - } -}); - -CanvasBezierPoint = Utilities.createClass( - function(stage, coordinateMaximumFactor) { - var pointMaximum = Stage.randomPosition(new Point(Math.min(stage.size.x, coordinateMaximumFactor * stage.size.x), Math.min(stage.size.y, coordinateMaximumFactor * stage.size.y))); - this._point1 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2)); - this._point2 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2)); - this._point3 = Stage.randomPosition(pointMaximum).add(new Point((stage.size.x - pointMaximum.x) / 2, (stage.size.y - pointMaximum.y) / 2)); - }, { - - draw: function(context) { - context.bezierCurveTo(this._point1.x, this._point1.y, this._point2.x, this._point2.y, this._point3.x, this._point3.y); - } -}); - -CanvasArcToSegment = Utilities.createClass( - function(stage) { - var maxSize = Stage.randomInt(20, 200); - var toCenter = Stage.randomPosition(stage.size).subtract(new Point(maxSize/2, maxSize/2)); - - this._point1 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._point2 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._point3 = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._radius = Stage.randomInt(20, 200); - this._color = Stage.randomColor(); - this._lineWidth = Stage.randomInt(1, 50); - }, { - - draw: function(context) { - context.strokeStyle = this._color; - context.lineWidth = this._lineWidth; - context.beginPath(); - context.moveTo(this._point1.x, this._point1.y); - context.arcTo(this._point2.x, this._point2.y, this._point3.x, this._point3.y, this._radius); - context.stroke(); - } -}); - -CanvasArcToSegmentFill = Utilities.createClass( - function(stage) { - CanvasArcToSegment.call(this, stage); - }, { - - draw: function(context) { - context.fillStyle = this._color; - context.beginPath(); - context.moveTo(this._point1.x, this._point1.y); - context.arcTo(this._point2.x, this._point2.y, this._point3.x, this._point3.y, this._radius); - context.fill(); - } -}); - -CanvasArcSegment = Utilities.createClass( - function(stage) { - var maxSize = Stage.randomInt(20, 200); - var toCenter = Stage.randomPosition(stage.size).subtract(new Point(maxSize/2, maxSize/2)); - - this._point = Stage.randomPosition(new Point(maxSize, maxSize)).add(toCenter); - this._radius = Stage.randomInt(20, 200); - this._startAngle = Stage.randomAngle(); - this._endAngle = Stage.randomAngle(); - this._counterclockwise = Stage.randomBool(); - this._color = Stage.randomColor(); - this._lineWidth = Stage.randomInt(1, 50); - }, { - - draw: function(context) { - context.strokeStyle = this._color; - context.lineWidth = this._lineWidth; - context.beginPath(); - context.arc(this._point.x, this._point.y, this._radius, this._startAngle, this._endAngle, this._counterclockwise); - context.stroke(); - } -}); - -CanvasArcSegmentFill = Utilities.createClass( - function(stage) { - CanvasArcSegment.call(this, stage); - }, { - - draw: function(context) { - context.fillStyle = this._color; - context.beginPath(); - context.arc(this._point.x, this._point.y, this._radius, this._startAngle, this._endAngle, this._counterclockwise); - context.fill(); - } -}); - -CanvasRect = Utilities.createClass( - function(stage) { - this._width = Stage.randomInt(20, 200); - this._height = Stage.randomInt(20, 200); - this._point = Stage.randomPosition(stage.size).subtract(new Point(this._width/2, this._height/2)); - this._color = Stage.randomColor(); - this._lineWidth = Stage.randomInt(1, 20); - }, { - - draw: function(context) { - context.strokeStyle = this._color; - context.lineWidth = this._lineWidth; - context.beginPath(); - context.rect(this._point.x, this._point.y, this._width, this._height); - context.stroke(); - } -}); - -CanvasRectFill = Utilities.createClass( - function(stage) { - CanvasRect.call(this, stage); - }, { - - draw: function(context) { - context.fillStyle = this._color; - context.beginPath(); - context.rect(this._point.x, this._point.y, this._width, this._height); - context.fill(); - } -}); - -CanvasEllipse = Utilities.createClass( - function(stage) { - this._radius = new Point(Stage.randomInt(20, 200), Stage.randomInt(20, 200)); - var toCenter = Stage.randomPosition(stage.size).subtract(this._radius.multiply(.5)); - - this._center = Stage.randomPosition(this._radius).add(toCenter); - this._rotation = Stage.randomAngle(); - this._startAngle = Stage.randomAngle(); - this._endAngle = Stage.randomAngle(); - this._anticlockwise = Stage.randomBool(); - this._color = Stage.randomColor(); - this._lineWidth = Stage.randomInt(1, 20); - }, { - - draw: function(context) { - context.strokeStyle = this._color; - context.lineWidth = this._lineWidth; - context.beginPath(); - context.ellipse(this._center.x, this._center.y, this._radius.width, this._radius.height, this._rotation, this._startAngle, this._endAngle, this._anticlockwise); - context.stroke(); - } -}); - -CanvasEllipseFill = Utilities.createClass( - function(stage) { - CanvasEllipse.call(this, stage); - }, { - - draw: function(context) { - context.fillStyle = this._color; - context.beginPath(); - context.ellipse(this._center.x, this._center.y, this._radius.width, this._radius.height, this._rotation, this._startAngle, this._endAngle, this._anticlockwise); - context.fill(); - } -}); - -CanvasStroke = Utilities.createClass( - function (stage) { - this._object = new (Stage.randomElementInArray(this.objectTypes))(stage); - }, { - - objectTypes: [ - CanvasQuadraticSegment, - CanvasBezierSegment, - CanvasArcToSegment, - CanvasArcSegment, - CanvasRect, - CanvasEllipse - ], - - draw: function(context) { - this._object.draw(context); - } -}); - -CanvasFill = Utilities.createClass( - function (stage) { - this._object = new (Stage.randomElementInArray(this.objectTypes))(stage); - }, { - - objectTypes: [ - CanvasArcToSegmentFill, - CanvasArcSegmentFill, - CanvasRectFill, - CanvasEllipseFill - ], - - draw: function(context) { - this._object.draw(context); - } -}); - -// === STAGES === - -SimpleCanvasPathStrokeStage = Utilities.createSubclass(SimpleCanvasStage, - function(canvasObject) { - SimpleCanvasStage.call(this, canvasObject); - }, { - - animate: function() - { - var context = this.context; - context.clearRect(0, 0, this.size.x, this.size.y); - context.lineWidth = Stage.randomInt(1, 20); - context.strokeStyle = Stage.rotatingColor(); - context.beginPath(); - context.moveTo(this.size.x / 2, this.size.y / 2); - for (var i = 0, length = this.offsetIndex; i < length; ++i) - this.objects[i].draw(context); - context.stroke(); - } -}); - -SimpleCanvasPathFillStage = Utilities.createSubclass(SimpleCanvasStage, - function(canvasObject) { - SimpleCanvasStage.call(this, canvasObject); - }, { - - animate: function() - { - var context = this.context; - context.clearRect(0, 0, this.size.x, this.size.y); - context.fillStyle = Stage.rotatingColor(); - context.beginPath(); - context.moveTo(this.size.x / 2, this.size.y / 2); - for (var i = 0, length = this.offsetIndex; i < length; ++i) - this.objects[i].draw(context); - context.fill(); - } -}); - -CanvasLineSegmentStage = Utilities.createSubclass(SimpleCanvasStage, - function() - { - SimpleCanvasStage.call(this, CanvasLineSegment); - }, { - - initialize: function(benchmark, options) - { - SimpleCanvasStage.prototype.initialize.call(this, benchmark, options); - this.context.lineCap = options["lineCap"] || "butt"; - } -}); - -CanvasLinePathStage = Utilities.createSubclass(SimpleCanvasPathStrokeStage, - function() - { - SimpleCanvasPathStrokeStage.call(this, CanvasLinePoint); - }, { - - initialize: function(benchmark, options) - { - SimpleCanvasPathStrokeStage.prototype.initialize.call(this, benchmark, options); - this.context.lineJoin = options["lineJoin"] || "bevel"; - } -}); - -CanvasLineDashStage = Utilities.createSubclass(SimpleCanvasStage, - function() - { - SimpleCanvasStage.call(this, CanvasLinePoint); - this._step = 0; - }, { - - initialize: function(benchmark, options) - { - SimpleCanvasStage.prototype.initialize.call(this, benchmark, options); - this.context.setLineDash([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); - this.context.lineWidth = 1; - this.context.strokeStyle = "#000"; - }, - - animate: function() - { - var context = this.context; - context.clearRect(0, 0, this.size.x, this.size.y); - context.lineDashOffset = this._step++; - context.beginPath(); - context.moveTo(this.size.x / 2, this.size.y / 2); - for (var i = 0, length = this.offsetIndex; i < length; ++i) - this.objects[i].draw(context); - context.stroke(); - } -}); - -// === BENCHMARK === - -CanvasPathBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - var stage; - switch (options["pathType"]) { - case "line": - stage = new CanvasLineSegmentStage(); - break; - case "linePath": { - if ("lineJoin" in options) - stage = new CanvasLinePathStage(); - if ("lineDash" in options) - stage = new CanvasLineDashStage(); - break; - } - case "quadratic": - stage = new SimpleCanvasStage(CanvasQuadraticSegment); - break; - case "quadraticPath": - stage = new SimpleCanvasPathStrokeStage(CanvasQuadraticPoint); - break; - case "bezier": - stage = new SimpleCanvasStage(CanvasBezierSegment); - break; - case "bezierPath": - stage = new SimpleCanvasPathStrokeStage(CanvasBezierPoint); - break; - case "arcTo": - stage = new SimpleCanvasStage(CanvasArcToSegment); - break; - case "arc": - stage = new SimpleCanvasStage(CanvasArcSegment); - break; - case "rect": - stage = new SimpleCanvasStage(CanvasRect); - break; - case "ellipse": - stage = new SimpleCanvasStage(CanvasEllipse); - break; - case "lineFill": - stage = new SimpleCanvasPathFillStage(CanvasLinePoint); - break; - case "quadraticFill": - stage = new SimpleCanvasPathFillStage(CanvasQuadraticPoint); - break; - case "bezierFill": - stage = new SimpleCanvasPathFillStage(CanvasBezierPoint); - break; - case "arcToFill": - stage = new SimpleCanvasStage(CanvasArcToSegmentFill); - break; - case "arcFill": - stage = new SimpleCanvasStage(CanvasArcSegmentFill); - break; - case "rectFill": - stage = new SimpleCanvasStage(CanvasRectFill); - break; - case "ellipseFill": - stage = new SimpleCanvasStage(CanvasEllipseFill); - break; - case "strokes": - stage = new SimpleCanvasStage(CanvasStroke); - break; - case "fills": - stage = new SimpleCanvasStage(CanvasFill); - break; - } - - Benchmark.call(this, stage, options); - } -); - -window.benchmarkClass = CanvasPathBenchmark; - -})(); \ No newline at end of file diff --git a/MotionMark/tests/simple/resources/tiled-canvas-image.js b/MotionMark/tests/simple/resources/tiled-canvas-image.js deleted file mode 100644 index 3f0700c..0000000 --- a/MotionMark/tests/simple/resources/tiled-canvas-image.js +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -CanvasImageTile = Utilities.createClass( - function(stage, source) - { - this._context = stage.context; - this._size = stage.tileSize; - this.source = source; - }, { - - getImageData: function() - { - this._imagedata = this._context.getImageData(this.source.x, this.source.y, this._size.width, this._size.height); - }, - - putImageData: function(destination) - { - this._context.putImageData(this._imagedata, destination.x, destination.y); - } -}); - -TiledCanvasImageStage = Utilities.createSubclass(Stage, - function(element, options) - { - Stage.call(this); - }, { - - initialize: function(benchmark, options) - { - Stage.prototype.initialize.call(this, benchmark, options); - this.context = this.element.getContext("2d"); - this._setupTiles(); - }, - - _setupTiles: function() - { - const maxTilesPerRow = 50; - const maxTilesPerCol = 50; - - this.tileSize = this.size.multiply(new Point(1 / maxTilesPerRow, 1 / maxTilesPerCol)); - - this._tiles = new Array(maxTilesPerRow * maxTilesPerCol); - - var source = Point.zero; - for (var index = 0; index < this._tiles.length; ++index) { - this._tiles[index] = new CanvasImageTile(this, source); - source = this._nextTilePosition(source); - } - - this._ctiles = 0; - }, - - _nextTilePosition: function(destination) - { - var next = destination.add(this.tileSize); - - if (next.x >= this._size.width) - return new Point(0, next.y >= this._size.height ? 0 : next.y); - - return new Point(next.x, destination.y); - }, - - tune: function(count) - { - this._ctiles += count; - - this._ctiles = Math.max(this._ctiles, 0); - this._ctiles = Math.min(this._ctiles, this._tiles.length); - }, - - _drawBackground: function() - { - var size = this._benchmark._stage.size; - var gradient = this.context.createLinearGradient(0, 0, size.width, 0); - gradient.addColorStop(0, "red"); - gradient.addColorStop(1, "white"); - this.context.save(); - this.context.fillStyle = gradient; - this.context.fillRect(0, 0, size.width, size.height); - this.context.restore(); - }, - - animate: function(timeDelta) - { - this._drawBackground(); - - if (!this._ctiles) - return; - - this._tiles.shuffle(); - - var destinations = new Array(this._ctiles); - for (var index = 0; index < this._ctiles; ++index) { - this._tiles[index].getImageData(); - destinations[index] = this._tiles[index].source; - } - - destinations.shuffle(); - - for (var index = 0; index < this._ctiles; ++index) - this._tiles[index].putImageData(destinations[index]); - }, - - complexity: function() - { - return this._ctiles; - } -}); - -TiledCanvasImageBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new TiledCanvasImageStage(), options); - } -); - -window.benchmarkClass = TiledCanvasImageBenchmark; - -})(); diff --git a/MotionMark/tests/simple/simple-canvas-paths.html b/MotionMark/tests/simple/simple-canvas-paths.html deleted file mode 100644 index a914548..0000000 --- a/MotionMark/tests/simple/simple-canvas-paths.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/simple/tiled-canvas-image.html b/MotionMark/tests/simple/tiled-canvas-image.html deleted file mode 100644 index 237aeac..0000000 --- a/MotionMark/tests/simple/tiled-canvas-image.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/svg/suits.html b/MotionMark/tests/svg/suits.html deleted file mode 100644 index a39d1d8..0000000 --- a/MotionMark/tests/svg/suits.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/svg/suits.js b/MotionMark/tests/svg/suits.js deleted file mode 100644 index 9916755..0000000 --- a/MotionMark/tests/svg/suits.js +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2018 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -(function() { - -var SuperSuitsParticle = window.SuitsParticle; -ClipSuit = Utilities.createSubclass(SuperSuitsParticle, - function(stage) - { - this.initialize(stage); - }, { - - isClipPath: true, - hasGradient: false, - move: function() - { - this.element.setAttribute("transform", "translate(" + (this.position.x - this.size.center.x) + "," + (this.position.y - this.size.center.x) + ")"); - } -}); - -ShapeSuit = Utilities.createSubclass(SuperSuitsParticle, - function(stage) - { - this.initialize(stage); - }, { - - isClipPath: false, - hasGradient: false, - move: function() - { - this.element.setAttribute("transform", "translate(" + this.position.x + "," + this.position.y + ") " + this.transformSuffix); - } -}); - -RotationSuit = Utilities.createSubclass(SuperSuitsParticle, - function(stage) - { - this.isClipPath = stage.particleCounter % 2; - this.initialize(stage); - }, { - - hasGradient: false, -}); - -GradientSuit = Utilities.createSubclass(SuperSuitsParticle, - function(stage) - { - this.isClipPath = stage.particleCounter % 2; - this.initialize(stage); - }, { - - hasGradient: true, - move: function() - { - this.element.setAttribute("transform", "translate(" + this.position.x + "," + this.position.y + ") " + this.transformSuffix); - } -}); - -StaticSuit = Utilities.createSubclass(SuperSuitsParticle, - function(stage) - { - this.isClipPath = stage.particleCounter % 2; - this.initialize(stage); - }, { - - hasGradient: true, - reset: function() - { - SuperSuitsParticle.prototype.reset.call(this); - this.originalPosition = Stage.randomPosition(this.stage.size); - this.transformSuffix = " rotate(" + Math.floor(Stage.randomAngle() * 180 / Math.PI) + ",0,0)" + this.transformSuffix; - }, - - move: function() - { - this.element.setAttribute("transform", "translate(" + this.originalPosition.x + "," + this.originalPosition.y + ") " + this.transformSuffix); - } -}); - -var SuitsBenchmark = window.benchmarkClass; -var SuitsDerivedBenchmark = Utilities.createSubclass(SuitsBenchmark, - function(options) - { - switch (options["style"]) { - case "clip": - window.SuitsParticle = ClipSuit; - break; - case "shape": - window.SuitsParticle = ShapeSuit; - break; - case "rotation": - window.SuitsParticle = RotationSuit; - break; - case "gradient": - window.SuitsParticle = GradientSuit; - break; - case "static": - window.SuitsParticle = StaticSuit; - break; - } - SuitsBenchmark.call(this, options); - } -); - -window.benchmarkClass = SuitsDerivedBenchmark; - -})(); diff --git a/MotionMark/tests/template/resources/template-canvas.js b/MotionMark/tests/template/resources/template-canvas.js deleted file mode 100644 index 9a0c727..0000000 --- a/MotionMark/tests/template/resources/template-canvas.js +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -function TemplateCanvasObject(stage) -{ - // For the canvas stage, most likely you will need to create your - // animated object since it's only draw time thing. - - // Fill in your object data. -} - -TemplateCanvasObject.prototype = { - _draw: function() - { - // Draw your object. - }, - - animate: function(timeDelta) - { - // Redraw the animated object. The last time this animated - // item was drawn before 'timeDelta'. - - // Move your object. - - // Redraw your object. - this._draw(); - } -}; - -TemplateCanvasStage = Utilities.createSubclass(Stage, - function() - { - Stage.call(this); - }, { - - initialize: function(benchmark, options) - { - Stage.prototype.initialize.call(this, benchmark, options); - this.context = this.element.getContext("2d"); - - // Define a collection for your objects. - }, - - tune: function(count) - { - // If count is -ve, -count elements need to be removed form the - // stage. If count is +ve, +count elements need to be added to - // the stage. - - // Change objects in the stage. - }, - - animate: function(timeDelta) - { - // Animate the elements such that all of them are redrawn. Most - // likely you will need to call TemplateCanvasObject.animate() - // for all your animated objects here. - - // Most likely you will need to clear the canvas with every redraw. - this.context.clearRect(0, 0, this.size.x, this.size.y); - - // Loop through all your objects and ask them to animate. - } -}); - -TemplateCanvasBenchmark = Utilities.createSubclass(Benchmark, - function(options) - { - Benchmark.call(this, new TemplateCanvasStage(), options); - }, { - - // Override this function if the benchmark needs to wait for resources to be - // loaded. - // - // Default implementation returns a resolved promise, so that the benchmark - // benchmark starts right away. Here's an example where we're waiting 5 - // seconds before starting the benchmark. - waitUntilReady: function() - { - var promise = new SimplePromise; - window.setTimeout(function() { - promise.resolve(); - }, 5000); - return promise; - } -}); - -window.benchmarkClass = TemplateCanvasBenchmark; - -})(); \ No newline at end of file diff --git a/MotionMark/tests/template/template-canvas.html b/MotionMark/tests/template/template-canvas.html deleted file mode 100644 index bdcab6f..0000000 --- a/MotionMark/tests/template/template-canvas.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/template/template-css.html b/MotionMark/tests/template/template-css.html deleted file mode 100644 index ed6b6ca..0000000 --- a/MotionMark/tests/template/template-css.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - -
- - - - - - - - diff --git a/MotionMark/tests/template/template-svg.html b/MotionMark/tests/template/template-svg.html deleted file mode 100644 index eb7a034..0000000 --- a/MotionMark/tests/template/template-svg.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/text/design-6.html b/MotionMark/tests/text/design-6.html deleted file mode 100644 index decbdd2..0000000 --- a/MotionMark/tests/text/design-6.html +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- - - - - - - - - diff --git a/MotionMark/tests/text/design-6.js b/MotionMark/tests/text/design-6.js deleted file mode 100644 index 9401657..0000000 --- a/MotionMark/tests/text/design-6.js +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -// The MotionMark-based TextBenchmark should already be set to |window.benchmarkClass| -var TextBenchmark = window.benchmarkClass; -var TextTemplateBenchmark = Utilities.createSubclass(TextBenchmark, - function(options) - { - var dataset; - switch (options["corpus"]) { - case "latin": - dataset = [ - "σχέδιο", - "umění", - "design", - "искусство", - "conception", - "diseño" - ]; - break; - case "cjk": - dataset = [ - "设计", - "디자인", - "デザイン", - "예술", - "使吃惊", - "がいねん", - ]; - break; - case "arabic": - dataset = [ - {text: "تصميم", direction: "rtl"}, - "வடிவமைப்பு", - "योजना", - {text: "לְעַצֵב", direction: "rtl"}, - {text: "خلاق", direction: "rtl"}, - "ศิลปะ", - ]; - break; - } - - dataset.forEach(function(entry, i) { - var td = document.getElementById("cell" + i); - if (typeof entry === 'string') { - td.innerText = entry; - } else { - td.innerText = entry.text; - td.classList.add("rtl"); - } - }) - - TextBenchmark.call(this, options); - } -); - -window.benchmarkClass = TextTemplateBenchmark; - -})(); \ No newline at end of file diff --git a/MotionMark/tests/text/design.html b/MotionMark/tests/text/design.html deleted file mode 100644 index 2de4977..0000000 --- a/MotionMark/tests/text/design.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - -
-
-
- - - - - - - - - diff --git a/MotionMark/tests/text/design.js b/MotionMark/tests/text/design.js deleted file mode 100644 index 9ec8a80..0000000 --- a/MotionMark/tests/text/design.js +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2017 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -(function() { - -// The MotionMark-based TextBenchmark should already be set to |window.benchmarkClass| -var TextBenchmark = window.benchmarkClass; -var TextTemplateBenchmark = Utilities.createSubclass(TextBenchmark, - function(options) - { - var dataset; - switch (options["corpus"]) { - case "latin": - dataset = [ - "σχέδιο", - "umění", - "suunnittelu", - "design", - "deseń", - "искусство", - "дизайн", - "conception", - "kunst", - "konstruktion", - "τέχνη", - "diseño" - ]; - break; - case "cjk": - dataset = [ - "设计", - "디자인", - "デザイン", - "がいねん", - "藝術", - "养殖", - "예술", - "展開する", - "발달", - "技術", - "驚き", - "使吃惊", - ]; - break; - case "arabic": - dataset = [ - {text: "تصميم", direction: "rtl"}, - "வடிவமைப்பு", - "योजना", - {text: "לְעַצֵב", direction: "rtl"}, - {text: "خلاق", direction: "rtl"}, - "ศิลปะ", - "कौशल", - {text: "אָמָנוּת", direction: "rtl"}, - "கலை", - "ดีไซน์", - "পরিকল্পনা", - {text: "ډیزاین", direction: "rtl"}, - ]; - break; - } - - dataset.forEach(function(entry, i) { - var td = document.getElementById("cell" + i); - if (typeof entry === 'string') { - td.innerText = entry; - } else { - td.innerText = entry.text; - td.classList.add("rtl"); - } - }) - - TextBenchmark.call(this, options); - } -); - -window.benchmarkClass = TextTemplateBenchmark; - -})(); \ No newline at end of file diff --git a/MotionMark/unit-tests/resources/js-test.js b/MotionMark/unit-tests/resources/js-test.js new file mode 100644 index 0000000..2becb06 --- /dev/null +++ b/MotionMark/unit-tests/resources/js-test.js @@ -0,0 +1,968 @@ +// Copyright 2014 Google Inc. All rights reserved. +// Copyright 2023 Apple Inc. All rights reserved. + +if (self.testRunner) { + // svg/dynamic-updates tests set enablePixelTesting=true, as we want to dump text + pixel results + if (self.enablePixelTesting) + testRunner.dumpAsTextWithPixelResults(); + else + testRunner.dumpAsText(); +} + +var description, debug, didFailSomeTests, successfullyParsed; + +didFailSomeTests = false; + +var expectingError; // set by shouldHaveError() +var expectedErrorMessage; // set by onerror when expectingError is true +var unexpectedErrorMessage; // set by onerror when expectingError is not true + +(function() { + + function createHTMLElement(tagName) + { + // FIXME: In an XML document, document.createElement() creates an element with a null namespace URI. + // So, we need use document.createElementNS() to explicitly create an element with the specified + // tag name in the HTML namespace. We can remove this function and use document.createElement() + // directly once we fix . + if (document.createElementNS) + return document.createElementNS("http://www.w3.org/1999/xhtml", tagName); + return document.createElement(tagName); + } + + var rootElement = null; + function ensureRootElement() + { + if (!rootElement || !rootElement.isConnected) { + rootElement = document.body || document.documentElement; + if (document.documentElement.namespaceURI == 'http://www.w3.org/2000/svg') { + // FIXME: Make the test harness use SVG elements naively. + var foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject'); + foreignObject.setAttribute('x', '0px'); + foreignObject.setAttribute('y', '0px'); + foreignObject.setAttribute('width', '100%'); + foreignObject.setAttribute('height', '100%'); + foreignObject.setAttribute('style', 'padding: 10px; background-color: rgba(255, 255, 255, 0.5)'); + document.documentElement.appendChild(foreignObject); + rootElement = foreignObject; + } + } + return rootElement; + } + + moveForeignObjectToTopIfNeeded = function () { + if (rootElement && rootElement.localName == 'foreignObject') + document.documentElement.appendChild(rootElement); + } + + getOrCreate = function getOrCreate(id, tagName) + { + var element = document.getElementById(id); + if (element) + return element; + + element = createHTMLElement(tagName); + element.id = id; + var refNode; + var parent = ensureRootElement(); + + if (id == "description") + refNode = getOrCreate("console", "div"); + else + refNode = parent.firstChild; + + parent.insertBefore(element, refNode); + return element; + } + + description = function description(msg, quiet) + { + // For MSIE 6 compatibility + var span = createHTMLElement("span"); + if (quiet) + span.innerHTML = '

' + msg + '

On success, you will see no "FAIL" messages, followed by "TEST COMPLETE".

'; + else + span.innerHTML = '

' + msg + '

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".

'; + + var description = getOrCreate("description", "p"); + if (description.firstChild) + description.replaceChild(span, description.firstChild); + else + description.appendChild(span); + }; + + debug = function debug(msg) + { + var span = createHTMLElement("span"); + span.innerHTML = msg + '
'; + getOrCreate("console", "div").appendChild(span); + }; + + var css = + ".pass {" + + "font-weight: bold;" + + "color: green;" + + "}" + + ".fail {" + + "font-weight: bold;" + + "color: red;" + + "}" + + "#console {" + + "white-space: pre-wrap;" + + "font-family: monospace;" + + "}"; + + function insertStyleSheet() + { + var styleElement = createHTMLElement("style"); + styleElement.textContent = css; + (document.head || ensureRootElement()).appendChild(styleElement); + } + + function handleTestFinished() + { + // FIXME: Get rid of this boolean. + wasPostTestScriptParsed = true; + if (window.jsTestIsAsync) { + if (window.testRunner) + testRunner.waitUntilDone(); + if (window.wasFinishJSTestCalled) + finishJSTest(); + } else + finishJSTest(); + } + + if (!isWorker()) { + window.addEventListener('DOMContentLoaded', function() { + // Call waitUntilDone() as early as possible otherwise some tests may complete before + // the load event has fired. + if (window.jsTestIsAsync && window.testRunner) + testRunner.waitUntilDone(); + + // Some tests set jsTestIsAsync in load event handler. Adding the listener late + // makes handleTestFinished() run after the test handles load events. + window.addEventListener("load", handleTestFinished, false); + }, false); + insertStyleSheet(); + } + + if (!self.isOnErrorTest) { + self.onerror = function(message) + { + if (self.expectingError) { + self.expectedErrorMessage = message; + self.expectingError = false; + return; + } + self.unexpectedErrorMessage = message; + if (self.jsTestIsAsync) { + self.testFailed("Unexpected error: " + message); + finishJSTest(); + } + }; + } +})(); + +function isWorker() +{ + // It's conceivable that someone would stub out 'document' in a worker so + // also check for childNodes, an arbitrary DOM-related object that is + // meaningless in a WorkerContext. + return (typeof document === 'undefined' || typeof document.childNodes === 'undefined') && !!self.importScripts; +} + +function descriptionQuiet(msg) { description(msg, true); } + +function escapeHTML(text) +{ + return text.replace(/&/g, "&").replace(/PASS ' + escapeHTML(msg) + ''); +} + +function testFailed(msg) +{ + didFailSomeTests = true; + debug('FAIL ' + escapeHTML(msg) + ''); +} + +function areArraysEqual(a, b) +{ + try { + if (a.length !== b.length) + return false; + for (var i = 0; i < a.length; i++) + if (a[i] !== b[i]) + return false; + } catch (ex) { + return false; + } + return true; +} + +function isMinusZero(n) +{ + // the only way to tell 0 from -0 in JS is the fact that 1/-0 is + // -Infinity instead of Infinity + return n === 0 && 1/n < 0; +} + +function isNewSVGTearOffType(v) +{ + return ['[object SVGLength]', '[object SVGLengthList]', '[object SVGPoint]', '[object SVGPointList]', '[object SVGNumber]'].indexOf(""+v) != -1; +} + +function isResultCorrect(actual, expected) +{ + if (expected === 0) + return actual === expected && (1/actual) === (1/expected); + if (actual === expected) + return true; + // http://crbug.com/308818 : The new implementation of SVGListProperties do not necessary return the same wrapper object, so === operator would not work. We compare for their string representation instead. + if (isNewSVGTearOffType(expected) && typeof(expected) == typeof(actual) && actual.valueAsString == expected.valueAsString) + return true; + if (typeof(expected) == "number" && isNaN(expected)) + return typeof(actual) == "number" && isNaN(actual); + if (expected && (Object.prototype.toString.call(expected) == Object.prototype.toString.call([]))) + return areArraysEqual(actual, expected); + return false; +} + +function stringify(v) +{ + if (isNewSVGTearOffType(v)) + return v.valueAsString; + if (v === 0 && 1/v < 0) + return "-0"; + else return "" + v; +} + +function evalAndLog(_a, _quiet) +{ + if (typeof _a != "string") + debug("WARN: tryAndLog() expects a string argument"); + + // Log first in case things go horribly wrong or this causes a sync event. + if (!_quiet) + debug(_a); + + var _av; + try { + _av = eval(_a); + } catch (e) { + testFailed(_a + " threw exception " + e); + } + return _av; +} + +function shouldBe(_a, _b, _quiet) +{ + if ((typeof _a != "function" && typeof _a != "string") || (typeof _b != "function" && typeof _b != "string")) + debug("WARN: shouldBe() expects function or string arguments"); + var _exception; + var _av; + try { + _av = (typeof _a == "function" ? _a() : eval(_a)); + } catch (e) { + _exception = e; + } + var _bv = (typeof _b == "function" ? _b() : eval(_b)); + + if (_exception) + testFailed(_a + " should be " + stringify(_bv) + ". Threw exception " + _exception); + else if (isResultCorrect(_av, _bv)) { + if (!_quiet) { + testPassed(_a + " is " + (typeof _b == "function" ? _bv : _b)); + } + } else if (typeof(_av) == typeof(_bv)) + testFailed(_a + " should be " + stringify(_bv) + ". Was " + stringify(_av) + "."); + else + testFailed(_a + " should be " + stringify(_bv) + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ")."); +} + +function shouldBeOneOfValues(_a, _values) +{ + if ((typeof _a != "function" && typeof _a != "string")) + debug("WARN: shouldBeOneOfValues() expects the first argument to be a function or a string"); + if (!Array.isArray(_values)) { + testFailed("The second argument to shouldBeOneOfValues() must be an array of values"); + return; + } + + var _exception; + var _av; + try { + _av = (typeof _a == "function" ? _a() : eval(_a)); + } catch (e) { + _exception = e; + } + + var stringifiedValues = ''; + for (var i = 0; i < _values.length; ++i) { + if (i) { + if (i + 1 == _values.length) + stringifiedValues += ', and '; + else + stringifiedValues += ',' + } + stringifiedValues += "`" + stringify(_values[i]) + "`"; + } + if (_exception) + testFailed(_a + " should be one of " + stringifiedValues + ". Threw exception " + _exception); + else { + var matchedValue = _values.find(function (value) { return isResultCorrect(_av, value); }); + if (matchedValue !== undefined) { + testPassed(_a + " is one of " + stringifiedValues); + } else { + testFailed(_a + " should be one of " + stringifiedValues + ". Was " + stringify(_av) + "."); + } + } +} + +// Execute condition every 5 milliseconds until it succeeds. +function _waitForCondition(condition, completionHandler) +{ + if (condition()) + completionHandler(); + else + setTimeout(_waitForCondition, 5, condition, completionHandler); +} + +function shouldBecomeEqual(_a, _b, completionHandler) +{ + if (typeof _a != "string" || typeof _b != "string") + debug("WARN: shouldBecomeEqual() expects string arguments"); + + function condition() { + var exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + exception = e; + } + var _bv = eval(_b); + if (exception) + testFailed(_a + " should become " + _bv + ". Threw exception " + exception); + if (isResultCorrect(_av, _bv)) { + testPassed(_a + " became " + _b); + return true; + } + return false; + } + + if (!completionHandler) + return new Promise(resolve => setTimeout(_waitForCondition, 0, condition, resolve)); + + setTimeout(_waitForCondition, 0, condition, completionHandler); +} + +function shouldBecomeEqualToString(value, reference, completionHandler) +{ + if (typeof value !== "string" || typeof reference !== "string") + debug("WARN: shouldBecomeEqualToString() expects string arguments"); + var unevaledString = JSON.stringify(reference); + shouldBecomeEqual(value, unevaledString, completionHandler); +} + +function shouldBeType(_a, _type) { + var _exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + _exception = e; + } + + var _typev = eval(_type); + if (_av instanceof _typev) { + testPassed(_a + " is an instance of " + _type); + } else { + testFailed(_a + " is not an instance of " + _type); + } +} + +// Variant of shouldBe()--confirms that result of eval(_to_eval) is within +// numeric _tolerance of numeric _target. +function shouldBeCloseTo(_to_eval, _target, _tolerance, _quiet) +{ + if (typeof _to_eval != "string") { + testFailed("shouldBeCloseTo() requires string argument _to_eval. was type " + typeof _to_eval); + return; + } + if (typeof _target != "number") { + testFailed("shouldBeCloseTo() requires numeric argument _target. was type " + typeof _target); + return; + } + if (typeof _tolerance != "number") { + testFailed("shouldBeCloseTo() requires numeric argument _tolerance. was type " + typeof _tolerance); + return; + } + + var _result; + try { + _result = eval(_to_eval); + } catch (e) { + testFailed(_to_eval + " should be within " + _tolerance + " of " + + _target + ". Threw exception " + e); + return; + } + + if (typeof(_result) != typeof(_target)) { + testFailed(_to_eval + " should be of type " + typeof _target + + " but was of type " + typeof _result); + } else if (Math.abs(_result - _target) <= _tolerance) { + if (!_quiet) { + testPassed(_to_eval + " is within " + _tolerance + " of " + _target); + } + } else { + testFailed(_to_eval + " should be within " + _tolerance + " of " + _target + + ". Was " + _result + "."); + } +} + +function shouldNotBe(_a, _b, _quiet) +{ + if ((typeof _a != "function" && typeof _a != "string") || (typeof _b != "function" && typeof _b != "string")) + debug("WARN: shouldNotBe() expects function or string arguments"); + var _exception; + var _av; + try { + _av = (typeof _a == "function" ? _a() : eval(_a)); + } catch (e) { + _exception = e; + } + var _bv = (typeof _b == "function" ? _b() : eval(_b)); + + if (_exception) + testFailed(_a + " should not be " + _bv + ". Threw exception " + _exception); + else if (!isResultCorrect(_av, _bv)) { + if (!_quiet) { + testPassed(_a + " is not " + (typeof _b == "function" ? _bv : _b)); + } + } else + testFailed(_a + " should not be " + _bv + "."); +} + +function shouldBecomeDifferent(_a, _b, completionHandler) +{ + if (typeof _a != "string" || typeof _b != "string") + debug("WARN: shouldBecomeDifferent() expects string arguments"); + + function condition() { + var exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + exception = e; + } + var _bv = eval(_b); + if (exception) + testFailed(_a + " should became not equal to " + _bv + ". Threw exception " + exception); + if (!isResultCorrect(_av, _bv)) { + testPassed(_a + " became different from " + _b); + return true; + } + return false; + } + + if (!completionHandler) + return new Promise(resolve => setTimeout(_waitForCondition, 0, condition, resolve)); + + setTimeout(_waitForCondition, 0, condition, completionHandler); +} + +function shouldBeTrue(a, quiet) { shouldBe(a, "true", quiet); } +function shouldBeTrueQuiet(a) { shouldBe(a, "true", true); } +function shouldBeFalse(a, quiet) { shouldBe(a, "false", quiet); } +function shouldBeNaN(a, quiet) { shouldBe(a, "NaN", quiet); } +function shouldBeNull(a, quiet) { shouldBe(a, "null", quiet); } +function shouldBeZero(a, quiet) { shouldBe(a, "0", quiet); } + +function shouldBeEqualToString(a, b) +{ + if (typeof a !== "string" || typeof b !== "string") + debug("WARN: shouldBeEqualToString() expects string arguments"); + var unevaledString = JSON.stringify(b); + shouldBe(a, unevaledString); +} + +function shouldBeEqualToNumber(a, b) +{ + if (typeof a !== "string" || typeof b !== "number") + debug("WARN: shouldBeEqualToNumber() expects a string and a number arguments"); + var unevaledString = JSON.stringify(b); + shouldBe(a, unevaledString); +} + +function shouldBeEmptyString(a) { shouldBeEqualToString(a, ""); } + +function shouldEvaluateTo(actual, expected) { + // A general-purpose comparator. 'actual' should be a string to be + // evaluated, as for shouldBe(). 'expected' may be any type and will be + // used without being eval'ed. + if (expected == null) { + // Do this before the object test, since null is of type 'object'. + shouldBeNull(actual); + } else if (typeof expected == "undefined") { + shouldBeUndefined(actual); + } else if (typeof expected == "function") { + // All this fuss is to avoid the string-arg warning from shouldBe(). + try { + var actualValue = eval(actual); + } catch (e) { + testFailed("Evaluating " + actual + ": Threw exception " + e); + return; + } + shouldBe("'" + actualValue.toString().replace(/\n/g, "") + "'", + "'" + expected.toString().replace(/\n/g, "") + "'"); + } else if (typeof expected == "object") { + shouldBeTrue(actual + " == '" + expected + "'"); + } else if (typeof expected == "string") { + shouldBe(actual, expected); + } else if (typeof expected == "boolean") { + shouldBe("typeof " + actual, "'boolean'"); + if (expected) + shouldBeTrue(actual); + else + shouldBeFalse(actual); + } else if (typeof expected == "number") { + shouldBe(actual, stringify(expected)); + } else { + debug(expected + " is unknown type " + typeof expected); + shouldBeTrue(actual, "'" +expected.toString() + "'"); + } +} + +function shouldBeNonZero(_a) +{ + var _exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + _exception = e; + } + + if (_exception) + testFailed(_a + " should be non-zero. Threw exception " + _exception); + else if (_av != 0) + testPassed(_a + " is non-zero."); + else + testFailed(_a + " should be non-zero. Was " + _av); +} + +function shouldBeNonNull(_a) +{ + var _exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + _exception = e; + } + + if (_exception) + testFailed(_a + " should be non-null. Threw exception " + _exception); + else if (_av != null) + testPassed(_a + " is non-null."); + else + testFailed(_a + " should be non-null. Was " + _av); +} + +function shouldBeUndefined(_a) +{ + var _exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + _exception = e; + } + + if (_exception) + testFailed(_a + " should be undefined. Threw exception " + _exception); + else if (typeof _av == "undefined") + testPassed(_a + " is undefined."); + else + testFailed(_a + " should be undefined. Was " + _av); +} + +function shouldBeDefined(_a) +{ + var _exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + _exception = e; + } + + if (_exception) + testFailed(_a + " should be defined. Threw exception " + _exception); + else if (_av !== undefined) + testPassed(_a + " is defined."); + else + testFailed(_a + " should be defined. Was " + _av); +} + +function shouldBeGreaterThan(_a, _b) { + if (typeof _a != "string" || typeof _b != "string") + debug("WARN: shouldBeGreaterThan expects string arguments"); + + var _exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + _exception = e; + } + var _bv = eval(_b); + + if (_exception) + testFailed(_a + " should be > " + _b + ". Threw exception " + _exception); + else if (typeof _av == "undefined" || _av <= _bv) + testFailed(_a + " should be > " + _b + ". Was " + _av + " (of type " + typeof _av + ")."); + else + testPassed(_a + " is > " + _b); +} + +function shouldBeGreaterThanOrEqual(_a, _b) { + if (typeof _a != "string" || typeof _b != "string") + debug("WARN: shouldBeGreaterThanOrEqual expects string arguments"); + + var _exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + _exception = e; + } + var _bv = eval(_b); + + if (_exception) + testFailed(_a + " should be >= " + _b + ". Threw exception " + _exception); + else if (typeof _av == "undefined" || _av < _bv) + testFailed(_a + " should be >= " + _b + ". Was " + _av + " (of type " + typeof _av + ")."); + else + testPassed(_a + " is >= " + _b); +} + +function shouldBeLessThanOrEqual(_a, _b) { + if (typeof _a != "string" || typeof _b != "string") + debug("WARN: shouldBeLessThanOrEqual expects string arguments"); + + var _exception; + var _av; + try { + _av = eval(_a); + } catch (e) { + _exception = e; + } + var _bv = eval(_b); + + if (_exception) + testFailed(_a + " should be <= " + _b + ". Threw exception " + _exception); + else if (typeof _av == "undefined" || _av > _bv) + testFailed(_a + " should be <= " + _b + ". Was " + _av + " (of type " + typeof _av + ")."); + else + testPassed(_a + " is <= " + _b); +} + +function expectTrue(v, msg) { + if (v) { + testPassed(msg); + } else { + testFailed(msg); + } +} + +function shouldNotThrow(_a, _message) { + try { + typeof _a == "function" ? _a() : eval(_a); + testPassed((_message ? _message : _a) + " did not throw exception."); + } catch (e) { + testFailed((_message ? _message : _a) + " should not throw exception. Threw exception " + e + "."); + } +} + +function shouldThrow(_a, _e, _message) +{ + var _exception; + var _av; + try { + _av = typeof _a == "function" ? _a() : eval(_a); + } catch (e) { + _exception = e; + } + + var _ev; + if (_e) + _ev = eval(_e); + + if (_exception) { + if (typeof _e == "undefined" || _exception == _ev) + testPassed((_message ? _message : _a) + " threw exception " + _exception + "."); + else + testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + _exception + "."); + } else if (typeof _av == "undefined") + testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined."); + else + testFailed((_message ? _message : _a) + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + "."); +} + +function shouldBeNow(a, delta) +{ + // Right now, V8 and Chromium / Blink use two different clock + // implementations. On Windows, the implementations are non-trivial and can + // be slightly out of sync. The delta is intended to compensate for that. + // + // FIXME: reconsider this when the V8 and Blink clocks get unified, see http://crbug.com/324110 + if (delta === undefined) + delta = 1000; + + for (var i = 0; i < 1000; ++i) { + var startDate = Date.now(); + var av = eval(a); + var date = av.valueOf(); + var endDate = Date.now(); + + // On some occasions such as NTP updates, the current time can go + // backwards. This should only happen rarely, so we can get away with + // retrying the test a few times if we detect the time going backwards. + if (startDate > endDate) + continue; + + if (typeof date !== "number") { + testFailed(a + " is not a number or a Date. Got " + av); + return; + } + if (date < startDate - delta) { + testFailed(a + " is not the curent time. Got " + av + " which is " + (startDate - date) / 1000 + " seconds in the past."); + return; + } + if (date > endDate + delta) { + testFailed(a + " is not the current time. Got " + av + " which is " + (date - endDate) / 1000 + " seconds in the future."); + return; + } + + testPassed(a + " is equivalent to Date.now()."); + return; + } + testFailed(a + " cannot be tested against the current time. The clock is going backwards too often."); +} + +function expectError() +{ + if (expectingError) { + testFailed("shouldHaveError() called twice before an error occurred!"); + } + expectingError = true; +} + +function shouldReject(_a, _message) +{ + return shouldRejectWithErrorName(_a, undefined, _message); +} + +function shouldRejectWithErrorName(_a, _name, _message) +{ + var _exception; + var _av; + try { + _av = typeof _a == "function" ? _a() : eval(_a); + } catch (e) { + testFailed((_message ? _message : _a) + " should not throw exception. Threw exception " + e + "."); + return Promise.resolve(); + } + + return _av.then(function(result) { + testFailed((_message ? _message : _a) + " should reject promise. Resolved with " + result + "."); + }, function(error) { + if (_name === undefined) { + testPassed((_message ? _message : _a) + " rejected promise."); + } else if (error['name'] === _name) { + // FIXME: Remove the extra space and '.' (DOMException descriptions already end with periods) then rebase tests. + testPassed((_message ? _message : _a) + " rejected promise with " + error + "."); + } else + testFailed((_message ? _message : _a) + " should reject promise with " + _name + ". Rejected with " + error['name'] + " instead."); + }); +} + +function shouldThrowErrorName(_a, _name) +{ + var _exception; + try { + typeof _a == "function" ? _a() : eval(_a); + } catch (e) { + _exception = e; + } + + if (_exception) { + if (_exception.name == _name) + testPassed(_a + " threw exception " + _exception + "."); + else + testFailed(_a + " should throw a " + _name + ". Threw a " + _exception.name + "."); + } else + testFailed(_a + " should throw a " + _name + ". Did not throw."); +} + +function shouldHaveHadError(message) +{ + if (expectingError) { + testFailed("No error thrown between expectError() and shouldHaveHadError()"); + return; + } + + if (expectedErrorMessage) { + if (!message) + testPassed("Got expected error"); + else if (expectedErrorMessage.indexOf(message) !== -1) + testPassed("Got expected error: '" + message + "'"); + else + testFailed("Unexpected error '" + message + "'"); + expectedErrorMessage = undefined; + return; + } + + testFailed("expectError() not called before shouldHaveHadError()"); +} + +function gc() { + if (typeof GCController !== "undefined") + GCController.collect(); + else { + var gcRec = function (n) { + if (n < 1) + return {}; + var temp = {i: "ab" + i + (i / 100000)}; + temp += "foo"; + gcRec(n-1); + }; + for (var i = 0; i < 1000; i++) + gcRec(10); + } +} + +function minorGC() { + if (typeof GCController !== "undefined") + GCController.minorCollect(); + else + testFailed("Minor GC is available only when you enable the --expose-gc option in V8."); +} + +function isSuccessfullyParsed() +{ + // FIXME: Remove this and only report unexpected syntax errors. + successfullyParsed = !unexpectedErrorMessage; + shouldBeTrue("successfullyParsed"); + if (didFailSomeTests) + debug("Some tests failed."); + debug('
TEST COMPLETE'); +} + +// It's possible for an async test to call finishJSTest() before js-test-post.js +// has been parsed. +function finishJSTest() +{ + wasFinishJSTestCalled = true; + if (!self.wasPostTestScriptParsed) + return; + isSuccessfullyParsed(); + moveForeignObjectToTopIfNeeded(); + if (self.jsTestIsAsync && self.testRunner) + testRunner.notifyDone(); +} + +function areObjectsEqual(a, b) { + for (var property in a) { + if (!b.hasOwnProperty(property)) + return false; + + switch (typeof (a[property])) { + case 'function': + if (typeof b[property] == 'undefined' || a[property].toString() != b[property].toString()) + return false; + break; + case 'object': + if (!areObjectsEqual(a, b)) + return false; + break; + default: + if (a[property] != b[property]) + return false; + } + } + + for (var property in b) { + if (!a.hasOwnProperty(property)) + return false; + } + + return true; +}; + +function startWorker(testScriptURL) +{ + self.jsTestIsAsync = true; + debug('Starting worker: ' + testScriptURL); + var worker = new Worker(testScriptURL); + worker.onmessage = function(event) + { + var workerPrefix = "[Worker] "; + if (event.data.length < 5 || event.data.charAt(4) != ':') { + debug(workerPrefix + event.data); + return; + } + var code = event.data.substring(0, 4); + var payload = workerPrefix + event.data.substring(5); + if (code == "PASS") + testPassed(payload); + else if (code == "FAIL") + testFailed(payload); + else if (code == "DESC") + description(payload); + else if (code == "DONE") + finishJSTest(); + else + debug(workerPrefix + event.data); + }; + + worker.onerror = function(event) + { + debug('Got error from worker: ' + event.message); + finishJSTest(); + }; + + return worker; +} + +if (isWorker()) { + var workerPort = self; + description = function(msg, quiet) { + workerPort.postMessage('DESC:' + msg); + }; + testFailed = function(msg) { + workerPort.postMessage('FAIL:' + msg); + }; + testPassed = function(msg) { + workerPort.postMessage('PASS:' + msg); + }; + finishJSTest = function() { + workerPort.postMessage('DONE:'); + }; + debug = function(msg) { + workerPort.postMessage(msg); + }; +} + +function downgradeReferrerCallback(policy, host) { + let scriptElement = document.createElement("script"); + scriptElement.src = "http://".concat(host, ":8000/referrer-policy/resources/script.py"); + scriptElement.referrerPolicy = policy; + document.body.appendChild(scriptElement); +} diff --git a/MotionMark/unit-tests/test-animator.html b/MotionMark/unit-tests/test-animator.html new file mode 100644 index 0000000..59091db --- /dev/null +++ b/MotionMark/unit-tests/test-animator.html @@ -0,0 +1,72 @@ + + + + + + + + diff --git a/MotionMark/unit-tests/test-fixed-controller.html b/MotionMark/unit-tests/test-fixed-controller.html new file mode 100644 index 0000000..aa5dfe2 --- /dev/null +++ b/MotionMark/unit-tests/test-fixed-controller.html @@ -0,0 +1,59 @@ + + + + + + + diff --git a/MotionMark/unit-tests/test-ramp-controller.html b/MotionMark/unit-tests/test-ramp-controller.html new file mode 100644 index 0000000..6ae7933 --- /dev/null +++ b/MotionMark/unit-tests/test-ramp-controller.html @@ -0,0 +1,10 @@ + + + + + + + diff --git a/MotionMark/unit-tests/test-regression.html b/MotionMark/unit-tests/test-regression.html new file mode 100644 index 0000000..0e1bef4 --- /dev/null +++ b/MotionMark/unit-tests/test-regression.html @@ -0,0 +1,272 @@ + + + + + + + diff --git a/MotionMark/unit-tests/test-spiral-iterator.html b/MotionMark/unit-tests/test-spiral-iterator.html new file mode 100644 index 0000000..c9bb47f --- /dev/null +++ b/MotionMark/unit-tests/test-spiral-iterator.html @@ -0,0 +1,29 @@ + + + + + + +

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 - - + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + diff --git a/MotionMark/tests/3d/triangles-webgpu.html b/MotionMark/tests/core/canvas-lines.html similarity index 51% rename from MotionMark/tests/3d/triangles-webgpu.html rename to MotionMark/tests/core/canvas-lines.html index e8929b0..750dd46 100644 --- a/MotionMark/tests/3d/triangles-webgpu.html +++ b/MotionMark/tests/core/canvas-lines.html @@ -1,5 +1,5 @@ - - - - - - - - - - - - - - - - - diff --git a/MotionMark/tests/core/design.html b/MotionMark/tests/core/design.html index 0f30dfd..e4bc55f 100644 --- a/MotionMark/tests/core/design.html +++ b/MotionMark/tests/core/design.html @@ -1,5 +1,5 @@ - - - - - - - - -