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.
5 #include "components/mus/gles2/command_buffer_local.h"
8 #include "components/mus/gles2/command_buffer_local_client.h"
9 #include "components/mus/gles2/gpu_memory_tracker.h"
10 #include "components/mus/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/transfer_buffer_manager.h"
19 #include "gpu/command_buffer/service/valuebuffer_manager.h"
20 #include "ui/gfx/vsync_provider.h"
21 #include "ui/gl/gl_context.h"
22 #include "ui/gl/gl_image_memory.h"
23 #include "ui/gl/gl_surface.h"
27 const unsigned int GL_MAP_CHROMIUM
= 0x78F1;
29 CommandBufferLocal::CommandBufferLocal(CommandBufferLocalClient
* client
,
30 gfx::AcceleratedWidget widget
,
31 const scoped_refptr
<GpuState
>& gpu_state
)
33 gpu_state_(gpu_state
),
35 weak_factory_(this) {}
37 CommandBufferLocal::~CommandBufferLocal() {
38 command_buffer_
.reset();
40 bool have_context
= decoder_
->GetGLContext()->MakeCurrent(surface_
.get());
41 decoder_
->Destroy(have_context
);
46 bool CommandBufferLocal::Initialize() {
47 if (widget_
== gfx::kNullAcceleratedWidget
) {
48 surface_
= gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
50 surface_
= gfx::GLSurface::CreateViewGLSurface(widget_
);
51 gfx::VSyncProvider
* vsync_provider
=
52 surface_
? surface_
->GetVSyncProvider() : nullptr;
54 vsync_provider
->GetVSyncParameters(
55 base::Bind(&CommandBufferLocal::OnUpdateVSyncParameters
,
56 weak_factory_
.GetWeakPtr()));
63 // TODO(piman): virtual contexts, gpu preference.
64 context_
= gfx::GLContext::CreateGLContext(
65 gpu_state_
->share_group(), surface_
.get(), gfx::PreferIntegratedGpu
);
69 if (!context_
->MakeCurrent(surface_
.get()))
72 // TODO(piman): ShaderTranslatorCache is currently per-ContextGroup but
73 // only needs to be per-thread.
74 bool bind_generates_resource
= false;
75 scoped_refptr
<gpu::gles2::ContextGroup
> context_group
=
76 new gpu::gles2::ContextGroup(
77 gpu_state_
->mailbox_manager(), new GpuMemoryTracker
,
78 new gpu::gles2::ShaderTranslatorCache
,
79 new gpu::gles2::FramebufferCompletenessCache
, nullptr, nullptr,
80 nullptr, bind_generates_resource
);
82 command_buffer_
.reset(
83 new gpu::CommandBufferService(context_group
->transfer_buffer_manager()));
84 bool result
= command_buffer_
->Initialize();
87 decoder_
.reset(::gpu::gles2::GLES2Decoder::Create(context_group
.get()));
88 scheduler_
.reset(new gpu::GpuScheduler(command_buffer_
.get(), decoder_
.get(),
90 decoder_
->set_engine(scheduler_
.get());
91 decoder_
->SetResizeCallback(
92 base::Bind(&CommandBufferLocal::OnResize
, base::Unretained(this)));
93 decoder_
->SetWaitSyncPointCallback(
94 base::Bind(&CommandBufferLocal::OnWaitSyncPoint
, base::Unretained(this)));
96 gpu::gles2::DisallowedFeatures disallowed_features
;
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
,
105 command_buffer_
->SetPutOffsetChangeCallback(
106 base::Bind(&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)));
114 gpu::CommandBuffer
* CommandBufferLocal::GetCommandBuffer() {
115 return command_buffer_
.get();
118 /******************************************************************************/
120 /******************************************************************************/
122 gpu::Capabilities
CommandBufferLocal::GetCapabilities() {
123 return decoder_
->GetCapabilities();
126 int32_t CommandBufferLocal::CreateImage(ClientBuffer buffer
,
129 unsigned internalformat
) {
130 MojoGpuMemoryBufferImpl
* gpu_memory_buffer
=
131 MojoGpuMemoryBufferImpl::FromClientBuffer(buffer
);
133 scoped_refptr
<gfx::GLImageMemory
> image(new gfx::GLImageMemory(
134 gfx::Size(static_cast<int>(width
), static_cast<int>(height
)),
136 if (!image
->Initialize(
137 static_cast<const unsigned char*>(gpu_memory_buffer
->GetMemory()),
138 gpu_memory_buffer
->GetFormat())) {
142 static int32 next_id
= 1;
143 int32 new_id
= next_id
++;
145 gpu::gles2::ImageManager
* image_manager
= decoder_
->GetImageManager();
146 DCHECK(image_manager
);
147 image_manager
->AddImage(image
.get(), new_id
);
151 void CommandBufferLocal::DestroyImage(int32 id
) {
152 gpu::gles2::ImageManager
* image_manager
= decoder_
->GetImageManager();
153 DCHECK(image_manager
);
154 image_manager
->RemoveImage(id
);
157 int32_t CommandBufferLocal::CreateGpuMemoryBufferImage(size_t width
,
159 unsigned internalformat
,
161 DCHECK_EQ(usage
, static_cast<unsigned>(GL_MAP_CHROMIUM
));
162 scoped_ptr
<gfx::GpuMemoryBuffer
> buffer(MojoGpuMemoryBufferImpl::Create(
163 gfx::Size(static_cast<int>(width
), static_cast<int>(height
)),
164 gpu::ImageFactory::DefaultBufferFormatForImageFormat(internalformat
),
165 gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage
)));
168 return CreateImage(buffer
->AsClientBuffer(), width
, height
, internalformat
);
171 uint32_t CommandBufferLocal::InsertSyncPoint() {
175 uint32_t CommandBufferLocal::InsertFutureSyncPoint() {
180 void CommandBufferLocal::RetireSyncPoint(uint32_t sync_point
) {
184 void CommandBufferLocal::SignalSyncPoint(uint32_t sync_point
,
185 const base::Closure
& callback
) {}
187 void CommandBufferLocal::SignalQuery(uint32_t query
,
188 const base::Closure
& callback
) {
193 void CommandBufferLocal::SetSurfaceVisible(bool visible
) {
198 uint32_t CommandBufferLocal::CreateStreamTexture(uint32_t texture_id
) {
204 void CommandBufferLocal::SetLock(base::Lock
* lock
) {
208 bool CommandBufferLocal::IsGpuChannelLost() {
209 // This is only possible for out-of-process command buffers.
213 gpu::CommandBufferNamespace
CommandBufferLocal::GetNamespaceID() const {
215 return gpu::CommandBufferNamespace::INVALID
;
218 uint64_t CommandBufferLocal::GetCommandBufferID() const {
223 void CommandBufferLocal::PumpCommands() {
224 if (!decoder_
->MakeCurrent()) {
225 command_buffer_
->SetContextLostReason(decoder_
->GetContextLostReason());
226 command_buffer_
->SetParseError(::gpu::error::kLostContext
);
229 scheduler_
->PutChanged();
232 void CommandBufferLocal::OnResize(gfx::Size size
, float scale_factor
) {
233 surface_
->Resize(size
);
236 void CommandBufferLocal::OnUpdateVSyncParameters(
237 const base::TimeTicks timebase
,
238 const base::TimeDelta interval
) {
240 client_
->UpdateVSyncParameters(timebase
.ToInternalValue(),
241 interval
.ToInternalValue());
244 bool CommandBufferLocal::OnWaitSyncPoint(uint32_t sync_point
) {
247 if (gpu_state_
->sync_point_manager()->IsSyncPointRetired(sync_point
))
249 scheduler_
->SetScheduled(false);
250 gpu_state_
->sync_point_manager()->AddSyncPointCallback(
251 sync_point
, base::Bind(&CommandBufferLocal::OnSyncPointRetired
,
252 weak_factory_
.GetWeakPtr()));
253 return scheduler_
->scheduled();
256 void CommandBufferLocal::OnParseError() {
257 gpu::CommandBuffer::State state
= command_buffer_
->GetLastState();
258 OnContextLost(state
.context_lost_reason
);
261 void CommandBufferLocal::OnContextLost(uint32_t reason
) {
263 client_
->DidLoseContext();
266 void CommandBufferLocal::OnSyncPointRetired() {
267 scheduler_
->SetScheduled(true);