Commit 35805ad1 authored by ernstm@chromium.org's avatar ernstm@chromium.org

cc: Add invalidation micro benchmark.

This micro benchmark will used in a follow-up patch to generate various
kinds of invalidations (viewport, random, full layer) from the telemetry
repaint benchmark.

R=vmpstr@chromium.org
BUG=376379

Review URL: https://codereview.chromium.org/298723013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274065 0039d316-1c4b-4281-b951-d872f2087c98
parent 8acc5f59
......@@ -102,6 +102,8 @@
'debug/frame_rate_counter.cc',
'debug/frame_rate_counter.h',
'debug/frame_viewer_instrumentation.h',
'debug/invalidation_benchmark.cc',
'debug/invalidation_benchmark.h',
'debug/lap_timer.cc',
'debug/lap_timer.h',
'debug/layer_tree_debug_state.cc',
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cc/debug/invalidation_benchmark.h"
#include <algorithm>
#include <limits>
#include "base/basictypes.h"
#include "base/rand_util.h"
#include "base/values.h"
#include "cc/layers/layer.h"
#include "cc/layers/picture_layer.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_common.h"
#include "ui/gfx/rect.h"
namespace cc {
namespace {
const char* kDefaultInvalidationMode = "viewport";
} // namespace
InvalidationBenchmark::InvalidationBenchmark(
scoped_ptr<base::Value> value,
const MicroBenchmark::DoneCallback& callback)
: MicroBenchmark(callback), seed_(0) {
base::DictionaryValue* settings = NULL;
value->GetAsDictionary(&settings);
if (!settings)
return;
std::string mode_string = kDefaultInvalidationMode;
if (settings->HasKey("mode"))
settings->GetString("mode", &mode_string);
if (mode_string == "fixed_size") {
mode_ = FIXED_SIZE;
CHECK(settings->HasKey("width"))
<< "Must provide a width for fixed_size mode.";
CHECK(settings->HasKey("height"))
<< "Must provide a height for fixed_size mode.";
settings->GetInteger("width", &width_);
settings->GetInteger("height", &height_);
} else if (mode_string == "layer") {
mode_ = LAYER;
} else if (mode_string == "random") {
mode_ = RANDOM;
} else if (mode_string == "viewport") {
mode_ = VIEWPORT;
} else {
CHECK(false) << "Invalid mode: " << mode_string
<< ". One of {fixed_size, layer, viewport, random} expected.";
}
}
InvalidationBenchmark::~InvalidationBenchmark() {
}
void InvalidationBenchmark::DidUpdateLayers(LayerTreeHost* host) {
LayerTreeHostCommon::CallFunctionForSubtree(
host->root_layer(),
base::Bind(&InvalidationBenchmark::Run, base::Unretained(this)));
}
void InvalidationBenchmark::Run(Layer* layer) {
layer->RunMicroBenchmark(this);
}
void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) {
switch (mode_) {
case FIXED_SIZE: {
// Invalidation with a random position and fixed size.
gfx::Rect visible_content_rect = layer->visible_content_rect();
int x = LCGRandom() * (visible_content_rect.width() - width_);
int y = LCGRandom() * (visible_content_rect.height() - height_);
gfx::Rect invalidation_rect(x, y, width_, height_);
layer->SetNeedsDisplayRect(invalidation_rect);
break;
}
case LAYER: {
// Invalidate entire layer.
layer->SetNeedsDisplay();
break;
}
case RANDOM: {
// Random invalidation inside the viewport.
gfx::Rect visible_content_rect = layer->visible_content_rect();
int x_min = LCGRandom() * visible_content_rect.width();
int x_max = LCGRandom() * visible_content_rect.width();
int y_min = LCGRandom() * visible_content_rect.height();
int y_max = LCGRandom() * visible_content_rect.height();
if (x_min > x_max)
std::swap(x_min, x_max);
if (y_min > y_max)
std::swap(y_min, y_max);
gfx::Rect invalidation_rect(x_min, y_min, x_max - x_min, y_max - y_min);
layer->SetNeedsDisplayRect(invalidation_rect);
break;
}
case VIEWPORT: {
// Invalidate entire viewport.
layer->SetNeedsDisplayRect(layer->visible_content_rect());
break;
}
}
}
bool InvalidationBenchmark::ProcessMessage(scoped_ptr<base::Value> value) {
base::DictionaryValue* message = NULL;
value->GetAsDictionary(&message);
if (!message)
return false;
bool notify_done;
if (message->HasKey("notify_done")) {
message->GetBoolean("notify_done", &notify_done);
if (notify_done)
NotifyDone(scoped_ptr<base::Value>(base::Value::CreateNullValue()));
return true;
}
return false;
}
// A simple linear congruential generator. The random numbers don't need to be
// high quality, but they need to be identical in each run. Therefore, we use a
// LCG and keep the state locally in the benchmark.
float InvalidationBenchmark::LCGRandom() {
const uint32 a = 1664525;
const uint32 c = 1013904223;
seed_ = a * seed_ + c;
return static_cast<float>(seed_) / std::numeric_limits<uint32>::max();
}
} // namespace cc
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_DEBUG_INVALIDATION_BENCHMARK_H_
#define CC_DEBUG_INVALIDATION_BENCHMARK_H_
#include <string>
#include "cc/debug/micro_benchmark_controller.h"
namespace cc {
class LayerTreeHost;
class Layer;
// NOTE: this benchmark will not measure or return any results, it will simply
// invalidate a certain area of each layer every frame. It is intended to be
// used in combination with a telemetry benchmark that does the actual
// measurement.
class CC_EXPORT InvalidationBenchmark : public MicroBenchmark {
public:
explicit InvalidationBenchmark(scoped_ptr<base::Value> value,
const MicroBenchmark::DoneCallback& callback);
virtual ~InvalidationBenchmark();
// Implements MicroBenchmark interface.
virtual void DidUpdateLayers(LayerTreeHost* host) OVERRIDE;
virtual void RunOnLayer(PictureLayer* layer) OVERRIDE;
virtual bool ProcessMessage(scoped_ptr<base::Value> value) OVERRIDE;
private:
enum Mode { FIXED_SIZE, LAYER, VIEWPORT, RANDOM };
void Run(Layer* layer);
float LCGRandom();
Mode mode_;
int width_;
int height_;
uint32 seed_;
};
} // namespace cc
#endif // CC_DEBUG_INVALIDATION_BENCHMARK_H_
......@@ -10,6 +10,7 @@
#include "base/callback.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/values.h"
#include "cc/debug/invalidation_benchmark.h"
#include "cc/debug/picture_record_benchmark.h"
#include "cc/debug/rasterize_and_record_benchmark.h"
#include "cc/debug/unittest_only_benchmark.h"
......@@ -26,7 +27,10 @@ scoped_ptr<MicroBenchmark> CreateBenchmark(
const std::string& name,
scoped_ptr<base::Value> value,
const MicroBenchmark::DoneCallback& callback) {
if (name == "picture_record_benchmark") {
if (name == "invalidation_benchmark") {
return scoped_ptr<MicroBenchmark>(
new InvalidationBenchmark(value.Pass(), callback));
} else if (name == "picture_record_benchmark") {
return scoped_ptr<MicroBenchmark>(
new PictureRecordBenchmark(value.Pass(), callback));
} else if (name == "rasterize_and_record_benchmark") {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment