Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 1 | // Copyright (c) 2017 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/service/raster_command_buffer_stub.h" |
| 6 | |
Jonathan Backer | 0cd1c432 | 2018-04-17 16:57:10 | [diff] [blame] | 7 | #include <memory> |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 8 | #include <utility> |
| 9 | |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 10 | #include "base/macros.h" |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 11 | #include "base/memory/shared_memory.h" |
| 12 | #include "base/trace_event/trace_event.h" |
| 13 | #include "build/build_config.h" |
| 14 | #include "gpu/command_buffer/common/constants.h" |
| 15 | #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" |
| 16 | #include "gpu/command_buffer/common/mailbox.h" |
| 17 | #include "gpu/command_buffer/service/gl_context_virtual.h" |
| 18 | #include "gpu/command_buffer/service/gl_state_restorer_impl.h" |
| 19 | #include "gpu/command_buffer/service/image_manager.h" |
| 20 | #include "gpu/command_buffer/service/logger.h" |
| 21 | #include "gpu/command_buffer/service/mailbox_manager.h" |
| 22 | #include "gpu/command_buffer/service/memory_tracking.h" |
Jonathan Backer | 7f90dfb66 | 2017-12-18 16:52:04 | [diff] [blame] | 23 | #include "gpu/command_buffer/service/raster_decoder.h" |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 24 | #include "gpu/command_buffer/service/service_utils.h" |
| 25 | #include "gpu/command_buffer/service/sync_point_manager.h" |
| 26 | #include "gpu/command_buffer/service/transfer_buffer_manager.h" |
| 27 | #include "gpu/config/gpu_crash_keys.h" |
| 28 | #include "gpu/ipc/common/gpu_messages.h" |
| 29 | #include "gpu/ipc/service/gpu_channel.h" |
| 30 | #include "gpu/ipc/service/gpu_channel_manager.h" |
| 31 | #include "gpu/ipc/service/gpu_channel_manager_delegate.h" |
| 32 | #include "gpu/ipc/service/gpu_memory_buffer_factory.h" |
| 33 | #include "gpu/ipc/service/gpu_memory_manager.h" |
| 34 | #include "gpu/ipc/service/gpu_memory_tracking.h" |
| 35 | #include "gpu/ipc/service/gpu_watchdog_thread.h" |
| 36 | #include "ui/gl/gl_bindings.h" |
| 37 | #include "ui/gl/gl_context.h" |
| 38 | #include "ui/gl/gl_image.h" |
| 39 | #include "ui/gl/gl_implementation.h" |
| 40 | #include "ui/gl/gl_switches.h" |
| 41 | #include "ui/gl/gl_workarounds.h" |
| 42 | #include "ui/gl/init/gl_factory.h" |
| 43 | |
| 44 | #if defined(OS_WIN) |
| 45 | #include "base/win/win_util.h" |
| 46 | #endif |
| 47 | |
| 48 | #if defined(OS_ANDROID) |
| 49 | #include "gpu/ipc/service/stream_texture_android.h" |
| 50 | #endif |
| 51 | |
| 52 | namespace gpu { |
| 53 | |
| 54 | RasterCommandBufferStub::RasterCommandBufferStub( |
| 55 | GpuChannel* channel, |
| 56 | const GPUCreateCommandBufferConfig& init_params, |
| 57 | CommandBufferId command_buffer_id, |
| 58 | SequenceId sequence_id, |
| 59 | int32_t stream_id, |
| 60 | int32_t route_id) |
| 61 | : CommandBufferStub(channel, |
| 62 | init_params, |
| 63 | command_buffer_id, |
| 64 | sequence_id, |
| 65 | stream_id, |
| 66 | route_id) {} |
| 67 | |
Jonathan Backer | 1d807a4 | 2018-01-08 20:45:54 | [diff] [blame] | 68 | RasterCommandBufferStub::~RasterCommandBufferStub() {} |
| 69 | |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 70 | gpu::ContextResult RasterCommandBufferStub::Initialize( |
| 71 | CommandBufferStub* share_command_buffer_stub, |
| 72 | const GPUCreateCommandBufferConfig& init_params, |
| 73 | std::unique_ptr<base::SharedMemory> shared_state_shm) { |
| 74 | #if defined(OS_FUCHSIA) |
| 75 | // TODO(crbug.com/707031): Implement this. |
| 76 | NOTIMPLEMENTED(); |
| 77 | LOG(ERROR) << "ContextResult::kFatalFailure: no fuchsia support"; |
| 78 | return gpu::ContextResult::kFatalFailure; |
| 79 | #else |
| 80 | TRACE_EVENT0("gpu", "RasterBufferStub::Initialize"); |
| 81 | FastSetActiveURL(active_url_, active_url_hash_, channel_); |
| 82 | |
| 83 | GpuChannelManager* manager = channel_->gpu_channel_manager(); |
| 84 | DCHECK(manager); |
| 85 | |
| 86 | if (share_command_buffer_stub) { |
Khushal | 99831df | 2018-06-28 01:25:02 | [diff] [blame] | 87 | LOG(ERROR) << "Using a share group is not supported with RasterDecoder"; |
| 88 | return ContextResult::kFatalFailure; |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 89 | } |
| 90 | |
Khushal | db2d4ad7 | 2018-07-03 22:36:27 | [diff] [blame^] | 91 | if (surface_handle_ != kNullSurfaceHandle) { |
| 92 | LOG(ERROR) << "ContextResult::kFatalFailure: " |
| 93 | "RenderInterface clients must render offscreen."; |
| 94 | return gpu::ContextResult::kFatalFailure; |
| 95 | } |
| 96 | |
Khushal | 99831df | 2018-06-28 01:25:02 | [diff] [blame] | 97 | scoped_refptr<gles2::FeatureInfo> feature_info = new gles2::FeatureInfo( |
| 98 | manager->gpu_driver_bug_workarounds(), manager->gpu_feature_info()); |
| 99 | gpu::GpuMemoryBufferFactory* gmb_factory = |
| 100 | manager->gpu_memory_buffer_factory(); |
| 101 | context_group_ = new gles2::ContextGroup( |
| 102 | manager->gpu_preferences(), gles2::PassthroughCommandDecoderSupported(), |
| 103 | manager->mailbox_manager(), CreateMemoryTracker(init_params), |
| 104 | manager->shader_translator_cache(), |
| 105 | manager->framebuffer_completeness_cache(), feature_info, |
| 106 | init_params.attribs.bind_generates_resource, channel_->image_manager(), |
| 107 | gmb_factory ? gmb_factory->AsImageFactory() : nullptr, |
| 108 | manager->watchdog() /* progress_reporter */, manager->gpu_feature_info(), |
| 109 | manager->discardable_manager()); |
| 110 | |
Khushal | db2d4ad7 | 2018-07-03 22:36:27 | [diff] [blame^] | 111 | ContextResult result; |
| 112 | auto raster_decoder_context_state = |
| 113 | manager->GetRasterDecoderContextState(init_params.attribs, &result); |
| 114 | if (!raster_decoder_context_state) { |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 115 | LOG(ERROR) << "ContextResult::kFatalFailure: " |
Khushal | db2d4ad7 | 2018-07-03 22:36:27 | [diff] [blame^] | 116 | "Failed to create raster decoder state."; |
| 117 | DCHECK_NE(result, gpu::ContextResult::kSuccess); |
| 118 | return result; |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 119 | } |
| 120 | |
Khushal | db2d4ad7 | 2018-07-03 22:36:27 | [diff] [blame^] | 121 | surface_ = raster_decoder_context_state->surface; |
| 122 | share_group_ = raster_decoder_context_state->share_group; |
| 123 | use_virtualized_gl_context_ = |
| 124 | raster_decoder_context_state->use_virtualized_gl_contexts; |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 125 | |
| 126 | command_buffer_ = std::make_unique<CommandBufferService>( |
| 127 | this, context_group_->transfer_buffer_manager()); |
Jonathan Backer | 7471b278 | 2018-01-25 18:14:19 | [diff] [blame] | 128 | std::unique_ptr<raster::RasterDecoder> decoder(raster::RasterDecoder::Create( |
Khushal | db2d4ad7 | 2018-07-03 22:36:27 | [diff] [blame^] | 129 | this, command_buffer_.get(), manager->outputter(), context_group_.get(), |
| 130 | raster_decoder_context_state)); |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 131 | |
| 132 | sync_point_client_state_ = |
| 133 | channel_->sync_point_manager()->CreateSyncPointClientState( |
| 134 | CommandBufferNamespace::GPU_IO, command_buffer_id_, sequence_id_); |
| 135 | |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 136 | // TODO(sunnyps): Should this use ScopedCrashKey instead? |
Robert Sesek | d732922 | 2017-12-08 15:31:08 | [diff] [blame] | 137 | crash_keys::gpu_gl_context_is_virtual.Set(use_virtualized_gl_context_ ? "1" |
| 138 | : "0"); |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 139 | |
Khushal | db2d4ad7 | 2018-07-03 22:36:27 | [diff] [blame^] | 140 | scoped_refptr<gl::GLContext> context = raster_decoder_context_state->context; |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 141 | if (use_virtualized_gl_context_) { |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 142 | context = base::MakeRefCounted<GLContextVirtual>( |
Jonathan Backer | 1d807a4 | 2018-01-08 20:45:54 | [diff] [blame] | 143 | share_group_.get(), context.get(), decoder->AsWeakPtr()); |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 144 | if (!context->Initialize(surface_.get(), |
| 145 | GenerateGLContextAttribs(init_params.attribs, |
| 146 | context_group_.get()))) { |
| 147 | // The real context created above for the default offscreen surface |
| 148 | // might not be compatible with this surface. |
| 149 | context = nullptr; |
| 150 | // TODO(piman): This might not be fatal, we could recurse into |
| 151 | // CreateGLContext to get more info, tho it should be exceedingly |
| 152 | // rare and may not be recoverable anyway. |
| 153 | LOG(ERROR) << "ContextResult::kFatalFailure: " |
| 154 | "Failed to initialize virtual GL context."; |
| 155 | return gpu::ContextResult::kFatalFailure; |
| 156 | } |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 157 | |
Khushal | db2d4ad7 | 2018-07-03 22:36:27 | [diff] [blame^] | 158 | context->SetGLStateRestorer(new GLStateRestorerImpl(decoder->AsWeakPtr())); |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 159 | } |
| 160 | |
| 161 | if (!context->MakeCurrent(surface_.get())) { |
| 162 | LOG(ERROR) << "ContextResult::kTransientFailure: " |
| 163 | "Failed to make context current."; |
| 164 | return gpu::ContextResult::kTransientFailure; |
| 165 | } |
| 166 | |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 167 | if (!context_group_->has_program_cache() && |
| 168 | !context_group_->feature_info()->workarounds().disable_program_cache) { |
| 169 | context_group_->set_program_cache(manager->program_cache()); |
| 170 | } |
| 171 | |
| 172 | // Initialize the decoder with either the view or pbuffer GLContext. |
Khushal | db2d4ad7 | 2018-07-03 22:36:27 | [diff] [blame^] | 173 | result = decoder->Initialize(surface_, context, true /* offscreen */, |
| 174 | gpu::gles2::DisallowedFeatures(), |
| 175 | init_params.attribs); |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 176 | if (result != gpu::ContextResult::kSuccess) { |
| 177 | DLOG(ERROR) << "Failed to initialize decoder."; |
| 178 | return result; |
| 179 | } |
| 180 | |
| 181 | if (manager->gpu_preferences().enable_gpu_service_logging) { |
Jonathan Backer | 0cd1c432 | 2018-04-17 16:57:10 | [diff] [blame] | 182 | decoder->SetLogCommands(true); |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 183 | } |
Jonathan Backer | 1d807a4 | 2018-01-08 20:45:54 | [diff] [blame] | 184 | set_decoder_context(std::move(decoder)); |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 185 | |
| 186 | const size_t kSharedStateSize = sizeof(CommandBufferSharedState); |
| 187 | if (!shared_state_shm->Map(kSharedStateSize)) { |
| 188 | LOG(ERROR) << "ContextResult::kFatalFailure: " |
| 189 | "Failed to map shared state buffer."; |
| 190 | return gpu::ContextResult::kFatalFailure; |
| 191 | } |
| 192 | command_buffer_->SetSharedStateBuffer(MakeBackingFromSharedMemory( |
| 193 | std::move(shared_state_shm), kSharedStateSize)); |
| 194 | |
| 195 | if (!active_url_.is_empty()) |
| 196 | manager->delegate()->DidCreateOffscreenContext(active_url_); |
| 197 | |
| 198 | if (use_virtualized_gl_context_) { |
| 199 | // If virtualized GL contexts are in use, then real GL context state |
| 200 | // is in an indeterminate state, since the GLStateRestorer was not |
| 201 | // initialized at the time the GLContextVirtual was made current. In |
| 202 | // the case that this command decoder is the next one to be |
| 203 | // processed, force a "full virtual" MakeCurrent to be performed. |
| 204 | // Note that GpuChannel's initialization of the gpu::Capabilities |
| 205 | // expects the context to be left current. |
| 206 | context->ForceReleaseVirtuallyCurrent(); |
| 207 | if (!context->MakeCurrent(surface_.get())) { |
| 208 | LOG(ERROR) << "ContextResult::kTransientFailure: " |
| 209 | "Failed to make context current after initialization."; |
| 210 | return gpu::ContextResult::kTransientFailure; |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | manager->delegate()->DidCreateContextSuccessfully(); |
| 215 | initialized_ = true; |
| 216 | return gpu::ContextResult::kSuccess; |
| 217 | #endif // defined(OS_FUCHSIA) |
| 218 | } |
| 219 | |
Jonathan Backer | 4d9fb08 | 2018-01-09 16:38:33 | [diff] [blame] | 220 | // RasterInterface clients should not manipulate the front buffer. |
| 221 | void RasterCommandBufferStub::OnTakeFrontBuffer(const Mailbox& mailbox) { |
| 222 | NOTREACHED(); |
| 223 | } |
| 224 | void RasterCommandBufferStub::OnReturnFrontBuffer(const Mailbox& mailbox, |
| 225 | bool is_lost) { |
| 226 | NOTREACHED(); |
| 227 | } |
| 228 | |
Eric Karl | b6b2c63 | 2018-05-07 22:45:04 | [diff] [blame] | 229 | void RasterCommandBufferStub::OnSwapBuffers(uint64_t swap_id, uint32_t flags) {} |
Peng Huang | 2a30e26 | 2018-05-02 21:08:59 | [diff] [blame] | 230 | |
Jonathan Backer | be0b63a | 2017-12-05 20:40:41 | [diff] [blame] | 231 | } // namespace gpu |