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
<ContextProviderCommandBuffer
>& worker_context
,
21 const scoped_refptr
<ui::CompositorVSyncManager
>& vsync_manager
,
22 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>
23 overlay_candidate_validator
)
24 : BrowserCompositorOutputSurface(context
,
27 overlay_candidate_validator
.Pass()),
28 #if defined(OS_MACOSX)
29 should_show_frames_state_(SHOULD_SHOW_FRAMES
),
31 swap_buffers_completion_callback_(
32 base::Bind(&GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted
,
33 base::Unretained(this))),
34 update_vsync_parameters_callback_(base::Bind(
35 &BrowserCompositorOutputSurface::OnUpdateVSyncParametersFromGpu
,
36 base::Unretained(this))) {
39 GpuBrowserCompositorOutputSurface::~GpuBrowserCompositorOutputSurface() {}
41 CommandBufferProxyImpl
*
42 GpuBrowserCompositorOutputSurface::GetCommandBufferProxy() {
43 ContextProviderCommandBuffer
* provider_command_buffer
=
44 static_cast<content::ContextProviderCommandBuffer
*>(
45 context_provider_
.get());
46 CommandBufferProxyImpl
* command_buffer_proxy
=
47 provider_command_buffer
->GetCommandBufferProxy();
48 DCHECK(command_buffer_proxy
);
49 return command_buffer_proxy
;
52 bool GpuBrowserCompositorOutputSurface::BindToClient(
53 cc::OutputSurfaceClient
* client
) {
54 if (!BrowserCompositorOutputSurface::BindToClient(client
))
57 GetCommandBufferProxy()->SetSwapBuffersCompletionCallback(
58 swap_buffers_completion_callback_
.callback());
59 GetCommandBufferProxy()->SetUpdateVSyncParametersCallback(
60 update_vsync_parameters_callback_
.callback());
64 void GpuBrowserCompositorOutputSurface::OnReflectorChanged() {
66 reflector_texture_
.reset();
68 reflector_texture_
.reset(new ReflectorTexture(context_provider()));
69 reflector_
->OnSourceTextureMailboxUpdated(reflector_texture_
->mailbox());
73 void GpuBrowserCompositorOutputSurface::SwapBuffers(
74 cc::CompositorFrame
* frame
) {
75 DCHECK(frame
->gl_frame_data
);
77 GetCommandBufferProxy()->SetLatencyInfo(frame
->metadata
.latency_info
);
80 if (frame
->gl_frame_data
->sub_buffer_rect
==
81 gfx::Rect(frame
->gl_frame_data
->size
)) {
82 reflector_texture_
->CopyTextureFullImage(SurfaceSize());
83 reflector_
->OnSourceSwapBuffers();
85 const gfx::Rect
& rect
= frame
->gl_frame_data
->sub_buffer_rect
;
86 reflector_texture_
->CopyTextureSubImage(rect
);
87 reflector_
->OnSourcePostSubBuffer(rect
);
91 if (frame
->gl_frame_data
->sub_buffer_rect
==
92 gfx::Rect(frame
->gl_frame_data
->size
)) {
93 context_provider_
->ContextSupport()->Swap();
95 context_provider_
->ContextSupport()->PartialSwapBuffers(
96 frame
->gl_frame_data
->sub_buffer_rect
);
99 client_
->DidSwapBuffers();
101 #if defined(OS_MACOSX)
102 if (should_show_frames_state_
==
103 SHOULD_NOT_SHOW_FRAMES_NO_SWAP_AFTER_SUSPENDED
) {
104 should_show_frames_state_
= SHOULD_SHOW_FRAMES
;
109 void GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted(
110 const std::vector
<ui::LatencyInfo
>& latency_info
,
111 gfx::SwapResult result
) {
112 #if defined(OS_MACOSX)
113 // On Mac, delay acknowledging the swap to the output surface client until
114 // it has been drawn, see OnSurfaceDisplayed();
117 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info
);
118 OnSwapBuffersComplete();
122 #if defined(OS_MACOSX)
123 void GpuBrowserCompositorOutputSurface::OnSurfaceDisplayed() {
124 cc::OutputSurface::OnSwapBuffersComplete();
127 void GpuBrowserCompositorOutputSurface::SetSurfaceSuspendedForRecycle(
130 // It may be that there are frames in-flight from the GPU process back to
131 // the browser. Make sure that these frames are not displayed by ignoring
132 // them in GpuProcessHostUIShim, until the browser issues a SwapBuffers for
134 should_show_frames_state_
= SHOULD_NOT_SHOW_FRAMES_SUSPENDED
;
136 // Discard the backbuffer before drawing the new frame. This is necessary
137 // only when using a ImageTransportSurfaceFBO with a
138 // CALayerStorageProvider. Discarding the backbuffer results in the next
139 // frame using a new CALayer and CAContext, which guarantees that the
140 // browser will not flash stale content when adding the remote CALayer to
141 // the NSView hierarchy (it could flash stale content because the system
142 // window server is not synchronized with any signals we control or
144 if (should_show_frames_state_
== SHOULD_NOT_SHOW_FRAMES_SUSPENDED
) {
146 should_show_frames_state_
=
147 SHOULD_NOT_SHOW_FRAMES_NO_SWAP_AFTER_SUSPENDED
;
152 bool GpuBrowserCompositorOutputSurface::
153 SurfaceShouldNotShowFramesAfterSuspendForRecycle() const {
154 return should_show_frames_state_
!= SHOULD_SHOW_FRAMES
;
158 bool GpuBrowserCompositorOutputSurface::SurfaceIsSuspendForRecycle() const {
159 #if defined(OS_MACOSX)
160 return should_show_frames_state_
== SHOULD_NOT_SHOW_FRAMES_SUSPENDED
;
166 } // namespace content