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