| Index: content/common/gpu/client/gpu_channel_host.cc
|
| diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc
|
| deleted file mode 100644
|
| index 9c8e09f570f529af66b6a6a1df0df3d75a3cdc3b..0000000000000000000000000000000000000000
|
| --- a/content/common/gpu/client/gpu_channel_host.cc
|
| +++ /dev/null
|
| @@ -1,481 +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/gpu_channel_host.h"
|
| -
|
| -#include <algorithm>
|
| -#include <utility>
|
| -
|
| -#include "base/atomic_sequence_num.h"
|
| -#include "base/bind.h"
|
| -#include "base/location.h"
|
| -#include "base/posix/eintr_wrapper.h"
|
| -#include "base/profiler/scoped_tracker.h"
|
| -#include "base/single_thread_task_runner.h"
|
| -#include "base/thread_task_runner_handle.h"
|
| -#include "base/threading/thread_restrictions.h"
|
| -#include "base/trace_event/trace_event.h"
|
| -#include "build/build_config.h"
|
| -#include "content/common/gpu/client/command_buffer_proxy_impl.h"
|
| -#include "gpu/ipc/common/gpu_messages.h"
|
| -#include "gpu/ipc/common/gpu_param_traits_macros.h"
|
| -#include "ipc/ipc_sync_message_filter.h"
|
| -#include "url/gurl.h"
|
| -
|
| -using base::AutoLock;
|
| -
|
| -namespace content {
|
| -namespace {
|
| -
|
| -// Global atomic to generate unique transfer buffer IDs.
|
| -base::StaticAtomicSequenceNumber g_next_transfer_buffer_id;
|
| -
|
| -} // namespace
|
| -
|
| -GpuChannelHost::StreamFlushInfo::StreamFlushInfo()
|
| - : next_stream_flush_id(1),
|
| - flushed_stream_flush_id(0),
|
| - verified_stream_flush_id(0),
|
| - flush_pending(false),
|
| - route_id(MSG_ROUTING_NONE),
|
| - put_offset(0),
|
| - flush_count(0),
|
| - flush_id(0) {}
|
| -
|
| -GpuChannelHost::StreamFlushInfo::StreamFlushInfo(const StreamFlushInfo& other) =
|
| - default;
|
| -
|
| -GpuChannelHost::StreamFlushInfo::~StreamFlushInfo() {}
|
| -
|
| -// static
|
| -scoped_refptr<GpuChannelHost> GpuChannelHost::Create(
|
| - GpuChannelHostFactory* factory,
|
| - int channel_id,
|
| - const gpu::GPUInfo& gpu_info,
|
| - const IPC::ChannelHandle& channel_handle,
|
| - base::WaitableEvent* shutdown_event,
|
| - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) {
|
| - DCHECK(factory->IsMainThread());
|
| - scoped_refptr<GpuChannelHost> host =
|
| - new GpuChannelHost(factory, channel_id, gpu_info,
|
| - gpu_memory_buffer_manager);
|
| - host->Connect(channel_handle, shutdown_event);
|
| - return host;
|
| -}
|
| -
|
| -GpuChannelHost::GpuChannelHost(
|
| - GpuChannelHostFactory* factory,
|
| - int channel_id,
|
| - const gpu::GPUInfo& gpu_info,
|
| - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager)
|
| - : factory_(factory),
|
| - channel_id_(channel_id),
|
| - gpu_info_(gpu_info),
|
| - gpu_memory_buffer_manager_(gpu_memory_buffer_manager) {
|
| - next_image_id_.GetNext();
|
| - next_route_id_.GetNext();
|
| - next_stream_id_.GetNext();
|
| -}
|
| -
|
| -void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle,
|
| - base::WaitableEvent* shutdown_event) {
|
| - DCHECK(factory_->IsMainThread());
|
| - // Open a channel to the GPU process. We pass nullptr as the main listener
|
| - // here since we need to filter everything to route it to the right thread.
|
| - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
|
| - factory_->GetIOThreadTaskRunner();
|
| - channel_ = IPC::SyncChannel::Create(channel_handle, IPC::Channel::MODE_CLIENT,
|
| - nullptr, io_task_runner.get(), true,
|
| - shutdown_event);
|
| -
|
| - sync_filter_ = channel_->CreateSyncMessageFilter();
|
| -
|
| - channel_filter_ = new MessageFilter();
|
| -
|
| - // Install the filter last, because we intercept all leftover
|
| - // messages.
|
| - channel_->AddFilter(channel_filter_.get());
|
| -}
|
| -
|
| -bool GpuChannelHost::Send(IPC::Message* msg) {
|
| - // Callee takes ownership of message, regardless of whether Send is
|
| - // successful. See IPC::Sender.
|
| - scoped_ptr<IPC::Message> message(msg);
|
| - // The GPU process never sends synchronous IPCs so clear the unblock flag to
|
| - // preserve order.
|
| - message->set_unblock(false);
|
| -
|
| - // Currently we need to choose between two different mechanisms for sending.
|
| - // On the main thread we use the regular channel Send() method, on another
|
| - // thread we use SyncMessageFilter. We also have to be careful interpreting
|
| - // IsMainThread() since it might return false during shutdown,
|
| - // impl we are actually calling from the main thread (discard message then).
|
| - //
|
| - // TODO: Can we just always use sync_filter_ since we setup the channel
|
| - // without a main listener?
|
| - if (factory_->IsMainThread()) {
|
| - // channel_ is only modified on the main thread, so we don't need to take a
|
| - // lock here.
|
| - if (!channel_) {
|
| - DVLOG(1) << "GpuChannelHost::Send failed: Channel already destroyed";
|
| - return false;
|
| - }
|
| - // http://crbug.com/125264
|
| - base::ThreadRestrictions::ScopedAllowWait allow_wait;
|
| - bool result = channel_->Send(message.release());
|
| - if (!result)
|
| - DVLOG(1) << "GpuChannelHost::Send failed: Channel::Send failed";
|
| - return result;
|
| - }
|
| -
|
| - bool result = sync_filter_->Send(message.release());
|
| - return result;
|
| -}
|
| -
|
| -uint32_t GpuChannelHost::OrderingBarrier(
|
| - int32_t route_id,
|
| - int32_t stream_id,
|
| - int32_t put_offset,
|
| - uint32_t flush_count,
|
| - const std::vector<ui::LatencyInfo>& latency_info,
|
| - bool put_offset_changed,
|
| - bool do_flush) {
|
| - AutoLock lock(context_lock_);
|
| - StreamFlushInfo& flush_info = stream_flush_info_[stream_id];
|
| - if (flush_info.flush_pending && flush_info.route_id != route_id)
|
| - InternalFlush(&flush_info);
|
| -
|
| - if (put_offset_changed) {
|
| - const uint32_t flush_id = flush_info.next_stream_flush_id++;
|
| - flush_info.flush_pending = true;
|
| - flush_info.route_id = route_id;
|
| - flush_info.put_offset = put_offset;
|
| - flush_info.flush_count = flush_count;
|
| - flush_info.flush_id = flush_id;
|
| - flush_info.latency_info.insert(flush_info.latency_info.end(),
|
| - latency_info.begin(), latency_info.end());
|
| -
|
| - if (do_flush)
|
| - InternalFlush(&flush_info);
|
| -
|
| - return flush_id;
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -void GpuChannelHost::FlushPendingStream(int32_t stream_id) {
|
| - AutoLock lock(context_lock_);
|
| - auto flush_info_iter = stream_flush_info_.find(stream_id);
|
| - if (flush_info_iter == stream_flush_info_.end())
|
| - return;
|
| -
|
| - StreamFlushInfo& flush_info = flush_info_iter->second;
|
| - if (flush_info.flush_pending)
|
| - InternalFlush(&flush_info);
|
| -}
|
| -
|
| -void GpuChannelHost::InternalFlush(StreamFlushInfo* flush_info) {
|
| - context_lock_.AssertAcquired();
|
| - DCHECK(flush_info);
|
| - DCHECK(flush_info->flush_pending);
|
| - DCHECK_LT(flush_info->flushed_stream_flush_id, flush_info->flush_id);
|
| - Send(new GpuCommandBufferMsg_AsyncFlush(
|
| - flush_info->route_id, flush_info->put_offset, flush_info->flush_count,
|
| - flush_info->latency_info));
|
| - flush_info->latency_info.clear();
|
| - flush_info->flush_pending = false;
|
| -
|
| - flush_info->flushed_stream_flush_id = flush_info->flush_id;
|
| -}
|
| -
|
| -scoped_ptr<CommandBufferProxyImpl> GpuChannelHost::CreateCommandBuffer(
|
| - gpu::SurfaceHandle surface_handle,
|
| - const gfx::Size& size,
|
| - CommandBufferProxyImpl* share_group,
|
| - int32_t stream_id,
|
| - gpu::GpuStreamPriority stream_priority,
|
| - const std::vector<int32_t>& attribs,
|
| - const GURL& active_url,
|
| - gfx::GpuPreference gpu_preference) {
|
| - DCHECK(!share_group || (stream_id == share_group->stream_id()));
|
| - TRACE_EVENT1("gpu", "GpuChannelHost::CreateViewCommandBuffer",
|
| - "surface_handle", surface_handle);
|
| -
|
| - GPUCreateCommandBufferConfig init_params;
|
| - init_params.share_group_id =
|
| - share_group ? share_group->route_id() : MSG_ROUTING_NONE;
|
| - init_params.stream_id = stream_id;
|
| - init_params.stream_priority = stream_priority;
|
| - init_params.attribs = attribs;
|
| - init_params.active_url = active_url;
|
| - init_params.gpu_preference = gpu_preference;
|
| -
|
| - int32_t route_id = GenerateRouteID();
|
| -
|
| - // TODO(vadimt): Remove ScopedTracker below once crbug.com/125248 is fixed.
|
| - tracked_objects::ScopedTracker tracking_profile(
|
| - FROM_HERE_WITH_EXPLICIT_FUNCTION(
|
| - "125248 GpuChannelHost::CreateCommandBuffer"));
|
| -
|
| - // We're blocking the UI thread, which is generally undesirable.
|
| - // In this case we need to wait for this before we can show any UI /anyway/,
|
| - // so it won't cause additional jank.
|
| - // TODO(piman): Make this asynchronous (http://crbug.com/125248).
|
| -
|
| - bool succeeded = false;
|
| - if (!Send(new GpuChannelMsg_CreateCommandBuffer(
|
| - surface_handle, size, init_params, route_id, &succeeded))) {
|
| - LOG(ERROR) << "Failed to send GpuChannelMsg_CreateCommandBuffer.";
|
| - return nullptr;
|
| - }
|
| -
|
| - if (!succeeded) {
|
| - LOG(ERROR) << "GpuChannelMsg_CreateCommandBuffer returned failure.";
|
| - return nullptr;
|
| - }
|
| -
|
| - scoped_ptr<CommandBufferProxyImpl> command_buffer =
|
| - make_scoped_ptr(new CommandBufferProxyImpl(this, route_id, stream_id));
|
| - AddRoute(route_id, command_buffer->AsWeakPtr());
|
| -
|
| - return command_buffer;
|
| -}
|
| -
|
| -void GpuChannelHost::DestroyCommandBuffer(
|
| - CommandBufferProxyImpl* command_buffer) {
|
| - TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer");
|
| -
|
| - int32_t route_id = command_buffer->route_id();
|
| - int32_t stream_id = command_buffer->stream_id();
|
| - Send(new GpuChannelMsg_DestroyCommandBuffer(route_id));
|
| - RemoveRoute(route_id);
|
| -
|
| - AutoLock lock(context_lock_);
|
| - StreamFlushInfo& flush_info = stream_flush_info_[stream_id];
|
| - if (flush_info.flush_pending && flush_info.route_id == route_id)
|
| - flush_info.flush_pending = false;
|
| -}
|
| -
|
| -void GpuChannelHost::DestroyChannel() {
|
| - DCHECK(factory_->IsMainThread());
|
| - AutoLock lock(context_lock_);
|
| - channel_.reset();
|
| -}
|
| -
|
| -void GpuChannelHost::AddRoute(
|
| - int route_id, base::WeakPtr<IPC::Listener> listener) {
|
| - AddRouteWithTaskRunner(route_id, listener,
|
| - base::ThreadTaskRunnerHandle::Get());
|
| -}
|
| -
|
| -void GpuChannelHost::AddRouteWithTaskRunner(
|
| - int route_id,
|
| - base::WeakPtr<IPC::Listener> listener,
|
| - scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
|
| - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
|
| - factory_->GetIOThreadTaskRunner();
|
| - io_task_runner->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&GpuChannelHost::MessageFilter::AddRoute,
|
| - channel_filter_.get(), route_id, listener, task_runner));
|
| -}
|
| -
|
| -void GpuChannelHost::RemoveRoute(int route_id) {
|
| - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner =
|
| - factory_->GetIOThreadTaskRunner();
|
| - io_task_runner->PostTask(
|
| - FROM_HERE, base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute,
|
| - channel_filter_.get(), route_id));
|
| -}
|
| -
|
| -base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess(
|
| - base::SharedMemoryHandle source_handle) {
|
| - if (IsLost())
|
| - return base::SharedMemory::NULLHandle();
|
| -
|
| - return base::SharedMemory::DuplicateHandle(source_handle);
|
| -}
|
| -
|
| -int32_t GpuChannelHost::ReserveTransferBufferId() {
|
| - // 0 is a reserved value.
|
| - return g_next_transfer_buffer_id.GetNext() + 1;
|
| -}
|
| -
|
| -gfx::GpuMemoryBufferHandle GpuChannelHost::ShareGpuMemoryBufferToGpuProcess(
|
| - 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 = ShareToGpuProcess(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::SURFACE_TEXTURE_BUFFER:
|
| - case gfx::OZONE_NATIVE_PIXMAP:
|
| - *requires_sync_point = true;
|
| - return source_handle;
|
| - default:
|
| - NOTREACHED();
|
| - return gfx::GpuMemoryBufferHandle();
|
| - }
|
| -}
|
| -
|
| -int32_t GpuChannelHost::ReserveImageId() {
|
| - return next_image_id_.GetNext();
|
| -}
|
| -
|
| -int32_t GpuChannelHost::GenerateRouteID() {
|
| - return next_route_id_.GetNext();
|
| -}
|
| -
|
| -int32_t GpuChannelHost::GenerateStreamID() {
|
| - const int32_t stream_id = next_stream_id_.GetNext();
|
| - DCHECK_NE(0, stream_id);
|
| - DCHECK_NE(kDefaultStreamId, stream_id);
|
| - return stream_id;
|
| -}
|
| -
|
| -uint32_t GpuChannelHost::ValidateFlushIDReachedServer(int32_t stream_id,
|
| - bool force_validate) {
|
| - // Store what flush ids we will be validating for all streams.
|
| - base::hash_map<int32_t, uint32_t> validate_flushes;
|
| - uint32_t flushed_stream_flush_id = 0;
|
| - uint32_t verified_stream_flush_id = 0;
|
| - {
|
| - AutoLock lock(context_lock_);
|
| - for (const auto& iter : stream_flush_info_) {
|
| - const int32_t iter_stream_id = iter.first;
|
| - const StreamFlushInfo& flush_info = iter.second;
|
| - if (iter_stream_id == stream_id) {
|
| - flushed_stream_flush_id = flush_info.flushed_stream_flush_id;
|
| - verified_stream_flush_id = flush_info.verified_stream_flush_id;
|
| - }
|
| -
|
| - if (flush_info.flushed_stream_flush_id >
|
| - flush_info.verified_stream_flush_id) {
|
| - validate_flushes.insert(
|
| - std::make_pair(iter_stream_id, flush_info.flushed_stream_flush_id));
|
| - }
|
| - }
|
| - }
|
| -
|
| - if (!force_validate && flushed_stream_flush_id == verified_stream_flush_id) {
|
| - // Current stream has no unverified flushes.
|
| - return verified_stream_flush_id;
|
| - }
|
| -
|
| - if (Send(new GpuChannelMsg_Nop())) {
|
| - // Update verified flush id for all streams.
|
| - uint32_t highest_flush_id = 0;
|
| - AutoLock lock(context_lock_);
|
| - for (const auto& iter : validate_flushes) {
|
| - const int32_t validated_stream_id = iter.first;
|
| - const uint32_t validated_flush_id = iter.second;
|
| - StreamFlushInfo& flush_info = stream_flush_info_[validated_stream_id];
|
| - if (flush_info.verified_stream_flush_id < validated_flush_id) {
|
| - flush_info.verified_stream_flush_id = validated_flush_id;
|
| - }
|
| -
|
| - if (validated_stream_id == stream_id)
|
| - highest_flush_id = flush_info.verified_stream_flush_id;
|
| - }
|
| -
|
| - return highest_flush_id;
|
| - }
|
| -
|
| - return 0;
|
| -}
|
| -
|
| -uint32_t GpuChannelHost::GetHighestValidatedFlushID(int32_t stream_id) {
|
| - AutoLock lock(context_lock_);
|
| - StreamFlushInfo& flush_info = stream_flush_info_[stream_id];
|
| - return flush_info.verified_stream_flush_id;
|
| -}
|
| -
|
| -GpuChannelHost::~GpuChannelHost() {
|
| -#if DCHECK_IS_ON()
|
| - AutoLock lock(context_lock_);
|
| - DCHECK(!channel_)
|
| - << "GpuChannelHost::DestroyChannel must be called before destruction.";
|
| -#endif
|
| -}
|
| -
|
| -GpuChannelHost::MessageFilter::ListenerInfo::ListenerInfo() {}
|
| -
|
| -GpuChannelHost::MessageFilter::ListenerInfo::ListenerInfo(
|
| - const ListenerInfo& other) = default;
|
| -
|
| -GpuChannelHost::MessageFilter::ListenerInfo::~ListenerInfo() {}
|
| -
|
| -GpuChannelHost::MessageFilter::MessageFilter()
|
| - : lost_(false) {
|
| -}
|
| -
|
| -GpuChannelHost::MessageFilter::~MessageFilter() {}
|
| -
|
| -void GpuChannelHost::MessageFilter::AddRoute(
|
| - int32_t route_id,
|
| - base::WeakPtr<IPC::Listener> listener,
|
| - scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
|
| - DCHECK(listeners_.find(route_id) == listeners_.end());
|
| - DCHECK(task_runner);
|
| - ListenerInfo info;
|
| - info.listener = listener;
|
| - info.task_runner = task_runner;
|
| - listeners_[route_id] = info;
|
| -}
|
| -
|
| -void GpuChannelHost::MessageFilter::RemoveRoute(int32_t route_id) {
|
| - listeners_.erase(route_id);
|
| -}
|
| -
|
| -bool GpuChannelHost::MessageFilter::OnMessageReceived(
|
| - const IPC::Message& message) {
|
| - // Never handle sync message replies or we will deadlock here.
|
| - if (message.is_reply())
|
| - return false;
|
| -
|
| - auto it = listeners_.find(message.routing_id());
|
| - if (it == listeners_.end())
|
| - return false;
|
| -
|
| - const ListenerInfo& info = it->second;
|
| - info.task_runner->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(base::IgnoreResult(&IPC::Listener::OnMessageReceived),
|
| - info.listener, message));
|
| - return true;
|
| -}
|
| -
|
| -void GpuChannelHost::MessageFilter::OnChannelError() {
|
| - // Set the lost state before signalling the proxies. That way, if they
|
| - // themselves post a task to recreate the context, they will not try to re-use
|
| - // this channel host.
|
| - {
|
| - AutoLock lock(lock_);
|
| - lost_ = true;
|
| - }
|
| -
|
| - // Inform all the proxies that an error has occurred. This will be reported
|
| - // via OpenGL as a lost context.
|
| - for (const auto& kv : listeners_) {
|
| - const ListenerInfo& info = kv.second;
|
| - info.task_runner->PostTask(
|
| - FROM_HERE, base::Bind(&IPC::Listener::OnChannelError, info.listener));
|
| - }
|
| -
|
| - listeners_.clear();
|
| -}
|
| -
|
| -bool GpuChannelHost::MessageFilter::IsLost() const {
|
| - AutoLock lock(lock_);
|
| - return lost_;
|
| -}
|
| -
|
| -} // namespace content
|
|
|