[Android WebView] Fix webview perf bot switchover to use org.chromium.webview_shell...
[chromium-blink-merge.git] / content / common / gpu / image_transport_surface.cc
blob587d3a53b69337a7c551636c002cf86dc3837850
1 // Copyright (c) 2012 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/common/gpu/image_transport_surface.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/trace_event/trace_event.h"
11 #include "content/common/gpu/gpu_channel.h"
12 #include "content/common/gpu/gpu_channel_manager.h"
13 #include "content/common/gpu/gpu_command_buffer_stub.h"
14 #include "content/common/gpu/gpu_messages.h"
15 #include "content/common/gpu/null_transport_surface.h"
16 #include "gpu/command_buffer/service/sync_point_manager.h"
17 #include "ui/gfx/vsync_provider.h"
18 #include "ui/gl/gl_implementation.h"
19 #include "ui/gl/gl_switches.h"
21 namespace content {
23 ImageTransportSurface::ImageTransportSurface() {}
25 ImageTransportSurface::~ImageTransportSurface() {}
27 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateSurface(
28 GpuChannelManager* manager,
29 GpuCommandBufferStub* stub,
30 const gfx::GLSurfaceHandle& handle) {
31 scoped_refptr<gfx::GLSurface> surface;
32 if (handle.transport_type == gfx::NULL_TRANSPORT) {
33 #if defined(OS_ANDROID)
34 surface = CreateTransportSurface(manager, stub, handle);
35 #else
36 surface = new NullTransportSurface(manager, stub, handle);
37 #endif
38 } else {
39 surface = CreateNativeSurface(manager, stub, handle);
42 if (!surface.get() || !surface->Initialize())
43 return NULL;
44 return surface;
47 ImageTransportHelper::ImageTransportHelper(ImageTransportSurface* surface,
48 GpuChannelManager* manager,
49 GpuCommandBufferStub* stub,
50 gfx::PluginWindowHandle handle)
51 : surface_(surface),
52 manager_(manager),
53 stub_(stub->AsWeakPtr()),
54 handle_(handle) {
55 route_id_ = manager_->GenerateRouteID();
56 manager_->AddRoute(route_id_, this);
59 ImageTransportHelper::~ImageTransportHelper() {
60 if (stub_.get()) {
61 stub_->SetLatencyInfoCallback(
62 base::Callback<void(const std::vector<ui::LatencyInfo>&)>());
64 manager_->RemoveRoute(route_id_);
67 bool ImageTransportHelper::Initialize() {
68 gpu::gles2::GLES2Decoder* decoder = Decoder();
70 if (!decoder)
71 return false;
73 decoder->SetResizeCallback(
74 base::Bind(&ImageTransportHelper::Resize, base::Unretained(this)));
76 stub_->SetLatencyInfoCallback(
77 base::Bind(&ImageTransportHelper::SetLatencyInfo,
78 base::Unretained(this)));
80 manager_->Send(new GpuHostMsg_AcceleratedSurfaceInitialized(
81 stub_->surface_id(), route_id_));
83 return true;
86 bool ImageTransportHelper::OnMessageReceived(const IPC::Message& message) {
87 bool handled = true;
88 IPC_BEGIN_MESSAGE_MAP(ImageTransportHelper, message)
89 #if defined(OS_MACOSX)
90 IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BufferPresented,
91 OnBufferPresented)
92 #endif
93 IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_WakeUpGpu, OnWakeUpGpu);
94 IPC_MESSAGE_UNHANDLED(handled = false)
95 IPC_END_MESSAGE_MAP()
96 return handled;
99 #if defined(OS_MACOSX)
100 void ImageTransportHelper::SendAcceleratedSurfaceBuffersSwapped(
101 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params) {
102 // TRACE_EVENT for gpu tests:
103 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffers",
104 TRACE_EVENT_SCOPE_THREAD,
105 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
106 "width", params.size.width());
107 params.surface_id = stub_->surface_id();
108 params.route_id = route_id_;
109 manager_->Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));
111 #endif
113 void ImageTransportHelper::SetPreemptByFlag(
114 scoped_refptr<gpu::PreemptionFlag> preemption_flag) {
115 stub_->channel()->SetPreemptByFlag(preemption_flag);
118 bool ImageTransportHelper::MakeCurrent() {
119 gpu::gles2::GLES2Decoder* decoder = Decoder();
120 if (!decoder)
121 return false;
122 return decoder->MakeCurrent();
125 void ImageTransportHelper::SetSwapInterval(gfx::GLContext* context) {
126 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
127 switches::kDisableGpuVsync))
128 context->ForceSwapIntervalZero(true);
129 else
130 context->SetSwapInterval(1);
133 gpu::gles2::GLES2Decoder* ImageTransportHelper::Decoder() {
134 if (!stub_.get())
135 return NULL;
136 return stub_->decoder();
139 #if defined(OS_MACOSX)
140 void ImageTransportHelper::OnBufferPresented(
141 const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
142 surface_->OnBufferPresented(params);
144 #endif
146 void ImageTransportHelper::OnWakeUpGpu() {
147 surface_->WakeUpGpu();
150 void ImageTransportHelper::Resize(gfx::Size size, float scale_factor) {
151 surface_->OnResize(size, scale_factor);
153 #if defined(OS_ANDROID)
154 manager_->gpu_memory_manager()->ScheduleManage(
155 GpuMemoryManager::kScheduleManageNow);
156 #endif
159 void ImageTransportHelper::SetLatencyInfo(
160 const std::vector<ui::LatencyInfo>& latency_info) {
161 surface_->SetLatencyInfo(latency_info);
164 PassThroughImageTransportSurface::PassThroughImageTransportSurface(
165 GpuChannelManager* manager,
166 GpuCommandBufferStub* stub,
167 gfx::GLSurface* surface)
168 : GLSurfaceAdapter(surface),
169 did_set_swap_interval_(false),
170 weak_ptr_factory_(this) {
171 helper_.reset(new ImageTransportHelper(this,
172 manager,
173 stub,
174 gfx::kNullPluginWindow));
177 bool PassThroughImageTransportSurface::Initialize() {
178 // The surface is assumed to have already been initialized.
179 return helper_->Initialize();
182 void PassThroughImageTransportSurface::Destroy() {
183 GLSurfaceAdapter::Destroy();
186 void PassThroughImageTransportSurface::SetLatencyInfo(
187 const std::vector<ui::LatencyInfo>& latency_info) {
188 for (size_t i = 0; i < latency_info.size(); i++)
189 latency_info_.push_back(latency_info[i]);
192 gfx::SwapResult PassThroughImageTransportSurface::SwapBuffers() {
193 // GetVsyncValues before SwapBuffers to work around Mali driver bug:
194 // crbug.com/223558.
195 SendVSyncUpdateIfAvailable();
197 base::TimeTicks swap_time = base::TimeTicks::Now();
198 for (auto& latency : latency_info_) {
199 latency.AddLatencyNumberWithTimestamp(
200 ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1);
203 // We use WeakPtr here to avoid manual management of life time of an instance
204 // of this class. Callback will not be called once the instance of this class
205 // is destroyed. However, this also means that the callback can be run on
206 // the calling thread only.
207 std::vector<ui::LatencyInfo>* latency_info_ptr =
208 new std::vector<ui::LatencyInfo>();
209 latency_info_ptr->swap(latency_info_);
210 return gfx::GLSurfaceAdapter::SwapBuffersAsync(base::Bind(
211 &PassThroughImageTransportSurface::SwapBuffersCallBack,
212 weak_ptr_factory_.GetWeakPtr(), base::Owned(latency_info_ptr)))
213 ? gfx::SwapResult::SWAP_ACK
214 : gfx::SwapResult::SWAP_FAILED;
217 gfx::SwapResult PassThroughImageTransportSurface::PostSubBuffer(int x,
218 int y,
219 int width,
220 int height) {
221 SendVSyncUpdateIfAvailable();
223 base::TimeTicks swap_time = base::TimeTicks::Now();
224 for (auto& latency : latency_info_) {
225 latency.AddLatencyNumberWithTimestamp(
226 ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0, swap_time, 1);
229 // We use WeakPtr here to avoid manual management of life time of an instance
230 // of this class. Callback will not be called once the instance of this class
231 // is destroyed. However, this also means that the callback can be run on
232 // the calling thread only.
233 std::vector<ui::LatencyInfo>* latency_info_ptr =
234 new std::vector<ui::LatencyInfo>();
235 latency_info_ptr->swap(latency_info_);
236 return gfx::GLSurfaceAdapter::PostSubBufferAsync(
237 x, y, width, height,
238 base::Bind(&PassThroughImageTransportSurface::SwapBuffersCallBack,
239 weak_ptr_factory_.GetWeakPtr(),
240 base::Owned(latency_info_ptr)))
241 ? gfx::SwapResult::SWAP_ACK
242 : gfx::SwapResult::SWAP_FAILED;
245 void PassThroughImageTransportSurface::SwapBuffersCallBack(
246 std::vector<ui::LatencyInfo>* latency_info_ptr,
247 gfx::SwapResult result) {
248 base::TimeTicks swap_ack_time = base::TimeTicks::Now();
249 for (auto& latency : *latency_info_ptr) {
250 latency.AddLatencyNumberWithTimestamp(
251 ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0,
252 swap_ack_time, 1);
255 helper_->stub()->SendSwapBuffersCompleted(*latency_info_ptr, result);
258 bool PassThroughImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
259 if (!did_set_swap_interval_) {
260 ImageTransportHelper::SetSwapInterval(context);
261 did_set_swap_interval_ = true;
263 return true;
266 #if defined(OS_MACOSX)
267 void PassThroughImageTransportSurface::OnBufferPresented(
268 const AcceleratedSurfaceMsg_BufferPresented_Params& /* params */) {
269 NOTREACHED();
271 #endif
273 void PassThroughImageTransportSurface::OnResize(gfx::Size size,
274 float scale_factor) {
275 Resize(size);
278 gfx::Size PassThroughImageTransportSurface::GetSize() {
279 return GLSurfaceAdapter::GetSize();
282 void PassThroughImageTransportSurface::WakeUpGpu() {
283 NOTREACHED();
286 PassThroughImageTransportSurface::~PassThroughImageTransportSurface() {}
288 void PassThroughImageTransportSurface::SendVSyncUpdateIfAvailable() {
289 gfx::VSyncProvider* vsync_provider = GetVSyncProvider();
290 if (vsync_provider) {
291 vsync_provider->GetVSyncParameters(
292 base::Bind(&GpuCommandBufferStub::SendUpdateVSyncParameters,
293 helper_->stub()->AsWeakPtr()));
297 } // namespace content