| Index: components/view_manager/gles2/command_buffer_local.cc
|
| diff --git a/components/view_manager/gles2/command_buffer_local.cc b/components/view_manager/gles2/command_buffer_local.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..02e58aab3d0e49277e0bd667520f5e38093aaf68
|
| --- /dev/null
|
| +++ b/components/view_manager/gles2/command_buffer_local.cc
|
| @@ -0,0 +1,264 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "components/view_manager/gles2/command_buffer_local.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "components/view_manager/gles2/command_buffer_local_client.h"
|
| +#include "components/view_manager/gles2/gpu_memory_tracker.h"
|
| +#include "components/view_manager/gles2/mojo_gpu_memory_buffer.h"
|
| +#include "gpu/command_buffer/service/command_buffer_service.h"
|
| +#include "gpu/command_buffer/service/context_group.h"
|
| +#include "gpu/command_buffer/service/gpu_scheduler.h"
|
| +#include "gpu/command_buffer/service/image_factory.h"
|
| +#include "gpu/command_buffer/service/image_manager.h"
|
| +#include "gpu/command_buffer/service/memory_tracking.h"
|
| +#include "gpu/command_buffer/service/shader_translator_cache.h"
|
| +#include "gpu/command_buffer/service/valuebuffer_manager.h"
|
| +#include "ui/gfx/vsync_provider.h"
|
| +#include "ui/gl/gl_context.h"
|
| +#include "ui/gl/gl_image_memory.h"
|
| +#include "ui/gl/gl_surface.h"
|
| +
|
| +namespace gles2 {
|
| +
|
| +const unsigned int GL_MAP_CHROMIUM = 0x78F1;
|
| +
|
| +CommandBufferLocal::CommandBufferLocal(
|
| + CommandBufferLocalClient* client,
|
| + gfx::AcceleratedWidget widget,
|
| + const scoped_refptr<gles2::GpuState>& gpu_state)
|
| + : widget_(widget),
|
| + gpu_state_(gpu_state),
|
| + client_(client),
|
| + weak_factory_(this) {
|
| +}
|
| +
|
| +CommandBufferLocal::~CommandBufferLocal() {
|
| + command_buffer_.reset();
|
| + if (decoder_.get()) {
|
| + bool have_context = decoder_->GetGLContext()->MakeCurrent(surface_.get());
|
| + decoder_->Destroy(have_context);
|
| + decoder_.reset();
|
| + }
|
| +}
|
| +
|
| +bool CommandBufferLocal::Initialize() {
|
| + if (widget_ == gfx::kNullAcceleratedWidget) {
|
| + surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
|
| + } else {
|
| + surface_ = gfx::GLSurface::CreateViewGLSurface(widget_);
|
| + gfx::VSyncProvider* vsync_provider =
|
| + surface_ ? surface_->GetVSyncProvider() : nullptr;
|
| + if (vsync_provider) {
|
| + vsync_provider->GetVSyncParameters(
|
| + base::Bind(&CommandBufferLocal::OnUpdateVSyncParameters,
|
| + weak_factory_.GetWeakPtr()));
|
| + }
|
| + }
|
| +
|
| + if (!surface_.get())
|
| + return false;
|
| +
|
| + // TODO(piman): virtual contexts, gpu preference.
|
| + context_ = gfx::GLContext::CreateGLContext(
|
| + gpu_state_->share_group(), surface_.get(), gfx::PreferIntegratedGpu);
|
| + if (!context_.get())
|
| + return false;
|
| +
|
| + if (!context_->MakeCurrent(surface_.get()))
|
| + return false;
|
| +
|
| + // TODO(piman): ShaderTranslatorCache is currently per-ContextGroup but
|
| + // only needs to be per-thread.
|
| + bool bind_generates_resource = false;
|
| + scoped_refptr<gpu::gles2::ContextGroup> context_group =
|
| + new gpu::gles2::ContextGroup(
|
| + gpu_state_->mailbox_manager(), new gles2::GpuMemoryTracker,
|
| + new gpu::gles2::ShaderTranslatorCache, nullptr, nullptr, nullptr,
|
| + bind_generates_resource);
|
| +
|
| + command_buffer_.reset(
|
| + new gpu::CommandBufferService(context_group->transfer_buffer_manager()));
|
| + bool result = command_buffer_->Initialize();
|
| + DCHECK(result);
|
| +
|
| + decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group.get()));
|
| + scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), decoder_.get(),
|
| + decoder_.get()));
|
| + decoder_->set_engine(scheduler_.get());
|
| + decoder_->SetResizeCallback(
|
| + base::Bind(&CommandBufferLocal::OnResize, base::Unretained(this)));
|
| + decoder_->SetWaitSyncPointCallback(base::Bind(
|
| + &CommandBufferLocal::OnWaitSyncPoint, base::Unretained(this)));
|
| +
|
| + gpu::gles2::DisallowedFeatures disallowed_features;
|
| +
|
| + // TODO(piman): attributes.
|
| + std::vector<int32> attrib_vector;
|
| + if (!decoder_->Initialize(surface_, context_, false /* offscreen */,
|
| + gfx::Size(1, 1), disallowed_features,
|
| + attrib_vector))
|
| + return false;
|
| +
|
| + command_buffer_->SetPutOffsetChangeCallback(base::Bind(
|
| + &CommandBufferLocal::PumpCommands, base::Unretained(this)));
|
| + command_buffer_->SetGetBufferChangeCallback(base::Bind(
|
| + &gpu::GpuScheduler::SetGetBuffer, base::Unretained(scheduler_.get())));
|
| + command_buffer_->SetParseErrorCallback(
|
| + base::Bind(&CommandBufferLocal::OnParseError, base::Unretained(this)));
|
| + return true;
|
| +}
|
| +
|
| +gpu::CommandBuffer* CommandBufferLocal::GetCommandBuffer() {
|
| + return command_buffer_.get();
|
| +}
|
| +
|
| +/******************************************************************************/
|
| +// gpu::GpuControl:
|
| +/******************************************************************************/
|
| +
|
| +gpu::Capabilities CommandBufferLocal::GetCapabilities() {
|
| + return decoder_->GetCapabilities();
|
| +}
|
| +
|
| +int32_t CommandBufferLocal::CreateImage(ClientBuffer buffer,
|
| + size_t width,
|
| + size_t height,
|
| + unsigned internalformat) {
|
| + gles2::MojoGpuMemoryBufferImpl* gpu_memory_buffer =
|
| + gles2::MojoGpuMemoryBufferImpl::FromClientBuffer(buffer);
|
| +
|
| + scoped_refptr<gfx::GLImageMemory> image(
|
| + new gfx::GLImageMemory(gfx::Size(width, height),
|
| + internalformat));
|
| + if (!image->Initialize(
|
| + static_cast<const unsigned char*>(gpu_memory_buffer->GetMemory()),
|
| + gpu_memory_buffer->GetFormat())) {
|
| + return -1;
|
| + }
|
| +
|
| + static int32 next_id = 1;
|
| + int32 new_id = next_id++;
|
| +
|
| + gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
|
| + DCHECK(image_manager);
|
| + image_manager->AddImage(image.get(), new_id);
|
| + return new_id;
|
| +}
|
| +
|
| +void CommandBufferLocal::DestroyImage(int32 id) {
|
| + gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
|
| + DCHECK(image_manager);
|
| + image_manager->RemoveImage(id);
|
| +}
|
| +
|
| +int32_t CommandBufferLocal::CreateGpuMemoryBufferImage(
|
| + size_t width,
|
| + size_t height,
|
| + unsigned internalformat,
|
| + unsigned usage) {
|
| + DCHECK_EQ(usage, static_cast<unsigned>(GL_MAP_CHROMIUM));
|
| + scoped_ptr<gfx::GpuMemoryBuffer> buffer(
|
| + gles2::MojoGpuMemoryBufferImpl::Create(
|
| + gfx::Size(width, height),
|
| + gpu::ImageFactory::ImageFormatToGpuMemoryBufferFormat(internalformat),
|
| + gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage)));
|
| + if (!buffer)
|
| + return -1;
|
| + return CreateImage(buffer->AsClientBuffer(), width, height, internalformat);
|
| +}
|
| +
|
| +uint32_t CommandBufferLocal::InsertSyncPoint() {
|
| + return 0;
|
| +}
|
| +
|
| +uint32_t CommandBufferLocal::InsertFutureSyncPoint() {
|
| + NOTIMPLEMENTED();
|
| + return 0;
|
| +}
|
| +
|
| +void CommandBufferLocal::RetireSyncPoint(uint32_t sync_point) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void CommandBufferLocal::SignalSyncPoint(uint32_t sync_point,
|
| + const base::Closure& callback) {
|
| +}
|
| +
|
| +void CommandBufferLocal::SignalQuery(uint32_t query,
|
| + const base::Closure& callback) {
|
| + // TODO(piman)
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +void CommandBufferLocal::SetSurfaceVisible(bool visible) {
|
| + // TODO(piman)
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +uint32_t CommandBufferLocal::CreateStreamTexture(uint32_t texture_id) {
|
| + // TODO(piman)
|
| + NOTIMPLEMENTED();
|
| + return 0;
|
| +}
|
| +
|
| +void CommandBufferLocal::SetLock(base::Lock* lock) {
|
| + NOTIMPLEMENTED();
|
| +}
|
| +
|
| +bool CommandBufferLocal::IsGpuChannelLost() {
|
| + // This is only possible for out-of-process command buffers.
|
| + return false;
|
| +}
|
| +
|
| +void CommandBufferLocal::PumpCommands() {
|
| + if (!decoder_->MakeCurrent()) {
|
| + command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
|
| + command_buffer_->SetParseError(::gpu::error::kLostContext);
|
| + return;
|
| + }
|
| + scheduler_->PutChanged();
|
| +}
|
| +
|
| +void CommandBufferLocal::OnResize(gfx::Size size, float scale_factor) {
|
| + surface_->Resize(size);
|
| +}
|
| +
|
| +void CommandBufferLocal::OnUpdateVSyncParameters(
|
| + const base::TimeTicks timebase,
|
| + const base::TimeDelta interval) {
|
| + if (client_)
|
| + client_->UpdateVSyncParameters(timebase.ToInternalValue(),
|
| + interval.ToInternalValue());
|
| +
|
| +}
|
| +
|
| +bool CommandBufferLocal::OnWaitSyncPoint(uint32_t sync_point) {
|
| + if (!sync_point)
|
| + return true;
|
| + if (gpu_state_->sync_point_manager()->IsSyncPointRetired(sync_point))
|
| + return true;
|
| + scheduler_->SetScheduled(false);
|
| + gpu_state_->sync_point_manager()->AddSyncPointCallback(
|
| + sync_point, base::Bind(&CommandBufferLocal::OnSyncPointRetired,
|
| + weak_factory_.GetWeakPtr()));
|
| + return scheduler_->IsScheduled();
|
| +}
|
| +
|
| +void CommandBufferLocal::OnParseError() {
|
| + gpu::CommandBuffer::State state = command_buffer_->GetLastState();
|
| + OnContextLost(state.context_lost_reason);
|
| +}
|
| +
|
| +void CommandBufferLocal::OnContextLost(uint32_t reason) {
|
| + if (client_)
|
| + client_->DidLoseContext();
|
| +}
|
| +
|
| +void CommandBufferLocal::OnSyncPointRetired() {
|
| + scheduler_->SetScheduled(true);
|
| +}
|
| +
|
| +} // namespace gles2
|
|
|