compositor.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
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)
2340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)Compositor::Compositor(gfx::AcceleratedWidget widget)
2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : root_layer_(NULL),
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      widget_(widget),
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      posted_swaps_(new PostedSwapQueue()),
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      device_scale_factor_(0.0f),
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_started_frame_(0),
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_ended_frame_(0),
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_(false),
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disable_schedule_composite_(false),
2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      compositor_lock_(NULL),
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      defer_draw_scheduling_(false),
2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      waiting_on_compositing_end_(false),
2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      draw_on_compositing_end_(false),
2470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      schedule_draw_factory_(this) {
248c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized)
249c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      << "Compositor::Initialize must be called before creating a Compositor.";
250c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_ = cc::Layer::Create();
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->SetAnchorPoint(gfx::PointF(0.f, 0.f));
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine* command_line = CommandLine::ForCurrentProcess();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cc::LayerTreeSettings settings;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.refresh_rate =
258c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      ContextFactory::GetInstance()->DoesCreateTestContexts()
259c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      ? kTestRefreshRate
260c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      : kDefaultRefreshRate;
26168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  settings.deadline_scheduling_enabled =
26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      switches::IsUIDeadlineSchedulingEnabled();
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.partial_swap_enabled =
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !command_line->HasSwitch(cc::switches::kUIDisablePartialSwap);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.per_tile_painting_enabled =
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIEnablePerTilePainting);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These flags should be mirrored by renderer versions in content/renderer/.
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_debug_borders =
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_fps_counter =
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_paint_rects =
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(switches::kUIShowPaintRects);
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_property_changed_rects =
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowPropertyChangedRects);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_surface_damage_rects =
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowSurfaceDamageRects);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_screen_space_rects =
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowScreenSpaceRects);
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_replica_screen_space_rects =
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowReplicaScreenSpaceRects);
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_occluding_rects =
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowOccludingRects);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  settings.initial_debug_state.show_non_occluding_rects =
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      command_line->HasSwitch(cc::switches::kUIShowNonOccludingRects);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner =
289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      g_compositor_thread ? g_compositor_thread->message_loop_proxy() : NULL;
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  host_ =
2921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      cc::LayerTreeHost::Create(this, NULL, settings, compositor_task_runner);
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetRootLayer(root_web_layer_);
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  host_->SetLayerTreeHostClientReady();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Compositor::~Compositor() {
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TRACE_EVENT0("shutdown", "Compositor::destructor");
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
300c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized);
301c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelCompositorLock();
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!compositor_lock_);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stop all outstanding draws before telling the ContextFactory to tear
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // down any contexts that the |host_| may rely upon.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_.reset();
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ContextFactory::GetInstance()->RemoveCompositor(this);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Initialize() {
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_thread = !CommandLine::ForCurrentProcess()->HasSwitch(
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switches::kUIDisableThreadedCompositing);
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool use_thread =
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switches::kUIEnableThreadedCompositing) &&
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      !CommandLine::ForCurrentProcess()->HasSwitch(
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switches::kUIDisableThreadedCompositing);
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (use_thread) {
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread = new base::Thread("Browser Compositor");
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Start();
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
331c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
332c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(!g_compositor_initialized) << "Compositor initialized twice.";
333c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  g_compositor_initialized = true;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool Compositor::WasInitializedWithThread() {
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DCHECK(g_compositor_initialized);
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !!g_compositor_thread;
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)scoped_refptr<base::MessageLoopProxy> Compositor::GetCompositorMessageLoop() {
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> proxy;
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (g_compositor_thread)
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    proxy = g_compositor_thread->message_loop_proxy();
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return proxy;
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::Terminate() {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread) {
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_compositor_thread->Stop();
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete g_compositor_thread;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_compositor_thread = NULL;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
357c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
358c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DCHECK(g_compositor_initialized) << "Compositor::Initialize() didn't happen.";
359c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  g_compositor_initialized = false;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::ScheduleDraw() {
3638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (g_compositor_thread) {
3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    host_->Composite(gfx::FrameTime::Now());
3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } else if (!defer_draw_scheduling_) {
3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    defer_draw_scheduling_ = true;
3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::MessageLoop::current()->PostTask(
3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        FROM_HERE,
3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::Bind(&Compositor::Draw, schedule_draw_factory_.GetWeakPtr()));
3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetRootLayer(Layer* root_layer) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ == root_layer)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(NULL);
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  root_layer_ = root_layer;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_ && !root_layer_->GetCompositor())
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SetCompositor(this);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root_web_layer_->RemoveAllChildren();
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->AddChild(root_layer_->cc_layer());
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetHostHasTransparentBackground(
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool host_has_transparent_background) {
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->set_has_transparent_background(host_has_transparent_background);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::Draw() {
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  defer_draw_scheduling_ = false;
3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (waiting_on_compositing_end_) {
3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    draw_on_compositing_end_ = true;
3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
3988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  waiting_on_compositing_end_ = true;
4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT_ASYNC_BEGIN0("ui", "Compositor::Draw", last_started_frame_ + 1);
4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!root_layer_)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_started_frame_++;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap pending_swap(DRAW_SWAP, posted_swaps_.get());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsLocked()) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TODO(nduca): Temporary while compositor calls
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // compositeImmediately() directly.
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layout();
4121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    host_->Composite(gfx::FrameTime::Now());
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN)
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // While we resize, we are usually a few frames behind. By blocking
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the UI thread here we minize the area that is mis-painted, specially
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // in the non-client area. See RenderWidgetHostViewAura::SetBounds for
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // more details and bug 177115.
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (next_draw_is_resize_ && (last_ended_frame_ > 1)) {
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_draw_is_resize_ = false;
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      host_->FinishAllRendering();
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pending_swap.posted())
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyEnd();
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleFullRedraw() {
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  host_->SetNeedsRedraw();
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetNeedsRedrawRect(damage_rect);
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
438868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Compositor::SetLatencyInfo(const ui::LatencyInfo& latency_info) {
439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  host_->SetLatencyInfo(latency_info);
440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::ReadPixels(SkBitmap* bitmap,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const gfx::Rect& bounds_in_pixel) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bounds_in_pixel.right() > size().width() ||
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bounds_in_pixel.bottom() > size().height())
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap->setConfig(SkBitmap::kARGB_8888_Config,
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    bounds_in_pixel.width(), bounds_in_pixel.height());
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bitmap->allocPixels();
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoLockPixels lock_image(*bitmap);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CancelCompositorLock();
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PendingSwap pending_swap(READPIXELS_SWAP, posted_swaps_.get());
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return host_->CompositeAndReadback(pixels, bounds_in_pixel);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(scale, 0);
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!size_in_pixel.IsEmpty()) {
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_ = size_in_pixel;
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    host_->SetViewportSize(size_in_pixel);
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root_web_layer_->SetBounds(size_in_pixel);
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    next_draw_is_resize_ = true;
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (device_scale_factor_ != scale) {
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device_scale_factor_ = scale;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (root_layer_)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      root_layer_->OnDeviceScaleFactorChanged(scale);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetBackgroundColor(SkColor color) {
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->set_background_color(color);
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ScheduleDraw();
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::AddObserver(CompositorObserver* observer) {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.AddObserver(observer);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::RemoveObserver(CompositorObserver* observer) {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer_list_.RemoveObserver(observer);
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::HasObserver(CompositorObserver* observer) {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return observer_list_.HasObserver(observer);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersPosted() {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->PostSwap();
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersComplete() {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!g_compositor_thread);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(posted_swaps_->AreSwapsPosted());
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NotifyEnd();
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  posted_swaps_->EndSwap();
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersAborted() {
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!g_compositor_thread) {
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP));
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // We've just lost the context, so unwind all posted_swaps.
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    while (posted_swaps_->AreSwapsPosted()) {
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (posted_swaps_->NextPostedSwap() == DRAW_SWAP)
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        NotifyEnd();
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      posted_swaps_->EndSwap();
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingAborted(this));
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::OnUpdateVSyncParameters(base::TimeTicks timebase,
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                         base::TimeDelta interval) {
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    observer_list_,
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnUpdateVSyncParameters(this, timebase, interval));
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::Layout() {
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We're sending damage that will be addressed during this composite
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cycle, so we don't need to schedule another composite to address it.
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = true;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root_layer_)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_layer_->SendDamagedRects();
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  disable_schedule_composite_ = false;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
537a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<cc::OutputSurface> Compositor::CreateOutputSurface(bool fallback) {
538558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return ContextFactory::GetInstance()->CreateOutputSurface(this);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommit() {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!IsLocked());
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingDidCommit(this));
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCommitAndDrawFrame() {
5491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  base::TimeTicks start_time = gfx::FrameTime::Now();
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    OnCompositingStarted(this, start_time));
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::DidCompleteSwapBuffers() {
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(g_compositor_thread);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotifyEnd();
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Compositor::ScheduleComposite() {
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!disable_schedule_composite_)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleDraw();
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)scoped_refptr<cc::ContextProvider> Compositor::OffscreenContextProvider() {
5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return ContextFactory::GetInstance()->OffscreenCompositorContextProvider();
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return host_->debug_state();
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Compositor::SetLayerTreeDebugState(
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const cc::LayerTreeDebugState& debug_state) {
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host_->SetDebugState(debug_state);
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<CompositorLock> Compositor::GetCompositorLock() {
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_lock_) {
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_ = new CompositorLock(this);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (g_compositor_thread)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      host_->SetDeferCommits(true);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FOR_EACH_OBSERVER(CompositorObserver,
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      observer_list_,
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      OnCompositingLockStateChanged(this));
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return compositor_lock_;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::UnlockCompositor() {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(compositor_lock_);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_lock_ = NULL;
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_compositor_thread)
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    host_->SetDeferCommits(false);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingLockStateChanged(this));
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::CancelCompositorLock() {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (compositor_lock_)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    compositor_lock_->CancelLock();
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::NotifyEnd() {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_ended_frame_++;
6078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  TRACE_EVENT_ASYNC_END0("ui", "Compositor::Draw", last_ended_frame_);
6088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  waiting_on_compositing_end_ = false;
6098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (draw_on_compositing_end_) {
6108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    draw_on_compositing_end_ = false;
6118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Call ScheduleDraw() instead of Draw() in order to allow other
6138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // CompositorObservers to be notified before starting another
6148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // draw cycle.
6158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ScheduleDraw();
6168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(CompositorObserver,
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    observer_list_,
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    OnCompositingEnded(this));
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
623