1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
#include "cc/output/compositor_frame.h"
#include "cc/output/output_surface_client.h"
#include "content/browser/compositor/reflector_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/common/gpu/client/context_provider_command_buffer.h"
#include "content/public/browser/browser_thread.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
namespace content {
GpuBrowserCompositorOutputSurface::GpuBrowserCompositorOutputSurface(
const scoped_refptr<ContextProviderCommandBuffer>& context,
int surface_id,
IDMap<BrowserCompositorOutputSurface>* output_surface_map,
const scoped_refptr<ui::CompositorVSyncManager>& vsync_manager,
scoped_ptr<cc::OverlayCandidateValidator> overlay_candidate_validator)
: BrowserCompositorOutputSurface(context,
surface_id,
output_surface_map,
vsync_manager),
#if defined(OS_MACOSX)
should_not_show_frames_(false),
#endif
swap_buffers_completion_callback_(
base::Bind(&GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted,
base::Unretained(this))) {
overlay_candidate_validator_ = overlay_candidate_validator.Pass();
}
GpuBrowserCompositorOutputSurface::~GpuBrowserCompositorOutputSurface() {}
CommandBufferProxyImpl*
GpuBrowserCompositorOutputSurface::GetCommandBufferProxy() {
ContextProviderCommandBuffer* provider_command_buffer =
static_cast<content::ContextProviderCommandBuffer*>(
context_provider_.get());
CommandBufferProxyImpl* command_buffer_proxy =
provider_command_buffer->GetCommandBufferProxy();
DCHECK(command_buffer_proxy);
return command_buffer_proxy;
}
bool GpuBrowserCompositorOutputSurface::BindToClient(
cc::OutputSurfaceClient* client) {
if (!BrowserCompositorOutputSurface::BindToClient(client))
return false;
GetCommandBufferProxy()->SetSwapBuffersCompletionCallback(
swap_buffers_completion_callback_.callback());
return true;
}
void GpuBrowserCompositorOutputSurface::SwapBuffers(
cc::CompositorFrame* frame) {
DCHECK(frame->gl_frame_data);
GetCommandBufferProxy()->SetLatencyInfo(frame->metadata.latency_info);
if (reflector_.get()) {
if (frame->gl_frame_data->sub_buffer_rect ==
gfx::Rect(frame->gl_frame_data->size))
reflector_->OnSwapBuffers();
else
reflector_->OnPostSubBuffer(frame->gl_frame_data->sub_buffer_rect);
}
if (frame->gl_frame_data->sub_buffer_rect ==
gfx::Rect(frame->gl_frame_data->size)) {
context_provider_->ContextSupport()->Swap();
} else {
context_provider_->ContextSupport()->PartialSwapBuffers(
frame->gl_frame_data->sub_buffer_rect);
}
client_->DidSwapBuffers();
#if defined(OS_MACOSX)
if (should_not_show_frames_)
should_not_show_frames_ = false;
#endif
}
void GpuBrowserCompositorOutputSurface::OnSwapBuffersCompleted(
const std::vector<ui::LatencyInfo>& latency_info) {
#if defined(OS_MACOSX)
// On Mac, delay acknowledging the swap to the output surface client until
// it has been drawn, see OnSurfaceDisplayed();
NOTREACHED();
#else
if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
RenderWidgetHostImpl::CompositorFrameDrawn(latency_info);
} else {
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
base::Bind(&RenderWidgetHostImpl::CompositorFrameDrawn, latency_info));
}
OnSwapBuffersComplete();
#endif
}
#if defined(OS_MACOSX)
void GpuBrowserCompositorOutputSurface::OnSurfaceDisplayed() {
cc::OutputSurface::OnSwapBuffersComplete();
}
void GpuBrowserCompositorOutputSurface::OnSurfaceRecycled() {
// Discard the backbuffer immediately. This is necessary only when using a
// ImageTransportSurfaceFBO with a CALayerStorageProvider. Discarding the
// backbuffer results in the next frame using a new CALayer and CAContext,
// which guarantees that the browser will not flash stale content when adding
// the remote CALayer to the NSView hierarchy (it could flash stale content
// because the system window server is not synchronized with any signals we
// control or observe).
DiscardBackbuffer();
// It may be that there are frames in-flight from the GPU process back to the
// browser. Make sure that these frames are not displayed by ignoring them in
// GpuProcessHostUIShim, until the browser issues a SwapBuffers for the new
// content.
should_not_show_frames_ = true;
}
bool GpuBrowserCompositorOutputSurface::ShouldNotShowFramesAfterRecycle()
const {
return should_not_show_frames_;
}
#endif
} // namespace content
|