Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 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 | |
| 5 #include "base/at_exit.h" | |
| 6 #include "base/bind.h" | |
| 7 #include "base/command_line.h" | |
| 8 #include "base/i18n/icu_util.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "base/message_loop.h" | |
| 11 #include "base/string_split.h" | |
| 12 #include "base/time.h" | |
| 13 #include "third_party/skia/include/core/SkXfermode.h" | |
| 14 #include "ui/aura/env.h" | |
| 15 #include "ui/aura/event.h" | |
| 16 #include "ui/aura/root_window.h" | |
| 17 #include "ui/aura/single_monitor_manager.h" | |
| 18 #include "ui/aura/window.h" | |
| 19 #include "ui/base/hit_test.h" | |
| 20 #include "ui/base/resource/resource_bundle.h" | |
| 21 #include "ui/base/ui_base_paths.h" | |
| 22 #include "ui/compositor/compositor.h" | |
| 23 #include "ui/compositor/compositor_observer.h" | |
| 24 #include "ui/compositor/debug_utils.h" | |
| 25 #include "ui/compositor/layer.h" | |
| 26 #include "ui/compositor/test/compositor_test_support.h" | |
| 27 #include "ui/gfx/canvas.h" | |
| 28 #include "ui/gfx/rect.h" | |
| 29 #include "ui/gfx/skia_util.h" | |
| 30 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGraphicsC ontext3D.h" | |
|
sky
2012/05/25 15:30:42
nit: sort
piman
2012/05/25 22:11:28
Done.
| |
| 31 #include "third_party/khronos/GLES2/gl2.h" | |
| 32 #ifndef GL_GLEXT_PROTOTYPES | |
| 33 #define GL_GLEXT_PROTOTYPES 1 | |
| 34 #endif | |
| 35 #include "third_party/khronos/GLES2/gl2ext.h" | |
| 36 | |
| 37 #if defined(USE_X11) | |
| 38 #include "base/message_pump_x.h" | |
| 39 #endif | |
| 40 | |
| 41 using base::TimeTicks; | |
| 42 using ui::Compositor; | |
| 43 using ui::Layer; | |
| 44 using ui::LayerDelegate; | |
| 45 using WebKit::WebGraphicsContext3D; | |
| 46 | |
| 47 namespace { | |
| 48 | |
| 49 class ColoredLayer : public Layer, public LayerDelegate { | |
| 50 public: | |
| 51 explicit ColoredLayer(SkColor color) | |
| 52 : Layer(ui::LAYER_TEXTURED), | |
| 53 color_(color), | |
| 54 draw_(true) { | |
| 55 set_delegate(this); | |
| 56 } | |
| 57 | |
| 58 virtual ~ColoredLayer() { } | |
|
sky
2012/05/25 15:30:42
nit: { } -> {}
piman
2012/05/25 22:11:28
Done.
| |
| 59 | |
| 60 // Overridden from LayerDelegate: | |
| 61 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE { | |
| 62 if (draw_) { | |
| 63 canvas->DrawColor(color_); | |
| 64 } | |
| 65 } | |
| 66 | |
| 67 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE { | |
| 68 } | |
| 69 | |
| 70 void set_color(SkColor color) { color_ = color; } | |
| 71 void set_draw(bool draw) { draw_ = draw; } | |
| 72 | |
| 73 private: | |
| 74 SkColor color_; | |
| 75 bool draw_; | |
| 76 }; | |
|
sky
2012/05/25 15:30:42
DISALLOW_... (here and all classes you're creating
piman
2012/05/25 22:11:28
Done.
| |
| 77 | |
| 78 const int kFrames = 100; | |
| 79 | |
| 80 // Benchmark base class, hooks up drawing callback and displaying FPS. | |
| 81 class BenchCompositorObserver : public ui::CompositorObserver { | |
| 82 public: | |
| 83 explicit BenchCompositorObserver(int max_frames) | |
| 84 : start_time_(), | |
| 85 frames_(0), | |
| 86 max_frames_(max_frames) { | |
| 87 } | |
| 88 virtual void OnCompositingStarted(Compositor* compositor) {} | |
|
sky
2012/05/25 15:30:42
OVERRIDE (here and 90)
piman
2012/05/25 22:11:28
Done.
| |
| 89 | |
| 90 virtual void OnCompositingEnded(Compositor* compositor) { | |
| 91 if (start_time_.is_null()) { | |
| 92 start_time_ = TimeTicks::Now(); | |
| 93 } else { | |
| 94 ++frames_; | |
| 95 if (frames_ % kFrames == 0) { | |
| 96 TimeTicks now = TimeTicks::Now(); | |
| 97 double ms = (now - start_time_).InMillisecondsF() / kFrames; | |
| 98 LOG(INFO) << "FPS: " << 1000.f / ms << " (" << ms << " ms)"; | |
| 99 start_time_ = now; | |
| 100 } | |
| 101 } | |
| 102 if (max_frames_ && frames_ == max_frames_) { | |
| 103 MessageLoop::current()->Quit(); | |
| 104 } else { | |
| 105 MessageLoop::current()->PostTask( | |
|
sky
2012/05/25 15:30:42
Why do you need this? And how to you guarantee thi
piman
2012/05/25 22:11:28
There was a bug that prevented ScheduleDraw from w
| |
| 106 FROM_HERE, | |
| 107 base::Bind(&BenchCompositorObserver::Draw, base::Unretained(this))); | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 virtual void Draw() {} | |
| 112 | |
| 113 int frames() const { return frames_; } | |
| 114 | |
| 115 private: | |
| 116 TimeTicks start_time_; | |
| 117 int frames_; | |
| 118 int max_frames_; | |
| 119 }; | |
| 120 | |
| 121 class WebGLTexture : public ui::Texture { | |
| 122 public: | |
| 123 WebGLTexture(WebGraphicsContext3D* context, const gfx::Size& size) | |
| 124 : ui::Texture(false, size), | |
| 125 context_(context) { | |
| 126 set_texture_id(context_->createTexture()); | |
| 127 context_->bindTexture(GL_TEXTURE_2D, texture_id()); | |
| 128 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 129 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 130 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 131 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 132 context_->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | |
| 133 size.width(), size.height(), 0, | |
| 134 GL_RGBA, GL_UNSIGNED_BYTE, NULL); | |
| 135 } | |
| 136 | |
| 137 virtual ~WebGLTexture() { | |
| 138 context_->deleteTexture(texture_id()); | |
| 139 } | |
| 140 | |
| 141 private: | |
| 142 WebGraphicsContext3D* context_; | |
| 143 }; | |
| 144 | |
| 145 // A benchmark that adds a texture layer that is updated every frame. | |
| 146 class WebGLBench : public BenchCompositorObserver { | |
| 147 public: | |
| 148 WebGLBench(Layer* parent, Compositor* compositor, int max_frames) | |
| 149 : BenchCompositorObserver(max_frames), | |
| 150 parent_(parent), | |
| 151 webgl_(ui::LAYER_TEXTURED), | |
| 152 compositor_(compositor), | |
| 153 context_(), | |
| 154 texture_(), | |
| 155 fbo_(0), | |
| 156 do_draw_(true) { | |
| 157 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 158 do_draw_ = !command_line->HasSwitch("disable-draw"); | |
| 159 | |
| 160 std::string webgl_size = command_line->GetSwitchValueASCII("webgl-size"); | |
| 161 int width = 0; | |
| 162 int height = 0; | |
| 163 if (!webgl_size.empty()) { | |
| 164 std::vector<std::string> split_size; | |
| 165 base::SplitString(webgl_size, 'x', &split_size); | |
| 166 if (split_size.size() == 2) { | |
| 167 width = atoi(split_size[0].c_str()); | |
| 168 height = atoi(split_size[1].c_str()); | |
| 169 } | |
| 170 } | |
| 171 if (!width || !height) { | |
| 172 width = 800; | |
| 173 height = 600; | |
| 174 } | |
| 175 gfx::Rect bounds(width, height); | |
| 176 webgl_.SetBounds(bounds); | |
| 177 parent_->Add(&webgl_); | |
| 178 | |
| 179 context_.reset( | |
| 180 ui::ContextFactory::GetInstance()->CreateOffscreenContext(compositor)); | |
| 181 context_->makeContextCurrent(); | |
| 182 texture_ = new WebGLTexture(context_.get(), bounds.size()); | |
| 183 fbo_ = context_->createFramebuffer(); | |
| 184 compositor->AddObserver(this); | |
| 185 webgl_.SetExternalTexture(texture_); | |
| 186 context_->bindFramebuffer(GL_FRAMEBUFFER, fbo_); | |
| 187 context_->framebufferTexture2D( | |
| 188 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
| 189 GL_TEXTURE_2D, texture_->texture_id(), 0); | |
| 190 context_->clearColor(0.f, 1.f, 0.f, 1.f); | |
| 191 context_->clear(GL_COLOR_BUFFER_BIT); | |
| 192 context_->flush(); | |
| 193 } | |
| 194 | |
| 195 virtual ~WebGLBench() { | |
| 196 context_->makeContextCurrent(); | |
| 197 context_->deleteFramebuffer(fbo_); | |
| 198 webgl_.SetExternalTexture(NULL); | |
| 199 texture_ = NULL; | |
| 200 compositor_->RemoveObserver(this); | |
| 201 } | |
| 202 | |
| 203 virtual void Draw() { | |
|
sky
2012/05/25 15:30:42
OVERRIDE
piman
2012/05/25 22:11:28
Done.
| |
| 204 if (do_draw_) { | |
| 205 context_->makeContextCurrent(); | |
| 206 context_->clearColor((frames() % kFrames)*1.0/kFrames, 1.f, 0.f, 1.f); | |
| 207 context_->clear(GL_COLOR_BUFFER_BIT); | |
| 208 context_->flush(); | |
| 209 } | |
| 210 webgl_.SetExternalTexture(texture_); | |
| 211 webgl_.SchedulePaint(gfx::Rect(webgl_.bounds().size())); | |
| 212 compositor_->ScheduleDraw(); | |
| 213 } | |
| 214 | |
| 215 private: | |
| 216 Layer* parent_; | |
| 217 Layer webgl_; | |
| 218 Compositor* compositor_; | |
| 219 scoped_ptr<WebGraphicsContext3D> context_; | |
| 220 scoped_refptr<WebGLTexture> texture_; | |
| 221 unsigned int fbo_; | |
|
sky
2012/05/25 15:30:42
How about a description of fbo_ and do_draw_ ?
piman
2012/05/25 22:11:28
Done.
| |
| 222 bool do_draw_; | |
| 223 }; | |
| 224 | |
| 225 // A benchmark that paints (in software) all tiles every frame. | |
| 226 class SoftwareScrollBench : public BenchCompositorObserver { | |
| 227 public: | |
| 228 SoftwareScrollBench(ColoredLayer* layer, | |
| 229 Compositor* compositor, | |
| 230 int max_frames) | |
| 231 : BenchCompositorObserver(max_frames), | |
| 232 layer_(layer), | |
| 233 compositor_(compositor) { | |
| 234 compositor->AddObserver(this); | |
| 235 layer_->set_draw( | |
| 236 !CommandLine::ForCurrentProcess()->HasSwitch("disable-draw")); | |
| 237 } | |
| 238 | |
| 239 virtual ~SoftwareScrollBench() { | |
| 240 compositor_->RemoveObserver(this); | |
| 241 } | |
| 242 | |
| 243 virtual void Draw() { | |
| 244 layer_->set_color( | |
| 245 SkColorSetARGBInline(255*(frames() % kFrames)/kFrames, 255, 0, 255)); | |
| 246 layer_->SchedulePaint(gfx::Rect(layer_->bounds().size())); | |
| 247 } | |
| 248 | |
| 249 private: | |
| 250 ColoredLayer* layer_; | |
| 251 Compositor* compositor_; | |
| 252 }; | |
| 253 | |
| 254 } // anonymous namespace | |
| 255 | |
| 256 int main(int argc, char** argv) { | |
| 257 CommandLine::Init(argc, argv); | |
| 258 | |
| 259 base::AtExitManager exit_manager; | |
| 260 | |
| 261 ui::RegisterPathProvider(); | |
| 262 icu_util::Initialize(); | |
| 263 ResourceBundle::InitSharedInstanceWithLocale("en-US", NULL); | |
| 264 | |
| 265 MessageLoop message_loop(MessageLoop::TYPE_UI); | |
| 266 ui::CompositorTestSupport::Initialize(); | |
| 267 aura::SingleMonitorManager* manager = new aura::SingleMonitorManager; | |
| 268 manager->set_use_fullscreen_host_window(true); | |
| 269 aura::Env::GetInstance()->SetMonitorManager(manager); | |
| 270 scoped_ptr<aura::RootWindow> root_window( | |
| 271 aura::MonitorManager::CreateRootWindowForPrimaryMonitor()); | |
| 272 | |
| 273 | |
| 274 // add layers | |
| 275 ColoredLayer background(SK_ColorRED); | |
| 276 background.SetBounds(root_window->bounds()); | |
| 277 root_window->layer()->Add(&background); | |
| 278 | |
| 279 ColoredLayer window(SK_ColorBLUE); | |
| 280 window.SetBounds(gfx::Rect(background.bounds().size())); | |
| 281 background.Add(&window); | |
| 282 | |
| 283 Layer content_layer(ui::LAYER_NOT_DRAWN); | |
| 284 | |
| 285 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 286 bool force = command_line->HasSwitch("force-render-surface"); | |
| 287 content_layer.SetForceRenderSurface(force); | |
| 288 gfx::Rect bounds(window.bounds().size()); | |
| 289 bounds.Inset(0, 30, 0, 0); | |
| 290 content_layer.SetBounds(bounds); | |
| 291 window.Add(&content_layer); | |
| 292 | |
| 293 ColoredLayer page_background(SK_ColorWHITE); | |
| 294 page_background.SetBounds(gfx::Rect(content_layer.bounds().size())); | |
| 295 content_layer.Add(&page_background); | |
| 296 | |
| 297 int frames = atoi(command_line->GetSwitchValueASCII("frames").c_str()); | |
| 298 scoped_ptr<BenchCompositorObserver> bench; | |
| 299 | |
| 300 if (command_line->HasSwitch("bench-software-scroll")) { | |
| 301 bench.reset(new SoftwareScrollBench(&page_background, | |
| 302 root_window->compositor(), | |
| 303 frames)); | |
| 304 } else { | |
| 305 bench.reset(new WebGLBench(&page_background, | |
| 306 root_window->compositor(), | |
| 307 frames)); | |
| 308 } | |
| 309 | |
| 310 #ifndef NDEBUG | |
| 311 ui::PrintLayerHierarchy(root_window->layer(), gfx::Point(100, 100)); | |
| 312 #endif | |
| 313 | |
| 314 root_window->ShowRootWindow(); | |
| 315 MessageLoopForUI::current()->Run(); | |
| 316 root_window.reset(); | |
| 317 | |
| 318 ui::CompositorTestSupport::Terminate(); | |
| 319 | |
| 320 return 0; | |
| 321 } | |
| OLD | NEW |