compositor.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/singleton.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/run_loop.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/string_util.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/switches.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/thread_impl.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/input/input_handler.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/context_provider.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/layer_tree_host.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor_observer.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor_switches.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/dip_util.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/test_web_graphics_context_3d.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_surface.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "webkit/gpu/grcontext_for_webgraphicscontext3d.h"
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/chromeos/chromeos_version.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const double kDefaultRefreshRate = 60.0;
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const double kTestRefreshRate = 200.0;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum SwapType {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DRAW_SWAP,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  READPIXELS_SWAP,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Thread* g_compositor_thread = NULL;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool g_test_compositor_enabled = false;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ui::ContextFactory* g_implicit_factory = NULL;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::ContextFactory* g_context_factory = NULL;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCompositorLockTimeoutMs = 67;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PendingSwap {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PendingSwap();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType type() const { return type_; }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool posted() const { return posted_; }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ui::PostedSwapQueue;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType type_;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool posted_;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::PostedSwapQueue* posted_swaps_;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PendingSwap);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SetupImplicitFactory() {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We leak the implicit factory so that we don't race with the tear down of
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the gl_bindings.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!g_context_factory);
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!g_implicit_factory);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (g_test_compositor_enabled) {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_implicit_factory = new ui::TestContextFactory;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Using DefaultContextFactory";
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ui::DefaultContextFactory> instance(
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ui::DefaultContextFactory());
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (instance->Initialize())
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      g_implicit_factory = instance.release();
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_context_factory = g_implicit_factory;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResetImplicitFactory() {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!g_implicit_factory || g_context_factory != g_implicit_factory)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete g_implicit_factory;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_implicit_factory = NULL;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_context_factory = NULL;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextFactory* ContextFactory::GetInstance() {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!g_context_factory)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetupImplicitFactory();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_context_factory;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContextFactory::SetInstance(ContextFactory* instance) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_context_factory = instance;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ContextProviderFromContextFactory : public cc::ContextProvider {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_refptr<ContextProviderFromContextFactory> Create(
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ContextFactory* factory) {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<ContextProviderFromContextFactory> provider =
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ContextProviderFromContextFactory(factory);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!provider->InitializeOnMainThread())
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return NULL;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return provider;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool BindToCurrentThread() OVERRIDE {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(context3d_);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return context3d_->makeContextCurrent();
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(context3d_);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return context3d_.get();
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual class GrContext* GrContext() OVERRIDE {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(context3d_);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!gr_context_) {
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gr_context_.reset(
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new webkit::gpu::GrContextForWebGraphicsContext3D(context3d_.get()));
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gr_context_->get();
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void VerifyContexts() OVERRIDE {
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(context3d_);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (context3d_->isContextLost()) {
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::AutoLock lock(destroyed_lock_);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      destroyed_ = true;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool DestroyedOnMainThread() OVERRIDE {
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::AutoLock lock(destroyed_lock_);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return destroyed_;
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit ContextProviderFromContextFactory(ContextFactory* factory)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : factory_(factory),
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        destroyed_(false) {}
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~ContextProviderFromContextFactory() {}
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool InitializeOnMainThread() {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (context3d_)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context3d_.reset(factory_->CreateOffscreenContext());
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return !!context3d_;
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ContextFactory* factory_;
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Lock destroyed_lock_;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool destroyed_;
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WebKit::WebGraphicsContext3D> context3d_;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<webkit::gpu::GrContextForWebGraphicsContext3D> gr_context_;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DefaultContextFactory::DefaultContextFactory() {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DefaultContextFactory::~DefaultContextFactory() {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DefaultContextFactory::Initialize() {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gfx::GLSurface::InitializeOneOff() ||
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::GetGLImplementation() == gfx::kGLImplementationNone) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not load the GL bindings";
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)cc::OutputSurface* DefaultContextFactory::CreateOutputSurface(
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Compositor* compositor) {
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new cc::OutputSurface(
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      make_scoped_ptr(CreateContextCommon(compositor, false)));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateOffscreenContext() {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CreateContextCommon(NULL, true);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DefaultContextFactory::OffscreenContextProviderForMainThread() {
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!offscreen_contexts_main_thread_ ||
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !offscreen_contexts_main_thread_->DestroyedOnMainThread()) {
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_contexts_main_thread_ =
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ContextProviderFromContextFactory::Create(this);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (offscreen_contexts_main_thread_ &&
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !offscreen_contexts_main_thread_->BindToCurrentThread())
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      offscreen_contexts_main_thread_ = NULL;
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offscreen_contexts_main_thread_;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DefaultContextFactory::OffscreenContextProviderForCompositorThread() {
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!offscreen_contexts_compositor_thread_ ||
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) {
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_contexts_compositor_thread_ =
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ContextProviderFromContextFactory::Create(this);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offscreen_contexts_compositor_thread_;
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DefaultContextFactory::RemoveCompositor(Compositor* compositor) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateContextCommon(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Compositor* compositor,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool offscreen) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(offscreen || compositor);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKit::WebGraphicsContext3D::Attributes attrs;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attrs.depth = false;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attrs.stencil = false;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attrs.antialias = false;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  attrs.shareResources = true;
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebKit::WebGraphicsContext3D* context =
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      offscreen ?
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      WebGraphicsContext3DInProcessCommandBufferImpl::CreateOffscreenContext(
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          attrs) :
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      WebGraphicsContext3DInProcessCommandBufferImpl::CreateViewContext(
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          attrs, compositor->widget());
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!context)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!offscreen) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context->makeContextCurrent();
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GLContext* gl_context = gfx::GLContext::GetCurrent();
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool vsync = !command_line->HasSwitch(switches::kDisableGpuVsync);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gl_context->SetSwapInterval(vsync ? 1 : 0);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gl_context->ReleaseCurrent(NULL);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestContextFactory::TestContextFactory() {}
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestContextFactory::~TestContextFactory() {}
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)cc::OutputSurface* TestContextFactory::CreateOutputSurface(
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Compositor* compositor) {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new cc::OutputSurface(make_scoped_ptr(CreateOffscreenContext()));
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebKit::WebGraphicsContext3D* TestContextFactory::CreateOffscreenContext() {
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::TestWebGraphicsContext3D* context = new ui::TestWebGraphicsContext3D;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  context->Initialize();
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return context;
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestContextFactory::OffscreenContextProviderForMainThread() {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!offscreen_contexts_main_thread_ ||
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      offscreen_contexts_main_thread_->DestroyedOnMainThread()) {
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_contexts_main_thread_ =
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ContextProviderFromContextFactory::Create(this);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CHECK(offscreen_contexts_main_thread_->BindToCurrentThread());
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offscreen_contexts_main_thread_;
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestContextFactory::OffscreenContextProviderForCompositorThread() {
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!offscreen_contexts_compositor_thread_ ||
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      offscreen_contexts_compositor_thread_->DestroyedOnMainThread()) {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    offscreen_contexts_compositor_thread_ =
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ContextProviderFromContextFactory::Create(this);
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return offscreen_contexts_compositor_thread_;
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestContextFactory::RemoveCompositor(Compositor* compositor) {
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : size_(size),
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flipped_(flipped),
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_scale_factor_(device_scale_factor) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::~Texture() {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string Texture::Produce() {
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return EmptyString();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::CompositorLock(Compositor* compositor)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : compositor_(compositor) {
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&CompositorLock::CancelLock, AsWeakPtr()),
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::~CompositorLock() {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelLock();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CompositorLock::CancelLock() {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_->UnlockCompositor();
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_ = NULL;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::Wait(Compositor* compositor) {
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DrawWaiterForTest waiter;
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  waiter.WaitImpl(compositor);
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DrawWaiterForTest::DrawWaiterForTest() {
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DrawWaiterForTest::~DrawWaiterForTest() {
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::WaitImpl(Compositor* compositor) {
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  compositor->AddObserver(this);
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  wait_run_loop_.reset(new base::RunLoop());
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  wait_run_loop_->Run();
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  compositor->RemoveObserver(this);
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingDidCommit(Compositor* compositor) {
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingStarted(Compositor* compositor,
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             base::TimeTicks start_time) {
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingEnded(Compositor* compositor) {
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  wait_run_loop_->Quit();
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingAborted(Compositor* compositor) {
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingLockStateChanged(Compositor* compositor) {
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnUpdateVSyncParameters(Compositor* compositor,
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                base::TimeTicks timebase,
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                base::TimeDelta interval) {
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PostedSwapQueue {
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostedSwapQueue() : pending_swap_(NULL) {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PostedSwapQueue() {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!pending_swap_);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType NextPostedSwap() const {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return queue_.front();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AreSwapsPosted() const {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return !queue_.empty();
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int NumSwapsPosted(SwapType type) const {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int count = 0;
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (std::deque<SwapType>::const_iterator it = queue_.begin();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != queue_.end(); ++it) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (*it == type)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        count++;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return count;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PostSwap() {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(pending_swap_);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    queue_.push_back(pending_swap_->type());
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_swap_->posted_ = true;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EndSwap() {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    queue_.pop_front();
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ::PendingSwap;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap* pending_swap_;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::deque<SwapType> queue_;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PostedSwapQueue);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : type_(type), posted_(false), posted_swaps_(posted_swaps) {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only one pending swap in flight.
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(static_cast<PendingSwap*>(NULL), posted_swaps_->pending_swap_);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->pending_swap_ = this;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::~PendingSwap() {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(this, posted_swaps_->pending_swap_);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->pending_swap_ = NULL;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Compositor::Compositor(CompositorDelegate* delegate,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       gfx::AcceleratedWidget widget)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : delegate_(delegate),
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      root_layer_(NULL),
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_(widget),
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      posted_swaps_(new PostedSwapQueue()),
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_scale_factor_(0.0f),
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_started_frame_(0),
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_ended_frame_(0),
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_(false),
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disable_schedule_composite_(false),
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      compositor_lock_(NULL) {
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_ = cc::Layer::Create();
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(piman): remove after crbug.com/235302 is fixed.
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  root_web_layer_->SetMasksToBounds(true);
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cc::LayerTreeSettings settings;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.refresh_rate =
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      g_test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate;
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.partial_swap_enabled =
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.per_tile_painting_enabled =
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIEnablePerTilePainting);
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These flags should be mirrored by renderer versions in content/renderer/.
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_debug_borders =
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders);
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_fps_counter =
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_paint_rects =
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(switches::kUIShowPaintRects);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_platform_layer_tree =
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowCompositedLayerTree);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_property_changed_rects =
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowPropertyChangedRects);
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_surface_damage_rects =
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowSurfaceDamageRects);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_screen_space_rects =
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowScreenSpaceRects);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_replica_screen_space_rects =
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowReplicaScreenSpaceRects);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_occluding_rects =
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowOccludingRects);
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_non_occluding_rects =
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<cc::Thread> thread;
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (g_compositor_thread) {
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    thread = cc::ThreadImpl::CreateForDifferentThread(
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        g_compositor_thread->message_loop_proxy());
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_ = cc::LayerTreeHost::Create(this, settings, thread.Pass());
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetRootLayer(root_web_layer_);
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetSurfaceReady();
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Compositor::~Compositor() {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelCompositorLock();
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!compositor_lock_);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't call |CompositorDelegate::ScheduleDraw| from this point.
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = NULL;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stop all outstanding draws before telling the ContextFactory to tear
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // down any contexts that the |host_| may rely upon.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_.reset();
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ContextFactory::GetInstance()->RemoveCompositor(this);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Initialize() {
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_thread = !CommandLine::ForCurrentProcess()->HasSwitch(
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switches::kUIDisableThreadedCompositing);
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_thread =
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switches::kUIEnableThreadedCompositing) &&
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switches::kUIDisableThreadedCompositing);
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_thread) {
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread = new base::Thread("Browser Compositor");
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Start();
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool Compositor::WasInitializedWithThread() {
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !!g_compositor_thread;
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::Terminate() {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread) {
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Stop();
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete g_compositor_thread;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_compositor_thread = NULL;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::ScheduleDraw() {
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (g_compositor_thread)
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->Composite(base::TimeTicks::Now());
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (delegate_)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->ScheduleDraw();
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetRootLayer(Layer* root_layer) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ == root_layer)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_layer_ = root_layer;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ && !root_layer_->GetCompositor())
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(this);
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->RemoveAllChildren();
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->AddChild(root_layer_->cc_layer());
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetHostHasTransparentBackground(
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool host_has_transparent_background) {
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->set_has_transparent_background(host_has_transparent_background);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Draw() {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!root_layer_)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_started_frame_++;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap pending_swap(DRAW_SWAP, posted_swaps_.get());
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsLocked()) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nduca): Temporary while compositor calls
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // compositeImmediately() directly.
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layout();
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->Composite(base::TimeTicks::Now());
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN)
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // While we resize, we are usually a few frames behind. By blocking
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the UI thread here we minize the area that is mis-painted, specially
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // in the non-client area. See RenderWidgetHostViewAura::SetBounds for
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // more details and bug 177115.
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (next_draw_is_resize_ && (last_ended_frame_ > 1)) {
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_ = false;
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_->FinishAllRendering();
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pending_swap.posted())
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyEnd();
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleFullRedraw() {
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetNeedsRedraw();
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetNeedsRedrawRect(damage_rect);
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::ReadPixels(SkBitmap* bitmap,
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const gfx::Rect& bounds_in_pixel) {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_in_pixel.right() > size().width() ||
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bounds_in_pixel.bottom() > size().height())
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap->setConfig(SkBitmap::kARGB_8888_Config,
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    bounds_in_pixel.width(), bounds_in_pixel.height());
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap->allocPixels();
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels lock_image(*bitmap);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelCompositorLock();
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap pending_swap(READPIXELS_SWAP, posted_swaps_.get());
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return host_->CompositeAndReadback(pixels, bounds_in_pixel);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(scale, 0);
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!size_in_pixel.IsEmpty()) {
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_ = size_in_pixel;
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    host_->SetViewportSize(size_in_pixel);
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->SetBounds(size_in_pixel);
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    next_draw_is_resize_ = true;
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (device_scale_factor_ != scale) {
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_scale_factor_ = scale;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (root_layer_)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      root_layer_->OnDeviceScaleFactorChanged(scale);
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetBackgroundColor(SkColor color) {
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->set_background_color(color);
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ScheduleDraw();
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::AddObserver(CompositorObserver* observer) {
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.AddObserver(observer);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::RemoveObserver(CompositorObserver* observer) {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.RemoveObserver(observer);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::HasObserver(CompositorObserver* observer) {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return observer_list_.HasObserver(observer);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersPosted() {
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->PostSwap();
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersComplete() {
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(posted_swaps_->AreSwapsPosted());
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyEnd();
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->EndSwap();
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersAborted() {
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!g_compositor_thread) {
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // We've just lost the context, so unwind all posted_swaps.
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    while (posted_swaps_->AreSwapsPosted()) {
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        NotifyEnd();
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      posted_swaps_->EndSwap();
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingAborted(this));
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::OnUpdateVSyncParameters(base::TimeTicks timebase,
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         base::TimeDelta interval) {
6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    observer_list_,
7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnUpdateVSyncParameters(this, timebase, interval));
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::Layout() {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're sending damage that will be addressed during this composite
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cycle, so we don't need to schedule another composite to address it.
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = true;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SendDamagedRects();
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = false;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface() {
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return make_scoped_ptr(
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ContextFactory::GetInstance()->CreateOutputSurface(this));
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<cc::InputHandlerClient> Compositor::CreateInputHandlerClient() {
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return scoped_ptr<cc::InputHandlerClient>();
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommit() {
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsLocked());
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingDidCommit(this));
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommitAndDrawFrame() {
7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::Now();
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnCompositingStarted(this, start_time));
734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If we're threaded without a swap complete callback, we have to
735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // call DidCompleteSwapBuffersManually.
736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (g_compositor_thread &&
737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !host_->GetRendererCapabilities().using_swap_complete_callback)
738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DidCompleteSwapBuffers();
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCompleteSwapBuffers() {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(g_compositor_thread);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyEnd();
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::ScheduleComposite() {
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!disable_schedule_composite_)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleDraw();
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Compositor::OffscreenContextProviderForMainThread() {
7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ContextFactory::GetInstance()->OffscreenContextProviderForMainThread();
7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<cc::ContextProvider>
7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Compositor::OffscreenContextProviderForCompositorThread() {
7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ContextFactory::GetInstance()->
7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OffscreenContextProviderForCompositorThread();
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return host_->debug_state();
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetLayerTreeDebugState(
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const cc::LayerTreeDebugState& debug_state) {
768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetDebugState(debug_state);
769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_lock_) {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_ = new CompositorLock(this);
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (g_compositor_thread)
7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_->SetDeferCommits(true);
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(CompositorObserver,
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      observer_list_,
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnCompositingLockStateChanged(this));
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return compositor_lock_;
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::UnlockCompositor() {
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(compositor_lock_);
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_lock_ = NULL;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread)
7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->SetDeferCommits(false);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingLockStateChanged(this));
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::CancelCompositorLock() {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (compositor_lock_)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_->CancelLock();
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::NotifyEnd() {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_ended_frame_++;
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingEnded(this));
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPOSITOR_EXPORT void SetupTestCompositor() {
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CommandLine::ForCurrentProcess()->HasSwitch(
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisableTestCompositor)) {
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_test_compositor_enabled = true;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the test is running on the chromeos envrionment (such as
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // device or vm bots), use the real compositor.
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::chromeos::IsRunningOnChromeOS())
8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_test_compositor_enabled = false;
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetImplicitFactory();
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPOSITOR_EXPORT void DisableTestCompositor() {
8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResetImplicitFactory();
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_test_compositor_enabled = false;
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPOSITOR_EXPORT bool IsTestCompositorEnabled() {
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return g_test_compositor_enabled;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
829