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" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/json/json_writer.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/gpu/devtools_gpu_instrumentation.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel_manager.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_command_buffer_stub.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/common/gpu/gpu_memory_buffer_factory.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_memory_manager.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_memory_tracking.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_watchdog.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/image_transport_surface.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/media/gpu_video_decode_accelerator.h" 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/common/gpu/media/gpu_video_encode_accelerator.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/sync_point_manager.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_client.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/constants.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h" 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h" 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/gl_context_virtual.h" 32a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "gpu/command_buffer/service/gl_state_restorer_impl.h" 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "gpu/command_buffer/service/image_manager.h" 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "gpu/command_buffer/service/logger.h" 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "gpu/command_buffer/service/mailbox_manager.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/memory_tracking.h" 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "gpu/command_buffer/service/query_manager.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_bindings.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_switches.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/sandbox_init.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID) 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/gpu/stream_texture_android.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochstruct WaitForCommandState { 51c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch WaitForCommandState(int32 start, int32 end, IPC::Message* reply) 52c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : start(start), end(end), reply(reply) {} 53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 start; 55c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 end; 56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_ptr<IPC::Message> reply; 57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The GpuCommandBufferMemoryTracker class provides a bridge between the 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ContextGroup's memory type managers and the GpuMemoryManager class. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GpuCommandBufferMemoryTracker : public gpu::gles2::MemoryTracker { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit GpuCommandBufferMemoryTracker(GpuChannel* channel) : 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracking_group_(channel->gpu_channel_manager()->gpu_memory_manager()-> 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateTrackingGroup(channel->renderer_pid(), this)) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void TrackMemoryAllocatedChange( 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t old_size, 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t new_size, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu::gles2::MemoryTracker::Pool pool) OVERRIDE { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tracking_group_->TrackMemoryAllocatedChange( 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) old_size, new_size, pool); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool EnsureGPUMemoryAvailable(size_t size_needed) OVERRIDE { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tracking_group_->EnsureGPUMemoryAvailable(size_needed); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~GpuCommandBufferMemoryTracker() { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<GpuMemoryTrackingGroup> tracking_group_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferMemoryTracker); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FastSetActiveURL will shortcut the expensive call to SetActiveURL when the 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// url_hash matches. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FastSetActiveURL(const GURL& url, size_t url_hash) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Leave the previously set URL in the empty case -- empty URLs are given by 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebKitPlatformSupportImpl::createOffscreenGraphicsContext3D. Hopefully the 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // onscreen context URL was set previously and will show up even when a crash 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occurs during offscreen command processing. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url.is_empty()) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static size_t g_last_url_hash = 0; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (url_hash != g_last_url_hash) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_last_url_hash = url_hash; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetContentClient()->SetActiveURL(url); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The first time polling a fence, delay some extra time to allow other 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stubs to process some work, or else the timing of the fences could 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// allow a pattern of alternating fast and slow frames to occur. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kHandleMoreWorkPeriodMs = 2; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kHandleMoreWorkPeriodBusyMs = 1; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Prevents idle work from being starved. 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kMaxTimeSinceIdleMs = 10; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class DevToolsChannelData : public base::debug::ConvertableToTraceFormat { 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public: 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static scoped_refptr<base::debug::ConvertableToTraceFormat> CreateForChannel( 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GpuChannel* channel); 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE { 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string tmp; 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::JSONWriter::Write(value_.get(), &tmp); 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *out += tmp; 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private: 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) explicit DevToolsChannelData(base::Value* value) : value_(value) {} 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual ~DevToolsChannelData() {} 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<base::Value> value_; 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DevToolsChannelData); 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_refptr<base::debug::ConvertableToTraceFormat> 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)DevToolsChannelData::CreateForChannel(GpuChannel* channel) { 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue); 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res->SetInteger("renderer_pid", channel->renderer_pid()); 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res->SetDouble("used_bytes", channel->GetMemoryUsage()); 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res->SetDouble("limit_bytes", 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel->gpu_channel_manager() 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->gpu_memory_manager() 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ->GetMaximumClientAllocation()); 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return new DevToolsChannelData(res.release()); 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuCommandBufferStub::GpuCommandBufferStub( 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannel* channel, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferStub* share_group, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::GLSurfaceHandle& handle, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::gles2::MailboxManager* mailbox_manager, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gpu::gles2::DisallowedFeatures& disallowed_features, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<int32>& attribs, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GpuPreference gpu_preference, 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool use_virtualized_gl_context, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 route_id, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 surface_id, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuWatchdog* watchdog, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool software, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& active_url) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : channel_(channel), 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_(handle), 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_size_(size), 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disallowed_features_(disallowed_features), 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requested_attribs_(attribs), 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_preference_(gpu_preference), 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) use_virtualized_gl_context_(use_virtualized_gl_context), 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id_(route_id), 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_id_(surface_id), 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) software_(software), 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_flush_count_(0), 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_memory_allocation_valid_(false), 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) watchdog_(watchdog), 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_point_wait_count_(0), 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_work_scheduled_(false), 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_messages_processed_(0), 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) active_url_(active_url), 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_gpu_memory_(0) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) active_url_hash_ = base::Hash(active_url.possibly_invalid_spec()); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FastSetActiveURL(active_url_, active_url_hash_); 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gpu::gles2::ContextCreationAttribHelper attrib_parser; 184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch attrib_parser.Parse(requested_attribs_); 185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (share_group) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_group_ = share_group->context_group_; 188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(context_group_->bind_generates_resource() == 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) attrib_parser.bind_generates_resource); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_group_ = new gpu::gles2::ContextGroup( 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mailbox_manager, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new GpuCommandBufferMemoryTracker(channel), 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch channel_->gpu_channel_manager()->shader_translator_cache(), 195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NULL, 1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) attrib_parser.bind_generates_resource); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) use_virtualized_gl_context_ |= 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) context_group_->feature_info()->workarounds().use_virtualized_gl_contexts; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuCommandBufferStub::~GpuCommandBufferStub() { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer(surface_id())); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GpuMemoryManager* GpuCommandBufferStub::GetMemoryManager() const { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel()->gpu_channel_manager()->gpu_memory_manager(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "GPUTask", 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "data", 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DevToolsChannelData::CreateForChannel(channel())); 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(yurys): remove devtools_gpu_instrumentation call once DevTools 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Timeline migrates to tracing crbug.com/361045. 221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch devtools_gpu_instrumentation::ScopedGpuTask task(channel()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FastSetActiveURL(active_url_, active_url_hash_); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 224010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool have_context = false; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure the appropriate GL context is current before handling any IPC 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // messages directed at the command buffer. This ensures that the message 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // handler can assume that the context is current (not necessary for 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Echo, RetireSyncPoint, or WaitSyncPoint). 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (decoder_.get() && message.type() != GpuCommandBufferMsg_Echo::ID && 230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch message.type() != GpuCommandBufferMsg_WaitForTokenInRange::ID && 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch message.type() != GpuCommandBufferMsg_WaitForGetOffsetInRange::ID && 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci message.type() != GpuCommandBufferMsg_RetireSyncPoint::ID) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!MakeCurrent()) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 235010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) have_context = true; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here. This is so the reply can be delayed if the scheduler is unscheduled. 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitialize); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSetGetBuffer); 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ProduceFrontBuffer, 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OnProduceFrontBuffer); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Echo, OnEcho); 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_WaitForTokenInRange, 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch OnWaitForTokenInRange); 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_WaitForGetOffsetInRange, 252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch OnWaitForGetOffsetInRange); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Rescheduled, OnRescheduled); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer, 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnRegisterTransferBuffer); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer, 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnDestroyTransferBuffer); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoDecoder, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCreateVideoDecoder) 261c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_CreateVideoEncoder, 262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch OnCreateVideoEncoder) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetSurfaceVisible, 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSetSurfaceVisible) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RetireSyncPoint, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnRetireSyncPoint) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalSyncPoint, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSignalSyncPoint) 269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalQuery, 270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OnSignalQuery) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER( 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_SetClientHasMemoryAllocationChangedCallback, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSetClientHasMemoryAllocationChangedCallback) 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterGpuMemoryBuffer, 2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OnRegisterGpuMemoryBuffer); 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_UnregisterGpuMemoryBuffer, 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OnUnregisterGpuMemoryBuffer); 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture, 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnCreateStreamTexture) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 283c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CheckCompleteWaits(); 284c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (have_context) { 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Ensure that any delayed work that was created will be handled. 287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ScheduleDelayedWork(kHandleMoreWorkPeriodMs); 288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(handled); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::Send(IPC::Message* message) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_->Send(message); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::IsScheduled() { 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (!scheduler_.get() || scheduler_->IsScheduled()); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::HasMoreWork() { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scheduler_.get() && scheduler_->HasMoreWork(); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::PollWork() { 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::PollWork"); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delayed_work_scheduled_ = false; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FastSetActiveURL(active_url_, active_url_hash_); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_.get() && !MakeCurrent()) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (scheduler_) { 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool fences_complete = scheduler_->PollUnscheduleFences(); 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Perform idle work if all fences are complete. 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (fences_complete) { 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 current_messages_processed = 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel()->gpu_channel_manager()->MessagesProcessed(); 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We're idle when no messages were processed or scheduled. 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_idle = 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (previous_messages_processed_ == current_messages_processed) && 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !channel()->gpu_channel_manager()->HandleMessagesScheduled(); 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_idle && !last_idle_time_.is_null()) { 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta time_since_idle = base::TimeTicks::Now() - 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_idle_time_; 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta max_time_since_idle = 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Force idle when it's been too long since last time we were idle. 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (time_since_idle > max_time_since_idle) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_idle = true; 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_idle) { 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_idle_time_ = base::TimeTicks::Now(); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->PerformIdleWork(); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::HasUnprocessedCommands() { 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_buffer_) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State state = command_buffer_->GetLastState(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state.put_offset != state.get_offset && 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !gpu::error::IsError(state.error); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) { 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!HasMoreWork()) { 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_idle_time_ = base::TimeTicks(); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (delayed_work_scheduled_) 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delayed_work_scheduled_ = true; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Idle when no messages are processed between now and when 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // PollWork is called. 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) previous_messages_processed_ = 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel()->gpu_channel_manager()->MessagesProcessed(); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (last_idle_time_.is_null()) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_idle_time_ = base::TimeTicks::Now(); 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // IsScheduled() returns true after passing all unschedule fences 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and this is when we can start performing idle work. Idle work 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // is done synchronously so we can set delay to 0 and instead poll 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for more work at the rate idle work is performed. This also ensures 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that idle work is done as efficiently as possible without any 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // unnecessary delays. 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (scheduler_.get() && 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->IsScheduled() && 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->HasMoreIdleWork()) { 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delay = 0; 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(delay)); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnEcho(const IPC::Message& message) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnEcho"); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new IPC::Message(message)); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuCommandBufferStub::MakeCurrent() { 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (decoder_->MakeCurrent()) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Context lost because MakeCurrent failed."; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetParseError(gpu::error::kLostContext); 3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CheckContextLost(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::Destroy() { 403c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (wait_for_token_) { 404c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Send(wait_for_token_->reply.release()); 405c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_token_.reset(); 406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 407c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (wait_for_get_offset_) { 408c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Send(wait_for_get_offset_->reply.release()); 409c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_get_offset_.reset(); 410c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (handle_.is_null() && !active_url_.is_empty()) { 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_channel_manager->Send(new GpuHostMsg_DidDestroyOffscreenContext( 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) active_url_)); 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_manager_client_state_.reset(); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!sync_points_.empty()) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnRetireSyncPoint(sync_points_.front()); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (decoder_) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoder_->set_engine(NULL); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The scheduler has raw references to the decoder and the command buffer so 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroy it before those. 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_.reset(); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool have_context = false; 4307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (decoder_ && command_buffer_ && 4315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu command_buffer_->GetLastState().error != gpu::error::kLostContext) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) have_context = decoder_->MakeCurrent(); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(DestructionObserver, 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destruction_observers_, 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnWillDestroyStub()); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (decoder_) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->Destroy(have_context); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.reset(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_.reset(); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4445e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) // Remove this after crbug.com/248395 is sorted out. 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_ = NULL; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Destroy(); 450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GpuCommandBufferMsg_Initialize::WriteReplyParams( 451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) reply_message, false, gpu::Capabilities()); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnInitialize( 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemoryHandle shared_state_handle, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* reply_message) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnInitialize"); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!command_buffer_.get()); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::SharedMemory> shared_state_shm( 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new base::SharedMemory(shared_state_handle, false)); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_.reset(new gpu::CommandBufferService( 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_group_->transfer_buffer_manager())); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool result = command_buffer_->Initialize(); 468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(result); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get())); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.get(), 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_.get())); 475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (preemption_flag_.get()) 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetPreemptByFlag(preemption_flag_); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->set_engine(scheduler_.get()); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!handle_.is_null()) { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (software_) { 483c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LOG(ERROR) << "No software support."; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_ = ImageTransportSurface::CreateSurface( 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->gpu_channel_manager(), 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* manager = channel_->gpu_channel_manager(); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_ = manager->GetDefaultOffscreenSurface(); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 498868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!surface_.get()) { 499c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DLOG(ERROR) << "Failed to create surface."; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<gfx::GLContext> context; 50558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (use_virtualized_gl_context_ && channel_->share_group()) { 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = channel_->share_group()->GetSharedContext(); 507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!context.get()) { 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = gfx::GLContext::CreateGLContext( 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->share_group(), 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->gpu_channel_manager()->GetDefaultOffscreenSurface(), 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_preference_); 512c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!context.get()) { 513c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DLOG(ERROR) << "Failed to create shared context for virtualization."; 514c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch OnInitializeFailed(reply_message); 515c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 516c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) channel_->share_group()->SetSharedContext(context.get()); 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This should be a non-virtual GL context. 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(context->GetHandle()); 521868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) context = new gpu::GLContextVirtual( 522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) channel_->share_group(), context.get(), decoder_->AsWeakPtr()); 523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!context->Initialize(surface_.get(), gpu_preference_)) { 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(sievers): The real context created above for the default 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // offscreen surface might not be compatible with this surface. 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Need to adjust at least GLX to be able to create the initial context 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // with a config that is compatible with onscreen and offscreen surfaces. 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = NULL; 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DLOG(ERROR) << "Failed to initialize virtual GL context."; 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnInitializeFailed(reply_message); 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!context.get()) { 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context = gfx::GLContext::CreateGLContext( 537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) channel_->share_group(), surface_.get(), gpu_preference_); 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!context.get()) { 540c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DLOG(ERROR) << "Failed to create context."; 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!context->MakeCurrent(surface_.get())) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to make context current."; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 551a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!context->GetGLStateRestorer()) { 552a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) context->SetGLStateRestorer( 553a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) new gpu::GLStateRestorerImpl(decoder_->AsWeakPtr())); 554a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 555a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!context->GetTotalGpuMemory(&total_gpu_memory_)) 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_gpu_memory_ = 0; 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!context_group_->has_program_cache()) { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_group_->set_program_cache( 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->gpu_channel_manager()->program_cache()); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the decoder with either the view or pbuffer GLContext. 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!decoder_->Initialize(surface_, 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context, 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !surface_id(), 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_size_, 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disallowed_features_, 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) requested_attribs_)) { 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Failed to initialize decoder."; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnInitializeFailed(reply_message); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kEnableGPUServiceLogging)) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decoder_->set_log_commands(true); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) decoder_->GetLogger()->SetMsgCallback( 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::SendConsoleMessage, 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoder_->SetShaderCacheCallback( 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GpuCommandBufferStub::SendCachedShader, 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) decoder_->SetWaitSyncPointCallback( 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint, 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this))); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetPutOffsetChangeCallback( 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this))); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetGetBufferChangeCallback( 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&gpu::GpuScheduler::SetGetBuffer, 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(scheduler_.get()))); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->SetParseErrorCallback( 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this))); 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetSchedulingChangedCallback( 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GpuChannel::StubSchedulingChanged, 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(channel_))); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (watchdog_) { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->SetCommandProcessedCallback( 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnCommandProcessed, 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 608e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const size_t kSharedStateSize = sizeof(gpu::CommandBufferSharedState); 609e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!shared_state_shm->Map(kSharedStateSize)) { 610e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DLOG(ERROR) << "Failed to map shared state buffer."; 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnInitializeFailed(reply_message); 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 614e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch command_buffer_->SetSharedStateBuffer(gpu::MakeBackingFromSharedMemory( 615e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shared_state_shm.Pass(), kSharedStateSize)); 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 617116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gpu::Capabilities capabilities = decoder_->GetCapabilities(); 618116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch capabilities.future_sync_points = channel_->allow_future_sync_points(); 619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 620a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) GpuCommandBufferMsg_Initialize::WriteReplyParams( 621116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reply_message, true, capabilities); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (handle_.is_null() && !active_url_.is_empty()) { 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_channel_manager->Send(new GpuHostMsg_DidCreateOffscreenContext( 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) active_url_)); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 631c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuCommandBufferStub::OnCreateStreamTexture( 632c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch uint32 texture_id, int32 stream_id, bool* succeeded) { 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_ANDROID) 634c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *succeeded = StreamTexture::Create(this, texture_id, stream_id); 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#else 636c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *succeeded = false; 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void GpuCommandBufferStub::SetLatencyInfoCallback( 641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const LatencyInfoCallback& callback) { 642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) latency_info_callback_ = callback; 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int32 GpuCommandBufferStub::GetRequestedAttribute(int attr) const { 646f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The command buffer is pairs of enum, value 647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // search for the requested attribute, return the value. 648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (std::vector<int32>::const_iterator it = requested_attribs_.begin(); 649f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) it != requested_attribs_.end(); ++it) { 650f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (*it++ == attr) { 651f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return *it; 652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 653f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return -1; 655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 656f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::OnSetGetBuffer(int32 shm_id, 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Message* reply_message) { 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetGetBuffer"); 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_buffer_) 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) command_buffer_->SetGetBuffer(shm_id); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_message); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void GpuCommandBufferStub::OnProduceFrontBuffer(const gpu::Mailbox& mailbox) { 666868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnProduceFrontBuffer"); 6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!decoder_) { 668868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LOG(ERROR) << "Can't produce front buffer before initialization."; 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) decoder_->ProduceFrontBuffer(mailbox); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnParseError() { 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnParseError"); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(command_buffer_.get()); 6785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gpu::CommandBuffer::State state = command_buffer_->GetLastState(); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* msg = new GpuCommandBufferMsg_Destroyed( 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id_, state.context_lost_reason); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->set_unblock(true); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(msg); 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Tell the browser about this context loss as well, so it can 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // determine whether client APIs like WebGL need to be immediately 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // blocked from automatically running. 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_channel_manager->Send(new GpuHostMsg_DidLoseContext( 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handle_.is_null(), state.context_lost_reason, active_url_)); 6907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CheckContextLost(); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 694c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuCommandBufferStub::OnWaitForTokenInRange(int32 start, 695c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 end, 696c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::Message* reply_message) { 697c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnWaitForTokenInRange"); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(command_buffer_.get()); 6997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CheckContextLost(); 700c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (wait_for_token_) 701c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LOG(ERROR) << "Got WaitForToken command while currently waiting for token."; 702c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_token_ = 703c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch make_scoped_ptr(new WaitForCommandState(start, end, reply_message)); 704c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CheckCompleteWaits(); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 707c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuCommandBufferStub::OnWaitForGetOffsetInRange( 708c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 start, 709c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 end, 710c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::Message* reply_message) { 711c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnWaitForGetOffsetInRange"); 712c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(command_buffer_.get()); 713c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CheckContextLost(); 714c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (wait_for_get_offset_) { 715c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LOG(ERROR) 716c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << "Got WaitForGetOffset command while currently waiting for offset."; 717c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 718c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_get_offset_ = 719c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch make_scoped_ptr(new WaitForCommandState(start, end, reply_message)); 720c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CheckCompleteWaits(); 721c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 722c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 723c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuCommandBufferStub::CheckCompleteWaits() { 724c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (wait_for_token_ || wait_for_get_offset_) { 7255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gpu::CommandBuffer::State state = command_buffer_->GetLastState(); 726c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (wait_for_token_ && 727c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (gpu::CommandBuffer::InRange( 728c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_token_->start, wait_for_token_->end, state.token) || 729c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state.error != gpu::error::kNoError)) { 730c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ReportState(); 731c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GpuCommandBufferMsg_WaitForTokenInRange::WriteReplyParams( 732c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_token_->reply.get(), state); 733c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Send(wait_for_token_->reply.release()); 734c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_token_.reset(); 735c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 736c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (wait_for_get_offset_ && 737c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (gpu::CommandBuffer::InRange(wait_for_get_offset_->start, 738c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_get_offset_->end, 739c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state.get_offset) || 740c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch state.error != gpu::error::kNoError)) { 741c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ReportState(); 742c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GpuCommandBufferMsg_WaitForGetOffsetInRange::WriteReplyParams( 743c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_get_offset_->reply.get(), state); 744c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Send(wait_for_get_offset_->reply.release()); 745c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch wait_for_get_offset_.reset(); 746c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 747c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 748c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 749c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 7501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GpuCommandBufferStub::OnAsyncFlush( 7511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int32 put_offset, 7521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uint32 flush_count, 7531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<ui::LatencyInfo>& latency_info) { 754c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TRACE_EVENT1( 755c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch "gpu", "GpuCommandBufferStub::OnAsyncFlush", "put_offset", put_offset); 7561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 7571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ui::LatencyInfo::Verify(latency_info, 7581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "GpuCommandBufferStub::OnAsyncFlush") && 7591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !latency_info_callback_.is_null()) { 7601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci latency_info_callback_.Run(latency_info); 7611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(command_buffer_.get()); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flush_count - last_flush_count_ < 0x8000000U) { 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_flush_count_ = flush_count; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->Flush(put_offset); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We received this message out-of-order. This should not happen but is here 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to catch regressions. Ignore the message. 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Received a Flush message out-of-order"; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportState(); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnRescheduled() { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State pre_state = command_buffer_->GetLastState(); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->Flush(pre_state.put_offset); 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::CommandBuffer::State post_state = command_buffer_->GetLastState(); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pre_state.get_offset != post_state.get_offset) 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportState(); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnRegisterTransferBuffer( 7852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int32 id, 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemoryHandle transfer_buffer, 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 size) { 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterTransferBuffer"); 789effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 790effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Take ownership of the memory and map it into this process. 791effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // This validates the size. 792effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<base::SharedMemory> shared_memory( 793effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new base::SharedMemory(transfer_buffer, false)); 794effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!shared_memory->Map(size)) { 795effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DVLOG(0) << "Failed to map shared memory."; 796effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return; 797effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 799e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (command_buffer_) { 800e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch command_buffer_->RegisterTransferBuffer( 801e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch id, gpu::MakeBackingFromSharedMemory(shared_memory.Pass(), size)); 802e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::OnDestroyTransferBuffer(int32 id) { 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnDestroyTransferBuffer"); 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_buffer_) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_buffer_->DestroyTransferBuffer(id); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnCommandProcessed() { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (watchdog_) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) watchdog_->CheckArmed(); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 817c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuCommandBufferStub::ReportState() { command_buffer_->UpdateState(); } 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::PutChanged() { 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FastSetActiveURL(active_url_, active_url_hash_); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scheduler_->PutChanged(); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnCreateVideoDecoder( 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::VideoCodecProfile profile, 826c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 decoder_route_id, 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* reply_message) { 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoDecoder"); 82958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GpuVideoDecodeAccelerator* decoder = new GpuVideoDecodeAccelerator( 83058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) decoder_route_id, this, channel_->io_message_loop()); 83158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) decoder->Initialize(profile, reply_message); 832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // decoder is registered as a DestructionObserver of this stub and will 833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // self-delete during destruction of this stub. 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 836c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuCommandBufferStub::OnCreateVideoEncoder( 837c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch media::VideoFrame::Format input_format, 838c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const gfx::Size& input_visible_size, 839c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch media::VideoCodecProfile output_profile, 840c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch uint32 initial_bitrate, 841c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 encoder_route_id, 842c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::Message* reply_message) { 843c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnCreateVideoEncoder"); 844c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GpuVideoEncodeAccelerator* encoder = 845c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new GpuVideoEncodeAccelerator(encoder_route_id, this); 846c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch encoder->Initialize(input_format, 847c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch input_visible_size, 848c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch output_profile, 849c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch initial_bitrate, 850c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch reply_message); 851c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // encoder is registered as a DestructionObserver of this stub and will 852c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // self-delete during destruction of this stub. 853c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 854c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) { 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSetSurfaceVisible"); 857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (memory_manager_client_state_) 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_manager_client_state_->SetVisible(visible); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::AddSyncPoint(uint32 sync_point) { 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_points_.push_back(sync_point); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) { 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!sync_points_.empty() && sync_points_.front() == sync_point); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_points_.pop_front(); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* manager = channel_->gpu_channel_manager(); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->sync_point_manager()->RetireSyncPoint(sync_point); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) { 873a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!sync_point) 874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GpuChannelManager* manager = channel_->gpu_channel_manager(); 8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (manager->sync_point_manager()->IsSyncPointRetired(sync_point)) 8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sync_point_wait_count_ == 0) { 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitSyncPoint", this, 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuCommandBufferStub", this); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetScheduled(false); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++sync_point_wait_count_; 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->sync_point_manager()->AddSyncPointCallback( 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_point, 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnSyncPointRetired, 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->AsWeakPtr())); 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scheduler_->IsScheduled(); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSyncPointRetired() { 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --sync_point_wait_count_; 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sync_point_wait_count_ == 0) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this, 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuCommandBufferStub", this); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetScheduled(true); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSignalSyncPoint(uint32 sync_point, uint32 id) { 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuChannelManager* manager = channel_->gpu_channel_manager(); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->sync_point_manager()->AddSyncPointCallback( 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_point, 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck, 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->AsWeakPtr(), 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id)); 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSignalSyncPointAck(uint32 id) { 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new GpuCommandBufferMsg_SignalSyncPointAck(route_id_, id)); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 914eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid GpuCommandBufferStub::OnSignalQuery(uint32 query_id, uint32 id) { 915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (decoder_) { 916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gpu::gles2::QueryManager* query_manager = decoder_->GetQueryManager(); 917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (query_manager) { 918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gpu::gles2::QueryManager::Query* query = 919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch query_manager->GetQuery(query_id); 920eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (query) { 921eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch query->AddCallback( 922eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::Bind(&GpuCommandBufferStub::OnSignalSyncPointAck, 923eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch this->AsWeakPtr(), 924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch id)); 925eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 928eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 929eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Something went wrong, run callback immediately. 930eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OnSignalSyncPointAck(id); 931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 932eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback( 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_callback) { 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0( 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "gpu", 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuCommandBufferStub::OnSetClientHasMemoryAllocationChangedCallback"); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (has_callback) { 940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!memory_manager_client_state_) { 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_manager_client_state_.reset(GetMemoryManager()->CreateClientState( 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, surface_id_ != 0, true)); 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memory_manager_client_state_.reset(); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void GpuCommandBufferStub::OnRegisterGpuMemoryBuffer( 9501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int32 id, 9515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::GpuMemoryBufferHandle handle, 9521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) uint32 width, 9531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) uint32 height, 9541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) uint32 internalformat) { 9551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnRegisterGpuMemoryBuffer"); 9564ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#if defined(OS_ANDROID) 9574ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // Verify that renderer is not trying to use a surface texture it doesn't own. 9585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (handle.type == gfx::SURFACE_TEXTURE_BUFFER && 9595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) handle.surface_texture_id.secondary_id != channel()->client_id()) { 9604ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch LOG(ERROR) << "Illegal surface texture ID for renderer."; 9614ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch return; 9624ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch } 9634ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch#endif 9645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!decoder_) 9665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 9675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); 9695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(image_manager); 9705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (image_manager->LookupImage(id)) { 9715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Image already exists with same ID."; 9725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 9731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 9745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GpuChannelManager* manager = channel_->gpu_channel_manager(); 9765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<gfx::GLImage> image = 9775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) manager->gpu_memory_buffer_factory()->CreateImageForGpuMemoryBuffer( 9785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) handle, 9795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Size(width, height), 9805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) internalformat, 9815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) channel()->client_id()); 9821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!image.get()) 9835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 9845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // For Android specific workaround. 9865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (context_group_->feature_info()->workarounds().release_image_after_use) 9875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) image->SetReleaseAfterUse(); 9885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) image_manager->AddImage(image.get(), id); 9901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 9911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 9925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GpuCommandBufferStub::OnUnregisterGpuMemoryBuffer(int32 id) { 9935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnUnregisterGpuMemoryBuffer"); 9945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!decoder_) 9965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 9975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); 9995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(image_manager); 10005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!image_manager->LookupImage(id)) { 10015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) LOG(ERROR) << "Image with ID doesn't exist."; 10025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 10035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 10045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) image_manager->RemoveImage(id); 10061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 10071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::SendConsoleMessage( 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 id, 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& message) { 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GPUCommandBufferConsoleMessage console_message; 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) console_message.id = id; 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) console_message.message = message; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* msg = new GpuCommandBufferMsg_ConsoleMsg( 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id_, console_message); 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->set_unblock(true); 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(msg); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::SendCachedShader( 10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& key, const std::string& shader) { 10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->CacheShader(key, shader); 10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::AddDestructionObserver( 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestructionObserver* observer) { 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destruction_observers_.AddObserver(observer); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::RemoveDestructionObserver( 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestructionObserver* observer) { 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) destruction_observers_.RemoveObserver(observer); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuCommandBufferStub::SetPreemptByFlag( 10362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<gpu::PreemptionFlag> flag) { 10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_flag_ = flag; 1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (scheduler_) 10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scheduler_->SetPreemptByFlag(preemption_flag_); 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GpuCommandBufferStub::GetTotalGpuMemory(uint64* bytes) { 10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *bytes = total_gpu_memory_; 10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !!total_gpu_memory_; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size GpuCommandBufferStub::GetSurfaceSize() const { 1048868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!surface_.get()) 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return surface_->GetSize(); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gpu::gles2::MemoryTracker* GpuCommandBufferStub::GetMemoryTracker() const { 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return context_group_->memory_tracker(); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuCommandBufferStub::SetMemoryAllocation( 10581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const gpu::MemoryAllocation& allocation) { 10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!last_memory_allocation_valid_ || 10601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) !allocation.Equals(last_memory_allocation_)) { 10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send(new GpuCommandBufferMsg_SetMemoryAllocation( 10621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) route_id_, allocation)); 10632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_memory_allocation_valid_ = true; 10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_memory_allocation_ = allocation; 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void GpuCommandBufferStub::SuggestHaveFrontBuffer( 10701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool suggest_have_frontbuffer) { 10711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // This can be called outside of OnMessageReceived, so the context needs 10721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // to be made current before calling methods on the surface. 10731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (surface_.get() && MakeCurrent()) 10741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) surface_->SetFrontbufferAllocation(suggest_have_frontbuffer); 10751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 10761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 10777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool GpuCommandBufferStub::CheckContextLost() { 10787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(command_buffer_); 10795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu gpu::CommandBuffer::State state = command_buffer_->GetLastState(); 10807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool was_lost = state.error == gpu::error::kLostContext; 10817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Lose all other contexts if the reset was triggered by the robustness 10827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // extension instead of being synthetic. 10837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (was_lost && decoder_ && decoder_->WasContextLostByRobustnessExtension() && 10847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (gfx::GLContext::LosesAllContextsOnContextLost() || 10857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch use_virtualized_gl_context_)) 10867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch channel_->LoseAllContexts(); 1087c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CheckCompleteWaits(); 10887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return was_lost; 10897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 10907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 10917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid GpuCommandBufferStub::MarkContextLost() { 10927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!command_buffer_ || 10935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu command_buffer_->GetLastState().error == gpu::error::kLostContext) 10947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 10957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 10967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch command_buffer_->SetContextLostReason(gpu::error::kUnknown); 10977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (decoder_) 10987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch decoder_->LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB); 10997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch command_buffer_->SetParseError(gpu::error::kLostContext); 11007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 11017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)uint64 GpuCommandBufferStub::GetMemoryUsage() const { 1103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return GetMemoryManager()->GetClientMemoryUsage(this); 1104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 1107