OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 "components/view_manager/gles2/command_buffer_local.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "components/view_manager/gles2/command_buffer_local_client.h" |
| 9 #include "components/view_manager/gles2/gpu_memory_tracker.h" |
| 10 #include "components/view_manager/gles2/mojo_gpu_memory_buffer.h" |
| 11 #include "gpu/command_buffer/service/command_buffer_service.h" |
| 12 #include "gpu/command_buffer/service/context_group.h" |
| 13 #include "gpu/command_buffer/service/gpu_scheduler.h" |
| 14 #include "gpu/command_buffer/service/image_factory.h" |
| 15 #include "gpu/command_buffer/service/image_manager.h" |
| 16 #include "gpu/command_buffer/service/memory_tracking.h" |
| 17 #include "gpu/command_buffer/service/shader_translator_cache.h" |
| 18 #include "gpu/command_buffer/service/valuebuffer_manager.h" |
| 19 #include "ui/gfx/vsync_provider.h" |
| 20 #include "ui/gl/gl_context.h" |
| 21 #include "ui/gl/gl_image_memory.h" |
| 22 #include "ui/gl/gl_surface.h" |
| 23 |
| 24 namespace gles2 { |
| 25 |
| 26 const unsigned int GL_MAP_CHROMIUM = 0x78F1; |
| 27 |
| 28 CommandBufferLocal::CommandBufferLocal( |
| 29 CommandBufferLocalClient* client, |
| 30 gfx::AcceleratedWidget widget, |
| 31 const scoped_refptr<gles2::GpuState>& gpu_state) |
| 32 : widget_(widget), |
| 33 gpu_state_(gpu_state), |
| 34 client_(client), |
| 35 weak_factory_(this) { |
| 36 } |
| 37 |
| 38 CommandBufferLocal::~CommandBufferLocal() { |
| 39 command_buffer_.reset(); |
| 40 if (decoder_.get()) { |
| 41 bool have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get()); |
| 42 decoder_->Destroy(have_context); |
| 43 decoder_.reset(); |
| 44 } |
| 45 } |
| 46 |
| 47 bool CommandBufferLocal::Initialize() { |
| 48 if (widget_ == gfx::kNullAcceleratedWidget) { |
| 49 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); |
| 50 } else { |
| 51 surface_ = gfx::GLSurface::CreateViewGLSurface(widget_); |
| 52 gfx::VSyncProvider* vsync_provider = |
| 53 surface_ ? surface_->GetVSyncProvider() : nullptr; |
| 54 if (vsync_provider) { |
| 55 vsync_provider->GetVSyncParameters( |
| 56 base::Bind(&CommandBufferLocal::OnUpdateVSyncParameters, |
| 57 weak_factory_.GetWeakPtr())); |
| 58 } |
| 59 } |
| 60 |
| 61 if (!surface_.get()) |
| 62 return false; |
| 63 |
| 64 // TODO(piman): virtual contexts, gpu preference. |
| 65 context_ = gfx::GLContext::CreateGLContext( |
| 66 gpu_state_->share_group(), surface_.get(), gfx::PreferIntegratedGpu); |
| 67 if (!context_.get()) |
| 68 return false; |
| 69 |
| 70 if (!context_->MakeCurrent(surface_.get())) |
| 71 return false; |
| 72 |
| 73 // TODO(piman): ShaderTranslatorCache is currently per-ContextGroup but |
| 74 // only needs to be per-thread. |
| 75 bool bind_generates_resource = false; |
| 76 scoped_refptr<gpu::gles2::ContextGroup> context_group = |
| 77 new gpu::gles2::ContextGroup( |
| 78 gpu_state_->mailbox_manager(), new gles2::GpuMemoryTracker, |
| 79 new gpu::gles2::ShaderTranslatorCache, nullptr, nullptr, nullptr, |
| 80 bind_generates_resource); |
| 81 |
| 82 command_buffer_.reset( |
| 83 new gpu::CommandBufferService(context_group->transfer_buffer_manager())); |
| 84 bool result = command_buffer_->Initialize(); |
| 85 DCHECK(result); |
| 86 |
| 87 decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group.get())); |
| 88 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), decoder_.get(), |
| 89 decoder_.get())); |
| 90 decoder_->set_engine(scheduler_.get()); |
| 91 decoder_->SetResizeCallback( |
| 92 base::Bind(&CommandBufferLocal::OnResize, base::Unretained(this))); |
| 93 decoder_->SetWaitSyncPointCallback(base::Bind( |
| 94 &CommandBufferLocal::OnWaitSyncPoint, base::Unretained(this))); |
| 95 |
| 96 gpu::gles2::DisallowedFeatures disallowed_features; |
| 97 |
| 98 // TODO(piman): attributes. |
| 99 std::vector<int32> attrib_vector; |
| 100 if (!decoder_->Initialize(surface_, context_, false /* offscreen */, |
| 101 gfx::Size(1, 1), disallowed_features, |
| 102 attrib_vector)) |
| 103 return false; |
| 104 |
| 105 command_buffer_->SetPutOffsetChangeCallback(base::Bind( |
| 106 &CommandBufferLocal::PumpCommands, base::Unretained(this))); |
| 107 command_buffer_->SetGetBufferChangeCallback(base::Bind( |
| 108 &gpu::GpuScheduler::SetGetBuffer, base::Unretained(scheduler_.get()))); |
| 109 command_buffer_->SetParseErrorCallback( |
| 110 base::Bind(&CommandBufferLocal::OnParseError, base::Unretained(this))); |
| 111 return true; |
| 112 } |
| 113 |
| 114 gpu::CommandBuffer* CommandBufferLocal::GetCommandBuffer() { |
| 115 return command_buffer_.get(); |
| 116 } |
| 117 |
| 118 /******************************************************************************/ |
| 119 // gpu::GpuControl: |
| 120 /******************************************************************************/ |
| 121 |
| 122 gpu::Capabilities CommandBufferLocal::GetCapabilities() { |
| 123 return decoder_->GetCapabilities(); |
| 124 } |
| 125 |
| 126 int32_t CommandBufferLocal::CreateImage(ClientBuffer buffer, |
| 127 size_t width, |
| 128 size_t height, |
| 129 unsigned internalformat) { |
| 130 gles2::MojoGpuMemoryBufferImpl* gpu_memory_buffer = |
| 131 gles2::MojoGpuMemoryBufferImpl::FromClientBuffer(buffer); |
| 132 |
| 133 scoped_refptr<gfx::GLImageMemory> image( |
| 134 new gfx::GLImageMemory(gfx::Size(width, height), |
| 135 internalformat)); |
| 136 if (!image->Initialize( |
| 137 static_cast<const unsigned char*>(gpu_memory_buffer->GetMemory()), |
| 138 gpu_memory_buffer->GetFormat())) { |
| 139 return -1; |
| 140 } |
| 141 |
| 142 static int32 next_id = 1; |
| 143 int32 new_id = next_id++; |
| 144 |
| 145 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); |
| 146 DCHECK(image_manager); |
| 147 image_manager->AddImage(image.get(), new_id); |
| 148 return new_id; |
| 149 } |
| 150 |
| 151 void CommandBufferLocal::DestroyImage(int32 id) { |
| 152 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); |
| 153 DCHECK(image_manager); |
| 154 image_manager->RemoveImage(id); |
| 155 } |
| 156 |
| 157 int32_t CommandBufferLocal::CreateGpuMemoryBufferImage( |
| 158 size_t width, |
| 159 size_t height, |
| 160 unsigned internalformat, |
| 161 unsigned usage) { |
| 162 DCHECK_EQ(usage, static_cast<unsigned>(GL_MAP_CHROMIUM)); |
| 163 scoped_ptr<gfx::GpuMemoryBuffer> buffer( |
| 164 gles2::MojoGpuMemoryBufferImpl::Create( |
| 165 gfx::Size(width, height), |
| 166 gpu::ImageFactory::ImageFormatToGpuMemoryBufferFormat(internalformat), |
| 167 gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage))); |
| 168 if (!buffer) |
| 169 return -1; |
| 170 return CreateImage(buffer->AsClientBuffer(), width, height, internalformat); |
| 171 } |
| 172 |
| 173 uint32_t CommandBufferLocal::InsertSyncPoint() { |
| 174 return 0; |
| 175 } |
| 176 |
| 177 uint32_t CommandBufferLocal::InsertFutureSyncPoint() { |
| 178 NOTIMPLEMENTED(); |
| 179 return 0; |
| 180 } |
| 181 |
| 182 void CommandBufferLocal::RetireSyncPoint(uint32_t sync_point) { |
| 183 NOTIMPLEMENTED(); |
| 184 } |
| 185 |
| 186 void CommandBufferLocal::SignalSyncPoint(uint32_t sync_point, |
| 187 const base::Closure& callback) { |
| 188 } |
| 189 |
| 190 void CommandBufferLocal::SignalQuery(uint32_t query, |
| 191 const base::Closure& callback) { |
| 192 // TODO(piman) |
| 193 NOTIMPLEMENTED(); |
| 194 } |
| 195 |
| 196 void CommandBufferLocal::SetSurfaceVisible(bool visible) { |
| 197 // TODO(piman) |
| 198 NOTIMPLEMENTED(); |
| 199 } |
| 200 |
| 201 uint32_t CommandBufferLocal::CreateStreamTexture(uint32_t texture_id) { |
| 202 // TODO(piman) |
| 203 NOTIMPLEMENTED(); |
| 204 return 0; |
| 205 } |
| 206 |
| 207 void CommandBufferLocal::SetLock(base::Lock* lock) { |
| 208 NOTIMPLEMENTED(); |
| 209 } |
| 210 |
| 211 bool CommandBufferLocal::IsGpuChannelLost() { |
| 212 // This is only possible for out-of-process command buffers. |
| 213 return false; |
| 214 } |
| 215 |
| 216 void CommandBufferLocal::PumpCommands() { |
| 217 if (!decoder_->MakeCurrent()) { |
| 218 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); |
| 219 command_buffer_->SetParseError(::gpu::error::kLostContext); |
| 220 return; |
| 221 } |
| 222 scheduler_->PutChanged(); |
| 223 } |
| 224 |
| 225 void CommandBufferLocal::OnResize(gfx::Size size, float scale_factor) { |
| 226 surface_->Resize(size); |
| 227 } |
| 228 |
| 229 void CommandBufferLocal::OnUpdateVSyncParameters( |
| 230 const base::TimeTicks timebase, |
| 231 const base::TimeDelta interval) { |
| 232 if (client_) |
| 233 client_->UpdateVSyncParameters(timebase.ToInternalValue(), |
| 234 interval.ToInternalValue()); |
| 235 |
| 236 } |
| 237 |
| 238 bool CommandBufferLocal::OnWaitSyncPoint(uint32_t sync_point) { |
| 239 if (!sync_point) |
| 240 return true; |
| 241 if (gpu_state_->sync_point_manager()->IsSyncPointRetired(sync_point)) |
| 242 return true; |
| 243 scheduler_->SetScheduled(false); |
| 244 gpu_state_->sync_point_manager()->AddSyncPointCallback( |
| 245 sync_point, base::Bind(&CommandBufferLocal::OnSyncPointRetired, |
| 246 weak_factory_.GetWeakPtr())); |
| 247 return scheduler_->IsScheduled(); |
| 248 } |
| 249 |
| 250 void CommandBufferLocal::OnParseError() { |
| 251 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); |
| 252 OnContextLost(state.context_lost_reason); |
| 253 } |
| 254 |
| 255 void CommandBufferLocal::OnContextLost(uint32_t reason) { |
| 256 if (client_) |
| 257 client_->DidLoseContext(); |
| 258 } |
| 259 |
| 260 void CommandBufferLocal::OnSyncPointRetired() { |
| 261 scheduler_->SetScheduled(true); |
| 262 } |
| 263 |
| 264 } // namespace gles2 |
OLD | NEW |