1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gpu/ipc/in_process_gpu_thread_holder.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/threading/thread_task_runner_handle.h"
12 #include "build/build_config.h"
13 #include "gpu/command_buffer/service/mailbox_manager_factory.h"
14 #include "gpu/command_buffer/service/scheduler.h"
15 #include "gpu/command_buffer/service/service_utils.h"
16 #include "gpu/command_buffer/service/shared_image_manager.h"
17 #include "gpu/command_buffer/service/sync_point_manager.h"
18 #include "gpu/config/gpu_info_collector.h"
19 #include "gpu/config/gpu_util.h"
20 #include "ui/gl/init/gl_factory.h"
21
22 namespace gpu {
23
InProcessGpuThreadHolder()24 InProcessGpuThreadHolder::InProcessGpuThreadHolder()
25 : base::Thread("GpuThread") {
26 DCHECK(base::CommandLine::InitializedForCurrentProcess());
27 auto* command_line = base::CommandLine::ForCurrentProcess();
28 gpu_preferences_ = gles2::ParseGpuPreferences(command_line);
29
30 gpu::GPUInfo gpu_info;
31 gpu::CollectGraphicsInfoForTesting(&gpu_info);
32 gpu_feature_info_ = gpu::ComputeGpuFeatureInfo(gpu_info, gpu_preferences_,
33 command_line, nullptr);
34
35 Start();
36 }
37
~InProcessGpuThreadHolder()38 InProcessGpuThreadHolder::~InProcessGpuThreadHolder() {
39 // Ensure members created on GPU thread are destroyed there too.
40 task_runner()->PostTask(
41 FROM_HERE, base::BindOnce(&InProcessGpuThreadHolder::DeleteOnGpuThread,
42 base::Unretained(this)));
43 Stop();
44 }
45
GetGpuPreferences()46 GpuPreferences* InProcessGpuThreadHolder::GetGpuPreferences() {
47 DCHECK(!task_executor_);
48 return &gpu_preferences_;
49 }
50
GetGpuFeatureInfo()51 GpuFeatureInfo* InProcessGpuThreadHolder::GetGpuFeatureInfo() {
52 DCHECK(!task_executor_);
53 return &gpu_feature_info_;
54 }
55
GetTaskExecutor()56 CommandBufferTaskExecutor* InProcessGpuThreadHolder::GetTaskExecutor() {
57 if (!task_executor_) {
58 base::WaitableEvent completion;
59 task_runner()->PostTask(
60 FROM_HERE,
61 base::BindOnce(&InProcessGpuThreadHolder::InitializeOnGpuThread,
62 base::Unretained(this), &completion));
63 completion.Wait();
64 }
65 return task_executor_.get();
66 }
67
InitializeOnGpuThread(base::WaitableEvent * completion)68 void InProcessGpuThreadHolder::InitializeOnGpuThread(
69 base::WaitableEvent* completion) {
70 sync_point_manager_ = std::make_unique<SyncPointManager>();
71 scheduler_ = std::make_unique<Scheduler>(
72 task_runner(), sync_point_manager_.get(), gpu_preferences_);
73 mailbox_manager_ = gles2::CreateMailboxManager(gpu_preferences_);
74 shared_image_manager_ = std::make_unique<SharedImageManager>();
75
76 share_group_ = new gl::GLShareGroup();
77 surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size());
78 gl::GLContextAttribs attribs = gles2::GenerateGLContextAttribs(
79 ContextCreationAttribs(), false /* use_passthrough_decoder */);
80 context_ =
81 gl::init::CreateGLContext(share_group_.get(), surface_.get(), attribs);
82 CHECK(context_->MakeCurrent(surface_.get()));
83 GpuDriverBugWorkarounds gpu_driver_bug_workarounds(
84 gpu_feature_info_.enabled_gpu_driver_bug_workarounds);
85
86 bool use_virtualized_gl_context_ = false;
87 #if defined(OS_MACOSX)
88 // Virtualize GpuPreference:::kLowPower contexts by default on OS X to prevent
89 // performance regressions when enabling FCM. https://crbug.com/180463
90 use_virtualized_gl_context_ = true;
91 #endif
92 use_virtualized_gl_context_ |=
93 gpu_driver_bug_workarounds.use_virtualized_gl_contexts;
94
95 context_state_ = base::MakeRefCounted<SharedContextState>(
96 share_group_, surface_, context_, use_virtualized_gl_context_,
97 base::DoNothing(), gpu_preferences_.gr_context_type);
98 auto feature_info = base::MakeRefCounted<gles2::FeatureInfo>(
99 gpu_driver_bug_workarounds, gpu_feature_info_);
100 context_state_->InitializeGL(gpu_preferences_, feature_info);
101 context_state_->InitializeGrContext(gpu_preferences_,
102 gpu_driver_bug_workarounds, nullptr);
103
104 task_executor_ = std::make_unique<GpuInProcessThreadService>(
105 this, task_runner(), scheduler_.get(), sync_point_manager_.get(),
106 mailbox_manager_.get(), gl::GLSurfaceFormat(), gpu_feature_info_,
107 gpu_preferences_, shared_image_manager_.get(), nullptr);
108
109 completion->Signal();
110 }
111
DeleteOnGpuThread()112 void InProcessGpuThreadHolder::DeleteOnGpuThread() {
113 task_executor_.reset();
114 scheduler_.reset();
115 sync_point_manager_.reset();
116 shared_image_manager_.reset();
117
118 context_state_.reset();
119 context_.reset();
120 surface_.reset();
121 share_group_.reset();
122 }
123
124 scoped_refptr<SharedContextState>
GetSharedContextState()125 InProcessGpuThreadHolder::GetSharedContextState() {
126 DCHECK(context_state_);
127 return context_state_;
128 }
129
GetShareGroup()130 scoped_refptr<gl::GLShareGroup> InProcessGpuThreadHolder::GetShareGroup() {
131 if (!share_group_)
132 share_group_ = base::MakeRefCounted<gl::GLShareGroup>();
133 return share_group_;
134 }
135
136 } // namespace gpu
137