gpu_command_buffer_stub.cc revision a93a17c8d99d686bd4a1511e5504e5e6cc9fcadf
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" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/shared_memory.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/time.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel_manager.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_command_buffer_stub.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_memory_manager.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_memory_tracking.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_watchdog.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/image_transport_surface.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/media/gpu_video_decode_accelerator.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/sync_point_manager.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_client.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_switches.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/constants.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/gl_context_virtual.h" 28a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "gpu/command_buffer/service/gl_state_restorer_impl.h" 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/command_buffer/service/logger.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/memory_tracking.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/sandbox_init.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/stream_texture_manager_android.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The GpuCommandBufferMemoryTracker class provides a bridge between the 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ContextGroup's memory type managers and the GpuMemoryManager class. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GpuCommandBufferMemoryTracker : public gpu::gles2::MemoryTracker { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit GpuCommandBufferMemoryTracker(GpuChannel* channel) : 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracking_group_(channel->gpu_channel_manager()->gpu_memory_manager()-> 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateTrackingGroup(channel->renderer_pid(), this)) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void TrackMemoryAllocatedChange( 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t old_size, 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t new_size, 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu::gles2::MemoryTracker::Pool pool) OVERRIDE { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracking_group_->TrackMemoryAllocatedChange( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_size, new_size, pool); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool EnsureGPUMemoryAvailable(size_t size_needed) OVERRIDE { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tracking_group_->EnsureGPUMemoryAvailable(size_needed); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~GpuCommandBufferMemoryTracker() { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<GpuMemoryTrackingGroup> tracking_group_; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FastSetActiveURL will shortcut the expensive call to SetActiveURL when the 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// url_hash matches. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FastSetActiveURL(const GURL& url, size_t url_hash) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Leave the previously set URL in the empty case -- empty URLs are given by 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebKitPlatformSupportImpl::createOffscreenGraphicsContext3D. Hopefully the 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // onscreen context URL was set previously and will show up even when a crash 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurs during offscreen command processing. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.is_empty()) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static size_t g_last_url_hash = 0; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_hash != g_last_url_hash) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_last_url_hash = url_hash; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetContentClient()->SetActiveURL(url); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The first time polling a fence, delay some extra time to allow other 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stubs to process some work, or else the timing of the fences could 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// allow a pattern of alternating fast and slow frames to occur. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kHandleMoreWorkPeriodMs = 2; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kHandleMoreWorkPeriodBusyMs = 1; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Prevents idle work from being starved. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kMaxTimeSinceIdleMs = 10; 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuCommandBufferStub::GpuCommandBufferStub( 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannel* channel, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferStub* share_group, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::GLSurfaceHandle& handle, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::gles2::MailboxManager* mailbox_manager, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::gles2::ImageManager* image_manager, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gpu::gles2::DisallowedFeatures& disallowed_features, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& allowed_extensions, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int32>& attribs, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference, 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool use_virtualized_gl_context, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 route_id, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 surface_id, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuWatchdog* watchdog, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool software, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& active_url) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : channel_(channel), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_(handle), 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_size_(size), 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disallowed_features_(disallowed_features), 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allowed_extensions_(allowed_extensions), 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requested_attribs_(attribs), 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_preference_(gpu_preference), 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) use_virtualized_gl_context_(use_virtualized_gl_context), 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id_(route_id), 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_id_(surface_id), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) software_(software), 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_flush_count_(0), 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_memory_allocation_valid_(false), 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_stub_for_initialization_(), 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_texture_for_initialization_(0), 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 { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_group_ = new gpu::gles2::ContextGroup( 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mailbox_manager, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_manager, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new GpuCommandBufferMemoryTracker(channel), 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuCommandBufferStub::~GpuCommandBufferStub() { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer(surface_id())); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuMemoryManager* GpuCommandBufferStub::GetMemoryManager() { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel()->gpu_channel_manager()->gpu_memory_manager(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FastSetActiveURL(active_url_, active_url_hash_); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the appropriate GL context is current before handling any IPC 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages directed at the command buffer. This ensures that the message 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // handler can assume that the context is current (not necessary for 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Echo, RetireSyncPoint, or WaitSyncPoint). 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_.get() && 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.type() != GpuCommandBufferMsg_Echo::ID && 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID && 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message.type() != GpuCommandBufferMsg_SetLatencyInfo::ID) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!MakeCurrent()) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here. This is so the reply can be delayed if the scheduler is unscheduled. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitialize); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSetGetBuffer); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetParent, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSetParent); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Echo, OnEcho); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetStateFast, 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnGetStateFast); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush); 193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetLatencyInfo, OnSetLatencyInfo); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Rescheduled, OnRescheduled); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer, 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnRegisterTransferBuffer); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer, 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnDestroyTransferBuffer); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetTransferBuffer, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnGetTransferBuffer); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder, 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCreateVideoDecoder) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetSurfaceVisible, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSetSurfaceVisible) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DiscardBackbuffer, 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnDiscardBackbuffer) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_EnsureBackbuffer, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnEnsureBackbuffer) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RetireSyncPoint, 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnRetireSyncPoint) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncPoint, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSignalSyncPoint) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SendClientManagedMemoryStats, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnReceivedClientManagedMemoryStats) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER( 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_SetClientHasMemoryAllocationChangedCallback, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSetClientHasMemoryAllocationChangedCallback) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that any delayed work that was created will be handled. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleDelayedWork(kHandleMoreWorkPeriodMs); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(handled); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::Send(IPC::Message* message) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_->Send(message); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::IsScheduled() { 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (!scheduler_.get() || scheduler_->IsScheduled()); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::HasMoreWork() { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scheduler_.get() && scheduler_->HasMoreWork(); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::PollWork() { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::PollWork"); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_work_scheduled_ = false; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FastSetActiveURL(active_url_, active_url_hash_); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_.get() && !MakeCurrent()) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (scheduler_) { 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fences_complete = scheduler_->PollUnscheduleFences(); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Perform idle work if all fences are complete. 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fences_complete) { 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 current_messages_processed = 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel()->gpu_channel_manager()->MessagesProcessed(); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We're idle when no messages were processed or scheduled. 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_idle = 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (previous_messages_processed_ == current_messages_processed) && 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !channel()->gpu_channel_manager()->HandleMessagesScheduled(); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_idle && !last_idle_time_.is_null()) { 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta time_since_idle = base::TimeTicks::Now() - 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_idle_time_; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta max_time_since_idle = 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Force idle when it's been too long since last time we were idle. 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (time_since_idle > max_time_since_idle) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_idle = true; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_idle) { 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_idle_time_ = base::TimeTicks::Now(); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->PerformIdleWork(); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::HasUnprocessedCommands() { 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_buffer_) { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State state = command_buffer_->GetLastState(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state.put_offset != state.get_offset && 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !gpu::error::IsError(state.error); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!HasMoreWork()) { 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_idle_time_ = base::TimeTicks(); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delayed_work_scheduled_) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delayed_work_scheduled_ = true; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Idle when no messages are processed between now and when 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // PollWork is called. 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_messages_processed_ = 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel()->gpu_channel_manager()->MessagesProcessed(); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (last_idle_time_.is_null()) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_idle_time_ = base::TimeTicks::Now(); 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // IsScheduled() returns true after passing all unschedule fences 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and this is when we can start performing idle work. Idle work 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is done synchronously so we can set delay to 0 and instead poll 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for more work at the rate idle work is performed. This also ensures 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that idle work is done as efficiently as possible without any 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // unnecessary delays. 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (scheduler_.get() && 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->IsScheduled() && 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->HasMoreIdleWork()) { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delay = 0; 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(delay)); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnEcho(const IPC::Message& message) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEcho"); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new IPC::Message(message)); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::MakeCurrent() { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_->MakeCurrent()) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Context lost because MakeCurrent failed."; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetParseError(gpu::error::kLostContext); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gfx::GLContext::LosesAllContextsOnContextLost()) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->LoseAllContexts(); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::Destroy() { 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (handle_.is_null() && !active_url_.is_empty()) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_channel_manager->Send(new GpuHostMsg_DidDestroyOffscreenContext( 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) active_url_)); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_manager_client_state_.reset(); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!sync_points_.empty()) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnRetireSyncPoint(sync_points_.front()); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (decoder_) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoder_->set_engine(NULL); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The scheduler has raw references to the decoder and the command buffer so 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroy it before those. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_.reset(); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool have_context = false; 357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (decoder_) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) have_context = decoder_->MakeCurrent(); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(DestructionObserver, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destruction_observers_, 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnWillDestroyStub()); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<gfx::GLContext> context; 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (decoder_) { 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = decoder_->GetGLContext(); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->Destroy(have_context); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.reset(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_.reset(); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure that context_ is current while we destroy surface_, because 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // surface_ may have GL resources that it needs to destroy, and will need 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // context_ to be current in order to not leak these resources. 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context->MakeCurrent(surface_.get()); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_ = NULL; 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (context) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context->ReleaseCurrent(NULL); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, false); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnInitialize( 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemoryHandle shared_state_handle, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* reply_message) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnInitialize"); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!command_buffer_.get()); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::SharedMemory> shared_state_shm( 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new base::SharedMemory(shared_state_handle, false)); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_.reset(new gpu::CommandBufferService( 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_group_->transfer_buffer_manager())); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!command_buffer_->Initialize()) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "CommandBufferService failed to initialize.\n"; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get())); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.get(), 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.get())); 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (preemption_flag_) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetPreemptByFlag(preemption_flag_); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->set_engine(scheduler_.get()); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handle_.is_null()) { 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (software_) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "No software support.\n"; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_ = ImageTransportSurface::CreateSurface( 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->gpu_channel_manager(), 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* manager = channel_->gpu_channel_manager(); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_ = manager->GetDefaultOffscreenSurface(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!surface_) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Failed to create surface.\n"; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<gfx::GLContext> context; 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((CommandLine::ForCurrentProcess()->HasSwitch( 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switches::kEnableVirtualGLContexts) || use_virtualized_gl_context_) && 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) channel_->share_group()) { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = channel_->share_group()->GetSharedContext(); 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context) { 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = gfx::GLContext::CreateGLContext( 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->share_group(), 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->gpu_channel_manager()->GetDefaultOffscreenSurface(), 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_preference_); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->share_group()->SetSharedContext(context); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should be a non-virtual GL context. 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(context->GetHandle()); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = new gpu::GLContextVirtual(channel_->share_group(), 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context, 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoder_->AsWeakPtr()); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context->Initialize(surface_, gpu_preference_)) { 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(sievers): The real context created above for the default 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // offscreen surface might not be compatible with this surface. 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Need to adjust at least GLX to be able to create the initial context 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // with a config that is compatible with onscreen and offscreen surfaces. 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = NULL; 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Failed to initialize virtual GL context."; 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnInitializeFailed(reply_message); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(INFO) << "Created virtual GL context."; 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context) { 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = gfx::GLContext::CreateGLContext( 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->share_group(), 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) surface_.get(), 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_preference_); 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Failed to create context.\n"; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!context->MakeCurrent(surface_)) { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to make context current."; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 489a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!context->GetGLStateRestorer()) { 490a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) context->SetGLStateRestorer( 491a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) new gpu::GLStateRestorerImpl(decoder_->AsWeakPtr())); 492a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 493a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context->GetTotalGpuMemory(&total_gpu_memory_)) 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_gpu_memory_ = 0; 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!context_group_->has_program_cache()) { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_group_->set_program_cache( 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->gpu_channel_manager()->program_cache()); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the decoder with either the view or pbuffer GLContext. 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!decoder_->Initialize(surface_, 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context, 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !surface_id(), 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_size_, 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disallowed_features_, 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allowed_extensions_.c_str(), 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requested_attribs_)) { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Failed to initialize decoder."; 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kEnableGPUServiceLogging)) { 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->set_log_commands(true); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) decoder_->GetLogger()->SetMsgCallback( 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::SendConsoleMessage, 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoder_->SetShaderCacheCallback( 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GpuCommandBufferStub::SendCachedShader, 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoder_->SetWaitSyncPointCallback( 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint, 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetPutOffsetChangeCallback( 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this))); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetGetBufferChangeCallback( 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&gpu::GpuScheduler::SetGetBuffer, 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(scheduler_.get()))); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetParseErrorCallback( 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this))); 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetSchedulingChangedCallback( 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GpuChannel::StubSchedulingChanged, 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(channel_))); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (watchdog_) { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->SetCommandProcessedCallback( 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnCommandProcessed, 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->SetStreamTextureManager(channel_->stream_texture_manager()); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent_stub_for_initialization_) { 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(), 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_texture_for_initialization_); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_stub_for_initialization_.reset(); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_texture_for_initialization_ = 0; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!command_buffer_->SetSharedStateBuffer(shared_state_shm.Pass())) { 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Failed to map shared stae buffer."; 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnInitializeFailed(reply_message); 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, true); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (handle_.is_null() && !active_url_.is_empty()) { 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_channel_manager->Send(new GpuHostMsg_DidCreateOffscreenContext( 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) active_url_)); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuCommandBufferStub::OnSetLatencyInfo( 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const cc::LatencyInfo& latency_info) { 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!latency_info_callback_.is_null()) 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) latency_info_callback_.Run(latency_info); 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuCommandBufferStub::SetLatencyInfoCallback( 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const LatencyInfoCallback& callback) { 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) latency_info_callback_ = callback; 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::OnSetGetBuffer(int32 shm_id, 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Message* reply_message) { 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer"); 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_buffer_) 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_buffer_->SetGetBuffer(shm_id); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSetParent(int32 parent_route_id, 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 parent_texture_id, 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* reply_message) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetParent"); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferStub* parent_stub = NULL; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent_route_id != MSG_ROUTING_NONE) { 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_stub = channel_->LookupCommandBuffer(parent_route_id); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = true; 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (scheduler_) { 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::gles2::GLES2Decoder* parent_decoder = 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_stub ? parent_stub->decoder_.get() : NULL; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = decoder_->SetParent(parent_decoder, parent_texture_id); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we don't have a scheduler, it means that Initialize hasn't been called 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // yet. Keep around the requested parent stub and texture so that we can set 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it in Initialize(). 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_stub_for_initialization_ = parent_stub ? 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_stub->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>(); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent_texture_for_initialization_ = parent_texture_id; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_SetParent::WriteReplyParams(reply_message, result); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnGetState(IPC::Message* reply_message) { 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetState"); 621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_buffer_) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State state = command_buffer_->GetState(); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state.error == gpu::error::kLostContext && 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GLContext::LosesAllContextsOnContextLost()) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->LoseAllContexts(); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_GetState::WriteReplyParams(reply_message, state); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "no command_buffer."; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_message->set_reply_error(); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnParseError() { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnParseError"); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(command_buffer_.get()); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State state = command_buffer_->GetState(); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* msg = new GpuCommandBufferMsg_Destroyed( 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id_, state.context_lost_reason); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->set_unblock(true); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(msg); 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Tell the browser about this context loss as well, so it can 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // determine whether client APIs like WebGL need to be immediately 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // blocked from automatically running. 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_channel_manager->Send(new GpuHostMsg_DidLoseContext( 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handle_.is_null(), state.context_lost_reason, active_url_)); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnGetStateFast(IPC::Message* reply_message) { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetStateFast"); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(command_buffer_.get()); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State state = command_buffer_->GetState(); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state.error == gpu::error::kLostContext && 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GLContext::LosesAllContextsOnContextLost()) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->LoseAllContexts(); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_GetStateFast::WriteReplyParams(reply_message, state); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset, 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 flush_count) { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT1("gpu", "GpuCommandBufferStub::OnAsyncFlush", 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "put_offset", put_offset); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(command_buffer_.get()); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flush_count - last_flush_count_ < 0x8000000U) { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_flush_count_ = flush_count; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->Flush(put_offset); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We received this message out-of-order. This should not happen but is here 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to catch regressions. Ignore the message. 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Received a Flush message out-of-order"; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportState(); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnRescheduled() { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState(); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->Flush(pre_state.put_offset); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State post_state = command_buffer_->GetLastState(); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pre_state.get_offset != post_state.get_offset) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportState(); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnRegisterTransferBuffer( 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 id, 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle transfer_buffer, 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 size) { 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterTransferBuffer"); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemory shared_memory(transfer_buffer, false); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_buffer_) 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_buffer_->RegisterTransferBuffer(id, &shared_memory, size); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::OnDestroyTransferBuffer(int32 id) { 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyTransferBuffer"); 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_buffer_) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->DestroyTransferBuffer(id); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnGetTransferBuffer( 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 id, 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* reply_message) { 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnGetTransferBuffer"); 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_buffer_) { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle(); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 size = 0; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer.shared_memory) { 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_buffer = NULL; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrokerDuplicateHandle(buffer.shared_memory->handle(), 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->renderer_pid(), &transfer_buffer, FILE_MAP_READ | 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_MAP_WRITE, 0); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(transfer_buffer != NULL); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.shared_memory->ShareToProcess(channel_->renderer_pid(), 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &transfer_buffer); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = buffer.size; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_GetTransferBuffer::WriteReplyParams(reply_message, 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_buffer, 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_message->set_reply_error(); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnCommandProcessed() { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (watchdog_) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) watchdog_->CheckArmed(); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::ReportState() { 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State state = command_buffer_->GetState(); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (state.error == gpu::error::kLostContext && 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GLContext::LosesAllContextsOnContextLost()) { 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->LoseAllContexts(); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->UpdateState(); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::PutChanged() { 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FastSetActiveURL(active_url_, active_url_hash_); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->PutChanged(); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnCreateVideoDecoder( 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoCodecProfile profile, 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* reply_message) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoDecoder"); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int decoder_route_id = channel_->GenerateRouteID(); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuVideoDecodeAccelerator* decoder = 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new GpuVideoDecodeAccelerator(decoder_route_id, this); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder->Initialize(profile, reply_message); 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // decoder is registered as a DestructionObserver of this stub and will 769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // self-delete during destruction of this stub. 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) { 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSurfaceVisible"); 774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (memory_manager_client_state_) 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_manager_client_state_->SetVisible(visible); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnDiscardBackbuffer() { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDiscardBackbuffer"); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!surface_) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (surface_->DeferDraws()) { 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!IsScheduled()); 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->RequeueMessage(); 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!surface_->SetBackbufferAllocation(false)) 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->DestroySoon(); 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnEnsureBackbuffer() { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEnsureBackbuffer"); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!surface_) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (surface_->DeferDraws()) { 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!IsScheduled()); 7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->RequeueMessage(); 7982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!surface_->SetBackbufferAllocation(true)) 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->DestroySoon(); 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::AddSyncPoint(uint32 sync_point) { 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_points_.push_back(sync_point); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) { 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_points_.pop_front(); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* manager = channel_->gpu_channel_manager(); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->sync_point_manager()->RetireSyncPoint(sync_point); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sync_point_wait_count_ == 0) { 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this, 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuCommandBufferStub", this); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetScheduled(false); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++sync_point_wait_count_; 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* manager = channel_->gpu_channel_manager(); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->sync_point_manager()->AddSyncPointCallback( 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_point, 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnSyncPointRetired, 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->AsWeakPtr())); 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scheduler_->IsScheduled(); 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSyncPointRetired() { 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --sync_point_wait_count_; 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sync_point_wait_count_ == 0) { 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this, 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuCommandBufferStub", this); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetScheduled(true); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSignalSyncPoint(uint32 sync_point, uint32 id) { 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* manager = channel_->gpu_channel_manager(); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->sync_point_manager()->AddSyncPointCallback( 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_point, 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck, 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->AsWeakPtr(), 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id)); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSignalSyncPointAck(uint32 id) { 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new GpuCommandBufferMsg_SignalSyncPointAck(route_id_, id)); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnReceivedClientManagedMemoryStats( 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GpuManagedMemoryStats& stats) { 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0( 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "gpu", 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuCommandBufferStub::OnReceivedClientManagedMemoryStats"); 857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (memory_manager_client_state_) 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_manager_client_state_->SetManagedMemoryStats(stats); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback( 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_callback) { 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0( 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "gpu", 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback"); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_callback) { 867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!memory_manager_client_state_) { 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_manager_client_state_.reset(GetMemoryManager()->CreateClientState( 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, surface_id_ != 0, true)); 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_manager_client_state_.reset(); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::SendConsoleMessage( 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 id, 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& message) { 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GPUCommandBufferConsoleMessage console_message; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) console_message.id = id; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) console_message.message = message; 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* msg = new GpuCommandBufferMsg_ConsoleMsg( 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id_, console_message); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->set_unblock(true); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(msg); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::SendCachedShader( 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& key, const std::string& shader) { 8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->CacheShader(key, shader); 8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::AddDestructionObserver( 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestructionObserver* observer) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destruction_observers_.AddObserver(observer); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::RemoveDestructionObserver( 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestructionObserver* observer) { 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destruction_observers_.RemoveObserver(observer); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::SetPreemptByFlag( 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<gpu::PreemptionFlag> flag) { 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_flag_ = flag; 906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (scheduler_) 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetPreemptByFlag(preemption_flag_); 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuCommandBufferStub::GetTotalGpuMemory(uint64* bytes) { 9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *bytes = total_gpu_memory_; 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !!total_gpu_memory_; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size GpuCommandBufferStub::GetSurfaceSize() const { 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!surface_) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return surface_->GetSize(); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gpu::gles2::MemoryTracker* GpuCommandBufferStub::GetMemoryTracker() const { 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context_group_->memory_tracker(); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::SetMemoryAllocation( 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GpuMemoryAllocation& allocation) { 9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!last_memory_allocation_valid_ || 9282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !allocation.renderer_allocation.Equals( 9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_memory_allocation_.renderer_allocation)) { 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send(new GpuCommandBufferMsg_SetMemoryAllocation( 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) route_id_, allocation.renderer_allocation)); 9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!last_memory_allocation_valid_ || 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !allocation.browser_allocation.Equals( 9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_memory_allocation_.browser_allocation)) { 9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This can be called outside of OnMessageReceived, so the context needs 9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be made current before calling methods on the surface. 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (surface_ && MakeCurrent()) 9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) surface_->SetFrontbufferAllocation( 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) allocation.browser_allocation.suggest_have_frontbuffer); 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_memory_allocation_valid_ = true; 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_memory_allocation_ = allocation; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 949