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"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/debug/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/sync_point_manager.h"
16 #include "content/common/gpu/texture_image_transport_surface.h"
17 #include "gpu/command_buffer/service/gpu_scheduler.h"
18 #include "ui/gfx/vsync_provider.h"
19 #include "ui/gl/gl_implementation.h"
20 #include "ui/gl/gl_switches.h"
24 ImageTransportSurface::ImageTransportSurface() {}
26 ImageTransportSurface::~ImageTransportSurface() {}
28 scoped_refptr
<gfx::GLSurface
> ImageTransportSurface::CreateSurface(
29 GpuChannelManager
* manager
,
30 GpuCommandBufferStub
* stub
,
31 const gfx::GLSurfaceHandle
& handle
) {
32 scoped_refptr
<gfx::GLSurface
> surface
;
33 if (handle
.transport_type
== gfx::TEXTURE_TRANSPORT
)
34 surface
= new TextureImageTransportSurface(manager
, stub
, handle
);
36 surface
= CreateNativeSurface(manager
, stub
, handle
);
38 if (!surface
.get() || !surface
->Initialize())
43 ImageTransportHelper::ImageTransportHelper(ImageTransportSurface
* surface
,
44 GpuChannelManager
* manager
,
45 GpuCommandBufferStub
* stub
,
46 gfx::PluginWindowHandle handle
)
49 stub_(stub
->AsWeakPtr()),
51 route_id_
= manager_
->GenerateRouteID();
52 manager_
->AddRoute(route_id_
, this);
55 ImageTransportHelper::~ImageTransportHelper() {
57 stub_
->SetLatencyInfoCallback(
58 base::Callback
<void(const std::vector
<ui::LatencyInfo
>&)>());
60 manager_
->RemoveRoute(route_id_
);
63 bool ImageTransportHelper::Initialize() {
64 gpu::gles2::GLES2Decoder
* decoder
= Decoder();
69 decoder
->SetResizeCallback(
70 base::Bind(&ImageTransportHelper::Resize
, base::Unretained(this)));
72 stub_
->SetLatencyInfoCallback(
73 base::Bind(&ImageTransportHelper::SetLatencyInfo
,
74 base::Unretained(this)));
76 manager_
->Send(new GpuHostMsg_AcceleratedSurfaceInitialized(
77 stub_
->surface_id(), route_id_
));
82 void ImageTransportHelper::Destroy() {}
84 bool ImageTransportHelper::OnMessageReceived(const IPC::Message
& message
) {
86 IPC_BEGIN_MESSAGE_MAP(ImageTransportHelper
, message
)
87 IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BufferPresented
,
89 IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_WakeUpGpu
, OnWakeUpGpu
);
90 IPC_MESSAGE_UNHANDLED(handled
= false)
95 void ImageTransportHelper::SendAcceleratedSurfaceBuffersSwapped(
96 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params
) {
97 // TRACE_EVENT for gpu tests:
98 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffers",
99 TRACE_EVENT_SCOPE_THREAD
,
100 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
101 "width", params
.size
.width());
102 params
.surface_id
= stub_
->surface_id();
103 params
.route_id
= route_id_
;
104 manager_
->Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params
));
107 void ImageTransportHelper::SendAcceleratedSurfacePostSubBuffer(
108 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params
) {
109 params
.surface_id
= stub_
->surface_id();
110 params
.route_id
= route_id_
;
111 manager_
->Send(new GpuHostMsg_AcceleratedSurfacePostSubBuffer(params
));
114 void ImageTransportHelper::SendAcceleratedSurfaceRelease() {
115 GpuHostMsg_AcceleratedSurfaceRelease_Params params
;
116 params
.surface_id
= stub_
->surface_id();
117 manager_
->Send(new GpuHostMsg_AcceleratedSurfaceRelease(params
));
120 void ImageTransportHelper::SendUpdateVSyncParameters(
121 base::TimeTicks timebase
, base::TimeDelta interval
) {
122 manager_
->Send(new GpuHostMsg_UpdateVSyncParameters(stub_
->surface_id(),
127 void ImageTransportHelper::SendLatencyInfo(
128 const std::vector
<ui::LatencyInfo
>& latency_info
) {
129 manager_
->Send(new GpuHostMsg_FrameDrawn(latency_info
));
132 void ImageTransportHelper::SetScheduled(bool is_scheduled
) {
133 gpu::GpuScheduler
* scheduler
= Scheduler();
137 scheduler
->SetScheduled(is_scheduled
);
140 void ImageTransportHelper::DeferToFence(base::Closure task
) {
141 gpu::GpuScheduler
* scheduler
= Scheduler();
144 scheduler
->DeferToFence(task
);
147 void ImageTransportHelper::SetPreemptByFlag(
148 scoped_refptr
<gpu::PreemptionFlag
> preemption_flag
) {
149 stub_
->channel()->SetPreemptByFlag(preemption_flag
);
152 bool ImageTransportHelper::MakeCurrent() {
153 gpu::gles2::GLES2Decoder
* decoder
= Decoder();
156 return decoder
->MakeCurrent();
159 void ImageTransportHelper::SetSwapInterval(gfx::GLContext
* context
) {
160 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync
))
161 context
->SetSwapInterval(0);
163 context
->SetSwapInterval(1);
166 void ImageTransportHelper::Suspend() {
167 manager_
->Send(new GpuHostMsg_AcceleratedSurfaceSuspend(stub_
->surface_id()));
170 gpu::GpuScheduler
* ImageTransportHelper::Scheduler() {
173 return stub_
->scheduler();
176 gpu::gles2::GLES2Decoder
* ImageTransportHelper::Decoder() {
179 return stub_
->decoder();
182 void ImageTransportHelper::OnBufferPresented(
183 const AcceleratedSurfaceMsg_BufferPresented_Params
& params
) {
184 surface_
->OnBufferPresented(params
);
187 void ImageTransportHelper::OnWakeUpGpu() {
188 surface_
->WakeUpGpu();
191 void ImageTransportHelper::Resize(gfx::Size size
, float scale_factor
) {
192 surface_
->OnResize(size
, scale_factor
);
194 #if defined(OS_ANDROID)
195 manager_
->gpu_memory_manager()->ScheduleManage(
196 GpuMemoryManager::kScheduleManageNow
);
200 void ImageTransportHelper::SetLatencyInfo(
201 const std::vector
<ui::LatencyInfo
>& latency_info
) {
202 surface_
->SetLatencyInfo(latency_info
);
205 PassThroughImageTransportSurface::PassThroughImageTransportSurface(
206 GpuChannelManager
* manager
,
207 GpuCommandBufferStub
* stub
,
208 gfx::GLSurface
* surface
)
209 : GLSurfaceAdapter(surface
),
210 did_set_swap_interval_(false) {
211 helper_
.reset(new ImageTransportHelper(this,
214 gfx::kNullPluginWindow
));
217 bool PassThroughImageTransportSurface::Initialize() {
218 // The surface is assumed to have already been initialized.
219 return helper_
->Initialize();
222 void PassThroughImageTransportSurface::Destroy() {
224 GLSurfaceAdapter::Destroy();
227 void PassThroughImageTransportSurface::SetLatencyInfo(
228 const std::vector
<ui::LatencyInfo
>& latency_info
) {
229 for (size_t i
= 0; i
< latency_info
.size(); i
++)
230 latency_info_
.push_back(latency_info
[i
]);
233 bool PassThroughImageTransportSurface::SwapBuffers() {
234 // GetVsyncValues before SwapBuffers to work around Mali driver bug:
236 SendVSyncUpdateIfAvailable();
237 bool result
= gfx::GLSurfaceAdapter::SwapBuffers();
238 for (size_t i
= 0; i
< latency_info_
.size(); i
++) {
239 latency_info_
[i
].AddLatencyNumber(
240 ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT
, 0, 0);
243 helper_
->SendLatencyInfo(latency_info_
);
244 latency_info_
.clear();
248 bool PassThroughImageTransportSurface::PostSubBuffer(
249 int x
, int y
, int width
, int height
) {
250 SendVSyncUpdateIfAvailable();
251 bool result
= gfx::GLSurfaceAdapter::PostSubBuffer(x
, y
, width
, height
);
252 for (size_t i
= 0; i
< latency_info_
.size(); i
++) {
253 latency_info_
[i
].AddLatencyNumber(
254 ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT
, 0, 0);
257 helper_
->SendLatencyInfo(latency_info_
);
258 latency_info_
.clear();
262 bool PassThroughImageTransportSurface::OnMakeCurrent(gfx::GLContext
* context
) {
263 if (!did_set_swap_interval_
) {
264 ImageTransportHelper::SetSwapInterval(context
);
265 did_set_swap_interval_
= true;
270 void PassThroughImageTransportSurface::OnBufferPresented(
271 const AcceleratedSurfaceMsg_BufferPresented_Params
& /* params */) {
275 void PassThroughImageTransportSurface::OnResize(gfx::Size size
,
276 float scale_factor
) {
280 gfx::Size
PassThroughImageTransportSurface::GetSize() {
281 return GLSurfaceAdapter::GetSize();
284 void PassThroughImageTransportSurface::WakeUpGpu() {
288 PassThroughImageTransportSurface::~PassThroughImageTransportSurface() {}
290 void PassThroughImageTransportSurface::SendVSyncUpdateIfAvailable() {
291 gfx::VSyncProvider
* vsync_provider
= GetVSyncProvider();
292 if (vsync_provider
) {
293 vsync_provider
->GetVSyncParameters(
294 base::Bind(&ImageTransportHelper::SendUpdateVSyncParameters
,
295 helper_
->AsWeakPtr()));
299 } // namespace content