Index: content/common/gpu/client/command_buffer_proxy_impl.cc |
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc |
deleted file mode 100644 |
index 760060dd47f16324f0764f57afabb1e4d6c60dce..0000000000000000000000000000000000000000 |
--- a/content/common/gpu/client/command_buffer_proxy_impl.cc |
+++ /dev/null |
@@ -1,747 +0,0 @@ |
-// Copyright (c) 2012 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 "content/common/gpu/client/command_buffer_proxy_impl.h" |
- |
-#include <utility> |
-#include <vector> |
- |
-#include "base/callback.h" |
-#include "base/logging.h" |
-#include "base/memory/shared_memory.h" |
-#include "base/stl_util.h" |
-#include "base/thread_task_runner_handle.h" |
-#include "base/trace_event/trace_event.h" |
-#include "content/common/gpu/client/gpu_channel_host.h" |
-#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" |
-#include "gpu/command_buffer/common/cmd_buffer_common.h" |
-#include "gpu/command_buffer/common/command_buffer_id.h" |
-#include "gpu/command_buffer/common/command_buffer_shared.h" |
-#include "gpu/command_buffer/common/gpu_memory_allocation.h" |
-#include "gpu/command_buffer/common/sync_token.h" |
-#include "gpu/command_buffer/service/image_factory.h" |
-#include "gpu/ipc/common/gpu_messages.h" |
-#include "gpu/ipc/common/gpu_param_traits.h" |
-#include "ui/gfx/geometry/size.h" |
-#include "ui/gl/gl_bindings.h" |
- |
-namespace content { |
- |
-namespace { |
- |
-gpu::CommandBufferId CommandBufferProxyID(int channel_id, int32_t route_id) { |
- return gpu::CommandBufferId::FromUnsafeValue( |
- (static_cast<uint64_t>(channel_id) << 32) | route_id); |
-} |
- |
-} // namespace |
- |
-CommandBufferProxyImpl::CommandBufferProxyImpl(GpuChannelHost* channel, |
- int32_t route_id, |
- int32_t stream_id) |
- : lock_(nullptr), |
- channel_(channel), |
- command_buffer_id_(CommandBufferProxyID(channel->channel_id(), route_id)), |
- route_id_(route_id), |
- stream_id_(stream_id), |
- flush_count_(0), |
- last_put_offset_(-1), |
- last_barrier_put_offset_(-1), |
- next_fence_sync_release_(1), |
- flushed_fence_sync_release_(0), |
- verified_fence_sync_release_(0), |
- next_signal_id_(0), |
- weak_this_(AsWeakPtr()), |
- callback_thread_(base::ThreadTaskRunnerHandle::Get()) { |
- DCHECK(channel); |
- DCHECK(stream_id); |
-} |
- |
-CommandBufferProxyImpl::~CommandBufferProxyImpl() { |
- FOR_EACH_OBSERVER(DeletionObserver, |
- deletion_observers_, |
- OnWillDeleteImpl()); |
- if (channel_) { |
- channel_->DestroyCommandBuffer(this); |
- channel_ = nullptr; |
- } |
-} |
- |
-bool CommandBufferProxyImpl::OnMessageReceived(const IPC::Message& message) { |
- scoped_ptr<base::AutoLock> lock; |
- if (lock_) |
- lock.reset(new base::AutoLock(*lock_)); |
- bool handled = true; |
- IPC_BEGIN_MESSAGE_MAP(CommandBufferProxyImpl, message) |
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Destroyed, OnDestroyed); |
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ConsoleMsg, OnConsoleMessage); |
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalAck, |
- OnSignalAck); |
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SwapBuffersCompleted, |
- OnSwapBuffersCompleted); |
- IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_UpdateVSyncParameters, |
- OnUpdateVSyncParameters); |
- IPC_MESSAGE_UNHANDLED(handled = false) |
- IPC_END_MESSAGE_MAP() |
- |
- if (!handled) { |
- DLOG(ERROR) << "Gpu process sent invalid message."; |
- InvalidGpuMessage(); |
- } |
- return handled; |
-} |
- |
-void CommandBufferProxyImpl::OnChannelError() { |
- scoped_ptr<base::AutoLock> lock; |
- if (lock_) |
- lock.reset(new base::AutoLock(*lock_)); |
- |
- gpu::error::ContextLostReason context_lost_reason = |
- gpu::error::kGpuChannelLost; |
- if (shared_state_shm_ && shared_state_shm_->memory()) { |
- TryUpdateState(); |
- // The GPU process might have intentionally been crashed |
- // (exit_on_context_lost), so try to find out the original reason. |
- if (last_state_.error == gpu::error::kLostContext) |
- context_lost_reason = last_state_.context_lost_reason; |
- } |
- OnDestroyed(context_lost_reason, gpu::error::kLostContext); |
-} |
- |
-void CommandBufferProxyImpl::OnDestroyed(gpu::error::ContextLostReason reason, |
- gpu::error::Error error) { |
- CheckLock(); |
- // Prevent any further messages from being sent. |
- if (channel_) { |
- channel_->DestroyCommandBuffer(this); |
- channel_ = nullptr; |
- } |
- |
- // When the client sees that the context is lost, they should delete this |
- // CommandBufferProxyImpl and create a new one. |
- last_state_.error = error; |
- last_state_.context_lost_reason = reason; |
- |
- if (!context_lost_callback_.is_null()) { |
- context_lost_callback_.Run(); |
- // Avoid calling the error callback more than once. |
- context_lost_callback_.Reset(); |
- } |
-} |
- |
-void CommandBufferProxyImpl::OnConsoleMessage( |
- const GPUCommandBufferConsoleMessage& message) { |
- if (!console_message_callback_.is_null()) { |
- console_message_callback_.Run(message.message, message.id); |
- } |
-} |
- |
-void CommandBufferProxyImpl::AddDeletionObserver(DeletionObserver* observer) { |
- scoped_ptr<base::AutoLock> lock; |
- if (lock_) |
- lock.reset(new base::AutoLock(*lock_)); |
- deletion_observers_.AddObserver(observer); |
-} |
- |
-void CommandBufferProxyImpl::RemoveDeletionObserver( |
- DeletionObserver* observer) { |
- scoped_ptr<base::AutoLock> lock; |
- if (lock_) |
- lock.reset(new base::AutoLock(*lock_)); |
- deletion_observers_.RemoveObserver(observer); |
-} |
- |
-void CommandBufferProxyImpl::OnSignalAck(uint32_t id) { |
- SignalTaskMap::iterator it = signal_tasks_.find(id); |
- if (it == signal_tasks_.end()) { |
- DLOG(ERROR) << "Gpu process sent invalid SignalAck."; |
- InvalidGpuMessage(); |
- return; |
- } |
- base::Closure callback = it->second; |
- signal_tasks_.erase(it); |
- callback.Run(); |
-} |
- |
-void CommandBufferProxyImpl::SetContextLostCallback( |
- const base::Closure& callback) { |
- CheckLock(); |
- context_lost_callback_ = callback; |
-} |
- |
-bool CommandBufferProxyImpl::Initialize() { |
- TRACE_EVENT0("gpu", "CommandBufferProxyImpl::Initialize"); |
- shared_state_shm_.reset(channel_->factory()->AllocateSharedMemory( |
- sizeof(*shared_state())).release()); |
- if (!shared_state_shm_) |
- return false; |
- |
- if (!shared_state_shm_->Map(sizeof(*shared_state()))) |
- return false; |
- |
- shared_state()->Initialize(); |
- |
- // This handle is owned by the GPU process and must be passed to it or it |
- // will leak. In otherwords, do not early out on error between here and the |
- // sending of the Initialize IPC below. |
- base::SharedMemoryHandle handle = |
- channel_->ShareToGpuProcess(shared_state_shm_->handle()); |
- if (!base::SharedMemory::IsHandleValid(handle)) |
- return false; |
- |
- bool result = false; |
- if (!Send(new GpuCommandBufferMsg_Initialize( |
- route_id_, handle, &result, &capabilities_))) { |
- LOG(ERROR) << "Could not send GpuCommandBufferMsg_Initialize."; |
- return false; |
- } |
- |
- if (!result) { |
- LOG(ERROR) << "Failed to initialize command buffer service."; |
- return false; |
- } |
- |
- capabilities_.image = true; |
- |
- return true; |
-} |
- |
-gpu::CommandBuffer::State CommandBufferProxyImpl::GetLastState() { |
- return last_state_; |
-} |
- |
-int32_t CommandBufferProxyImpl::GetLastToken() { |
- TryUpdateState(); |
- return last_state_.token; |
-} |
- |
-void CommandBufferProxyImpl::Flush(int32_t put_offset) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return; |
- |
- TRACE_EVENT1("gpu", |
- "CommandBufferProxyImpl::Flush", |
- "put_offset", |
- put_offset); |
- |
- bool put_offset_changed = last_put_offset_ != put_offset; |
- last_put_offset_ = put_offset; |
- last_barrier_put_offset_ = put_offset; |
- |
- if (channel_) { |
- const uint32_t flush_id = channel_->OrderingBarrier( |
- route_id_, stream_id_, put_offset, ++flush_count_, latency_info_, |
- put_offset_changed, true); |
- if (put_offset_changed) { |
- DCHECK(flush_id); |
- const uint64_t fence_sync_release = next_fence_sync_release_ - 1; |
- if (fence_sync_release > flushed_fence_sync_release_) { |
- flushed_fence_sync_release_ = fence_sync_release; |
- flushed_release_flush_id_.push( |
- std::make_pair(fence_sync_release, flush_id)); |
- } |
- } |
- } |
- |
- if (put_offset_changed) |
- latency_info_.clear(); |
-} |
- |
-void CommandBufferProxyImpl::OrderingBarrier(int32_t put_offset) { |
- if (last_state_.error != gpu::error::kNoError) |
- return; |
- |
- TRACE_EVENT1("gpu", "CommandBufferProxyImpl::OrderingBarrier", "put_offset", |
- put_offset); |
- |
- bool put_offset_changed = last_barrier_put_offset_ != put_offset; |
- last_barrier_put_offset_ = put_offset; |
- |
- if (channel_) { |
- const uint32_t flush_id = channel_->OrderingBarrier( |
- route_id_, stream_id_, put_offset, ++flush_count_, latency_info_, |
- put_offset_changed, false); |
- if (put_offset_changed) { |
- DCHECK(flush_id); |
- const uint64_t fence_sync_release = next_fence_sync_release_ - 1; |
- if (fence_sync_release > flushed_fence_sync_release_) { |
- flushed_fence_sync_release_ = fence_sync_release; |
- flushed_release_flush_id_.push( |
- std::make_pair(fence_sync_release, flush_id)); |
- } |
- } |
- } |
- |
- if (put_offset_changed) |
- latency_info_.clear(); |
-} |
- |
-void CommandBufferProxyImpl::SetLatencyInfo( |
- const std::vector<ui::LatencyInfo>& latency_info) { |
- CheckLock(); |
- for (size_t i = 0; i < latency_info.size(); i++) |
- latency_info_.push_back(latency_info[i]); |
-} |
- |
-void CommandBufferProxyImpl::SetSwapBuffersCompletionCallback( |
- const SwapBuffersCompletionCallback& callback) { |
- CheckLock(); |
- swap_buffers_completion_callback_ = callback; |
-} |
- |
-void CommandBufferProxyImpl::SetUpdateVSyncParametersCallback( |
- const UpdateVSyncParametersCallback& callback) { |
- CheckLock(); |
- update_vsync_parameters_completion_callback_ = callback; |
-} |
- |
-void CommandBufferProxyImpl::WaitForTokenInRange(int32_t start, int32_t end) { |
- CheckLock(); |
- TRACE_EVENT2("gpu", |
- "CommandBufferProxyImpl::WaitForToken", |
- "start", |
- start, |
- "end", |
- end); |
- TryUpdateState(); |
- if (!InRange(start, end, last_state_.token) && |
- last_state_.error == gpu::error::kNoError) { |
- gpu::CommandBuffer::State state; |
- if (Send(new GpuCommandBufferMsg_WaitForTokenInRange( |
- route_id_, start, end, &state))) |
- OnUpdateState(state); |
- } |
- if (!InRange(start, end, last_state_.token) && |
- last_state_.error == gpu::error::kNoError) { |
- DLOG(ERROR) << "GPU state invalid after WaitForTokenInRange."; |
- InvalidGpuReply(); |
- } |
-} |
- |
-void CommandBufferProxyImpl::WaitForGetOffsetInRange(int32_t start, |
- int32_t end) { |
- CheckLock(); |
- TRACE_EVENT2("gpu", |
- "CommandBufferProxyImpl::WaitForGetOffset", |
- "start", |
- start, |
- "end", |
- end); |
- TryUpdateState(); |
- if (!InRange(start, end, last_state_.get_offset) && |
- last_state_.error == gpu::error::kNoError) { |
- gpu::CommandBuffer::State state; |
- if (Send(new GpuCommandBufferMsg_WaitForGetOffsetInRange( |
- route_id_, start, end, &state))) |
- OnUpdateState(state); |
- } |
- if (!InRange(start, end, last_state_.get_offset) && |
- last_state_.error == gpu::error::kNoError) { |
- DLOG(ERROR) << "GPU state invalid after WaitForGetOffsetInRange."; |
- InvalidGpuReply(); |
- } |
-} |
- |
-void CommandBufferProxyImpl::SetGetBuffer(int32_t shm_id) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return; |
- |
- Send(new GpuCommandBufferMsg_SetGetBuffer(route_id_, shm_id)); |
- last_put_offset_ = -1; |
-} |
- |
-scoped_refptr<gpu::Buffer> CommandBufferProxyImpl::CreateTransferBuffer( |
- size_t size, |
- int32_t* id) { |
- CheckLock(); |
- *id = -1; |
- |
- if (last_state_.error != gpu::error::kNoError) |
- return NULL; |
- |
- int32_t new_id = channel_->ReserveTransferBufferId(); |
- |
- scoped_ptr<base::SharedMemory> shared_memory( |
- channel_->factory()->AllocateSharedMemory(size)); |
- if (!shared_memory) { |
- if (last_state_.error == gpu::error::kNoError) |
- last_state_.error = gpu::error::kOutOfBounds; |
- return NULL; |
- } |
- |
- DCHECK(!shared_memory->memory()); |
- if (!shared_memory->Map(size)) { |
- if (last_state_.error == gpu::error::kNoError) |
- last_state_.error = gpu::error::kOutOfBounds; |
- return NULL; |
- } |
- |
- // This handle is owned by the GPU process and must be passed to it or it |
- // will leak. In otherwords, do not early out on error between here and the |
- // sending of the RegisterTransferBuffer IPC below. |
- base::SharedMemoryHandle handle = |
- channel_->ShareToGpuProcess(shared_memory->handle()); |
- if (!base::SharedMemory::IsHandleValid(handle)) { |
- if (last_state_.error == gpu::error::kNoError) |
- last_state_.error = gpu::error::kLostContext; |
- return NULL; |
- } |
- |
- Send(new GpuCommandBufferMsg_RegisterTransferBuffer(route_id_, new_id, handle, |
- size)); |
- *id = new_id; |
- scoped_refptr<gpu::Buffer> buffer( |
- gpu::MakeBufferFromSharedMemory(std::move(shared_memory), size)); |
- return buffer; |
-} |
- |
-void CommandBufferProxyImpl::DestroyTransferBuffer(int32_t id) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return; |
- |
- Send(new GpuCommandBufferMsg_DestroyTransferBuffer(route_id_, id)); |
-} |
- |
-gpu::Capabilities CommandBufferProxyImpl::GetCapabilities() { |
- return capabilities_; |
-} |
- |
-int32_t CommandBufferProxyImpl::CreateImage(ClientBuffer buffer, |
- size_t width, |
- size_t height, |
- unsigned internal_format) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return -1; |
- |
- int32_t new_id = channel_->ReserveImageId(); |
- |
- gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager = |
- channel_->gpu_memory_buffer_manager(); |
- gfx::GpuMemoryBuffer* gpu_memory_buffer = |
- gpu_memory_buffer_manager->GpuMemoryBufferFromClientBuffer(buffer); |
- DCHECK(gpu_memory_buffer); |
- |
- // This handle is owned by the GPU process and must be passed to it or it |
- // will leak. In otherwords, do not early out on error between here and the |
- // sending of the CreateImage IPC below. |
- bool requires_sync_token = false; |
- gfx::GpuMemoryBufferHandle handle = |
- channel_->ShareGpuMemoryBufferToGpuProcess(gpu_memory_buffer->GetHandle(), |
- &requires_sync_token); |
- |
- uint64_t image_fence_sync = 0; |
- if (requires_sync_token) { |
- image_fence_sync = GenerateFenceSyncRelease(); |
- |
- // Make sure fence syncs were flushed before CreateImage() was called. |
- DCHECK_LE(image_fence_sync - 1, flushed_fence_sync_release_); |
- } |
- |
- DCHECK(gpu::ImageFactory::IsGpuMemoryBufferFormatSupported( |
- gpu_memory_buffer->GetFormat(), capabilities_)); |
- DCHECK(gpu::ImageFactory::IsImageSizeValidForGpuMemoryBufferFormat( |
- gfx::Size(width, height), gpu_memory_buffer->GetFormat())); |
- DCHECK(gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat( |
- internal_format, gpu_memory_buffer->GetFormat())); |
- |
- GpuCommandBufferMsg_CreateImage_Params params; |
- params.id = new_id; |
- params.gpu_memory_buffer = handle; |
- params.size = gfx::Size(width, height); |
- params.format = gpu_memory_buffer->GetFormat(); |
- params.internal_format = internal_format; |
- params.image_release_count = image_fence_sync; |
- |
- Send(new GpuCommandBufferMsg_CreateImage(route_id_, params)); |
- |
- if (image_fence_sync) { |
- gpu::SyncToken sync_token(GetNamespaceID(), GetExtraCommandBufferData(), |
- GetCommandBufferID(), image_fence_sync); |
- |
- // Force a synchronous IPC to validate sync token. |
- EnsureWorkVisible(); |
- sync_token.SetVerifyFlush(); |
- |
- gpu_memory_buffer_manager->SetDestructionSyncToken(gpu_memory_buffer, |
- sync_token); |
- } |
- |
- return new_id; |
-} |
- |
-void CommandBufferProxyImpl::DestroyImage(int32_t id) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return; |
- |
- Send(new GpuCommandBufferMsg_DestroyImage(route_id_, id)); |
-} |
- |
-int32_t CommandBufferProxyImpl::CreateGpuMemoryBufferImage( |
- size_t width, |
- size_t height, |
- unsigned internal_format, |
- unsigned usage) { |
- CheckLock(); |
- scoped_ptr<gfx::GpuMemoryBuffer> buffer( |
- channel_->gpu_memory_buffer_manager()->AllocateGpuMemoryBuffer( |
- gfx::Size(width, height), |
- gpu::ImageFactory::DefaultBufferFormatForImageFormat(internal_format), |
- gfx::BufferUsage::SCANOUT)); |
- if (!buffer) |
- return -1; |
- |
- return CreateImage(buffer->AsClientBuffer(), width, height, internal_format); |
-} |
- |
-uint32_t CommandBufferProxyImpl::CreateStreamTexture(uint32_t texture_id) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return 0; |
- |
- int32_t stream_id = channel_->GenerateRouteID(); |
- bool succeeded = false; |
- Send(new GpuCommandBufferMsg_CreateStreamTexture( |
- route_id_, texture_id, stream_id, &succeeded)); |
- if (!succeeded) { |
- DLOG(ERROR) << "GpuCommandBufferMsg_CreateStreamTexture returned failure"; |
- return 0; |
- } |
- return stream_id; |
-} |
- |
-void CommandBufferProxyImpl::SetLock(base::Lock* lock) { |
- lock_ = lock; |
-} |
- |
-bool CommandBufferProxyImpl::IsGpuChannelLost() { |
- return !channel_ || channel_->IsLost(); |
-} |
- |
-void CommandBufferProxyImpl::EnsureWorkVisible() { |
- if (channel_) |
- channel_->ValidateFlushIDReachedServer(stream_id_, true); |
-} |
- |
-gpu::CommandBufferNamespace CommandBufferProxyImpl::GetNamespaceID() const { |
- return gpu::CommandBufferNamespace::GPU_IO; |
-} |
- |
-gpu::CommandBufferId CommandBufferProxyImpl::GetCommandBufferID() const { |
- return command_buffer_id_; |
-} |
- |
-int32_t CommandBufferProxyImpl::GetExtraCommandBufferData() const { |
- return stream_id_; |
-} |
- |
-uint64_t CommandBufferProxyImpl::GenerateFenceSyncRelease() { |
- return next_fence_sync_release_++; |
-} |
- |
-bool CommandBufferProxyImpl::IsFenceSyncRelease(uint64_t release) { |
- return release != 0 && release < next_fence_sync_release_; |
-} |
- |
-bool CommandBufferProxyImpl::IsFenceSyncFlushed(uint64_t release) { |
- return release != 0 && release <= flushed_fence_sync_release_; |
-} |
- |
-bool CommandBufferProxyImpl::IsFenceSyncFlushReceived(uint64_t release) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return false; |
- |
- if (release <= verified_fence_sync_release_) |
- return true; |
- |
- // Check if we have actually flushed the fence sync release. |
- if (release <= flushed_fence_sync_release_) { |
- DCHECK(!flushed_release_flush_id_.empty()); |
- // Check if it has already been validated by another context. |
- UpdateVerifiedReleases(channel_->GetHighestValidatedFlushID(stream_id_)); |
- if (release <= verified_fence_sync_release_) |
- return true; |
- |
- // Has not been validated, validate it now. |
- UpdateVerifiedReleases( |
- channel_->ValidateFlushIDReachedServer(stream_id_, false)); |
- return release <= verified_fence_sync_release_; |
- } |
- |
- return false; |
-} |
- |
-void CommandBufferProxyImpl::SignalSyncToken(const gpu::SyncToken& sync_token, |
- const base::Closure& callback) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return; |
- |
- uint32_t signal_id = next_signal_id_++; |
- Send(new GpuCommandBufferMsg_SignalSyncToken(route_id_, sync_token, |
- signal_id)); |
- signal_tasks_.insert(std::make_pair(signal_id, callback)); |
-} |
- |
-bool CommandBufferProxyImpl::CanWaitUnverifiedSyncToken( |
- const gpu::SyncToken* sync_token) { |
- // Can only wait on an unverified sync token if it is from the same channel. |
- const uint64_t token_channel = |
- sync_token->command_buffer_id().GetUnsafeValue() >> 32; |
- const uint64_t channel = command_buffer_id_.GetUnsafeValue() >> 32; |
- if (sync_token->namespace_id() != gpu::CommandBufferNamespace::GPU_IO || |
- token_channel != channel) { |
- return false; |
- } |
- |
- // If waiting on a different stream, flush pending commands on that stream. |
- const int32_t release_stream_id = sync_token->extra_data_field(); |
- if (release_stream_id == 0) |
- return false; |
- |
- if (release_stream_id != stream_id_) |
- channel_->FlushPendingStream(release_stream_id); |
- |
- return true; |
-} |
- |
-void CommandBufferProxyImpl::SignalQuery(uint32_t query, |
- const base::Closure& callback) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return; |
- |
- // Signal identifiers are hidden, so nobody outside of this class will see |
- // them. (And thus, they cannot save them.) The IDs themselves only last |
- // until the callback is invoked, which will happen as soon as the GPU |
- // catches upwith the command buffer. |
- // A malicious caller trying to create a collision by making next_signal_id |
- // would have to make calls at an astounding rate (300B/s) and even if they |
- // could do that, all they would do is to prevent some callbacks from getting |
- // called, leading to stalled threads and/or memory leaks. |
- uint32_t signal_id = next_signal_id_++; |
- Send(new GpuCommandBufferMsg_SignalQuery(route_id_, query, signal_id)); |
- signal_tasks_.insert(std::make_pair(signal_id, callback)); |
-} |
- |
-bool CommandBufferProxyImpl::ProduceFrontBuffer(const gpu::Mailbox& mailbox) { |
- CheckLock(); |
- if (last_state_.error != gpu::error::kNoError) |
- return false; |
- |
- Send(new GpuCommandBufferMsg_ProduceFrontBuffer(route_id_, mailbox)); |
- return true; |
-} |
- |
-gpu::error::Error CommandBufferProxyImpl::GetLastError() { |
- return last_state_.error; |
-} |
- |
-bool CommandBufferProxyImpl::Send(IPC::Message* msg) { |
- // Caller should not intentionally send a message if the context is lost. |
- DCHECK(last_state_.error == gpu::error::kNoError); |
- DCHECK(channel_); |
- |
- if (!msg->is_sync()) { |
- bool result = channel_->Send(msg); |
- // Send() should always return true for async messages. |
- DCHECK(result); |
- return true; |
- } |
- |
- if (channel_->Send(msg)) |
- return true; |
- |
- // Flag the command buffer as lost. Defer deleting the channel until |
- // OnChannelError is called after returning to the message loop in case |
- // it is referenced elsewhere. |
- DVLOG(1) << "CommandBufferProxyImpl::Send failed. Losing context."; |
- last_state_.error = gpu::error::kLostContext; |
- return false; |
-} |
- |
-void CommandBufferProxyImpl::OnUpdateState( |
- const gpu::CommandBuffer::State& state) { |
- // Handle wraparound. It works as long as we don't have more than 2B state |
- // updates in flight across which reordering occurs. |
- if (state.generation - last_state_.generation < 0x80000000U) |
- last_state_ = state; |
-} |
- |
-void CommandBufferProxyImpl::SetOnConsoleMessageCallback( |
- const GpuConsoleMessageCallback& callback) { |
- CheckLock(); |
- console_message_callback_ = callback; |
-} |
- |
-void CommandBufferProxyImpl::TryUpdateState() { |
- if (last_state_.error == gpu::error::kNoError) |
- shared_state()->Read(&last_state_); |
-} |
- |
-void CommandBufferProxyImpl::UpdateVerifiedReleases(uint32_t verified_flush) { |
- while (!flushed_release_flush_id_.empty()) { |
- const std::pair<uint64_t, uint32_t>& front_item = |
- flushed_release_flush_id_.front(); |
- if (front_item.second > verified_flush) |
- break; |
- verified_fence_sync_release_ = front_item.first; |
- flushed_release_flush_id_.pop(); |
- } |
-} |
- |
-gpu::CommandBufferSharedState* CommandBufferProxyImpl::shared_state() const { |
- return reinterpret_cast<gpu::CommandBufferSharedState*>( |
- shared_state_shm_->memory()); |
-} |
- |
-void CommandBufferProxyImpl::OnSwapBuffersCompleted( |
- const std::vector<ui::LatencyInfo>& latency_info, |
- gfx::SwapResult result) { |
- if (!swap_buffers_completion_callback_.is_null()) { |
- if (!ui::LatencyInfo::Verify( |
- latency_info, "CommandBufferProxyImpl::OnSwapBuffersCompleted")) { |
- swap_buffers_completion_callback_.Run(std::vector<ui::LatencyInfo>(), |
- result); |
- return; |
- } |
- swap_buffers_completion_callback_.Run(latency_info, result); |
- } |
-} |
- |
-void CommandBufferProxyImpl::OnUpdateVSyncParameters(base::TimeTicks timebase, |
- base::TimeDelta interval) { |
- if (!update_vsync_parameters_completion_callback_.is_null()) |
- update_vsync_parameters_completion_callback_.Run(timebase, interval); |
-} |
- |
-void CommandBufferProxyImpl::InvalidGpuMessage() { |
- LOG(ERROR) << "Received invalid message from the GPU process."; |
- OnDestroyed(gpu::error::kInvalidGpuMessage, gpu::error::kLostContext); |
-} |
- |
-void CommandBufferProxyImpl::InvalidGpuReply() { |
- CheckLock(); |
- LOG(ERROR) << "Received invalid reply from the GPU process."; |
- last_state_.error = gpu::error::kLostContext; |
- last_state_.context_lost_reason = gpu::error::kInvalidGpuMessage; |
- callback_thread_->PostTask( |
- FROM_HERE, |
- base::Bind(&CommandBufferProxyImpl::InvalidGpuReplyOnClientThread, |
- weak_this_)); |
-} |
- |
-void CommandBufferProxyImpl::InvalidGpuReplyOnClientThread() { |
- scoped_ptr<base::AutoLock> lock; |
- if (lock_) |
- lock.reset(new base::AutoLock(*lock_)); |
- OnDestroyed(gpu::error::kInvalidGpuMessage, gpu::error::kLostContext); |
-} |
- |
-} // namespace content |