blob: 15418bd4d6c19ff18acc9ac92456f2d216956c25 [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]56fc2f22012-07-09 23:50:3640namespace {
[email protected]d1a9e062012-07-13 00:45:1441
[email protected]00b192572012-07-28 04:00:2242// The GpuCommandBufferMemoryTracker class provides a bridge between the
43// ContextGroup's memory type managers and the GpuMemoryManager class.
44class GpuCommandBufferMemoryTracker : public gpu::gles2::MemoryTracker {
45 public:
[email protected]fb246af2012-08-18 03:11:4146 GpuCommandBufferMemoryTracker(GpuChannel* channel) {
47 gpu_memory_manager_tracking_group_ = new GpuMemoryTrackingGroup(
48 channel->renderer_pid(),
49 channel->gpu_channel_manager()->gpu_memory_manager());
50 }
51
[email protected]00b192572012-07-28 04:00:2252 void TrackMemoryAllocatedChange(size_t old_size, size_t new_size) {
[email protected]fb246af2012-08-18 03:11:4153 gpu_memory_manager_tracking_group_->TrackMemoryAllocatedChange(
54 old_size, new_size);
[email protected]00b192572012-07-28 04:00:2255 }
56
57 private:
[email protected]fb246af2012-08-18 03:11:4158 ~GpuCommandBufferMemoryTracker() {
59 delete gpu_memory_manager_tracking_group_;
60 }
61 GpuMemoryTrackingGroup* gpu_memory_manager_tracking_group_;
[email protected]00b192572012-07-28 04:00:2262
63 DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker);
64};
65
[email protected]d1a9e062012-07-13 00:45:1466// FastSetActiveURL will shortcut the expensive call to SetActiveURL when the
67// url_hash matches.
68void FastSetActiveURL(const GURL& url, size_t url_hash) {
69 // Leave the previously set URL in the empty case -- empty URLs are given by
70 // WebKitPlatformSupportImpl::createOffscreenGraphicsContext3D. Hopefully the
71 // onscreen context URL was set previously and will show up even when a crash
72 // occurs during offscreen command processing.
73 if (url.is_empty())
74 return;
75 static size_t g_last_url_hash = 0;
76 if (url_hash != g_last_url_hash) {
77 g_last_url_hash = url_hash;
78 content::GetContentClient()->SetActiveURL(url);
79 }
80}
81
[email protected]56fc2f22012-07-09 23:50:3682// The first time polling a fence, delay some extra time to allow other
83// stubs to process some work, or else the timing of the fences could
84// allow a pattern of alternating fast and slow frames to occur.
85const int64 kHandleMoreWorkPeriodMs = 2;
86const int64 kHandleMoreWorkPeriodBusyMs = 1;
[email protected]d1a9e062012-07-13 00:45:1487
88} // namespace
[email protected]56fc2f22012-07-09 23:50:3689
[email protected]5178c4422012-10-17 12:08:0790GpuCommandBufferStub::MemoryManagerState::MemoryManagerState(
91 bool has_surface,
92 bool visible,
93 base::TimeTicks last_used_time)
94 : has_surface(has_surface),
[email protected]672c7312012-02-03 16:28:5595 visible(visible),
[email protected]5178c4422012-10-17 12:08:0796 client_has_memory_allocation_changed_callback(false),
[email protected]672c7312012-02-03 16:28:5597 last_used_time(last_used_time) {
98}
99
[email protected]a3ded6d2010-10-19 06:44:39100GpuCommandBufferStub::GpuCommandBufferStub(
101 GpuChannel* channel,
[email protected]3b1ecc262011-08-03 22:49:57102 GpuCommandBufferStub* share_group,
[email protected]fc4ed092012-02-21 19:46:55103 const gfx::GLSurfaceHandle& handle,
[email protected]78b514b2012-05-01 21:50:59104 gpu::gles2::MailboxManager* mailbox_manager,
[email protected]a3ded6d2010-10-19 06:44:39105 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29106 const gpu::gles2::DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39107 const std::string& allowed_extensions,
108 const std::vector<int32>& attribs,
[email protected]276f89062011-10-13 22:55:50109 gfx::GpuPreference gpu_preference,
[email protected]a3ded6d2010-10-19 06:44:39110 int32 route_id,
[email protected]9f4f3322012-01-18 22:29:56111 int32 surface_id,
[email protected]f81f5952011-07-21 18:52:47112 GpuWatchdog* watchdog,
[email protected]d1a9e062012-07-13 00:45:14113 bool software,
[email protected]7f1a51c322012-07-19 18:52:02114 const GURL& active_url)
[email protected]246a70452010-03-05 21:53:50115 : channel_(channel),
[email protected]6ebf2fc2010-07-01 01:06:32116 handle_(handle),
[email protected]6217d392010-03-25 22:08:35117 initial_size_(size),
[email protected]e82fb792011-09-22 00:33:29118 disallowed_features_(disallowed_features),
[email protected]bc518752010-10-20 21:38:27119 allowed_extensions_(allowed_extensions),
[email protected]34ff8b0c2010-10-01 20:06:02120 requested_attribs_(attribs),
[email protected]276f89062011-10-13 22:55:50121 gpu_preference_(gpu_preference),
[email protected]77e74db2010-08-04 17:46:23122 route_id_(route_id),
[email protected]5178c4422012-10-17 12:08:07123 surface_id_(surface_id),
[email protected]f81f5952011-07-21 18:52:47124 software_(software),
[email protected]a38477142011-05-28 02:45:58125 last_flush_count_(0),
[email protected]e7da6aef2011-06-22 19:29:03126 parent_stub_for_initialization_(),
127 parent_texture_for_initialization_(0),
[email protected]35a0b4b2012-06-15 03:53:30128 watchdog_(watchdog),
[email protected]56fc2f22012-07-09 23:50:36129 sync_point_wait_count_(0),
[email protected]d1a9e062012-07-13 00:45:14130 delayed_work_scheduled_(false),
131 active_url_(active_url) {
[email protected]51ddf722012-09-01 00:55:09132 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec());
[email protected]d1a9e062012-07-13 00:45:14133 FastSetActiveURL(active_url_, active_url_hash_);
[email protected]bf5a8d132011-08-16 08:39:35134 if (share_group) {
[email protected]3b1ecc262011-08-03 22:49:57135 context_group_ = share_group->context_group_;
[email protected]bf5a8d132011-08-16 08:39:35136 } else {
[email protected]00b192572012-07-28 04:00:22137 context_group_ = new gpu::gles2::ContextGroup(
[email protected]fb246af2012-08-18 03:11:41138 mailbox_manager,
139 new GpuCommandBufferMemoryTracker(channel),
140 true);
[email protected]bf5a8d132011-08-16 08:39:35141 }
[email protected]5178c4422012-10-17 12:08:07142 memory_manager_state_.reset(new GpuCommandBufferStubBase::MemoryManagerState(
143 surface_id != 0, true, base::TimeTicks::Now()));
[email protected]35a0b4b2012-06-15 03:53:30144 if (handle_.sync_point)
145 OnWaitSyncPoint(handle_.sync_point);
[email protected]246a70452010-03-05 21:53:50146}
147
148GpuCommandBufferStub::~GpuCommandBufferStub() {
[email protected]79311e82011-09-20 00:40:50149 Destroy();
[email protected]d8a58e42011-01-27 15:24:25150
[email protected]f24a1e2b2011-04-08 01:48:48151 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
[email protected]672c7312012-02-03 16:28:55152 gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer(surface_id()));
[email protected]246a70452010-03-05 21:53:50153}
154
[email protected]a95986a82010-12-24 06:19:28155bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
[email protected]d1a9e062012-07-13 00:45:14156 FastSetActiveURL(active_url_, active_url_hash_);
157
[email protected]79311e82011-09-20 00:40:50158 // Ensure the appropriate GL context is current before handling any IPC
159 // messages directed at the command buffer. This ensures that the message
[email protected]6802e3c62012-06-06 22:32:44160 // handler can assume that the context is current (not necessary for
[email protected]68c70282012-06-25 23:31:17161 // Echo, RetireSyncPoint, or WaitSyncPoint).
[email protected]6802e3c62012-06-06 22:32:44162 if (decoder_.get() &&
[email protected]68c70282012-06-25 23:31:17163 message.type() != GpuCommandBufferMsg_Echo::ID &&
164 message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID &&
165 message.type() != GpuCommandBufferMsg_WaitSyncPoint::ID) {
[email protected]062e5e82012-06-20 19:30:35166 if (!MakeCurrent())
[email protected]79311e82011-09-20 00:40:50167 return false;
[email protected]79311e82011-09-20 00:40:50168 }
169
[email protected]310bed512011-05-09 21:12:25170 // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
171 // here. This is so the reply can be delayed if the scheduler is unscheduled.
[email protected]a95986a82010-12-24 06:19:28172 bool handled = true;
[email protected]246a70452010-03-05 21:53:50173 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
[email protected]310bed512011-05-09 21:12:25174 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize,
175 OnInitialize);
[email protected]503b3a22011-12-12 23:29:40176 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer,
177 OnSetGetBuffer);
[email protected]68eff952012-02-17 21:56:35178 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetSharedStateBuffer,
179 OnSetSharedStateBuffer);
[email protected]3c644d82011-06-20 19:58:24180 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetParent,
181 OnSetParent);
[email protected]1ef068c2012-03-02 16:30:47182 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Echo, OnEcho);
[email protected]310bed512011-05-09 21:12:25183 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState);
[email protected]451e9662011-10-10 21:14:34184 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetStateFast,
185 OnGetStateFast);
[email protected]246a70452010-03-05 21:53:50186 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
[email protected]d0f02c42011-07-21 21:40:48187 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Rescheduled, OnRescheduled);
[email protected]310bed512011-05-09 21:12:25188 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateTransferBuffer,
189 OnCreateTransferBuffer);
190 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_RegisterTransferBuffer,
191 OnRegisterTransferBuffer);
192 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_DestroyTransferBuffer,
193 OnDestroyTransferBuffer);
194 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetTransferBuffer,
195 OnGetTransferBuffer);
[email protected]c8423062011-07-29 19:25:38196 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder,
197 OnCreateVideoDecoder)
[email protected]a13da242011-07-07 19:48:17198 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyVideoDecoder,
199 OnDestroyVideoDecoder)
[email protected]8cc980c52011-10-14 20:35:51200 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetSurfaceVisible,
201 OnSetSurfaceVisible)
[email protected]251622e2012-03-23 16:17:40202 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DiscardBackbuffer,
203 OnDiscardBackbuffer)
204 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_EnsureBackbuffer,
205 OnEnsureBackbuffer)
[email protected]c02f93e42012-06-05 23:35:16206 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RetireSyncPoint,
207 OnRetireSyncPoint)
208 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_WaitSyncPoint,
209 OnWaitSyncPoint)
[email protected]5ab44ef2012-06-19 00:03:51210 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncPoint,
211 OnSignalSyncPoint)
[email protected]c1f12142012-05-01 22:21:06212 IPC_MESSAGE_HANDLER(
213 GpuCommandBufferMsg_SetClientHasMemoryAllocationChangedCallback,
214 OnSetClientHasMemoryAllocationChangedCallback)
[email protected]a95986a82010-12-24 06:19:28215 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]246a70452010-03-05 21:53:50216 IPC_END_MESSAGE_MAP()
[email protected]a13da242011-07-07 19:48:17217
[email protected]56fc2f22012-07-09 23:50:36218 // Ensure that any delayed work that was created will be handled.
219 ScheduleDelayedWork(kHandleMoreWorkPeriodMs);
220
[email protected]a95986a82010-12-24 06:19:28221 DCHECK(handled);
222 return handled;
[email protected]246a70452010-03-05 21:53:50223}
224
225bool GpuCommandBufferStub::Send(IPC::Message* message) {
226 return channel_->Send(message);
227}
228
[email protected]d0f02c42011-07-21 21:40:48229bool GpuCommandBufferStub::IsScheduled() {
[email protected]35a0b4b2012-06-15 03:53:30230 return sync_point_wait_count_ == 0 &&
231 (!scheduler_.get() || scheduler_->IsScheduled());
[email protected]d0f02c42011-07-21 21:40:48232}
233
[email protected]20f656f2011-12-08 02:25:15234bool GpuCommandBufferStub::HasMoreWork() {
235 return scheduler_.get() && scheduler_->HasMoreWork();
236}
237
[email protected]f5f910d52012-03-06 22:33:09238void GpuCommandBufferStub::PollWork() {
[email protected]56fc2f22012-07-09 23:50:36239 TRACE_EVENT0("gpu", "GpuCommandBufferStub::PollWork");
240 delayed_work_scheduled_ = false;
[email protected]a5b2abb912012-07-13 04:45:04241 FastSetActiveURL(active_url_, active_url_hash_);
[email protected]062e5e82012-06-20 19:30:35242 if (decoder_.get() && !MakeCurrent())
243 return;
[email protected]f5f910d52012-03-06 22:33:09244 if (scheduler_.get())
245 scheduler_->PollUnscheduleFences();
[email protected]56fc2f22012-07-09 23:50:36246 ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs);
[email protected]f5f910d52012-03-06 22:33:09247}
248
[email protected]df621aff2012-03-02 23:04:58249bool GpuCommandBufferStub::HasUnprocessedCommands() {
250 if (command_buffer_.get()) {
251 gpu::CommandBuffer::State state = command_buffer_->GetLastState();
[email protected]6dadf652012-03-22 02:49:24252 return state.put_offset != state.get_offset &&
253 !gpu::error::IsError(state.error);
[email protected]df621aff2012-03-02 23:04:58254 }
255 return false;
256}
257
[email protected]56fc2f22012-07-09 23:50:36258void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) {
259 if (HasMoreWork() && !delayed_work_scheduled_) {
260 delayed_work_scheduled_ = true;
261 MessageLoop::current()->PostDelayedTask(
262 FROM_HERE,
263 base::Bind(&GpuCommandBufferStub::PollWork,
264 AsWeakPtr()),
265 base::TimeDelta::FromMilliseconds(delay));
266 }
267}
268
[email protected]1ef068c2012-03-02 16:30:47269void GpuCommandBufferStub::OnEcho(const IPC::Message& message) {
270 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEcho");
271 Send(new IPC::Message(message));
272}
273
[email protected]ac9ab812012-03-06 22:44:05274void GpuCommandBufferStub::DelayEcho(IPC::Message* message) {
275 delayed_echos_.push_back(message);
276}
277
278void GpuCommandBufferStub::OnReschedule() {
[email protected]35a0b4b2012-06-15 03:53:30279 if (!IsScheduled())
280 return;
[email protected]ac9ab812012-03-06 22:44:05281 while (!delayed_echos_.empty()) {
282 scoped_ptr<IPC::Message> message(delayed_echos_.front());
283 delayed_echos_.pop_front();
284
285 OnMessageReceived(*message);
286 }
287
288 channel_->OnScheduled();
289}
290
[email protected]062e5e82012-06-20 19:30:35291bool GpuCommandBufferStub::MakeCurrent() {
292 if (decoder_->MakeCurrent())
293 return true;
294 DLOG(ERROR) << "Context lost because MakeCurrent failed.";
295 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
296 command_buffer_->SetParseError(gpu::error::kLostContext);
297 if (gfx::GLContext::LosesAllContextsOnContextLost())
298 channel_->LoseAllContexts();
299 return false;
300}
301
[email protected]79311e82011-09-20 00:40:50302void GpuCommandBufferStub::Destroy() {
[email protected]c02f93e42012-06-05 23:35:16303 while (!sync_points_.empty())
304 OnRetireSyncPoint(sync_points_.front());
305
[email protected]79311e82011-09-20 00:40:50306 // The scheduler has raw references to the decoder and the command buffer so
307 // destroy it before those.
[email protected]4ee0c3052011-09-16 19:30:36308 scheduler_.reset();
[email protected]79311e82011-09-20 00:40:50309
[email protected]ac9ab812012-03-06 22:44:05310 while (!delayed_echos_.empty()) {
311 delete delayed_echos_.front();
312 delayed_echos_.pop_front();
313 }
314
[email protected]706b69f2012-07-27 04:59:30315 bool have_context = false;
[email protected]0f9386892012-02-15 01:44:07316 if (decoder_.get())
[email protected]706b69f2012-07-27 04:59:30317 have_context = decoder_->MakeCurrent();
[email protected]0f9386892012-02-15 01:44:07318 FOR_EACH_OBSERVER(DestructionObserver,
319 destruction_observers_,
320 OnWillDestroyStub(this));
321
[email protected]79311e82011-09-20 00:40:50322 if (decoder_.get()) {
[email protected]706b69f2012-07-27 04:59:30323 decoder_->Destroy(have_context);
[email protected]79311e82011-09-20 00:40:50324 decoder_.reset();
325 }
326
[email protected]4ee0c3052011-09-16 19:30:36327 command_buffer_.reset();
[email protected]79311e82011-09-20 00:40:50328
329 context_ = NULL;
330 surface_ = NULL;
[email protected]672c7312012-02-03 16:28:55331
[email protected]5d5374e2012-06-19 16:46:51332 channel_->gpu_channel_manager()->gpu_memory_manager()->ScheduleManage(false);
[email protected]79311e82011-09-20 00:40:50333}
334
335void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) {
336 Destroy();
[email protected]2e7bbf22011-07-22 18:41:29337 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, false);
338 Send(reply_message);
339}
340
[email protected]246a70452010-03-05 21:53:50341void GpuCommandBufferStub::OnInitialize(
[email protected]310bed512011-05-09 21:12:25342 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32343 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnInitialize");
[email protected]246a70452010-03-05 21:53:50344 DCHECK(!command_buffer_.get());
345
[email protected]1d471e82012-06-01 06:13:40346 command_buffer_.reset(new gpu::CommandBufferService(
347 context_group_->transfer_buffer_manager()));
[email protected]246a70452010-03-05 21:53:50348
[email protected]503b3a22011-12-12 23:29:40349 if (!command_buffer_->Initialize()) {
[email protected]198e0c442011-12-02 19:45:06350 DLOG(ERROR) << "CommandBufferService failed to initialize.\n";
[email protected]79311e82011-09-20 00:40:50351 OnInitializeFailed(reply_message);
352 return;
353 }
354
355 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get()));
356
357 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
358 decoder_.get(),
[email protected]8a9e1a12011-12-20 01:46:05359 decoder_.get()));
[email protected]6802e3c62012-06-06 22:32:44360 if (preempt_by_counter_.get())
361 scheduler_->SetPreemptByCounter(preempt_by_counter_);
[email protected]79311e82011-09-20 00:40:50362
363 decoder_->set_engine(scheduler_.get());
364
[email protected]47940c82012-02-08 02:23:49365 if (!handle_.is_null()) {
[email protected]839d5172011-10-13 17:18:11366#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]2e7bbf22011-07-22 18:41:29367 if (software_) {
[email protected]198e0c442011-12-02 19:45:06368 DLOG(ERROR) << "No software support.\n";
[email protected]2e7bbf22011-07-22 18:41:29369 OnInitializeFailed(reply_message);
370 return;
371 }
[email protected]290fc492011-11-22 23:25:23372#endif
[email protected]2e7bbf22011-07-22 18:41:29373
[email protected]79311e82011-09-20 00:40:50374 surface_ = ImageTransportSurface::CreateSurface(
375 channel_->gpu_channel_manager(),
[email protected]9f4f3322012-01-18 22:29:56376 this,
[email protected]04d58ce2011-09-29 13:12:23377 handle_);
[email protected]79311e82011-09-20 00:40:50378 } else {
[email protected]b8673e62012-09-25 03:15:00379 GpuChannelManager* manager = channel_->gpu_channel_manager();
380 surface_ = manager->GetDefaultOffscreenSurface();
[email protected]79311e82011-09-20 00:40:50381 }
382
383 if (!surface_.get()) {
[email protected]cdcd5bd2011-10-15 00:19:38384 // Ensure the decoder is not destroyed if it is not initialized.
385 decoder_.reset();
386
[email protected]cc63025a2011-10-29 02:16:24387 DLOG(ERROR) << "Failed to create surface.\n";
[email protected]79311e82011-09-20 00:40:50388 OnInitializeFailed(reply_message);
389 return;
390 }
391
[email protected]276f89062011-10-13 22:55:50392 context_ = gfx::GLContext::CreateGLContext(
393 channel_->share_group(),
394 surface_.get(),
[email protected]96a28ea2012-06-09 02:16:09395 gpu_preference_);
[email protected]79311e82011-09-20 00:40:50396 if (!context_.get()) {
[email protected]cdcd5bd2011-10-15 00:19:38397 // Ensure the decoder is not destroyed if it is not initialized.
398 decoder_.reset();
399
[email protected]cc63025a2011-10-29 02:16:24400 DLOG(ERROR) << "Failed to create context.\n";
[email protected]79311e82011-09-20 00:40:50401 OnInitializeFailed(reply_message);
402 return;
403 }
[email protected]4bbe6d0c2011-09-16 18:58:54404
[email protected]63c9b052012-05-17 18:27:38405 if (!context_->MakeCurrent(surface_.get())) {
[email protected]35a0b4b2012-06-15 03:53:30406 // Ensure the decoder is not destroyed if it is not initialized.
407 decoder_.reset();
[email protected]63c9b052012-05-17 18:27:38408 LOG(ERROR) << "Failed to make context current.";
409 OnInitializeFailed(reply_message);
410 return;
411 }
412
[email protected]65dfc602012-07-23 20:39:39413 if (!context_group_->has_program_cache()) {
414 context_group_->set_program_cache(
415 channel_->gpu_channel_manager()->program_cache());
416 }
417
[email protected]79311e82011-09-20 00:40:50418 // Initialize the decoder with either the view or pbuffer GLContext.
[email protected]63c9b052012-05-17 18:27:38419 if (!decoder_->Initialize(surface_,
420 context_,
[email protected]069944672012-04-25 20:52:23421 !surface_id(),
[email protected]79311e82011-09-20 00:40:50422 initial_size_,
[email protected]e82fb792011-09-22 00:33:29423 disallowed_features_,
[email protected]79311e82011-09-20 00:40:50424 allowed_extensions_.c_str(),
425 requested_attribs_)) {
[email protected]cc63025a2011-10-29 02:16:24426 DLOG(ERROR) << "Failed to initialize decoder.";
[email protected]79311e82011-09-20 00:40:50427 OnInitializeFailed(reply_message);
428 return;
429 }
430
431 if (CommandLine::ForCurrentProcess()->HasSwitch(
432 switches::kEnableGPUServiceLogging)) {
[email protected]e844ae22012-01-14 03:36:26433 decoder_->set_log_commands(true);
[email protected]79311e82011-09-20 00:40:50434 }
435
[email protected]6b6e7ee2011-12-13 08:04:52436 decoder_->SetMsgCallback(
437 base::Bind(&GpuCommandBufferStub::SendConsoleMessage,
438 base::Unretained(this)));
439
[email protected]79311e82011-09-20 00:40:50440 command_buffer_->SetPutOffsetChangeCallback(
[email protected]d1a9e062012-07-13 00:45:14441 base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this)));
[email protected]503b3a22011-12-12 23:29:40442 command_buffer_->SetGetBufferChangeCallback(
443 base::Bind(&gpu::GpuScheduler::SetGetBuffer,
444 base::Unretained(scheduler_.get())));
[email protected]79311e82011-09-20 00:40:50445 command_buffer_->SetParseErrorCallback(
[email protected]9d37f062011-11-22 01:24:52446 base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50447 scheduler_->SetScheduledCallback(
[email protected]ac9ab812012-03-06 22:44:05448 base::Bind(&GpuCommandBufferStub::OnReschedule, base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50449
[email protected]79311e82011-09-20 00:40:50450 if (watchdog_) {
451 scheduler_->SetCommandProcessedCallback(
[email protected]9d37f062011-11-22 01:24:52452 base::Bind(&GpuCommandBufferStub::OnCommandProcessed,
453 base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50454 }
455
[email protected]34aaa5682012-09-25 00:48:50456#if defined(OS_ANDROID)
457 decoder_->SetStreamTextureManager(channel_->stream_texture_manager());
458#endif
459
[email protected]79311e82011-09-20 00:40:50460 if (parent_stub_for_initialization_) {
461 decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(),
462 parent_texture_for_initialization_);
463 parent_stub_for_initialization_.reset();
464 parent_texture_for_initialization_ = 0;
465 }
[email protected]310bed512011-05-09 21:12:25466
[email protected]2e7bbf22011-07-22 18:41:29467 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, true);
[email protected]310bed512011-05-09 21:12:25468 Send(reply_message);
[email protected]672c7312012-02-03 16:28:55469
[email protected]5d5374e2012-06-19 16:46:51470 channel_->gpu_channel_manager()->gpu_memory_manager()->ScheduleManage(true);
[email protected]246a70452010-03-05 21:53:50471}
472
[email protected]503b3a22011-12-12 23:29:40473void GpuCommandBufferStub::OnSetGetBuffer(
474 int32 shm_id, IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32475 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer");
[email protected]773bf5e2012-01-06 01:07:13476 if (command_buffer_.get()) {
477 command_buffer_->SetGetBuffer(shm_id);
478 } else {
479 DLOG(ERROR) << "no command_buffer.";
480 reply_message->set_reply_error();
481 }
[email protected]503b3a22011-12-12 23:29:40482 Send(reply_message);
483}
484
[email protected]68eff952012-02-17 21:56:35485void GpuCommandBufferStub::OnSetSharedStateBuffer(
486 int32 shm_id, IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32487 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSharedStateBuffer");
[email protected]68eff952012-02-17 21:56:35488 if (command_buffer_.get()) {
489 command_buffer_->SetSharedStateBuffer(shm_id);
490 } else {
491 DLOG(ERROR) << "no command_buffer.";
492 reply_message->set_reply_error();
493 }
494 Send(reply_message);
495}
496
[email protected]3c644d82011-06-20 19:58:24497void GpuCommandBufferStub::OnSetParent(int32 parent_route_id,
498 uint32 parent_texture_id,
499 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32500 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetParent");
[email protected]e7da6aef2011-06-22 19:29:03501 GpuCommandBufferStub* parent_stub = NULL;
502 if (parent_route_id != MSG_ROUTING_NONE) {
503 parent_stub = channel_->LookupCommandBuffer(parent_route_id);
[email protected]3c644d82011-06-20 19:58:24504 }
505
[email protected]e7da6aef2011-06-22 19:29:03506 bool result = true;
507 if (scheduler_.get()) {
[email protected]79311e82011-09-20 00:40:50508 gpu::gles2::GLES2Decoder* parent_decoder =
509 parent_stub ? parent_stub->decoder_.get() : NULL;
510 result = decoder_->SetParent(parent_decoder, parent_texture_id);
[email protected]e7da6aef2011-06-22 19:29:03511 } else {
512 // If we don't have a scheduler, it means that Initialize hasn't been called
513 // yet. Keep around the requested parent stub and texture so that we can set
514 // it in Initialize().
515 parent_stub_for_initialization_ = parent_stub ?
516 parent_stub->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>();
517 parent_texture_for_initialization_ = parent_texture_id;
518 }
[email protected]3c644d82011-06-20 19:58:24519 GpuCommandBufferMsg_SetParent::WriteReplyParams(reply_message, result);
520 Send(reply_message);
521}
522
[email protected]310bed512011-05-09 21:12:25523void GpuCommandBufferStub::OnGetState(IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32524 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetState");
[email protected]773bf5e2012-01-06 01:07:13525 if (command_buffer_.get()) {
526 gpu::CommandBuffer::State state = command_buffer_->GetState();
527 if (state.error == gpu::error::kLostContext &&
528 gfx::GLContext::LosesAllContextsOnContextLost())
529 channel_->LoseAllContexts();
[email protected]310bed512011-05-09 21:12:25530
[email protected]773bf5e2012-01-06 01:07:13531 GpuCommandBufferMsg_GetState::WriteReplyParams(reply_message, state);
532 } else {
533 DLOG(ERROR) << "no command_buffer.";
534 reply_message->set_reply_error();
535 }
[email protected]310bed512011-05-09 21:12:25536 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50537}
538
[email protected]0a68ac872011-06-07 04:48:27539void GpuCommandBufferStub::OnParseError() {
540 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnParseError");
[email protected]773bf5e2012-01-06 01:07:13541 DCHECK(command_buffer_.get());
[email protected]38d139d2011-07-14 00:38:43542 gpu::CommandBuffer::State state = command_buffer_->GetState();
543 IPC::Message* msg = new GpuCommandBufferMsg_Destroyed(
544 route_id_, state.context_lost_reason);
[email protected]0a68ac872011-06-07 04:48:27545 msg->set_unblock(true);
546 Send(msg);
547}
548
[email protected]451e9662011-10-10 21:14:34549void GpuCommandBufferStub::OnGetStateFast(IPC::Message* reply_message) {
550 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetStateFast");
[email protected]773bf5e2012-01-06 01:07:13551 DCHECK(command_buffer_.get());
[email protected]d0f02c42011-07-21 21:40:48552 gpu::CommandBuffer::State state = command_buffer_->GetState();
[email protected]451e9662011-10-10 21:14:34553 if (state.error == gpu::error::kLostContext &&
554 gfx::GLContext::LosesAllContextsOnContextLost())
555 channel_->LoseAllContexts();
[email protected]1d4ea842011-07-20 01:11:51556
[email protected]451e9662011-10-10 21:14:34557 GpuCommandBufferMsg_GetStateFast::WriteReplyParams(reply_message, state);
558 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50559}
560
[email protected]451e9662011-10-10 21:14:34561void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset,
562 uint32 flush_count) {
563 TRACE_EVENT1("gpu", "GpuCommandBufferStub::OnAsyncFlush",
564 "put_offset", put_offset);
[email protected]773bf5e2012-01-06 01:07:13565 DCHECK(command_buffer_.get());
[email protected]fde205d2011-05-31 22:29:50566 if (flush_count - last_flush_count_ < 0x8000000U) {
[email protected]a38477142011-05-28 02:45:58567 last_flush_count_ = flush_count;
568 command_buffer_->Flush(put_offset);
569 } else {
[email protected]fde205d2011-05-31 22:29:50570 // We received this message out-of-order. This should not happen but is here
571 // to catch regressions. Ignore the message.
572 NOTREACHED() << "Received a Flush message out-of-order";
[email protected]a38477142011-05-28 02:45:58573 }
[email protected]d0f02c42011-07-21 21:40:48574
575 ReportState();
576}
577
578void GpuCommandBufferStub::OnRescheduled() {
[email protected]20f656f2011-12-08 02:25:15579 gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState();
580 command_buffer_->Flush(pre_state.put_offset);
581 gpu::CommandBuffer::State post_state = command_buffer_->GetLastState();
[email protected]d0f02c42011-07-21 21:40:48582
[email protected]20f656f2011-12-08 02:25:15583 if (pre_state.get_offset != post_state.get_offset)
584 ReportState();
[email protected]246a70452010-03-05 21:53:50585}
586
[email protected]ce9eea602011-04-12 20:09:57587void GpuCommandBufferStub::OnCreateTransferBuffer(int32 size,
588 int32 id_request,
[email protected]310bed512011-05-09 21:12:25589 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32590 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateTransferBuffer");
[email protected]773bf5e2012-01-06 01:07:13591 if (command_buffer_.get()) {
592 int32 id = command_buffer_->CreateTransferBuffer(size, id_request);
593 GpuCommandBufferMsg_CreateTransferBuffer::WriteReplyParams(
594 reply_message, id);
595 } else {
596 reply_message->set_reply_error();
597 }
[email protected]310bed512011-05-09 21:12:25598 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50599}
600
[email protected]0100b7a2011-02-24 22:54:50601void GpuCommandBufferStub::OnRegisterTransferBuffer(
602 base::SharedMemoryHandle transfer_buffer,
603 size_t size,
[email protected]ce9eea602011-04-12 20:09:57604 int32 id_request,
[email protected]310bed512011-05-09 21:12:25605 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32606 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterTransferBuffer");
[email protected]0100b7a2011-02-24 22:54:50607 base::SharedMemory shared_memory(transfer_buffer, false);
[email protected]7df1d1a2011-02-26 02:07:57608
[email protected]773bf5e2012-01-06 01:07:13609 if (command_buffer_.get()) {
610 int32 id = command_buffer_->RegisterTransferBuffer(&shared_memory,
611 size,
612 id_request);
613 GpuCommandBufferMsg_RegisterTransferBuffer::WriteReplyParams(reply_message,
614 id);
615 } else {
616 reply_message->set_reply_error();
617 }
[email protected]310bed512011-05-09 21:12:25618
[email protected]310bed512011-05-09 21:12:25619 Send(reply_message);
[email protected]0100b7a2011-02-24 22:54:50620}
621
[email protected]310bed512011-05-09 21:12:25622void GpuCommandBufferStub::OnDestroyTransferBuffer(
623 int32 id,
624 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32625 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyTransferBuffer");
[email protected]773bf5e2012-01-06 01:07:13626 if (command_buffer_.get()) {
627 command_buffer_->DestroyTransferBuffer(id);
628 } else {
629 reply_message->set_reply_error();
630 }
[email protected]310bed512011-05-09 21:12:25631 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50632}
633
634void GpuCommandBufferStub::OnGetTransferBuffer(
635 int32 id,
[email protected]310bed512011-05-09 21:12:25636 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32637 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetTransferBuffer");
[email protected]773bf5e2012-01-06 01:07:13638 if (command_buffer_.get()) {
639 base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle();
640 uint32 size = 0;
[email protected]310bed512011-05-09 21:12:25641
[email protected]773bf5e2012-01-06 01:07:13642 gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id);
643 if (buffer.shared_memory) {
[email protected]cd0bd792012-04-14 00:52:16644#if defined(OS_WIN)
645 transfer_buffer = NULL;
[email protected]d30ce6e2012-04-16 15:32:36646 content::BrokerDuplicateHandle(buffer.shared_memory->handle(),
[email protected]cd0bd792012-04-14 00:52:16647 channel_->renderer_pid(), &transfer_buffer, FILE_MAP_READ |
648 FILE_MAP_WRITE, 0);
[email protected]8f9904d2012-05-09 00:20:22649 DCHECK(transfer_buffer != NULL);
[email protected]cd0bd792012-04-14 00:52:16650#else
651 buffer.shared_memory->ShareToProcess(channel_->renderer_pid(),
[email protected]773bf5e2012-01-06 01:07:13652 &transfer_buffer);
[email protected]cd0bd792012-04-14 00:52:16653#endif
[email protected]773bf5e2012-01-06 01:07:13654 size = buffer.size;
655 }
656
657 GpuCommandBufferMsg_GetTransferBuffer::WriteReplyParams(reply_message,
658 transfer_buffer,
659 size);
660 } else {
661 reply_message->set_reply_error();
662 }
[email protected]310bed512011-05-09 21:12:25663 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50664}
665
[email protected]310bed512011-05-09 21:12:25666void GpuCommandBufferStub::OnCommandProcessed() {
667 if (watchdog_)
668 watchdog_->CheckArmed();
669}
670
[email protected]ef16c172011-04-28 23:37:14671void GpuCommandBufferStub::ReportState() {
672 gpu::CommandBuffer::State state = command_buffer_->GetState();
673 if (state.error == gpu::error::kLostContext &&
674 gfx::GLContext::LosesAllContextsOnContextLost()) {
675 channel_->LoseAllContexts();
676 } else {
[email protected]68eff952012-02-17 21:56:35677 command_buffer_->UpdateState();
[email protected]ef16c172011-04-28 23:37:14678 }
679}
680
[email protected]d1a9e062012-07-13 00:45:14681void GpuCommandBufferStub::PutChanged() {
682 FastSetActiveURL(active_url_, active_url_hash_);
683 scheduler_->PutChanged();
684}
685
[email protected]a13da242011-07-07 19:48:17686void GpuCommandBufferStub::OnCreateVideoDecoder(
[email protected]e5ca6362012-03-30 09:45:58687 media::VideoCodecProfile profile,
[email protected]c8423062011-07-29 19:25:38688 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32689 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoDecoder");
[email protected]502e6052011-08-17 00:17:23690 int decoder_route_id = channel_->GenerateRouteID();
[email protected]502e6052011-08-17 00:17:23691 GpuVideoDecodeAccelerator* decoder =
692 new GpuVideoDecodeAccelerator(this, decoder_route_id, this);
693 video_decoders_.AddWithID(decoder, decoder_route_id);
694 channel_->AddRoute(decoder_route_id, decoder);
[email protected]cd0bd792012-04-14 00:52:16695 decoder->Initialize(profile, reply_message);
[email protected]a13da242011-07-07 19:48:17696}
697
[email protected]502e6052011-08-17 00:17:23698void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) {
[email protected]3551cb202012-05-24 10:55:32699 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyVideoDecoder");
[email protected]502e6052011-08-17 00:17:23700 channel_->RemoveRoute(decoder_route_id);
701 video_decoders_.Remove(decoder_route_id);
[email protected]a13da242011-07-07 19:48:17702}
703
[email protected]8cc980c52011-10-14 20:35:51704void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) {
[email protected]3551cb202012-05-24 10:55:32705 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSurfaceVisible");
[email protected]5178c4422012-10-17 12:08:07706 memory_manager_state_->visible = visible;
707 memory_manager_state_->last_used_time = base::TimeTicks::Now();
708 channel_->gpu_channel_manager()->gpu_memory_manager()->
709 ScheduleManage(visible);
[email protected]8cc980c52011-10-14 20:35:51710}
711
[email protected]251622e2012-03-23 16:17:40712void GpuCommandBufferStub::OnDiscardBackbuffer() {
[email protected]3551cb202012-05-24 10:55:32713 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDiscardBackbuffer");
[email protected]251622e2012-03-23 16:17:40714 if (!surface_)
715 return;
[email protected]3ac71bf2012-05-16 15:55:53716 surface_->SetBackbufferAllocation(false);
[email protected]251622e2012-03-23 16:17:40717}
718
719void GpuCommandBufferStub::OnEnsureBackbuffer() {
[email protected]3551cb202012-05-24 10:55:32720 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEnsureBackbuffer");
[email protected]251622e2012-03-23 16:17:40721 if (!surface_)
722 return;
[email protected]3ac71bf2012-05-16 15:55:53723 surface_->SetBackbufferAllocation(true);
[email protected]251622e2012-03-23 16:17:40724}
725
[email protected]c02f93e42012-06-05 23:35:16726void GpuCommandBufferStub::AddSyncPoint(uint32 sync_point) {
727 sync_points_.push_back(sync_point);
728}
729
730void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) {
731 DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point);
732 sync_points_.pop_front();
733 GpuChannelManager* manager = channel_->gpu_channel_manager();
734 manager->sync_point_manager()->RetireSyncPoint(sync_point);
735}
736
737void GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) {
[email protected]35a0b4b2012-06-15 03:53:30738 if (sync_point_wait_count_ == 0) {
739 TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this,
740 "GpuCommandBufferStub", this);
741 }
742 ++sync_point_wait_count_;
[email protected]c02f93e42012-06-05 23:35:16743 GpuChannelManager* manager = channel_->gpu_channel_manager();
744 manager->sync_point_manager()->AddSyncPointCallback(
745 sync_point,
746 base::Bind(&GpuCommandBufferStub::OnSyncPointRetired,
747 this->AsWeakPtr()));
748}
749
750void GpuCommandBufferStub::OnSyncPointRetired() {
[email protected]35a0b4b2012-06-15 03:53:30751 --sync_point_wait_count_;
752 if (sync_point_wait_count_ == 0) {
753 TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this,
754 "GpuCommandBufferStub", this);
755 }
756 OnReschedule();
[email protected]c02f93e42012-06-05 23:35:16757}
758
[email protected]5ab44ef2012-06-19 00:03:51759void GpuCommandBufferStub::OnSignalSyncPoint(uint32 sync_point, uint32 id) {
760 GpuChannelManager* manager = channel_->gpu_channel_manager();
761 manager->sync_point_manager()->AddSyncPointCallback(
762 sync_point,
763 base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck,
764 this->AsWeakPtr(),
765 id));
766}
767
768void GpuCommandBufferStub::OnSignalSyncPointAck(uint32 id) {
769 Send(new GpuCommandBufferMsg_SignalSyncPointAck(route_id_, id));
770}
771
[email protected]c1f12142012-05-01 22:21:06772void GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback(
773 bool has_callback) {
[email protected]3551cb202012-05-24 10:55:32774 TRACE_EVENT0(
775 "gpu",
776 "GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback");
[email protected]5178c4422012-10-17 12:08:07777 memory_manager_state_->client_has_memory_allocation_changed_callback =
778 has_callback;
[email protected]5d5374e2012-06-19 16:46:51779 channel_->gpu_channel_manager()->gpu_memory_manager()->
780 ScheduleManage(false);
[email protected]c1f12142012-05-01 22:21:06781}
782
[email protected]6b6e7ee2011-12-13 08:04:52783void GpuCommandBufferStub::SendConsoleMessage(
784 int32 id,
785 const std::string& message) {
786 GPUCommandBufferConsoleMessage console_message;
787 console_message.id = id;
788 console_message.message = message;
789 IPC::Message* msg = new GpuCommandBufferMsg_ConsoleMsg(
790 route_id_, console_message);
791 msg->set_unblock(true);
792 Send(msg);
793}
794
[email protected]0f9386892012-02-15 01:44:07795void GpuCommandBufferStub::AddDestructionObserver(
796 DestructionObserver* observer) {
797 destruction_observers_.AddObserver(observer);
798}
799
800void GpuCommandBufferStub::RemoveDestructionObserver(
801 DestructionObserver* observer) {
802 destruction_observers_.RemoveObserver(observer);
803}
804
[email protected]6802e3c62012-06-06 22:32:44805void GpuCommandBufferStub::SetPreemptByCounter(
[email protected]68c70282012-06-25 23:31:17806 scoped_refptr<gpu::RefCountedCounter> counter) {
[email protected]6802e3c62012-06-06 22:32:44807 preempt_by_counter_ = counter;
808 if (scheduler_.get())
809 scheduler_->SetPreemptByCounter(preempt_by_counter_);
810}
811
[email protected]4b8a6b092012-10-05 01:20:06812bool GpuCommandBufferStub::GetTotalGpuMemory(size_t* bytes) {
813 if (!MakeCurrent())
814 return false;
815 return context_->GetTotalGpuMemory(bytes);
816}
817
[email protected]1d56e9642012-05-04 15:40:13818gfx::Size GpuCommandBufferStub::GetSurfaceSize() const {
819 if (!surface_)
820 return gfx::Size();
821 return surface_->GetSize();
822}
823
[email protected]c53709012012-02-21 03:22:22824bool GpuCommandBufferStub::IsInSameContextShareGroup(
825 const GpuCommandBufferStubBase& other) const {
826 return context_group_ ==
827 static_cast<const GpuCommandBufferStub&>(other).context_group_;
828}
829
[email protected]c1f12142012-05-01 22:21:06830
[email protected]5178c4422012-10-17 12:08:07831const GpuCommandBufferStubBase::MemoryManagerState&
832 GpuCommandBufferStub::memory_manager_state() const {
833 return *memory_manager_state_.get();
[email protected]672c7312012-02-03 16:28:55834}
[email protected]74b407d2012-02-11 01:13:55835void GpuCommandBufferStub::SetMemoryAllocation(
836 const GpuMemoryAllocation& allocation) {
[email protected]3ac71bf2012-05-16 15:55:53837 Send(new GpuCommandBufferMsg_SetMemoryAllocation(route_id_, allocation));
[email protected]062e5e82012-06-20 19:30:35838 // This can be called outside of OnMessageReceived, so the context needs to be
839 // made current before calling methods on the surface.
840 if (!surface_ || !MakeCurrent())
[email protected]3ac71bf2012-05-16 15:55:53841 return;
842 surface_->SetFrontbufferAllocation(allocation.suggest_have_frontbuffer);
[email protected]74b407d2012-02-11 01:13:55843}
844
[email protected]8e5cc282010-12-05 18:11:39845#endif // defined(ENABLE_GPU)