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

Unified Diff: gpu/ipc/service/gpu_channel.cc

Issue 2440093003: WIP GPU scheduler + delayed activation / tile draw
Patch Set: SignalSyncToken -> IsFenceSyncReleased Created 4 years 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/ipc/service/gpu_channel.h ('k') | gpu/ipc/service/gpu_channel_manager.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/ipc/service/gpu_channel.cc
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc
index 8ed788a38174e3cf06d81a61d7c6181fe5a81986..871e34401678fd9141e4a10de019d0611ad222de 100644
--- a/gpu/ipc/service/gpu_channel.cc
+++ b/gpu/ipc/service/gpu_channel.cc
@@ -39,6 +39,7 @@
#include "gpu/ipc/service/gpu_channel_manager.h"
#include "gpu/ipc/service/gpu_channel_manager_delegate.h"
#include "gpu/ipc/service/gpu_memory_buffer_factory.h"
+#include "gpu/ipc/service/gpu_scheduler.h"
#include "ipc/ipc_channel.h"
#include "ipc/message_filter.h"
#include "ui/gl/gl_context.h"
@@ -71,13 +72,16 @@ scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageQueue::Create(
int32_t stream_id,
GpuStreamPriority stream_priority,
GpuChannel* channel,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
- const scoped_refptr<PreemptionFlag>& preempting_flag,
- const scoped_refptr<PreemptionFlag>& preempted_flag,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ GpuScheduler* scheduler,
+ scoped_refptr<PreemptionFlag> preempting_flag,
+ scoped_refptr<PreemptionFlag> preemption_flag,
SyncPointManager* sync_point_manager) {
- return new GpuChannelMessageQueue(stream_id, stream_priority, channel,
- io_task_runner, preempting_flag,
- preempted_flag, sync_point_manager);
+ return new GpuChannelMessageQueue(
+ stream_id, stream_priority, channel, std::move(main_task_runner),
+ std::move(io_task_runner), scheduler, std::move(preempting_flag),
+ std::move(preemption_flag), sync_point_manager);
}
scoped_refptr<SyncPointOrderData>
@@ -89,13 +93,15 @@ GpuChannelMessageQueue::GpuChannelMessageQueue(
int32_t stream_id,
GpuStreamPriority stream_priority,
GpuChannel* channel,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
- const scoped_refptr<PreemptionFlag>& preempting_flag,
- const scoped_refptr<PreemptionFlag>& preempted_flag,
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ GpuScheduler* scheduler,
+ scoped_refptr<PreemptionFlag> preempting_flag,
+ scoped_refptr<PreemptionFlag> preemption_flag,
SyncPointManager* sync_point_manager)
: stream_id_(stream_id),
- stream_priority_(stream_priority),
- enabled_(true),
+ priority_(stream_priority),
+ num_routes_(0u),
scheduled_(true),
channel_(channel),
preemption_state_(IDLE),
@@ -103,30 +109,25 @@ GpuChannelMessageQueue::GpuChannelMessageQueue(
base::TimeDelta::FromMilliseconds(kMaxPreemptTimeMs)),
timer_(new base::OneShotTimer),
sync_point_order_data_(SyncPointOrderData::Create()),
- io_task_runner_(io_task_runner),
- preempting_flag_(preempting_flag),
- preempted_flag_(preempted_flag),
+ main_task_runner_(std::move(main_task_runner)),
+ io_task_runner_(std::move(io_task_runner)),
+ scheduler_(scheduler),
+ preempting_flag_(std::move(preempting_flag)),
+ preemption_flag_(std::move(preemption_flag)),
sync_point_manager_(sync_point_manager) {
timer_->SetTaskRunner(io_task_runner);
io_thread_checker_.DetachFromThread();
+ if (scheduler_)
+ scheduler_->AddStream(this, stream_priority);
}
GpuChannelMessageQueue::~GpuChannelMessageQueue() {
- DCHECK(!enabled_);
DCHECK(channel_messages_.empty());
}
-void GpuChannelMessageQueue::Disable() {
- {
- base::AutoLock auto_lock(channel_lock_);
- DCHECK(enabled_);
- enabled_ = false;
- }
-
- // We guarantee that the queues will no longer be modified after enabled_
- // is set to false, it is now safe to modify the queue without the lock.
- // All public facing modifying functions check enabled_ while all
- // private modifying functions DCHECK(enabled_) to enforce this.
+void GpuChannelMessageQueue::Destroy() {
+ // We guarantee that the queues will no longer be modified when |Destroy| is
+ // called therefore it is now safe to modify the queue without the lock.
while (!channel_messages_.empty()) {
const IPC::Message& msg = channel_messages_.front()->message;
if (msg.is_sync()) {
@@ -140,32 +141,67 @@ void GpuChannelMessageQueue::Disable() {
sync_point_order_data_->Destroy();
sync_point_order_data_ = nullptr;
+ if (scheduler_)
+ scheduler_->RemoveStream(this);
+
+ channel_ = nullptr;
+
io_task_runner_->PostTask(
- FROM_HERE, base::Bind(&GpuChannelMessageQueue::DisableIO, this));
+ FROM_HERE, base::Bind(&GpuChannelMessageQueue::DestroyIO, this));
}
-void GpuChannelMessageQueue::DisableIO() {
+void GpuChannelMessageQueue::DestroyIO() {
DCHECK(io_thread_checker_.CalledOnValidThread());
timer_ = nullptr;
}
+void GpuChannelMessageQueue::OnRouteAdded() {
+ num_routes_++;
+}
+
+void GpuChannelMessageQueue::OnRouteRemoved() {
+ num_routes_--;
+}
+
+size_t GpuChannelMessageQueue::NumRoutes() const {
+ return num_routes_;
+}
+
+void GpuChannelMessageQueue::Run() {
+ DCHECK(scheduler_);
+ while (!scheduler_->ShouldYield() && HasMessages() && IsScheduled())
+ channel_->HandleMessageOnStream(this);
+}
+
bool GpuChannelMessageQueue::IsScheduled() const {
base::AutoLock lock(channel_lock_);
return scheduled_;
}
-void GpuChannelMessageQueue::OnRescheduled(bool scheduled) {
+void GpuChannelMessageQueue::Schedule() {
base::AutoLock lock(channel_lock_);
- DCHECK(enabled_);
- if (scheduled_ == scheduled)
+ if (scheduled_)
return;
- scheduled_ = scheduled;
- if (scheduled)
- channel_->PostHandleMessage(this);
- if (preempting_flag_) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&GpuChannelMessageQueue::UpdatePreemptionState, this));
+ scheduled_ = true;
+ if (scheduler_) {
+ scheduler_->ScheduleStream(this);
+ } else {
+ if (!channel_messages_.empty())
+ channel_->PostHandleMessageOnStream(this);
+ if (preempting_flag_)
+ PostUpdatePreemptionState();
+ }
+}
+
+void GpuChannelMessageQueue::Deschedule() {
+ base::AutoLock lock(channel_lock_);
+ if (!scheduled_)
+ return;
+ scheduled_ = false;
+ if (scheduler_) {
+ scheduler_->DescheduleStream(this);
+ } else if (preempting_flag_) {
+ PostUpdatePreemptionState();
}
}
@@ -177,45 +213,42 @@ uint32_t GpuChannelMessageQueue::GetProcessedOrderNum() const {
return sync_point_order_data_->processed_order_num();
}
-bool GpuChannelMessageQueue::PushBackMessage(const IPC::Message& message) {
+bool GpuChannelMessageQueue::HasMessages() const {
base::AutoLock auto_lock(channel_lock_);
- if (enabled_) {
- if (message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID ||
- message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) {
- channel_->PostHandleOutOfOrderMessage(message);
- return true;
- }
+ return !channel_messages_.empty();
+}
- uint32_t order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber(
- sync_point_manager_);
- std::unique_ptr<GpuChannelMessage> msg(
- new GpuChannelMessage(message, order_num, base::TimeTicks::Now()));
+void GpuChannelMessageQueue::PushBackMessage(const IPC::Message& message) {
+ base::AutoLock auto_lock(channel_lock_);
+ DCHECK(channel_);
- if (channel_messages_.empty()) {
- DCHECK(scheduled_);
- channel_->PostHandleMessage(this);
- }
+ uint32_t order_num = sync_point_order_data_->GenerateUnprocessedOrderNumber(
+ sync_point_manager_);
+ std::unique_ptr<GpuChannelMessage> msg(
+ new GpuChannelMessage(message, order_num, base::TimeTicks::Now()));
+ channel_messages_.push_back(std::move(msg));
- channel_messages_.push_back(std::move(msg));
+ bool start_running = channel_messages_.size() == 1 && scheduled_;
+ if (scheduler_) {
+ if (start_running)
+ scheduler_->ScheduleStream(this);
+ } else {
+ if (start_running)
+ channel_->PostHandleMessageOnStream(this);
if (preempting_flag_)
UpdatePreemptionStateHelper();
-
- return true;
}
- return false;
}
const GpuChannelMessage* GpuChannelMessageQueue::BeginMessageProcessing() {
base::AutoLock auto_lock(channel_lock_);
- DCHECK(enabled_);
- // If we have been preempted by another channel, just post a task to wake up.
- if (preempted_flag_ && preempted_flag_->IsSet()) {
- channel_->PostHandleMessage(this);
- return nullptr;
- }
if (channel_messages_.empty())
return nullptr;
+ if (preemption_flag_ && preemption_flag_->IsSet()) {
+ channel_->PostHandleMessageOnStream(this);
+ return nullptr;
+ }
sync_point_order_data_->BeginProcessingOrderNumber(
channel_messages_.front()->order_number);
return channel_messages_.front().get();
@@ -225,12 +258,15 @@ void GpuChannelMessageQueue::PauseMessageProcessing() {
base::AutoLock auto_lock(channel_lock_);
DCHECK(!channel_messages_.empty());
- // If we have been preempted by another channel, just post a task to wake up.
- if (scheduled_)
- channel_->PostHandleMessage(this);
-
sync_point_order_data_->PauseProcessingOrderNumber(
channel_messages_.front()->order_number);
+
+ if (!scheduler_) {
+ if (scheduled_)
+ channel_->PostHandleMessageOnStream(this);
+ if (preempting_flag_)
+ PostUpdatePreemptionState();
+ }
}
void GpuChannelMessageQueue::FinishMessageProcessing() {
@@ -242,27 +278,34 @@ void GpuChannelMessageQueue::FinishMessageProcessing() {
channel_messages_.front()->order_number);
channel_messages_.pop_front();
- if (!channel_messages_.empty())
- channel_->PostHandleMessage(this);
-
- if (preempting_flag_) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&GpuChannelMessageQueue::UpdatePreemptionState, this));
+ if (scheduler_) {
+ if (channel_messages_.empty())
+ scheduler_->DescheduleStream(this);
+ } else {
+ if (!channel_messages_.empty())
+ channel_->PostHandleMessageOnStream(this);
+ if (preempting_flag_)
+ PostUpdatePreemptionState();
}
}
-void GpuChannelMessageQueue::UpdatePreemptionState() {
- DCHECK(io_thread_checker_.CalledOnValidThread());
+void GpuChannelMessageQueue::PostUpdatePreemptionState() {
DCHECK(preempting_flag_);
+ DCHECK(!scheduler_);
+ io_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&GpuChannelMessageQueue::UpdatePreemptionState, this));
+}
+
+void GpuChannelMessageQueue::UpdatePreemptionState() {
base::AutoLock lock(channel_lock_);
UpdatePreemptionStateHelper();
}
void GpuChannelMessageQueue::UpdatePreemptionStateHelper() {
DCHECK(io_thread_checker_.CalledOnValidThread());
- DCHECK(preempting_flag_);
channel_lock_.AssertAcquired();
+ DCHECK(preempting_flag_);
switch (preemption_state_) {
case IDLE:
UpdateStateIdle();
@@ -443,11 +486,21 @@ void GpuChannelMessageQueue::TransitionToWouldPreemptDescheduled() {
TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 0);
}
-GpuChannelMessageFilter::GpuChannelMessageFilter()
- : channel_(nullptr), peer_pid_(base::kNullProcessId) {}
+GpuChannelMessageFilter::GpuChannelMessageFilter(GpuChannel* gpu_channel)
+ : gpu_channel_(gpu_channel) {}
GpuChannelMessageFilter::~GpuChannelMessageFilter() {}
+scoped_refptr<GpuChannelMessageFilter> GpuChannelMessageFilter::Create(
+ GpuChannel* gpu_channel) {
+ return make_scoped_refptr(new GpuChannelMessageFilter(gpu_channel));
+}
+
+void GpuChannelMessageFilter::Disable() {
+ base::AutoLock lock(lock_);
+ enabled_ = false;
+}
+
void GpuChannelMessageFilter::OnFilterAdded(IPC::Channel* channel) {
DCHECK(!channel_);
channel_ = channel;
@@ -501,25 +554,32 @@ void GpuChannelMessageFilter::RemoveChannelFilter(
std::find(channel_filters_.begin(), channel_filters_.end(), filter));
}
-// This gets called from the main thread and assumes that all messages which
-// lead to creation of a new route are synchronous messages.
-// TODO(sunnyps): Create routes (and streams) on the IO thread so that we can
-// make the CreateCommandBuffer/VideoDecoder/VideoEncoder messages asynchronous.
void GpuChannelMessageFilter::AddRoute(
int32_t route_id,
- const scoped_refptr<GpuChannelMessageQueue>& queue) {
- base::AutoLock lock(routes_lock_);
- routes_.insert(std::make_pair(route_id, queue));
+ scoped_refptr<GpuChannelMessageQueue> stream) {
+ base::AutoLock lock(lock_);
+ routes_.insert(std::make_pair(route_id, stream));
}
-void GpuChannelMessageFilter::RemoveRoute(int32_t route_id) {
- base::AutoLock lock(routes_lock_);
- routes_.erase(route_id);
+scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageFilter::RemoveRoute(
+ int32_t route_id) {
+ base::AutoLock lock(lock_);
+ auto it = routes_.find(route_id);
+ if (it != routes_.end()) {
+ scoped_refptr<GpuChannelMessageQueue> stream(it->second);
+ routes_.erase(it);
+ return stream;
+ }
+ return nullptr;
}
bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) {
+ base::AutoLock lock(lock_);
DCHECK(channel_);
+ if (!enabled_)
+ return MessageErrorHandler(message, "Channel destroyed");
+
if (message.should_unblock() || message.is_reply())
return MessageErrorHandler(message, "Unexpected message type");
@@ -534,15 +594,19 @@ bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) {
return true;
}
- scoped_refptr<GpuChannelMessageQueue> message_queue =
- LookupStreamByRoute(message.routing_id());
-
- if (!message_queue)
- return MessageErrorHandler(message, "Could not find message queue");
+ if (message.routing_id() == MSG_ROUTING_CONTROL ||
+ message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID ||
+ message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) {
+ gpu_channel_->PostHandleOutOfOrderMessage(message);
+ return true;
+ }
- if (!message_queue->PushBackMessage(message))
- return MessageErrorHandler(message, "Channel destroyed");
+ scoped_refptr<GpuChannelMessageQueue> stream =
+ LookupRoute(message.routing_id());
+ if (!stream)
+ return MessageErrorHandler(message, "Could not find route");
+ stream->PushBackMessage(message);
return true;
}
@@ -550,13 +614,13 @@ bool GpuChannelMessageFilter::Send(IPC::Message* message) {
return channel_->Send(message);
}
-scoped_refptr<GpuChannelMessageQueue>
-GpuChannelMessageFilter::LookupStreamByRoute(int32_t route_id) {
- base::AutoLock lock(routes_lock_);
+scoped_refptr<GpuChannelMessageQueue> GpuChannelMessageFilter::LookupRoute(
+ int32_t route_id) {
+ scoped_refptr<GpuChannelMessageQueue> stream;
auto it = routes_.find(route_id);
if (it != routes_.end())
- return it->second;
- return nullptr;
+ stream = it->second;
+ return stream;
}
bool GpuChannelMessageFilter::MessageErrorHandler(const IPC::Message& message,
@@ -570,52 +634,51 @@ bool GpuChannelMessageFilter::MessageErrorHandler(const IPC::Message& message,
return true;
}
-GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
- SyncPointManager* sync_point_manager,
- GpuWatchdogThread* watchdog,
- gl::GLShareGroup* share_group,
- gles2::MailboxManager* mailbox,
- PreemptionFlag* preempting_flag,
- PreemptionFlag* preempted_flag,
- base::SingleThreadTaskRunner* task_runner,
- base::SingleThreadTaskRunner* io_task_runner,
- int32_t client_id,
- uint64_t client_tracing_id,
- bool allow_view_command_buffers,
- bool allow_real_time_streams)
+GpuChannel::GpuChannel(
+ GpuChannelManager* gpu_channel_manager,
+ SyncPointManager* sync_point_manager,
+ GpuWatchdogThread* watchdog,
+ GpuScheduler* scheduler,
+ scoped_refptr<gl::GLShareGroup> share_group,
+ scoped_refptr<gles2::MailboxManager> mailbox_manager,
+ scoped_refptr<PreemptionFlag> preempting_flag,
+ scoped_refptr<PreemptionFlag> preemption_flag,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
+ int32_t client_id,
+ uint64_t client_tracing_id,
+ bool allow_view_command_buffers,
+ bool allow_real_time_streams)
: gpu_channel_manager_(gpu_channel_manager),
sync_point_manager_(sync_point_manager),
+ scheduler_(scheduler),
unhandled_message_listener_(nullptr),
- preempting_flag_(preempting_flag),
- preempted_flag_(preempted_flag),
+ preempting_flag_(std::move(preempting_flag)),
+ preemption_flag_(std::move(preemption_flag)),
client_id_(client_id),
client_tracing_id_(client_tracing_id),
- task_runner_(task_runner),
- io_task_runner_(io_task_runner),
- share_group_(share_group),
- mailbox_manager_(mailbox),
+ task_runner_(std::move(task_runner)),
+ io_task_runner_(std::move(io_task_runner)),
+ share_group_(std::move(share_group)),
+ mailbox_manager_(std::move(mailbox_manager)),
watchdog_(watchdog),
allow_view_command_buffers_(allow_view_command_buffers),
- allow_real_time_streams_(allow_real_time_streams),
- weak_factory_(this) {
+ allow_real_time_streams_(allow_real_time_streams) {
DCHECK(gpu_channel_manager);
DCHECK(client_id);
-
- filter_ = new GpuChannelMessageFilter();
-
- scoped_refptr<GpuChannelMessageQueue> control_queue =
- CreateStream(GPU_STREAM_DEFAULT, GpuStreamPriority::HIGH);
- AddRouteToStream(MSG_ROUTING_CONTROL, GPU_STREAM_DEFAULT);
+ filter_ = GpuChannelMessageFilter::Create(this);
}
GpuChannel::~GpuChannel() {
// Clear stubs first because of dependencies.
stubs_.clear();
+ filter_->Disable();
+
for (auto& kv : streams_)
- kv.second->Disable();
+ kv.second->Destroy();
- if (preempting_flag_.get())
+ if (preempting_flag_)
preempting_flag_->Reset();
}
@@ -637,15 +700,21 @@ void GpuChannel::SetUnhandledMessageListener(IPC::Listener* listener) {
unhandled_message_listener_ = listener;
}
-base::WeakPtr<GpuChannel> GpuChannel::AsWeakPtr() {
- return weak_factory_.GetWeakPtr();
-}
-
base::ProcessId GpuChannel::GetClientPID() const {
DCHECK_NE(peer_pid_, base::kNullProcessId);
return peer_pid_;
}
+base::Callback<bool(void)> GpuChannel::GetPreemptionCallback() const {
+ if (scheduler_) {
+ return base::Bind(&GpuScheduler::ShouldYield, base::Unretained(scheduler_));
+ } else if (preemption_flag_) {
+ return base::Bind(&PreemptionFlag::IsSet,
+ base::RetainedRef(preemption_flag_));
+ }
+ return base::Callback<bool(void)>();
+}
+
uint32_t GpuChannel::GetProcessedOrderNum() const {
uint32_t processed_order_num = 0;
for (auto& kv : streams_) {
@@ -665,7 +734,8 @@ uint32_t GpuChannel::GetUnprocessedOrderNum() const {
}
bool GpuChannel::OnMessageReceived(const IPC::Message& msg) {
- // All messages should be pushed to channel_messages_ and handled separately.
+ // All messages should be pushed to channel_messages_ and handled
+ // separately.
NOTREACHED();
return false;
}
@@ -694,14 +764,36 @@ bool GpuChannel::Send(IPC::Message* message) {
return channel_->Send(message);
}
-void GpuChannel::OnStreamRescheduled(int32_t stream_id, bool scheduled) {
- scoped_refptr<GpuChannelMessageQueue> queue = LookupStream(stream_id);
- DCHECK(queue);
- queue->OnRescheduled(scheduled);
+void GpuChannel::ScheduleCommandBuffer(GpuCommandBufferStub* stub) {
+ scoped_refptr<GpuChannelMessageQueue> stream =
+ LookupStream(stub->stream_id());
+ DCHECK(stream);
+ stream->Schedule();
+}
+
+void GpuChannel::DescheduleCommandBuffer(GpuCommandBufferStub* stub) {
+ scoped_refptr<GpuChannelMessageQueue> stream =
+ LookupStream(stub->stream_id());
+ DCHECK(stream);
+ stream->Deschedule();
+}
+
+scoped_refptr<GpuChannelMessageQueue> GpuChannel::LookupStreamByCommandBufferId(
+ CommandBufferId command_buffer_id) {
+ int32_t channel_id = GpuCommandBufferStub::GetChannelID(command_buffer_id);
+ GpuChannel* channel = gpu_channel_manager_->LookupChannel(channel_id);
+
+ int32_t route_id = GpuCommandBufferStub::GetRouteID(command_buffer_id);
+ GpuCommandBufferStub* stub = channel->LookupCommandBuffer(route_id);
+
+ return channel->LookupStream(stub->stream_id());
}
GpuCommandBufferStub* GpuChannel::LookupCommandBuffer(int32_t route_id) {
- return stubs_.get(route_id);
+ auto it = stubs_.find(route_id);
+ if (it != stubs_.end())
+ return it->second.get();
+ return nullptr;
}
void GpuChannel::LoseAllContexts() {
@@ -717,7 +809,9 @@ bool GpuChannel::AddRoute(int32_t route_id,
int32_t stream_id,
IPC::Listener* listener) {
if (router_.AddRoute(route_id, listener)) {
- AddRouteToStream(route_id, stream_id);
+ scoped_refptr<GpuChannelMessageQueue> stream = LookupStream(stream_id);
+ filter_->AddRoute(route_id, stream);
+ stream->OnRouteAdded();
return true;
}
return false;
@@ -725,7 +819,12 @@ bool GpuChannel::AddRoute(int32_t route_id,
void GpuChannel::RemoveRoute(int32_t route_id) {
router_.RemoveRoute(route_id);
- RemoveRouteFromStream(route_id);
+ scoped_refptr<GpuChannelMessageQueue> stream = filter_->RemoveRoute(route_id);
+ stream->OnRouteRemoved();
+ if (stream->NumRoutes() == 0) {
+ stream->Destroy();
+ streams_.erase(stream->stream_id());
+ }
}
bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
@@ -750,51 +849,49 @@ scoped_refptr<SyncPointOrderData> GpuChannel::GetSyncPointOrderData(
return it->second->GetSyncPointOrderData();
}
-void GpuChannel::PostHandleMessage(
- const scoped_refptr<GpuChannelMessageQueue>& queue) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&GpuChannel::HandleMessage,
- weak_factory_.GetWeakPtr(), queue));
+void GpuChannel::PostHandleMessageOnStream(
+ scoped_refptr<GpuChannelMessageQueue> stream) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&GpuChannel::HandleMessageOnStream, AsWeakPtr(), stream));
}
-void GpuChannel::PostHandleOutOfOrderMessage(const IPC::Message& msg) {
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&GpuChannel::HandleOutOfOrderMessage,
- weak_factory_.GetWeakPtr(), msg));
-}
-
-void GpuChannel::HandleMessage(
- const scoped_refptr<GpuChannelMessageQueue>& message_queue) {
- const GpuChannelMessage* channel_msg =
- message_queue->BeginMessageProcessing();
- if (!channel_msg)
+void GpuChannel::HandleMessageOnStream(
+ scoped_refptr<GpuChannelMessageQueue> stream) {
+ const GpuChannelMessage* msg_wrapper = stream->BeginMessageProcessing();
+ if (!msg_wrapper)
return;
- const IPC::Message& msg = channel_msg->message;
- int32_t routing_id = msg.routing_id();
- GpuCommandBufferStub* stub = stubs_.get(routing_id);
-
+ const IPC::Message& msg = msg_wrapper->message;
+ GpuCommandBufferStub* stub = LookupCommandBuffer(msg.routing_id());
DCHECK(!stub || stub->IsScheduled());
-
DVLOG(1) << "received message @" << &msg << " on channel @" << this
<< " with type " << msg.type();
HandleMessageHelper(msg);
- // If we get descheduled or yield while processing a message.
- if ((stub && stub->HasUnprocessedCommands()) ||
- !message_queue->IsScheduled()) {
+ // If we get descheduled or preempted while processing a message.
+ if ((stub && stub->HasUnprocessedCommands()) || !stream->IsScheduled()) {
DCHECK((uint32_t)GpuCommandBufferMsg_AsyncFlush::ID == msg.type() ||
(uint32_t)GpuCommandBufferMsg_WaitSyncToken::ID == msg.type());
- message_queue->PauseMessageProcessing();
+ stream->PauseMessageProcessing();
} else {
- message_queue->FinishMessageProcessing();
+ stream->FinishMessageProcessing();
}
}
+void GpuChannel::PostHandleOutOfOrderMessage(const IPC::Message& msg) {
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&GpuChannel::HandleOutOfOrderMessage, AsWeakPtr(), msg));
+}
+
+void GpuChannel::HandleOutOfOrderMessage(const IPC::Message& msg) {
+ HandleMessageHelper(msg);
+}
+
void GpuChannel::HandleMessageHelper(const IPC::Message& msg) {
int32_t routing_id = msg.routing_id();
-
bool handled = false;
if (routing_id == MSG_ROUTING_CONTROL) {
handled = OnControlMessageReceived(msg);
@@ -813,67 +910,26 @@ void GpuChannel::HandleMessageHelper(const IPC::Message& msg) {
}
}
-void GpuChannel::HandleOutOfOrderMessage(const IPC::Message& msg) {
- HandleMessageHelper(msg);
-}
-
-void GpuChannel::HandleMessageForTesting(const IPC::Message& msg) {
- HandleMessageHelper(msg);
-}
-
scoped_refptr<GpuChannelMessageQueue> GpuChannel::CreateStream(
int32_t stream_id,
GpuStreamPriority stream_priority) {
- DCHECK(streams_.find(stream_id) == streams_.end());
- scoped_refptr<GpuChannelMessageQueue> queue = GpuChannelMessageQueue::Create(
- stream_id, stream_priority, this, io_task_runner_,
- (stream_id == GPU_STREAM_DEFAULT) ? preempting_flag_ : nullptr,
- preempted_flag_, sync_point_manager_);
- streams_.insert(std::make_pair(stream_id, queue));
- streams_to_num_routes_.insert(std::make_pair(stream_id, 0));
- return queue;
+ return GpuChannelMessageQueue::Create(
+ stream_id, stream_priority, this, task_runner_, io_task_runner_,
+ scheduler_, preempting_flag_, preemption_flag_, sync_point_manager_);
}
scoped_refptr<GpuChannelMessageQueue> GpuChannel::LookupStream(
int32_t stream_id) {
- auto stream_it = streams_.find(stream_id);
- if (stream_it != streams_.end())
- return stream_it->second;
+ auto it = streams_.find(stream_id);
+ if (it != streams_.end())
+ return it->second;
return nullptr;
}
-void GpuChannel::DestroyStreamIfNecessary(
- const scoped_refptr<GpuChannelMessageQueue>& queue) {
- int32_t stream_id = queue->stream_id();
- if (streams_to_num_routes_[stream_id] == 0) {
- queue->Disable();
- streams_to_num_routes_.erase(stream_id);
- streams_.erase(stream_id);
- }
-}
-
-void GpuChannel::AddRouteToStream(int32_t route_id, int32_t stream_id) {
- DCHECK(streams_.find(stream_id) != streams_.end());
- DCHECK(routes_to_streams_.find(route_id) == routes_to_streams_.end());
- streams_to_num_routes_[stream_id]++;
- routes_to_streams_.insert(std::make_pair(route_id, stream_id));
- filter_->AddRoute(route_id, streams_[stream_id]);
-}
-
-void GpuChannel::RemoveRouteFromStream(int32_t route_id) {
- DCHECK(routes_to_streams_.find(route_id) != routes_to_streams_.end());
- int32_t stream_id = routes_to_streams_[route_id];
- DCHECK(streams_.find(stream_id) != streams_.end());
- routes_to_streams_.erase(route_id);
- streams_to_num_routes_[stream_id]--;
- filter_->RemoveRoute(route_id);
- DestroyStreamIfNecessary(streams_[stream_id]);
-}
-
#if defined(OS_ANDROID)
const GpuCommandBufferStub* GpuChannel::GetOneStub() const {
for (const auto& kv : stubs_) {
- const GpuCommandBufferStub* stub = kv.second;
+ const GpuCommandBufferStub* stub = kv.second.get();
if (stub->decoder() && !stub->decoder()->WasContextLost())
return stub;
}
@@ -891,19 +947,18 @@ void GpuChannel::OnCreateCommandBuffer(
"offscreen", (init_params.surface_handle == kNullSurfaceHandle));
std::unique_ptr<base::SharedMemory> shared_state_shm(
new base::SharedMemory(shared_state_handle, false));
- std::unique_ptr<GpuCommandBufferStub> stub =
+ GpuCommandBufferStub* stub =
CreateCommandBuffer(init_params, route_id, std::move(shared_state_shm));
if (stub) {
*result = true;
*capabilities = stub->decoder()->GetCapabilities();
- stubs_.set(route_id, std::move(stub));
} else {
*result = false;
*capabilities = gpu::Capabilities();
}
}
-std::unique_ptr<GpuCommandBufferStub> GpuChannel::CreateCommandBuffer(
+GpuCommandBufferStub* GpuChannel::CreateCommandBuffer(
const GPUCreateCommandBufferConfig& init_params,
int32_t route_id,
std::unique_ptr<base::SharedMemory> shared_state_shm) {
@@ -915,11 +970,10 @@ std::unique_ptr<GpuCommandBufferStub> GpuChannel::CreateCommandBuffer(
}
int32_t share_group_id = init_params.share_group_id;
- GpuCommandBufferStub* share_group = stubs_.get(share_group_id);
+ GpuCommandBufferStub* share_group = LookupCommandBuffer(share_group_id);
if (!share_group && share_group_id != MSG_ROUTING_NONE) {
- DLOG(ERROR)
- << "GpuChannel::CreateCommandBuffer(): invalid share group id";
+ DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): invalid share group id";
return nullptr;
}
@@ -952,39 +1006,44 @@ std::unique_ptr<GpuCommandBufferStub> GpuChannel::CreateCommandBuffer(
return nullptr;
}
- scoped_refptr<GpuChannelMessageQueue> queue = LookupStream(stream_id);
- if (!queue)
- queue = CreateStream(stream_id, stream_priority);
+ scoped_refptr<GpuChannelMessageQueue> stream = LookupStream(stream_id);
+ if (!stream) {
+ stream = CreateStream(stream_id, stream_priority);
+ streams_.insert(std::make_pair(stream_id, stream));
+ }
std::unique_ptr<GpuCommandBufferStub> stub(GpuCommandBufferStub::Create(
this, share_group, init_params, route_id, std::move(shared_state_shm)));
- if (!stub) {
- DestroyStreamIfNecessary(queue);
- return nullptr;
- }
-
- if (!AddRoute(route_id, stream_id, stub.get())) {
- DestroyStreamIfNecessary(queue);
+ if (!router_.AddRoute(route_id, stub.get())) {
DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): failed to add route";
+ if (stream->NumRoutes() == 0) {
+ stream->Destroy();
+ streams_.erase(stream_id);
+ }
return nullptr;
}
- return stub;
+ filter_->AddRoute(route_id, stream);
+ stream->OnRouteAdded();
+
+ GpuCommandBufferStub* ret_stub = stub.get();
+ stubs_.insert(std::make_pair(route_id, std::move(stub)));
+
+ return ret_stub;
}
void GpuChannel::OnDestroyCommandBuffer(int32_t route_id) {
- TRACE_EVENT1("gpu", "GpuChannel::OnDestroyCommandBuffer",
- "route_id", route_id);
-
- std::unique_ptr<GpuCommandBufferStub> stub = stubs_.take_and_erase(route_id);
- // In case the renderer is currently blocked waiting for a sync reply from the
- // stub, we need to make sure to reschedule the correct stream here.
- if (stub && !stub->IsScheduled()) {
- // This stub won't get a chance to reschedule the stream so do that now.
- OnStreamRescheduled(stub->stream_id(), true);
+ TRACE_EVENT1("gpu", "GpuChannel::OnDestroyCommandBuffer", "route_id",
+ route_id);
+ auto it = stubs_.find(route_id);
+ if (it != stubs_.end()) {
+ std::unique_ptr<GpuCommandBufferStub> stub(std::move(it->second));
+ stubs_.erase(it);
+ // In case the renderer is currently blocked waiting for a sync reply from
+ // the stub, we need to make sure to reschedule the correct stream here.
+ ScheduleCommandBuffer(stub.get());
}
-
RemoveRoute(route_id);
}
@@ -1005,14 +1064,16 @@ void GpuChannel::CacheShader(const std::string& key,
void GpuChannel::AddFilter(IPC::MessageFilter* filter) {
io_task_runner_->PostTask(
- FROM_HERE, base::Bind(&GpuChannelMessageFilter::AddChannelFilter,
- filter_, make_scoped_refptr(filter)));
+ FROM_HERE,
+ base::Bind(&GpuChannelMessageFilter::AddChannelFilter,
+ base::RetainedRef(filter_), make_scoped_refptr(filter)));
}
void GpuChannel::RemoveFilter(IPC::MessageFilter* filter) {
io_task_runner_->PostTask(
- FROM_HERE, base::Bind(&GpuChannelMessageFilter::RemoveChannelFilter,
- filter_, make_scoped_refptr(filter)));
+ FROM_HERE,
+ base::Bind(&GpuChannelMessageFilter::RemoveChannelFilter,
+ base::RetainedRef(filter_), make_scoped_refptr(filter)));
}
uint64_t GpuChannel::GetMemoryUsage() {
« no previous file with comments | « gpu/ipc/service/gpu_channel.h ('k') | gpu/ipc/service/gpu_channel_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698