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/view_manager/gles2/command_buffer_local.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/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(
30 CommandBufferLocalClient
* client
,
31 gfx::AcceleratedWidget widget
,
32 const scoped_refptr
<gles2::GpuState
>& gpu_state
)
34 gpu_state_(gpu_state
),
39 CommandBufferLocal::~CommandBufferLocal() {
40 command_buffer_
.reset();
42 bool have_context
= decoder_
->GetGLContext()->MakeCurrent(surface_
.get());
43 decoder_
->Destroy(have_context
);
48 bool CommandBufferLocal::Initialize() {
49 if (widget_
== gfx::kNullAcceleratedWidget
) {
50 surface_
= gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
52 surface_
= gfx::GLSurface::CreateViewGLSurface(widget_
);
53 gfx::VSyncProvider
* vsync_provider
=
54 surface_
? surface_
->GetVSyncProvider() : nullptr;
56 vsync_provider
->GetVSyncParameters(
57 base::Bind(&CommandBufferLocal::OnUpdateVSyncParameters
,
58 weak_factory_
.GetWeakPtr()));
65 // TODO(piman): virtual contexts, gpu preference.
66 context_
= gfx::GLContext::CreateGLContext(
67 gpu_state_
->share_group(), surface_
.get(), gfx::PreferIntegratedGpu
);
71 if (!context_
->MakeCurrent(surface_
.get()))
74 // TODO(piman): ShaderTranslatorCache is currently per-ContextGroup but
75 // only needs to be per-thread.
76 bool bind_generates_resource
= false;
77 scoped_refptr
<gpu::gles2::ContextGroup
> context_group
=
78 new gpu::gles2::ContextGroup(
79 gpu_state_
->mailbox_manager(), new gles2::GpuMemoryTracker
,
80 new gpu::gles2::ShaderTranslatorCache
,
81 new gpu::gles2::FramebufferCompletenessCache
, nullptr, nullptr,
82 nullptr, bind_generates_resource
);
84 command_buffer_
.reset(
85 new gpu::CommandBufferService(context_group
->transfer_buffer_manager()));
86 bool result
= command_buffer_
->Initialize();
89 decoder_
.reset(::gpu::gles2::GLES2Decoder::Create(context_group
.get()));
90 scheduler_
.reset(new gpu::GpuScheduler(command_buffer_
.get(), decoder_
.get(),
92 decoder_
->set_engine(scheduler_
.get());
93 decoder_
->SetResizeCallback(
94 base::Bind(&CommandBufferLocal::OnResize
, base::Unretained(this)));
95 decoder_
->SetWaitSyncPointCallback(base::Bind(
96 &CommandBufferLocal::OnWaitSyncPoint
, base::Unretained(this)));
98 gpu::gles2::DisallowedFeatures disallowed_features
;
100 // TODO(piman): attributes.
101 std::vector
<int32
> attrib_vector
;
102 if (!decoder_
->Initialize(surface_
, context_
, false /* offscreen */,
103 gfx::Size(1, 1), disallowed_features
,
107 command_buffer_
->SetPutOffsetChangeCallback(base::Bind(
108 &CommandBufferLocal::PumpCommands
, base::Unretained(this)));
109 command_buffer_
->SetGetBufferChangeCallback(base::Bind(
110 &gpu::GpuScheduler::SetGetBuffer
, base::Unretained(scheduler_
.get())));
111 command_buffer_
->SetParseErrorCallback(
112 base::Bind(&CommandBufferLocal::OnParseError
, base::Unretained(this)));
116 gpu::CommandBuffer
* CommandBufferLocal::GetCommandBuffer() {
117 return command_buffer_
.get();
120 /******************************************************************************/
122 /******************************************************************************/
124 gpu::Capabilities
CommandBufferLocal::GetCapabilities() {
125 return decoder_
->GetCapabilities();
128 int32_t CommandBufferLocal::CreateImage(ClientBuffer buffer
,
131 unsigned internalformat
) {
132 gles2::MojoGpuMemoryBufferImpl
* gpu_memory_buffer
=
133 gles2::MojoGpuMemoryBufferImpl::FromClientBuffer(buffer
);
135 scoped_refptr
<gfx::GLImageMemory
> image(new gfx::GLImageMemory(
136 gfx::Size(static_cast<int>(width
), static_cast<int>(height
)),
138 if (!image
->Initialize(
139 static_cast<const unsigned char*>(gpu_memory_buffer
->GetMemory()),
140 gpu_memory_buffer
->GetFormat())) {
144 static int32 next_id
= 1;
145 int32 new_id
= next_id
++;
147 gpu::gles2::ImageManager
* image_manager
= decoder_
->GetImageManager();
148 DCHECK(image_manager
);
149 image_manager
->AddImage(image
.get(), new_id
);
153 void CommandBufferLocal::DestroyImage(int32 id
) {
154 gpu::gles2::ImageManager
* image_manager
= decoder_
->GetImageManager();
155 DCHECK(image_manager
);
156 image_manager
->RemoveImage(id
);
159 int32_t CommandBufferLocal::CreateGpuMemoryBufferImage(
162 unsigned internalformat
,
164 DCHECK_EQ(usage
, static_cast<unsigned>(GL_MAP_CHROMIUM
));
165 scoped_ptr
<gfx::GpuMemoryBuffer
> buffer(
166 gles2::MojoGpuMemoryBufferImpl::Create(
167 gfx::Size(static_cast<int>(width
), static_cast<int>(height
)),
168 gpu::ImageFactory::DefaultBufferFormatForImageFormat(internalformat
),
169 gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage
)));
172 return CreateImage(buffer
->AsClientBuffer(), width
, height
, internalformat
);
175 uint32_t CommandBufferLocal::InsertSyncPoint() {
179 uint32_t CommandBufferLocal::InsertFutureSyncPoint() {
184 void CommandBufferLocal::RetireSyncPoint(uint32_t sync_point
) {
188 void CommandBufferLocal::SignalSyncPoint(uint32_t sync_point
,
189 const base::Closure
& callback
) {
192 void CommandBufferLocal::SignalQuery(uint32_t query
,
193 const base::Closure
& callback
) {
198 void CommandBufferLocal::SetSurfaceVisible(bool visible
) {
203 uint32_t CommandBufferLocal::CreateStreamTexture(uint32_t texture_id
) {
209 void CommandBufferLocal::SetLock(base::Lock
* lock
) {
213 bool CommandBufferLocal::IsGpuChannelLost() {
214 // This is only possible for out-of-process command buffers.
218 void CommandBufferLocal::PumpCommands() {
219 if (!decoder_
->MakeCurrent()) {
220 command_buffer_
->SetContextLostReason(decoder_
->GetContextLostReason());
221 command_buffer_
->SetParseError(::gpu::error::kLostContext
);
224 scheduler_
->PutChanged();
227 void CommandBufferLocal::OnResize(gfx::Size size
, float scale_factor
) {
228 surface_
->Resize(size
);
231 void CommandBufferLocal::OnUpdateVSyncParameters(
232 const base::TimeTicks timebase
,
233 const base::TimeDelta interval
) {
235 client_
->UpdateVSyncParameters(timebase
.ToInternalValue(),
236 interval
.ToInternalValue());
240 bool CommandBufferLocal::OnWaitSyncPoint(uint32_t sync_point
) {
243 if (gpu_state_
->sync_point_manager()->IsSyncPointRetired(sync_point
))
245 scheduler_
->SetScheduled(false);
246 gpu_state_
->sync_point_manager()->AddSyncPointCallback(
247 sync_point
, base::Bind(&CommandBufferLocal::OnSyncPointRetired
,
248 weak_factory_
.GetWeakPtr()));
249 return scheduler_
->IsScheduled();
252 void CommandBufferLocal::OnParseError() {
253 gpu::CommandBuffer::State state
= command_buffer_
->GetLastState();
254 OnContextLost(state
.context_lost_reason
);
257 void CommandBufferLocal::OnContextLost(uint32_t reason
) {
259 client_
->DidLoseContext();
262 void CommandBufferLocal::OnSyncPointRetired() {
263 scheduler_
->SetScheduled(true);