summaryrefslogtreecommitdiff
path: root/chromium/content/browser/aura/browser_compositor_output_surface.cc
blob: 11fbe0c42a958a99a2f47cf686eadf9e22bb3ff7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/aura/browser_compositor_output_surface.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/string_number_conversions.h"
#include "cc/output/compositor_frame.h"
#include "content/browser/aura/reflector_impl.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/compositor_switches.h"

namespace content {

BrowserCompositorOutputSurface::BrowserCompositorOutputSurface(
    scoped_ptr<WebKit::WebGraphicsContext3D> context,
    int surface_id,
    IDMap<BrowserCompositorOutputSurface>* output_surface_map,
    base::MessageLoopProxy* compositor_message_loop,
    base::WeakPtr<ui::Compositor> compositor)
    : OutputSurface(context.Pass()),
      surface_id_(surface_id),
      output_surface_map_(output_surface_map),
      compositor_message_loop_(compositor_message_loop),
      compositor_(compositor) {
  CommandLine* command_line = CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kUIMaxFramesPending)) {
    std::string string_value = command_line->GetSwitchValueASCII(
        switches::kUIMaxFramesPending);
    int int_value;
    if (base::StringToInt(string_value, &int_value))
      capabilities_.max_frames_pending = int_value;
    else
      LOG(ERROR) << "Trouble parsing --" << switches::kUIMaxFramesPending;
  }
  capabilities_.adjust_deadline_for_parent = false;
  DetachFromThread();
}

BrowserCompositorOutputSurface::~BrowserCompositorOutputSurface() {
  DCHECK(CalledOnValidThread());
  if (!HasClient())
    return;
  output_surface_map_->Remove(surface_id_);
}

bool BrowserCompositorOutputSurface::BindToClient(
    cc::OutputSurfaceClient* client) {
  DCHECK(CalledOnValidThread());

  if (!OutputSurface::BindToClient(client))
    return false;

  output_surface_map_->AddWithID(this, surface_id_);
  return true;
}

void BrowserCompositorOutputSurface::Reshape(gfx::Size size,
                                             float scale_factor) {
  OutputSurface::Reshape(size, scale_factor);
  if (reflector_.get())
    reflector_->OnReshape(size);
}

void BrowserCompositorOutputSurface::SwapBuffers(cc::CompositorFrame* frame) {
  DCHECK(frame->gl_frame_data);

  WebGraphicsContext3DCommandBufferImpl* command_buffer =
      static_cast<WebGraphicsContext3DCommandBufferImpl*>(context3d());
  CommandBufferProxyImpl* command_buffer_proxy =
      command_buffer->GetCommandBufferProxy();
  DCHECK(command_buffer_proxy);
  context3d()->shallowFlushCHROMIUM();
  command_buffer_proxy->SetLatencyInfo(frame->metadata.latency_info);

  if (reflector_.get()) {
    if (frame->gl_frame_data->sub_buffer_rect ==
        gfx::Rect(frame->gl_frame_data->size))
      reflector_->OnSwapBuffers();
    else
      reflector_->OnPostSubBuffer(frame->gl_frame_data->sub_buffer_rect);
  }

  OutputSurface::SwapBuffers(frame);
}

void BrowserCompositorOutputSurface::OnUpdateVSyncParameters(
    base::TimeTicks timebase,
    base::TimeDelta interval) {
  DCHECK(CalledOnValidThread());
  DCHECK(HasClient());
  OnVSyncParametersChanged(timebase, interval);
  compositor_message_loop_->PostTask(
      FROM_HERE,
      base::Bind(&ui::Compositor::OnUpdateVSyncParameters,
                 compositor_, timebase, interval));
}

void BrowserCompositorOutputSurface::SetReflector(ReflectorImpl* reflector) {
  reflector_ = reflector;
}

}  // namespace content