blob: 81ce31b3546aeea50f51abf97bf83547397138d9 [file] [log] [blame]
[email protected]35805ad2014-05-31 22:17:191// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
chrishtr82b5d9502017-03-20 18:25:335#include "cc/benchmarks/invalidation_benchmark.h"
[email protected]35805ad2014-05-31 22:17:196
avi02a4d172015-12-21 06:14:367#include <stdint.h>
8
[email protected]35805ad2014-05-31 22:17:199#include <algorithm>
10#include <limits>
11
[email protected]35805ad2014-05-31 22:17:1912#include "base/rand_util.h"
13#include "base/values.h"
14#include "cc/layers/layer.h"
15#include "cc/layers/picture_layer.h"
jaydasika0f02fed2016-04-05 19:07:0216#include "cc/trees/draw_property_utils.h"
khushalsagarb69ba9452017-01-27 22:20:0717#include "cc/trees/layer_tree_host.h"
[email protected]35805ad2014-05-31 22:17:1918#include "cc/trees/layer_tree_host_common.h"
heejin.r.chungd28506ba2014-10-23 16:36:2019#include "ui/gfx/geometry/rect.h"
[email protected]35805ad2014-05-31 22:17:1920
21namespace cc {
22
23namespace {
24
25const char* kDefaultInvalidationMode = "viewport";
26
27} // namespace
28
29InvalidationBenchmark::InvalidationBenchmark(
danakj60bc3bc2016-04-09 00:24:4830 std::unique_ptr<base::Value> value,
Sadrul Habib Chowdhuryd7cc06cf72018-01-26 23:08:4031 MicroBenchmark::DoneCallback callback)
32 : MicroBenchmark(std::move(callback)), seed_(0) {
kulkarni.a4015690f12014-10-10 13:50:0633 base::DictionaryValue* settings = nullptr;
[email protected]35805ad2014-05-31 22:17:1934 value->GetAsDictionary(&settings);
35 if (!settings)
36 return;
37
38 std::string mode_string = kDefaultInvalidationMode;
39
40 if (settings->HasKey("mode"))
41 settings->GetString("mode", &mode_string);
42
43 if (mode_string == "fixed_size") {
44 mode_ = FIXED_SIZE;
45 CHECK(settings->HasKey("width"))
46 << "Must provide a width for fixed_size mode.";
47 CHECK(settings->HasKey("height"))
48 << "Must provide a height for fixed_size mode.";
49 settings->GetInteger("width", &width_);
50 settings->GetInteger("height", &height_);
51 } else if (mode_string == "layer") {
52 mode_ = LAYER;
53 } else if (mode_string == "random") {
54 mode_ = RANDOM;
55 } else if (mode_string == "viewport") {
56 mode_ = VIEWPORT;
57 } else {
58 CHECK(false) << "Invalid mode: " << mode_string
59 << ". One of {fixed_size, layer, viewport, random} expected.";
60 }
61}
62
Chris Watkinsf6353292017-12-04 02:36:0563InvalidationBenchmark::~InvalidationBenchmark() = default;
[email protected]35805ad2014-05-31 22:17:1964
khushalsagarb69ba9452017-01-27 22:20:0765void InvalidationBenchmark::DidUpdateLayers(LayerTreeHost* layer_tree_host) {
jaydasika13c05062016-04-01 18:12:2766 LayerTreeHostCommon::CallFunctionForEveryLayer(
khushalsagarb69ba9452017-01-27 22:20:0767 layer_tree_host,
68 [this](Layer* layer) { layer->RunMicroBenchmark(this); });
[email protected]35805ad2014-05-31 22:17:1969}
70
71void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) {
sunxd713aedbd2016-08-10 22:22:1472 gfx::Rect visible_layer_rect = gfx::Rect(layer->bounds());
73 gfx::Transform from_screen;
xidachen41fb39b2017-04-11 21:40:2574 bool invertible = layer->ScreenSpaceTransform().GetInverse(&from_screen);
sunxd713aedbd2016-08-10 22:22:1475 if (!invertible)
76 from_screen = gfx::Transform();
77 gfx::Rect viewport_rect = MathUtil::ProjectEnclosingClippedRect(
khushalsagarb69ba9452017-01-27 22:20:0778 from_screen, gfx::Rect(layer->layer_tree_host()->device_viewport_size()));
sunxd713aedbd2016-08-10 22:22:1479 visible_layer_rect.Intersect(viewport_rect);
[email protected]35805ad2014-05-31 22:17:1980 switch (mode_) {
81 case FIXED_SIZE: {
82 // Invalidation with a random position and fixed size.
danakj64767d902015-06-19 00:10:4383 int x = LCGRandom() * (visible_layer_rect.width() - width_);
84 int y = LCGRandom() * (visible_layer_rect.height() - height_);
[email protected]35805ad2014-05-31 22:17:1985 gfx::Rect invalidation_rect(x, y, width_, height_);
86 layer->SetNeedsDisplayRect(invalidation_rect);
87 break;
88 }
89 case LAYER: {
90 // Invalidate entire layer.
91 layer->SetNeedsDisplay();
92 break;
93 }
94 case RANDOM: {
95 // Random invalidation inside the viewport.
danakj64767d902015-06-19 00:10:4396 int x_min = LCGRandom() * visible_layer_rect.width();
97 int x_max = LCGRandom() * visible_layer_rect.width();
98 int y_min = LCGRandom() * visible_layer_rect.height();
99 int y_max = LCGRandom() * visible_layer_rect.height();
[email protected]35805ad2014-05-31 22:17:19100 if (x_min > x_max)
101 std::swap(x_min, x_max);
102 if (y_min > y_max)
103 std::swap(y_min, y_max);
104 gfx::Rect invalidation_rect(x_min, y_min, x_max - x_min, y_max - y_min);
105 layer->SetNeedsDisplayRect(invalidation_rect);
106 break;
107 }
108 case VIEWPORT: {
109 // Invalidate entire viewport.
sunxd713aedbd2016-08-10 22:22:14110 layer->SetNeedsDisplayRect(visible_layer_rect);
[email protected]35805ad2014-05-31 22:17:19111 break;
112 }
113 }
114}
115
danakj60bc3bc2016-04-09 00:24:48116bool InvalidationBenchmark::ProcessMessage(std::unique_ptr<base::Value> value) {
kulkarni.a4015690f12014-10-10 13:50:06117 base::DictionaryValue* message = nullptr;
[email protected]35805ad2014-05-31 22:17:19118 value->GetAsDictionary(&message);
119 if (!message)
120 return false;
121
122 bool notify_done;
123 if (message->HasKey("notify_done")) {
124 message->GetBoolean("notify_done", &notify_done);
125 if (notify_done)
Jeremy Roman909d927b2017-08-27 18:34:09126 NotifyDone(std::make_unique<base::Value>());
[email protected]35805ad2014-05-31 22:17:19127 return true;
128 }
129 return false;
130}
131
132// A simple linear congruential generator. The random numbers don't need to be
133// high quality, but they need to be identical in each run. Therefore, we use a
134// LCG and keep the state locally in the benchmark.
135float InvalidationBenchmark::LCGRandom() {
avi02a4d172015-12-21 06:14:36136 const uint32_t a = 1664525;
137 const uint32_t c = 1013904223;
[email protected]35805ad2014-05-31 22:17:19138 seed_ = a * seed_ + c;
avi02a4d172015-12-21 06:14:36139 return static_cast<float>(seed_) / std::numeric_limits<uint32_t>::max();
[email protected]35805ad2014-05-31 22:17:19140}
141
142} // namespace cc