Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / compositor / gpu_browser_compositor_output_surface.cc
blob9ca1d51e5de9ba511e93b111f0834f04375ba58d
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/reflector_impl.h"
10 #include "content/browser/renderer_host/render_widget_host_impl.h"
11 #include "content/common/gpu/client/context_provider_command_buffer.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "gpu/command_buffer/client/context_support.h"
14 #include "gpu/command_buffer/client/gles2_interface.h"
16 namespace content {
18 GpuBrowserCompositorOutputSurface::GpuBrowserCompositorOutputSurface(
19 const scoped_refptr<ContextProviderCommandBuffer>& context,
20 const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager,
21 scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator)
22 : BrowserCompositorOutputSurface(context,
23 vsync_manager),
24 #if defined(OS_MACOSX)
25 should_not_show_frames_(false),
26 #endif
27 swap_buffers_completion_callback_(
28 base::Bind(&GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted,
29 base::Unretained(this))),
30 update_vsync_parameters_callback_(base::Bind(
31 &BrowserCompositorOutputSurface::OnUpdateVSyncParametersFromGpu,
32 base::Unretained(this))) {
33 overlay_candidate_validator_ = overlay_candidate_validator.Pass();
36 GpuBrowserCompositorOutputSurface::~GpuBrowserCompositorOutputSurface() {}
38 CommandBufferProxyImpl*
39 GpuBrowserCompositorOutputSurface::GetCommandBufferProxy() {
40 ContextProviderCommandBuffer* provider_command_buffer =
41 static_cast<content::ContextProviderCommandBuffer*>(
42 context_provider_.get());
43 CommandBufferProxyImpl* command_buffer_proxy =
44 provider_command_buffer->GetCommandBufferProxy();
45 DCHECK(command_buffer_proxy);
46 return command_buffer_proxy;
49 bool GpuBrowserCompositorOutputSurface::BindToClient(
50 cc::OutputSurfaceClient* client) {
51 if (!BrowserCompositorOutputSurface::BindToClient(client))
52 return false;
54 GetCommandBufferProxy()->SetSwapBuffersCompletionCallback(
55 swap_buffers_completion_callback_.callback());
56 GetCommandBufferProxy()->SetUpdateVSyncParametersCallback(
57 update_vsync_parameters_callback_.callback());
58 return true;
61 void GpuBrowserCompositorOutputSurface::SwapBuffers(
62 cc::CompositorFrame* frame) {
63 DCHECK(frame->gl_frame_data);
65 GetCommandBufferProxy()->SetLatencyInfo(frame->metadata.latency_info);
67 if (reflector_) {
68 if (frame->gl_frame_data->sub_buffer_rect ==
69 gfx::Rect(frame->gl_frame_data->size))
70 reflector_->OnSourceSwapBuffers();
71 else
72 reflector_->OnSourcePostSubBuffer(frame->gl_frame_data->sub_buffer_rect);
75 if (frame->gl_frame_data->sub_buffer_rect ==
76 gfx::Rect(frame->gl_frame_data->size)) {
77 context_provider_->ContextSupport()->Swap();
78 } else {
79 context_provider_->ContextSupport()->PartialSwapBuffers(
80 frame->gl_frame_data->sub_buffer_rect);
83 client_->DidSwapBuffers();
85 #if defined(OS_MACOSX)
86 if (should_not_show_frames_)
87 should_not_show_frames_ = false;
88 #endif
91 void GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted(
92 const std::vector<ui::LatencyInfo>& latency_info) {
93 #if defined(OS_MACOSX)
94 // On Mac, delay acknowledging the swap to the output surface client until
95 // it has been drawn, see OnSurfaceDisplayed();
96 NOTREACHED();
97 #else
98 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
99 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info);
100 } else {
101 BrowserThread::PostTask(
102 BrowserThread::UI,
103 FROM_HERE,
104 base::Bind(&RenderWidgetHostImpl::CompositorFrameDrawn, latency_info));
106 OnSwapBuffersComplete();
107 #endif
110 #if defined(OS_MACOSX)
111 void GpuBrowserCompositorOutputSurface::OnSurfaceDisplayed() {
112 cc::OutputSurface::OnSwapBuffersComplete();
115 void GpuBrowserCompositorOutputSurface::OnSurfaceRecycled() {
116 // Discard the backbuffer immediately. This is necessary only when using a
117 // ImageTransportSurfaceFBO with a CALayerStorageProvider. Discarding the
118 // backbuffer results in the next frame using a new CALayer and CAContext,
119 // which guarantees that the browser will not flash stale content when adding
120 // the remote CALayer to the NSView hierarchy (it could flash stale content
121 // because the system window server is not synchronized with any signals we
122 // control or observe).
123 DiscardBackbuffer();
124 // It may be that there are frames in-flight from the GPU process back to the
125 // browser. Make sure that these frames are not displayed by ignoring them in
126 // GpuProcessHostUIShim, until the browser issues a SwapBuffers for the new
127 // content.
128 should_not_show_frames_ = true;
131 bool GpuBrowserCompositorOutputSurface::ShouldNotShowFramesAfterRecycle()
132 const {
133 return should_not_show_frames_;
135 #endif
137 } // namespace content