1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/compositor/browser_compositor_output_surface.h"
6
7#include "base/bind.h"
8#include "base/location.h"
9#include "base/strings/string_number_conversions.h"
10#include "content/browser/compositor/reflector_impl.h"
11#include "content/common/gpu/client/context_provider_command_buffer.h"
12
13namespace content {
14
15BrowserCompositorOutputSurface::BrowserCompositorOutputSurface(
16    const scoped_refptr<ContextProviderCommandBuffer>& context_provider,
17    int surface_id,
18    IDMap<BrowserCompositorOutputSurface>* output_surface_map,
19    const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager)
20    : OutputSurface(context_provider),
21      surface_id_(surface_id),
22      output_surface_map_(output_surface_map),
23      vsync_manager_(vsync_manager) {
24  Initialize();
25}
26
27BrowserCompositorOutputSurface::BrowserCompositorOutputSurface(
28    scoped_ptr<cc::SoftwareOutputDevice> software_device,
29    int surface_id,
30    IDMap<BrowserCompositorOutputSurface>* output_surface_map,
31    const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager)
32    : OutputSurface(software_device.Pass()),
33      surface_id_(surface_id),
34      output_surface_map_(output_surface_map),
35      vsync_manager_(vsync_manager) {
36  Initialize();
37}
38
39BrowserCompositorOutputSurface::~BrowserCompositorOutputSurface() {
40  DCHECK(CalledOnValidThread());
41  if (reflector_.get())
42    reflector_->DetachFromOutputSurface();
43  DCHECK(!reflector_.get());
44  if (!HasClient())
45    return;
46  output_surface_map_->Remove(surface_id_);
47  vsync_manager_->RemoveObserver(this);
48}
49
50void BrowserCompositorOutputSurface::Initialize() {
51  capabilities_.max_frames_pending = 1;
52  capabilities_.adjust_deadline_for_parent = false;
53
54  DetachFromThread();
55}
56
57bool BrowserCompositorOutputSurface::BindToClient(
58    cc::OutputSurfaceClient* client) {
59  DCHECK(CalledOnValidThread());
60
61  if (!OutputSurface::BindToClient(client))
62    return false;
63
64  output_surface_map_->AddWithID(this, surface_id_);
65  if (reflector_.get())
66    reflector_->OnSourceSurfaceReady(this);
67  vsync_manager_->AddObserver(this);
68  return true;
69}
70
71void BrowserCompositorOutputSurface::OnSwapBuffersComplete() {
72  // On Mac, delay acknowledging the swap to the output surface client until
73  // it has been drawn.
74#if !defined(OS_MACOSX)
75  cc::OutputSurface::OnSwapBuffersComplete();
76#endif
77}
78
79void BrowserCompositorOutputSurface::OnUpdateVSyncParameters(
80    base::TimeTicks timebase,
81    base::TimeDelta interval) {
82  DCHECK(CalledOnValidThread());
83  DCHECK(HasClient());
84  CommitVSyncParameters(timebase, interval);
85}
86
87void BrowserCompositorOutputSurface::OnUpdateVSyncParametersFromGpu(
88    base::TimeTicks timebase,
89    base::TimeDelta interval) {
90  DCHECK(CalledOnValidThread());
91  DCHECK(HasClient());
92  vsync_manager_->UpdateVSyncParameters(timebase, interval);
93}
94
95void BrowserCompositorOutputSurface::SetReflector(ReflectorImpl* reflector) {
96  reflector_ = reflector;
97}
98
99#if defined(OS_MACOSX)
100void BrowserCompositorOutputSurface::OnSurfaceDisplayed() {
101  cc::OutputSurface::OnSwapBuffersComplete();
102}
103#endif
104
105}  // namespace content
106