blob: ddc2996567475c196bc219b410881f07426c458e [file] [log] [blame]
// Copyright (c) 2012 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 "content/renderer/all_rendering_benchmarks.h"
#include <algorithm>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/time.h"
#include "content/renderer/rendering_benchmark.h"
#include "skia/ext/platform_canvas.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/utils/SkNullCanvas.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebViewBenchmarkSupport.h"
using base::TimeDelta;
using base::TimeTicks;
using WebKit::WebSize;
using WebKit::WebCanvas;
using WebKit::WebViewBenchmarkSupport;
using WebKit::WebRect;
using std::vector;
namespace {
// This is a base class for timing the painting of the current webpage to
// custom WebCanvases.
class CustomPaintBenchmark
: public content::RenderingBenchmark,
public WebViewBenchmarkSupport::PaintClient {
public:
CustomPaintBenchmark(const std::string& name,
WebViewBenchmarkSupport::PaintMode paint_mode)
: content::RenderingBenchmark(name),
paint_mode_(paint_mode) { }
virtual WebCanvas* willPaint(const WebSize& size) OVERRIDE {
WebCanvas* canvas = createCanvas(size);
before_time_ = TimeTicks::HighResNow();
return canvas;
}
virtual void didPaint(WebCanvas* canvas) OVERRIDE {
paint_time_total_ += (TimeTicks::HighResNow() - before_time_);
delete canvas;
}
virtual double Run(WebViewBenchmarkSupport* support) OVERRIDE {
paint_time_total_ = TimeDelta();
support->paint(this, paint_mode_);
return paint_time_total_.InMillisecondsF();
}
private:
virtual WebCanvas* createCanvas(const WebSize& size) = 0;
TimeTicks before_time_;
TimeDelta paint_time_total_;
const WebViewBenchmarkSupport::PaintMode paint_mode_;
};
class BitmapCanvasPaintBenchmark : public CustomPaintBenchmark {
public:
BitmapCanvasPaintBenchmark(const std::string& name,
WebViewBenchmarkSupport::PaintMode paint_mode)
: CustomPaintBenchmark(name, paint_mode) { }
private:
virtual WebCanvas* createCanvas(const WebSize& size) OVERRIDE {
return skia::CreateBitmapCanvas(size.width, size.height, false);
}
};
class CanvasCountBenchmark
: public content::RenderingBenchmark,
public WebViewBenchmarkSupport::PaintClient {
public:
CanvasCountBenchmark(const std::string& name,
WebViewBenchmarkSupport::PaintMode paint_mode)
: content::RenderingBenchmark(name),
canvas_count_(0),
paint_mode_(paint_mode) { }
virtual WebCanvas* willPaint(const WebSize& size) OVERRIDE {
++canvas_count_;
return SkCreateNullCanvas();
}
virtual void didPaint(WebCanvas* canvas) OVERRIDE {
delete canvas;
}
virtual double Run(WebViewBenchmarkSupport* support) OVERRIDE {
canvas_count_ = 0;
support->paint(this, paint_mode_);
return canvas_count_;
}
private:
int canvas_count_;
const WebViewBenchmarkSupport::PaintMode paint_mode_;
};
class NullCanvasPaintBenchmark : public CustomPaintBenchmark {
public:
NullCanvasPaintBenchmark(const std::string& name,
WebViewBenchmarkSupport::PaintMode paint_mode)
: CustomPaintBenchmark(name, paint_mode) { }
private:
virtual WebCanvas* createCanvas(const WebSize& size) OVERRIDE {
return SkCreateNullCanvas();
}
};
class SkPicturePaintBenchmark : public CustomPaintBenchmark {
public:
SkPicturePaintBenchmark(const std::string& name,
WebViewBenchmarkSupport::PaintMode paint_mode)
: CustomPaintBenchmark(name, paint_mode) { }
virtual void didPaint(WebCanvas* canvas) OVERRIDE {
DCHECK(picture_.getRecordingCanvas() == canvas);
picture_.endRecording();
CustomPaintBenchmark::didPaint(NULL);
}
private:
virtual WebCanvas* createCanvas(const WebSize& size) OVERRIDE {
return picture_.beginRecording(size.width, size.height);
}
SkPicture picture_;
};
// Base class for timing the replaying of the SkPicture into canvases.
class TiledReplayBenchmark
: public content::RenderingBenchmark,
public WebViewBenchmarkSupport::PaintClient {
public:
TiledReplayBenchmark(const std::string& name,
WebViewBenchmarkSupport::PaintMode paint_mode)
: RenderingBenchmark(name),
paint_mode_(paint_mode) {}
virtual WebCanvas* willPaint(const WebSize& size) OVERRIDE {
return picture_.beginRecording(size.width, size.height);
}
virtual void didPaint(WebCanvas* canvas) OVERRIDE {
DCHECK(picture_.getRecordingCanvas() == canvas);
picture_.endRecording();
const vector<WebRect> repaint_tiles = GetRepaintTiles(
WebSize(picture_.width(), picture_.height()));
vector<WebRect>::const_iterator it;
for (it = repaint_tiles.begin(); it != repaint_tiles.end(); ++it) {
WebRect tile = *it;
scoped_ptr<WebCanvas> canvas(
skia::CreateBitmapCanvas(tile.width, tile.height, false));
TimeTicks before_time = TimeTicks::HighResNow();
canvas->translate(-tile.x, -tile.y);
picture_.draw(canvas.get());
paint_time_total_ += (TimeTicks::HighResNow() - before_time);
}
}
virtual double Run(WebViewBenchmarkSupport* support) {
paint_time_total_ = TimeDelta();
support->paint(this, paint_mode_);
return paint_time_total_.InMillisecondsF();
}
private:
virtual vector<WebRect> GetRepaintTiles(const WebSize& layer_size) const = 0;
TimeDelta paint_time_total_;
SkPicture picture_;
const WebViewBenchmarkSupport::PaintMode paint_mode_;
};
class SquareTiledReplayBenchmark : public TiledReplayBenchmark {
public:
SquareTiledReplayBenchmark(const std::string& name,
WebViewBenchmarkSupport::PaintMode paint_mode,
int tile_size)
: TiledReplayBenchmark(name, paint_mode),
tile_size_(tile_size) {
CHECK_GT(tile_size, 0);
}
private:
virtual vector<WebRect> GetRepaintTiles(
const WebSize& layer_size) const OVERRIDE {
vector<WebRect> tiles;
for (int x = 0; x < layer_size.width; x += tile_size_) {
for (int y = 0; y < layer_size.height; y += tile_size_) {
int width = std::min(layer_size.width - x, tile_size_);
int height = std::min(layer_size.height - y, tile_size_);
tiles.push_back(WebRect(x, y, width, height));
}
}
return tiles;
}
int tile_size_;
};
class LayerWidthTiledReplayBenchmark : public TiledReplayBenchmark {
public:
LayerWidthTiledReplayBenchmark(const std::string& name,
WebViewBenchmarkSupport::PaintMode paint_mode,
int tile_height)
: TiledReplayBenchmark(name, paint_mode),
tile_height_(tile_height) {
CHECK_GT(tile_height, 0);
}
private:
virtual vector<WebRect> GetRepaintTiles(
const WebSize& layer_size) const OVERRIDE {
vector<WebRect> tiles;
for (int y = 0; y < layer_size.height; y += tile_height_) {
int height = std::min(layer_size.height - y, tile_height_);
tiles.push_back(WebRect(0, y, layer_size.width, height));
}
return tiles;
}
int tile_height_;
};
} // anonymous namespace
namespace content {
ScopedVector<RenderingBenchmark> AllRenderingBenchmarks() {
ScopedVector<RenderingBenchmark> benchmarks;
benchmarks.push_back(new BitmapCanvasPaintBenchmark(
"PaintEverythingToBitmapMs",
WebViewBenchmarkSupport::PaintModeEverything));
benchmarks.push_back(new NullCanvasPaintBenchmark(
"PaintEverythingToNullCanvasMs",
WebViewBenchmarkSupport::PaintModeEverything));
benchmarks.push_back(new CanvasCountBenchmark(
"LayerCount",
WebViewBenchmarkSupport::PaintModeEverything));
benchmarks.push_back(new SkPicturePaintBenchmark(
"PaintEverythingToSkPictureMs",
WebViewBenchmarkSupport::PaintModeEverything));
benchmarks.push_back(new SquareTiledReplayBenchmark(
"RepaintEverythingTo256x256BitmapMs",
WebViewBenchmarkSupport::PaintModeEverything,
256));
benchmarks.push_back(new SquareTiledReplayBenchmark(
"RepaintEverythingTo128x128BitmapMs",
WebViewBenchmarkSupport::PaintModeEverything,
128));
benchmarks.push_back(new SquareTiledReplayBenchmark(
"RepaintEverythingTo512x512BitmapMs",
WebViewBenchmarkSupport::PaintModeEverything,
512));
benchmarks.push_back(new LayerWidthTiledReplayBenchmark(
"RepaintEverythingToLayerWidthx256BitmapMs",
WebViewBenchmarkSupport::PaintModeEverything,
256));
benchmarks.push_back(new LayerWidthTiledReplayBenchmark(
"RepaintEverythingToLayerWidthx128BitmapMs",
WebViewBenchmarkSupport::PaintModeEverything,
128));
benchmarks.push_back(new LayerWidthTiledReplayBenchmark(
"RepaintEverythingToLayerWidthx64BitmapMs",
WebViewBenchmarkSupport::PaintModeEverything,
64));
benchmarks.push_back(new LayerWidthTiledReplayBenchmark(
"RepaintEverythingToLayerWidthx512BitmapMs",
WebViewBenchmarkSupport::PaintModeEverything,
512));
return benchmarks.Pass();
}
} // namespace content