compositor.cc revision 58537e28ecd584eab876aee8be7156509866d23a
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/debug/trace_event.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/singleton.h"
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/run_loop.h"
165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/switches.h"
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "cc/debug/test_context_provider.h"
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "cc/debug/test_web_graphics_context_3d.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/input/input_handler.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/context_provider.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor_observer.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor_switches.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/dip_util.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/compositor/reflector.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_surface.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h"
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "webkit/common/gpu/context_provider_in_process.h"
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/gpu/grcontext_for_webgraphicscontext3d.h"
3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/common/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/chromeos/chromeos_version.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const double kDefaultRefreshRate = 60.0;
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const double kTestRefreshRate = 200.0;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum SwapType {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DRAW_SWAP,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  READPIXELS_SWAP,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochbool g_compositor_initialized = false;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Thread* g_compositor_thread = NULL;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::ContextFactory* g_implicit_factory = NULL;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::ContextFactory* g_context_factory = NULL;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCompositorLockTimeoutMs = 67;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PendingSwap {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PendingSwap();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType type() const { return type_; }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool posted() const { return posted_; }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ui::PostedSwapQueue;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType type_;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool posted_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::PostedSwapQueue* posted_swaps_;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PendingSwap);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextFactory* ContextFactory::GetInstance() {
87c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_context_factory);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_context_factory;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContextFactory::SetInstance(ContextFactory* instance) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_context_factory = instance;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DefaultContextFactory::DefaultContextFactory() {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DefaultContextFactory::~DefaultContextFactory() {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DefaultContextFactory::Initialize() {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gfx::GLSurface::InitializeOneOff() ||
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not load the GL bindings";
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<cc::OutputSurface> DefaultContextFactory::CreateOutputSurface(
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Compositor* compositor) {
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  WebKit::WebGraphicsContext3D::Attributes attrs;
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  attrs.depth = false;
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  attrs.stencil = false;
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  attrs.antialias = false;
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  attrs.shareResources = true;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context3d(
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      WebGraphicsContext3DInProcessCommandBufferImpl::CreateViewContext(
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          attrs, compositor->widget()));
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(context3d);
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  using webkit::gpu::ContextProviderInProcess;
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<ContextProviderInProcess> context_provider =
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ContextProviderInProcess::Create(context3d.Pass());
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return make_scoped_ptr(new cc::OutputSurface(context_provider));
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<Reflector> DefaultContextFactory::CreateReflector(
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Compositor* mirroed_compositor,
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Layer* mirroring_layer) {
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return NULL;
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void DefaultContextFactory::RemoveReflector(
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    scoped_refptr<Reflector> reflector) {
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DefaultContextFactory::OffscreenContextProviderForMainThread() {
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!offscreen_contexts_main_thread_.get() ||
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !offscreen_contexts_main_thread_->DestroyedOnMainThread()) {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_contexts_main_thread_ =
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        webkit::gpu::ContextProviderInProcess::CreateOffscreen();
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (offscreen_contexts_main_thread_.get() &&
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !offscreen_contexts_main_thread_->BindToCurrentThread())
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      offscreen_contexts_main_thread_ = NULL;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offscreen_contexts_main_thread_;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DefaultContextFactory::OffscreenContextProviderForCompositorThread() {
157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!offscreen_contexts_compositor_thread_.get() ||
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) {
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_contexts_compositor_thread_ =
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        webkit::gpu::ContextProviderInProcess::CreateOffscreen();
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offscreen_contexts_compositor_thread_;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DefaultContextFactory::RemoveCompositor(Compositor* compositor) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
168c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochbool DefaultContextFactory::DoesCreateTestContexts() { return false; }
169c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestContextFactory::TestContextFactory() {}
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestContextFactory::~TestContextFactory() {}
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
174558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<cc::OutputSurface> TestContextFactory::CreateOutputSurface(
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Compositor* compositor) {
1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return make_scoped_ptr(
1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new cc::OutputSurface(cc::TestContextProvider::Create()));
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<Reflector> TestContextFactory::CreateReflector(
181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Compositor* mirrored_compositor,
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    Layer* mirroring_layer) {
183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return new Reflector();
184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void TestContextFactory::RemoveReflector(scoped_refptr<Reflector> reflector) {
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestContextFactory::OffscreenContextProviderForMainThread() {
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!offscreen_contexts_main_thread_.get() ||
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      offscreen_contexts_main_thread_->DestroyedOnMainThread()) {
1933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    offscreen_contexts_main_thread_ = cc::TestContextProvider::Create();
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK(offscreen_contexts_main_thread_->BindToCurrentThread());
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offscreen_contexts_main_thread_;
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestContextFactory::OffscreenContextProviderForCompositorThread() {
201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!offscreen_contexts_compositor_thread_.get() ||
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) {
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    offscreen_contexts_compositor_thread_ = cc::TestContextProvider::Create();
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offscreen_contexts_compositor_thread_;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestContextFactory::RemoveCompositor(Compositor* compositor) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
211c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochbool TestContextFactory::DoesCreateTestContexts() { return true; }
212c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : size_(size),
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flipped_(flipped),
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_scale_factor_(device_scale_factor) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::~Texture() {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string Texture::Produce() {
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return EmptyString();
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::CompositorLock(Compositor* compositor)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : compositor_(compositor) {
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&CompositorLock::CancelLock, AsWeakPtr()),
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs));
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::~CompositorLock() {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelLock();
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CompositorLock::CancelLock() {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_->UnlockCompositor();
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_ = NULL;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::Wait(Compositor* compositor) {
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DrawWaiterForTest waiter;
2485e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  waiter.wait_for_commit_ = false;
2495e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  waiter.WaitImpl(compositor);
2505e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)}
2515e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
2525e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// static
2535e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void DrawWaiterForTest::WaitForCommit(Compositor* compositor) {
2545e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  DrawWaiterForTest waiter;
2555e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  waiter.wait_for_commit_ = true;
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  waiter.WaitImpl(compositor);
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DrawWaiterForTest::DrawWaiterForTest() {
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DrawWaiterForTest::~DrawWaiterForTest() {
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::WaitImpl(Compositor* compositor) {
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  compositor->AddObserver(this);
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  wait_run_loop_.reset(new base::RunLoop());
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  wait_run_loop_->Run();
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  compositor->RemoveObserver(this);
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingDidCommit(Compositor* compositor) {
2735e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  if (wait_for_commit_)
2745e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    wait_run_loop_->Quit();
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingStarted(Compositor* compositor,
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             base::TimeTicks start_time) {
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingEnded(Compositor* compositor) {
2825e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  if (!wait_for_commit_)
2835e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    wait_run_loop_->Quit();
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingAborted(Compositor* compositor) {
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingLockStateChanged(Compositor* compositor) {
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnUpdateVSyncParameters(Compositor* compositor,
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                base::TimeTicks timebase,
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                base::TimeDelta interval) {
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PostedSwapQueue {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostedSwapQueue() : pending_swap_(NULL) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PostedSwapQueue() {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!pending_swap_);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType NextPostedSwap() const {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return queue_.front();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AreSwapsPosted() const {
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return !queue_.empty();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int NumSwapsPosted(SwapType type) const {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int count = 0;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (std::deque<SwapType>::const_iterator it = queue_.begin();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != queue_.end(); ++it) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (*it == type)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        count++;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return count;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PostSwap() {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(pending_swap_);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    queue_.push_back(pending_swap_->type());
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_swap_->posted_ = true;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EndSwap() {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    queue_.pop_front();
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ::PendingSwap;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap* pending_swap_;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::deque<SwapType> queue_;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PostedSwapQueue);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : type_(type), posted_(false), posted_swaps_(posted_swaps) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only one pending swap in flight.
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(static_cast<PendingSwap*>(NULL), posted_swaps_->pending_swap_);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->pending_swap_ = this;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::~PendingSwap() {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(this, posted_swaps_->pending_swap_);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->pending_swap_ = NULL;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Compositor::Compositor(CompositorDelegate* delegate,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       gfx::AcceleratedWidget widget)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : delegate_(delegate),
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      root_layer_(NULL),
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_(widget),
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      posted_swaps_(new PostedSwapQueue()),
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_scale_factor_(0.0f),
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_started_frame_(0),
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_ended_frame_(0),
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_(false),
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disable_schedule_composite_(false),
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      compositor_lock_(NULL) {
375c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized)
376c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      << "Compositor::Initialize must be called before creating a Compositor.";
377c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_ = cc::Layer::Create();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cc::LayerTreeSettings settings;
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.refresh_rate =
385c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      ContextFactory::GetInstance()->DoesCreateTestContexts()
386c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      ? kTestRefreshRate
387c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      : kDefaultRefreshRate;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.partial_swap_enabled =
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.per_tile_painting_enabled =
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIEnablePerTilePainting);
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These flags should be mirrored by renderer versions in content/renderer/.
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_debug_borders =
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders);
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_fps_counter =
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_paint_rects =
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(switches::kUIShowPaintRects);
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_property_changed_rects =
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowPropertyChangedRects);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_surface_damage_rects =
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowSurfaceDamageRects);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_screen_space_rects =
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowScreenSpaceRects);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_replica_screen_space_rects =
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowReplicaScreenSpaceRects);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_occluding_rects =
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowOccludingRects);
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_non_occluding_rects =
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner =
414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      g_compositor_thread ? g_compositor_thread->message_loop_proxy() : NULL;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  host_ = cc::LayerTreeHost::Create(this, settings, compositor_task_runner);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetRootLayer(root_web_layer_);
418b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  host_->SetLayerTreeHostClientReady();
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Compositor::~Compositor() {
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("shutdown", "Compositor::destructor");
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
424c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized);
425c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelCompositorLock();
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!compositor_lock_);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't call |CompositorDelegate::ScheduleDraw| from this point.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = NULL;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stop all outstanding draws before telling the ContextFactory to tear
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // down any contexts that the |host_| may rely upon.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_.reset();
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ContextFactory::GetInstance()->RemoveCompositor(this);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
442c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochvoid Compositor::InitializeContextFactoryForTests(bool allow_test_contexts) {
443c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(!g_context_factory) << "ContextFactory already initialized.";
444c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(!g_implicit_factory) <<
445c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      "ContextFactory for tests already initialized.";
446c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
447c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  bool use_test_contexts = true;
448c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
449c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // Always use test contexts unless the disable command line flag is used.
450c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  CommandLine* command_line = CommandLine::ForCurrentProcess();
451c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  if (command_line->HasSwitch(switches::kDisableTestCompositor))
452c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    use_test_contexts = false;
453c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
454c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#if defined(OS_CHROMEOS)
455c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // If the test is running on the chromeos envrionment (such as
456c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // device or vm bots), always use real contexts.
457c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  if (base::chromeos::IsRunningOnChromeOS())
458c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    use_test_contexts = false;
459c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch#endif
460c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
461c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  if (!allow_test_contexts)
462c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    use_test_contexts = false;
463c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
464c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  if (use_test_contexts) {
465c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    g_implicit_factory = new ui::TestContextFactory;
466c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  } else {
467c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    DVLOG(1) << "Using DefaultContextFactory";
468c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    scoped_ptr<ui::DefaultContextFactory> instance(
469c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        new ui::DefaultContextFactory());
470c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    if (instance->Initialize())
471c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      g_implicit_factory = instance.release();
472c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  }
473c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  g_context_factory = g_implicit_factory;
474c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch}
475c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
476c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch// static
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Initialize() {
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_thread = !CommandLine::ForCurrentProcess()->HasSwitch(
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switches::kUIDisableThreadedCompositing);
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_thread =
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switches::kUIEnableThreadedCompositing) &&
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switches::kUIDisableThreadedCompositing);
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_thread) {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread = new base::Thread("Browser Compositor");
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Start();
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
492c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
493c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(!g_compositor_initialized) << "Compositor initialized twice.";
494c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  g_compositor_initialized = true;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool Compositor::WasInitializedWithThread() {
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !!g_compositor_thread;
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
503868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<base::MessageLoopProxy> Compositor::GetCompositorMessageLoop() {
504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> proxy;
505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (g_compositor_thread)
506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    proxy = g_compositor_thread->message_loop_proxy();
507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return proxy;
508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
509868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
510868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::Terminate() {
512c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  if (g_context_factory) {
513c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    if (g_implicit_factory) {
514c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      delete g_implicit_factory;
515c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      g_implicit_factory = NULL;
516c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    }
517c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    g_context_factory = NULL;
518c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  }
519c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread) {
521c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch    DCHECK(!g_context_factory)
522c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        << "The ContextFactory should not outlive the compositor thread.";
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Stop();
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete g_compositor_thread;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_compositor_thread = NULL;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
527c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
528c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized) << "Compositor::Initialize() didn't happen.";
529c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  g_compositor_initialized = false;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::ScheduleDraw() {
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (g_compositor_thread)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->Composite(base::TimeTicks::Now());
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (delegate_)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->ScheduleDraw();
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetRootLayer(Layer* root_layer) {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ == root_layer)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_layer_ = root_layer;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ && !root_layer_->GetCompositor())
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(this);
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->RemoveAllChildren();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->AddChild(root_layer_->cc_layer());
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetHostHasTransparentBackground(
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool host_has_transparent_background) {
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->set_has_transparent_background(host_has_transparent_background);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Draw() {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!root_layer_)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_started_frame_++;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap pending_swap(DRAW_SWAP, posted_swaps_.get());
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsLocked()) {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nduca): Temporary while compositor calls
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // compositeImmediately() directly.
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layout();
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->Composite(base::TimeTicks::Now());
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN)
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // While we resize, we are usually a few frames behind. By blocking
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the UI thread here we minize the area that is mis-painted, specially
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // in the non-client area. See RenderWidgetHostViewAura::SetBounds for
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // more details and bug 177115.
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (next_draw_is_resize_ && (last_ended_frame_ > 1)) {
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_ = false;
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_->FinishAllRendering();
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pending_swap.posted())
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyEnd();
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleFullRedraw() {
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetNeedsRedraw();
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetNeedsRedrawRect(damage_rect);
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) {
596868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host_->SetLatencyInfo(latency_info);
597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::ReadPixels(SkBitmap* bitmap,
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const gfx::Rect& bounds_in_pixel) {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_in_pixel.right() > size().width() ||
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bounds_in_pixel.bottom() > size().height())
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap->setConfig(SkBitmap::kARGB_8888_Config,
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    bounds_in_pixel.width(), bounds_in_pixel.height());
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap->allocPixels();
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels lock_image(*bitmap);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelCompositorLock();
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap pending_swap(READPIXELS_SWAP, posted_swaps_.get());
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return host_->CompositeAndReadback(pixels, bounds_in_pixel);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(scale, 0);
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!size_in_pixel.IsEmpty()) {
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_ = size_in_pixel;
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    host_->SetViewportSize(size_in_pixel);
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->SetBounds(size_in_pixel);
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    next_draw_is_resize_ = true;
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (device_scale_factor_ != scale) {
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_scale_factor_ = scale;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (root_layer_)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      root_layer_->OnDeviceScaleFactorChanged(scale);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetBackgroundColor(SkColor color) {
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->set_background_color(color);
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ScheduleDraw();
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::AddObserver(CompositorObserver* observer) {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.AddObserver(observer);
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::RemoveObserver(CompositorObserver* observer) {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.RemoveObserver(observer);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::HasObserver(CompositorObserver* observer) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return observer_list_.HasObserver(observer);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersPosted() {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->PostSwap();
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersComplete() {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(posted_swaps_->AreSwapsPosted());
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyEnd();
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->EndSwap();
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersAborted() {
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!g_compositor_thread) {
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // We've just lost the context, so unwind all posted_swaps.
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    while (posted_swaps_->AreSwapsPosted()) {
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        NotifyEnd();
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      posted_swaps_->EndSwap();
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingAborted(this));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::OnUpdateVSyncParameters(base::TimeTicks timebase,
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         base::TimeDelta interval) {
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    observer_list_,
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnUpdateVSyncParameters(this, timebase, interval));
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::Layout() {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're sending damage that will be addressed during this composite
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cycle, so we don't need to schedule another composite to address it.
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = true;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SendDamagedRects();
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = false;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
694a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) {
695558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return ContextFactory::GetInstance()->CreateOutputSurface(this);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommit() {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsLocked());
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingDidCommit(this));
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommitAndDrawFrame() {
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::Now();
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
7092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnCompositingStarted(this, start_time));
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCompleteSwapBuffers() {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(g_compositor_thread);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyEnd();
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::ScheduleComposite() {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!disable_schedule_composite_)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleDraw();
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Compositor::OffscreenContextProviderForMainThread() {
7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ContextFactory::GetInstance()->OffscreenContextProviderForMainThread();
7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Compositor::OffscreenContextProviderForCompositorThread() {
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ContextFactory::GetInstance()->
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OffscreenContextProviderForCompositorThread();
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return host_->debug_state();
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetLayerTreeDebugState(
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const cc::LayerTreeDebugState& debug_state) {
739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetDebugState(debug_state);
740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_lock_) {
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_ = new CompositorLock(this);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (g_compositor_thread)
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_->SetDeferCommits(true);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(CompositorObserver,
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      observer_list_,
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnCompositingLockStateChanged(this));
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return compositor_lock_;
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::UnlockCompositor() {
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(compositor_lock_);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_lock_ = NULL;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread)
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->SetDeferCommits(false);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingLockStateChanged(this));
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::CancelCompositorLock() {
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (compositor_lock_)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_->CancelLock();
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::NotifyEnd() {
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_ended_frame_++;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingEnded(this));
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
777