compositor.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/debug/trace_event.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/singleton.h"
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/run_loop.h"
165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/sys_info.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/switches.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/input/input_handler.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/context_provider.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"
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/gfx/frame_time.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const double kDefaultRefreshRate = 60.0;
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const double kTestRefreshRate = 200.0;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum SwapType {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DRAW_SWAP,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  READPIXELS_SWAP,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochbool g_compositor_initialized = false;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::Thread* g_compositor_thread = NULL;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::ContextFactory* g_context_factory = NULL;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCompositorLockTimeoutMs = 67;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PendingSwap {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PendingSwap();
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType type() const { return type_; }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool posted() const { return posted_; }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ui::PostedSwapQueue;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType type_;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool posted_;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::PostedSwapQueue* posted_swaps_;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PendingSwap);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextFactory* ContextFactory::GetInstance() {
75c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_context_factory);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_context_factory;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContextFactory::SetInstance(ContextFactory* instance) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_context_factory = instance;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : size_(size),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      flipped_(flipped),
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_scale_factor_(device_scale_factor) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::~Texture() {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string Texture::Produce() {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return EmptyString();
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::CompositorLock(Compositor* compositor)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : compositor_(compositor) {
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&CompositorLock::CancelLock, AsWeakPtr()),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs));
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::~CompositorLock() {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelLock();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CompositorLock::CancelLock() {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_->UnlockCompositor();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_ = NULL;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::Wait(Compositor* compositor) {
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DrawWaiterForTest waiter;
1195e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  waiter.wait_for_commit_ = false;
1205e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  waiter.WaitImpl(compositor);
1215e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)}
1225e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)
1235e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)// static
1245e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void DrawWaiterForTest::WaitForCommit(Compositor* compositor) {
1255e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  DrawWaiterForTest waiter;
1265e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  waiter.wait_for_commit_ = true;
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  waiter.WaitImpl(compositor);
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DrawWaiterForTest::DrawWaiterForTest() {
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DrawWaiterForTest::~DrawWaiterForTest() {
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::WaitImpl(Compositor* compositor) {
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  compositor->AddObserver(this);
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  wait_run_loop_.reset(new base::RunLoop());
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  wait_run_loop_->Run();
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  compositor->RemoveObserver(this);
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingDidCommit(Compositor* compositor) {
1445e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  if (wait_for_commit_)
1455e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    wait_run_loop_->Quit();
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingStarted(Compositor* compositor,
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             base::TimeTicks start_time) {
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingEnded(Compositor* compositor) {
1535e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  if (!wait_for_commit_)
1545e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)    wait_run_loop_->Quit();
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingAborted(Compositor* compositor) {
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnCompositingLockStateChanged(Compositor* compositor) {
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void DrawWaiterForTest::OnUpdateVSyncParameters(Compositor* compositor,
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                base::TimeTicks timebase,
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                base::TimeDelta interval) {
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PostedSwapQueue {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PostedSwapQueue() : pending_swap_(NULL) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~PostedSwapQueue() {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!pending_swap_);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwapType NextPostedSwap() const {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return queue_.front();
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool AreSwapsPosted() const {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return !queue_.empty();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int NumSwapsPosted(SwapType type) const {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int count = 0;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (std::deque<SwapType>::const_iterator it = queue_.begin();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != queue_.end(); ++it) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (*it == type)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        count++;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return count;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PostSwap() {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(pending_swap_);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    queue_.push_back(pending_swap_->type());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_swap_->posted_ = true;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EndSwap() {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    queue_.pop_front();
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ::PendingSwap;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap* pending_swap_;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::deque<SwapType> queue_;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PostedSwapQueue);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : type_(type), posted_(false), posted_swaps_(posted_swaps) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only one pending swap in flight.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(static_cast<PendingSwap*>(NULL), posted_swaps_->pending_swap_);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->pending_swap_ = this;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::~PendingSwap() {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(this, posted_swaps_->pending_swap_);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->pending_swap_ = NULL;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)Compositor::Compositor(bool use_software_renderer,
2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                       gfx::AcceleratedWidget widget)
2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : root_layer_(NULL),
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_(widget),
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      posted_swaps_(new PostedSwapQueue()),
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_scale_factor_(0.0f),
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_started_frame_(0),
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_ended_frame_(0),
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_(false),
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disable_schedule_composite_(false),
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      compositor_lock_(NULL),
2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      defer_draw_scheduling_(false),
2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      waiting_on_compositing_end_(false),
2478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      draw_on_compositing_end_(false),
2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      schedule_draw_factory_(this),
2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      use_software_renderer_(use_software_renderer) {
250c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized)
251c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      << "Compositor::Initialize must be called before creating a Compositor.";
252c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_ = cc::Layer::Create();
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cc::LayerTreeSettings settings;
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.refresh_rate =
260c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      ContextFactory::GetInstance()->DoesCreateTestContexts()
261c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      ? kTestRefreshRate
262c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      : kDefaultRefreshRate;
26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  settings.deadline_scheduling_enabled =
26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      switches::IsUIDeadlineSchedulingEnabled();
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.partial_swap_enabled =
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.per_tile_painting_enabled =
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIEnablePerTilePainting);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These flags should be mirrored by renderer versions in content/renderer/.
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_debug_borders =
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders);
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_fps_counter =
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_paint_rects =
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(switches::kUIShowPaintRects);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_property_changed_rects =
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowPropertyChangedRects);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_surface_damage_rects =
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowSurfaceDamageRects);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_screen_space_rects =
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowScreenSpaceRects);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_replica_screen_space_rects =
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowReplicaScreenSpaceRects);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_occluding_rects =
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowOccludingRects);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_non_occluding_rects =
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects);
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner =
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      g_compositor_thread ? g_compositor_thread->message_loop_proxy() : NULL;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  host_ =
2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      cc::LayerTreeHost::Create(this, NULL, settings, compositor_task_runner);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetRootLayer(root_web_layer_);
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  host_->SetLayerTreeHostClientReady();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Compositor::~Compositor() {
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("shutdown", "Compositor::destructor");
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
302c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized);
303c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelCompositorLock();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!compositor_lock_);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stop all outstanding draws before telling the ContextFactory to tear
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // down any contexts that the |host_| may rely upon.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_.reset();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ContextFactory::GetInstance()->RemoveCompositor(this);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Initialize() {
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_thread = !CommandLine::ForCurrentProcess()->HasSwitch(
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switches::kUIDisableThreadedCompositing);
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_thread =
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switches::kUIEnableThreadedCompositing) &&
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switches::kUIDisableThreadedCompositing);
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_thread) {
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread = new base::Thread("Browser Compositor");
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Start();
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
333c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
334c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(!g_compositor_initialized) << "Compositor initialized twice.";
335c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  g_compositor_initialized = true;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool Compositor::WasInitializedWithThread() {
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(g_compositor_initialized);
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !!g_compositor_thread;
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<base::MessageLoopProxy> Compositor::GetCompositorMessageLoop() {
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> proxy;
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (g_compositor_thread)
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    proxy = g_compositor_thread->message_loop_proxy();
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return proxy;
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::Terminate() {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread) {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Stop();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete g_compositor_thread;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_compositor_thread = NULL;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
359c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
360c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized) << "Compositor::Initialize() didn't happen.";
361c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  g_compositor_initialized = false;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::ScheduleDraw() {
3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (g_compositor_thread) {
3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    host_->Composite(gfx::FrameTime::Now());
3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else if (!defer_draw_scheduling_) {
3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    defer_draw_scheduling_ = true;
3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        FROM_HERE,
3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr()));
3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetRootLayer(Layer* root_layer) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ == root_layer)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_layer_ = root_layer;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ && !root_layer_->GetCompositor())
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(this);
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->RemoveAllChildren();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->AddChild(root_layer_->cc_layer());
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetHostHasTransparentBackground(
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool host_has_transparent_background) {
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->set_has_transparent_background(host_has_transparent_background);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Draw() {
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  defer_draw_scheduling_ = false;
3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (waiting_on_compositing_end_) {
3988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    draw_on_compositing_end_ = true;
3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  waiting_on_compositing_end_ = true;
4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1);
4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!root_layer_)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_started_frame_++;
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap pending_swap(DRAW_SWAP, posted_swaps_.get());
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsLocked()) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nduca): Temporary while compositor calls
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // compositeImmediately() directly.
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layout();
4141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    host_->Composite(gfx::FrameTime::Now());
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN)
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // While we resize, we are usually a few frames behind. By blocking
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the UI thread here we minize the area that is mis-painted, specially
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // in the non-client area. See RenderWidgetHostViewAura::SetBounds for
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // more details and bug 177115.
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (next_draw_is_resize_ && (last_ended_frame_ > 1)) {
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_ = false;
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_->FinishAllRendering();
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pending_swap.posted())
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyEnd();
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleFullRedraw() {
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetNeedsRedraw();
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetNeedsRedrawRect(damage_rect);
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) {
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host_->SetLatencyInfo(latency_info);
442868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::ReadPixels(SkBitmap* bitmap,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const gfx::Rect& bounds_in_pixel) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_in_pixel.right() > size().width() ||
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bounds_in_pixel.bottom() > size().height())
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap->setConfig(SkBitmap::kARGB_8888_Config,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    bounds_in_pixel.width(), bounds_in_pixel.height());
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap->allocPixels();
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels lock_image(*bitmap);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelCompositorLock();
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap pending_swap(READPIXELS_SWAP, posted_swaps_.get());
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return host_->CompositeAndReadback(pixels, bounds_in_pixel);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(scale, 0);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!size_in_pixel.IsEmpty()) {
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_ = size_in_pixel;
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    host_->SetViewportSize(size_in_pixel);
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->SetBounds(size_in_pixel);
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    next_draw_is_resize_ = true;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (device_scale_factor_ != scale) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_scale_factor_ = scale;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (root_layer_)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      root_layer_->OnDeviceScaleFactorChanged(scale);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetBackgroundColor(SkColor color) {
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->set_background_color(color);
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ScheduleDraw();
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::AddObserver(CompositorObserver* observer) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.AddObserver(observer);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::RemoveObserver(CompositorObserver* observer) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.RemoveObserver(observer);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::HasObserver(CompositorObserver* observer) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return observer_list_.HasObserver(observer);
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersPosted() {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->PostSwap();
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersComplete() {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(posted_swaps_->AreSwapsPosted());
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyEnd();
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->EndSwap();
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersAborted() {
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!g_compositor_thread) {
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // We've just lost the context, so unwind all posted_swaps.
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    while (posted_swaps_->AreSwapsPosted()) {
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        NotifyEnd();
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      posted_swaps_->EndSwap();
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingAborted(this));
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::OnUpdateVSyncParameters(base::TimeTicks timebase,
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         base::TimeDelta interval) {
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    observer_list_,
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnUpdateVSyncParameters(this, timebase, interval));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::Layout() {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're sending damage that will be addressed during this composite
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cycle, so we don't need to schedule another composite to address it.
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = true;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SendDamagedRects();
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = false;
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) {
540558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return ContextFactory::GetInstance()->CreateOutputSurface(this);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommit() {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsLocked());
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingDidCommit(this));
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommitAndDrawFrame() {
5511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::TimeTicks start_time = gfx::FrameTime::Now();
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnCompositingStarted(this, start_time));
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCompleteSwapBuffers() {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(g_compositor_thread);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyEnd();
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::ScheduleComposite() {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!disable_schedule_composite_)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleDraw();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)scoped_refptr<cc::ContextProvider> Compositor::OffscreenContextProvider() {
5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return ContextFactory::GetInstance()->OffscreenCompositorContextProvider();
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return host_->debug_state();
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetLayerTreeDebugState(
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const cc::LayerTreeDebugState& debug_state) {
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetDebugState(debug_state);
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_lock_) {
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_ = new CompositorLock(this);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (g_compositor_thread)
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_->SetDeferCommits(true);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(CompositorObserver,
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      observer_list_,
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnCompositingLockStateChanged(this));
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return compositor_lock_;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::UnlockCompositor() {
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(compositor_lock_);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_lock_ = NULL;
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread)
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->SetDeferCommits(false);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingLockStateChanged(this));
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::CancelCompositorLock() {
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (compositor_lock_)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_->CancelLock();
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::NotifyEnd() {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_ended_frame_++;
6098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_);
6108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  waiting_on_compositing_end_ = false;
6118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (draw_on_compositing_end_) {
6128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    draw_on_compositing_end_ = false;
6138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Call ScheduleDraw() instead of Draw() in order to allow other
6158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // CompositorObservers to be notified before starting another
6168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // draw cycle.
6178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ScheduleDraw();
6188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingEnded(this));
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
625