blob: faa3796375e89807eb3a6840d3ae6918a3c2bc46 [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
[email protected]80c49752011-04-18 23:55:105#include "base/bind.h"
[email protected]9d37f062011-11-22 01:24:526#include "base/bind_helpers.h"
[email protected]79311e82011-09-20 00:40:507#include "base/command_line.h"
[email protected]366ae242011-05-10 02:23:588#include "base/debug/trace_event.h"
[email protected]51ddf722012-09-01 00:55:099#include "base/hash.h"
[email protected]246a70452010-03-05 21:53:5010#include "base/shared_memory.h"
[email protected]672c7312012-02-03 16:28:5511#include "base/time.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]672c7312012-02-03 16:28:5516#include "content/common/gpu/gpu_memory_manager.h"
[email protected]fb246af2012-08-18 03:11:4117#include "content/common/gpu/gpu_memory_tracking.h"
[email protected]202b54ff2011-04-22 21:36:3818#include "content/common/gpu/gpu_messages.h"
[email protected]2dcf7022011-04-15 19:20:4119#include "content/common/gpu/gpu_watchdog.h"
[email protected]bc4a3432011-11-21 23:55:5620#include "content/common/gpu/image_transport_surface.h"
[email protected]cdd3d642012-06-27 19:59:1421#include "content/common/gpu/media/gpu_video_decode_accelerator.h"
[email protected]c02f93e42012-06-05 23:35:1622#include "content/common/gpu/sync_point_manager.h"
[email protected]d1a9e062012-07-13 00:45:1423#include "content/public/common/content_client.h"
[email protected]ee1e6aa2012-11-29 09:24:1024#include "content/public/common/content_switches.h"
[email protected]290fc492011-11-22 23:25:2325#include "gpu/command_buffer/common/constants.h"
[email protected]d670e702012-03-30 10:38:2126#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]ee1e6aa2012-11-29 09:24:1027#include "gpu/command_buffer/service/gl_context_virtual.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]879c7dfd2012-12-19 21:44:3747 GpuCommandBufferMemoryTracker(GpuChannel* channel) :
[email protected]931989f2012-12-24 23:34:4548 tracking_group_(channel->gpu_channel_manager()->gpu_memory_manager()->
49 CreateTrackingGroup(channel->renderer_pid(), this)) {
[email protected]fb246af2012-08-18 03:11:4150 }
51
[email protected]68e81a4a62012-12-13 01:16:4852 void TrackMemoryAllocatedChange(size_t old_size,
53 size_t new_size,
54 gpu::gles2::MemoryTracker::Pool pool) {
[email protected]931989f2012-12-24 23:34:4555 tracking_group_->TrackMemoryAllocatedChange(
[email protected]68e81a4a62012-12-13 01:16:4856 old_size, new_size, pool);
[email protected]00b192572012-07-28 04:00:2257 }
58
[email protected]7989c9e2013-01-23 06:39:2659 virtual bool EnsureGPUMemoryAvailable(size_t size_needed) {
60 return tracking_group_->EnsureGPUMemoryAvailable(size_needed);
61 };
62
[email protected]00b192572012-07-28 04:00:2263 private:
[email protected]fb246af2012-08-18 03:11:4164 ~GpuCommandBufferMemoryTracker() {
[email protected]fb246af2012-08-18 03:11:4165 }
[email protected]931989f2012-12-24 23:34:4566 scoped_ptr<GpuMemoryTrackingGroup> tracking_group_;
[email protected]00b192572012-07-28 04:00:2267
68 DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker);
69};
70
[email protected]d1a9e062012-07-13 00:45:1471// FastSetActiveURL will shortcut the expensive call to SetActiveURL when the
72// url_hash matches.
73void FastSetActiveURL(const GURL& url, size_t url_hash) {
74 // Leave the previously set URL in the empty case -- empty URLs are given by
75 // WebKitPlatformSupportImpl::createOffscreenGraphicsContext3D. Hopefully the
76 // onscreen context URL was set previously and will show up even when a crash
77 // occurs during offscreen command processing.
78 if (url.is_empty())
79 return;
80 static size_t g_last_url_hash = 0;
81 if (url_hash != g_last_url_hash) {
82 g_last_url_hash = url_hash;
[email protected]eb398192012-10-22 20:16:1983 GetContentClient()->SetActiveURL(url);
[email protected]d1a9e062012-07-13 00:45:1484 }
85}
86
[email protected]56fc2f22012-07-09 23:50:3687// The first time polling a fence, delay some extra time to allow other
88// stubs to process some work, or else the timing of the fences could
89// allow a pattern of alternating fast and slow frames to occur.
90const int64 kHandleMoreWorkPeriodMs = 2;
91const int64 kHandleMoreWorkPeriodBusyMs = 1;
[email protected]d1a9e062012-07-13 00:45:1492
93} // namespace
[email protected]56fc2f22012-07-09 23:50:3694
[email protected]a3ded6d2010-10-19 06:44:3995GpuCommandBufferStub::GpuCommandBufferStub(
96 GpuChannel* channel,
[email protected]3b1ecc262011-08-03 22:49:5797 GpuCommandBufferStub* share_group,
[email protected]fc4ed092012-02-21 19:46:5598 const gfx::GLSurfaceHandle& handle,
[email protected]78b514b2012-05-01 21:50:5999 gpu::gles2::MailboxManager* mailbox_manager,
[email protected]09d50362012-10-18 20:54:37100 gpu::gles2::ImageManager* image_manager,
[email protected]a3ded6d2010-10-19 06:44:39101 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29102 const gpu::gles2::DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39103 const std::string& allowed_extensions,
104 const std::vector<int32>& attribs,
[email protected]276f89062011-10-13 22:55:50105 gfx::GpuPreference gpu_preference,
[email protected]a3ded6d2010-10-19 06:44:39106 int32 route_id,
[email protected]9f4f3322012-01-18 22:29:56107 int32 surface_id,
[email protected]f81f5952011-07-21 18:52:47108 GpuWatchdog* watchdog,
[email protected]d1a9e062012-07-13 00:45:14109 bool software,
[email protected]7f1a51c322012-07-19 18:52:02110 const GURL& active_url)
[email protected]246a70452010-03-05 21:53:50111 : channel_(channel),
[email protected]6ebf2fc2010-07-01 01:06:32112 handle_(handle),
[email protected]6217d392010-03-25 22:08:35113 initial_size_(size),
[email protected]e82fb792011-09-22 00:33:29114 disallowed_features_(disallowed_features),
[email protected]bc518752010-10-20 21:38:27115 allowed_extensions_(allowed_extensions),
[email protected]34ff8b0c2010-10-01 20:06:02116 requested_attribs_(attribs),
[email protected]276f89062011-10-13 22:55:50117 gpu_preference_(gpu_preference),
[email protected]77e74db2010-08-04 17:46:23118 route_id_(route_id),
[email protected]5178c4422012-10-17 12:08:07119 surface_id_(surface_id),
[email protected]f81f5952011-07-21 18:52:47120 software_(software),
[email protected]a38477142011-05-28 02:45:58121 last_flush_count_(0),
[email protected]e6e1fc22013-01-25 01:38:06122 last_memory_allocation_valid_(false),
[email protected]e7da6aef2011-06-22 19:29:03123 parent_stub_for_initialization_(),
124 parent_texture_for_initialization_(0),
[email protected]35a0b4b2012-06-15 03:53:30125 watchdog_(watchdog),
[email protected]56fc2f22012-07-09 23:50:36126 sync_point_wait_count_(0),
[email protected]d1a9e062012-07-13 00:45:14127 delayed_work_scheduled_(false),
[email protected]ee1e6aa2012-11-29 09:24:10128 active_url_(active_url),
129 total_gpu_memory_(0) {
[email protected]51ddf722012-09-01 00:55:09130 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec());
[email protected]d1a9e062012-07-13 00:45:14131 FastSetActiveURL(active_url_, active_url_hash_);
[email protected]bf5a8d132011-08-16 08:39:35132 if (share_group) {
[email protected]3b1ecc262011-08-03 22:49:57133 context_group_ = share_group->context_group_;
[email protected]bf5a8d132011-08-16 08:39:35134 } else {
[email protected]00b192572012-07-28 04:00:22135 context_group_ = new gpu::gles2::ContextGroup(
[email protected]fb246af2012-08-18 03:11:41136 mailbox_manager,
[email protected]09d50362012-10-18 20:54:37137 image_manager,
[email protected]fb246af2012-08-18 03:11:41138 new GpuCommandBufferMemoryTracker(channel),
139 true);
[email protected]bf5a8d132011-08-16 08:39:35140 }
[email protected]246a70452010-03-05 21:53:50141}
142
143GpuCommandBufferStub::~GpuCommandBufferStub() {
[email protected]79311e82011-09-20 00:40:50144 Destroy();
[email protected]d8a58e42011-01-27 15:24:25145
[email protected]f24a1e2b2011-04-08 01:48:48146 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
[email protected]672c7312012-02-03 16:28:55147 gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer(surface_id()));
[email protected]246a70452010-03-05 21:53:50148}
149
[email protected]c805f8d92012-11-06 12:45:52150GpuMemoryManager* GpuCommandBufferStub::GetMemoryManager() {
151 return channel()->gpu_channel_manager()->gpu_memory_manager();
152}
153
[email protected]a95986a82010-12-24 06:19:28154bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
[email protected]d1a9e062012-07-13 00:45:14155 FastSetActiveURL(active_url_, active_url_hash_);
156
[email protected]79311e82011-09-20 00:40:50157 // Ensure the appropriate GL context is current before handling any IPC
158 // messages directed at the command buffer. This ensures that the message
[email protected]6802e3c62012-06-06 22:32:44159 // handler can assume that the context is current (not necessary for
[email protected]68c70282012-06-25 23:31:17160 // Echo, RetireSyncPoint, or WaitSyncPoint).
[email protected]6802e3c62012-06-06 22:32:44161 if (decoder_.get() &&
[email protected]68c70282012-06-25 23:31:17162 message.type() != GpuCommandBufferMsg_Echo::ID &&
163 message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID &&
164 message.type() != GpuCommandBufferMsg_WaitSyncPoint::ID) {
[email protected]062e5e82012-06-20 19:30:35165 if (!MakeCurrent())
[email protected]79311e82011-09-20 00:40:50166 return false;
[email protected]79311e82011-09-20 00:40:50167 }
168
[email protected]310bed512011-05-09 21:12:25169 // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
170 // here. This is so the reply can be delayed if the scheduler is unscheduled.
[email protected]a95986a82010-12-24 06:19:28171 bool handled = true;
[email protected]246a70452010-03-05 21:53:50172 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
[email protected]310bed512011-05-09 21:12:25173 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize,
174 OnInitialize);
[email protected]392fbb3d2012-12-14 00:34:07175 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer,
176 OnSetGetBuffer);
[email protected]3c644d82011-06-20 19:58:24177 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetParent,
178 OnSetParent);
[email protected]1ef068c2012-03-02 16:30:47179 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Echo, OnEcho);
[email protected]310bed512011-05-09 21:12:25180 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState);
[email protected]451e9662011-10-10 21:14:34181 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetStateFast,
182 OnGetStateFast);
[email protected]246a70452010-03-05 21:53:50183 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
[email protected]d0f02c42011-07-21 21:40:48184 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Rescheduled, OnRescheduled);
[email protected]67c80782012-12-21 01:16:52185 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer,
186 OnRegisterTransferBuffer);
187 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer,
188 OnDestroyTransferBuffer);
[email protected]310bed512011-05-09 21:12:25189 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetTransferBuffer,
190 OnGetTransferBuffer);
[email protected]c8423062011-07-29 19:25:38191 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder,
192 OnCreateVideoDecoder)
[email protected]a13da242011-07-07 19:48:17193 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyVideoDecoder,
194 OnDestroyVideoDecoder)
[email protected]8cc980c52011-10-14 20:35:51195 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetSurfaceVisible,
196 OnSetSurfaceVisible)
[email protected]251622e2012-03-23 16:17:40197 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DiscardBackbuffer,
198 OnDiscardBackbuffer)
199 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_EnsureBackbuffer,
200 OnEnsureBackbuffer)
[email protected]c02f93e42012-06-05 23:35:16201 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RetireSyncPoint,
202 OnRetireSyncPoint)
203 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_WaitSyncPoint,
204 OnWaitSyncPoint)
[email protected]5ab44ef2012-06-19 00:03:51205 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncPoint,
206 OnSignalSyncPoint)
[email protected]ba148052012-10-30 03:24:05207 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SendClientManagedMemoryStats,
208 OnReceivedClientManagedMemoryStats)
[email protected]c1f12142012-05-01 22:21:06209 IPC_MESSAGE_HANDLER(
210 GpuCommandBufferMsg_SetClientHasMemoryAllocationChangedCallback,
211 OnSetClientHasMemoryAllocationChangedCallback)
[email protected]a95986a82010-12-24 06:19:28212 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]246a70452010-03-05 21:53:50213 IPC_END_MESSAGE_MAP()
[email protected]a13da242011-07-07 19:48:17214
[email protected]56fc2f22012-07-09 23:50:36215 // Ensure that any delayed work that was created will be handled.
216 ScheduleDelayedWork(kHandleMoreWorkPeriodMs);
217
[email protected]a95986a82010-12-24 06:19:28218 DCHECK(handled);
219 return handled;
[email protected]246a70452010-03-05 21:53:50220}
221
222bool GpuCommandBufferStub::Send(IPC::Message* message) {
223 return channel_->Send(message);
224}
225
[email protected]d0f02c42011-07-21 21:40:48226bool GpuCommandBufferStub::IsScheduled() {
[email protected]35a0b4b2012-06-15 03:53:30227 return sync_point_wait_count_ == 0 &&
228 (!scheduler_.get() || scheduler_->IsScheduled());
[email protected]d0f02c42011-07-21 21:40:48229}
230
[email protected]20f656f2011-12-08 02:25:15231bool GpuCommandBufferStub::HasMoreWork() {
232 return scheduler_.get() && scheduler_->HasMoreWork();
233}
234
[email protected]f5f910d52012-03-06 22:33:09235void GpuCommandBufferStub::PollWork() {
[email protected]56fc2f22012-07-09 23:50:36236 TRACE_EVENT0("gpu", "GpuCommandBufferStub::PollWork");
237 delayed_work_scheduled_ = false;
[email protected]a5b2abb912012-07-13 04:45:04238 FastSetActiveURL(active_url_, active_url_hash_);
[email protected]062e5e82012-06-20 19:30:35239 if (decoder_.get() && !MakeCurrent())
240 return;
[email protected]f5f910d52012-03-06 22:33:09241 if (scheduler_.get())
242 scheduler_->PollUnscheduleFences();
[email protected]56fc2f22012-07-09 23:50:36243 ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs);
[email protected]f5f910d52012-03-06 22:33:09244}
245
[email protected]df621aff2012-03-02 23:04:58246bool GpuCommandBufferStub::HasUnprocessedCommands() {
247 if (command_buffer_.get()) {
248 gpu::CommandBuffer::State state = command_buffer_->GetLastState();
[email protected]6dadf652012-03-22 02:49:24249 return state.put_offset != state.get_offset &&
250 !gpu::error::IsError(state.error);
[email protected]df621aff2012-03-02 23:04:58251 }
252 return false;
253}
254
[email protected]56fc2f22012-07-09 23:50:36255void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) {
256 if (HasMoreWork() && !delayed_work_scheduled_) {
257 delayed_work_scheduled_ = true;
258 MessageLoop::current()->PostDelayedTask(
259 FROM_HERE,
260 base::Bind(&GpuCommandBufferStub::PollWork,
261 AsWeakPtr()),
262 base::TimeDelta::FromMilliseconds(delay));
263 }
264}
265
[email protected]1ef068c2012-03-02 16:30:47266void GpuCommandBufferStub::OnEcho(const IPC::Message& message) {
267 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEcho");
268 Send(new IPC::Message(message));
269}
270
[email protected]ac9ab812012-03-06 22:44:05271void GpuCommandBufferStub::DelayEcho(IPC::Message* message) {
272 delayed_echos_.push_back(message);
273}
274
275void GpuCommandBufferStub::OnReschedule() {
[email protected]35a0b4b2012-06-15 03:53:30276 if (!IsScheduled())
277 return;
[email protected]ac9ab812012-03-06 22:44:05278 while (!delayed_echos_.empty()) {
279 scoped_ptr<IPC::Message> message(delayed_echos_.front());
280 delayed_echos_.pop_front();
281
282 OnMessageReceived(*message);
283 }
284
285 channel_->OnScheduled();
286}
287
[email protected]062e5e82012-06-20 19:30:35288bool GpuCommandBufferStub::MakeCurrent() {
289 if (decoder_->MakeCurrent())
290 return true;
291 DLOG(ERROR) << "Context lost because MakeCurrent failed.";
292 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
293 command_buffer_->SetParseError(gpu::error::kLostContext);
294 if (gfx::GLContext::LosesAllContextsOnContextLost())
295 channel_->LoseAllContexts();
296 return false;
297}
298
[email protected]79311e82011-09-20 00:40:50299void GpuCommandBufferStub::Destroy() {
[email protected]54947032012-12-08 01:44:01300 if (handle_.is_null() && !active_url_.is_empty()) {
301 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
302 gpu_channel_manager->Send(new GpuHostMsg_DidDestroyOffscreenContext(
303 active_url_));
304 }
305
[email protected]931989f2012-12-24 23:34:45306 memory_manager_client_state_.reset();
[email protected]c805f8d92012-11-06 12:45:52307
[email protected]c02f93e42012-06-05 23:35:16308 while (!sync_points_.empty())
309 OnRetireSyncPoint(sync_points_.front());
310
[email protected]79311e82011-09-20 00:40:50311 // The scheduler has raw references to the decoder and the command buffer so
312 // destroy it before those.
[email protected]4ee0c3052011-09-16 19:30:36313 scheduler_.reset();
[email protected]79311e82011-09-20 00:40:50314
[email protected]ac9ab812012-03-06 22:44:05315 while (!delayed_echos_.empty()) {
316 delete delayed_echos_.front();
317 delayed_echos_.pop_front();
318 }
319
[email protected]706b69f2012-07-27 04:59:30320 bool have_context = false;
[email protected]0f9386892012-02-15 01:44:07321 if (decoder_.get())
[email protected]706b69f2012-07-27 04:59:30322 have_context = decoder_->MakeCurrent();
[email protected]0f9386892012-02-15 01:44:07323 FOR_EACH_OBSERVER(DestructionObserver,
324 destruction_observers_,
325 OnWillDestroyStub(this));
326
[email protected]ee1e6aa2012-11-29 09:24:10327 scoped_refptr<gfx::GLContext> context;
[email protected]79311e82011-09-20 00:40:50328 if (decoder_.get()) {
[email protected]ee1e6aa2012-11-29 09:24:10329 context = decoder_->GetGLContext();
[email protected]706b69f2012-07-27 04:59:30330 decoder_->Destroy(have_context);
[email protected]79311e82011-09-20 00:40:50331 decoder_.reset();
332 }
333
[email protected]4ee0c3052011-09-16 19:30:36334 command_buffer_.reset();
[email protected]79311e82011-09-20 00:40:50335
[email protected]8a08d9e42012-11-16 07:36:04336 // Make sure that context_ is current while we destroy surface_, because
337 // surface_ may have GL resources that it needs to destroy, and will need
338 // context_ to be current in order to not leak these resources.
[email protected]ee1e6aa2012-11-29 09:24:10339 if (context)
340 context->MakeCurrent(surface_.get());
[email protected]79311e82011-09-20 00:40:50341 surface_ = NULL;
[email protected]5eb008a2012-11-30 01:23:55342 if (context)
343 context->ReleaseCurrent(NULL);
[email protected]79311e82011-09-20 00:40:50344}
345
346void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) {
347 Destroy();
[email protected]2e7bbf22011-07-22 18:41:29348 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, false);
349 Send(reply_message);
350}
351
[email protected]392fbb3d2012-12-14 00:34:07352void GpuCommandBufferStub::OnInitialize(
[email protected]67c80782012-12-21 01:16:52353 base::SharedMemoryHandle shared_state_handle,
[email protected]392fbb3d2012-12-14 00:34:07354 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32355 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnInitialize");
[email protected]246a70452010-03-05 21:53:50356 DCHECK(!command_buffer_.get());
357
[email protected]67c80782012-12-21 01:16:52358 scoped_ptr<base::SharedMemory> shared_state_shm(
359 new base::SharedMemory(shared_state_handle, false));
360
[email protected]1d471e82012-06-01 06:13:40361 command_buffer_.reset(new gpu::CommandBufferService(
362 context_group_->transfer_buffer_manager()));
[email protected]246a70452010-03-05 21:53:50363
[email protected]503b3a22011-12-12 23:29:40364 if (!command_buffer_->Initialize()) {
[email protected]198e0c442011-12-02 19:45:06365 DLOG(ERROR) << "CommandBufferService failed to initialize.\n";
[email protected]79311e82011-09-20 00:40:50366 OnInitializeFailed(reply_message);
367 return;
368 }
369
370 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get()));
371
372 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
373 decoder_.get(),
[email protected]8a9e1a12011-12-20 01:46:05374 decoder_.get()));
[email protected]737ed6502013-01-26 03:58:25375 if (preemption_flag_.get())
376 scheduler_->SetPreemptByFlag(preemption_flag_);
[email protected]79311e82011-09-20 00:40:50377
378 decoder_->set_engine(scheduler_.get());
379
[email protected]47940c82012-02-08 02:23:49380 if (!handle_.is_null()) {
[email protected]839d5172011-10-13 17:18:11381#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]2e7bbf22011-07-22 18:41:29382 if (software_) {
[email protected]198e0c442011-12-02 19:45:06383 DLOG(ERROR) << "No software support.\n";
[email protected]2e7bbf22011-07-22 18:41:29384 OnInitializeFailed(reply_message);
385 return;
386 }
[email protected]290fc492011-11-22 23:25:23387#endif
[email protected]2e7bbf22011-07-22 18:41:29388
[email protected]79311e82011-09-20 00:40:50389 surface_ = ImageTransportSurface::CreateSurface(
390 channel_->gpu_channel_manager(),
[email protected]9f4f3322012-01-18 22:29:56391 this,
[email protected]04d58ce2011-09-29 13:12:23392 handle_);
[email protected]79311e82011-09-20 00:40:50393 } else {
[email protected]b8673e62012-09-25 03:15:00394 GpuChannelManager* manager = channel_->gpu_channel_manager();
395 surface_ = manager->GetDefaultOffscreenSurface();
[email protected]79311e82011-09-20 00:40:50396 }
397
398 if (!surface_.get()) {
[email protected]cdcd5bd2011-10-15 00:19:38399 // Ensure the decoder is not destroyed if it is not initialized.
400 decoder_.reset();
401
[email protected]cc63025a2011-10-29 02:16:24402 DLOG(ERROR) << "Failed to create surface.\n";
[email protected]79311e82011-09-20 00:40:50403 OnInitializeFailed(reply_message);
404 return;
405 }
406
[email protected]ee1e6aa2012-11-29 09:24:10407 scoped_refptr<gfx::GLContext> context;
[email protected]f34ffdf22012-12-15 00:41:27408 if (CommandLine::ForCurrentProcess()->HasSwitch(
409 switches::kEnableVirtualGLContexts) && channel_->share_group()) {
[email protected]ee1e6aa2012-11-29 09:24:10410 context = channel_->share_group()->GetSharedContext();
411 if (!context) {
412 context = gfx::GLContext::CreateGLContext(
413 channel_->share_group(),
414 channel_->gpu_channel_manager()->GetDefaultOffscreenSurface(),
415 gpu_preference_);
416 channel_->share_group()->SetSharedContext(context);
417 }
418 // This should be a non-virtual GL context.
419 DCHECK(context->GetHandle());
420 context = new gpu::GLContextVirtual(channel_->share_group(),
421 context,
422 decoder_->AsWeakPtr());
423 if (!context->Initialize(surface_, gpu_preference_)) {
424 // TODO(sievers): The real context created above for the default
425 // offscreen surface might not be compatible with this surface.
426 // Need to adjust at least GLX to be able to create the initial context
427 // with a config that is compatible with onscreen and offscreen surfaces.
428 context = NULL;
429 LOG(FATAL) << "Failed to initialize virtual GL context.";
430 } else {
431 LOG(INFO) << "Created virtual GL context.";
432 }
433 }
434 if (!context) {
435 context = gfx::GLContext::CreateGLContext(
436 channel_->share_group(),
437 surface_.get(),
438 gpu_preference_);
439 }
440 if (!context) {
[email protected]cdcd5bd2011-10-15 00:19:38441 // Ensure the decoder is not destroyed if it is not initialized.
442 decoder_.reset();
443
[email protected]cc63025a2011-10-29 02:16:24444 DLOG(ERROR) << "Failed to create context.\n";
[email protected]79311e82011-09-20 00:40:50445 OnInitializeFailed(reply_message);
446 return;
447 }
[email protected]4bbe6d0c2011-09-16 18:58:54448
[email protected]ee1e6aa2012-11-29 09:24:10449 if (!context->MakeCurrent(surface_.get())) {
[email protected]35a0b4b2012-06-15 03:53:30450 // Ensure the decoder is not destroyed if it is not initialized.
451 decoder_.reset();
[email protected]63c9b052012-05-17 18:27:38452 LOG(ERROR) << "Failed to make context current.";
453 OnInitializeFailed(reply_message);
454 return;
455 }
456
[email protected]ee1e6aa2012-11-29 09:24:10457 if (!context->GetTotalGpuMemory(&total_gpu_memory_))
458 total_gpu_memory_ = 0;
459
[email protected]65dfc602012-07-23 20:39:39460 if (!context_group_->has_program_cache()) {
461 context_group_->set_program_cache(
462 channel_->gpu_channel_manager()->program_cache());
463 }
464
[email protected]79311e82011-09-20 00:40:50465 // Initialize the decoder with either the view or pbuffer GLContext.
[email protected]63c9b052012-05-17 18:27:38466 if (!decoder_->Initialize(surface_,
[email protected]ee1e6aa2012-11-29 09:24:10467 context,
[email protected]069944672012-04-25 20:52:23468 !surface_id(),
[email protected]79311e82011-09-20 00:40:50469 initial_size_,
[email protected]e82fb792011-09-22 00:33:29470 disallowed_features_,
[email protected]79311e82011-09-20 00:40:50471 allowed_extensions_.c_str(),
472 requested_attribs_)) {
[email protected]cc63025a2011-10-29 02:16:24473 DLOG(ERROR) << "Failed to initialize decoder.";
[email protected]79311e82011-09-20 00:40:50474 OnInitializeFailed(reply_message);
475 return;
476 }
477
478 if (CommandLine::ForCurrentProcess()->HasSwitch(
479 switches::kEnableGPUServiceLogging)) {
[email protected]e844ae22012-01-14 03:36:26480 decoder_->set_log_commands(true);
[email protected]79311e82011-09-20 00:40:50481 }
482
[email protected]6b6e7ee2011-12-13 08:04:52483 decoder_->SetMsgCallback(
484 base::Bind(&GpuCommandBufferStub::SendConsoleMessage,
485 base::Unretained(this)));
486
[email protected]79311e82011-09-20 00:40:50487 command_buffer_->SetPutOffsetChangeCallback(
[email protected]d1a9e062012-07-13 00:45:14488 base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this)));
[email protected]503b3a22011-12-12 23:29:40489 command_buffer_->SetGetBufferChangeCallback(
490 base::Bind(&gpu::GpuScheduler::SetGetBuffer,
491 base::Unretained(scheduler_.get())));
[email protected]79311e82011-09-20 00:40:50492 command_buffer_->SetParseErrorCallback(
[email protected]9d37f062011-11-22 01:24:52493 base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50494 scheduler_->SetScheduledCallback(
[email protected]ac9ab812012-03-06 22:44:05495 base::Bind(&GpuCommandBufferStub::OnReschedule, base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50496
[email protected]79311e82011-09-20 00:40:50497 if (watchdog_) {
498 scheduler_->SetCommandProcessedCallback(
[email protected]9d37f062011-11-22 01:24:52499 base::Bind(&GpuCommandBufferStub::OnCommandProcessed,
500 base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50501 }
502
[email protected]34aaa5682012-09-25 00:48:50503#if defined(OS_ANDROID)
504 decoder_->SetStreamTextureManager(channel_->stream_texture_manager());
505#endif
506
[email protected]79311e82011-09-20 00:40:50507 if (parent_stub_for_initialization_) {
508 decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(),
509 parent_texture_for_initialization_);
510 parent_stub_for_initialization_.reset();
511 parent_texture_for_initialization_ = 0;
512 }
[email protected]310bed512011-05-09 21:12:25513
[email protected]67c80782012-12-21 01:16:52514 if (!command_buffer_->SetSharedStateBuffer(shared_state_shm.Pass())) {
515 DLOG(ERROR) << "Failed to map shared stae buffer.";
516 OnInitializeFailed(reply_message);
517 return;
518 }
519
[email protected]2e7bbf22011-07-22 18:41:29520 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, true);
[email protected]310bed512011-05-09 21:12:25521 Send(reply_message);
[email protected]54947032012-12-08 01:44:01522
523 if (handle_.is_null() && !active_url_.is_empty()) {
524 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
525 gpu_channel_manager->Send(new GpuHostMsg_DidCreateOffscreenContext(
526 active_url_));
527 }
[email protected]246a70452010-03-05 21:53:50528}
529
[email protected]67c80782012-12-21 01:16:52530void GpuCommandBufferStub::OnSetGetBuffer(int32 shm_id,
531 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32532 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer");
[email protected]67c80782012-12-21 01:16:52533 if (command_buffer_.get())
[email protected]773bf5e2012-01-06 01:07:13534 command_buffer_->SetGetBuffer(shm_id);
[email protected]68eff952012-02-17 21:56:35535 Send(reply_message);
536}
537
[email protected]3c644d82011-06-20 19:58:24538void GpuCommandBufferStub::OnSetParent(int32 parent_route_id,
539 uint32 parent_texture_id,
540 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32541 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetParent");
[email protected]e7da6aef2011-06-22 19:29:03542 GpuCommandBufferStub* parent_stub = NULL;
543 if (parent_route_id != MSG_ROUTING_NONE) {
544 parent_stub = channel_->LookupCommandBuffer(parent_route_id);
[email protected]3c644d82011-06-20 19:58:24545 }
546
[email protected]e7da6aef2011-06-22 19:29:03547 bool result = true;
548 if (scheduler_.get()) {
[email protected]79311e82011-09-20 00:40:50549 gpu::gles2::GLES2Decoder* parent_decoder =
550 parent_stub ? parent_stub->decoder_.get() : NULL;
551 result = decoder_->SetParent(parent_decoder, parent_texture_id);
[email protected]e7da6aef2011-06-22 19:29:03552 } else {
553 // If we don't have a scheduler, it means that Initialize hasn't been called
554 // yet. Keep around the requested parent stub and texture so that we can set
555 // it in Initialize().
556 parent_stub_for_initialization_ = parent_stub ?
557 parent_stub->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>();
558 parent_texture_for_initialization_ = parent_texture_id;
559 }
[email protected]3c644d82011-06-20 19:58:24560 GpuCommandBufferMsg_SetParent::WriteReplyParams(reply_message, result);
561 Send(reply_message);
562}
563
[email protected]310bed512011-05-09 21:12:25564void GpuCommandBufferStub::OnGetState(IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32565 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetState");
[email protected]773bf5e2012-01-06 01:07:13566 if (command_buffer_.get()) {
567 gpu::CommandBuffer::State state = command_buffer_->GetState();
568 if (state.error == gpu::error::kLostContext &&
569 gfx::GLContext::LosesAllContextsOnContextLost())
570 channel_->LoseAllContexts();
[email protected]310bed512011-05-09 21:12:25571
[email protected]773bf5e2012-01-06 01:07:13572 GpuCommandBufferMsg_GetState::WriteReplyParams(reply_message, state);
573 } else {
574 DLOG(ERROR) << "no command_buffer.";
575 reply_message->set_reply_error();
576 }
[email protected]310bed512011-05-09 21:12:25577 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50578}
579
[email protected]0a68ac872011-06-07 04:48:27580void GpuCommandBufferStub::OnParseError() {
581 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnParseError");
[email protected]773bf5e2012-01-06 01:07:13582 DCHECK(command_buffer_.get());
[email protected]38d139d2011-07-14 00:38:43583 gpu::CommandBuffer::State state = command_buffer_->GetState();
584 IPC::Message* msg = new GpuCommandBufferMsg_Destroyed(
585 route_id_, state.context_lost_reason);
[email protected]0a68ac872011-06-07 04:48:27586 msg->set_unblock(true);
587 Send(msg);
[email protected]54947032012-12-08 01:44:01588
589 // Tell the browser about this context loss as well, so it can
590 // determine whether client APIs like WebGL need to be immediately
591 // blocked from automatically running.
592 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
593 gpu_channel_manager->Send(new GpuHostMsg_DidLoseContext(
594 handle_.is_null(), state.context_lost_reason, active_url_));
[email protected]0a68ac872011-06-07 04:48:27595}
596
[email protected]451e9662011-10-10 21:14:34597void GpuCommandBufferStub::OnGetStateFast(IPC::Message* reply_message) {
598 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetStateFast");
[email protected]773bf5e2012-01-06 01:07:13599 DCHECK(command_buffer_.get());
[email protected]d0f02c42011-07-21 21:40:48600 gpu::CommandBuffer::State state = command_buffer_->GetState();
[email protected]451e9662011-10-10 21:14:34601 if (state.error == gpu::error::kLostContext &&
602 gfx::GLContext::LosesAllContextsOnContextLost())
603 channel_->LoseAllContexts();
[email protected]1d4ea842011-07-20 01:11:51604
[email protected]451e9662011-10-10 21:14:34605 GpuCommandBufferMsg_GetStateFast::WriteReplyParams(reply_message, state);
606 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50607}
608
[email protected]451e9662011-10-10 21:14:34609void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset,
610 uint32 flush_count) {
611 TRACE_EVENT1("gpu", "GpuCommandBufferStub::OnAsyncFlush",
612 "put_offset", put_offset);
[email protected]773bf5e2012-01-06 01:07:13613 DCHECK(command_buffer_.get());
[email protected]fde205d2011-05-31 22:29:50614 if (flush_count - last_flush_count_ < 0x8000000U) {
[email protected]a38477142011-05-28 02:45:58615 last_flush_count_ = flush_count;
616 command_buffer_->Flush(put_offset);
617 } else {
[email protected]fde205d2011-05-31 22:29:50618 // We received this message out-of-order. This should not happen but is here
619 // to catch regressions. Ignore the message.
620 NOTREACHED() << "Received a Flush message out-of-order";
[email protected]a38477142011-05-28 02:45:58621 }
[email protected]d0f02c42011-07-21 21:40:48622
623 ReportState();
624}
625
626void GpuCommandBufferStub::OnRescheduled() {
[email protected]20f656f2011-12-08 02:25:15627 gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState();
628 command_buffer_->Flush(pre_state.put_offset);
629 gpu::CommandBuffer::State post_state = command_buffer_->GetLastState();
[email protected]d0f02c42011-07-21 21:40:48630
[email protected]20f656f2011-12-08 02:25:15631 if (pre_state.get_offset != post_state.get_offset)
632 ReportState();
[email protected]246a70452010-03-05 21:53:50633}
634
[email protected]0100b7a2011-02-24 22:54:50635void GpuCommandBufferStub::OnRegisterTransferBuffer(
[email protected]67c80782012-12-21 01:16:52636 int32 id,
[email protected]0100b7a2011-02-24 22:54:50637 base::SharedMemoryHandle transfer_buffer,
[email protected]67c80782012-12-21 01:16:52638 uint32 size) {
[email protected]3551cb202012-05-24 10:55:32639 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterTransferBuffer");
[email protected]0100b7a2011-02-24 22:54:50640 base::SharedMemory shared_memory(transfer_buffer, false);
[email protected]7df1d1a2011-02-26 02:07:57641
[email protected]67c80782012-12-21 01:16:52642 if (command_buffer_.get())
643 command_buffer_->RegisterTransferBuffer(id, &shared_memory, size);
[email protected]0100b7a2011-02-24 22:54:50644}
645
[email protected]67c80782012-12-21 01:16:52646void GpuCommandBufferStub::OnDestroyTransferBuffer(int32 id) {
[email protected]3551cb202012-05-24 10:55:32647 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyTransferBuffer");
[email protected]67c80782012-12-21 01:16:52648
649 if (command_buffer_.get())
[email protected]773bf5e2012-01-06 01:07:13650 command_buffer_->DestroyTransferBuffer(id);
[email protected]246a70452010-03-05 21:53:50651}
652
653void GpuCommandBufferStub::OnGetTransferBuffer(
654 int32 id,
[email protected]310bed512011-05-09 21:12:25655 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32656 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetTransferBuffer");
[email protected]773bf5e2012-01-06 01:07:13657 if (command_buffer_.get()) {
658 base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle();
659 uint32 size = 0;
[email protected]310bed512011-05-09 21:12:25660
[email protected]773bf5e2012-01-06 01:07:13661 gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id);
662 if (buffer.shared_memory) {
[email protected]cd0bd792012-04-14 00:52:16663#if defined(OS_WIN)
664 transfer_buffer = NULL;
[email protected]eb398192012-10-22 20:16:19665 BrokerDuplicateHandle(buffer.shared_memory->handle(),
[email protected]cd0bd792012-04-14 00:52:16666 channel_->renderer_pid(), &transfer_buffer, FILE_MAP_READ |
667 FILE_MAP_WRITE, 0);
[email protected]8f9904d2012-05-09 00:20:22668 DCHECK(transfer_buffer != NULL);
[email protected]cd0bd792012-04-14 00:52:16669#else
670 buffer.shared_memory->ShareToProcess(channel_->renderer_pid(),
[email protected]773bf5e2012-01-06 01:07:13671 &transfer_buffer);
[email protected]cd0bd792012-04-14 00:52:16672#endif
[email protected]773bf5e2012-01-06 01:07:13673 size = buffer.size;
674 }
675
676 GpuCommandBufferMsg_GetTransferBuffer::WriteReplyParams(reply_message,
677 transfer_buffer,
678 size);
679 } else {
680 reply_message->set_reply_error();
681 }
[email protected]310bed512011-05-09 21:12:25682 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50683}
684
[email protected]310bed512011-05-09 21:12:25685void GpuCommandBufferStub::OnCommandProcessed() {
686 if (watchdog_)
687 watchdog_->CheckArmed();
688}
689
[email protected]ef16c172011-04-28 23:37:14690void GpuCommandBufferStub::ReportState() {
691 gpu::CommandBuffer::State state = command_buffer_->GetState();
692 if (state.error == gpu::error::kLostContext &&
693 gfx::GLContext::LosesAllContextsOnContextLost()) {
694 channel_->LoseAllContexts();
695 } else {
[email protected]68eff952012-02-17 21:56:35696 command_buffer_->UpdateState();
[email protected]ef16c172011-04-28 23:37:14697 }
698}
699
[email protected]d1a9e062012-07-13 00:45:14700void GpuCommandBufferStub::PutChanged() {
701 FastSetActiveURL(active_url_, active_url_hash_);
702 scheduler_->PutChanged();
703}
704
[email protected]a13da242011-07-07 19:48:17705void GpuCommandBufferStub::OnCreateVideoDecoder(
[email protected]e5ca6362012-03-30 09:45:58706 media::VideoCodecProfile profile,
[email protected]c8423062011-07-29 19:25:38707 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32708 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoDecoder");
[email protected]502e6052011-08-17 00:17:23709 int decoder_route_id = channel_->GenerateRouteID();
[email protected]502e6052011-08-17 00:17:23710 GpuVideoDecodeAccelerator* decoder =
711 new GpuVideoDecodeAccelerator(this, decoder_route_id, this);
712 video_decoders_.AddWithID(decoder, decoder_route_id);
713 channel_->AddRoute(decoder_route_id, decoder);
[email protected]cd0bd792012-04-14 00:52:16714 decoder->Initialize(profile, reply_message);
[email protected]a13da242011-07-07 19:48:17715}
716
[email protected]502e6052011-08-17 00:17:23717void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) {
[email protected]3551cb202012-05-24 10:55:32718 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyVideoDecoder");
[email protected]502e6052011-08-17 00:17:23719 channel_->RemoveRoute(decoder_route_id);
720 video_decoders_.Remove(decoder_route_id);
[email protected]a13da242011-07-07 19:48:17721}
722
[email protected]8cc980c52011-10-14 20:35:51723void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) {
[email protected]3551cb202012-05-24 10:55:32724 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSurfaceVisible");
[email protected]931989f2012-12-24 23:34:45725 if (memory_manager_client_state_.get())
726 memory_manager_client_state_->SetVisible(visible);
[email protected]8cc980c52011-10-14 20:35:51727}
728
[email protected]251622e2012-03-23 16:17:40729void GpuCommandBufferStub::OnDiscardBackbuffer() {
[email protected]3551cb202012-05-24 10:55:32730 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDiscardBackbuffer");
[email protected]251622e2012-03-23 16:17:40731 if (!surface_)
732 return;
[email protected]50776f72012-11-30 02:36:05733 if (surface_->DeferDraws()) {
734 DCHECK(!IsScheduled());
735 channel_->RequeueMessage();
736 } else {
737 surface_->SetBackbufferAllocation(false);
738 }
[email protected]251622e2012-03-23 16:17:40739}
740
741void GpuCommandBufferStub::OnEnsureBackbuffer() {
[email protected]3551cb202012-05-24 10:55:32742 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEnsureBackbuffer");
[email protected]251622e2012-03-23 16:17:40743 if (!surface_)
744 return;
[email protected]50776f72012-11-30 02:36:05745 if (surface_->DeferDraws()) {
746 DCHECK(!IsScheduled());
747 channel_->RequeueMessage();
748 } else {
749 surface_->SetBackbufferAllocation(true);
750 }
[email protected]251622e2012-03-23 16:17:40751}
752
[email protected]c02f93e42012-06-05 23:35:16753void GpuCommandBufferStub::AddSyncPoint(uint32 sync_point) {
754 sync_points_.push_back(sync_point);
755}
756
757void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) {
758 DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point);
759 sync_points_.pop_front();
760 GpuChannelManager* manager = channel_->gpu_channel_manager();
761 manager->sync_point_manager()->RetireSyncPoint(sync_point);
762}
763
764void GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) {
[email protected]35a0b4b2012-06-15 03:53:30765 if (sync_point_wait_count_ == 0) {
766 TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this,
767 "GpuCommandBufferStub", this);
768 }
769 ++sync_point_wait_count_;
[email protected]c02f93e42012-06-05 23:35:16770 GpuChannelManager* manager = channel_->gpu_channel_manager();
771 manager->sync_point_manager()->AddSyncPointCallback(
772 sync_point,
773 base::Bind(&GpuCommandBufferStub::OnSyncPointRetired,
774 this->AsWeakPtr()));
775}
776
777void GpuCommandBufferStub::OnSyncPointRetired() {
[email protected]35a0b4b2012-06-15 03:53:30778 --sync_point_wait_count_;
779 if (sync_point_wait_count_ == 0) {
780 TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this,
781 "GpuCommandBufferStub", this);
782 }
783 OnReschedule();
[email protected]c02f93e42012-06-05 23:35:16784}
785
[email protected]5ab44ef2012-06-19 00:03:51786void GpuCommandBufferStub::OnSignalSyncPoint(uint32 sync_point, uint32 id) {
787 GpuChannelManager* manager = channel_->gpu_channel_manager();
788 manager->sync_point_manager()->AddSyncPointCallback(
789 sync_point,
790 base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck,
791 this->AsWeakPtr(),
792 id));
793}
794
795void GpuCommandBufferStub::OnSignalSyncPointAck(uint32 id) {
796 Send(new GpuCommandBufferMsg_SignalSyncPointAck(route_id_, id));
797}
798
[email protected]ba148052012-10-30 03:24:05799void GpuCommandBufferStub::OnReceivedClientManagedMemoryStats(
800 const GpuManagedMemoryStats& stats) {
801 TRACE_EVENT0(
802 "gpu",
803 "GpuCommandBufferStub::OnReceivedClientManagedMemoryStats");
[email protected]931989f2012-12-24 23:34:45804 if (memory_manager_client_state_.get())
805 memory_manager_client_state_->SetManagedMemoryStats(stats);
[email protected]ba148052012-10-30 03:24:05806}
807
[email protected]c1f12142012-05-01 22:21:06808void GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback(
809 bool has_callback) {
[email protected]3551cb202012-05-24 10:55:32810 TRACE_EVENT0(
811 "gpu",
812 "GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback");
[email protected]931989f2012-12-24 23:34:45813 if (has_callback) {
814 if (!memory_manager_client_state_.get()) {
815 memory_manager_client_state_.reset(GetMemoryManager()->CreateClientState(
816 this, surface_id_ != 0, true));
817 }
818 } else {
819 memory_manager_client_state_.reset();
820 }
[email protected]c1f12142012-05-01 22:21:06821}
822
[email protected]6b6e7ee2011-12-13 08:04:52823void GpuCommandBufferStub::SendConsoleMessage(
824 int32 id,
825 const std::string& message) {
826 GPUCommandBufferConsoleMessage console_message;
827 console_message.id = id;
828 console_message.message = message;
829 IPC::Message* msg = new GpuCommandBufferMsg_ConsoleMsg(
830 route_id_, console_message);
831 msg->set_unblock(true);
832 Send(msg);
833}
834
[email protected]0f9386892012-02-15 01:44:07835void GpuCommandBufferStub::AddDestructionObserver(
836 DestructionObserver* observer) {
837 destruction_observers_.AddObserver(observer);
838}
839
840void GpuCommandBufferStub::RemoveDestructionObserver(
841 DestructionObserver* observer) {
842 destruction_observers_.RemoveObserver(observer);
843}
844
[email protected]737ed6502013-01-26 03:58:25845void GpuCommandBufferStub::SetPreemptByFlag(
846 scoped_refptr<gpu::PreemptionFlag> flag) {
847 preemption_flag_ = flag;
[email protected]6802e3c62012-06-06 22:32:44848 if (scheduler_.get())
[email protected]737ed6502013-01-26 03:58:25849 scheduler_->SetPreemptByFlag(preemption_flag_);
[email protected]6802e3c62012-06-06 22:32:44850}
851
[email protected]4b8a6b092012-10-05 01:20:06852bool GpuCommandBufferStub::GetTotalGpuMemory(size_t* bytes) {
[email protected]ee1e6aa2012-11-29 09:24:10853 *bytes = total_gpu_memory_;
854 return !!total_gpu_memory_;
[email protected]4b8a6b092012-10-05 01:20:06855}
856
[email protected]1d56e9642012-05-04 15:40:13857gfx::Size GpuCommandBufferStub::GetSurfaceSize() const {
858 if (!surface_)
859 return gfx::Size();
860 return surface_->GetSize();
861}
862
[email protected]9db65ff2012-11-02 04:22:04863gpu::gles2::MemoryTracker* GpuCommandBufferStub::GetMemoryTracker() const {
864 return context_group_->memory_tracker();
[email protected]c53709012012-02-21 03:22:22865}
866
[email protected]74b407d2012-02-11 01:13:55867void GpuCommandBufferStub::SetMemoryAllocation(
868 const GpuMemoryAllocation& allocation) {
[email protected]e6e1fc22013-01-25 01:38:06869 if (!last_memory_allocation_valid_ ||
870 !allocation.renderer_allocation.Equals(
871 last_memory_allocation_.renderer_allocation)) {
872 Send(new GpuCommandBufferMsg_SetMemoryAllocation(
873 route_id_, allocation.renderer_allocation));
874 }
875
876 if (!last_memory_allocation_valid_ ||
877 !allocation.browser_allocation.Equals(
878 last_memory_allocation_.browser_allocation)) {
879 // This can be called outside of OnMessageReceived, so the context needs
880 // to be made current before calling methods on the surface.
881 if (surface_ && MakeCurrent())
882 surface_->SetFrontbufferAllocation(
883 allocation.browser_allocation.suggest_have_frontbuffer);
884 }
885
886 last_memory_allocation_valid_ = true;
887 last_memory_allocation_ = allocation;
[email protected]74b407d2012-02-11 01:13:55888}
889
[email protected]eb398192012-10-22 20:16:19890} // namespace content