gpu_command_buffer_stub.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/hash.h"
107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/gpu/devtools_gpu_instrumentation.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel_manager.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_command_buffer_stub.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_memory_manager.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_memory_tracking.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_watchdog.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/image_transport_surface.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/media/gpu_video_decode_accelerator.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/sync_point_manager.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_client.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/constants.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h"
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/gl_context_virtual.h"
29a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "gpu/command_buffer/service/gl_state_restorer_impl.h"
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "gpu/command_buffer/service/gpu_control_service.h"
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "gpu/command_buffer/service/image_manager.h"
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/command_buffer/service/logger.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/memory_tracking.h"
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "gpu/command_buffer/service/query_manager.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/sandbox_init.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/stream_texture_manager_android.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The GpuCommandBufferMemoryTracker class provides a bridge between the
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ContextGroup's memory type managers and the GpuMemoryManager class.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GpuCommandBufferMemoryTracker : public gpu::gles2::MemoryTracker {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit GpuCommandBufferMemoryTracker(GpuChannel* channel) :
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tracking_group_(channel->gpu_channel_manager()->gpu_memory_manager()->
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          CreateTrackingGroup(channel->renderer_pid(), this)) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TrackMemoryAllocatedChange(
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t old_size,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_t new_size,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gpu::gles2::MemoryTracker::Pool pool) OVERRIDE {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    tracking_group_->TrackMemoryAllocatedChange(
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        old_size, new_size, pool);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool EnsureGPUMemoryAvailable(size_t size_needed) OVERRIDE {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return tracking_group_->EnsureGPUMemoryAvailable(size_needed);
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~GpuCommandBufferMemoryTracker() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<GpuMemoryTrackingGroup> tracking_group_;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FastSetActiveURL will shortcut the expensive call to SetActiveURL when the
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// url_hash matches.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FastSetActiveURL(const GURL& url, size_t url_hash) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Leave the previously set URL in the empty case -- empty URLs are given by
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebKitPlatformSupportImpl::createOffscreenGraphicsContext3D. Hopefully the
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // onscreen context URL was set previously and will show up even when a crash
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // occurs during offscreen command processing.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url.is_empty())
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t g_last_url_hash = 0;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url_hash != g_last_url_hash) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_last_url_hash = url_hash;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetContentClient()->SetActiveURL(url);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The first time polling a fence, delay some extra time to allow other
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stubs to process some work, or else the timing of the fences could
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// allow a pattern of alternating fast and slow frames to occur.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kHandleMoreWorkPeriodMs = 2;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kHandleMoreWorkPeriodBusyMs = 1;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Prevents idle work from being starved.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kMaxTimeSinceIdleMs = 10;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuCommandBufferStub::GpuCommandBufferStub(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuChannel* channel,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuCommandBufferStub* share_group,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::GLSurfaceHandle& handle,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpu::gles2::MailboxManager* mailbox_manager,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpu::gles2::ImageManager* image_manager,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& size,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gpu::gles2::DisallowedFeatures& disallowed_features,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<int32>& attribs,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::GpuPreference gpu_preference,
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool use_virtualized_gl_context,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 route_id,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 surface_id,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuWatchdog* watchdog,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool software,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& active_url)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : channel_(channel),
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      handle_(handle),
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      initial_size_(size),
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disallowed_features_(disallowed_features),
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      requested_attribs_(attribs),
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gpu_preference_(gpu_preference),
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      use_virtualized_gl_context_(use_virtualized_gl_context),
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      route_id_(route_id),
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      surface_id_(surface_id),
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      software_(software),
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_flush_count_(0),
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      last_memory_allocation_valid_(false),
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      watchdog_(watchdog),
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_point_wait_count_(0),
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delayed_work_scheduled_(false),
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      previous_messages_processed_(0),
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      active_url_(active_url),
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      total_gpu_memory_(0) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  active_url_hash_ = base::Hash(active_url.possibly_invalid_spec());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FastSetActiveURL(active_url_, active_url_hash_);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (share_group) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_group_ = share_group->context_group_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    gpu::StreamTextureManager* stream_texture_manager = NULL;
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_ANDROID)
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    stream_texture_manager = channel_->stream_texture_manager();
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_group_ = new gpu::gles2::ContextGroup(
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mailbox_manager,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        image_manager,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new GpuCommandBufferMemoryTracker(channel),
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        stream_texture_manager,
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        NULL,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        true);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  use_virtualized_gl_context_ |=
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      context_group_->feature_info()->workarounds().use_virtualized_gl_contexts;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuCommandBufferStub::~GpuCommandBufferStub() {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Destroy();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer(surface_id()));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GpuMemoryManager* GpuCommandBufferStub::GetMemoryManager() const {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return channel()->gpu_channel_manager()->gpu_memory_manager();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  devtools_gpu_instrumentation::ScopedGpuTask task(this);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FastSetActiveURL(active_url_, active_url_hash_);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the appropriate GL context is current before handling any IPC
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // messages directed at the command buffer. This ensures that the message
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handler can assume that the context is current (not necessary for
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Echo, RetireSyncPoint, or WaitSyncPoint).
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (decoder_.get() &&
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message.type() != GpuCommandBufferMsg_Echo::ID &&
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      message.type() != GpuCommandBufferMsg_GetStateFast::ID &&
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID &&
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      message.type() != GpuCommandBufferMsg_SetLatencyInfo::ID) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!MakeCurrent())
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here. This is so the reply can be delayed if the scheduler is unscheduled.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handled = true;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnInitialize);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnSetGetBuffer);
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ProduceFrontBuffer,
198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                        OnProduceFrontBuffer);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Echo, OnEcho);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetStateFast,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnGetStateFast);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetLatencyInfo, OnSetLatencyInfo);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Rescheduled, OnRescheduled);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer,
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnRegisterTransferBuffer);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer,
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        OnDestroyTransferBuffer);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetTransferBuffer,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnGetTransferBuffer);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    OnCreateVideoDecoder)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetSurfaceVisible,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnSetSurfaceVisible)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DiscardBackbuffer,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnDiscardBackbuffer)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_EnsureBackbuffer,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnEnsureBackbuffer)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RetireSyncPoint,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnRetireSyncPoint)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncPoint,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnSignalSyncPoint)
224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalQuery,
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        OnSignalQuery)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SendClientManagedMemoryStats,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        OnReceivedClientManagedMemoryStats)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_HANDLER(
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GpuCommandBufferMsg_SetClientHasMemoryAllocationChangedCallback,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        OnSetClientHasMemoryAllocationChangedCallback)
2311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterGpuMemoryBuffer,
2321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                        OnRegisterGpuMemoryBuffer);
2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyGpuMemoryBuffer,
2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                        OnDestroyGpuMemoryBuffer);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that any delayed work that was created will be handled.
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleDelayedWork(kHandleMoreWorkPeriodMs);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(handled);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handled;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::Send(IPC::Message* message) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return channel_->Send(message);
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::IsScheduled() {
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (!scheduler_.get() || scheduler_->IsScheduled());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::HasMoreWork() {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scheduler_.get() && scheduler_->HasMoreWork();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::PollWork() {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::PollWork");
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delayed_work_scheduled_ = false;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FastSetActiveURL(active_url_, active_url_hash_);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (decoder_.get() && !MakeCurrent())
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (scheduler_) {
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool fences_complete = scheduler_->PollUnscheduleFences();
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Perform idle work if all fences are complete.
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (fences_complete) {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uint64 current_messages_processed =
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          channel()->gpu_channel_manager()->MessagesProcessed();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // We're idle when no messages were processed or scheduled.
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool is_idle =
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          (previous_messages_processed_ == current_messages_processed) &&
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          !channel()->gpu_channel_manager()->HandleMessagesScheduled();
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!is_idle && !last_idle_time_.is_null()) {
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta time_since_idle = base::TimeTicks::Now() -
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            last_idle_time_;
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta max_time_since_idle =
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs);
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        // Force idle when it's been too long since last time we were idle.
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (time_since_idle > max_time_since_idle)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          is_idle = true;
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (is_idle) {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        last_idle_time_ = base::TimeTicks::Now();
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        scheduler_->PerformIdleWork();
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::HasUnprocessedCommands() {
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (command_buffer_) {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpu::CommandBuffer::State state = command_buffer_->GetLastState();
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return state.put_offset != state.get_offset &&
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !gpu::error::IsError(state.error);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) {
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!HasMoreWork()) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_idle_time_ = base::TimeTicks();
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (delayed_work_scheduled_)
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delayed_work_scheduled_ = true;
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Idle when no messages are processed between now and when
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // PollWork is called.
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  previous_messages_processed_ =
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      channel()->gpu_channel_manager()->MessagesProcessed();
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (last_idle_time_.is_null())
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_idle_time_ = base::TimeTicks::Now();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // IsScheduled() returns true after passing all unschedule fences
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and this is when we can start performing idle work. Idle work
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is done synchronously so we can set delay to 0 and instead poll
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // for more work at the rate idle work is performed. This also ensures
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that idle work is done as efficiently as possible without any
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // unnecessary delays.
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (scheduler_.get() &&
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scheduler_->IsScheduled() &&
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scheduler_->HasMoreIdleWork()) {
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delay = 0;
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE,
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()),
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(delay));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnEcho(const IPC::Message& message) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEcho");
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new IPC::Message(message));
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::MakeCurrent() {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (decoder_->MakeCurrent())
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DLOG(ERROR) << "Context lost because MakeCurrent failed.";
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_buffer_->SetParseError(gpu::error::kLostContext);
3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CheckContextLost();
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::Destroy() {
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (handle_.is_null() && !active_url_.is_empty()) {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_channel_manager->Send(new GpuHostMsg_DidDestroyOffscreenContext(
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        active_url_));
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  memory_manager_client_state_.reset();
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!sync_points_.empty())
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnRetireSyncPoint(sync_points_.front());
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (decoder_)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    decoder_->set_engine(NULL);
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The scheduler has raw references to the decoder and the command buffer so
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroy it before those.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler_.reset();
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool have_context = false;
3737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (decoder_ && command_buffer_ &&
3747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      command_buffer_->GetState().error != gpu::error::kLostContext)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    have_context = decoder_->MakeCurrent();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FOR_EACH_OBSERVER(DestructionObserver,
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    destruction_observers_,
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    OnWillDestroyStub());
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (decoder_) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decoder_->Destroy(have_context);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decoder_.reset();
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_buffer_.reset();
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)  // Remove this after crbug.com/248395 is sorted out.
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  surface_ = NULL;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) {
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Destroy();
393a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GpuCommandBufferMsg_Initialize::WriteReplyParams(
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      reply_message, false, gpu::Capabilities());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_message);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnInitialize(
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::SharedMemoryHandle shared_state_handle,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::Message* reply_message) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnInitialize");
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!command_buffer_.get());
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<base::SharedMemory> shared_state_shm(
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new base::SharedMemory(shared_state_handle, false));
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_buffer_.reset(new gpu::CommandBufferService(
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_group_->transfer_buffer_manager()));
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!command_buffer_->Initialize()) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "CommandBufferService failed to initialize.\n";
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnInitializeFailed(reply_message);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get()));
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(),
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         decoder_.get(),
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         decoder_.get()));
421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (preemption_flag_.get())
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scheduler_->SetPreemptByFlag(preemption_flag_);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  decoder_->set_engine(scheduler_.get());
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!handle_.is_null()) {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (software_) {
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG(ERROR) << "No software support.\n";
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OnInitializeFailed(reply_message);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    surface_ = ImageTransportSurface::CreateSurface(
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        channel_->gpu_channel_manager(),
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        this,
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        handle_);
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuChannelManager* manager = channel_->gpu_channel_manager();
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    surface_ = manager->GetDefaultOffscreenSurface();
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
444868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!surface_.get()) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "Failed to create surface.\n";
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnInitializeFailed(reply_message);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<gfx::GLContext> context;
45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (use_virtualized_gl_context_ && channel_->share_group()) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context = channel_->share_group()->GetSharedContext();
453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!context.get()) {
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      context = gfx::GLContext::CreateGLContext(
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          channel_->share_group(),
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          channel_->gpu_channel_manager()->GetDefaultOffscreenSurface(),
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gpu_preference_);
458868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      channel_->share_group()->SetSharedContext(context.get());
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This should be a non-virtual GL context.
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(context->GetHandle());
462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    context = new gpu::GLContextVirtual(
463868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        channel_->share_group(), context.get(), decoder_->AsWeakPtr());
464868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!context->Initialize(surface_.get(), gpu_preference_)) {
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // TODO(sievers): The real context created above for the default
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // offscreen surface might not be compatible with this surface.
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Need to adjust at least GLX to be able to create the initial context
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // with a config that is compatible with onscreen and offscreen surfaces.
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      context = NULL;
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DLOG(ERROR) << "Failed to initialize virtual GL context.";
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      OnInitializeFailed(reply_message);
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!context.get()) {
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    context = gfx::GLContext::CreateGLContext(
478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        channel_->share_group(), surface_.get(), gpu_preference_);
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!context.get()) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "Failed to create context.\n";
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnInitializeFailed(reply_message);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!context->MakeCurrent(surface_.get())) {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to make context current.";
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnInitializeFailed(reply_message);
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (!context->GetGLStateRestorer()) {
493a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    context->SetGLStateRestorer(
494a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        new gpu::GLStateRestorerImpl(decoder_->AsWeakPtr()));
495a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
496a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!context->GetTotalGpuMemory(&total_gpu_memory_))
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    total_gpu_memory_ = 0;
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!context_group_->has_program_cache()) {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    context_group_->set_program_cache(
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        channel_->gpu_channel_manager()->program_cache());
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initialize the decoder with either the view or pbuffer GLContext.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!decoder_->Initialize(surface_,
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            context,
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            !surface_id(),
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            initial_size_,
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            disallowed_features_,
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            requested_attribs_)) {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "Failed to initialize decoder.";
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnInitializeFailed(reply_message);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  gpu_control_.reset(
518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      new gpu::GpuControlService(context_group_->image_manager(),
519a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 NULL,
520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 context_group_->mailbox_manager(),
521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 NULL,
522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                 decoder_->GetCapabilities()));
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kEnableGPUServiceLogging)) {
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    decoder_->set_log_commands(true);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  decoder_->GetLogger()->SetMsgCallback(
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GpuCommandBufferStub::SendConsoleMessage,
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this)));
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder_->SetShaderCacheCallback(
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&GpuCommandBufferStub::SendCachedShader,
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)));
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  decoder_->SetWaitSyncPointCallback(
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint,
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(this)));
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_buffer_->SetPutOffsetChangeCallback(
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this)));
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_buffer_->SetGetBufferChangeCallback(
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&gpu::GpuScheduler::SetGetBuffer,
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(scheduler_.get())));
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_buffer_->SetParseErrorCallback(
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this)));
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_->SetSchedulingChangedCallback(
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&GpuChannel::StubSchedulingChanged,
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(channel_)));
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (watchdog_) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scheduler_->SetCommandProcessedCallback(
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&GpuCommandBufferStub::OnCommandProcessed,
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!command_buffer_->SetSharedStateBuffer(shared_state_shm.Pass())) {
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DLOG(ERROR) << "Failed to map shared stae buffer.";
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    OnInitializeFailed(reply_message);
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  GpuCommandBufferMsg_Initialize::WriteReplyParams(
563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      reply_message, true, gpu_control_->GetCapabilities());
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_message);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (handle_.is_null() && !active_url_.is_empty()) {
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gpu_channel_manager->Send(new GpuHostMsg_DidCreateOffscreenContext(
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        active_url_));
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuCommandBufferStub::OnSetLatencyInfo(
57490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const ui::LatencyInfo& latency_info) {
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!latency_info_callback_.is_null())
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    latency_info_callback_.Run(latency_info);
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuCommandBufferStub::SetLatencyInfoCallback(
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const LatencyInfoCallback& callback) {
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  latency_info_callback_ = callback;
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int32 GpuCommandBufferStub::GetRequestedAttribute(int attr) const {
585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The command buffer is pairs of enum, value
586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // search for the requested attribute, return the value.
587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (std::vector<int32>::const_iterator it = requested_attribs_.begin();
588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)       it != requested_attribs_.end(); ++it) {
589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (*it++ == attr) {
590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return *it;
591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return -1;
594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::OnSetGetBuffer(int32 shm_id,
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          IPC::Message* reply_message) {
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer");
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (command_buffer_)
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_buffer_->SetGetBuffer(shm_id);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_message);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GpuCommandBufferStub::OnProduceFrontBuffer(const gpu::Mailbox& mailbox) {
605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnProduceFrontBuffer");
606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!decoder_)
607868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    LOG(ERROR) << "Can't produce front buffer before initialization.";
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
609868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!decoder_->ProduceFrontBuffer(mailbox))
610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    LOG(ERROR) << "Failed to produce front buffer.";
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnGetState(IPC::Message* reply_message) {
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetState");
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (command_buffer_) {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpu::CommandBuffer::State state = command_buffer_->GetState();
6177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    CheckContextLost();
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuCommandBufferMsg_GetState::WriteReplyParams(reply_message, state);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "no command_buffer.";
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reply_message->set_reply_error();
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_message);
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnParseError() {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnParseError");
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(command_buffer_.get());
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu::CommandBuffer::State state = command_buffer_->GetState();
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Message* msg = new GpuCommandBufferMsg_Destroyed(
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      route_id_, state.context_lost_reason);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  msg->set_unblock(true);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(msg);
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tell the browser about this context loss as well, so it can
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // determine whether client APIs like WebGL need to be immediately
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // blocked from automatically running.
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager();
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gpu_channel_manager->Send(new GpuHostMsg_DidLoseContext(
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      handle_.is_null(), state.context_lost_reason, active_url_));
6417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CheckContextLost();
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnGetStateFast(IPC::Message* reply_message) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetStateFast");
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(command_buffer_.get());
6487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CheckContextLost();
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu::CommandBuffer::State state = command_buffer_->GetState();
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuCommandBufferMsg_GetStateFast::WriteReplyParams(reply_message, state);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_message);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset,
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        uint32 flush_count) {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT1("gpu", "GpuCommandBufferStub::OnAsyncFlush",
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "put_offset", put_offset);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(command_buffer_.get());
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (flush_count - last_flush_count_ < 0x8000000U) {
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_flush_count_ = flush_count;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_buffer_->Flush(put_offset);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We received this message out-of-order. This should not happen but is here
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to catch regressions. Ignore the message.
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Received a Flush message out-of-order";
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReportState();
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnRescheduled() {
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState();
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command_buffer_->Flush(pre_state.put_offset);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu::CommandBuffer::State post_state = command_buffer_->GetLastState();
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pre_state.get_offset != post_state.get_offset)
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ReportState();
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnRegisterTransferBuffer(
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int32 id,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SharedMemoryHandle transfer_buffer,
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32 size) {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterTransferBuffer");
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SharedMemory shared_memory(transfer_buffer, false);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (command_buffer_)
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_buffer_->RegisterTransferBuffer(id, &shared_memory, size);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::OnDestroyTransferBuffer(int32 id) {
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyTransferBuffer");
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (command_buffer_)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_buffer_->DestroyTransferBuffer(id);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnGetTransferBuffer(
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 id,
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::Message* reply_message) {
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetTransferBuffer");
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (command_buffer_) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle();
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 size = 0;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (buffer.shared_memory) {
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transfer_buffer = NULL;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrokerDuplicateHandle(buffer.shared_memory->handle(),
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          channel_->renderer_pid(), &transfer_buffer, FILE_MAP_READ |
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FILE_MAP_WRITE, 0);
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(transfer_buffer != NULL);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer.shared_memory->ShareToProcess(channel_->renderer_pid(),
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           &transfer_buffer);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size = buffer.size;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GpuCommandBufferMsg_GetTransferBuffer::WriteReplyParams(reply_message,
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            transfer_buffer,
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                            size);
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reply_message->set_reply_error();
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(reply_message);
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnCommandProcessed() {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (watchdog_)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    watchdog_->CheckArmed();
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::ReportState() {
7367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!CheckContextLost())
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_buffer_->UpdateState();
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::PutChanged() {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FastSetActiveURL(active_url_, active_url_hash_);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scheduler_->PutChanged();
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnCreateVideoDecoder(
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    media::VideoCodecProfile profile,
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::Message* reply_message) {
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoDecoder");
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int decoder_route_id = channel_->GenerateRouteID();
75058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  GpuVideoDecodeAccelerator* decoder = new GpuVideoDecodeAccelerator(
75158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      decoder_route_id, this, channel_->io_message_loop());
75258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  decoder->Initialize(profile, reply_message);
753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // decoder is registered as a DestructionObserver of this stub and will
754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // self-delete during destruction of this stub.
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) {
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSurfaceVisible");
759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (memory_manager_client_state_)
7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memory_manager_client_state_->SetVisible(visible);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnDiscardBackbuffer() {
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDiscardBackbuffer");
765868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!surface_.get())
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (surface_->DeferDraws()) {
7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!IsScheduled());
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    channel_->RequeueMessage();
7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!surface_->SetBackbufferAllocation(false))
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      channel_->DestroySoon();
7732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnEnsureBackbuffer() {
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEnsureBackbuffer");
778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!surface_.get())
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (surface_->DeferDraws()) {
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!IsScheduled());
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    channel_->RequeueMessage();
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!surface_->SetBackbufferAllocation(true))
7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      channel_->DestroySoon();
7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::AddSyncPoint(uint32 sync_point) {
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_points_.push_back(sync_point);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sync_points_.pop_front();
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuChannelManager* manager = channel_->gpu_channel_manager();
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager->sync_point_manager()->RetireSyncPoint(sync_point);
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) {
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sync_point_wait_count_ == 0) {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this,
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             "GpuCommandBufferStub", this);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_->SetScheduled(false);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++sync_point_wait_count_;
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuChannelManager* manager = channel_->gpu_channel_manager();
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager->sync_point_manager()->AddSyncPointCallback(
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_point,
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GpuCommandBufferStub::OnSyncPointRetired,
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 this->AsWeakPtr()));
8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scheduler_->IsScheduled();
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSyncPointRetired() {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  --sync_point_wait_count_;
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sync_point_wait_count_ == 0) {
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this,
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           "GpuCommandBufferStub", this);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler_->SetScheduled(true);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSignalSyncPoint(uint32 sync_point, uint32 id) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GpuChannelManager* manager = channel_->gpu_channel_manager();
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manager->sync_point_manager()->AddSyncPointCallback(
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sync_point,
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck,
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 this->AsWeakPtr(),
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 id));
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSignalSyncPointAck(uint32 id) {
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(new GpuCommandBufferMsg_SignalSyncPointAck(route_id_, id));
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
837eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid GpuCommandBufferStub::OnSignalQuery(uint32 query_id, uint32 id) {
838eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (decoder_) {
839eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    gpu::gles2::QueryManager* query_manager = decoder_->GetQueryManager();
840eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (query_manager) {
841eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      gpu::gles2::QueryManager::Query* query =
842eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          query_manager->GetQuery(query_id);
843eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      if (query) {
844eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        query->AddCallback(
845eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck,
846eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     this->AsWeakPtr(),
847eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                     id));
848eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        return;
849eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      }
850eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
851eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
852eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Something went wrong, run callback immediately.
853eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  OnSignalSyncPointAck(id);
854eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
855eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnReceivedClientManagedMemoryStats(
8581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const gpu::ManagedMemoryStats& stats) {
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0(
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "gpu",
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GpuCommandBufferStub::OnReceivedClientManagedMemoryStats");
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (memory_manager_client_state_)
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memory_manager_client_state_->SetManagedMemoryStats(stats);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback(
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool has_callback) {
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0(
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "gpu",
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback");
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_callback) {
872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!memory_manager_client_state_) {
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      memory_manager_client_state_.reset(GetMemoryManager()->CreateClientState(
8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this, surface_id_ != 0, true));
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memory_manager_client_state_.reset();
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void GpuCommandBufferStub::OnRegisterGpuMemoryBuffer(
8821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    int32 id,
8831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::GpuMemoryBufferHandle gpu_memory_buffer,
8841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    uint32 width,
8851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    uint32 height,
8861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    uint32 internalformat) {
8871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterGpuMemoryBuffer");
8881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (gpu_control_) {
8891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gpu_control_->RegisterGpuMemoryBuffer(id,
8901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          gpu_memory_buffer,
8911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          width,
8921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          height,
8931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                          internalformat);
8941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
8951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
8961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
8971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void GpuCommandBufferStub::OnDestroyGpuMemoryBuffer(int32 id) {
8981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyGpuMemoryBuffer");
8991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (gpu_control_)
9001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gpu_control_->DestroyGpuMemoryBuffer(id);
9011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
9021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::SendConsoleMessage(
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 id,
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& message) {
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GPUCommandBufferConsoleMessage console_message;
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  console_message.id = id;
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  console_message.message = message;
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Message* msg = new GpuCommandBufferMsg_ConsoleMsg(
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      route_id_, console_message);
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  msg->set_unblock(true);
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Send(msg);
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::SendCachedShader(
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& key, const std::string& shader) {
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  channel_->CacheShader(key, shader);
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::AddDestructionObserver(
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DestructionObserver* observer) {
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destruction_observers_.AddObserver(observer);
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::RemoveDestructionObserver(
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DestructionObserver* observer) {
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  destruction_observers_.RemoveObserver(observer);
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::SetPreemptByFlag(
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<gpu::PreemptionFlag> flag) {
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  preemption_flag_ = flag;
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (scheduler_)
9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scheduler_->SetPreemptByFlag(preemption_flag_);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuCommandBufferStub::GetTotalGpuMemory(uint64* bytes) {
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *bytes = total_gpu_memory_;
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !!total_gpu_memory_;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size GpuCommandBufferStub::GetSurfaceSize() const {
943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!surface_.get())
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return gfx::Size();
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return surface_->GetSize();
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gpu::gles2::MemoryTracker* GpuCommandBufferStub::GetMemoryTracker() const {
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return context_group_->memory_tracker();
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::SetMemoryAllocation(
9531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    const gpu::MemoryAllocation& allocation) {
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!last_memory_allocation_valid_ ||
9551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      !allocation.Equals(last_memory_allocation_)) {
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Send(new GpuCommandBufferMsg_SetMemoryAllocation(
9571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        route_id_, allocation));
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  last_memory_allocation_valid_ = true;
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  last_memory_allocation_ = allocation;
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void GpuCommandBufferStub::SuggestHaveFrontBuffer(
9651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    bool suggest_have_frontbuffer) {
9661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // This can be called outside of OnMessageReceived, so the context needs
9671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // to be made current before calling methods on the surface.
9681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (surface_.get() && MakeCurrent())
9691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    surface_->SetFrontbufferAllocation(suggest_have_frontbuffer);
9701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
9711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
9727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool GpuCommandBufferStub::CheckContextLost() {
9737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(command_buffer_);
9747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  gpu::CommandBuffer::State state = command_buffer_->GetState();
9757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool was_lost = state.error == gpu::error::kLostContext;
9767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Lose all other contexts if the reset was triggered by the robustness
9777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // extension instead of being synthetic.
9787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (was_lost && decoder_ && decoder_->WasContextLostByRobustnessExtension() &&
9797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      (gfx::GLContext::LosesAllContextsOnContextLost() ||
9807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       use_virtualized_gl_context_))
9817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    channel_->LoseAllContexts();
9827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return was_lost;
9837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
9847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
9857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid GpuCommandBufferStub::MarkContextLost() {
9867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!command_buffer_ ||
9877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      command_buffer_->GetState().error == gpu::error::kLostContext)
9887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
9897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
9907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  command_buffer_->SetContextLostReason(gpu::error::kUnknown);
9917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (decoder_)
9927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    decoder_->LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  command_buffer_->SetParseError(gpu::error::kLostContext);
9947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
9957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
996a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)uint64 GpuCommandBufferStub::GetMemoryUsage() const {
997a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return GetMemoryManager()->GetClientMemoryUsage(this);
998a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
999a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1001