blob: 5e741eec44db823939d97dd955ef91b7980484f7 [file] [log] [blame]
[email protected]04d58ce2011-09-29 13:12:231 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]246a70452010-03-05 21:53:502// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#if defined(ENABLE_GPU)
6
[email protected]80c49752011-04-18 23:55:107#include "base/bind.h"
[email protected]9d37f062011-11-22 01:24:528#include "base/bind_helpers.h"
[email protected]79311e82011-09-20 00:40:509#include "base/command_line.h"
[email protected]366ae242011-05-10 02:23:5810#include "base/debug/trace_event.h"
[email protected]246a70452010-03-05 21:53:5011#include "base/shared_memory.h"
[email protected]6217d392010-03-25 22:08:3512#include "build/build_config.h"
[email protected]f24a1e2b2011-04-08 01:48:4813#include "content/common/gpu/gpu_channel.h"
14#include "content/common/gpu/gpu_channel_manager.h"
15#include "content/common/gpu/gpu_command_buffer_stub.h"
[email protected]202b54ff2011-04-22 21:36:3816#include "content/common/gpu/gpu_messages.h"
[email protected]2dcf7022011-04-15 19:20:4117#include "content/common/gpu/gpu_watchdog.h"
[email protected]16aa68e2011-11-21 23:40:0218#include "gpu/command_buffer/common/constants.h"
[email protected]16aa68e2011-11-21 23:40:0219#include "ui/gfx/gl/gl_switches.h"
[email protected]dc683122011-11-18 02:22:5920
[email protected]bc4a3432011-11-21 23:55:5621#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
22#include "content/common/gpu/image_transport_surface.h"
23#endif
24
[email protected]a3ded6d2010-10-19 06:44:3925GpuCommandBufferStub::GpuCommandBufferStub(
26 GpuChannel* channel,
[email protected]3b1ecc262011-08-03 22:49:5727 GpuCommandBufferStub* share_group,
[email protected]a3ded6d2010-10-19 06:44:3928 gfx::PluginWindowHandle handle,
[email protected]a3ded6d2010-10-19 06:44:3929 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:2930 const gpu::gles2::DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:3931 const std::string& allowed_extensions,
32 const std::vector<int32>& attribs,
[email protected]276f89062011-10-13 22:55:5033 gfx::GpuPreference gpu_preference,
[email protected]a3ded6d2010-10-19 06:44:3934 int32 route_id,
35 int32 renderer_id,
[email protected]808f7fe72011-03-23 03:49:0236 int32 render_view_id,
[email protected]f81f5952011-07-21 18:52:4737 GpuWatchdog* watchdog,
38 bool software)
[email protected]246a70452010-03-05 21:53:5039 : channel_(channel),
[email protected]6ebf2fc2010-07-01 01:06:3240 handle_(handle),
[email protected]6217d392010-03-25 22:08:3541 initial_size_(size),
[email protected]e82fb792011-09-22 00:33:2942 disallowed_features_(disallowed_features),
[email protected]bc518752010-10-20 21:38:2743 allowed_extensions_(allowed_extensions),
[email protected]34ff8b0c2010-10-01 20:06:0244 requested_attribs_(attribs),
[email protected]276f89062011-10-13 22:55:5045 gpu_preference_(gpu_preference),
[email protected]77e74db2010-08-04 17:46:2346 route_id_(route_id),
[email protected]f81f5952011-07-21 18:52:4747 software_(software),
[email protected]a38477142011-05-28 02:45:5848 last_flush_count_(0),
[email protected]77e74db2010-08-04 17:46:2349 renderer_id_(renderer_id),
[email protected]808f7fe72011-03-23 03:49:0250 render_view_id_(render_view_id),
[email protected]e7da6aef2011-06-22 19:29:0351 parent_stub_for_initialization_(),
52 parent_texture_for_initialization_(0),
[email protected]35a5b752011-11-17 23:58:5853 watchdog_(watchdog) {
[email protected]bf5a8d132011-08-16 08:39:3554 if (share_group) {
[email protected]3b1ecc262011-08-03 22:49:5755 context_group_ = share_group->context_group_;
[email protected]bf5a8d132011-08-16 08:39:3556 } else {
57 // TODO(gman): this needs to be false for everything but Pepper.
58 bool bind_generates_resource = true;
59 context_group_ = new gpu::gles2::ContextGroup(bind_generates_resource);
60 }
[email protected]246a70452010-03-05 21:53:5061}
62
63GpuCommandBufferStub::~GpuCommandBufferStub() {
[email protected]79311e82011-09-20 00:40:5064 Destroy();
[email protected]d8a58e42011-01-27 15:24:2565
[email protected]f24a1e2b2011-04-08 01:48:4866 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
67 gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer(
[email protected]d8a58e42011-01-27 15:24:2568 handle_, renderer_id_, render_view_id_));
[email protected]246a70452010-03-05 21:53:5069}
70
[email protected]a95986a82010-12-24 06:19:2871bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
[email protected]79311e82011-09-20 00:40:5072 // Ensure the appropriate GL context is current before handling any IPC
73 // messages directed at the command buffer. This ensures that the message
74 // handler can assume that the context is current.
75 if (decoder_.get()) {
76 if (!decoder_->MakeCurrent()) {
[email protected]cc63025a2011-10-29 02:16:2477 DLOG(ERROR) << "Context lost because MakeCurrent failed.";
[email protected]79311e82011-09-20 00:40:5078 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
79 command_buffer_->SetParseError(gpu::error::kLostContext);
[email protected]8b34cf42011-09-23 20:53:5880 if (gfx::GLContext::LosesAllContextsOnContextLost())
81 channel_->LoseAllContexts();
[email protected]79311e82011-09-20 00:40:5082 return false;
83 }
84 }
85
[email protected]310bed512011-05-09 21:12:2586 // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
87 // here. This is so the reply can be delayed if the scheduler is unscheduled.
[email protected]a95986a82010-12-24 06:19:2888 bool handled = true;
[email protected]246a70452010-03-05 21:53:5089 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
[email protected]310bed512011-05-09 21:12:2590 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize,
91 OnInitialize);
[email protected]3c644d82011-06-20 19:58:2492 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetParent,
93 OnSetParent);
[email protected]310bed512011-05-09 21:12:2594 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState);
[email protected]451e9662011-10-10 21:14:3495 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetStateFast,
96 OnGetStateFast);
[email protected]246a70452010-03-05 21:53:5097 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
[email protected]d0f02c42011-07-21 21:40:4898 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Rescheduled, OnRescheduled);
[email protected]310bed512011-05-09 21:12:2599 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateTransferBuffer,
100 OnCreateTransferBuffer);
101 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_RegisterTransferBuffer,
102 OnRegisterTransferBuffer);
103 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_DestroyTransferBuffer,
104 OnDestroyTransferBuffer);
105 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetTransferBuffer,
106 OnGetTransferBuffer);
[email protected]c8423062011-07-29 19:25:38107 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder,
108 OnCreateVideoDecoder)
[email protected]a13da242011-07-07 19:48:17109 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyVideoDecoder,
110 OnDestroyVideoDecoder)
[email protected]8cc980c52011-10-14 20:35:51111 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetSurfaceVisible,
112 OnSetSurfaceVisible)
[email protected]a95986a82010-12-24 06:19:28113 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]246a70452010-03-05 21:53:50114 IPC_END_MESSAGE_MAP()
[email protected]a13da242011-07-07 19:48:17115
[email protected]a95986a82010-12-24 06:19:28116 DCHECK(handled);
117 return handled;
[email protected]246a70452010-03-05 21:53:50118}
119
120bool GpuCommandBufferStub::Send(IPC::Message* message) {
121 return channel_->Send(message);
122}
123
[email protected]d0f02c42011-07-21 21:40:48124bool GpuCommandBufferStub::IsScheduled() {
125 return !scheduler_.get() || scheduler_->IsScheduled();
126}
127
[email protected]79311e82011-09-20 00:40:50128void GpuCommandBufferStub::Destroy() {
129 // The scheduler has raw references to the decoder and the command buffer so
130 // destroy it before those.
[email protected]4ee0c3052011-09-16 19:30:36131 scheduler_.reset();
[email protected]79311e82011-09-20 00:40:50132
133 if (decoder_.get()) {
134 decoder_->Destroy();
135 decoder_.reset();
136 }
137
[email protected]4ee0c3052011-09-16 19:30:36138 command_buffer_.reset();
[email protected]79311e82011-09-20 00:40:50139
140 context_ = NULL;
141 surface_ = NULL;
[email protected]79311e82011-09-20 00:40:50142}
143
144void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) {
145 Destroy();
[email protected]2e7bbf22011-07-22 18:41:29146 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, false);
147 Send(reply_message);
148}
149
[email protected]246a70452010-03-05 21:53:50150void GpuCommandBufferStub::OnInitialize(
[email protected]36dbfe12011-02-28 23:36:54151 base::SharedMemoryHandle ring_buffer,
[email protected]246a70452010-03-05 21:53:50152 int32 size,
[email protected]310bed512011-05-09 21:12:25153 IPC::Message* reply_message) {
[email protected]246a70452010-03-05 21:53:50154 DCHECK(!command_buffer_.get());
155
[email protected]246a70452010-03-05 21:53:50156 command_buffer_.reset(new gpu::CommandBufferService);
157
[email protected]36dbfe12011-02-28 23:36:54158#if defined(OS_WIN)
159 // Windows dups the shared memory handle it receives into the current process
160 // and closes it when this variable goes out of scope.
161 base::SharedMemory shared_memory(ring_buffer,
162 false,
163 channel_->renderer_process());
164#else
165 // POSIX receives a dup of the shared memory handle and closes the dup when
166 // this variable goes out of scope.
167 base::SharedMemory shared_memory(ring_buffer, false);
168#endif
[email protected]246a70452010-03-05 21:53:50169
[email protected]79311e82011-09-20 00:40:50170 if (!command_buffer_->Initialize(&shared_memory, size)) {
171 OnInitializeFailed(reply_message);
172 return;
173 }
174
175 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get()));
176
177 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
178 decoder_.get(),
179 NULL));
180
181 decoder_->set_engine(scheduler_.get());
182
183 if (handle_) {
[email protected]839d5172011-10-13 17:18:11184#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]2e7bbf22011-07-22 18:41:29185 if (software_) {
186 OnInitializeFailed(reply_message);
187 return;
188 }
189
[email protected]79311e82011-09-20 00:40:50190 surface_ = ImageTransportSurface::CreateSurface(
191 channel_->gpu_channel_manager(),
192 render_view_id_,
193 renderer_id_,
[email protected]04d58ce2011-09-29 13:12:23194 route_id_,
195 handle_);
[email protected]bc4a3432011-11-21 23:55:56196#elif defined(OS_WIN) || defined(OS_LINUX) || defined(OS_OPENBSD)
197 surface_ = gfx::GLSurface::CreateViewGLSurface(software_, handle_);
198#endif
[email protected]79311e82011-09-20 00:40:50199 } else {
200 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_,
201 gfx::Size(1, 1));
202 }
203
204 if (!surface_.get()) {
[email protected]cdcd5bd2011-10-15 00:19:38205 // Ensure the decoder is not destroyed if it is not initialized.
206 decoder_.reset();
207
[email protected]cc63025a2011-10-29 02:16:24208 DLOG(ERROR) << "Failed to create surface.\n";
[email protected]79311e82011-09-20 00:40:50209 OnInitializeFailed(reply_message);
210 return;
211 }
212
[email protected]276f89062011-10-13 22:55:50213 gfx::GpuPreference gpu_preference =
214 channel_->ShouldPreferDiscreteGpu() ?
215 gfx::PreferDiscreteGpu : gpu_preference_;
216
217 context_ = gfx::GLContext::CreateGLContext(
218 channel_->share_group(),
219 surface_.get(),
220 gpu_preference);
[email protected]79311e82011-09-20 00:40:50221 if (!context_.get()) {
[email protected]cdcd5bd2011-10-15 00:19:38222 // Ensure the decoder is not destroyed if it is not initialized.
223 decoder_.reset();
224
[email protected]cc63025a2011-10-29 02:16:24225 DLOG(ERROR) << "Failed to create context.\n";
[email protected]79311e82011-09-20 00:40:50226 OnInitializeFailed(reply_message);
227 return;
228 }
[email protected]4bbe6d0c2011-09-16 18:58:54229
[email protected]79311e82011-09-20 00:40:50230 // Initialize the decoder with either the view or pbuffer GLContext.
231 if (!decoder_->Initialize(surface_.get(),
232 context_.get(),
233 initial_size_,
[email protected]e82fb792011-09-22 00:33:29234 disallowed_features_,
[email protected]79311e82011-09-20 00:40:50235 allowed_extensions_.c_str(),
236 requested_attribs_)) {
[email protected]cc63025a2011-10-29 02:16:24237 DLOG(ERROR) << "Failed to initialize decoder.";
[email protected]79311e82011-09-20 00:40:50238 OnInitializeFailed(reply_message);
239 return;
240 }
241
242 if (CommandLine::ForCurrentProcess()->HasSwitch(
243 switches::kEnableGPUServiceLogging)) {
244 decoder_->set_debug(true);
245 }
246
[email protected]ebe71442011-09-30 02:11:57247 SetSwapInterval();
248
[email protected]79311e82011-09-20 00:40:50249 command_buffer_->SetPutOffsetChangeCallback(
[email protected]9d37f062011-11-22 01:24:52250 base::Bind(&gpu::GpuScheduler::PutChanged,
251 base::Unretained(scheduler_.get())));
[email protected]79311e82011-09-20 00:40:50252 command_buffer_->SetParseErrorCallback(
[email protected]9d37f062011-11-22 01:24:52253 base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50254 scheduler_->SetScheduledCallback(
[email protected]9d37f062011-11-22 01:24:52255 base::Bind(&GpuChannel::OnScheduled, base::Unretained(channel_)));
[email protected]79311e82011-09-20 00:40:50256
[email protected]bc4a3432011-11-21 23:55:56257 // On platforms that use an ImageTransportSurface, the surface
258 // handles co-ordinating the resize with the browser process. The
259 // surface sets it's own resize callback, so we shouldn't do it here.
260#if !defined(OS_MACOSX) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
261 if (handle_ != gfx::kNullPluginWindow) {
262 decoder_->SetResizeCallback(
[email protected]9d37f062011-11-22 01:24:52263 base::Bind(&GpuCommandBufferStub::OnResize, base::Unretained(this)));
[email protected]bc4a3432011-11-21 23:55:56264 }
265#endif
266
[email protected]79311e82011-09-20 00:40:50267 if (watchdog_) {
268 scheduler_->SetCommandProcessedCallback(
[email protected]9d37f062011-11-22 01:24:52269 base::Bind(&GpuCommandBufferStub::OnCommandProcessed,
270 base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50271 }
272
273 if (parent_stub_for_initialization_) {
274 decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(),
275 parent_texture_for_initialization_);
276 parent_stub_for_initialization_.reset();
277 parent_texture_for_initialization_ = 0;
278 }
[email protected]310bed512011-05-09 21:12:25279
[email protected]2e7bbf22011-07-22 18:41:29280 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, true);
[email protected]310bed512011-05-09 21:12:25281 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50282}
283
[email protected]3c644d82011-06-20 19:58:24284void GpuCommandBufferStub::OnSetParent(int32 parent_route_id,
285 uint32 parent_texture_id,
286 IPC::Message* reply_message) {
[email protected]3c644d82011-06-20 19:58:24287
[email protected]e7da6aef2011-06-22 19:29:03288 GpuCommandBufferStub* parent_stub = NULL;
289 if (parent_route_id != MSG_ROUTING_NONE) {
290 parent_stub = channel_->LookupCommandBuffer(parent_route_id);
[email protected]3c644d82011-06-20 19:58:24291 }
292
[email protected]e7da6aef2011-06-22 19:29:03293 bool result = true;
294 if (scheduler_.get()) {
[email protected]79311e82011-09-20 00:40:50295 gpu::gles2::GLES2Decoder* parent_decoder =
296 parent_stub ? parent_stub->decoder_.get() : NULL;
297 result = decoder_->SetParent(parent_decoder, parent_texture_id);
[email protected]e7da6aef2011-06-22 19:29:03298 } else {
299 // If we don't have a scheduler, it means that Initialize hasn't been called
300 // yet. Keep around the requested parent stub and texture so that we can set
301 // it in Initialize().
302 parent_stub_for_initialization_ = parent_stub ?
303 parent_stub->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>();
304 parent_texture_for_initialization_ = parent_texture_id;
305 }
[email protected]3c644d82011-06-20 19:58:24306 GpuCommandBufferMsg_SetParent::WriteReplyParams(reply_message, result);
307 Send(reply_message);
308}
309
[email protected]310bed512011-05-09 21:12:25310void GpuCommandBufferStub::OnGetState(IPC::Message* reply_message) {
311 gpu::CommandBuffer::State state = command_buffer_->GetState();
312 if (state.error == gpu::error::kLostContext &&
[email protected]ef16c172011-04-28 23:37:14313 gfx::GLContext::LosesAllContextsOnContextLost())
314 channel_->LoseAllContexts();
[email protected]310bed512011-05-09 21:12:25315
316 GpuCommandBufferMsg_GetState::WriteReplyParams(reply_message, state);
317 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50318}
319
[email protected]0a68ac872011-06-07 04:48:27320void GpuCommandBufferStub::OnParseError() {
321 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnParseError");
[email protected]38d139d2011-07-14 00:38:43322 gpu::CommandBuffer::State state = command_buffer_->GetState();
323 IPC::Message* msg = new GpuCommandBufferMsg_Destroyed(
324 route_id_, state.context_lost_reason);
[email protected]0a68ac872011-06-07 04:48:27325 msg->set_unblock(true);
326 Send(msg);
327}
328
[email protected]451e9662011-10-10 21:14:34329void GpuCommandBufferStub::OnGetStateFast(IPC::Message* reply_message) {
330 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetStateFast");
[email protected]d0f02c42011-07-21 21:40:48331 gpu::CommandBuffer::State state = command_buffer_->GetState();
[email protected]451e9662011-10-10 21:14:34332 if (state.error == gpu::error::kLostContext &&
333 gfx::GLContext::LosesAllContextsOnContextLost())
334 channel_->LoseAllContexts();
[email protected]1d4ea842011-07-20 01:11:51335
[email protected]451e9662011-10-10 21:14:34336 GpuCommandBufferMsg_GetStateFast::WriteReplyParams(reply_message, state);
337 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50338}
339
[email protected]451e9662011-10-10 21:14:34340void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset,
341 uint32 flush_count) {
342 TRACE_EVENT1("gpu", "GpuCommandBufferStub::OnAsyncFlush",
343 "put_offset", put_offset);
[email protected]fde205d2011-05-31 22:29:50344 if (flush_count - last_flush_count_ < 0x8000000U) {
[email protected]a38477142011-05-28 02:45:58345 last_flush_count_ = flush_count;
346 command_buffer_->Flush(put_offset);
347 } else {
[email protected]fde205d2011-05-31 22:29:50348 // We received this message out-of-order. This should not happen but is here
349 // to catch regressions. Ignore the message.
350 NOTREACHED() << "Received a Flush message out-of-order";
[email protected]a38477142011-05-28 02:45:58351 }
[email protected]d0f02c42011-07-21 21:40:48352
353 ReportState();
354}
355
356void GpuCommandBufferStub::OnRescheduled() {
357 gpu::CommandBuffer::State state = command_buffer_->GetLastState();
358 command_buffer_->Flush(state.put_offset);
359
360 ReportState();
[email protected]246a70452010-03-05 21:53:50361}
362
[email protected]ce9eea602011-04-12 20:09:57363void GpuCommandBufferStub::OnCreateTransferBuffer(int32 size,
364 int32 id_request,
[email protected]310bed512011-05-09 21:12:25365 IPC::Message* reply_message) {
366 int32 id = command_buffer_->CreateTransferBuffer(size, id_request);
367 GpuCommandBufferMsg_CreateTransferBuffer::WriteReplyParams(reply_message, id);
368 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50369}
370
[email protected]0100b7a2011-02-24 22:54:50371void GpuCommandBufferStub::OnRegisterTransferBuffer(
372 base::SharedMemoryHandle transfer_buffer,
373 size_t size,
[email protected]ce9eea602011-04-12 20:09:57374 int32 id_request,
[email protected]310bed512011-05-09 21:12:25375 IPC::Message* reply_message) {
[email protected]0100b7a2011-02-24 22:54:50376#if defined(OS_WIN)
[email protected]7df1d1a2011-02-26 02:07:57377 // Windows dups the shared memory handle it receives into the current process
378 // and closes it when this variable goes out of scope.
[email protected]0100b7a2011-02-24 22:54:50379 base::SharedMemory shared_memory(transfer_buffer,
380 false,
381 channel_->renderer_process());
382#else
[email protected]7df1d1a2011-02-26 02:07:57383 // POSIX receives a dup of the shared memory handle and closes the dup when
384 // this variable goes out of scope.
[email protected]0100b7a2011-02-24 22:54:50385 base::SharedMemory shared_memory(transfer_buffer, false);
386#endif
[email protected]7df1d1a2011-02-26 02:07:57387
[email protected]310bed512011-05-09 21:12:25388 int32 id = command_buffer_->RegisterTransferBuffer(&shared_memory,
389 size,
390 id_request);
391
392 GpuCommandBufferMsg_RegisterTransferBuffer::WriteReplyParams(reply_message,
393 id);
394 Send(reply_message);
[email protected]0100b7a2011-02-24 22:54:50395}
396
[email protected]310bed512011-05-09 21:12:25397void GpuCommandBufferStub::OnDestroyTransferBuffer(
398 int32 id,
399 IPC::Message* reply_message) {
[email protected]246a70452010-03-05 21:53:50400 command_buffer_->DestroyTransferBuffer(id);
[email protected]310bed512011-05-09 21:12:25401 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50402}
403
404void GpuCommandBufferStub::OnGetTransferBuffer(
405 int32 id,
[email protected]310bed512011-05-09 21:12:25406 IPC::Message* reply_message) {
407 base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle();
408 uint32 size = 0;
[email protected]246a70452010-03-05 21:53:50409
[email protected]0100b7a2011-02-24 22:54:50410 // Fail if the renderer process has not provided its process handle.
411 if (!channel_->renderer_process())
412 return;
413
[email protected]79311e82011-09-20 00:40:50414 gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id);
[email protected]246a70452010-03-05 21:53:50415 if (buffer.shared_memory) {
416 // Assume service is responsible for duplicating the handle to the calling
417 // process.
[email protected]0100b7a2011-02-24 22:54:50418 buffer.shared_memory->ShareToProcess(channel_->renderer_process(),
[email protected]310bed512011-05-09 21:12:25419 &transfer_buffer);
420 size = buffer.size;
[email protected]246a70452010-03-05 21:53:50421 }
[email protected]310bed512011-05-09 21:12:25422
423 GpuCommandBufferMsg_GetTransferBuffer::WriteReplyParams(reply_message,
424 transfer_buffer,
425 size);
426 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50427}
428
[email protected]310bed512011-05-09 21:12:25429void GpuCommandBufferStub::OnCommandProcessed() {
430 if (watchdog_)
431 watchdog_->CheckArmed();
432}
433
[email protected]bc4a3432011-11-21 23:55:56434void GpuCommandBufferStub::OnResize(gfx::Size size) {
435 if (handle_ == gfx::kNullPluginWindow)
436 return;
437
438#if defined(TOOLKIT_USES_GTK) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) || \
439 defined(OS_WIN)
440 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
441
442 // On Windows, Linux, we need to coordinate resizing of onscreen
443 // contexts with the resizing of the actual OS-level window. We do this by
444 // sending a resize message to the browser process and descheduling the
445 // context until the ViewResized message comes back in reply.
446 // Send the resize message if needed
447 gpu_channel_manager->Send(
448 new GpuHostMsg_ResizeView(renderer_id_,
449 render_view_id_,
450 route_id_,
451 size));
452
453 scheduler_->SetScheduled(false);
454#endif
455}
456
457void GpuCommandBufferStub::ViewResized() {
458#if defined(TOOLKIT_USES_GTK) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) || \
459 defined(OS_WIN)
460 DCHECK(handle_ != gfx::kNullPluginWindow);
461 scheduler_->SetScheduled(true);
462#endif
463
464#if defined(OS_WIN)
465 // Recreate the view surface to match the window size. Swap chains do not
466 // automatically resize with window size with D3D.
467 context_->ReleaseCurrent(surface_.get());
468 if (surface_.get()) {
469 surface_->Destroy();
470 surface_->Initialize();
471 SetSwapInterval();
472 }
473#endif
474}
475
[email protected]ef16c172011-04-28 23:37:14476void GpuCommandBufferStub::ReportState() {
477 gpu::CommandBuffer::State state = command_buffer_->GetState();
478 if (state.error == gpu::error::kLostContext &&
479 gfx::GLContext::LosesAllContextsOnContextLost()) {
480 channel_->LoseAllContexts();
481 } else {
482 IPC::Message* msg = new GpuCommandBufferMsg_UpdateState(route_id_, state);
483 msg->set_unblock(true);
484 Send(msg);
485 }
486}
487
[email protected]bc4a3432011-11-21 23:55:56488void GpuCommandBufferStub::SetSwapInterval() {
489#if !defined(OS_MACOSX) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
490 // Set up swap interval for onscreen contexts.
491 if (!surface_->IsOffscreen()) {
492 decoder_->MakeCurrent();
493 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync))
494 context_->SetSwapInterval(0);
495 else
496 context_->SetSwapInterval(1);
497 }
498#endif
499}
500
[email protected]a13da242011-07-07 19:48:17501void GpuCommandBufferStub::OnCreateVideoDecoder(
[email protected]2ffc31a2011-09-01 03:18:28502 media::VideoDecodeAccelerator::Profile profile,
[email protected]c8423062011-07-29 19:25:38503 IPC::Message* reply_message) {
[email protected]502e6052011-08-17 00:17:23504 int decoder_route_id = channel_->GenerateRouteID();
505 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams(
506 reply_message, decoder_route_id);
507 GpuVideoDecodeAccelerator* decoder =
508 new GpuVideoDecodeAccelerator(this, decoder_route_id, this);
509 video_decoders_.AddWithID(decoder, decoder_route_id);
510 channel_->AddRoute(decoder_route_id, decoder);
[email protected]2ffc31a2011-09-01 03:18:28511 decoder->Initialize(profile, reply_message);
[email protected]a13da242011-07-07 19:48:17512}
513
[email protected]502e6052011-08-17 00:17:23514void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) {
515 channel_->RemoveRoute(decoder_route_id);
516 video_decoders_.Remove(decoder_route_id);
[email protected]a13da242011-07-07 19:48:17517}
518
[email protected]8cc980c52011-10-14 20:35:51519void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) {
520 surface_->SetVisible(visible);
521}
522
[email protected]8e5cc282010-12-05 18:11:39523#endif // defined(ENABLE_GPU)