blob: 404d7326b4e720002b76a6bb2a7e5c1f2bcc3970 [file] [log] [blame]
[email protected]6802e3c62012-06-06 22:32:441// Copyright (c) 2012 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]51ddf722012-09-01 00:55:0911#include "base/hash.h"
[email protected]246a70452010-03-05 21:53:5012#include "base/shared_memory.h"
[email protected]672c7312012-02-03 16:28:5513#include "base/time.h"
[email protected]6217d392010-03-25 22:08:3514#include "build/build_config.h"
[email protected]f24a1e2b2011-04-08 01:48:4815#include "content/common/gpu/gpu_channel.h"
16#include "content/common/gpu/gpu_channel_manager.h"
17#include "content/common/gpu/gpu_command_buffer_stub.h"
[email protected]672c7312012-02-03 16:28:5518#include "content/common/gpu/gpu_memory_manager.h"
[email protected]fb246af2012-08-18 03:11:4119#include "content/common/gpu/gpu_memory_tracking.h"
[email protected]202b54ff2011-04-22 21:36:3820#include "content/common/gpu/gpu_messages.h"
[email protected]2dcf7022011-04-15 19:20:4121#include "content/common/gpu/gpu_watchdog.h"
[email protected]bc4a3432011-11-21 23:55:5622#include "content/common/gpu/image_transport_surface.h"
[email protected]cdd3d642012-06-27 19:59:1423#include "content/common/gpu/media/gpu_video_decode_accelerator.h"
[email protected]c02f93e42012-06-05 23:35:1624#include "content/common/gpu/sync_point_manager.h"
[email protected]d1a9e062012-07-13 00:45:1425#include "content/public/common/content_client.h"
[email protected]290fc492011-11-22 23:25:2326#include "gpu/command_buffer/common/constants.h"
[email protected]d670e702012-03-30 10:38:2127#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]00b192572012-07-28 04:00:2228#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]c9e2cbbb2012-05-12 21:17:2729#include "ui/gl/gl_bindings.h"
30#include "ui/gl/gl_switches.h"
[email protected]bc4a3432011-11-21 23:55:5631
[email protected]cd0bd792012-04-14 00:52:1632#if defined(OS_WIN)
[email protected]d30ce6e2012-04-16 15:32:3633#include "content/public/common/sandbox_init.h"
[email protected]cd0bd792012-04-14 00:52:1634#endif
35
[email protected]34aaa5682012-09-25 00:48:5036#if defined(OS_ANDROID)
37#include "content/common/gpu/stream_texture_manager_android.h"
38#endif
39
[email protected]eb398192012-10-22 20:16:1940namespace content {
[email protected]56fc2f22012-07-09 23:50:3641namespace {
[email protected]d1a9e062012-07-13 00:45:1442
[email protected]00b192572012-07-28 04:00:2243// The GpuCommandBufferMemoryTracker class provides a bridge between the
44// ContextGroup's memory type managers and the GpuMemoryManager class.
45class GpuCommandBufferMemoryTracker : public gpu::gles2::MemoryTracker {
46 public:
[email protected]fb246af2012-08-18 03:11:4147 GpuCommandBufferMemoryTracker(GpuChannel* channel) {
48 gpu_memory_manager_tracking_group_ = new GpuMemoryTrackingGroup(
49 channel->renderer_pid(),
50 channel->gpu_channel_manager()->gpu_memory_manager());
51 }
52
[email protected]00b192572012-07-28 04:00:2253 void TrackMemoryAllocatedChange(size_t old_size, size_t new_size) {
[email protected]fb246af2012-08-18 03:11:4154 gpu_memory_manager_tracking_group_->TrackMemoryAllocatedChange(
55 old_size, new_size);
[email protected]00b192572012-07-28 04:00:2256 }
57
58 private:
[email protected]fb246af2012-08-18 03:11:4159 ~GpuCommandBufferMemoryTracker() {
60 delete gpu_memory_manager_tracking_group_;
61 }
62 GpuMemoryTrackingGroup* gpu_memory_manager_tracking_group_;
[email protected]00b192572012-07-28 04:00:2263
64 DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker);
65};
66
[email protected]d1a9e062012-07-13 00:45:1467// FastSetActiveURL will shortcut the expensive call to SetActiveURL when the
68// url_hash matches.
69void FastSetActiveURL(const GURL& url, size_t url_hash) {
70 // Leave the previously set URL in the empty case -- empty URLs are given by
71 // WebKitPlatformSupportImpl::createOffscreenGraphicsContext3D. Hopefully the
72 // onscreen context URL was set previously and will show up even when a crash
73 // occurs during offscreen command processing.
74 if (url.is_empty())
75 return;
76 static size_t g_last_url_hash = 0;
77 if (url_hash != g_last_url_hash) {
78 g_last_url_hash = url_hash;
[email protected]eb398192012-10-22 20:16:1979 GetContentClient()->SetActiveURL(url);
[email protected]d1a9e062012-07-13 00:45:1480 }
81}
82
[email protected]56fc2f22012-07-09 23:50:3683// The first time polling a fence, delay some extra time to allow other
84// stubs to process some work, or else the timing of the fences could
85// allow a pattern of alternating fast and slow frames to occur.
86const int64 kHandleMoreWorkPeriodMs = 2;
87const int64 kHandleMoreWorkPeriodBusyMs = 1;
[email protected]d1a9e062012-07-13 00:45:1488
89} // namespace
[email protected]56fc2f22012-07-09 23:50:3690
[email protected]5178c4422012-10-17 12:08:0791GpuCommandBufferStub::MemoryManagerState::MemoryManagerState(
92 bool has_surface,
93 bool visible,
94 base::TimeTicks last_used_time)
95 : has_surface(has_surface),
[email protected]672c7312012-02-03 16:28:5596 visible(visible),
[email protected]5178c4422012-10-17 12:08:0797 client_has_memory_allocation_changed_callback(false),
[email protected]672c7312012-02-03 16:28:5598 last_used_time(last_used_time) {
99}
100
[email protected]a3ded6d2010-10-19 06:44:39101GpuCommandBufferStub::GpuCommandBufferStub(
102 GpuChannel* channel,
[email protected]3b1ecc262011-08-03 22:49:57103 GpuCommandBufferStub* share_group,
[email protected]fc4ed092012-02-21 19:46:55104 const gfx::GLSurfaceHandle& handle,
[email protected]78b514b2012-05-01 21:50:59105 gpu::gles2::MailboxManager* mailbox_manager,
[email protected]09d50362012-10-18 20:54:37106 gpu::gles2::ImageManager* image_manager,
[email protected]a3ded6d2010-10-19 06:44:39107 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29108 const gpu::gles2::DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39109 const std::string& allowed_extensions,
110 const std::vector<int32>& attribs,
[email protected]276f89062011-10-13 22:55:50111 gfx::GpuPreference gpu_preference,
[email protected]a3ded6d2010-10-19 06:44:39112 int32 route_id,
[email protected]9f4f3322012-01-18 22:29:56113 int32 surface_id,
[email protected]f81f5952011-07-21 18:52:47114 GpuWatchdog* watchdog,
[email protected]d1a9e062012-07-13 00:45:14115 bool software,
[email protected]7f1a51c322012-07-19 18:52:02116 const GURL& active_url)
[email protected]246a70452010-03-05 21:53:50117 : channel_(channel),
[email protected]6ebf2fc2010-07-01 01:06:32118 handle_(handle),
[email protected]6217d392010-03-25 22:08:35119 initial_size_(size),
[email protected]e82fb792011-09-22 00:33:29120 disallowed_features_(disallowed_features),
[email protected]bc518752010-10-20 21:38:27121 allowed_extensions_(allowed_extensions),
[email protected]34ff8b0c2010-10-01 20:06:02122 requested_attribs_(attribs),
[email protected]276f89062011-10-13 22:55:50123 gpu_preference_(gpu_preference),
[email protected]77e74db2010-08-04 17:46:23124 route_id_(route_id),
[email protected]5178c4422012-10-17 12:08:07125 surface_id_(surface_id),
[email protected]f81f5952011-07-21 18:52:47126 software_(software),
[email protected]a38477142011-05-28 02:45:58127 last_flush_count_(0),
[email protected]e7da6aef2011-06-22 19:29:03128 parent_stub_for_initialization_(),
129 parent_texture_for_initialization_(0),
[email protected]35a0b4b2012-06-15 03:53:30130 watchdog_(watchdog),
[email protected]56fc2f22012-07-09 23:50:36131 sync_point_wait_count_(0),
[email protected]d1a9e062012-07-13 00:45:14132 delayed_work_scheduled_(false),
133 active_url_(active_url) {
[email protected]51ddf722012-09-01 00:55:09134 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec());
[email protected]d1a9e062012-07-13 00:45:14135 FastSetActiveURL(active_url_, active_url_hash_);
[email protected]bf5a8d132011-08-16 08:39:35136 if (share_group) {
[email protected]3b1ecc262011-08-03 22:49:57137 context_group_ = share_group->context_group_;
[email protected]bf5a8d132011-08-16 08:39:35138 } else {
[email protected]00b192572012-07-28 04:00:22139 context_group_ = new gpu::gles2::ContextGroup(
[email protected]fb246af2012-08-18 03:11:41140 mailbox_manager,
[email protected]09d50362012-10-18 20:54:37141 image_manager,
[email protected]fb246af2012-08-18 03:11:41142 new GpuCommandBufferMemoryTracker(channel),
143 true);
[email protected]bf5a8d132011-08-16 08:39:35144 }
[email protected]5178c4422012-10-17 12:08:07145 memory_manager_state_.reset(new GpuCommandBufferStubBase::MemoryManagerState(
146 surface_id != 0, true, base::TimeTicks::Now()));
[email protected]35a0b4b2012-06-15 03:53:30147 if (handle_.sync_point)
148 OnWaitSyncPoint(handle_.sync_point);
[email protected]246a70452010-03-05 21:53:50149}
150
151GpuCommandBufferStub::~GpuCommandBufferStub() {
[email protected]79311e82011-09-20 00:40:50152 Destroy();
[email protected]d8a58e42011-01-27 15:24:25153
[email protected]f24a1e2b2011-04-08 01:48:48154 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
[email protected]672c7312012-02-03 16:28:55155 gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer(surface_id()));
[email protected]246a70452010-03-05 21:53:50156}
157
[email protected]a95986a82010-12-24 06:19:28158bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
[email protected]d1a9e062012-07-13 00:45:14159 FastSetActiveURL(active_url_, active_url_hash_);
160
[email protected]79311e82011-09-20 00:40:50161 // Ensure the appropriate GL context is current before handling any IPC
162 // messages directed at the command buffer. This ensures that the message
[email protected]6802e3c62012-06-06 22:32:44163 // handler can assume that the context is current (not necessary for
[email protected]68c70282012-06-25 23:31:17164 // Echo, RetireSyncPoint, or WaitSyncPoint).
[email protected]6802e3c62012-06-06 22:32:44165 if (decoder_.get() &&
[email protected]68c70282012-06-25 23:31:17166 message.type() != GpuCommandBufferMsg_Echo::ID &&
167 message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID &&
168 message.type() != GpuCommandBufferMsg_WaitSyncPoint::ID) {
[email protected]062e5e82012-06-20 19:30:35169 if (!MakeCurrent())
[email protected]79311e82011-09-20 00:40:50170 return false;
[email protected]79311e82011-09-20 00:40:50171 }
172
[email protected]310bed512011-05-09 21:12:25173 // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
174 // here. This is so the reply can be delayed if the scheduler is unscheduled.
[email protected]a95986a82010-12-24 06:19:28175 bool handled = true;
[email protected]246a70452010-03-05 21:53:50176 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
[email protected]310bed512011-05-09 21:12:25177 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize,
178 OnInitialize);
[email protected]503b3a22011-12-12 23:29:40179 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer,
180 OnSetGetBuffer);
[email protected]68eff952012-02-17 21:56:35181 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetSharedStateBuffer,
182 OnSetSharedStateBuffer);
[email protected]3c644d82011-06-20 19:58:24183 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetParent,
184 OnSetParent);
[email protected]1ef068c2012-03-02 16:30:47185 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Echo, OnEcho);
[email protected]310bed512011-05-09 21:12:25186 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState);
[email protected]451e9662011-10-10 21:14:34187 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetStateFast,
188 OnGetStateFast);
[email protected]246a70452010-03-05 21:53:50189 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
[email protected]d0f02c42011-07-21 21:40:48190 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Rescheduled, OnRescheduled);
[email protected]310bed512011-05-09 21:12:25191 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateTransferBuffer,
192 OnCreateTransferBuffer);
193 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_RegisterTransferBuffer,
194 OnRegisterTransferBuffer);
195 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_DestroyTransferBuffer,
196 OnDestroyTransferBuffer);
197 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetTransferBuffer,
198 OnGetTransferBuffer);
[email protected]c8423062011-07-29 19:25:38199 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder,
200 OnCreateVideoDecoder)
[email protected]a13da242011-07-07 19:48:17201 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyVideoDecoder,
202 OnDestroyVideoDecoder)
[email protected]8cc980c52011-10-14 20:35:51203 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetSurfaceVisible,
204 OnSetSurfaceVisible)
[email protected]251622e2012-03-23 16:17:40205 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DiscardBackbuffer,
206 OnDiscardBackbuffer)
207 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_EnsureBackbuffer,
208 OnEnsureBackbuffer)
[email protected]c02f93e42012-06-05 23:35:16209 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RetireSyncPoint,
210 OnRetireSyncPoint)
211 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_WaitSyncPoint,
212 OnWaitSyncPoint)
[email protected]5ab44ef2012-06-19 00:03:51213 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncPoint,
214 OnSignalSyncPoint)
[email protected]c1f12142012-05-01 22:21:06215 IPC_MESSAGE_HANDLER(
216 GpuCommandBufferMsg_SetClientHasMemoryAllocationChangedCallback,
217 OnSetClientHasMemoryAllocationChangedCallback)
[email protected]a95986a82010-12-24 06:19:28218 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]246a70452010-03-05 21:53:50219 IPC_END_MESSAGE_MAP()
[email protected]a13da242011-07-07 19:48:17220
[email protected]56fc2f22012-07-09 23:50:36221 // Ensure that any delayed work that was created will be handled.
222 ScheduleDelayedWork(kHandleMoreWorkPeriodMs);
223
[email protected]a95986a82010-12-24 06:19:28224 DCHECK(handled);
225 return handled;
[email protected]246a70452010-03-05 21:53:50226}
227
228bool GpuCommandBufferStub::Send(IPC::Message* message) {
229 return channel_->Send(message);
230}
231
[email protected]d0f02c42011-07-21 21:40:48232bool GpuCommandBufferStub::IsScheduled() {
[email protected]35a0b4b2012-06-15 03:53:30233 return sync_point_wait_count_ == 0 &&
234 (!scheduler_.get() || scheduler_->IsScheduled());
[email protected]d0f02c42011-07-21 21:40:48235}
236
[email protected]20f656f2011-12-08 02:25:15237bool GpuCommandBufferStub::HasMoreWork() {
238 return scheduler_.get() && scheduler_->HasMoreWork();
239}
240
[email protected]f5f910d52012-03-06 22:33:09241void GpuCommandBufferStub::PollWork() {
[email protected]56fc2f22012-07-09 23:50:36242 TRACE_EVENT0("gpu", "GpuCommandBufferStub::PollWork");
243 delayed_work_scheduled_ = false;
[email protected]a5b2abb912012-07-13 04:45:04244 FastSetActiveURL(active_url_, active_url_hash_);
[email protected]062e5e82012-06-20 19:30:35245 if (decoder_.get() && !MakeCurrent())
246 return;
[email protected]f5f910d52012-03-06 22:33:09247 if (scheduler_.get())
248 scheduler_->PollUnscheduleFences();
[email protected]56fc2f22012-07-09 23:50:36249 ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs);
[email protected]f5f910d52012-03-06 22:33:09250}
251
[email protected]df621aff2012-03-02 23:04:58252bool GpuCommandBufferStub::HasUnprocessedCommands() {
253 if (command_buffer_.get()) {
254 gpu::CommandBuffer::State state = command_buffer_->GetLastState();
[email protected]6dadf652012-03-22 02:49:24255 return state.put_offset != state.get_offset &&
256 !gpu::error::IsError(state.error);
[email protected]df621aff2012-03-02 23:04:58257 }
258 return false;
259}
260
[email protected]56fc2f22012-07-09 23:50:36261void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) {
262 if (HasMoreWork() && !delayed_work_scheduled_) {
263 delayed_work_scheduled_ = true;
264 MessageLoop::current()->PostDelayedTask(
265 FROM_HERE,
266 base::Bind(&GpuCommandBufferStub::PollWork,
267 AsWeakPtr()),
268 base::TimeDelta::FromMilliseconds(delay));
269 }
270}
271
[email protected]1ef068c2012-03-02 16:30:47272void GpuCommandBufferStub::OnEcho(const IPC::Message& message) {
273 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEcho");
274 Send(new IPC::Message(message));
275}
276
[email protected]ac9ab812012-03-06 22:44:05277void GpuCommandBufferStub::DelayEcho(IPC::Message* message) {
278 delayed_echos_.push_back(message);
279}
280
281void GpuCommandBufferStub::OnReschedule() {
[email protected]35a0b4b2012-06-15 03:53:30282 if (!IsScheduled())
283 return;
[email protected]ac9ab812012-03-06 22:44:05284 while (!delayed_echos_.empty()) {
285 scoped_ptr<IPC::Message> message(delayed_echos_.front());
286 delayed_echos_.pop_front();
287
288 OnMessageReceived(*message);
289 }
290
291 channel_->OnScheduled();
292}
293
[email protected]062e5e82012-06-20 19:30:35294bool GpuCommandBufferStub::MakeCurrent() {
295 if (decoder_->MakeCurrent())
296 return true;
297 DLOG(ERROR) << "Context lost because MakeCurrent failed.";
298 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
299 command_buffer_->SetParseError(gpu::error::kLostContext);
300 if (gfx::GLContext::LosesAllContextsOnContextLost())
301 channel_->LoseAllContexts();
302 return false;
303}
304
[email protected]79311e82011-09-20 00:40:50305void GpuCommandBufferStub::Destroy() {
[email protected]c02f93e42012-06-05 23:35:16306 while (!sync_points_.empty())
307 OnRetireSyncPoint(sync_points_.front());
308
[email protected]79311e82011-09-20 00:40:50309 // The scheduler has raw references to the decoder and the command buffer so
310 // destroy it before those.
[email protected]4ee0c3052011-09-16 19:30:36311 scheduler_.reset();
[email protected]79311e82011-09-20 00:40:50312
[email protected]ac9ab812012-03-06 22:44:05313 while (!delayed_echos_.empty()) {
314 delete delayed_echos_.front();
315 delayed_echos_.pop_front();
316 }
317
[email protected]706b69f2012-07-27 04:59:30318 bool have_context = false;
[email protected]0f9386892012-02-15 01:44:07319 if (decoder_.get())
[email protected]706b69f2012-07-27 04:59:30320 have_context = decoder_->MakeCurrent();
[email protected]0f9386892012-02-15 01:44:07321 FOR_EACH_OBSERVER(DestructionObserver,
322 destruction_observers_,
323 OnWillDestroyStub(this));
324
[email protected]79311e82011-09-20 00:40:50325 if (decoder_.get()) {
[email protected]706b69f2012-07-27 04:59:30326 decoder_->Destroy(have_context);
[email protected]79311e82011-09-20 00:40:50327 decoder_.reset();
328 }
329
[email protected]4ee0c3052011-09-16 19:30:36330 command_buffer_.reset();
[email protected]79311e82011-09-20 00:40:50331
332 context_ = NULL;
333 surface_ = NULL;
[email protected]672c7312012-02-03 16:28:55334
[email protected]5d5374e2012-06-19 16:46:51335 channel_->gpu_channel_manager()->gpu_memory_manager()->ScheduleManage(false);
[email protected]79311e82011-09-20 00:40:50336}
337
338void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) {
339 Destroy();
[email protected]2e7bbf22011-07-22 18:41:29340 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, false);
341 Send(reply_message);
342}
343
[email protected]246a70452010-03-05 21:53:50344void GpuCommandBufferStub::OnInitialize(
[email protected]310bed512011-05-09 21:12:25345 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32346 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnInitialize");
[email protected]246a70452010-03-05 21:53:50347 DCHECK(!command_buffer_.get());
348
[email protected]1d471e82012-06-01 06:13:40349 command_buffer_.reset(new gpu::CommandBufferService(
350 context_group_->transfer_buffer_manager()));
[email protected]246a70452010-03-05 21:53:50351
[email protected]503b3a22011-12-12 23:29:40352 if (!command_buffer_->Initialize()) {
[email protected]198e0c442011-12-02 19:45:06353 DLOG(ERROR) << "CommandBufferService failed to initialize.\n";
[email protected]79311e82011-09-20 00:40:50354 OnInitializeFailed(reply_message);
355 return;
356 }
357
358 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get()));
359
360 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
361 decoder_.get(),
[email protected]8a9e1a12011-12-20 01:46:05362 decoder_.get()));
[email protected]6802e3c62012-06-06 22:32:44363 if (preempt_by_counter_.get())
364 scheduler_->SetPreemptByCounter(preempt_by_counter_);
[email protected]79311e82011-09-20 00:40:50365
366 decoder_->set_engine(scheduler_.get());
367
[email protected]47940c82012-02-08 02:23:49368 if (!handle_.is_null()) {
[email protected]839d5172011-10-13 17:18:11369#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]2e7bbf22011-07-22 18:41:29370 if (software_) {
[email protected]198e0c442011-12-02 19:45:06371 DLOG(ERROR) << "No software support.\n";
[email protected]2e7bbf22011-07-22 18:41:29372 OnInitializeFailed(reply_message);
373 return;
374 }
[email protected]290fc492011-11-22 23:25:23375#endif
[email protected]2e7bbf22011-07-22 18:41:29376
[email protected]79311e82011-09-20 00:40:50377 surface_ = ImageTransportSurface::CreateSurface(
378 channel_->gpu_channel_manager(),
[email protected]9f4f3322012-01-18 22:29:56379 this,
[email protected]04d58ce2011-09-29 13:12:23380 handle_);
[email protected]79311e82011-09-20 00:40:50381 } else {
[email protected]b8673e62012-09-25 03:15:00382 GpuChannelManager* manager = channel_->gpu_channel_manager();
383 surface_ = manager->GetDefaultOffscreenSurface();
[email protected]79311e82011-09-20 00:40:50384 }
385
386 if (!surface_.get()) {
[email protected]cdcd5bd2011-10-15 00:19:38387 // Ensure the decoder is not destroyed if it is not initialized.
388 decoder_.reset();
389
[email protected]cc63025a2011-10-29 02:16:24390 DLOG(ERROR) << "Failed to create surface.\n";
[email protected]79311e82011-09-20 00:40:50391 OnInitializeFailed(reply_message);
392 return;
393 }
394
[email protected]276f89062011-10-13 22:55:50395 context_ = gfx::GLContext::CreateGLContext(
396 channel_->share_group(),
397 surface_.get(),
[email protected]96a28ea2012-06-09 02:16:09398 gpu_preference_);
[email protected]79311e82011-09-20 00:40:50399 if (!context_.get()) {
[email protected]cdcd5bd2011-10-15 00:19:38400 // Ensure the decoder is not destroyed if it is not initialized.
401 decoder_.reset();
402
[email protected]cc63025a2011-10-29 02:16:24403 DLOG(ERROR) << "Failed to create context.\n";
[email protected]79311e82011-09-20 00:40:50404 OnInitializeFailed(reply_message);
405 return;
406 }
[email protected]4bbe6d0c2011-09-16 18:58:54407
[email protected]63c9b052012-05-17 18:27:38408 if (!context_->MakeCurrent(surface_.get())) {
[email protected]35a0b4b2012-06-15 03:53:30409 // Ensure the decoder is not destroyed if it is not initialized.
410 decoder_.reset();
[email protected]63c9b052012-05-17 18:27:38411 LOG(ERROR) << "Failed to make context current.";
412 OnInitializeFailed(reply_message);
413 return;
414 }
415
[email protected]65dfc602012-07-23 20:39:39416 if (!context_group_->has_program_cache()) {
417 context_group_->set_program_cache(
418 channel_->gpu_channel_manager()->program_cache());
419 }
420
[email protected]79311e82011-09-20 00:40:50421 // Initialize the decoder with either the view or pbuffer GLContext.
[email protected]63c9b052012-05-17 18:27:38422 if (!decoder_->Initialize(surface_,
423 context_,
[email protected]069944672012-04-25 20:52:23424 !surface_id(),
[email protected]79311e82011-09-20 00:40:50425 initial_size_,
[email protected]e82fb792011-09-22 00:33:29426 disallowed_features_,
[email protected]79311e82011-09-20 00:40:50427 allowed_extensions_.c_str(),
428 requested_attribs_)) {
[email protected]cc63025a2011-10-29 02:16:24429 DLOG(ERROR) << "Failed to initialize decoder.";
[email protected]79311e82011-09-20 00:40:50430 OnInitializeFailed(reply_message);
431 return;
432 }
433
434 if (CommandLine::ForCurrentProcess()->HasSwitch(
435 switches::kEnableGPUServiceLogging)) {
[email protected]e844ae22012-01-14 03:36:26436 decoder_->set_log_commands(true);
[email protected]79311e82011-09-20 00:40:50437 }
438
[email protected]6b6e7ee2011-12-13 08:04:52439 decoder_->SetMsgCallback(
440 base::Bind(&GpuCommandBufferStub::SendConsoleMessage,
441 base::Unretained(this)));
442
[email protected]79311e82011-09-20 00:40:50443 command_buffer_->SetPutOffsetChangeCallback(
[email protected]d1a9e062012-07-13 00:45:14444 base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this)));
[email protected]503b3a22011-12-12 23:29:40445 command_buffer_->SetGetBufferChangeCallback(
446 base::Bind(&gpu::GpuScheduler::SetGetBuffer,
447 base::Unretained(scheduler_.get())));
[email protected]79311e82011-09-20 00:40:50448 command_buffer_->SetParseErrorCallback(
[email protected]9d37f062011-11-22 01:24:52449 base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50450 scheduler_->SetScheduledCallback(
[email protected]ac9ab812012-03-06 22:44:05451 base::Bind(&GpuCommandBufferStub::OnReschedule, base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50452
[email protected]79311e82011-09-20 00:40:50453 if (watchdog_) {
454 scheduler_->SetCommandProcessedCallback(
[email protected]9d37f062011-11-22 01:24:52455 base::Bind(&GpuCommandBufferStub::OnCommandProcessed,
456 base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50457 }
458
[email protected]34aaa5682012-09-25 00:48:50459#if defined(OS_ANDROID)
460 decoder_->SetStreamTextureManager(channel_->stream_texture_manager());
461#endif
462
[email protected]79311e82011-09-20 00:40:50463 if (parent_stub_for_initialization_) {
464 decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(),
465 parent_texture_for_initialization_);
466 parent_stub_for_initialization_.reset();
467 parent_texture_for_initialization_ = 0;
468 }
[email protected]310bed512011-05-09 21:12:25469
[email protected]2e7bbf22011-07-22 18:41:29470 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, true);
[email protected]310bed512011-05-09 21:12:25471 Send(reply_message);
[email protected]672c7312012-02-03 16:28:55472
[email protected]5d5374e2012-06-19 16:46:51473 channel_->gpu_channel_manager()->gpu_memory_manager()->ScheduleManage(true);
[email protected]246a70452010-03-05 21:53:50474}
475
[email protected]503b3a22011-12-12 23:29:40476void GpuCommandBufferStub::OnSetGetBuffer(
477 int32 shm_id, IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32478 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer");
[email protected]773bf5e2012-01-06 01:07:13479 if (command_buffer_.get()) {
480 command_buffer_->SetGetBuffer(shm_id);
481 } else {
482 DLOG(ERROR) << "no command_buffer.";
483 reply_message->set_reply_error();
484 }
[email protected]503b3a22011-12-12 23:29:40485 Send(reply_message);
486}
487
[email protected]68eff952012-02-17 21:56:35488void GpuCommandBufferStub::OnSetSharedStateBuffer(
489 int32 shm_id, IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32490 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSharedStateBuffer");
[email protected]68eff952012-02-17 21:56:35491 if (command_buffer_.get()) {
492 command_buffer_->SetSharedStateBuffer(shm_id);
493 } else {
494 DLOG(ERROR) << "no command_buffer.";
495 reply_message->set_reply_error();
496 }
497 Send(reply_message);
498}
499
[email protected]3c644d82011-06-20 19:58:24500void GpuCommandBufferStub::OnSetParent(int32 parent_route_id,
501 uint32 parent_texture_id,
502 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32503 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetParent");
[email protected]e7da6aef2011-06-22 19:29:03504 GpuCommandBufferStub* parent_stub = NULL;
505 if (parent_route_id != MSG_ROUTING_NONE) {
506 parent_stub = channel_->LookupCommandBuffer(parent_route_id);
[email protected]3c644d82011-06-20 19:58:24507 }
508
[email protected]e7da6aef2011-06-22 19:29:03509 bool result = true;
510 if (scheduler_.get()) {
[email protected]79311e82011-09-20 00:40:50511 gpu::gles2::GLES2Decoder* parent_decoder =
512 parent_stub ? parent_stub->decoder_.get() : NULL;
513 result = decoder_->SetParent(parent_decoder, parent_texture_id);
[email protected]e7da6aef2011-06-22 19:29:03514 } else {
515 // If we don't have a scheduler, it means that Initialize hasn't been called
516 // yet. Keep around the requested parent stub and texture so that we can set
517 // it in Initialize().
518 parent_stub_for_initialization_ = parent_stub ?
519 parent_stub->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>();
520 parent_texture_for_initialization_ = parent_texture_id;
521 }
[email protected]3c644d82011-06-20 19:58:24522 GpuCommandBufferMsg_SetParent::WriteReplyParams(reply_message, result);
523 Send(reply_message);
524}
525
[email protected]310bed512011-05-09 21:12:25526void GpuCommandBufferStub::OnGetState(IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32527 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetState");
[email protected]773bf5e2012-01-06 01:07:13528 if (command_buffer_.get()) {
529 gpu::CommandBuffer::State state = command_buffer_->GetState();
530 if (state.error == gpu::error::kLostContext &&
531 gfx::GLContext::LosesAllContextsOnContextLost())
532 channel_->LoseAllContexts();
[email protected]310bed512011-05-09 21:12:25533
[email protected]773bf5e2012-01-06 01:07:13534 GpuCommandBufferMsg_GetState::WriteReplyParams(reply_message, state);
535 } else {
536 DLOG(ERROR) << "no command_buffer.";
537 reply_message->set_reply_error();
538 }
[email protected]310bed512011-05-09 21:12:25539 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50540}
541
[email protected]0a68ac872011-06-07 04:48:27542void GpuCommandBufferStub::OnParseError() {
543 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnParseError");
[email protected]773bf5e2012-01-06 01:07:13544 DCHECK(command_buffer_.get());
[email protected]38d139d2011-07-14 00:38:43545 gpu::CommandBuffer::State state = command_buffer_->GetState();
546 IPC::Message* msg = new GpuCommandBufferMsg_Destroyed(
547 route_id_, state.context_lost_reason);
[email protected]0a68ac872011-06-07 04:48:27548 msg->set_unblock(true);
549 Send(msg);
550}
551
[email protected]451e9662011-10-10 21:14:34552void GpuCommandBufferStub::OnGetStateFast(IPC::Message* reply_message) {
553 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetStateFast");
[email protected]773bf5e2012-01-06 01:07:13554 DCHECK(command_buffer_.get());
[email protected]d0f02c42011-07-21 21:40:48555 gpu::CommandBuffer::State state = command_buffer_->GetState();
[email protected]451e9662011-10-10 21:14:34556 if (state.error == gpu::error::kLostContext &&
557 gfx::GLContext::LosesAllContextsOnContextLost())
558 channel_->LoseAllContexts();
[email protected]1d4ea842011-07-20 01:11:51559
[email protected]451e9662011-10-10 21:14:34560 GpuCommandBufferMsg_GetStateFast::WriteReplyParams(reply_message, state);
561 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50562}
563
[email protected]451e9662011-10-10 21:14:34564void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset,
565 uint32 flush_count) {
566 TRACE_EVENT1("gpu", "GpuCommandBufferStub::OnAsyncFlush",
567 "put_offset", put_offset);
[email protected]773bf5e2012-01-06 01:07:13568 DCHECK(command_buffer_.get());
[email protected]fde205d2011-05-31 22:29:50569 if (flush_count - last_flush_count_ < 0x8000000U) {
[email protected]a38477142011-05-28 02:45:58570 last_flush_count_ = flush_count;
571 command_buffer_->Flush(put_offset);
572 } else {
[email protected]fde205d2011-05-31 22:29:50573 // We received this message out-of-order. This should not happen but is here
574 // to catch regressions. Ignore the message.
575 NOTREACHED() << "Received a Flush message out-of-order";
[email protected]a38477142011-05-28 02:45:58576 }
[email protected]d0f02c42011-07-21 21:40:48577
578 ReportState();
579}
580
581void GpuCommandBufferStub::OnRescheduled() {
[email protected]20f656f2011-12-08 02:25:15582 gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState();
583 command_buffer_->Flush(pre_state.put_offset);
584 gpu::CommandBuffer::State post_state = command_buffer_->GetLastState();
[email protected]d0f02c42011-07-21 21:40:48585
[email protected]20f656f2011-12-08 02:25:15586 if (pre_state.get_offset != post_state.get_offset)
587 ReportState();
[email protected]246a70452010-03-05 21:53:50588}
589
[email protected]ce9eea602011-04-12 20:09:57590void GpuCommandBufferStub::OnCreateTransferBuffer(int32 size,
591 int32 id_request,
[email protected]310bed512011-05-09 21:12:25592 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32593 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateTransferBuffer");
[email protected]773bf5e2012-01-06 01:07:13594 if (command_buffer_.get()) {
595 int32 id = command_buffer_->CreateTransferBuffer(size, id_request);
596 GpuCommandBufferMsg_CreateTransferBuffer::WriteReplyParams(
597 reply_message, id);
598 } else {
599 reply_message->set_reply_error();
600 }
[email protected]310bed512011-05-09 21:12:25601 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50602}
603
[email protected]0100b7a2011-02-24 22:54:50604void GpuCommandBufferStub::OnRegisterTransferBuffer(
605 base::SharedMemoryHandle transfer_buffer,
606 size_t size,
[email protected]ce9eea602011-04-12 20:09:57607 int32 id_request,
[email protected]310bed512011-05-09 21:12:25608 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32609 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterTransferBuffer");
[email protected]0100b7a2011-02-24 22:54:50610 base::SharedMemory shared_memory(transfer_buffer, false);
[email protected]7df1d1a2011-02-26 02:07:57611
[email protected]773bf5e2012-01-06 01:07:13612 if (command_buffer_.get()) {
613 int32 id = command_buffer_->RegisterTransferBuffer(&shared_memory,
614 size,
615 id_request);
616 GpuCommandBufferMsg_RegisterTransferBuffer::WriteReplyParams(reply_message,
617 id);
618 } else {
619 reply_message->set_reply_error();
620 }
[email protected]310bed512011-05-09 21:12:25621
[email protected]310bed512011-05-09 21:12:25622 Send(reply_message);
[email protected]0100b7a2011-02-24 22:54:50623}
624
[email protected]310bed512011-05-09 21:12:25625void GpuCommandBufferStub::OnDestroyTransferBuffer(
626 int32 id,
627 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32628 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyTransferBuffer");
[email protected]773bf5e2012-01-06 01:07:13629 if (command_buffer_.get()) {
630 command_buffer_->DestroyTransferBuffer(id);
631 } else {
632 reply_message->set_reply_error();
633 }
[email protected]310bed512011-05-09 21:12:25634 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50635}
636
637void GpuCommandBufferStub::OnGetTransferBuffer(
638 int32 id,
[email protected]310bed512011-05-09 21:12:25639 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32640 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetTransferBuffer");
[email protected]773bf5e2012-01-06 01:07:13641 if (command_buffer_.get()) {
642 base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle();
643 uint32 size = 0;
[email protected]310bed512011-05-09 21:12:25644
[email protected]773bf5e2012-01-06 01:07:13645 gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id);
646 if (buffer.shared_memory) {
[email protected]cd0bd792012-04-14 00:52:16647#if defined(OS_WIN)
648 transfer_buffer = NULL;
[email protected]eb398192012-10-22 20:16:19649 BrokerDuplicateHandle(buffer.shared_memory->handle(),
[email protected]cd0bd792012-04-14 00:52:16650 channel_->renderer_pid(), &transfer_buffer, FILE_MAP_READ |
651 FILE_MAP_WRITE, 0);
[email protected]8f9904d2012-05-09 00:20:22652 DCHECK(transfer_buffer != NULL);
[email protected]cd0bd792012-04-14 00:52:16653#else
654 buffer.shared_memory->ShareToProcess(channel_->renderer_pid(),
[email protected]773bf5e2012-01-06 01:07:13655 &transfer_buffer);
[email protected]cd0bd792012-04-14 00:52:16656#endif
[email protected]773bf5e2012-01-06 01:07:13657 size = buffer.size;
658 }
659
660 GpuCommandBufferMsg_GetTransferBuffer::WriteReplyParams(reply_message,
661 transfer_buffer,
662 size);
663 } else {
664 reply_message->set_reply_error();
665 }
[email protected]310bed512011-05-09 21:12:25666 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50667}
668
[email protected]310bed512011-05-09 21:12:25669void GpuCommandBufferStub::OnCommandProcessed() {
670 if (watchdog_)
671 watchdog_->CheckArmed();
672}
673
[email protected]ef16c172011-04-28 23:37:14674void GpuCommandBufferStub::ReportState() {
675 gpu::CommandBuffer::State state = command_buffer_->GetState();
676 if (state.error == gpu::error::kLostContext &&
677 gfx::GLContext::LosesAllContextsOnContextLost()) {
678 channel_->LoseAllContexts();
679 } else {
[email protected]68eff952012-02-17 21:56:35680 command_buffer_->UpdateState();
[email protected]ef16c172011-04-28 23:37:14681 }
682}
683
[email protected]d1a9e062012-07-13 00:45:14684void GpuCommandBufferStub::PutChanged() {
685 FastSetActiveURL(active_url_, active_url_hash_);
686 scheduler_->PutChanged();
687}
688
[email protected]a13da242011-07-07 19:48:17689void GpuCommandBufferStub::OnCreateVideoDecoder(
[email protected]e5ca6362012-03-30 09:45:58690 media::VideoCodecProfile profile,
[email protected]c8423062011-07-29 19:25:38691 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32692 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoDecoder");
[email protected]502e6052011-08-17 00:17:23693 int decoder_route_id = channel_->GenerateRouteID();
[email protected]502e6052011-08-17 00:17:23694 GpuVideoDecodeAccelerator* decoder =
695 new GpuVideoDecodeAccelerator(this, decoder_route_id, this);
696 video_decoders_.AddWithID(decoder, decoder_route_id);
697 channel_->AddRoute(decoder_route_id, decoder);
[email protected]cd0bd792012-04-14 00:52:16698 decoder->Initialize(profile, reply_message);
[email protected]a13da242011-07-07 19:48:17699}
700
[email protected]502e6052011-08-17 00:17:23701void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) {
[email protected]3551cb202012-05-24 10:55:32702 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyVideoDecoder");
[email protected]502e6052011-08-17 00:17:23703 channel_->RemoveRoute(decoder_route_id);
704 video_decoders_.Remove(decoder_route_id);
[email protected]a13da242011-07-07 19:48:17705}
706
[email protected]8cc980c52011-10-14 20:35:51707void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) {
[email protected]3551cb202012-05-24 10:55:32708 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSurfaceVisible");
[email protected]5178c4422012-10-17 12:08:07709 memory_manager_state_->visible = visible;
710 memory_manager_state_->last_used_time = base::TimeTicks::Now();
711 channel_->gpu_channel_manager()->gpu_memory_manager()->
712 ScheduleManage(visible);
[email protected]8cc980c52011-10-14 20:35:51713}
714
[email protected]251622e2012-03-23 16:17:40715void GpuCommandBufferStub::OnDiscardBackbuffer() {
[email protected]3551cb202012-05-24 10:55:32716 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDiscardBackbuffer");
[email protected]251622e2012-03-23 16:17:40717 if (!surface_)
718 return;
[email protected]3ac71bf2012-05-16 15:55:53719 surface_->SetBackbufferAllocation(false);
[email protected]251622e2012-03-23 16:17:40720}
721
722void GpuCommandBufferStub::OnEnsureBackbuffer() {
[email protected]3551cb202012-05-24 10:55:32723 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEnsureBackbuffer");
[email protected]251622e2012-03-23 16:17:40724 if (!surface_)
725 return;
[email protected]3ac71bf2012-05-16 15:55:53726 surface_->SetBackbufferAllocation(true);
[email protected]251622e2012-03-23 16:17:40727}
728
[email protected]c02f93e42012-06-05 23:35:16729void GpuCommandBufferStub::AddSyncPoint(uint32 sync_point) {
730 sync_points_.push_back(sync_point);
731}
732
733void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) {
734 DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point);
735 sync_points_.pop_front();
736 GpuChannelManager* manager = channel_->gpu_channel_manager();
737 manager->sync_point_manager()->RetireSyncPoint(sync_point);
738}
739
740void GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) {
[email protected]35a0b4b2012-06-15 03:53:30741 if (sync_point_wait_count_ == 0) {
742 TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this,
743 "GpuCommandBufferStub", this);
744 }
745 ++sync_point_wait_count_;
[email protected]c02f93e42012-06-05 23:35:16746 GpuChannelManager* manager = channel_->gpu_channel_manager();
747 manager->sync_point_manager()->AddSyncPointCallback(
748 sync_point,
749 base::Bind(&GpuCommandBufferStub::OnSyncPointRetired,
750 this->AsWeakPtr()));
751}
752
753void GpuCommandBufferStub::OnSyncPointRetired() {
[email protected]35a0b4b2012-06-15 03:53:30754 --sync_point_wait_count_;
755 if (sync_point_wait_count_ == 0) {
756 TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this,
757 "GpuCommandBufferStub", this);
758 }
759 OnReschedule();
[email protected]c02f93e42012-06-05 23:35:16760}
761
[email protected]5ab44ef2012-06-19 00:03:51762void GpuCommandBufferStub::OnSignalSyncPoint(uint32 sync_point, uint32 id) {
763 GpuChannelManager* manager = channel_->gpu_channel_manager();
764 manager->sync_point_manager()->AddSyncPointCallback(
765 sync_point,
766 base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck,
767 this->AsWeakPtr(),
768 id));
769}
770
771void GpuCommandBufferStub::OnSignalSyncPointAck(uint32 id) {
772 Send(new GpuCommandBufferMsg_SignalSyncPointAck(route_id_, id));
773}
774
[email protected]c1f12142012-05-01 22:21:06775void GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback(
776 bool has_callback) {
[email protected]3551cb202012-05-24 10:55:32777 TRACE_EVENT0(
778 "gpu",
779 "GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback");
[email protected]5178c4422012-10-17 12:08:07780 memory_manager_state_->client_has_memory_allocation_changed_callback =
781 has_callback;
[email protected]5d5374e2012-06-19 16:46:51782 channel_->gpu_channel_manager()->gpu_memory_manager()->
783 ScheduleManage(false);
[email protected]c1f12142012-05-01 22:21:06784}
785
[email protected]6b6e7ee2011-12-13 08:04:52786void GpuCommandBufferStub::SendConsoleMessage(
787 int32 id,
788 const std::string& message) {
789 GPUCommandBufferConsoleMessage console_message;
790 console_message.id = id;
791 console_message.message = message;
792 IPC::Message* msg = new GpuCommandBufferMsg_ConsoleMsg(
793 route_id_, console_message);
794 msg->set_unblock(true);
795 Send(msg);
796}
797
[email protected]0f9386892012-02-15 01:44:07798void GpuCommandBufferStub::AddDestructionObserver(
799 DestructionObserver* observer) {
800 destruction_observers_.AddObserver(observer);
801}
802
803void GpuCommandBufferStub::RemoveDestructionObserver(
804 DestructionObserver* observer) {
805 destruction_observers_.RemoveObserver(observer);
806}
807
[email protected]6802e3c62012-06-06 22:32:44808void GpuCommandBufferStub::SetPreemptByCounter(
[email protected]68c70282012-06-25 23:31:17809 scoped_refptr<gpu::RefCountedCounter> counter) {
[email protected]6802e3c62012-06-06 22:32:44810 preempt_by_counter_ = counter;
811 if (scheduler_.get())
812 scheduler_->SetPreemptByCounter(preempt_by_counter_);
813}
814
[email protected]4b8a6b092012-10-05 01:20:06815bool GpuCommandBufferStub::GetTotalGpuMemory(size_t* bytes) {
816 if (!MakeCurrent())
817 return false;
818 return context_->GetTotalGpuMemory(bytes);
819}
820
[email protected]1d56e9642012-05-04 15:40:13821gfx::Size GpuCommandBufferStub::GetSurfaceSize() const {
822 if (!surface_)
823 return gfx::Size();
824 return surface_->GetSize();
825}
826
[email protected]c53709012012-02-21 03:22:22827bool GpuCommandBufferStub::IsInSameContextShareGroup(
828 const GpuCommandBufferStubBase& other) const {
829 return context_group_ ==
830 static_cast<const GpuCommandBufferStub&>(other).context_group_;
831}
832
[email protected]c1f12142012-05-01 22:21:06833
[email protected]5178c4422012-10-17 12:08:07834const GpuCommandBufferStubBase::MemoryManagerState&
835 GpuCommandBufferStub::memory_manager_state() const {
836 return *memory_manager_state_.get();
[email protected]672c7312012-02-03 16:28:55837}
[email protected]74b407d2012-02-11 01:13:55838void GpuCommandBufferStub::SetMemoryAllocation(
839 const GpuMemoryAllocation& allocation) {
[email protected]3ac71bf2012-05-16 15:55:53840 Send(new GpuCommandBufferMsg_SetMemoryAllocation(route_id_, allocation));
[email protected]062e5e82012-06-20 19:30:35841 // This can be called outside of OnMessageReceived, so the context needs to be
842 // made current before calling methods on the surface.
843 if (!surface_ || !MakeCurrent())
[email protected]3ac71bf2012-05-16 15:55:53844 return;
845 surface_->SetFrontbufferAllocation(allocation.suggest_have_frontbuffer);
[email protected]74b407d2012-02-11 01:13:55846}
847
[email protected]eb398192012-10-22 20:16:19848} // namespace content
849
[email protected]8e5cc282010-12-05 18:11:39850#endif // defined(ENABLE_GPU)