bench_main.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// found in the LICENSE file.
4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/at_exit.h"
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/bind.h"
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/command_line.h"
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/i18n/icu_util.h"
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/message_loop/message_loop.h"
1102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "base/strings/string_split.h"
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/time/time.h"
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2.h"
1402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "third_party/skia/include/core/SkXfermode.h"
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/aura/client/default_capture_client.h"
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/aura/env.h"
1702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "ui/aura/focus_manager.h"
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/aura/root_window.h"
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/aura/test/test_screen.h"
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/aura/window.h"
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/base/hit_test.h"
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/base/ui_base_paths.h"
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/compositor/compositor.h"
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/compositor/compositor_observer.h"
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/compositor/debug_utils.h"
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/compositor/layer.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/gfx/canvas.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/gfx/rect.h"
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "ui/gfx/skia_util.h"
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef GL_GLEXT_PROTOTYPES
321e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#define GL_GLEXT_PROTOTYPES 1
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "third_party/khronos/GLES2/gl2ext.h"
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#if defined(USE_X11)
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/message_loop/message_pump_aurax11.h"
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciusing base::TimeTicks;
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using ui::Compositor;
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using ui::Layer;
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using ui::LayerDelegate;
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using WebKit::WebGraphicsContext3D;
467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace {
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class ColoredLayer : public Layer, public LayerDelegate {
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public:
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  explicit ColoredLayer(SkColor color)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      : Layer(ui::LAYER_TEXTURED),
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        color_(color),
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        draw_(true) {
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    set_delegate(this);
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual ~ColoredLayer() {}
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Overridden from LayerDelegate:
6102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch  virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (draw_) {
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      canvas->DrawColor(color_);
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch  }
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return base::Closure();
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  void set_color(SkColor color) { color_ = color; }
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  void set_draw(bool draw) { draw_ = draw; }
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private:
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  SkColor color_;
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  bool draw_;
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ColoredLayer);
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const int kFrames = 100;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Benchmark base class, hooks up drawing callback and displaying FPS.
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class BenchCompositorObserver : public ui::CompositorObserver {
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public:
8902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch  explicit BenchCompositorObserver(int max_frames)
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      : start_time_(),
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        frames_(0),
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        max_frames_(max_frames) {
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
957242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci  virtual void OnCompositingDidCommit(ui::Compositor* compositor) OVERRIDE {}
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void OnCompositingStarted(Compositor* compositor,
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                    base::TimeTicks start_time) OVERRIDE {}
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void OnCompositingEnded(Compositor* compositor) OVERRIDE {
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (start_time_.is_null()) {
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      start_time_ = TimeTicks::Now();
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      ++frames_;
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      if (frames_ % kFrames == 0) {
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        TimeTicks now = TimeTicks::Now();
10702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        double ms = (now - start_time_).InMillisecondsF() / kFrames;
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        LOG(INFO) << "FPS: " << 1000.f / ms << " (" << ms << " ms)";
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        start_time_ = now;
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      }
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (max_frames_ && frames_ == max_frames_) {
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      base::MessageLoop::current()->Quit();
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else {
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      Draw();
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void OnCompositingAborted(Compositor* compositor) OVERRIDE {}
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void OnCompositingLockStateChanged(
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      Compositor* compositor) OVERRIDE {}
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void OnUpdateVSyncParameters(ui::Compositor* compositor,
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                       base::TimeTicks timebase,
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                       base::TimeDelta interval) OVERRIDE {
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void Draw() {}
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  int frames() const { return frames_; }
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private:
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  TimeTicks start_time_;
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  int frames_;
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  int max_frames_;
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BenchCompositorObserver);
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class WebGLTexture : public ui::Texture {
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public:
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  WebGLTexture(WebGraphicsContext3D* context, const gfx::Size& size)
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      : ui::Texture(false, size, 1.0f),
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        context_(context),
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        texture_id_(context_->createTexture()) {
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    context_->bindTexture(GL_TEXTURE_2D, texture_id_);
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    context_->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                         size.width(), size.height(), 0,
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                         GL_RGBA, GL_UNSIGNED_BYTE, NULL);
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual unsigned int PrepareTexture() OVERRIDE {
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return texture_id_;
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual WebGraphicsContext3D* HostContext3D() OVERRIDE {
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return context_;
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private:
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual ~WebGLTexture() {
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    context_->deleteTexture(texture_id_);
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  WebGraphicsContext3D* context_;
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  unsigned texture_id_;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WebGLTexture);
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// A benchmark that adds a texture layer that is updated every frame.
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class WebGLBench : public BenchCompositorObserver {
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public:
179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)  WebGLBench(Layer* parent, Compositor* compositor, int max_frames)
180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)      : BenchCompositorObserver(max_frames),
181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        parent_(parent),
182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        webgl_(ui::LAYER_TEXTURED),
183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        compositor_(compositor),
184926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        context_(),
185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        texture_(),
186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        fbo_(0),
187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        do_draw_(true) {
188926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    CommandLine* command_line = CommandLine::ForCurrentProcess();
189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    do_draw_ = !command_line->HasSwitch("disable-draw");
190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    std::string webgl_size = command_line->GetSwitchValueASCII("webgl-size");
192926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    int width = 0;
193926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    int height = 0;
194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!webgl_size.empty()) {
195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)      std::vector<std::string> split_size;
196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)      base::SplitString(webgl_size, 'x', &split_size);
197926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)      if (split_size.size() == 2) {
198926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        width = atoi(split_size[0].c_str());
199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        height = atoi(split_size[1].c_str());
200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)      }
201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
202926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!width || !height) {
203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)      width = 800;
204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)      height = 600;
205926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
206926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    gfx::Rect bounds(width, height);
207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    webgl_.SetBounds(bounds);
208926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    parent_->Add(&webgl_);
209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
210926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    context_ = ui::ContextFactory::GetInstance()->CreateOffscreenContext();
211926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    context_->makeContextCurrent();
212926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    texture_ = new WebGLTexture(context_.get(), bounds.size());
213926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    fbo_ = context_->createFramebuffer();
214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    compositor->AddObserver(this);
215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    webgl_.SetExternalTexture(texture_.get());
216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    context_->bindFramebuffer(GL_FRAMEBUFFER, fbo_);
217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    context_->framebufferTexture2D(
218926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        GL_TEXTURE_2D, texture_->PrepareTexture(), 0);
220926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    context_->clearColor(0.f, 1.f, 0.f, 1.f);
221926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    context_->clear(GL_COLOR_BUFFER_BIT);
222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    context_->flush();
223926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)  }
224926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
225926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)  virtual ~WebGLBench() {
226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    context_->makeContextCurrent();
227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    context_->deleteFramebuffer(fbo_);
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    webgl_.SetExternalTexture(NULL);
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    texture_ = NULL;
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    compositor_->RemoveObserver(this);
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  }
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void Draw() OVERRIDE {
234c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (do_draw_) {
235      context_->makeContextCurrent();
236      context_->clearColor((frames() % kFrames)*1.0/kFrames, 1.f, 0.f, 1.f);
237      context_->clear(GL_COLOR_BUFFER_BIT);
238      context_->flush();
239    }
240    webgl_.SetExternalTexture(texture_.get());
241    webgl_.SchedulePaint(gfx::Rect(webgl_.bounds().size()));
242    compositor_->ScheduleDraw();
243  }
244
245 private:
246  Layer* parent_;
247  Layer webgl_;
248  Compositor* compositor_;
249  scoped_ptr<WebGraphicsContext3D> context_;
250  scoped_refptr<WebGLTexture> texture_;
251
252  // The FBO that is used to render to the texture.
253  unsigned int fbo_;
254
255  // Whether or not to draw to the texture every frame.
256  bool do_draw_;
257
258  DISALLOW_COPY_AND_ASSIGN(WebGLBench);
259};
260
261// A benchmark that paints (in software) all tiles every frame.
262class SoftwareScrollBench : public BenchCompositorObserver {
263 public:
264  SoftwareScrollBench(ColoredLayer* layer,
265                      Compositor* compositor,
266                      int max_frames)
267      : BenchCompositorObserver(max_frames),
268        layer_(layer),
269        compositor_(compositor) {
270    compositor->AddObserver(this);
271    layer_->set_draw(
272        !CommandLine::ForCurrentProcess()->HasSwitch("disable-draw"));
273  }
274
275  virtual ~SoftwareScrollBench() {
276    compositor_->RemoveObserver(this);
277  }
278
279  virtual void Draw() OVERRIDE {
280    layer_->set_color(
281        SkColorSetARGBInline(255*(frames() % kFrames)/kFrames, 255, 0, 255));
282    layer_->SchedulePaint(gfx::Rect(layer_->bounds().size()));
283  }
284
285 private:
286  ColoredLayer* layer_;
287  Compositor* compositor_;
288
289  DISALLOW_COPY_AND_ASSIGN(SoftwareScrollBench);
290};
291
292}  // namespace
293
294int main(int argc, char** argv) {
295  CommandLine::Init(argc, argv);
296
297  base::AtExitManager exit_manager;
298
299  ui::RegisterPathProvider();
300  icu_util::Initialize();
301  ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL);
302
303  base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);
304  aura::Env::GetInstance();
305  scoped_ptr<aura::TestScreen> test_screen(
306      aura::TestScreen::CreateFullscreen());
307  gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen.get());
308  scoped_ptr<aura::RootWindow> root_window(
309      test_screen->CreateRootWindowForPrimaryDisplay());
310  aura::client::SetCaptureClient(
311      root_window.get(),
312      new aura::client::DefaultCaptureClient(root_window.get()));
313
314  scoped_ptr<aura::client::FocusClient> focus_client(new aura::FocusManager);
315  aura::client::SetFocusClient(root_window.get(), focus_client.get());
316
317  // add layers
318  ColoredLayer background(SK_ColorRED);
319  background.SetBounds(root_window->bounds());
320  root_window->layer()->Add(&background);
321
322  ColoredLayer window(SK_ColorBLUE);
323  window.SetBounds(gfx::Rect(background.bounds().size()));
324  background.Add(&window);
325
326  Layer content_layer(ui::LAYER_NOT_DRAWN);
327
328  CommandLine* command_line = CommandLine::ForCurrentProcess();
329  bool force = command_line->HasSwitch("force-render-surface");
330  content_layer.SetForceRenderSurface(force);
331  gfx::Rect bounds(window.bounds().size());
332  bounds.Inset(0, 30, 0, 0);
333  content_layer.SetBounds(bounds);
334  window.Add(&content_layer);
335
336  ColoredLayer page_background(SK_ColorWHITE);
337  page_background.SetBounds(gfx::Rect(content_layer.bounds().size()));
338  content_layer.Add(&page_background);
339
340  int frames = atoi(command_line->GetSwitchValueASCII("frames").c_str());
341  scoped_ptr<BenchCompositorObserver> bench;
342
343  if (command_line->HasSwitch("bench-software-scroll")) {
344    bench.reset(new SoftwareScrollBench(&page_background,
345                                        root_window->compositor(),
346                                        frames));
347  } else {
348    bench.reset(new WebGLBench(&page_background,
349                               root_window->compositor(),
350                               frames));
351  }
352
353#ifndef NDEBUG
354  ui::PrintLayerHierarchy(root_window->layer(), gfx::Point(100, 100));
355#endif
356
357  root_window->ShowRootWindow();
358  base::MessageLoopForUI::current()->Run();
359  focus_client.reset();
360  root_window.reset();
361
362  return 0;
363}
364