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/gpu_browser_compositor_output_surface.h"
7 #include "cc/output/compositor_frame.h"
8 #include "cc/output/output_surface_client.h"
9 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator.h"
10 #include "content/browser/compositor/reflector_impl.h"
11 #include "content/browser/compositor/reflector_texture.h"
12 #include "content/browser/renderer_host/render_widget_host_impl.h"
13 #include "content/common/gpu/client/context_provider_command_buffer.h"
14 #include "gpu/command_buffer/client/context_support.h"
18 GpuBrowserCompositorOutputSurface::GpuBrowserCompositorOutputSurface(
19 const scoped_refptr
<ContextProviderCommandBuffer
>& context
,
20 const scoped_refptr
<ui::CompositorVSyncManager
>& vsync_manager
,
21 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>
22 overlay_candidate_validator
)
23 : BrowserCompositorOutputSurface(context
,
25 overlay_candidate_validator
.Pass()),
26 #if defined(OS_MACOSX)
27 should_show_frames_state_(SHOULD_SHOW_FRAMES
),
29 swap_buffers_completion_callback_(
30 base::Bind(&GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted
,
31 base::Unretained(this))),
32 update_vsync_parameters_callback_(base::Bind(
33 &BrowserCompositorOutputSurface::OnUpdateVSyncParametersFromGpu
,
34 base::Unretained(this))) {
37 GpuBrowserCompositorOutputSurface::~GpuBrowserCompositorOutputSurface() {}
39 CommandBufferProxyImpl
*
40 GpuBrowserCompositorOutputSurface::GetCommandBufferProxy() {
41 ContextProviderCommandBuffer
* provider_command_buffer
=
42 static_cast<content::ContextProviderCommandBuffer
*>(
43 context_provider_
.get());
44 CommandBufferProxyImpl
* command_buffer_proxy
=
45 provider_command_buffer
->GetCommandBufferProxy();
46 DCHECK(command_buffer_proxy
);
47 return command_buffer_proxy
;
50 bool GpuBrowserCompositorOutputSurface::BindToClient(
51 cc::OutputSurfaceClient
* client
) {
52 if (!BrowserCompositorOutputSurface::BindToClient(client
))
55 GetCommandBufferProxy()->SetSwapBuffersCompletionCallback(
56 swap_buffers_completion_callback_
.callback());
57 GetCommandBufferProxy()->SetUpdateVSyncParametersCallback(
58 update_vsync_parameters_callback_
.callback());
62 void GpuBrowserCompositorOutputSurface::OnReflectorChanged() {
64 reflector_texture_
.reset();
66 reflector_texture_
.reset(new ReflectorTexture(context_provider()));
67 reflector_
->OnSourceTextureMailboxUpdated(reflector_texture_
->mailbox());
71 void GpuBrowserCompositorOutputSurface::SwapBuffers(
72 cc::CompositorFrame
* frame
) {
73 DCHECK(frame
->gl_frame_data
);
75 GetCommandBufferProxy()->SetLatencyInfo(frame
->metadata
.latency_info
);
78 if (frame
->gl_frame_data
->sub_buffer_rect
==
79 gfx::Rect(frame
->gl_frame_data
->size
)) {
80 reflector_texture_
->CopyTextureFullImage(SurfaceSize());
81 reflector_
->OnSourceSwapBuffers();
83 const gfx::Rect
& rect
= frame
->gl_frame_data
->sub_buffer_rect
;
84 reflector_texture_
->CopyTextureSubImage(rect
);
85 reflector_
->OnSourcePostSubBuffer(rect
);
89 if (frame
->gl_frame_data
->sub_buffer_rect
==
90 gfx::Rect(frame
->gl_frame_data
->size
)) {
91 context_provider_
->ContextSupport()->Swap();
93 context_provider_
->ContextSupport()->PartialSwapBuffers(
94 frame
->gl_frame_data
->sub_buffer_rect
);
97 client_
->DidSwapBuffers();
99 #if defined(OS_MACOSX)
100 if (should_show_frames_state_
==
101 SHOULD_NOT_SHOW_FRAMES_NO_SWAP_AFTER_SUSPENDED
) {
102 should_show_frames_state_
= SHOULD_SHOW_FRAMES
;
107 void GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted(
108 const std::vector
<ui::LatencyInfo
>& latency_info
,
109 gfx::SwapResult result
) {
110 #if defined(OS_MACOSX)
111 // On Mac, delay acknowledging the swap to the output surface client until
112 // it has been drawn, see OnSurfaceDisplayed();
115 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info
);
116 OnSwapBuffersComplete();
120 #if defined(OS_MACOSX)
121 void GpuBrowserCompositorOutputSurface::OnSurfaceDisplayed() {
122 cc::OutputSurface::OnSwapBuffersComplete();
125 void GpuBrowserCompositorOutputSurface::SetSurfaceSuspendedForRecycle(
128 // It may be that there are frames in-flight from the GPU process back to
129 // the browser. Make sure that these frames are not displayed by ignoring
130 // them in GpuProcessHostUIShim, until the browser issues a SwapBuffers for
132 should_show_frames_state_
= SHOULD_NOT_SHOW_FRAMES_SUSPENDED
;
134 // Discard the backbuffer before drawing the new frame. This is necessary
135 // only when using a ImageTransportSurfaceFBO with a
136 // CALayerStorageProvider. Discarding the backbuffer results in the next
137 // frame using a new CALayer and CAContext, which guarantees that the
138 // browser will not flash stale content when adding the remote CALayer to
139 // the NSView hierarchy (it could flash stale content because the system
140 // window server is not synchronized with any signals we control or
142 if (should_show_frames_state_
== SHOULD_NOT_SHOW_FRAMES_SUSPENDED
) {
144 should_show_frames_state_
=
145 SHOULD_NOT_SHOW_FRAMES_NO_SWAP_AFTER_SUSPENDED
;
150 bool GpuBrowserCompositorOutputSurface::
151 SurfaceShouldNotShowFramesAfterSuspendForRecycle() const {
152 return should_show_frames_state_
!= SHOULD_SHOW_FRAMES
;
156 bool GpuBrowserCompositorOutputSurface::SurfaceIsSuspendForRecycle() const {
157 #if defined(OS_MACOSX)
158 return should_show_frames_state_
== SHOULD_NOT_SHOW_FRAMES_SUSPENDED
;
164 } // namespace content