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.
5 #include "content/browser/compositor/browser_compositor_view_mac.h"
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"
13 ////////////////////////////////////////////////////////////////////////////////
14 // BrowserCompositorViewMac
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;
24 // A spare BrowserCompositorViewMacInternal kept around for recycling.
25 base::LazyInstance<scoped_ptr<BrowserCompositorViewMacInternal>>
26 g_recyclable_internal_view;
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();
39 internal_view_.reset(new BrowserCompositorViewMacInternal);
40 internal_view_->SetClient(client_);
43 BrowserCompositorViewMac::~BrowserCompositorViewMac() {
44 // Make this BrowserCompositorViewMacInternal recyclable for future instances.
45 internal_view_->ResetClient();
46 g_recyclable_internal_view.Get() = internal_view_.Pass();
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();
54 ui::Compositor* BrowserCompositorViewMac::GetCompositor() const {
55 DCHECK(internal_view_);
56 return internal_view_->compositor();
59 bool BrowserCompositorViewMac::HasFrameOfSize(
60 const gfx::Size& dip_size) const {
62 return internal_view_->HasFrameOfSize(dip_size);
66 void BrowserCompositorViewMac::BeginPumpingFrames() {
68 internal_view_->BeginPumpingFrames();
71 void BrowserCompositorViewMac::EndPumpingFrames() {
73 internal_view_->EndPumpingFrames();
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);
87 internal_view->GotAcceleratedFrame(
88 surface_handle, surface_id, latency_info, pixel_size, scale_factor);
89 renderer_id = internal_view->GetRendererID();
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);
98 ui_shim->Send(new AcceleratedSurfaceMsg_BufferPresented(
99 gpu_route_id, ack_params));
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);
110 internal_view->GotSoftwareFrame(frame_data, scale_factor, canvas);
113 ////////////////////////////////////////////////////////////////////////////////
114 // BrowserCompositorViewPlaceholderMac
116 BrowserCompositorViewPlaceholderMac::BrowserCompositorViewPlaceholderMac() {
117 g_placeholder_count += 1;
120 BrowserCompositorViewPlaceholderMac::~BrowserCompositorViewPlaceholderMac() {
121 DCHECK_GT(g_placeholder_count, 0u);
122 g_placeholder_count -= 1;
124 // If there are no placeholders allocated, destroy the recyclable
125 // BrowserCompositorViewMacInternal.
126 if (!g_placeholder_count)
127 g_recyclable_internal_view.Get().reset();
130 } // namespace content