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