Chromium Code Reviews| Index: components/mus/gpu/gpu_service_mus.cc |
| diff --git a/components/mus/gpu/gpu_service_mus.cc b/components/mus/gpu/gpu_service_mus.cc |
| index d9c4b3c1a6d1a7a5fb4b7948d6bffccfee02d581..78b3b3fe283c8664ce584bce8bc9117ce97c909e 100644 |
| --- a/components/mus/gpu/gpu_service_mus.cc |
| +++ b/components/mus/gpu/gpu_service_mus.cc |
| @@ -4,45 +4,108 @@ |
| #include "components/mus/gpu/gpu_service_mus.h" |
| +#include "base/memory/shared_memory.h" |
| +#include "base/memory/singleton.h" |
| +#include "base/synchronization/waitable_event.h" |
| +#include "base/threading/thread_task_runner_handle.h" |
| +#include "components/mus/gpu/gpu_memory_buffer_manager_mus_local.h" |
| +#include "gpu/command_buffer/service/gpu_switches.h" |
| +#include "gpu/command_buffer/service/sync_point_manager.h" |
| +#include "gpu/config/gpu_info_collector.h" |
| +#include "gpu/config/gpu_switches.h" |
| +#include "gpu/config/gpu_util.h" |
| +#include "gpu/ipc/common/gpu_memory_buffer_support.h" |
| +#include "gpu/ipc/common/memory_stats.h" |
| #include "gpu/ipc/common/surface_handle.h" |
| +#include "gpu/ipc/service/gpu_memory_buffer_factory.h" |
| +#include "ipc/ipc_channel_handle.h" |
| +#include "ipc/ipc_sync_message_filter.h" |
| +#include "media/gpu/ipc/service/gpu_jpeg_decode_accelerator.h" |
| +#include "media/gpu/ipc/service/gpu_video_decode_accelerator.h" |
| +#include "media/gpu/ipc/service/gpu_video_encode_accelerator.h" |
| +#include "media/gpu/ipc/service/media_service.h" |
| +#include "ui/gl/gl_implementation.h" |
| +#include "ui/gl/gl_switches.h" |
| +#include "ui/gl/gpu_switching_manager.h" |
| +#include "url/gurl.h" |
| namespace mus { |
| +namespace { |
| -GpuServiceMus::GpuServiceMus() {} |
| +const int kLocalGpuChannelClientId = 1; |
| +const uint64_t kLocalGpuChannelClientTracingId = 1; |
| +} |
| -GpuServiceMus::~GpuServiceMus() {} |
| +GpuServiceMus::GpuServiceMus() |
| + : main_message_loop_(base::MessageLoop::current()), |
| + shutdown_event_(true, false), |
| + gpu_thread_("GpuThread"), |
| + io_thread_("GpuIOThread"), |
| + io_thread_local_("GpuIOThreadLocal") { |
| + Initialize(); |
| +} |
| -void GpuServiceMus::EstablishGpuChannel( |
| - bool prempts, |
| +GpuServiceMus::~GpuServiceMus() { |
| + // Signal this event before destroying the child process. That way all |
| + // background threads can cleanup. |
| + // For example, in the renderer the RenderThread instances will be able to |
| + // notice shutdown before the render process begins waiting for them to exit. |
| + shutdown_event_.Signal(); |
| + io_thread_.Stop(); |
| +} |
| + |
| +IPC::ChannelHandle GpuServiceMus::EstablishGpuChannel( |
| + int client_id, |
| + uint64_t client_tracing_id, |
| + bool preempts, |
| bool allow_view_command_buffers, |
| - bool allow_real_time_streams, |
| - const mojom::GpuService::EstablishGpuChannelCallback& callback) { |
| - NOTIMPLEMENTED(); |
| + bool allow_real_time_streams) { |
| + CHECK_GT(client_id, kLocalGpuChannelClientId); |
|
piman
2016/05/24 22:46:54
nit: DCHECK_GT
Peng
2016/05/25 19:42:55
Done.
|
| + |
| + if (!gpu_channel_manager_) |
| + return IPC::ChannelHandle(); |
| + |
| + IPC::ChannelHandle channel_handle; |
| + bool manual_reset = true; |
| + bool initially_signaled = false; |
| + base::WaitableEvent event(manual_reset, initially_signaled); |
| + gpu_thread_.task_runner()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&GpuServiceMus::EstablishGpuChannelOnGpuThread, |
| + base::Unretained(this), client_id, client_tracing_id, preempts, |
| + allow_view_command_buffers, allow_real_time_streams, |
| + &channel_handle, &event)); |
| + event.Wait(); |
| + return channel_handle; |
| } |
| -void GpuServiceMus::CreateGpuMemoryBuffer( |
| - mojom::GpuMemoryBufferIdPtr id, |
| - mojo::SizePtr size, |
| - mojom::BufferFormat format, |
| - mojom::BufferUsage usage, |
| - uint64_t surface_id, |
| - const mojom::GpuService::CreateGpuMemoryBufferCallback& callback) { |
| - NOTIMPLEMENTED(); |
| +gfx::GpuMemoryBufferHandle GpuServiceMus::CreateGpuMemoryBuffer( |
| + gfx::GpuMemoryBufferId id, |
| + const gfx::Size& size, |
| + gfx::BufferFormat format, |
| + gfx::BufferUsage usage, |
| + int client_id, |
| + int32_t surface_handle) { |
| + return gpu_memory_buffer_factory_->CreateGpuMemoryBuffer( |
| + id, size, format, usage, client_id, |
| + static_cast<gpu::SurfaceHandle>(surface_handle)); |
| } |
| -void GpuServiceMus::CreateGpuMemoryBufferFromHandle( |
| - mojom::GpuMemoryBufferHandlePtr buffer_handle, |
| - mojom::GpuMemoryBufferIdPtr id, |
| - mojo::SizePtr size, |
| - mojom::BufferFormat format, |
| - const mojom::GpuService::CreateGpuMemoryBufferFromHandleCallback& |
| - callback) { |
| - NOTIMPLEMENTED(); |
| +gfx::GpuMemoryBufferHandle GpuServiceMus::CreateGpuMemoryBufferFromeHandle( |
| + gfx::GpuMemoryBufferHandle buffer_handle, |
| + gfx::GpuMemoryBufferId id, |
| + const gfx::Size& size, |
| + gfx::BufferFormat format, |
| + int client_id) { |
| + return gpu_memory_buffer_factory_->CreateGpuMemoryBufferFromHandle( |
| + buffer_handle, id, size, format, client_id); |
| } |
| -void GpuServiceMus::DestroyGpuMemoryBuffer(mojom::GpuMemoryBufferIdPtr id, |
| +void GpuServiceMus::DestroyGpuMemoryBuffer(gfx::GpuMemoryBufferId id, |
| + int client_id, |
| const gpu::SyncToken& sync_token) { |
| - NOTIMPLEMENTED(); |
| + if (gpu_channel_manager_) |
| + gpu_channel_manager_->DestroyGpuMemoryBuffer(id, client_id, sync_token); |
| } |
| void GpuServiceMus::DidCreateOffscreenContext(const GURL& active_url) { |
| @@ -50,6 +113,7 @@ void GpuServiceMus::DidCreateOffscreenContext(const GURL& active_url) { |
| } |
| void GpuServiceMus::DidDestroyChannel(int client_id) { |
| + media_service_->RemoveChannel(client_id); |
| NOTIMPLEMENTED(); |
| } |
| @@ -67,7 +131,7 @@ void GpuServiceMus::GpuMemoryUmaStats(const gpu::GPUMemoryUmaStats& params) { |
| NOTIMPLEMENTED(); |
| } |
| -void GpuServiceMus::StoreShaderToDisk(int32_t client_id, |
| +void GpuServiceMus::StoreShaderToDisk(int client_id, |
| const std::string& key, |
| const std::string& shader) { |
| NOTIMPLEMENTED(); |
| @@ -85,4 +149,120 @@ void GpuServiceMus::SetActiveURL(const GURL& url) { |
| NOTIMPLEMENTED(); |
| } |
| +void GpuServiceMus::Initialize() { |
| + base::Thread::Options thread_options(base::MessageLoop::TYPE_DEFAULT, 0); |
| + thread_options.priority = base::ThreadPriority::NORMAL; |
| + CHECK(gpu_thread_.StartWithOptions(thread_options)); |
| + |
| + thread_options = base::Thread::Options(base::MessageLoop::TYPE_IO, 0); |
| + thread_options.priority = base::ThreadPriority::NORMAL; |
| +#if defined(OS_ANDROID) |
| + // TODO(reveman): Remove this in favor of setting it explicitly for each type |
| + // of process. |
| + thread_options.priority = base::ThreadPriority::DISPLAY; |
| +#endif |
| + CHECK(io_thread_.StartWithOptions(thread_options)); |
| + CHECK(io_thread_local_.StartWithOptions(thread_options)); |
| + |
| + IPC::ChannelHandle channel_handle; |
| + bool manual_reset = true; |
| + bool initially_signaled = false; |
| + base::WaitableEvent event(manual_reset, initially_signaled); |
| + gpu_thread_.task_runner()->PostTask( |
| + FROM_HERE, base::Bind(&GpuServiceMus::InitializeOnGpuThread, |
| + base::Unretained(this), &channel_handle, &event)); |
| + event.Wait(); |
| + |
| + gpu_memory_buffer_manager_mus_local_.reset(new GpuMemoryBufferManagerMusLocal( |
| + kLocalGpuChannelClientId, kLocalGpuChannelClientTracingId)); |
| + gpu_channel_local_ = gpu::GpuChannelHost::Create( |
| + this, kLocalGpuChannelClientId, gpu_info_, channel_handle, |
| + &shutdown_event_, gpu_memory_buffer_manager_mus_local_.get()); |
| +} |
| + |
| +void GpuServiceMus::InitializeOnGpuThread(IPC::ChannelHandle* channel_handle, |
| + base::WaitableEvent* event) { |
| + gpu_info_.video_decode_accelerator_capabilities = |
| + media::GpuVideoDecodeAccelerator::GetCapabilities(gpu_preferences_); |
| + gpu_info_.video_encode_accelerator_supported_profiles = |
| + media::GpuVideoEncodeAccelerator::GetSupportedProfiles(gpu_preferences_); |
| + gpu_info_.jpeg_decode_accelerator_supported = |
| + media::GpuJpegDecodeAccelerator::IsSupported(); |
| + |
| + if (gpu::GetNativeGpuMemoryBufferType() != gfx::EMPTY_BUFFER) { |
| + gpu_memory_buffer_factory_ = |
| + gpu::GpuMemoryBufferFactory::CreateNativeType(); |
| + } |
| + |
| + if (!gfx::GLSurface::InitializeOneOff()) |
| + VLOG(1) << "gfx::GLSurface::InitializeOneOff failed"; |
| + |
| + DCHECK(!owned_sync_point_manager_); |
| + owned_sync_point_manager_.reset(new gpu::SyncPointManager(false)); |
|
Fady Samuel
2016/05/25 17:06:47
What's this false?
Peng
2016/05/25 19:42:55
Done.
|
| + |
| + // Defer creation of the render thread. This is to prevent it from handling |
| + // IPC messages before the sandbox has been enabled and all other necessary |
| + // initialization has succeeded. |
| + gpu::GpuWatchdog* watchdog = nullptr; |
|
Fady Samuel
2016/05/25 17:06:47
Add a TODO here please to implement a watchdog thr
Peng
2016/05/25 19:42:55
Done.
|
| + gpu_channel_manager_.reset(new gpu::GpuChannelManager( |
| + gpu_preferences_, this, watchdog, |
| + base::ThreadTaskRunnerHandle::Get().get(), io_thread_.task_runner().get(), |
| + &shutdown_event_, owned_sync_point_manager_.get(), |
| + gpu_memory_buffer_factory_.get())); |
| + |
| + media_service_.reset(new media::MediaService(gpu_channel_manager_.get())); |
| + |
| +#if defined(USE_OZONE) |
| + ui::OzonePlatform::GetInstance() |
| + ->GetGpuPlatformSupport() |
| + ->OnChannelEstablished(this); |
| +#endif |
| + const bool preempts = true; |
| + const bool allow_view_command_buffers = true; |
| + const bool allow_real_time_streams = true; |
| + EstablishGpuChannelOnGpuThread( |
| + kLocalGpuChannelClientId, kLocalGpuChannelClientTracingId, preempts, |
| + allow_view_command_buffers, allow_real_time_streams, channel_handle, |
| + event); |
| +} |
| + |
| +void GpuServiceMus::EstablishGpuChannelOnGpuThread( |
| + int client_id, |
| + uint64_t client_tracing_id, |
| + bool preempts, |
| + bool allow_view_command_buffers, |
| + bool allow_real_time_streams, |
| + IPC::ChannelHandle* channel_handle, |
| + base::WaitableEvent* event) { |
| + if (gpu_channel_manager_) { |
| + *channel_handle = gpu_channel_manager_->EstablishChannel( |
| + client_id, client_tracing_id, preempts, allow_view_command_buffers, |
| + allow_real_time_streams); |
| + media_service_->AddChannel(client_id); |
| + } |
| + event->Signal(); |
| +} |
| + |
| +bool GpuServiceMus::IsMainThread() { |
| + return main_message_loop_ == base::MessageLoop::current(); |
| +} |
| + |
| +scoped_refptr<base::SingleThreadTaskRunner> |
| +GpuServiceMus::GetIOThreadTaskRunner() { |
| + return io_thread_local_.task_runner(); |
| +} |
| + |
| +std::unique_ptr<base::SharedMemory> GpuServiceMus::AllocateSharedMemory( |
| + size_t size) { |
| + std::unique_ptr<base::SharedMemory> shm(new base::SharedMemory()); |
| + if (!shm->CreateAnonymous(size)) |
| + return std::unique_ptr<base::SharedMemory>(); |
| + return shm; |
| +} |
| + |
| +// static |
| +GpuServiceMus* GpuServiceMus::GetInstance() { |
| + return base::Singleton<GpuServiceMus>::get(); |
| +} |
| + |
| } // namespace mus |