compositor.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/metrics/histogram.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/run_loop.h"
175e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/sys_info.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "cc/base/latency_info_swap_promise.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/switches.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/input/input_handler.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/context_provider.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"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/compositor_vsync_manager.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/dip_util.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/gfx/frame_time.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const double kDefaultRefreshRate = 60.0;
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const double kTestRefreshRate = 200.0;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum SwapType {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DRAW_SWAP,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochbool g_compositor_initialized = false;
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Thread* g_compositor_thread = NULL;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::ContextFactory* g_context_factory = NULL;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCompositorLockTimeoutMs = 67;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PendingSwap {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PendingSwap();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType type() const { return type_; }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool posted() const { return posted_; }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ui::PostedSwapQueue;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType type_;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool posted_;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::PostedSwapQueue* posted_swaps_;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PendingSwap);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextFactory* ContextFactory::GetInstance() {
77c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_context_factory);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_context_factory;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContextFactory::SetInstance(ContextFactory* instance) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_context_factory = instance;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : size_(size),
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flipped_(flipped),
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_scale_factor_(device_scale_factor) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::~Texture() {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gpu::Mailbox Texture::Produce() {
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return gpu::Mailbox();
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::CompositorLock(Compositor* compositor)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : compositor_(compositor) {
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&CompositorLock::CancelLock, AsWeakPtr()),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::~CompositorLock() {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelLock();
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CompositorLock::CancelLock() {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_->UnlockCompositor();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_ = NULL;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PostedSwapQueue {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostedSwapQueue() : pending_swap_(NULL) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PostedSwapQueue() {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!pending_swap_);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType NextPostedSwap() const {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return queue_.front();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AreSwapsPosted() const {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return !queue_.empty();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int NumSwapsPosted(SwapType type) const {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int count = 0;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (std::deque<SwapType>::const_iterator it = queue_.begin();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != queue_.end(); ++it) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (*it == type)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        count++;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return count;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PostSwap() {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(pending_swap_);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    queue_.push_back(pending_swap_->type());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_swap_->posted_ = true;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EndSwap() {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    queue_.pop_front();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ::PendingSwap;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap* pending_swap_;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::deque<SwapType> queue_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PostedSwapQueue);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : type_(type), posted_(false), posted_swaps_(posted_swaps) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only one pending swap in flight.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(static_cast<PendingSwap*>(NULL), posted_swaps_->pending_swap_);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->pending_swap_ = this;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::~PendingSwap() {
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(this, posted_swaps_->pending_swap_);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->pending_swap_ = NULL;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)Compositor::Compositor(gfx::AcceleratedWidget widget)
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : root_layer_(NULL),
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_(widget),
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      vsync_manager_(new CompositorVSyncManager()),
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      posted_swaps_(new PostedSwapQueue()),
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_scale_factor_(0.0f),
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_started_frame_(0),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_ended_frame_(0),
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_(false),
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disable_schedule_composite_(false),
1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      compositor_lock_(NULL),
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      defer_draw_scheduling_(false),
1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      waiting_on_compositing_end_(false),
1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      draw_on_compositing_end_(false),
1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      schedule_draw_factory_(this) {
199c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized)
200c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      << "Compositor::Initialize must be called before creating a Compositor.";
201c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_ = cc::Layer::Create();
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cc::LayerTreeSettings settings;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.refresh_rate =
209c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      ContextFactory::GetInstance()->DoesCreateTestContexts()
210c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      ? kTestRefreshRate
211c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      : kDefaultRefreshRate;
21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  settings.deadline_scheduling_enabled =
21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      switches::IsUIDeadlineSchedulingEnabled();
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.partial_swap_enabled =
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.per_tile_painting_enabled =
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIEnablePerTilePainting);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These flags should be mirrored by renderer versions in content/renderer/.
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_debug_borders =
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_fps_counter =
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  settings.initial_debug_state.show_layer_animation_bounds_rects =
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowLayerAnimationBounds);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_paint_rects =
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(switches::kUIShowPaintRects);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_property_changed_rects =
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowPropertyChangedRects);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_surface_damage_rects =
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowSurfaceDamageRects);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_screen_space_rects =
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowScreenSpaceRects);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_replica_screen_space_rects =
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowReplicaScreenSpaceRects);
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_occluding_rects =
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowOccludingRects);
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_non_occluding_rects =
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects);
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  settings.initial_debug_state.SetRecordRenderingStats(
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::TimeTicks before_create = base::TimeTicks::Now();
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!!g_compositor_thread) {
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_ = cc::LayerTreeHost::CreateThreaded(
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        this, NULL, settings, g_compositor_thread->message_loop_proxy());
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_ = cc::LayerTreeHost::CreateSingleThreaded(this, this, NULL, settings);
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor",
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      base::TimeTicks::Now() - before_create);
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetRootLayer(root_web_layer_);
254b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  host_->SetLayerTreeHostClientReady();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Compositor::~Compositor() {
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("shutdown", "Compositor::destructor");
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
260c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized);
261c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelCompositorLock();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!compositor_lock_);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stop all outstanding draws before telling the ContextFactory to tear
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // down any contexts that the |host_| may rely upon.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_.reset();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ContextFactory::GetInstance()->RemoveCompositor(this);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Initialize() {
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_thread = !CommandLine::ForCurrentProcess()->HasSwitch(
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switches::kUIDisableThreadedCompositing);
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool use_thread = false;
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_thread) {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread = new base::Thread("Browser Compositor");
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Start();
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
287c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
288c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(!g_compositor_initialized) << "Compositor initialized twice.";
289c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  g_compositor_initialized = true;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool Compositor::WasInitializedWithThread() {
2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(g_compositor_initialized);
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !!g_compositor_thread;
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<base::MessageLoopProxy> Compositor::GetCompositorMessageLoop() {
300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> proxy;
301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (g_compositor_thread)
302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    proxy = g_compositor_thread->message_loop_proxy();
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return proxy;
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::Terminate() {
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread) {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Stop();
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete g_compositor_thread;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_compositor_thread = NULL;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
313c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
314c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized) << "Compositor::Initialize() didn't happen.";
315c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  g_compositor_initialized = false;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::ScheduleDraw() {
3198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (g_compositor_thread) {
3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    host_->Composite(gfx::FrameTime::Now());
3218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else if (!defer_draw_scheduling_) {
3228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    defer_draw_scheduling_ = true;
3238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
3248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        FROM_HERE,
3258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr()));
3268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetRootLayer(Layer* root_layer) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ == root_layer)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_layer_ = root_layer;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ && !root_layer_->GetCompositor())
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(this);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->RemoveAllChildren();
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->AddChild(root_layer_->cc_layer());
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetHostHasTransparentBackground(
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool host_has_transparent_background) {
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->set_has_transparent_background(host_has_transparent_background);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Draw() {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  defer_draw_scheduling_ = false;
3518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (waiting_on_compositing_end_) {
3528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    draw_on_compositing_end_ = true;
3538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  waiting_on_compositing_end_ = true;
3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1);
3588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!root_layer_)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_started_frame_++;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap pending_swap(DRAW_SWAP, posted_swaps_.get());
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsLocked()) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nduca): Temporary while compositor calls
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // compositeImmediately() directly.
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layout();
3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    host_->Composite(gfx::FrameTime::Now());
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN)
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // While we resize, we are usually a few frames behind. By blocking
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the UI thread here we minize the area that is mis-painted, specially
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // in the non-client area. See RenderWidgetHostViewAura::SetBounds for
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // more details and bug 177115.
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (next_draw_is_resize_ && (last_ended_frame_ > 1)) {
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_ = false;
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_->FinishAllRendering();
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pending_swap.posted())
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyEnd();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleFullRedraw() {
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetNeedsRedraw();
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetNeedsRedrawRect(damage_rect);
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) {
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<cc::SwapPromise> swap_promise(
396a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new cc::LatencyInfoSwapPromise(latency_info));
397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  host_->QueueSwapPromise(swap_promise.Pass());
398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(scale, 0);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!size_in_pixel.IsEmpty()) {
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_ = size_in_pixel;
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    host_->SetViewportSize(size_in_pixel);
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->SetBounds(size_in_pixel);
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    next_draw_is_resize_ = true;
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (device_scale_factor_ != scale) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_scale_factor_ = scale;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (root_layer_)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      root_layer_->OnDeviceScaleFactorChanged(scale);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetBackgroundColor(SkColor color) {
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->set_background_color(color);
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ScheduleDraw();
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_refptr<CompositorVSyncManager> Compositor::vsync_manager() const {
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return vsync_manager_;
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::AddObserver(CompositorObserver* observer) {
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.AddObserver(observer);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::RemoveObserver(CompositorObserver* observer) {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.RemoveObserver(observer);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::HasObserver(CompositorObserver* observer) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return observer_list_.HasObserver(observer);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::Layout() {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're sending damage that will be addressed during this composite
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cycle, so we don't need to schedule another composite to address it.
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = true;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SendDamagedRects();
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = false;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) {
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return ContextFactory::GetInstance()->CreateOutputSurface(this, fallback);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommit() {
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsLocked());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingDidCommit(this));
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommitAndDrawFrame() {
4581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::TimeTicks start_time = gfx::FrameTime::Now();
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnCompositingStarted(this, start_time));
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCompleteSwapBuffers() {
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (g_compositor_thread) {
466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NotifyEnd();
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } else {
468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(posted_swaps_->AreSwapsPosted());
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NotifyEnd();
472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    posted_swaps_->EndSwap();
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<cc::ContextProvider> Compositor::OffscreenContextProvider() {
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return ContextFactory::GetInstance()->OffscreenCompositorContextProvider();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::ScheduleComposite() {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!disable_schedule_composite_)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleDraw();
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void Compositor::ScheduleAnimation() {
486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ScheduleComposite();
487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void Compositor::DidPostSwapBuffers() {
490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(!g_compositor_thread);
491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  posted_swaps_->PostSwap();
492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void Compositor::DidAbortSwapBuffers() {
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!g_compositor_thread) {
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // We've just lost the context, so unwind all posted_swaps.
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    while (posted_swaps_->AreSwapsPosted()) {
500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        NotifyEnd();
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      posted_swaps_->EndSwap();
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    observer_list_,
508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    OnCompositingAborted(this));
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return host_->debug_state();
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetLayerTreeDebugState(
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const cc::LayerTreeDebugState& debug_state) {
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetDebugState(debug_state);
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_lock_) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_ = new CompositorLock(this);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (g_compositor_thread)
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_->SetDeferCommits(true);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(CompositorObserver,
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      observer_list_,
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnCompositingLockStateChanged(this));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return compositor_lock_;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::UnlockCompositor() {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(compositor_lock_);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_lock_ = NULL;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread)
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->SetDeferCommits(false);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingLockStateChanged(this));
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::CancelCompositorLock() {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (compositor_lock_)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_->CancelLock();
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::NotifyEnd() {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_ended_frame_++;
5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_);
5508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  waiting_on_compositing_end_ = false;
5518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (draw_on_compositing_end_) {
5528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    draw_on_compositing_end_ = false;
5538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Call ScheduleDraw() instead of Draw() in order to allow other
5558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // CompositorObservers to be notified before starting another
5568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // draw cycle.
5578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ScheduleDraw();
5588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingEnded(this));
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
565