Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Unified Diff: gpu/command_buffer/service/in_process_command_buffer.cc

Issue 2493913002: Mus: Move InProcessCommandBuffer and GLInProcessContext to gpu/ipc (Closed)
Patch Set: Fixed casts on windows Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gpu/command_buffer/service/in_process_command_buffer.h ('k') | gpu/ipc/BUILD.gn » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/command_buffer/service/in_process_command_buffer.cc
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
deleted file mode 100644
index 51ddf4b6c992f135df47c4b9a177d367e8a4ff6e..0000000000000000000000000000000000000000
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ /dev/null
@@ -1,1077 +0,0 @@
-// Copyright 2013 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 "gpu/command_buffer/service/in_process_command_buffer.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <queue>
-#include <set>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/command_line.h"
-#include "base/lazy_instance.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/weak_ptr.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/sequence_checker.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "gpu/command_buffer/client/gpu_control_client.h"
-#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
-#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
-#include "gpu/command_buffer/common/sync_token.h"
-#include "gpu/command_buffer/service/command_buffer_service.h"
-#include "gpu/command_buffer/service/command_executor.h"
-#include "gpu/command_buffer/service/context_group.h"
-#include "gpu/command_buffer/service/gl_context_virtual.h"
-#include "gpu/command_buffer/service/gpu_preferences.h"
-#include "gpu/command_buffer/service/image_factory.h"
-#include "gpu/command_buffer/service/image_manager.h"
-#include "gpu/command_buffer/service/mailbox_manager.h"
-#include "gpu/command_buffer/service/memory_program_cache.h"
-#include "gpu/command_buffer/service/memory_tracking.h"
-#include "gpu/command_buffer/service/query_manager.h"
-#include "gpu/command_buffer/service/service_utils.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
-#include "gpu/command_buffer/service/transfer_buffer_manager.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_image.h"
-#include "ui/gl/gl_image_shared_memory.h"
-#include "ui/gl/gl_share_group.h"
-#include "ui/gl/init/gl_factory.h"
-
-#if defined(OS_WIN)
-#include <windows.h>
-#include "base/process/process_handle.h"
-#endif
-
-namespace gpu {
-
-namespace {
-
-base::StaticAtomicSequenceNumber g_next_command_buffer_id;
-
-template <typename T>
-static void RunTaskWithResult(base::Callback<T(void)> task,
- T* result,
- base::WaitableEvent* completion) {
- *result = task.Run();
- completion->Signal();
-}
-
-struct ScopedOrderNumberProcessor {
- ScopedOrderNumberProcessor(SyncPointOrderData* order_data, uint32_t order_num)
- : order_data_(order_data), order_num_(order_num) {
- order_data_->BeginProcessingOrderNumber(order_num_);
- }
-
- ~ScopedOrderNumberProcessor() {
- order_data_->FinishProcessingOrderNumber(order_num_);
- }
-
- private:
- SyncPointOrderData* order_data_;
- uint32_t order_num_;
-};
-
-struct GpuInProcessThreadHolder {
- GpuInProcessThreadHolder()
- : sync_point_manager(new SyncPointManager(false)),
- gpu_thread(new GpuInProcessThread(sync_point_manager.get())) {}
- std::unique_ptr<SyncPointManager> sync_point_manager;
- scoped_refptr<InProcessCommandBuffer::Service> gpu_thread;
-};
-
-base::LazyInstance<GpuInProcessThreadHolder> g_default_service =
- LAZY_INSTANCE_INITIALIZER;
-
-class ScopedEvent {
- public:
- explicit ScopedEvent(base::WaitableEvent* event) : event_(event) {}
- ~ScopedEvent() { event_->Signal(); }
-
- private:
- base::WaitableEvent* event_;
-};
-
-base::SharedMemoryHandle ShareToGpuThread(
- base::SharedMemoryHandle source_handle) {
- return base::SharedMemory::DuplicateHandle(source_handle);
-}
-
-gfx::GpuMemoryBufferHandle ShareGpuMemoryBufferToGpuThread(
- const gfx::GpuMemoryBufferHandle& source_handle,
- bool* requires_sync_point) {
- switch (source_handle.type) {
- case gfx::SHARED_MEMORY_BUFFER: {
- gfx::GpuMemoryBufferHandle handle;
- handle.type = gfx::SHARED_MEMORY_BUFFER;
- handle.handle = ShareToGpuThread(source_handle.handle);
- handle.offset = source_handle.offset;
- handle.stride = source_handle.stride;
- *requires_sync_point = false;
- return handle;
- }
- case gfx::IO_SURFACE_BUFFER:
- case gfx::OZONE_NATIVE_PIXMAP:
- *requires_sync_point = true;
- return source_handle;
- default:
- NOTREACHED();
- return gfx::GpuMemoryBufferHandle();
- }
-}
-
-scoped_refptr<InProcessCommandBuffer::Service> GetInitialService(
- const scoped_refptr<InProcessCommandBuffer::Service>& service) {
- if (service)
- return service;
-
- // Call base::ThreadTaskRunnerHandle::IsSet() to ensure that it is
- // instantiated before we create the GPU thread, otherwise shutdown order will
- // delete the ThreadTaskRunnerHandle before the GPU thread's message loop,
- // and when the message loop is shutdown, it will recreate
- // ThreadTaskRunnerHandle, which will re-add a new task to the, AtExitManager,
- // which causes a deadlock because it's already locked.
- base::ThreadTaskRunnerHandle::IsSet();
- return g_default_service.Get().gpu_thread;
-}
-
-} // anonyous namespace
-
-InProcessCommandBuffer::Service::Service()
- : gpu_driver_bug_workarounds_(base::CommandLine::ForCurrentProcess()) {}
-
-InProcessCommandBuffer::Service::Service(const GpuPreferences& gpu_preferences)
- : gpu_preferences_(gpu_preferences),
- gpu_driver_bug_workarounds_(base::CommandLine::ForCurrentProcess()) {}
-
-InProcessCommandBuffer::Service::~Service() {}
-
-const gpu::GpuPreferences&
-InProcessCommandBuffer::Service::gpu_preferences() {
- return gpu_preferences_;
-}
-
-const gpu::GpuDriverBugWorkarounds&
-InProcessCommandBuffer::Service::gpu_driver_bug_workarounds() {
- return gpu_driver_bug_workarounds_;
-}
-
-scoped_refptr<gl::GLShareGroup> InProcessCommandBuffer::Service::share_group() {
- if (!share_group_.get())
- share_group_ = new gl::GLShareGroup();
- return share_group_;
-}
-
-scoped_refptr<gles2::MailboxManager>
-InProcessCommandBuffer::Service::mailbox_manager() {
- if (!mailbox_manager_.get()) {
- mailbox_manager_ = gles2::MailboxManager::Create(gpu_preferences());
- }
- return mailbox_manager_;
-}
-
-gpu::gles2::ProgramCache* InProcessCommandBuffer::Service::program_cache() {
- if (!program_cache_.get() &&
- (gl::g_driver_gl.ext.b_GL_ARB_get_program_binary ||
- gl::g_driver_gl.ext.b_GL_OES_get_program_binary) &&
- !gpu_preferences().disable_gpu_program_cache) {
- bool disable_disk_cache =
- gpu_preferences_.disable_gpu_shader_disk_cache ||
- gpu_driver_bug_workarounds_.disable_program_disk_cache;
- program_cache_.reset(new gles2::MemoryProgramCache(
- gpu_preferences_.gpu_program_cache_size, disable_disk_cache));
- }
- return program_cache_.get();
-}
-
-InProcessCommandBuffer::InProcessCommandBuffer(
- const scoped_refptr<Service>& service)
- : command_buffer_id_(
- CommandBufferId::FromUnsafeValue(g_next_command_buffer_id.GetNext())),
- delayed_work_pending_(false),
- image_factory_(nullptr),
- gpu_control_client_(nullptr),
-#if DCHECK_IS_ON()
- context_lost_(false),
-#endif
- last_put_offset_(-1),
- gpu_memory_buffer_manager_(nullptr),
- next_fence_sync_release_(1),
- flushed_fence_sync_release_(0),
- flush_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- service_(GetInitialService(service)),
- fence_sync_wait_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- client_thread_weak_ptr_factory_(this),
- gpu_thread_weak_ptr_factory_(this) {
- DCHECK(service_.get());
- next_image_id_.GetNext();
-}
-
-InProcessCommandBuffer::~InProcessCommandBuffer() {
- Destroy();
-}
-
-bool InProcessCommandBuffer::MakeCurrent() {
- CheckSequencedThread();
- command_buffer_lock_.AssertAcquired();
-
- if (error::IsError(command_buffer_->GetLastState().error)) {
- DLOG(ERROR) << "MakeCurrent failed because context lost.";
- return false;
- }
- if (!decoder_->MakeCurrent()) {
- DLOG(ERROR) << "Context lost because MakeCurrent failed.";
- command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
- command_buffer_->SetParseError(gpu::error::kLostContext);
- return false;
- }
- return true;
-}
-
-void InProcessCommandBuffer::PumpCommandsOnGpuThread() {
- CheckSequencedThread();
- command_buffer_lock_.AssertAcquired();
-
- if (!MakeCurrent())
- return;
-
- executor_->PutChanged();
-}
-
-bool InProcessCommandBuffer::Initialize(
- scoped_refptr<gl::GLSurface> surface,
- bool is_offscreen,
- gfx::AcceleratedWidget window,
- const gles2::ContextCreationAttribHelper& attribs,
- InProcessCommandBuffer* share_group,
- GpuMemoryBufferManager* gpu_memory_buffer_manager,
- ImageFactory* image_factory,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
- DCHECK(!share_group || service_.get() == share_group->service_.get());
-
- if (surface) {
- // If a surface is provided, we are running in a webview and should not have
- // a task runner.
- DCHECK(!task_runner);
-
- // GPU thread must be the same as client thread due to GLSurface not being
- // thread safe.
- sequence_checker_.reset(new base::SequenceChecker);
- surface_ = surface;
- } else {
- DCHECK(task_runner);
- origin_task_runner_ = std::move(task_runner);
- client_thread_weak_ptr_ = client_thread_weak_ptr_factory_.GetWeakPtr();
- }
-
- gpu::Capabilities capabilities;
- InitializeOnGpuThreadParams params(is_offscreen, window, attribs,
- &capabilities, share_group, image_factory);
-
- base::Callback<bool(void)> init_task =
- base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread,
- base::Unretained(this), params);
-
- base::WaitableEvent completion(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- bool result = false;
- QueueTask(
- base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion));
- completion.Wait();
-
- gpu_memory_buffer_manager_ = gpu_memory_buffer_manager;
-
- if (result)
- capabilities_ = capabilities;
-
- return result;
-}
-
-bool InProcessCommandBuffer::InitializeOnGpuThread(
- const InitializeOnGpuThreadParams& params) {
- CheckSequencedThread();
- gpu_thread_weak_ptr_ = gpu_thread_weak_ptr_factory_.GetWeakPtr();
-
- TransferBufferManager* manager = new TransferBufferManager(nullptr);
- transfer_buffer_manager_ = manager;
- manager->Initialize();
-
- std::unique_ptr<CommandBufferService> command_buffer(
- new CommandBufferService(transfer_buffer_manager_.get()));
- command_buffer->SetPutOffsetChangeCallback(base::Bind(
- &InProcessCommandBuffer::PumpCommandsOnGpuThread, gpu_thread_weak_ptr_));
- command_buffer->SetParseErrorCallback(base::Bind(
- &InProcessCommandBuffer::OnContextLostOnGpuThread, gpu_thread_weak_ptr_));
-
- gl_share_group_ = params.context_group
- ? params.context_group->gl_share_group_
- : service_->share_group();
-
- bool bind_generates_resource = false;
- scoped_refptr<gles2::FeatureInfo> feature_info =
- new gles2::FeatureInfo(service_->gpu_driver_bug_workarounds());
- decoder_.reset(gles2::GLES2Decoder::Create(
- params.context_group
- ? params.context_group->decoder_->GetContextGroup()
- : new gles2::ContextGroup(
- service_->gpu_preferences(), service_->mailbox_manager(), NULL,
- service_->shader_translator_cache(),
- service_->framebuffer_completeness_cache(), feature_info,
- bind_generates_resource, nullptr, nullptr)));
-
- executor_.reset(new CommandExecutor(command_buffer.get(), decoder_.get(),
- decoder_.get()));
- command_buffer->SetGetBufferChangeCallback(base::Bind(
- &CommandExecutor::SetGetBuffer, base::Unretained(executor_.get())));
- command_buffer_ = std::move(command_buffer);
-
- decoder_->set_engine(executor_.get());
-
- if (!surface_.get()) {
- if (params.is_offscreen)
- surface_ = gl::init::CreateOffscreenGLSurface(gfx::Size());
- else
- surface_ = gl::init::CreateViewGLSurface(params.window);
- }
-
- if (!surface_.get()) {
- LOG(ERROR) << "Could not create GLSurface.";
- DestroyOnGpuThread();
- return false;
- }
-
- sync_point_order_data_ = SyncPointOrderData::Create();
- sync_point_client_ = service_->sync_point_manager()->CreateSyncPointClient(
- sync_point_order_data_, GetNamespaceID(), GetCommandBufferID());
-
- if (service_->UseVirtualizedGLContexts() ||
- decoder_->GetContextGroup()
- ->feature_info()
- ->workarounds()
- .use_virtualized_gl_contexts) {
- context_ = gl_share_group_->GetSharedContext(surface_.get());
- if (!context_.get()) {
- context_ = gl::init::CreateGLContext(
- gl_share_group_.get(), surface_.get(),
- GenerateGLContextAttribs(
- params.attribs, decoder_->GetContextGroup()->gpu_preferences()));
- gl_share_group_->SetSharedContext(surface_.get(), context_.get());
- }
-
- context_ = new GLContextVirtual(
- gl_share_group_.get(), context_.get(), decoder_->AsWeakPtr());
- if (context_->Initialize(
- surface_.get(),
- GenerateGLContextAttribs(
- params.attribs,
- decoder_->GetContextGroup()->gpu_preferences()))) {
- VLOG(1) << "Created virtual GL context.";
- } else {
- context_ = NULL;
- }
- } else {
- context_ = gl::init::CreateGLContext(
- gl_share_group_.get(), surface_.get(),
- GenerateGLContextAttribs(
- params.attribs, decoder_->GetContextGroup()->gpu_preferences()));
- }
-
- if (!context_.get()) {
- LOG(ERROR) << "Could not create GLContext.";
- DestroyOnGpuThread();
- return false;
- }
-
- if (!context_->MakeCurrent(surface_.get())) {
- LOG(ERROR) << "Could not make context current.";
- DestroyOnGpuThread();
- return false;
- }
-
- if (!decoder_->GetContextGroup()->has_program_cache() &&
- !decoder_->GetContextGroup()
- ->feature_info()
- ->workarounds()
- .disable_program_cache) {
- decoder_->GetContextGroup()->set_program_cache(service_->program_cache());
- }
-
- gles2::DisallowedFeatures disallowed_features;
- disallowed_features.gpu_memory_manager = true;
- if (!decoder_->Initialize(surface_,
- context_,
- params.is_offscreen,
- disallowed_features,
- params.attribs)) {
- LOG(ERROR) << "Could not initialize decoder.";
- DestroyOnGpuThread();
- return false;
- }
- *params.capabilities = decoder_->GetCapabilities();
-
- decoder_->SetFenceSyncReleaseCallback(
- base::Bind(&InProcessCommandBuffer::FenceSyncReleaseOnGpuThread,
- base::Unretained(this)));
- decoder_->SetWaitFenceSyncCallback(
- base::Bind(&InProcessCommandBuffer::WaitFenceSyncOnGpuThread,
- base::Unretained(this)));
- decoder_->SetDescheduleUntilFinishedCallback(
- base::Bind(&InProcessCommandBuffer::DescheduleUntilFinishedOnGpuThread,
- base::Unretained(this)));
- decoder_->SetRescheduleAfterFinishedCallback(
- base::Bind(&InProcessCommandBuffer::RescheduleAfterFinishedOnGpuThread,
- base::Unretained(this)));
-
- image_factory_ = params.image_factory;
-
- return true;
-}
-
-void InProcessCommandBuffer::Destroy() {
- CheckSequencedThread();
- client_thread_weak_ptr_factory_.InvalidateWeakPtrs();
- gpu_control_client_ = nullptr;
- base::WaitableEvent completion(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- bool result = false;
- base::Callback<bool(void)> destroy_task = base::Bind(
- &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this));
- QueueTask(
- base::Bind(&RunTaskWithResult<bool>, destroy_task, &result, &completion));
- completion.Wait();
-}
-
-bool InProcessCommandBuffer::DestroyOnGpuThread() {
- CheckSequencedThread();
- gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs();
- command_buffer_.reset();
- // Clean up GL resources if possible.
- bool have_context = context_.get() && context_->MakeCurrent(surface_.get());
- if (decoder_) {
- decoder_->Destroy(have_context);
- decoder_.reset();
- }
- context_ = nullptr;
- surface_ = nullptr;
- sync_point_client_ = nullptr;
- if (sync_point_order_data_) {
- sync_point_order_data_->Destroy();
- sync_point_order_data_ = nullptr;
- }
- gl_share_group_ = nullptr;
-
- return true;
-}
-
-void InProcessCommandBuffer::CheckSequencedThread() {
- DCHECK(!sequence_checker_ || sequence_checker_->CalledOnValidSequence());
-}
-
-void InProcessCommandBuffer::OnContextLostOnGpuThread() {
- if (!origin_task_runner_)
- return OnContextLost(); // Just kidding, we're on the client thread.
- origin_task_runner_->PostTask(
- FROM_HERE, base::Bind(&InProcessCommandBuffer::OnContextLost,
- client_thread_weak_ptr_));
-}
-
-void InProcessCommandBuffer::OnContextLost() {
- CheckSequencedThread();
-
-#if DCHECK_IS_ON()
- // This method shouldn't be called more than once.
- DCHECK(!context_lost_);
- context_lost_ = true;
-#endif
-
- if (gpu_control_client_)
- gpu_control_client_->OnGpuControlLostContext();
-}
-
-CommandBuffer::State InProcessCommandBuffer::GetStateFast() {
- CheckSequencedThread();
- base::AutoLock lock(state_after_last_flush_lock_);
- if (state_after_last_flush_.generation - last_state_.generation < 0x80000000U)
- last_state_ = state_after_last_flush_;
- return last_state_;
-}
-
-CommandBuffer::State InProcessCommandBuffer::GetLastState() {
- CheckSequencedThread();
- return last_state_;
-}
-
-int32_t InProcessCommandBuffer::GetLastToken() {
- CheckSequencedThread();
- GetStateFast();
- return last_state_.token;
-}
-
-void InProcessCommandBuffer::FlushOnGpuThread(int32_t put_offset,
- uint32_t order_num) {
- CheckSequencedThread();
- ScopedEvent handle_flush(&flush_event_);
- base::AutoLock lock(command_buffer_lock_);
-
- {
- ScopedOrderNumberProcessor scoped_order_num(sync_point_order_data_.get(),
- order_num);
- command_buffer_->Flush(put_offset);
- {
- // Update state before signaling the flush event.
- base::AutoLock lock(state_after_last_flush_lock_);
- state_after_last_flush_ = command_buffer_->GetLastState();
- }
-
- // Currently the in process command buffer does not support being
- // descheduled, if it does we would need to back off on calling the finish
- // processing number function until the message is rescheduled and finished
- // processing. This DCHECK is to enforce this.
- DCHECK(error::IsError(state_after_last_flush_.error) ||
- put_offset == state_after_last_flush_.get_offset);
- }
-
- // If we've processed all pending commands but still have pending queries,
- // pump idle work until the query is passed.
- if (put_offset == state_after_last_flush_.get_offset &&
- (executor_->HasMoreIdleWork() || executor_->HasPendingQueries())) {
- ScheduleDelayedWorkOnGpuThread();
- }
-}
-
-void InProcessCommandBuffer::PerformDelayedWorkOnGpuThread() {
- CheckSequencedThread();
- delayed_work_pending_ = false;
- base::AutoLock lock(command_buffer_lock_);
- if (MakeCurrent()) {
- executor_->PerformIdleWork();
- executor_->ProcessPendingQueries();
- if (executor_->HasMoreIdleWork() || executor_->HasPendingQueries()) {
- ScheduleDelayedWorkOnGpuThread();
- }
- }
-}
-
-void InProcessCommandBuffer::ScheduleDelayedWorkOnGpuThread() {
- CheckSequencedThread();
- if (delayed_work_pending_)
- return;
- delayed_work_pending_ = true;
- service_->ScheduleDelayedWork(
- base::Bind(&InProcessCommandBuffer::PerformDelayedWorkOnGpuThread,
- gpu_thread_weak_ptr_));
-}
-
-void InProcessCommandBuffer::Flush(int32_t put_offset) {
- CheckSequencedThread();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- if (last_put_offset_ == put_offset)
- return;
-
- SyncPointManager* sync_manager = service_->sync_point_manager();
- const uint32_t order_num =
- sync_point_order_data_->GenerateUnprocessedOrderNumber(sync_manager);
- last_put_offset_ = put_offset;
- base::Closure task = base::Bind(&InProcessCommandBuffer::FlushOnGpuThread,
- gpu_thread_weak_ptr_,
- put_offset,
- order_num);
- QueueTask(task);
-
- flushed_fence_sync_release_ = next_fence_sync_release_ - 1;
-}
-
-void InProcessCommandBuffer::OrderingBarrier(int32_t put_offset) {
- Flush(put_offset);
-}
-
-void InProcessCommandBuffer::WaitForTokenInRange(int32_t start, int32_t end) {
- CheckSequencedThread();
- while (!InRange(start, end, GetLastToken()) &&
- last_state_.error == gpu::error::kNoError)
- flush_event_.Wait();
-}
-
-void InProcessCommandBuffer::WaitForGetOffsetInRange(int32_t start,
- int32_t end) {
- CheckSequencedThread();
-
- GetStateFast();
- while (!InRange(start, end, last_state_.get_offset) &&
- last_state_.error == gpu::error::kNoError) {
- flush_event_.Wait();
- GetStateFast();
- }
-}
-
-void InProcessCommandBuffer::SetGetBuffer(int32_t shm_id) {
- CheckSequencedThread();
- if (last_state_.error != gpu::error::kNoError)
- return;
-
- base::WaitableEvent completion(
- base::WaitableEvent::ResetPolicy::MANUAL,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- base::Closure task =
- base::Bind(&InProcessCommandBuffer::SetGetBufferOnGpuThread,
- base::Unretained(this), shm_id, &completion);
- QueueTask(task);
- completion.Wait();
-
- {
- base::AutoLock lock(state_after_last_flush_lock_);
- state_after_last_flush_ = command_buffer_->GetLastState();
- }
-}
-
-void InProcessCommandBuffer::SetGetBufferOnGpuThread(
- int32_t shm_id,
- base::WaitableEvent* completion) {
- base::AutoLock lock(command_buffer_lock_);
- command_buffer_->SetGetBuffer(shm_id);
- last_put_offset_ = 0;
- completion->Signal();
-}
-
-scoped_refptr<Buffer> InProcessCommandBuffer::CreateTransferBuffer(
- size_t size,
- int32_t* id) {
- CheckSequencedThread();
- base::AutoLock lock(command_buffer_lock_);
- return command_buffer_->CreateTransferBuffer(size, id);
-}
-
-void InProcessCommandBuffer::DestroyTransferBuffer(int32_t id) {
- CheckSequencedThread();
- base::Closure task =
- base::Bind(&InProcessCommandBuffer::DestroyTransferBufferOnGpuThread,
- base::Unretained(this),
- id);
-
- QueueTask(task);
-}
-
-void InProcessCommandBuffer::DestroyTransferBufferOnGpuThread(int32_t id) {
- base::AutoLock lock(command_buffer_lock_);
- command_buffer_->DestroyTransferBuffer(id);
-}
-
-void InProcessCommandBuffer::SetGpuControlClient(GpuControlClient* client) {
- gpu_control_client_ = client;
-}
-
-gpu::Capabilities InProcessCommandBuffer::GetCapabilities() {
- return capabilities_;
-}
-
-int32_t InProcessCommandBuffer::CreateImage(ClientBuffer buffer,
- size_t width,
- size_t height,
- unsigned internalformat) {
- CheckSequencedThread();
-
- DCHECK(gpu_memory_buffer_manager_);
- gfx::GpuMemoryBuffer* gpu_memory_buffer =
- reinterpret_cast<gfx::GpuMemoryBuffer*>(buffer);
- DCHECK(gpu_memory_buffer);
-
- int32_t new_id = next_image_id_.GetNext();
-
- DCHECK(gpu::IsGpuMemoryBufferFormatSupported(gpu_memory_buffer->GetFormat(),
- capabilities_));
- DCHECK(gpu::IsImageFormatCompatibleWithGpuMemoryBufferFormat(
- internalformat, gpu_memory_buffer->GetFormat()));
-
- // This handle is owned by the GPU thread and must be passed to it or it
- // will leak. In otherwords, do not early out on error between here and the
- // queuing of the CreateImage task below.
- bool requires_sync_point = false;
- gfx::GpuMemoryBufferHandle handle =
- ShareGpuMemoryBufferToGpuThread(gpu_memory_buffer->GetHandle(),
- &requires_sync_point);
-
- SyncPointManager* sync_manager = service_->sync_point_manager();
- const uint32_t order_num =
- sync_point_order_data_->GenerateUnprocessedOrderNumber(sync_manager);
-
- uint64_t fence_sync = 0;
- if (requires_sync_point) {
- fence_sync = GenerateFenceSyncRelease();
-
- // Previous fence syncs should be flushed already.
- DCHECK_EQ(fence_sync - 1, flushed_fence_sync_release_);
- }
-
- QueueTask(base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread,
- base::Unretained(this), new_id, handle,
- gfx::Size(width, height), gpu_memory_buffer->GetFormat(),
- internalformat, order_num, fence_sync));
-
- if (fence_sync) {
- flushed_fence_sync_release_ = fence_sync;
- SyncToken sync_token(GetNamespaceID(), GetExtraCommandBufferData(),
- GetCommandBufferID(), fence_sync);
- sync_token.SetVerifyFlush();
- gpu_memory_buffer_manager_->SetDestructionSyncToken(gpu_memory_buffer,
- sync_token);
- }
-
- return new_id;
-}
-
-void InProcessCommandBuffer::CreateImageOnGpuThread(
- int32_t id,
- const gfx::GpuMemoryBufferHandle& handle,
- const gfx::Size& size,
- gfx::BufferFormat format,
- uint32_t internalformat,
- uint32_t order_num,
- uint64_t fence_sync) {
- ScopedOrderNumberProcessor scoped_order_num(sync_point_order_data_.get(),
- order_num);
- if (!decoder_)
- return;
-
- gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
- DCHECK(image_manager);
- if (image_manager->LookupImage(id)) {
- LOG(ERROR) << "Image already exists with same ID.";
- return;
- }
-
- switch (handle.type) {
- case gfx::SHARED_MEMORY_BUFFER: {
- if (!base::IsValueInRangeForNumericType<size_t>(handle.stride)) {
- LOG(ERROR) << "Invalid stride for image.";
- return;
- }
- scoped_refptr<gl::GLImageSharedMemory> image(
- new gl::GLImageSharedMemory(size, internalformat));
- if (!image->Initialize(handle.handle, handle.id, format, handle.offset,
- handle.stride)) {
- LOG(ERROR) << "Failed to initialize image.";
- return;
- }
-
- image_manager->AddImage(image.get(), id);
- break;
- }
- default: {
- if (!image_factory_) {
- LOG(ERROR) << "Image factory missing but required by buffer type.";
- return;
- }
-
- // Note: this assumes that client ID is always 0.
- const int kClientId = 0;
-
- scoped_refptr<gl::GLImage> image =
- image_factory_->CreateImageForGpuMemoryBuffer(
- handle, size, format, internalformat, kClientId,
- kNullSurfaceHandle);
- if (!image.get()) {
- LOG(ERROR) << "Failed to create image for buffer.";
- return;
- }
-
- image_manager->AddImage(image.get(), id);
- break;
- }
- }
-
- if (fence_sync) {
- sync_point_client_->ReleaseFenceSync(fence_sync);
- }
-}
-
-void InProcessCommandBuffer::DestroyImage(int32_t id) {
- CheckSequencedThread();
-
- QueueTask(base::Bind(&InProcessCommandBuffer::DestroyImageOnGpuThread,
- base::Unretained(this),
- id));
-}
-
-void InProcessCommandBuffer::DestroyImageOnGpuThread(int32_t id) {
- if (!decoder_)
- return;
-
- gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager();
- DCHECK(image_manager);
- if (!image_manager->LookupImage(id)) {
- LOG(ERROR) << "Image with ID doesn't exist.";
- return;
- }
-
- image_manager->RemoveImage(id);
-}
-
-int32_t InProcessCommandBuffer::CreateGpuMemoryBufferImage(
- size_t width,
- size_t height,
- unsigned internalformat,
- unsigned usage) {
- CheckSequencedThread();
-
- DCHECK(gpu_memory_buffer_manager_);
- std::unique_ptr<gfx::GpuMemoryBuffer> buffer(
- gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
- gfx::Size(width, height),
- gpu::DefaultBufferFormatForImageFormat(internalformat),
- gfx::BufferUsage::SCANOUT, gpu::kNullSurfaceHandle));
- if (!buffer)
- return -1;
-
- return CreateImage(buffer->AsClientBuffer(), width, height, internalformat);
-}
-
-void InProcessCommandBuffer::FenceSyncReleaseOnGpuThread(uint64_t release) {
- DCHECK(!sync_point_client_->client_state()->IsFenceSyncReleased(release));
- gles2::MailboxManager* mailbox_manager =
- decoder_->GetContextGroup()->mailbox_manager();
- if (mailbox_manager->UsesSync()) {
- SyncToken sync_token(GetNamespaceID(), GetExtraCommandBufferData(),
- GetCommandBufferID(), release);
- mailbox_manager->PushTextureUpdates(sync_token);
- }
-
- sync_point_client_->ReleaseFenceSync(release);
-}
-
-bool InProcessCommandBuffer::WaitFenceSyncOnGpuThread(
- gpu::CommandBufferNamespace namespace_id,
- gpu::CommandBufferId command_buffer_id,
- uint64_t release) {
- gpu::SyncPointManager* sync_point_manager = service_->sync_point_manager();
- DCHECK(sync_point_manager);
-
- scoped_refptr<gpu::SyncPointClientState> release_state =
- sync_point_manager->GetSyncPointClientState(namespace_id,
- command_buffer_id);
-
- if (!release_state)
- return true;
-
- if (!release_state->IsFenceSyncReleased(release)) {
- // Use waitable event which is signalled when the release fence is released.
- sync_point_client_->Wait(
- release_state.get(), release,
- base::Bind(&base::WaitableEvent::Signal,
- base::Unretained(&fence_sync_wait_event_)));
- fence_sync_wait_event_.Wait();
- }
-
- gles2::MailboxManager* mailbox_manager =
- decoder_->GetContextGroup()->mailbox_manager();
- SyncToken sync_token(namespace_id, 0, command_buffer_id, release);
- mailbox_manager->PullTextureUpdates(sync_token);
- return true;
-}
-
-void InProcessCommandBuffer::DescheduleUntilFinishedOnGpuThread() {
- NOTIMPLEMENTED();
-}
-
-void InProcessCommandBuffer::RescheduleAfterFinishedOnGpuThread() {
- NOTIMPLEMENTED();
-}
-
-void InProcessCommandBuffer::SignalSyncTokenOnGpuThread(
- const SyncToken& sync_token, const base::Closure& callback) {
- gpu::SyncPointManager* sync_point_manager = service_->sync_point_manager();
- DCHECK(sync_point_manager);
-
- scoped_refptr<gpu::SyncPointClientState> release_state =
- sync_point_manager->GetSyncPointClientState(
- sync_token.namespace_id(), sync_token.command_buffer_id());
-
- if (!release_state) {
- callback.Run();
- return;
- }
-
- sync_point_client_->WaitOutOfOrder(
- release_state.get(), sync_token.release_count(), WrapCallback(callback));
-}
-
-void InProcessCommandBuffer::SignalQuery(unsigned query_id,
- const base::Closure& callback) {
- CheckSequencedThread();
- QueueTask(base::Bind(&InProcessCommandBuffer::SignalQueryOnGpuThread,
- base::Unretained(this),
- query_id,
- WrapCallback(callback)));
-}
-
-void InProcessCommandBuffer::SignalQueryOnGpuThread(
- unsigned query_id,
- const base::Closure& callback) {
- gles2::QueryManager* query_manager_ = decoder_->GetQueryManager();
- DCHECK(query_manager_);
-
- gles2::QueryManager::Query* query = query_manager_->GetQuery(query_id);
- if (!query)
- callback.Run();
- else
- query->AddCallback(callback);
-}
-
-void InProcessCommandBuffer::SetLock(base::Lock*) {
- // No support for using on multiple threads.
- NOTREACHED();
-}
-
-void InProcessCommandBuffer::EnsureWorkVisible() {
- // This is only relevant for out-of-process command buffers.
-}
-
-CommandBufferNamespace InProcessCommandBuffer::GetNamespaceID() const {
- return CommandBufferNamespace::IN_PROCESS;
-}
-
-CommandBufferId InProcessCommandBuffer::GetCommandBufferID() const {
- return command_buffer_id_;
-}
-
-int32_t InProcessCommandBuffer::GetExtraCommandBufferData() const {
- return 0;
-}
-
-uint64_t InProcessCommandBuffer::GenerateFenceSyncRelease() {
- return next_fence_sync_release_++;
-}
-
-bool InProcessCommandBuffer::IsFenceSyncRelease(uint64_t release) {
- return release != 0 && release < next_fence_sync_release_;
-}
-
-bool InProcessCommandBuffer::IsFenceSyncFlushed(uint64_t release) {
- return release <= flushed_fence_sync_release_;
-}
-
-bool InProcessCommandBuffer::IsFenceSyncFlushReceived(uint64_t release) {
- return IsFenceSyncFlushed(release);
-}
-
-void InProcessCommandBuffer::SignalSyncToken(const SyncToken& sync_token,
- const base::Closure& callback) {
- CheckSequencedThread();
- QueueTask(base::Bind(&InProcessCommandBuffer::SignalSyncTokenOnGpuThread,
- base::Unretained(this),
- sync_token,
- WrapCallback(callback)));
-}
-
-bool InProcessCommandBuffer::CanWaitUnverifiedSyncToken(
- const SyncToken* sync_token) {
- return sync_token->namespace_id() == GetNamespaceID();
-}
-
-gpu::error::Error InProcessCommandBuffer::GetLastError() {
- CheckSequencedThread();
- return last_state_.error;
-}
-
-namespace {
-
-void PostCallback(
- const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
- const base::Closure& callback) {
- // The task_runner.get() check is to support using InProcessCommandBuffer on
- // a thread without a message loop.
- if (task_runner.get() && !task_runner->BelongsToCurrentThread()) {
- task_runner->PostTask(FROM_HERE, callback);
- } else {
- callback.Run();
- }
-}
-
-void RunOnTargetThread(std::unique_ptr<base::Closure> callback) {
- DCHECK(callback.get());
- callback->Run();
-}
-
-} // anonymous namespace
-
-base::Closure InProcessCommandBuffer::WrapCallback(
- const base::Closure& callback) {
- // Make sure the callback gets deleted on the target thread by passing
- // ownership.
- std::unique_ptr<base::Closure> scoped_callback(new base::Closure(callback));
- base::Closure callback_on_client_thread =
- base::Bind(&RunOnTargetThread, base::Passed(&scoped_callback));
- base::Closure wrapped_callback =
- base::Bind(&PostCallback, base::ThreadTaskRunnerHandle::IsSet()
- ? base::ThreadTaskRunnerHandle::Get()
- : nullptr,
- callback_on_client_thread);
- return wrapped_callback;
-}
-
-GpuInProcessThread::GpuInProcessThread(SyncPointManager* sync_point_manager)
- : base::Thread("GpuThread"), sync_point_manager_(sync_point_manager) {
- Start();
-}
-
-GpuInProcessThread::~GpuInProcessThread() {
- Stop();
-}
-
-void GpuInProcessThread::AddRef() const {
- base::RefCountedThreadSafe<GpuInProcessThread>::AddRef();
-}
-void GpuInProcessThread::Release() const {
- base::RefCountedThreadSafe<GpuInProcessThread>::Release();
-}
-
-void GpuInProcessThread::ScheduleTask(const base::Closure& task) {
- task_runner()->PostTask(FROM_HERE, task);
-}
-
-void GpuInProcessThread::ScheduleDelayedWork(const base::Closure& callback) {
- // Match delay with GpuCommandBufferStub.
- task_runner()->PostDelayedTask(FROM_HERE, callback,
- base::TimeDelta::FromMilliseconds(2));
-}
-
-bool GpuInProcessThread::UseVirtualizedGLContexts() {
- return false;
-}
-
-scoped_refptr<gles2::ShaderTranslatorCache>
-GpuInProcessThread::shader_translator_cache() {
- if (!shader_translator_cache_.get()) {
- shader_translator_cache_ =
- new gpu::gles2::ShaderTranslatorCache(gpu_preferences());
- }
- return shader_translator_cache_;
-}
-
-scoped_refptr<gles2::FramebufferCompletenessCache>
-GpuInProcessThread::framebuffer_completeness_cache() {
- if (!framebuffer_completeness_cache_.get())
- framebuffer_completeness_cache_ =
- new gpu::gles2::FramebufferCompletenessCache;
- return framebuffer_completeness_cache_;
-}
-
-SyncPointManager* GpuInProcessThread::sync_point_manager() {
- return sync_point_manager_;
-}
-
-} // namespace gpu
« no previous file with comments | « gpu/command_buffer/service/in_process_command_buffer.h ('k') | gpu/ipc/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698