Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / common / gpu / image_transport_surface.cc
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.
4
5 #include "content/common/gpu/image_transport_surface.h"
6
7 #include "base/bind.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/null_transport_surface.h"
16 #include "content/common/gpu/sync_point_manager.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"
21
22 namespace content {
23
24 ImageTransportSurface::ImageTransportSurface() {}
25
26 ImageTransportSurface::~ImageTransportSurface() {}
27
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::NULL_TRANSPORT) {
34 #if defined(OS_ANDROID)
35     surface = CreateTransportSurface(manager, stub, handle);
36 #else
37     surface = new NullTransportSurface(manager, stub, handle);
38 #endif
39   } else {
40     surface = CreateNativeSurface(manager, stub, handle);
41   }
42
43   if (!surface.get() || !surface->Initialize())
44     return NULL;
45   return surface;
46 }
47
48 ImageTransportHelper::ImageTransportHelper(ImageTransportSurface* surface,
49                                            GpuChannelManager* manager,
50                                            GpuCommandBufferStub* stub,
51                                            gfx::PluginWindowHandle handle)
52     : surface_(surface),
53       manager_(manager),
54       stub_(stub->AsWeakPtr()),
55       handle_(handle) {
56   route_id_ = manager_->GenerateRouteID();
57   manager_->AddRoute(route_id_, this);
58 }
59
60 ImageTransportHelper::~ImageTransportHelper() {
61   if (stub_.get()) {
62     stub_->SetLatencyInfoCallback(
63         base::Callback<void(const std::vector<ui::LatencyInfo>&)>());
64   }
65   manager_->RemoveRoute(route_id_);
66 }
67
68 bool ImageTransportHelper::Initialize() {
69   gpu::gles2::GLES2Decoder* decoder = Decoder();
70
71   if (!decoder)
72     return false;
73
74   decoder->SetResizeCallback(
75        base::Bind(&ImageTransportHelper::Resize, base::Unretained(this)));
76
77   stub_->SetLatencyInfoCallback(
78       base::Bind(&ImageTransportHelper::SetLatencyInfo,
79                  base::Unretained(this)));
80
81   manager_->Send(new GpuHostMsg_AcceleratedSurfaceInitialized(
82       stub_->surface_id(), route_id_));
83
84   return true;
85 }
86
87 bool ImageTransportHelper::OnMessageReceived(const IPC::Message& message) {
88   bool handled = true;
89   IPC_BEGIN_MESSAGE_MAP(ImageTransportHelper, message)
90 #if defined(OS_MACOSX)
91     IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_BufferPresented,
92                         OnBufferPresented)
93 #endif
94     IPC_MESSAGE_HANDLER(AcceleratedSurfaceMsg_WakeUpGpu, OnWakeUpGpu);
95     IPC_MESSAGE_UNHANDLED(handled = false)
96   IPC_END_MESSAGE_MAP()
97   return handled;
98 }
99
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));
110 }
111
112 void ImageTransportHelper::SendUpdateVSyncParameters(
113       base::TimeTicks timebase, base::TimeDelta interval) {
114   manager_->Send(new GpuHostMsg_UpdateVSyncParameters(stub_->surface_id(),
115                                                       timebase,
116                                                       interval));
117 }
118
119 void ImageTransportHelper::SwapBuffersCompleted(
120     const std::vector<ui::LatencyInfo>& latency_info) {
121   stub_->SwapBuffersCompleted(latency_info);
122 }
123
124 void ImageTransportHelper::SetScheduled(bool is_scheduled) {
125   gpu::GpuScheduler* scheduler = Scheduler();
126   if (!scheduler)
127     return;
128
129   scheduler->SetScheduled(is_scheduled);
130 }
131
132 void ImageTransportHelper::DeferToFence(base::Closure task) {
133   gpu::GpuScheduler* scheduler = Scheduler();
134   DCHECK(scheduler);
135
136   scheduler->DeferToFence(task);
137 }
138
139 void ImageTransportHelper::SetPreemptByFlag(
140     scoped_refptr<gpu::PreemptionFlag> preemption_flag) {
141   stub_->channel()->SetPreemptByFlag(preemption_flag);
142 }
143
144 bool ImageTransportHelper::MakeCurrent() {
145   gpu::gles2::GLES2Decoder* decoder = Decoder();
146   if (!decoder)
147     return false;
148   return decoder->MakeCurrent();
149 }
150
151 void ImageTransportHelper::SetSwapInterval(gfx::GLContext* context) {
152   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync))
153     context->SetSwapInterval(0);
154   else
155     context->SetSwapInterval(1);
156 }
157
158 gpu::GpuScheduler* ImageTransportHelper::Scheduler() {
159   if (!stub_.get())
160     return NULL;
161   return stub_->scheduler();
162 }
163
164 gpu::gles2::GLES2Decoder* ImageTransportHelper::Decoder() {
165   if (!stub_.get())
166     return NULL;
167   return stub_->decoder();
168 }
169
170 #if defined(OS_MACOSX)
171 void ImageTransportHelper::OnBufferPresented(
172     const AcceleratedSurfaceMsg_BufferPresented_Params& params) {
173   surface_->OnBufferPresented(params);
174 }
175 #endif
176
177 void ImageTransportHelper::OnWakeUpGpu() {
178   surface_->WakeUpGpu();
179 }
180
181 void ImageTransportHelper::Resize(gfx::Size size, float scale_factor) {
182   surface_->OnResize(size, scale_factor);
183
184 #if defined(OS_ANDROID)
185   manager_->gpu_memory_manager()->ScheduleManage(
186       GpuMemoryManager::kScheduleManageNow);
187 #endif
188 }
189
190 void ImageTransportHelper::SetLatencyInfo(
191     const std::vector<ui::LatencyInfo>& latency_info) {
192   surface_->SetLatencyInfo(latency_info);
193 }
194
195 PassThroughImageTransportSurface::PassThroughImageTransportSurface(
196     GpuChannelManager* manager,
197     GpuCommandBufferStub* stub,
198     gfx::GLSurface* surface)
199     : GLSurfaceAdapter(surface),
200       did_set_swap_interval_(false) {
201   helper_.reset(new ImageTransportHelper(this,
202                                          manager,
203                                          stub,
204                                          gfx::kNullPluginWindow));
205 }
206
207 bool PassThroughImageTransportSurface::Initialize() {
208   // The surface is assumed to have already been initialized.
209   return helper_->Initialize();
210 }
211
212 void PassThroughImageTransportSurface::Destroy() {
213   GLSurfaceAdapter::Destroy();
214 }
215
216 void PassThroughImageTransportSurface::SetLatencyInfo(
217     const std::vector<ui::LatencyInfo>& latency_info) {
218   for (size_t i = 0; i < latency_info.size(); i++)
219     latency_info_.push_back(latency_info[i]);
220 }
221
222 bool PassThroughImageTransportSurface::SwapBuffers() {
223   // GetVsyncValues before SwapBuffers to work around Mali driver bug:
224   // crbug.com/223558.
225   SendVSyncUpdateIfAvailable();
226   for (size_t i = 0; i < latency_info_.size(); ++i) {
227     latency_info_[i].AddLatencyNumber(
228         ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, 0);
229   }
230   bool result = gfx::GLSurfaceAdapter::SwapBuffers();
231   for (size_t i = 0; i < latency_info_.size(); i++) {
232     latency_info_[i].AddLatencyNumber(
233         ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0);
234   }
235
236   helper_->SwapBuffersCompleted(latency_info_);
237   latency_info_.clear();
238   return result;
239 }
240
241 bool PassThroughImageTransportSurface::PostSubBuffer(
242     int x, int y, int width, int height) {
243   SendVSyncUpdateIfAvailable();
244   bool result = gfx::GLSurfaceAdapter::PostSubBuffer(x, y, width, height);
245   for (size_t i = 0; i < latency_info_.size(); i++) {
246     latency_info_[i].AddLatencyNumber(
247         ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, 0);
248   }
249
250   helper_->SwapBuffersCompleted(latency_info_);
251   latency_info_.clear();
252   return result;
253 }
254
255 bool PassThroughImageTransportSurface::OnMakeCurrent(gfx::GLContext* context) {
256   if (!did_set_swap_interval_) {
257     ImageTransportHelper::SetSwapInterval(context);
258     did_set_swap_interval_ = true;
259   }
260   return true;
261 }
262
263 #if defined(OS_MACOSX)
264 void PassThroughImageTransportSurface::OnBufferPresented(
265     const AcceleratedSurfaceMsg_BufferPresented_Params& /* params */) {
266   NOTREACHED();
267 }
268 #endif
269
270 void PassThroughImageTransportSurface::OnResize(gfx::Size size,
271                                                 float scale_factor) {
272   Resize(size);
273 }
274
275 gfx::Size PassThroughImageTransportSurface::GetSize() {
276   return GLSurfaceAdapter::GetSize();
277 }
278
279 void PassThroughImageTransportSurface::WakeUpGpu() {
280   NOTREACHED();
281 }
282
283 PassThroughImageTransportSurface::~PassThroughImageTransportSurface() {}
284
285 void PassThroughImageTransportSurface::SendVSyncUpdateIfAvailable() {
286   gfx::VSyncProvider* vsync_provider = GetVSyncProvider();
287   if (vsync_provider) {
288     vsync_provider->GetVSyncParameters(
289       base::Bind(&ImageTransportHelper::SendUpdateVSyncParameters,
290                  helper_->AsWeakPtr()));
291   }
292 }
293
294 }  // namespace content