compositor.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/Source/Platform/chromium/public/Platform.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorSupport.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/Source/Platform/chromium/public/WebFloatPoint.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutputSurface.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor_observer.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor_switches.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/dip_util.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/test_web_graphics_context_3d.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_surface.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/glue/webthread_impl.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/chromeos/chromeos_version.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const double kDefaultRefreshRate = 60.0; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const double kTestRefreshRate = 100.0; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum SwapType { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRAW_SWAP, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) READPIXELS_SWAP, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)webkit_glue::WebThreadImpl* g_compositor_thread = NULL; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool test_compositor_enabled = false; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::ContextFactory* g_context_factory = NULL; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCompositorLockTimeoutMs = 67; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adapts a pure WebGraphicsContext3D into a WebCompositorOutputSurface. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebGraphicsContextToOutputSurfaceAdapter 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public WebKit::WebCompositorOutputSurface { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit WebGraphicsContextToOutputSurfaceAdapter( 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebGraphicsContext3D* context) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : context3D_(context), 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_(NULL) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool bindToClient( 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebCompositorOutputSurfaceClient* client) OVERRIDE { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(client); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!context3D_->makeContextCurrent()) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_ = client; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual const Capabilities& capabilities() const OVERRIDE { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return capabilities_; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual WebKit::WebGraphicsContext3D* context3D() const OVERRIDE { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context3D_.get(); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void sendFrameToParentCompositor( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WebKit::WebCompositorFrame&) OVERRIDE { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WebKit::WebGraphicsContext3D> context3D_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Capabilities capabilities_; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebCompositorOutputSurfaceClient* client_; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PendingSwap { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~PendingSwap(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwapType type() const { return type_; } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool posted() const { return posted_; } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ui::PostedSwapQueue; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwapType type_; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool posted_; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::PostedSwapQueue* posted_swaps_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PendingSwap); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContextFactory* ContextFactory::GetInstance() { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We leak the shared resources so that we don't race with 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the tear down of the gl_bindings. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!g_context_factory) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Using DefaultSharedResource"; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DefaultContextFactory> instance( 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new DefaultContextFactory()); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (instance->Initialize()) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_context_factory = instance.release(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return g_context_factory; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ContextFactory::SetInstance(ContextFactory* instance) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_context_factory = instance; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DefaultContextFactory::DefaultContextFactory() { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DefaultContextFactory::~DefaultContextFactory() { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DefaultContextFactory::Initialize() { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The following line of code exists soley to disable IO restrictions 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on this thread long enough to perform the GL bindings. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(wjmaclean) Remove this when GL initialisation cleaned up. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!gfx::GLSurface::InitializeOneOff() || 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GetGLImplementation() == gfx::kGLImplementationNone) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Could not load the GL bindings"; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebCompositorOutputSurface* DefaultContextFactory::CreateOutputSurface( 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Compositor* compositor) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new WebGraphicsContextToOutputSurfaceAdapter( 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateContextCommon(compositor, false)); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateOffscreenContext() { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateContextCommon(NULL, true); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DefaultContextFactory::RemoveCompositor(Compositor* compositor) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebGraphicsContext3D* DefaultContextFactory::CreateContextCommon( 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Compositor* compositor, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool offscreen) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(offscreen || compositor); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebGraphicsContext3D::Attributes attrs; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attrs.depth = false; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attrs.stencil = false; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attrs.antialias = false; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attrs.shareResources = true; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebGraphicsContext3D* context = 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) offscreen ? 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWebView( 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attrs, false) : 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWindow( 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attrs, compositor->widget(), share_group_.get()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!context) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine* command_line = CommandLine::ForCurrentProcess(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!offscreen) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context->makeContextCurrent(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GLContext* gl_context = gfx::GLContext::GetCurrent(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool vsync = !command_line->HasSwitch(switches::kDisableGpuVsync); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_context->SetSwapInterval(vsync ? 1 : 0); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_context->ReleaseCurrent(NULL); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::Texture(bool flipped, const gfx::Size& size, float device_scale_factor) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : flipped_(flipped), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_(size), 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_scale_factor_(device_scale_factor) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Texture::~Texture() { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::CompositorLock(Compositor* compositor) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : compositor_(compositor) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop::current()->PostDelayedTask( 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CompositorLock::CancelLock, AsWeakPtr()), 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kCompositorLockTimeoutMs)); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorLock::~CompositorLock() { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelLock(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CompositorLock::CancelLock() { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compositor_) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_->UnlockCompositor(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_ = NULL; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PostedSwapQueue { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostedSwapQueue() : pending_swap_(NULL) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~PostedSwapQueue() { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pending_swap_); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SwapType NextPostedSwap() const { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return queue_.front(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AreSwapsPosted() const { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !queue_.empty(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int NumSwapsPosted(SwapType type) const { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = 0; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::deque<SwapType>::const_iterator it = queue_.begin(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != queue_.end(); ++it) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*it == type) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count++; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return count; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PostSwap() { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pending_swap_); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queue_.push_back(pending_swap_->type()); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_swap_->posted_ = true; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EndSwap() { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queue_.pop_front(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class ::PendingSwap; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingSwap* pending_swap_; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::deque<SwapType> queue_; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(PostedSwapQueue); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::PendingSwap(SwapType type, ui::PostedSwapQueue* posted_swaps) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : type_(type), posted_(false), posted_swaps_(posted_swaps) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only one pending swap in flight. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(static_cast<PendingSwap*>(NULL), posted_swaps_->pending_swap_); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) posted_swaps_->pending_swap_ = this; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PendingSwap::~PendingSwap() { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(this, posted_swaps_->pending_swap_); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) posted_swaps_->pending_swap_ = NULL; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Compositor::Compositor(CompositorDelegate* delegate, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::AcceleratedWidget widget) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : delegate_(delegate), 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_layer_(NULL), 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) widget_(widget), 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) posted_swaps_(new PostedSwapQueue()), 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_scale_factor_(0.0f), 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_started_frame_(0), 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_ended_frame_(0), 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disable_schedule_composite_(false), 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_lock_(NULL) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebCompositorSupport* compositor_support = 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::Platform::current()->compositorSupport(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_web_layer_.reset(compositor_support->createLayer()); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebLayerTreeView::Settings settings; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine* command_line = CommandLine::ForCurrentProcess(); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings.showFPSCounter = 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line->HasSwitch(switches::kUIShowFPSCounter); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings.showPlatformLayerTree = 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line->HasSwitch(switches::kUIShowLayerTree); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings.refreshRate = 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_compositor_enabled ? kTestRefreshRate : kDefaultRefreshRate; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_web_layer_->setAnchorPoint(WebKit::WebFloatPoint(0.f, 0.f)); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_.reset(compositor_support->createLayerTreeView(this, *root_web_layer_, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings)); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_->setSurfaceReady(); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Compositor::~Compositor() { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelCompositorLock(); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!compositor_lock_); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't call |CompositorDelegate::ScheduleDraw| from this point. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_ = NULL; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_layer_) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_layer_->SetCompositor(NULL); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop all outstanding draws before telling the ContextFactory to tear 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // down any contexts that the |host_| may rely upon. 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_.reset(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!test_compositor_enabled) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContextFactory::GetInstance()->RemoveCompositor(this); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::Initialize(bool use_thread) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine* command_line = CommandLine::ForCurrentProcess(); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebCompositorSupport* compositor_support = 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::Platform::current()->compositorSupport(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These settings must be applied before we initialize the compositor. 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_support->setPartialSwapEnabled( 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line->HasSwitch(switches::kUIEnablePartialSwap)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_support->setPerTilePaintingEnabled( 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line->HasSwitch(switches::kUIEnablePerTilePainting)); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_thread) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_compositor_thread = new webkit_glue::WebThreadImpl("Browser Compositor"); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_support->initialize(g_compositor_thread); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::Terminate() { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::Platform::current()->compositorSupport()->shutdown(); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_compositor_thread) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete g_compositor_thread; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_compositor_thread = NULL; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::ScheduleDraw() { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_compositor_thread) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(nduca): Temporary while compositor calls 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // compositeImmediately() directly. 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout(); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_->composite(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (delegate_) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->ScheduleDraw(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetRootLayer(Layer* root_layer) { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_layer_ == root_layer) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_layer_) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_layer_->SetCompositor(NULL); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_layer_ = root_layer; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_layer_ && !root_layer_->GetCompositor()) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_layer_->SetCompositor(this); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_web_layer_->removeAllChildren(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_layer_) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_web_layer_->addChild(root_layer_->web_layer()); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetHostHasTransparentBackground( 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool host_has_transparent_background) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_->setHasTransparentBackground(host_has_transparent_background); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::Draw(bool force_clear) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!g_compositor_thread); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!root_layer_) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_started_frame_++; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingSwap pending_swap(DRAW_SWAP, posted_swaps_.get()); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsLocked()) { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(nduca): Temporary while compositor calls 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // compositeImmediately() directly. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_->composite(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_swap.posted()) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyEnd(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::ScheduleFullDraw() { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_->setNeedsRedraw(); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::ReadPixels(SkBitmap* bitmap, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Rect& bounds_in_pixel) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bounds_in_pixel.right() > size().width() || 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_in_pixel.bottom() > size().height()) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap->setConfig(SkBitmap::kARGB_8888_Config, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_in_pixel.width(), bounds_in_pixel.height()); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitmap->allocPixels(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkAutoLockPixels lock_image(*bitmap); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char* pixels = static_cast<unsigned char*>(bitmap->getPixels()); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelCompositorLock(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingSwap pending_swap(READPIXELS_SWAP, posted_swaps_.get()); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return host_->compositeAndReadback(pixels, bounds_in_pixel); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::SetScaleAndSize(float scale, const gfx::Size& size_in_pixel) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GT(scale, 0); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size_in_pixel.IsEmpty() || scale <= 0) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_ = size_in_pixel; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_->setViewportSize(size_in_pixel); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_web_layer_->setBounds(size_in_pixel); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (device_scale_factor_ != scale) { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_scale_factor_ = scale; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_layer_) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_layer_->OnDeviceScaleFactorChanged(scale); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::AddObserver(CompositorObserver* observer) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_.AddObserver(observer); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::RemoveObserver(CompositorObserver* observer) { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_.RemoveObserver(observer); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Compositor::HasObserver(CompositorObserver* observer) { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return observer_list_.HasObserver(observer); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersPosted() { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!g_compositor_thread); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) posted_swaps_->PostSwap(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersComplete() { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!g_compositor_thread); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(posted_swaps_->AreSwapsPosted()); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP)); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (posted_swaps_->NextPostedSwap() == DRAW_SWAP) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyEnd(); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) posted_swaps_->EndSwap(); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::OnSwapBuffersAborted() { 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!g_compositor_thread); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(1, posted_swaps_->NumSwapsPosted(DRAW_SWAP)); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We've just lost the context, so unwind all posted_swaps. 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (posted_swaps_->AreSwapsPosted()) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (posted_swaps_->NextPostedSwap() == DRAW_SWAP) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyEnd(); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) posted_swaps_->EndSwap(); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(CompositorObserver, 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_, 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCompositingAborted(this)); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::updateAnimations(double frameBeginTime) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::layout() { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're sending damage that will be addressed during this composite 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cycle, so we don't need to schedule another composite to address it. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disable_schedule_composite_ = true; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (root_layer_) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_layer_->SendDamagedRects(); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disable_schedule_composite_ = false; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::applyScrollAndScale(const WebKit::WebSize& scrollDelta, 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float scaleFactor) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebCompositorOutputSurface* Compositor::createOutputSurface() { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (test_compositor_enabled) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::TestWebGraphicsContext3D* test_context = 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ui::TestWebGraphicsContext3D(); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_context->Initialize(); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new WebGraphicsContextToOutputSurfaceAdapter(test_context); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ContextFactory::GetInstance()->CreateOutputSurface(this); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::didRecreateOutputSurface(bool success) { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::didCommit() { 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsLocked()); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(CompositorObserver, 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_, 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCompositingDidCommit(this)); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::didCommitAndDrawFrame() { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(CompositorObserver, 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_, 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCompositingStarted(this)); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::didCompleteSwapBuffers() { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(g_compositor_thread); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyEnd(); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::scheduleComposite() { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!disable_schedule_composite_) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleDraw(); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<CompositorLock> Compositor::GetCompositorLock() { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!compositor_lock_) { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_lock_ = new CompositorLock(this); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_compositor_thread) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_->setDeferCommits(true); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(CompositorObserver, 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_, 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCompositingLockStateChanged(this)); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return compositor_lock_; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::UnlockCompositor() { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(compositor_lock_); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_lock_ = NULL; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (g_compositor_thread) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_->setDeferCommits(false); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(CompositorObserver, 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_, 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCompositingLockStateChanged(this)); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::CancelCompositorLock() { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (compositor_lock_) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_lock_->CancelLock(); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Compositor::NotifyEnd() { 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_ended_frame_++; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(CompositorObserver, 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list_, 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCompositingEnded(this)); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPOSITOR_EXPORT void SetupTestCompositor() { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CommandLine::ForCurrentProcess()->HasSwitch( 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kDisableTestCompositor)) { 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_compositor_enabled = true; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the test is running on the chromeos envrionment (such as 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // device or vm bots), use the real compositor. 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::chromeos::IsRunningOnChromeOS()) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_compositor_enabled = false; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPOSITOR_EXPORT void DisableTestCompositor() { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_compositor_enabled = false; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPOSITOR_EXPORT bool IsTestCompositorEnabled() { 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return test_compositor_enabled; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 586