9feeefaa09248d8a0aad1bfa8ca029a3cf0f10c4
[platform/framework/web/crosswalk.git] / src / content / browser / compositor / browser_compositor_view_mac.mm
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_view_mac.h"
6
7 #include "base/debug/trace_event.h"
8 #include "base/lazy_instance.h"
9 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
10 #include "content/browser/compositor/browser_compositor_view_private_mac.h"
11 #include "content/common/gpu/gpu_messages.h"
12
13 ////////////////////////////////////////////////////////////////////////////////
14 // BrowserCompositorViewMac
15
16 namespace content {
17 namespace {
18
19 // The number of placeholder objects allocated. If this reaches zero, then
20 // the BrowserCompositorViewMacInternal being held on to for recycling,
21 // |g_recyclable_internal_view|, will be freed.
22 uint32 g_placeholder_count = 0;
23
24 // A spare BrowserCompositorViewMacInternal kept around for recycling.
25 base::LazyInstance<scoped_ptr<BrowserCompositorViewMacInternal>>
26   g_recyclable_internal_view;
27
28 }  // namespace
29
30 BrowserCompositorViewMac::BrowserCompositorViewMac(
31     BrowserCompositorViewMacClient* client) : client_(client) {
32   // Try to use the recyclable BrowserCompositorViewMacInternal if there is one,
33   // otherwise allocate a new one.
34   // TODO(ccameron): If there exists a frame in flight (swap has been called
35   // by the compositor, but the frame has not arrived from the GPU process
36   // yet), then that frame may inappropriately flash in the new view.
37   internal_view_ = g_recyclable_internal_view.Get().Pass();
38   if (!internal_view_)
39     internal_view_.reset(new BrowserCompositorViewMacInternal);
40   internal_view_->SetClient(client_);
41 }
42
43 BrowserCompositorViewMac::~BrowserCompositorViewMac() {
44   // Make this BrowserCompositorViewMacInternal recyclable for future instances.
45   internal_view_->ResetClient();
46   g_recyclable_internal_view.Get() = internal_view_.Pass();
47
48   // If there are no placeholders allocated, destroy the recyclable
49   // BrowserCompositorViewMacInternal that we just populated.
50   if (!g_placeholder_count)
51     g_recyclable_internal_view.Get().reset();
52 }
53
54 ui::Compositor* BrowserCompositorViewMac::GetCompositor() const {
55   DCHECK(internal_view_);
56   return internal_view_->compositor();
57 }
58
59 bool BrowserCompositorViewMac::HasFrameOfSize(
60     const gfx::Size& dip_size) const {
61   if (internal_view_)
62     return internal_view_->HasFrameOfSize(dip_size);
63   return false;
64 }
65
66 void BrowserCompositorViewMac::BeginPumpingFrames() {
67   if (internal_view_)
68     internal_view_->BeginPumpingFrames();
69 }
70
71 void BrowserCompositorViewMac::EndPumpingFrames() {
72   if (internal_view_)
73     internal_view_->EndPumpingFrames();
74 }
75
76 // static
77 void BrowserCompositorViewMac::GotAcceleratedFrame(
78     gfx::AcceleratedWidget widget,
79     uint64 surface_handle, int surface_id,
80     const std::vector<ui::LatencyInfo>& latency_info,
81     gfx::Size pixel_size, float scale_factor,
82     int gpu_host_id, int gpu_route_id) {
83   BrowserCompositorViewMacInternal* internal_view =
84       BrowserCompositorViewMacInternal::FromAcceleratedWidget(widget);
85   int renderer_id = 0;
86   if (internal_view) {
87     internal_view->GotAcceleratedFrame(
88         surface_handle, surface_id, latency_info, pixel_size, scale_factor);
89     renderer_id = internal_view->GetRendererID();
90   }
91
92   // Acknowledge the swap, now that it has been processed.
93   AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
94   ack_params.sync_point = 0;
95   ack_params.renderer_id = renderer_id;
96   GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(gpu_host_id);
97   if (ui_shim) {
98     ui_shim->Send(new AcceleratedSurfaceMsg_BufferPresented(
99         gpu_route_id, ack_params));
100   }
101 }
102
103 // static
104 void BrowserCompositorViewMac::GotSoftwareFrame(
105     gfx::AcceleratedWidget widget,
106     cc::SoftwareFrameData* frame_data, float scale_factor, SkCanvas* canvas) {
107   BrowserCompositorViewMacInternal* internal_view =
108       BrowserCompositorViewMacInternal::FromAcceleratedWidget(widget);
109   if (internal_view)
110     internal_view->GotSoftwareFrame(frame_data, scale_factor, canvas);
111 }
112
113 ////////////////////////////////////////////////////////////////////////////////
114 // BrowserCompositorViewPlaceholderMac
115
116 BrowserCompositorViewPlaceholderMac::BrowserCompositorViewPlaceholderMac() {
117   g_placeholder_count += 1;
118 }
119
120 BrowserCompositorViewPlaceholderMac::~BrowserCompositorViewPlaceholderMac() {
121   DCHECK_GT(g_placeholder_count, 0u);
122   g_placeholder_count -= 1;
123
124   // If there are no placeholders allocated, destroy the recyclable
125   // BrowserCompositorViewMacInternal.
126   if (!g_placeholder_count)
127     g_recyclable_internal_view.Get().reset();
128 }
129
130 }  // namespace content