blob: 9030ffe5e7cad684434e3cf1c7ae53e0601b438c [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]9cc992b2013-07-17 06:30:3610#include "base/memory/shared_memory.h"
[email protected]abb522162013-06-28 01:54:1611#include "base/time/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]290fc492011-11-22 23:25:2324#include "gpu/command_buffer/common/constants.h"
[email protected]d670e702012-03-30 10:38:2125#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]2ad674132013-06-05 07:48:5126#include "gpu/command_buffer/common/mailbox.h"
[email protected]ee1e6aa2012-11-29 09:24:1027#include "gpu/command_buffer/service/gl_context_virtual.h"
[email protected]217004512013-05-10 21:25:5528#include "gpu/command_buffer/service/gl_state_restorer_impl.h"
[email protected]bc10f462013-10-22 23:13:0929#include "gpu/command_buffer/service/gpu_control_service.h"
30#include "gpu/command_buffer/service/image_manager.h"
[email protected]1d82e822013-04-10 21:32:3231#include "gpu/command_buffer/service/logger.h"
[email protected]00b192572012-07-28 04:00:2232#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]20dab962013-06-25 03:22:4433#include "gpu/command_buffer/service/query_manager.h"
[email protected]c9e2cbbb2012-05-12 21:17:2734#include "ui/gl/gl_bindings.h"
35#include "ui/gl/gl_switches.h"
[email protected]bc4a3432011-11-21 23:55:5636
[email protected]cd0bd792012-04-14 00:52:1637#if defined(OS_WIN)
[email protected]d30ce6e2012-04-16 15:32:3638#include "content/public/common/sandbox_init.h"
[email protected]cd0bd792012-04-14 00:52:1639#endif
40
[email protected]34aaa5682012-09-25 00:48:5041#if defined(OS_ANDROID)
42#include "content/common/gpu/stream_texture_manager_android.h"
43#endif
44
[email protected]eb398192012-10-22 20:16:1945namespace content {
[email protected]56fc2f22012-07-09 23:50:3646namespace {
[email protected]d1a9e062012-07-13 00:45:1447
[email protected]00b192572012-07-28 04:00:2248// The GpuCommandBufferMemoryTracker class provides a bridge between the
49// ContextGroup's memory type managers and the GpuMemoryManager class.
50class GpuCommandBufferMemoryTracker : public gpu::gles2::MemoryTracker {
51 public:
[email protected]f2a7011c2013-01-26 17:17:2652 explicit GpuCommandBufferMemoryTracker(GpuChannel* channel) :
[email protected]931989f2012-12-24 23:34:4553 tracking_group_(channel->gpu_channel_manager()->gpu_memory_manager()->
54 CreateTrackingGroup(channel->renderer_pid(), this)) {
[email protected]fb246af2012-08-18 03:11:4155 }
56
[email protected]c3e35892013-02-12 02:08:0157 virtual void TrackMemoryAllocatedChange(
58 size_t old_size,
59 size_t new_size,
60 gpu::gles2::MemoryTracker::Pool pool) OVERRIDE {
[email protected]931989f2012-12-24 23:34:4561 tracking_group_->TrackMemoryAllocatedChange(
[email protected]68e81a4a62012-12-13 01:16:4862 old_size, new_size, pool);
[email protected]00b192572012-07-28 04:00:2263 }
64
[email protected]c3e35892013-02-12 02:08:0165 virtual bool EnsureGPUMemoryAvailable(size_t size_needed) OVERRIDE {
[email protected]7989c9e2013-01-23 06:39:2666 return tracking_group_->EnsureGPUMemoryAvailable(size_needed);
67 };
68
[email protected]00b192572012-07-28 04:00:2269 private:
[email protected]c3e35892013-02-12 02:08:0170 virtual ~GpuCommandBufferMemoryTracker() {
[email protected]fb246af2012-08-18 03:11:4171 }
[email protected]931989f2012-12-24 23:34:4572 scoped_ptr<GpuMemoryTrackingGroup> tracking_group_;
[email protected]00b192572012-07-28 04:00:2273
74 DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker);
75};
76
[email protected]d1a9e062012-07-13 00:45:1477// FastSetActiveURL will shortcut the expensive call to SetActiveURL when the
78// url_hash matches.
79void FastSetActiveURL(const GURL& url, size_t url_hash) {
80 // Leave the previously set URL in the empty case -- empty URLs are given by
81 // WebKitPlatformSupportImpl::createOffscreenGraphicsContext3D. Hopefully the
82 // onscreen context URL was set previously and will show up even when a crash
83 // occurs during offscreen command processing.
84 if (url.is_empty())
85 return;
86 static size_t g_last_url_hash = 0;
87 if (url_hash != g_last_url_hash) {
88 g_last_url_hash = url_hash;
[email protected]eb398192012-10-22 20:16:1989 GetContentClient()->SetActiveURL(url);
[email protected]d1a9e062012-07-13 00:45:1490 }
91}
92
[email protected]56fc2f22012-07-09 23:50:3693// The first time polling a fence, delay some extra time to allow other
94// stubs to process some work, or else the timing of the fences could
95// allow a pattern of alternating fast and slow frames to occur.
96const int64 kHandleMoreWorkPeriodMs = 2;
97const int64 kHandleMoreWorkPeriodBusyMs = 1;
[email protected]d1a9e062012-07-13 00:45:1498
[email protected]2b1767cf2013-03-16 09:25:0599// Prevents idle work from being starved.
100const int64 kMaxTimeSinceIdleMs = 10;
101
[email protected]d1a9e062012-07-13 00:45:14102} // namespace
[email protected]56fc2f22012-07-09 23:50:36103
[email protected]a3ded6d2010-10-19 06:44:39104GpuCommandBufferStub::GpuCommandBufferStub(
105 GpuChannel* channel,
[email protected]3b1ecc262011-08-03 22:49:57106 GpuCommandBufferStub* share_group,
[email protected]fc4ed092012-02-21 19:46:55107 const gfx::GLSurfaceHandle& handle,
[email protected]78b514b2012-05-01 21:50:59108 gpu::gles2::MailboxManager* mailbox_manager,
[email protected]09d50362012-10-18 20:54:37109 gpu::gles2::ImageManager* image_manager,
[email protected]a3ded6d2010-10-19 06:44:39110 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29111 const gpu::gles2::DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39112 const std::vector<int32>& attribs,
[email protected]276f89062011-10-13 22:55:50113 gfx::GpuPreference gpu_preference,
[email protected]e36f6702013-04-10 16:44:48114 bool use_virtualized_gl_context,
[email protected]a3ded6d2010-10-19 06:44:39115 int32 route_id,
[email protected]9f4f3322012-01-18 22:29:56116 int32 surface_id,
[email protected]f81f5952011-07-21 18:52:47117 GpuWatchdog* watchdog,
[email protected]d1a9e062012-07-13 00:45:14118 bool software,
[email protected]7f1a51c322012-07-19 18:52:02119 const GURL& active_url)
[email protected]246a70452010-03-05 21:53:50120 : channel_(channel),
[email protected]6ebf2fc2010-07-01 01:06:32121 handle_(handle),
[email protected]6217d392010-03-25 22:08:35122 initial_size_(size),
[email protected]e82fb792011-09-22 00:33:29123 disallowed_features_(disallowed_features),
[email protected]34ff8b0c2010-10-01 20:06:02124 requested_attribs_(attribs),
[email protected]276f89062011-10-13 22:55:50125 gpu_preference_(gpu_preference),
[email protected]e36f6702013-04-10 16:44:48126 use_virtualized_gl_context_(use_virtualized_gl_context),
[email protected]77e74db2010-08-04 17:46:23127 route_id_(route_id),
[email protected]5178c4422012-10-17 12:08:07128 surface_id_(surface_id),
[email protected]f81f5952011-07-21 18:52:47129 software_(software),
[email protected]a38477142011-05-28 02:45:58130 last_flush_count_(0),
[email protected]e6e1fc22013-01-25 01:38:06131 last_memory_allocation_valid_(false),
[email protected]35a0b4b2012-06-15 03:53:30132 watchdog_(watchdog),
[email protected]56fc2f22012-07-09 23:50:36133 sync_point_wait_count_(0),
[email protected]d1a9e062012-07-13 00:45:14134 delayed_work_scheduled_(false),
[email protected]2b1767cf2013-03-16 09:25:05135 previous_messages_processed_(0),
[email protected]ee1e6aa2012-11-29 09:24:10136 active_url_(active_url),
137 total_gpu_memory_(0) {
[email protected]51ddf722012-09-01 00:55:09138 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec());
[email protected]d1a9e062012-07-13 00:45:14139 FastSetActiveURL(active_url_, active_url_hash_);
[email protected]bf5a8d132011-08-16 08:39:35140 if (share_group) {
[email protected]3b1ecc262011-08-03 22:49:57141 context_group_ = share_group->context_group_;
[email protected]bf5a8d132011-08-16 08:39:35142 } else {
[email protected]4f9958142013-07-02 03:58:07143 gpu::StreamTextureManager* stream_texture_manager = NULL;
144#if defined(OS_ANDROID)
145 stream_texture_manager = channel_->stream_texture_manager();
146#endif
[email protected]00b192572012-07-28 04:00:22147 context_group_ = new gpu::gles2::ContextGroup(
[email protected]fb246af2012-08-18 03:11:41148 mailbox_manager,
[email protected]09d50362012-10-18 20:54:37149 image_manager,
[email protected]fb246af2012-08-18 03:11:41150 new GpuCommandBufferMemoryTracker(channel),
[email protected]4f9958142013-07-02 03:58:07151 stream_texture_manager,
[email protected]fb246af2012-08-18 03:11:41152 true);
[email protected]bf5a8d132011-08-16 08:39:35153 }
[email protected]41236f82013-09-07 00:24:34154
155 use_virtualized_gl_context_ |=
156 context_group_->feature_info()->workarounds().use_virtualized_gl_contexts;
[email protected]246a70452010-03-05 21:53:50157}
158
159GpuCommandBufferStub::~GpuCommandBufferStub() {
[email protected]79311e82011-09-20 00:40:50160 Destroy();
[email protected]d8a58e42011-01-27 15:24:25161
[email protected]f24a1e2b2011-04-08 01:48:48162 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
[email protected]672c7312012-02-03 16:28:55163 gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer(surface_id()));
[email protected]246a70452010-03-05 21:53:50164}
165
[email protected]c805f8d92012-11-06 12:45:52166GpuMemoryManager* GpuCommandBufferStub::GetMemoryManager() {
167 return channel()->gpu_channel_manager()->gpu_memory_manager();
168}
169
[email protected]a95986a82010-12-24 06:19:28170bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
[email protected]d1a9e062012-07-13 00:45:14171 FastSetActiveURL(active_url_, active_url_hash_);
172
[email protected]79311e82011-09-20 00:40:50173 // Ensure the appropriate GL context is current before handling any IPC
174 // messages directed at the command buffer. This ensures that the message
[email protected]6802e3c62012-06-06 22:32:44175 // handler can assume that the context is current (not necessary for
[email protected]68c70282012-06-25 23:31:17176 // Echo, RetireSyncPoint, or WaitSyncPoint).
[email protected]6802e3c62012-06-06 22:32:44177 if (decoder_.get() &&
[email protected]68c70282012-06-25 23:31:17178 message.type() != GpuCommandBufferMsg_Echo::ID &&
[email protected]627c1be2013-06-14 01:07:51179 message.type() != GpuCommandBufferMsg_GetStateFast::ID &&
[email protected]3ae68c52013-04-12 06:10:05180 message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID &&
181 message.type() != GpuCommandBufferMsg_SetLatencyInfo::ID) {
[email protected]062e5e82012-06-20 19:30:35182 if (!MakeCurrent())
[email protected]79311e82011-09-20 00:40:50183 return false;
[email protected]79311e82011-09-20 00:40:50184 }
185
[email protected]310bed512011-05-09 21:12:25186 // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
187 // here. This is so the reply can be delayed if the scheduler is unscheduled.
[email protected]a95986a82010-12-24 06:19:28188 bool handled = true;
[email protected]246a70452010-03-05 21:53:50189 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
[email protected]310bed512011-05-09 21:12:25190 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize,
191 OnInitialize);
[email protected]392fbb3d2012-12-14 00:34:07192 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer,
193 OnSetGetBuffer);
[email protected]2ad674132013-06-05 07:48:51194 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ProduceFrontBuffer,
195 OnProduceFrontBuffer);
[email protected]1ef068c2012-03-02 16:30:47196 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Echo, OnEcho);
[email protected]310bed512011-05-09 21:12:25197 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState);
[email protected]451e9662011-10-10 21:14:34198 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetStateFast,
199 OnGetStateFast);
[email protected]246a70452010-03-05 21:53:50200 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
[email protected]3ae68c52013-04-12 06:10:05201 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetLatencyInfo, OnSetLatencyInfo);
[email protected]d0f02c42011-07-21 21:40:48202 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Rescheduled, OnRescheduled);
[email protected]67c80782012-12-21 01:16:52203 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer,
204 OnRegisterTransferBuffer);
205 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer,
206 OnDestroyTransferBuffer);
[email protected]310bed512011-05-09 21:12:25207 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetTransferBuffer,
208 OnGetTransferBuffer);
[email protected]c8423062011-07-29 19:25:38209 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder,
210 OnCreateVideoDecoder)
[email protected]8cc980c52011-10-14 20:35:51211 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetSurfaceVisible,
212 OnSetSurfaceVisible)
[email protected]251622e2012-03-23 16:17:40213 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DiscardBackbuffer,
214 OnDiscardBackbuffer)
215 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_EnsureBackbuffer,
216 OnEnsureBackbuffer)
[email protected]c02f93e42012-06-05 23:35:16217 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RetireSyncPoint,
218 OnRetireSyncPoint)
[email protected]5ab44ef2012-06-19 00:03:51219 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncPoint,
220 OnSignalSyncPoint)
[email protected]20dab962013-06-25 03:22:44221 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalQuery,
222 OnSignalQuery)
[email protected]ba148052012-10-30 03:24:05223 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SendClientManagedMemoryStats,
224 OnReceivedClientManagedMemoryStats)
[email protected]c1f12142012-05-01 22:21:06225 IPC_MESSAGE_HANDLER(
226 GpuCommandBufferMsg_SetClientHasMemoryAllocationChangedCallback,
227 OnSetClientHasMemoryAllocationChangedCallback)
[email protected]bc10f462013-10-22 23:13:09228 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterGpuMemoryBuffer,
229 OnRegisterGpuMemoryBuffer);
230 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyGpuMemoryBuffer,
231 OnDestroyGpuMemoryBuffer);
[email protected]a95986a82010-12-24 06:19:28232 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]246a70452010-03-05 21:53:50233 IPC_END_MESSAGE_MAP()
[email protected]a13da242011-07-07 19:48:17234
[email protected]56fc2f22012-07-09 23:50:36235 // Ensure that any delayed work that was created will be handled.
236 ScheduleDelayedWork(kHandleMoreWorkPeriodMs);
237
[email protected]a95986a82010-12-24 06:19:28238 DCHECK(handled);
239 return handled;
[email protected]246a70452010-03-05 21:53:50240}
241
242bool GpuCommandBufferStub::Send(IPC::Message* message) {
243 return channel_->Send(message);
244}
245
[email protected]d0f02c42011-07-21 21:40:48246bool GpuCommandBufferStub::IsScheduled() {
[email protected]840a7e462013-02-27 01:29:51247 return (!scheduler_.get() || scheduler_->IsScheduled());
[email protected]d0f02c42011-07-21 21:40:48248}
249
[email protected]20f656f2011-12-08 02:25:15250bool GpuCommandBufferStub::HasMoreWork() {
251 return scheduler_.get() && scheduler_->HasMoreWork();
252}
253
[email protected]f5f910d52012-03-06 22:33:09254void GpuCommandBufferStub::PollWork() {
[email protected]56fc2f22012-07-09 23:50:36255 TRACE_EVENT0("gpu", "GpuCommandBufferStub::PollWork");
256 delayed_work_scheduled_ = false;
[email protected]a5b2abb912012-07-13 04:45:04257 FastSetActiveURL(active_url_, active_url_hash_);
[email protected]062e5e82012-06-20 19:30:35258 if (decoder_.get() && !MakeCurrent())
259 return;
[email protected]2b1767cf2013-03-16 09:25:05260
[email protected]59383c782013-04-17 16:43:27261 if (scheduler_) {
[email protected]2b1767cf2013-03-16 09:25:05262 bool fences_complete = scheduler_->PollUnscheduleFences();
263 // Perform idle work if all fences are complete.
264 if (fences_complete) {
265 uint64 current_messages_processed =
266 channel()->gpu_channel_manager()->MessagesProcessed();
267 // We're idle when no messages were processed or scheduled.
268 bool is_idle =
269 (previous_messages_processed_ == current_messages_processed) &&
270 !channel()->gpu_channel_manager()->HandleMessagesScheduled();
271 if (!is_idle && !last_idle_time_.is_null()) {
272 base::TimeDelta time_since_idle = base::TimeTicks::Now() -
273 last_idle_time_;
274 base::TimeDelta max_time_since_idle =
275 base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs);
276
277 // Force idle when it's been too long since last time we were idle.
278 if (time_since_idle > max_time_since_idle)
279 is_idle = true;
280 }
281
282 if (is_idle) {
283 last_idle_time_ = base::TimeTicks::Now();
284 scheduler_->PerformIdleWork();
285 }
286 }
287 }
[email protected]56fc2f22012-07-09 23:50:36288 ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs);
[email protected]f5f910d52012-03-06 22:33:09289}
290
[email protected]df621aff2012-03-02 23:04:58291bool GpuCommandBufferStub::HasUnprocessedCommands() {
[email protected]59383c782013-04-17 16:43:27292 if (command_buffer_) {
[email protected]df621aff2012-03-02 23:04:58293 gpu::CommandBuffer::State state = command_buffer_->GetLastState();
[email protected]6dadf652012-03-22 02:49:24294 return state.put_offset != state.get_offset &&
295 !gpu::error::IsError(state.error);
[email protected]df621aff2012-03-02 23:04:58296 }
297 return false;
298}
299
[email protected]56fc2f22012-07-09 23:50:36300void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) {
[email protected]2b1767cf2013-03-16 09:25:05301 if (!HasMoreWork()) {
302 last_idle_time_ = base::TimeTicks();
303 return;
[email protected]56fc2f22012-07-09 23:50:36304 }
[email protected]2b1767cf2013-03-16 09:25:05305
306 if (delayed_work_scheduled_)
307 return;
308 delayed_work_scheduled_ = true;
309
310 // Idle when no messages are processed between now and when
311 // PollWork is called.
312 previous_messages_processed_ =
313 channel()->gpu_channel_manager()->MessagesProcessed();
314 if (last_idle_time_.is_null())
315 last_idle_time_ = base::TimeTicks::Now();
316
317 // IsScheduled() returns true after passing all unschedule fences
318 // and this is when we can start performing idle work. Idle work
319 // is done synchronously so we can set delay to 0 and instead poll
320 // for more work at the rate idle work is performed. This also ensures
321 // that idle work is done as efficiently as possible without any
322 // unnecessary delays.
323 if (scheduler_.get() &&
324 scheduler_->IsScheduled() &&
325 scheduler_->HasMoreIdleWork()) {
326 delay = 0;
327 }
328
[email protected]dd32b1272013-05-04 14:17:11329 base::MessageLoop::current()->PostDelayedTask(
[email protected]2b1767cf2013-03-16 09:25:05330 FROM_HERE,
[email protected]dd32b1272013-05-04 14:17:11331 base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()),
[email protected]2b1767cf2013-03-16 09:25:05332 base::TimeDelta::FromMilliseconds(delay));
[email protected]56fc2f22012-07-09 23:50:36333}
334
[email protected]1ef068c2012-03-02 16:30:47335void GpuCommandBufferStub::OnEcho(const IPC::Message& message) {
336 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEcho");
337 Send(new IPC::Message(message));
338}
339
[email protected]062e5e82012-06-20 19:30:35340bool GpuCommandBufferStub::MakeCurrent() {
341 if (decoder_->MakeCurrent())
342 return true;
343 DLOG(ERROR) << "Context lost because MakeCurrent failed.";
344 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
345 command_buffer_->SetParseError(gpu::error::kLostContext);
[email protected]93a7d98f2013-07-11 00:04:22346 CheckContextLost();
[email protected]062e5e82012-06-20 19:30:35347 return false;
348}
349
[email protected]79311e82011-09-20 00:40:50350void GpuCommandBufferStub::Destroy() {
[email protected]54947032012-12-08 01:44:01351 if (handle_.is_null() && !active_url_.is_empty()) {
352 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
353 gpu_channel_manager->Send(new GpuHostMsg_DidDestroyOffscreenContext(
354 active_url_));
355 }
356
[email protected]931989f2012-12-24 23:34:45357 memory_manager_client_state_.reset();
[email protected]c805f8d92012-11-06 12:45:52358
[email protected]c02f93e42012-06-05 23:35:16359 while (!sync_points_.empty())
360 OnRetireSyncPoint(sync_points_.front());
361
[email protected]59383c782013-04-17 16:43:27362 if (decoder_)
[email protected]fe8d73c2013-02-16 22:37:32363 decoder_->set_engine(NULL);
364
[email protected]79311e82011-09-20 00:40:50365 // The scheduler has raw references to the decoder and the command buffer so
366 // destroy it before those.
[email protected]4ee0c3052011-09-16 19:30:36367 scheduler_.reset();
[email protected]79311e82011-09-20 00:40:50368
[email protected]706b69f2012-07-27 04:59:30369 bool have_context = false;
[email protected]93a7d98f2013-07-11 00:04:22370 if (decoder_ && command_buffer_ &&
371 command_buffer_->GetState().error != gpu::error::kLostContext)
[email protected]706b69f2012-07-27 04:59:30372 have_context = decoder_->MakeCurrent();
[email protected]0f9386892012-02-15 01:44:07373 FOR_EACH_OBSERVER(DestructionObserver,
374 destruction_observers_,
[email protected]24aa62c2013-04-27 02:16:45375 OnWillDestroyStub());
[email protected]0f9386892012-02-15 01:44:07376
[email protected]59383c782013-04-17 16:43:27377 if (decoder_) {
[email protected]706b69f2012-07-27 04:59:30378 decoder_->Destroy(have_context);
[email protected]79311e82011-09-20 00:40:50379 decoder_.reset();
380 }
381
[email protected]4ee0c3052011-09-16 19:30:36382 command_buffer_.reset();
[email protected]79311e82011-09-20 00:40:50383
[email protected]194d5bbb2013-06-13 18:07:07384 // Remove this after crbug.com/248395 is sorted out.
[email protected]79311e82011-09-20 00:40:50385 surface_ = NULL;
[email protected]79311e82011-09-20 00:40:50386}
387
388void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) {
389 Destroy();
[email protected]2e7bbf22011-07-22 18:41:29390 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, false);
391 Send(reply_message);
392}
393
[email protected]392fbb3d2012-12-14 00:34:07394void GpuCommandBufferStub::OnInitialize(
[email protected]67c80782012-12-21 01:16:52395 base::SharedMemoryHandle shared_state_handle,
[email protected]392fbb3d2012-12-14 00:34:07396 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32397 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnInitialize");
[email protected]246a70452010-03-05 21:53:50398 DCHECK(!command_buffer_.get());
399
[email protected]67c80782012-12-21 01:16:52400 scoped_ptr<base::SharedMemory> shared_state_shm(
401 new base::SharedMemory(shared_state_handle, false));
402
[email protected]1d471e82012-06-01 06:13:40403 command_buffer_.reset(new gpu::CommandBufferService(
404 context_group_->transfer_buffer_manager()));
[email protected]246a70452010-03-05 21:53:50405
[email protected]503b3a22011-12-12 23:29:40406 if (!command_buffer_->Initialize()) {
[email protected]198e0c442011-12-02 19:45:06407 DLOG(ERROR) << "CommandBufferService failed to initialize.\n";
[email protected]79311e82011-09-20 00:40:50408 OnInitializeFailed(reply_message);
409 return;
410 }
411
[email protected]bc10f462013-10-22 23:13:09412 gpu_control_.reset(
413 new gpu::GpuControlService(context_group_->image_manager(),
414 NULL,
415 context_group_->mailbox_manager(),
416 NULL));
417
[email protected]79311e82011-09-20 00:40:50418 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get()));
419
420 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
421 decoder_.get(),
[email protected]8a9e1a12011-12-20 01:46:05422 decoder_.get()));
[email protected]fc72bb12013-06-02 21:13:46423 if (preemption_flag_.get())
[email protected]737ed6502013-01-26 03:58:25424 scheduler_->SetPreemptByFlag(preemption_flag_);
[email protected]79311e82011-09-20 00:40:50425
426 decoder_->set_engine(scheduler_.get());
427
[email protected]47940c82012-02-08 02:23:49428 if (!handle_.is_null()) {
[email protected]839d5172011-10-13 17:18:11429#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]2e7bbf22011-07-22 18:41:29430 if (software_) {
[email protected]198e0c442011-12-02 19:45:06431 DLOG(ERROR) << "No software support.\n";
[email protected]2e7bbf22011-07-22 18:41:29432 OnInitializeFailed(reply_message);
433 return;
434 }
[email protected]290fc492011-11-22 23:25:23435#endif
[email protected]2e7bbf22011-07-22 18:41:29436
[email protected]79311e82011-09-20 00:40:50437 surface_ = ImageTransportSurface::CreateSurface(
438 channel_->gpu_channel_manager(),
[email protected]9f4f3322012-01-18 22:29:56439 this,
[email protected]04d58ce2011-09-29 13:12:23440 handle_);
[email protected]79311e82011-09-20 00:40:50441 } else {
[email protected]b8673e62012-09-25 03:15:00442 GpuChannelManager* manager = channel_->gpu_channel_manager();
443 surface_ = manager->GetDefaultOffscreenSurface();
[email protected]79311e82011-09-20 00:40:50444 }
445
[email protected]fc72bb12013-06-02 21:13:46446 if (!surface_.get()) {
[email protected]cc63025a2011-10-29 02:16:24447 DLOG(ERROR) << "Failed to create surface.\n";
[email protected]79311e82011-09-20 00:40:50448 OnInitializeFailed(reply_message);
449 return;
450 }
451
[email protected]ee1e6aa2012-11-29 09:24:10452 scoped_refptr<gfx::GLContext> context;
[email protected]41236f82013-09-07 00:24:34453 if (use_virtualized_gl_context_ && channel_->share_group()) {
[email protected]ee1e6aa2012-11-29 09:24:10454 context = channel_->share_group()->GetSharedContext();
[email protected]fc72bb12013-06-02 21:13:46455 if (!context.get()) {
[email protected]ee1e6aa2012-11-29 09:24:10456 context = gfx::GLContext::CreateGLContext(
457 channel_->share_group(),
458 channel_->gpu_channel_manager()->GetDefaultOffscreenSurface(),
459 gpu_preference_);
[email protected]fc72bb12013-06-02 21:13:46460 channel_->share_group()->SetSharedContext(context.get());
[email protected]ee1e6aa2012-11-29 09:24:10461 }
462 // This should be a non-virtual GL context.
463 DCHECK(context->GetHandle());
[email protected]fc72bb12013-06-02 21:13:46464 context = new gpu::GLContextVirtual(
465 channel_->share_group(), context.get(), decoder_->AsWeakPtr());
466 if (!context->Initialize(surface_.get(), gpu_preference_)) {
[email protected]ee1e6aa2012-11-29 09:24:10467 // TODO(sievers): The real context created above for the default
468 // offscreen surface might not be compatible with this surface.
469 // Need to adjust at least GLX to be able to create the initial context
470 // with a config that is compatible with onscreen and offscreen surfaces.
471 context = NULL;
[email protected]bec15792013-01-30 23:47:20472
[email protected]bec15792013-01-30 23:47:20473 DLOG(ERROR) << "Failed to initialize virtual GL context.";
474 OnInitializeFailed(reply_message);
475 return;
[email protected]ee1e6aa2012-11-29 09:24:10476 }
477 }
[email protected]fc72bb12013-06-02 21:13:46478 if (!context.get()) {
[email protected]ee1e6aa2012-11-29 09:24:10479 context = gfx::GLContext::CreateGLContext(
[email protected]fc72bb12013-06-02 21:13:46480 channel_->share_group(), surface_.get(), gpu_preference_);
[email protected]ee1e6aa2012-11-29 09:24:10481 }
[email protected]fc72bb12013-06-02 21:13:46482 if (!context.get()) {
[email protected]cc63025a2011-10-29 02:16:24483 DLOG(ERROR) << "Failed to create context.\n";
[email protected]79311e82011-09-20 00:40:50484 OnInitializeFailed(reply_message);
485 return;
486 }
[email protected]4bbe6d0c2011-09-16 18:58:54487
[email protected]fc72bb12013-06-02 21:13:46488 if (!context->MakeCurrent(surface_.get())) {
[email protected]63c9b052012-05-17 18:27:38489 LOG(ERROR) << "Failed to make context current.";
490 OnInitializeFailed(reply_message);
491 return;
492 }
493
[email protected]217004512013-05-10 21:25:55494 if (!context->GetGLStateRestorer()) {
495 context->SetGLStateRestorer(
496 new gpu::GLStateRestorerImpl(decoder_->AsWeakPtr()));
497 }
498
[email protected]ee1e6aa2012-11-29 09:24:10499 if (!context->GetTotalGpuMemory(&total_gpu_memory_))
500 total_gpu_memory_ = 0;
501
[email protected]65dfc602012-07-23 20:39:39502 if (!context_group_->has_program_cache()) {
503 context_group_->set_program_cache(
504 channel_->gpu_channel_manager()->program_cache());
505 }
506
[email protected]79311e82011-09-20 00:40:50507 // Initialize the decoder with either the view or pbuffer GLContext.
[email protected]63c9b052012-05-17 18:27:38508 if (!decoder_->Initialize(surface_,
[email protected]ee1e6aa2012-11-29 09:24:10509 context,
[email protected]069944672012-04-25 20:52:23510 !surface_id(),
[email protected]79311e82011-09-20 00:40:50511 initial_size_,
[email protected]e82fb792011-09-22 00:33:29512 disallowed_features_,
[email protected]79311e82011-09-20 00:40:50513 requested_attribs_)) {
[email protected]cc63025a2011-10-29 02:16:24514 DLOG(ERROR) << "Failed to initialize decoder.";
[email protected]79311e82011-09-20 00:40:50515 OnInitializeFailed(reply_message);
516 return;
517 }
518
519 if (CommandLine::ForCurrentProcess()->HasSwitch(
520 switches::kEnableGPUServiceLogging)) {
[email protected]e844ae22012-01-14 03:36:26521 decoder_->set_log_commands(true);
[email protected]79311e82011-09-20 00:40:50522 }
523
[email protected]1d82e822013-04-10 21:32:32524 decoder_->GetLogger()->SetMsgCallback(
[email protected]6b6e7ee2011-12-13 08:04:52525 base::Bind(&GpuCommandBufferStub::SendConsoleMessage,
526 base::Unretained(this)));
[email protected]e3932abb2013-03-13 00:01:37527 decoder_->SetShaderCacheCallback(
528 base::Bind(&GpuCommandBufferStub::SendCachedShader,
529 base::Unretained(this)));
[email protected]840a7e462013-02-27 01:29:51530 decoder_->SetWaitSyncPointCallback(
531 base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint,
532 base::Unretained(this)));
[email protected]6b6e7ee2011-12-13 08:04:52533
[email protected]79311e82011-09-20 00:40:50534 command_buffer_->SetPutOffsetChangeCallback(
[email protected]d1a9e062012-07-13 00:45:14535 base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this)));
[email protected]503b3a22011-12-12 23:29:40536 command_buffer_->SetGetBufferChangeCallback(
537 base::Bind(&gpu::GpuScheduler::SetGetBuffer,
538 base::Unretained(scheduler_.get())));
[email protected]79311e82011-09-20 00:40:50539 command_buffer_->SetParseErrorCallback(
[email protected]9d37f062011-11-22 01:24:52540 base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this)));
[email protected]22218182013-03-01 03:42:10541 scheduler_->SetSchedulingChangedCallback(
542 base::Bind(&GpuChannel::StubSchedulingChanged,
543 base::Unretained(channel_)));
[email protected]79311e82011-09-20 00:40:50544
[email protected]79311e82011-09-20 00:40:50545 if (watchdog_) {
546 scheduler_->SetCommandProcessedCallback(
[email protected]9d37f062011-11-22 01:24:52547 base::Bind(&GpuCommandBufferStub::OnCommandProcessed,
548 base::Unretained(this)));
[email protected]79311e82011-09-20 00:40:50549 }
550
[email protected]67c80782012-12-21 01:16:52551 if (!command_buffer_->SetSharedStateBuffer(shared_state_shm.Pass())) {
552 DLOG(ERROR) << "Failed to map shared stae buffer.";
553 OnInitializeFailed(reply_message);
554 return;
555 }
556
[email protected]2e7bbf22011-07-22 18:41:29557 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, true);
[email protected]310bed512011-05-09 21:12:25558 Send(reply_message);
[email protected]54947032012-12-08 01:44:01559
560 if (handle_.is_null() && !active_url_.is_empty()) {
561 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
562 gpu_channel_manager->Send(new GpuHostMsg_DidCreateOffscreenContext(
563 active_url_));
564 }
[email protected]246a70452010-03-05 21:53:50565}
566
[email protected]3ae68c52013-04-12 06:10:05567void GpuCommandBufferStub::OnSetLatencyInfo(
[email protected]4b157662013-05-29 04:05:05568 const ui::LatencyInfo& latency_info) {
[email protected]3ae68c52013-04-12 06:10:05569 if (!latency_info_callback_.is_null())
570 latency_info_callback_.Run(latency_info);
571}
572
573void GpuCommandBufferStub::SetLatencyInfoCallback(
574 const LatencyInfoCallback& callback) {
575 latency_info_callback_ = callback;
576}
577
[email protected]67c80782012-12-21 01:16:52578void GpuCommandBufferStub::OnSetGetBuffer(int32 shm_id,
579 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32580 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer");
[email protected]59383c782013-04-17 16:43:27581 if (command_buffer_)
[email protected]773bf5e2012-01-06 01:07:13582 command_buffer_->SetGetBuffer(shm_id);
[email protected]68eff952012-02-17 21:56:35583 Send(reply_message);
584}
585
[email protected]2ad674132013-06-05 07:48:51586void GpuCommandBufferStub::OnProduceFrontBuffer(const gpu::Mailbox& mailbox) {
587 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnProduceFrontBuffer");
588 if (!decoder_)
589 LOG(ERROR) << "Can't produce front buffer before initialization.";
[email protected]3c644d82011-06-20 19:58:24590
[email protected]2ad674132013-06-05 07:48:51591 if (!decoder_->ProduceFrontBuffer(mailbox))
592 LOG(ERROR) << "Failed to produce front buffer.";
[email protected]3c644d82011-06-20 19:58:24593}
594
[email protected]310bed512011-05-09 21:12:25595void GpuCommandBufferStub::OnGetState(IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32596 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetState");
[email protected]59383c782013-04-17 16:43:27597 if (command_buffer_) {
[email protected]773bf5e2012-01-06 01:07:13598 gpu::CommandBuffer::State state = command_buffer_->GetState();
[email protected]93a7d98f2013-07-11 00:04:22599 CheckContextLost();
[email protected]773bf5e2012-01-06 01:07:13600 GpuCommandBufferMsg_GetState::WriteReplyParams(reply_message, state);
601 } else {
602 DLOG(ERROR) << "no command_buffer.";
603 reply_message->set_reply_error();
604 }
[email protected]310bed512011-05-09 21:12:25605 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50606}
607
[email protected]0a68ac872011-06-07 04:48:27608void GpuCommandBufferStub::OnParseError() {
609 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnParseError");
[email protected]773bf5e2012-01-06 01:07:13610 DCHECK(command_buffer_.get());
[email protected]38d139d2011-07-14 00:38:43611 gpu::CommandBuffer::State state = command_buffer_->GetState();
612 IPC::Message* msg = new GpuCommandBufferMsg_Destroyed(
613 route_id_, state.context_lost_reason);
[email protected]0a68ac872011-06-07 04:48:27614 msg->set_unblock(true);
615 Send(msg);
[email protected]54947032012-12-08 01:44:01616
617 // Tell the browser about this context loss as well, so it can
618 // determine whether client APIs like WebGL need to be immediately
619 // blocked from automatically running.
620 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
621 gpu_channel_manager->Send(new GpuHostMsg_DidLoseContext(
622 handle_.is_null(), state.context_lost_reason, active_url_));
[email protected]93a7d98f2013-07-11 00:04:22623
624 CheckContextLost();
[email protected]0a68ac872011-06-07 04:48:27625}
626
[email protected]451e9662011-10-10 21:14:34627void GpuCommandBufferStub::OnGetStateFast(IPC::Message* reply_message) {
628 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetStateFast");
[email protected]773bf5e2012-01-06 01:07:13629 DCHECK(command_buffer_.get());
[email protected]93a7d98f2013-07-11 00:04:22630 CheckContextLost();
[email protected]d0f02c42011-07-21 21:40:48631 gpu::CommandBuffer::State state = command_buffer_->GetState();
[email protected]451e9662011-10-10 21:14:34632 GpuCommandBufferMsg_GetStateFast::WriteReplyParams(reply_message, state);
633 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50634}
635
[email protected]451e9662011-10-10 21:14:34636void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset,
637 uint32 flush_count) {
638 TRACE_EVENT1("gpu", "GpuCommandBufferStub::OnAsyncFlush",
639 "put_offset", put_offset);
[email protected]773bf5e2012-01-06 01:07:13640 DCHECK(command_buffer_.get());
[email protected]fde205d2011-05-31 22:29:50641 if (flush_count - last_flush_count_ < 0x8000000U) {
[email protected]a38477142011-05-28 02:45:58642 last_flush_count_ = flush_count;
643 command_buffer_->Flush(put_offset);
644 } else {
[email protected]fde205d2011-05-31 22:29:50645 // We received this message out-of-order. This should not happen but is here
646 // to catch regressions. Ignore the message.
647 NOTREACHED() << "Received a Flush message out-of-order";
[email protected]a38477142011-05-28 02:45:58648 }
[email protected]d0f02c42011-07-21 21:40:48649
650 ReportState();
651}
652
653void GpuCommandBufferStub::OnRescheduled() {
[email protected]20f656f2011-12-08 02:25:15654 gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState();
655 command_buffer_->Flush(pre_state.put_offset);
656 gpu::CommandBuffer::State post_state = command_buffer_->GetLastState();
[email protected]d0f02c42011-07-21 21:40:48657
[email protected]20f656f2011-12-08 02:25:15658 if (pre_state.get_offset != post_state.get_offset)
659 ReportState();
[email protected]246a70452010-03-05 21:53:50660}
661
[email protected]0100b7a2011-02-24 22:54:50662void GpuCommandBufferStub::OnRegisterTransferBuffer(
[email protected]67c80782012-12-21 01:16:52663 int32 id,
[email protected]0100b7a2011-02-24 22:54:50664 base::SharedMemoryHandle transfer_buffer,
[email protected]67c80782012-12-21 01:16:52665 uint32 size) {
[email protected]3551cb202012-05-24 10:55:32666 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterTransferBuffer");
[email protected]0100b7a2011-02-24 22:54:50667 base::SharedMemory shared_memory(transfer_buffer, false);
[email protected]7df1d1a2011-02-26 02:07:57668
[email protected]59383c782013-04-17 16:43:27669 if (command_buffer_)
[email protected]67c80782012-12-21 01:16:52670 command_buffer_->RegisterTransferBuffer(id, &shared_memory, size);
[email protected]0100b7a2011-02-24 22:54:50671}
672
[email protected]67c80782012-12-21 01:16:52673void GpuCommandBufferStub::OnDestroyTransferBuffer(int32 id) {
[email protected]3551cb202012-05-24 10:55:32674 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyTransferBuffer");
[email protected]67c80782012-12-21 01:16:52675
[email protected]59383c782013-04-17 16:43:27676 if (command_buffer_)
[email protected]773bf5e2012-01-06 01:07:13677 command_buffer_->DestroyTransferBuffer(id);
[email protected]246a70452010-03-05 21:53:50678}
679
680void GpuCommandBufferStub::OnGetTransferBuffer(
681 int32 id,
[email protected]310bed512011-05-09 21:12:25682 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32683 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetTransferBuffer");
[email protected]59383c782013-04-17 16:43:27684 if (command_buffer_) {
[email protected]773bf5e2012-01-06 01:07:13685 base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle();
686 uint32 size = 0;
[email protected]310bed512011-05-09 21:12:25687
[email protected]773bf5e2012-01-06 01:07:13688 gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id);
689 if (buffer.shared_memory) {
[email protected]cd0bd792012-04-14 00:52:16690#if defined(OS_WIN)
691 transfer_buffer = NULL;
[email protected]eb398192012-10-22 20:16:19692 BrokerDuplicateHandle(buffer.shared_memory->handle(),
[email protected]cd0bd792012-04-14 00:52:16693 channel_->renderer_pid(), &transfer_buffer, FILE_MAP_READ |
694 FILE_MAP_WRITE, 0);
[email protected]8f9904d2012-05-09 00:20:22695 DCHECK(transfer_buffer != NULL);
[email protected]cd0bd792012-04-14 00:52:16696#else
697 buffer.shared_memory->ShareToProcess(channel_->renderer_pid(),
[email protected]773bf5e2012-01-06 01:07:13698 &transfer_buffer);
[email protected]cd0bd792012-04-14 00:52:16699#endif
[email protected]773bf5e2012-01-06 01:07:13700 size = buffer.size;
701 }
702
703 GpuCommandBufferMsg_GetTransferBuffer::WriteReplyParams(reply_message,
704 transfer_buffer,
705 size);
706 } else {
707 reply_message->set_reply_error();
708 }
[email protected]310bed512011-05-09 21:12:25709 Send(reply_message);
[email protected]246a70452010-03-05 21:53:50710}
711
[email protected]310bed512011-05-09 21:12:25712void GpuCommandBufferStub::OnCommandProcessed() {
713 if (watchdog_)
714 watchdog_->CheckArmed();
715}
716
[email protected]ef16c172011-04-28 23:37:14717void GpuCommandBufferStub::ReportState() {
[email protected]93a7d98f2013-07-11 00:04:22718 if (!CheckContextLost())
[email protected]68eff952012-02-17 21:56:35719 command_buffer_->UpdateState();
[email protected]ef16c172011-04-28 23:37:14720}
721
[email protected]d1a9e062012-07-13 00:45:14722void GpuCommandBufferStub::PutChanged() {
723 FastSetActiveURL(active_url_, active_url_hash_);
724 scheduler_->PutChanged();
725}
726
[email protected]a13da242011-07-07 19:48:17727void GpuCommandBufferStub::OnCreateVideoDecoder(
[email protected]e5ca6362012-03-30 09:45:58728 media::VideoCodecProfile profile,
[email protected]c8423062011-07-29 19:25:38729 IPC::Message* reply_message) {
[email protected]3551cb202012-05-24 10:55:32730 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoDecoder");
[email protected]502e6052011-08-17 00:17:23731 int decoder_route_id = channel_->GenerateRouteID();
[email protected]cf4edb432013-09-11 14:47:28732 GpuVideoDecodeAccelerator* decoder = new GpuVideoDecodeAccelerator(
733 decoder_route_id, this, channel_->io_message_loop());
734 decoder->Initialize(profile, reply_message);
[email protected]24aa62c2013-04-27 02:16:45735 // decoder is registered as a DestructionObserver of this stub and will
736 // self-delete during destruction of this stub.
[email protected]a13da242011-07-07 19:48:17737}
738
[email protected]8cc980c52011-10-14 20:35:51739void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) {
[email protected]3551cb202012-05-24 10:55:32740 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSurfaceVisible");
[email protected]59383c782013-04-17 16:43:27741 if (memory_manager_client_state_)
[email protected]931989f2012-12-24 23:34:45742 memory_manager_client_state_->SetVisible(visible);
[email protected]8cc980c52011-10-14 20:35:51743}
744
[email protected]251622e2012-03-23 16:17:40745void GpuCommandBufferStub::OnDiscardBackbuffer() {
[email protected]3551cb202012-05-24 10:55:32746 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDiscardBackbuffer");
[email protected]fc72bb12013-06-02 21:13:46747 if (!surface_.get())
[email protected]251622e2012-03-23 16:17:40748 return;
[email protected]50776f72012-11-30 02:36:05749 if (surface_->DeferDraws()) {
750 DCHECK(!IsScheduled());
751 channel_->RequeueMessage();
752 } else {
[email protected]a9327cf2013-01-30 00:01:30753 if (!surface_->SetBackbufferAllocation(false))
754 channel_->DestroySoon();
[email protected]50776f72012-11-30 02:36:05755 }
[email protected]251622e2012-03-23 16:17:40756}
757
758void GpuCommandBufferStub::OnEnsureBackbuffer() {
[email protected]3551cb202012-05-24 10:55:32759 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEnsureBackbuffer");
[email protected]fc72bb12013-06-02 21:13:46760 if (!surface_.get())
[email protected]251622e2012-03-23 16:17:40761 return;
[email protected]50776f72012-11-30 02:36:05762 if (surface_->DeferDraws()) {
763 DCHECK(!IsScheduled());
764 channel_->RequeueMessage();
765 } else {
[email protected]a9327cf2013-01-30 00:01:30766 if (!surface_->SetBackbufferAllocation(true))
767 channel_->DestroySoon();
[email protected]50776f72012-11-30 02:36:05768 }
[email protected]251622e2012-03-23 16:17:40769}
770
[email protected]c02f93e42012-06-05 23:35:16771void GpuCommandBufferStub::AddSyncPoint(uint32 sync_point) {
772 sync_points_.push_back(sync_point);
773}
774
775void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) {
776 DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point);
777 sync_points_.pop_front();
778 GpuChannelManager* manager = channel_->gpu_channel_manager();
779 manager->sync_point_manager()->RetireSyncPoint(sync_point);
780}
781
[email protected]840a7e462013-02-27 01:29:51782bool GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) {
[email protected]35a0b4b2012-06-15 03:53:30783 if (sync_point_wait_count_ == 0) {
784 TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this,
785 "GpuCommandBufferStub", this);
786 }
[email protected]840a7e462013-02-27 01:29:51787 scheduler_->SetScheduled(false);
[email protected]35a0b4b2012-06-15 03:53:30788 ++sync_point_wait_count_;
[email protected]c02f93e42012-06-05 23:35:16789 GpuChannelManager* manager = channel_->gpu_channel_manager();
790 manager->sync_point_manager()->AddSyncPointCallback(
791 sync_point,
792 base::Bind(&GpuCommandBufferStub::OnSyncPointRetired,
793 this->AsWeakPtr()));
[email protected]840a7e462013-02-27 01:29:51794 return scheduler_->IsScheduled();
[email protected]c02f93e42012-06-05 23:35:16795}
796
797void GpuCommandBufferStub::OnSyncPointRetired() {
[email protected]35a0b4b2012-06-15 03:53:30798 --sync_point_wait_count_;
799 if (sync_point_wait_count_ == 0) {
800 TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this,
801 "GpuCommandBufferStub", this);
802 }
[email protected]840a7e462013-02-27 01:29:51803 scheduler_->SetScheduled(true);
[email protected]c02f93e42012-06-05 23:35:16804}
805
[email protected]5ab44ef2012-06-19 00:03:51806void GpuCommandBufferStub::OnSignalSyncPoint(uint32 sync_point, uint32 id) {
807 GpuChannelManager* manager = channel_->gpu_channel_manager();
808 manager->sync_point_manager()->AddSyncPointCallback(
809 sync_point,
810 base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck,
811 this->AsWeakPtr(),
812 id));
813}
814
815void GpuCommandBufferStub::OnSignalSyncPointAck(uint32 id) {
816 Send(new GpuCommandBufferMsg_SignalSyncPointAck(route_id_, id));
817}
818
[email protected]20dab962013-06-25 03:22:44819void GpuCommandBufferStub::OnSignalQuery(uint32 query_id, uint32 id) {
820 if (decoder_) {
821 gpu::gles2::QueryManager* query_manager = decoder_->GetQueryManager();
822 if (query_manager) {
823 gpu::gles2::QueryManager::Query* query =
824 query_manager->GetQuery(query_id);
825 if (query) {
826 query->AddCallback(
827 base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck,
828 this->AsWeakPtr(),
829 id));
830 return;
831 }
832 }
833 }
834 // Something went wrong, run callback immediately.
835 OnSignalSyncPointAck(id);
836}
837
838
[email protected]ba148052012-10-30 03:24:05839void GpuCommandBufferStub::OnReceivedClientManagedMemoryStats(
840 const GpuManagedMemoryStats& stats) {
841 TRACE_EVENT0(
842 "gpu",
843 "GpuCommandBufferStub::OnReceivedClientManagedMemoryStats");
[email protected]59383c782013-04-17 16:43:27844 if (memory_manager_client_state_)
[email protected]931989f2012-12-24 23:34:45845 memory_manager_client_state_->SetManagedMemoryStats(stats);
[email protected]ba148052012-10-30 03:24:05846}
847
[email protected]c1f12142012-05-01 22:21:06848void GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback(
849 bool has_callback) {
[email protected]3551cb202012-05-24 10:55:32850 TRACE_EVENT0(
851 "gpu",
852 "GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback");
[email protected]931989f2012-12-24 23:34:45853 if (has_callback) {
[email protected]59383c782013-04-17 16:43:27854 if (!memory_manager_client_state_) {
[email protected]931989f2012-12-24 23:34:45855 memory_manager_client_state_.reset(GetMemoryManager()->CreateClientState(
856 this, surface_id_ != 0, true));
857 }
858 } else {
859 memory_manager_client_state_.reset();
860 }
[email protected]c1f12142012-05-01 22:21:06861}
862
[email protected]bc10f462013-10-22 23:13:09863void GpuCommandBufferStub::OnRegisterGpuMemoryBuffer(
864 int32 id,
865 gfx::GpuMemoryBufferHandle gpu_memory_buffer,
866 uint32 width,
867 uint32 height,
868 uint32 internalformat) {
869 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterGpuMemoryBuffer");
870 if (gpu_control_) {
871 gpu_control_->RegisterGpuMemoryBuffer(id,
872 gpu_memory_buffer,
873 width,
874 height,
875 internalformat);
876 }
877}
878
879void GpuCommandBufferStub::OnDestroyGpuMemoryBuffer(int32 id) {
880 TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyGpuMemoryBuffer");
881 if (gpu_control_)
882 gpu_control_->DestroyGpuMemoryBuffer(id);
883}
884
[email protected]6b6e7ee2011-12-13 08:04:52885void GpuCommandBufferStub::SendConsoleMessage(
886 int32 id,
887 const std::string& message) {
888 GPUCommandBufferConsoleMessage console_message;
889 console_message.id = id;
890 console_message.message = message;
891 IPC::Message* msg = new GpuCommandBufferMsg_ConsoleMsg(
892 route_id_, console_message);
893 msg->set_unblock(true);
894 Send(msg);
895}
896
[email protected]e3932abb2013-03-13 00:01:37897void GpuCommandBufferStub::SendCachedShader(
898 const std::string& key, const std::string& shader) {
899 channel_->CacheShader(key, shader);
900}
901
[email protected]0f9386892012-02-15 01:44:07902void GpuCommandBufferStub::AddDestructionObserver(
903 DestructionObserver* observer) {
904 destruction_observers_.AddObserver(observer);
905}
906
907void GpuCommandBufferStub::RemoveDestructionObserver(
908 DestructionObserver* observer) {
909 destruction_observers_.RemoveObserver(observer);
910}
911
[email protected]737ed6502013-01-26 03:58:25912void GpuCommandBufferStub::SetPreemptByFlag(
913 scoped_refptr<gpu::PreemptionFlag> flag) {
914 preemption_flag_ = flag;
[email protected]59383c782013-04-17 16:43:27915 if (scheduler_)
[email protected]737ed6502013-01-26 03:58:25916 scheduler_->SetPreemptByFlag(preemption_flag_);
[email protected]6802e3c62012-06-06 22:32:44917}
918
[email protected]677cf5f2013-01-31 21:31:48919bool GpuCommandBufferStub::GetTotalGpuMemory(uint64* bytes) {
[email protected]ee1e6aa2012-11-29 09:24:10920 *bytes = total_gpu_memory_;
921 return !!total_gpu_memory_;
[email protected]4b8a6b092012-10-05 01:20:06922}
923
[email protected]1d56e9642012-05-04 15:40:13924gfx::Size GpuCommandBufferStub::GetSurfaceSize() const {
[email protected]fc72bb12013-06-02 21:13:46925 if (!surface_.get())
[email protected]1d56e9642012-05-04 15:40:13926 return gfx::Size();
927 return surface_->GetSize();
928}
929
[email protected]9db65ff2012-11-02 04:22:04930gpu::gles2::MemoryTracker* GpuCommandBufferStub::GetMemoryTracker() const {
931 return context_group_->memory_tracker();
[email protected]c53709012012-02-21 03:22:22932}
933
[email protected]74b407d2012-02-11 01:13:55934void GpuCommandBufferStub::SetMemoryAllocation(
935 const GpuMemoryAllocation& allocation) {
[email protected]e6e1fc22013-01-25 01:38:06936 if (!last_memory_allocation_valid_ ||
937 !allocation.renderer_allocation.Equals(
938 last_memory_allocation_.renderer_allocation)) {
939 Send(new GpuCommandBufferMsg_SetMemoryAllocation(
940 route_id_, allocation.renderer_allocation));
941 }
942
943 if (!last_memory_allocation_valid_ ||
944 !allocation.browser_allocation.Equals(
945 last_memory_allocation_.browser_allocation)) {
946 // This can be called outside of OnMessageReceived, so the context needs
947 // to be made current before calling methods on the surface.
[email protected]fc72bb12013-06-02 21:13:46948 if (surface_.get() && MakeCurrent())
[email protected]e6e1fc22013-01-25 01:38:06949 surface_->SetFrontbufferAllocation(
950 allocation.browser_allocation.suggest_have_frontbuffer);
951 }
952
953 last_memory_allocation_valid_ = true;
954 last_memory_allocation_ = allocation;
[email protected]74b407d2012-02-11 01:13:55955}
956
[email protected]93a7d98f2013-07-11 00:04:22957bool GpuCommandBufferStub::CheckContextLost() {
958 DCHECK(command_buffer_);
959 gpu::CommandBuffer::State state = command_buffer_->GetState();
960 bool was_lost = state.error == gpu::error::kLostContext;
961 // Lose all other contexts if the reset was triggered by the robustness
962 // extension instead of being synthetic.
963 if (was_lost && decoder_ && decoder_->WasContextLostByRobustnessExtension() &&
964 (gfx::GLContext::LosesAllContextsOnContextLost() ||
965 use_virtualized_gl_context_))
966 channel_->LoseAllContexts();
967 return was_lost;
968}
969
970void GpuCommandBufferStub::MarkContextLost() {
971 if (!command_buffer_ ||
972 command_buffer_->GetState().error == gpu::error::kLostContext)
973 return;
974
975 command_buffer_->SetContextLostReason(gpu::error::kUnknown);
976 if (decoder_)
977 decoder_->LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
978 command_buffer_->SetParseError(gpu::error::kLostContext);
979}
980
[email protected]eb398192012-10-22 20:16:19981} // namespace content