Commit 7fdbae21 authored by sunnyps's avatar sunnyps Committed by Commit bot

gpu: Remove gpu channel filter and queue from header.

Remove GpuChannelMessageQueue and GpuChannelMessageFilter from header.
Also remove the dependency between MediaGpuChannel and the filter.

R=piman
BUG=none
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel

Review-Url: https://codereview.chromium.org/2870333003
Cr-Commit-Position: refs/heads/master@{#472212}
parent 2d5a6e23
......@@ -72,31 +72,178 @@ CommandBufferId GenerateCommandBufferId(int channel_id, int32_t route_id) {
} // anonymous namespace
SyncChannelFilteredSender::SyncChannelFilteredSender(
IPC::ChannelHandle channel_handle,
IPC::Listener* listener,
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner,
base::WaitableEvent* shutdown_event)
: channel_(IPC::SyncChannel::Create(channel_handle,
IPC::Channel::MODE_SERVER,
listener,
ipc_task_runner,
false,
shutdown_event)) {}
SyncChannelFilteredSender::~SyncChannelFilteredSender() = default;
bool SyncChannelFilteredSender::Send(IPC::Message* msg) {
return channel_->Send(msg);
}
void SyncChannelFilteredSender::AddFilter(IPC::MessageFilter* filter) {
channel_->AddFilter(filter);
}
struct GpuChannelMessage {
IPC::Message message;
uint32_t order_number;
base::TimeTicks time_received;
GpuChannelMessage(const IPC::Message& msg,
uint32_t order_num,
base::TimeTicks ts)
: message(msg), order_number(order_num), time_received(ts) {}
private:
DISALLOW_COPY_AND_ASSIGN(GpuChannelMessage);
};
// This message queue counts and timestamps each message forwarded to the
// channel so that we can preempt other channels if a message takes too long to
// process. To guarantee fairness, we must wait a minimum amount of time before
// preempting and we limit the amount of time that we can preempt in one shot
// (see constants above).
class GpuChannelMessageQueue
: public base::RefCountedThreadSafe<GpuChannelMessageQueue> {
public:
GpuChannelMessageQueue(
GpuChannel* channel,
scoped_refptr<SyncPointOrderData> sync_point_order_data,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
scoped_refptr<PreemptionFlag> preempting_flag,
scoped_refptr<PreemptionFlag> preempted_flag);
void Destroy();
SequenceId sequence_id() const {
return sync_point_order_data_->sequence_id();
}
void SyncChannelFilteredSender::RemoveFilter(IPC::MessageFilter* filter) {
channel_->RemoveFilter(filter);
}
bool IsScheduled() const;
void SetScheduled(bool scheduled);
// Should be called before a message begins to be processed. Returns false if
// there are no messages to process.
const GpuChannelMessage* BeginMessageProcessing();
// Should be called if a message began processing but did not finish.
void PauseMessageProcessing();
// Should be called if a message is completely processed. Returns true if
// there are more messages to process.
void FinishMessageProcessing();
void PushBackMessage(const IPC::Message& message);
private:
enum PreemptionState {
// Either there's no other channel to preempt, there are no messages
// pending processing, or we just finished preempting and have to wait
// before preempting again.
IDLE,
// We are waiting kPreemptWaitTimeMs before checking if we should preempt.
WAITING,
// We can preempt whenever any IPC processing takes more than
// kPreemptWaitTimeMs.
CHECKING,
// We are currently preempting (i.e. no stub is descheduled).
PREEMPTING,
// We would like to preempt, but some stub is descheduled.
WOULD_PREEMPT_DESCHEDULED,
};
friend class base::RefCountedThreadSafe<GpuChannelMessageQueue>;
~GpuChannelMessageQueue();
void PostHandleMessageOnQueue();
void UpdatePreemptionState();
void UpdatePreemptionStateHelper();
void UpdateStateIdle();
void UpdateStateWaiting();
void UpdateStateChecking();
void UpdateStatePreempting();
void UpdateStateWouldPreemptDescheduled();
void TransitionToIdle();
void TransitionToWaiting();
void TransitionToChecking();
void TransitionToPreempting();
void TransitionToWouldPreemptDescheduled();
bool ShouldTransitionToIdle() const;
// These can be accessed from both IO and main threads and are protected by
// |channel_lock_|.
bool scheduled_ = true;
GpuChannel* channel_ = nullptr; // set to nullptr on Destroy
std::deque<std::unique_ptr<GpuChannelMessage>> channel_messages_;
bool handle_message_post_task_pending_ = false;
mutable base::Lock channel_lock_;
// The following are accessed on the IO thread only.
// No lock is necessary for preemption state because it's only accessed on the
// IO thread.
PreemptionState preemption_state_ = IDLE;
// Maximum amount of time that we can spend in PREEMPTING.
// It is reset when we transition to IDLE.
base::TimeDelta max_preemption_time_;
// This timer is used and runs tasks on the IO thread.
std::unique_ptr<base::OneShotTimer> timer_;
base::ThreadChecker io_thread_checker_;
// Keeps track of sync point related state such as message order numbers.
scoped_refptr<SyncPointOrderData> sync_point_order_data_;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
scoped_refptr<PreemptionFlag> preempting_flag_;
scoped_refptr<PreemptionFlag> preempted_flag_;
DISALLOW_COPY_AND_ASSIGN(GpuChannelMessageQueue);
};
// This filter does the following:
// - handles the Nop message used for verifying sync tokens on the IO thread
// - forwards messages to child message filters
// - posts control and out of order messages to the main thread
// - forwards other messages to the message queue or the scheduler
class GPU_EXPORT GpuChannelMessageFilter : public IPC::MessageFilter {
public:
GpuChannelMessageFilter(
GpuChannel* gpu_channel,
Scheduler* scheduler,
scoped_refptr<GpuChannelMessageQueue> message_queue,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
// Methods called on main thread.
void Destroy();
// Called when scheduler is enabled.
void AddRoute(int32_t route_id, SequenceId sequence_id);
void RemoveRoute(int32_t route_id);
// Methods called on IO thread.
// IPC::MessageFilter implementation.
void OnFilterAdded(IPC::Channel* channel) override;
void OnFilterRemoved() override;
void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
void OnChannelClosing() override;
bool OnMessageReceived(const IPC::Message& message) override;
void AddChannelFilter(scoped_refptr<IPC::MessageFilter> filter);
void RemoveChannelFilter(scoped_refptr<IPC::MessageFilter> filter);
private:
~GpuChannelMessageFilter() override;
bool MessageErrorHandler(const IPC::Message& message, const char* error_msg);
IPC::Channel* ipc_channel_ = nullptr;
base::ProcessId peer_pid_ = base::kNullProcessId;
std::vector<scoped_refptr<IPC::MessageFilter>> channel_filters_;
GpuChannel* gpu_channel_ = nullptr;
// Map of route id to scheduler sequence id.
base::flat_map<int32_t, SequenceId> route_sequences_;
mutable base::Lock gpu_channel_lock_;
Scheduler* scheduler_;
scoped_refptr<GpuChannelMessageQueue> message_queue_;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
DISALLOW_COPY_AND_ASSIGN(GpuChannelMessageFilter);
};
GpuChannelMessageQueue::GpuChannelMessageQueue(
GpuChannel* channel,
......@@ -515,7 +662,7 @@ bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) {
if (message.type() == GpuChannelMsg_Nop::ID) {
IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
Send(reply);
ipc_channel_->Send(reply);
return true;
}
......@@ -561,17 +708,13 @@ bool GpuChannelMessageFilter::OnMessageReceived(const IPC::Message& message) {
return true;
}
bool GpuChannelMessageFilter::Send(IPC::Message* message) {
return ipc_channel_->Send(message);
}
bool GpuChannelMessageFilter::MessageErrorHandler(const IPC::Message& message,
const char* error_msg) {
DLOG(ERROR) << error_msg;
if (message.is_sync()) {
IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message);
reply->set_reply_error();
Send(reply);
ipc_channel_->Send(reply);
}
return true;
}
......@@ -582,6 +725,32 @@ FilteredSender::FilteredSender() = default;
FilteredSender::~FilteredSender() = default;
SyncChannelFilteredSender::SyncChannelFilteredSender(
IPC::ChannelHandle channel_handle,
IPC::Listener* listener,
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner,
base::WaitableEvent* shutdown_event)
: channel_(IPC::SyncChannel::Create(channel_handle,
IPC::Channel::MODE_SERVER,
listener,
ipc_task_runner,
false,
shutdown_event)) {}
SyncChannelFilteredSender::~SyncChannelFilteredSender() = default;
bool SyncChannelFilteredSender::Send(IPC::Message* msg) {
return channel_->Send(msg);
}
void SyncChannelFilteredSender::AddFilter(IPC::MessageFilter* filter) {
channel_->AddFilter(filter);
}
void SyncChannelFilteredSender::RemoveFilter(IPC::MessageFilter* filter) {
channel_->RemoveFilter(filter);
}
GpuChannel::GpuChannel(
GpuChannelManager* gpu_channel_manager,
Scheduler* scheduler,
......@@ -798,6 +967,11 @@ void GpuChannel::HandleMessageOnQueue() {
}
}
void GpuChannel::HandleMessageForTesting(const IPC::Message& msg) {
// Message filter gets message first on IO thread.
filter_->OnMessageReceived(msg);
}
void GpuChannel::HandleMessageHelper(const IPC::Message& msg) {
int32_t routing_id = msg.routing_id();
......
......@@ -115,10 +115,6 @@ class GPU_EXPORT GpuChannel : public IPC::Listener, public FilteredSender {
GpuWatchdogThread* watchdog() const { return watchdog_; }
const scoped_refptr<GpuChannelMessageFilter>& filter() const {
return filter_;
}
const scoped_refptr<gles2::MailboxManager>& mailbox_manager() const {
return mailbox_manager_;
}
......@@ -193,6 +189,8 @@ class GPU_EXPORT GpuChannel : public IPC::Listener, public FilteredSender {
// are completed.
void HandleOutOfOrderMessage(const IPC::Message& msg);
void HandleMessageForTesting(const IPC::Message& msg);
#if defined(OS_ANDROID)
const GpuCommandBufferStub* GetOneStub() const;
#endif
......@@ -284,181 +282,6 @@ class GPU_EXPORT GpuChannel : public IPC::Listener, public FilteredSender {
DISALLOW_COPY_AND_ASSIGN(GpuChannel);
};
// This filter does the following:
// - handles the Nop message used for verifying sync tokens on the IO thread
// - forwards messages to child message filters
// - posts control and out of order messages to the main thread
// - forwards other messages to the message queue or the scheduler
class GPU_EXPORT GpuChannelMessageFilter : public IPC::MessageFilter {
public:
GpuChannelMessageFilter(
GpuChannel* gpu_channel,
Scheduler* scheduler,
scoped_refptr<GpuChannelMessageQueue> message_queue,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner);
// Methods called on main thread.
void Destroy();
// Called when scheduler is enabled.
void AddRoute(int32_t route_id, SequenceId sequence_id);
void RemoveRoute(int32_t route_id);
// Methods called on IO thread.
// IPC::MessageFilter implementation.
void OnFilterAdded(IPC::Channel* channel) override;
void OnFilterRemoved() override;
void OnChannelConnected(int32_t peer_pid) override;
void OnChannelError() override;
void OnChannelClosing() override;
bool OnMessageReceived(const IPC::Message& message) override;
void AddChannelFilter(scoped_refptr<IPC::MessageFilter> filter);
void RemoveChannelFilter(scoped_refptr<IPC::MessageFilter> filter);
bool Send(IPC::Message* message);
private:
~GpuChannelMessageFilter() override;
bool MessageErrorHandler(const IPC::Message& message, const char* error_msg);
IPC::Channel* ipc_channel_ = nullptr;
base::ProcessId peer_pid_ = base::kNullProcessId;
std::vector<scoped_refptr<IPC::MessageFilter>> channel_filters_;
GpuChannel* gpu_channel_ = nullptr;
// Map of route id to scheduler sequence id.
base::flat_map<int32_t, SequenceId> route_sequences_;
mutable base::Lock gpu_channel_lock_;
Scheduler* scheduler_;
scoped_refptr<GpuChannelMessageQueue> message_queue_;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
DISALLOW_COPY_AND_ASSIGN(GpuChannelMessageFilter);
};
struct GpuChannelMessage {
IPC::Message message;
uint32_t order_number;
base::TimeTicks time_received;
GpuChannelMessage(const IPC::Message& msg,
uint32_t order_num,
base::TimeTicks ts)
: message(msg), order_number(order_num), time_received(ts) {}
private:
DISALLOW_COPY_AND_ASSIGN(GpuChannelMessage);
};
// This message queue counts and timestamps each message forwarded to the
// channel so that we can preempt other channels if a message takes too long to
// process. To guarantee fairness, we must wait a minimum amount of time before
// preempting and we limit the amount of time that we can preempt in one shot
// (see constants above).
class GpuChannelMessageQueue
: public base::RefCountedThreadSafe<GpuChannelMessageQueue> {
public:
GpuChannelMessageQueue(
GpuChannel* channel,
scoped_refptr<SyncPointOrderData> sync_point_order_data,
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
scoped_refptr<PreemptionFlag> preempting_flag,
scoped_refptr<PreemptionFlag> preempted_flag);
void Destroy();
SequenceId sequence_id() const {
return sync_point_order_data_->sequence_id();
}
bool IsScheduled() const;
void SetScheduled(bool scheduled);
// Should be called before a message begins to be processed. Returns false if
// there are no messages to process.
const GpuChannelMessage* BeginMessageProcessing();
// Should be called if a message began processing but did not finish.
void PauseMessageProcessing();
// Should be called if a message is completely processed. Returns true if
// there are more messages to process.
void FinishMessageProcessing();
void PushBackMessage(const IPC::Message& message);
private:
enum PreemptionState {
// Either there's no other channel to preempt, there are no messages
// pending processing, or we just finished preempting and have to wait
// before preempting again.
IDLE,
// We are waiting kPreemptWaitTimeMs before checking if we should preempt.
WAITING,
// We can preempt whenever any IPC processing takes more than
// kPreemptWaitTimeMs.
CHECKING,
// We are currently preempting (i.e. no stub is descheduled).
PREEMPTING,
// We would like to preempt, but some stub is descheduled.
WOULD_PREEMPT_DESCHEDULED,
};
friend class base::RefCountedThreadSafe<GpuChannelMessageQueue>;
~GpuChannelMessageQueue();
void PostHandleMessageOnQueue();
void UpdatePreemptionState();
void UpdatePreemptionStateHelper();
void UpdateStateIdle();
void UpdateStateWaiting();
void UpdateStateChecking();
void UpdateStatePreempting();
void UpdateStateWouldPreemptDescheduled();
void TransitionToIdle();
void TransitionToWaiting();
void TransitionToChecking();
void TransitionToPreempting();
void TransitionToWouldPreemptDescheduled();
bool ShouldTransitionToIdle() const;
// These can be accessed from both IO and main threads and are protected by
// |channel_lock_|.
bool scheduled_ = true;
GpuChannel* channel_ = nullptr; // set to nullptr on Destroy
std::deque<std::unique_ptr<GpuChannelMessage>> channel_messages_;
bool handle_message_post_task_pending_ = false;
mutable base::Lock channel_lock_;
// The following are accessed on the IO thread only.
// No lock is necessary for preemption state because it's only accessed on the
// IO thread.
PreemptionState preemption_state_ = IDLE;
// Maximum amount of time that we can spend in PREEMPTING.
// It is reset when we transition to IDLE.
base::TimeDelta max_preemption_time_;
// This timer is used and runs tasks on the IO thread.
std::unique_ptr<base::OneShotTimer> timer_;
base::ThreadChecker io_thread_checker_;
// Keeps track of sync point related state such as message order numbers.
scoped_refptr<SyncPointOrderData> sync_point_order_data_;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
scoped_refptr<PreemptionFlag> preempting_flag_;
scoped_refptr<PreemptionFlag> preempted_flag_;
DISALLOW_COPY_AND_ASSIGN(GpuChannelMessageQueue);
};
} // namespace gpu
#endif // GPU_IPC_SERVICE_GPU_CHANNEL_H_
......@@ -127,7 +127,7 @@ void GpuChannelTestCommon::HandleMessage(GpuChannel* channel,
msg->set_unblock(false);
// Message filter gets message first on IO thread.
channel->filter()->OnMessageReceived(*msg);
channel->HandleMessageForTesting(*msg);
// Run the HandleMessage task posted to the main thread.
task_runner()->RunPendingTasks();
......
......@@ -14,25 +14,6 @@
namespace media {
namespace {
void SendCreateJpegDecoderResult(
std::unique_ptr<IPC::Message> reply_message,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
base::WeakPtr<gpu::GpuChannel> channel,
scoped_refptr<gpu::GpuChannelMessageFilter> filter,
bool result) {
GpuChannelMsg_CreateJpegDecoder::WriteReplyParams(reply_message.get(),
result);
if (io_task_runner->BelongsToCurrentThread()) {
filter->Send(reply_message.release());
} else if (channel) {
channel->Send(reply_message.release());
}
}
} // namespace
class MediaGpuChannelDispatchHelper {
public:
MediaGpuChannelDispatchHelper(MediaGpuChannel* channel, int32_t routing_id)
......@@ -65,7 +46,8 @@ class MediaGpuChannelFilter : public IPC::MessageFilter {
: channel_token_(channel_token) {}
void OnFilterAdded(IPC::Channel* channel) override { channel_ = channel; }
bool Send(IPC::Message* msg) { return channel_->Send(msg); }
void OnFilterRemoved() override { channel_ = nullptr; }
bool OnMessageReceived(const IPC::Message& msg) override {
bool handled = true;
......@@ -83,6 +65,12 @@ class MediaGpuChannelFilter : public IPC::MessageFilter {
Send(reply_message);
}
bool Send(IPC::Message* msg) {
if (channel_)
return channel_->Send(msg);
return false;
}
private:
~MediaGpuChannelFilter() override {}
......@@ -94,8 +82,10 @@ MediaGpuChannel::MediaGpuChannel(
gpu::GpuChannel* channel,
const base::UnguessableToken& channel_token,
const AndroidOverlayMojoFactoryCB& overlay_factory_cb)
: channel_(channel), overlay_factory_cb_(overlay_factory_cb) {
channel_->AddFilter(new MediaGpuChannelFilter(channel_token));
: channel_(channel),
filter_(new MediaGpuChannelFilter(channel_token)),
overlay_factory_cb_(overlay_factory_cb) {
channel_->AddFilter(filter_.get());
}
MediaGpuChannel::~MediaGpuChannel() {}
......@@ -121,6 +111,25 @@ bool MediaGpuChannel::OnMessageReceived(const IPC::Message& message) {
return handled;
}
namespace {
void SendCreateJpegDecoderResult(
std::unique_ptr<IPC::Message> reply_message,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
base::WeakPtr<IPC::Sender> channel,
scoped_refptr<MediaGpuChannelFilter> filter,
bool result) {
GpuChannelMsg_CreateJpegDecoder::WriteReplyParams(reply_message.get(),
result);
if (io_task_runner->BelongsToCurrentThread()) {
filter->Send(reply_message.release());
} else if (channel) {
channel->Send(reply_message.release());
}
}
} // namespace
void MediaGpuChannel::OnCreateJpegDecoder(int32_t route_id,
IPC::Message* reply_msg) {
std::unique_ptr<IPC::Message> msg(reply_msg);
......@@ -133,9 +142,9 @@ void MediaGpuChannel::OnCreateJpegDecoder(int32_t route_id,
new GpuJpegDecodeAccelerator(channel_, channel_->io_task_runner()));
}
jpeg_decoder_->AddClient(
route_id, base::Bind(&SendCreateJpegDecoderResult, base::Passed(&msg),
channel_->io_task_runner(), channel_->AsWeakPtr(),
channel_->filter()));
route_id,
base::Bind(&SendCreateJpegDecoderResult, base::Passed(&msg),
channel_->io_task_runner(), channel_->AsWeakPtr(), filter_));
}
void MediaGpuChannel::OnCreateVideoDecoder(
......
......@@ -25,6 +25,7 @@ class GpuChannel;
namespace media {
class MediaGpuChannelDispatchHelper;
class MediaGpuChannelFilter;
class MediaGpuChannel : public IPC::Listener, public IPC::Sender {
public:
......@@ -53,9 +54,10 @@ class MediaGpuChannel : public IPC::Listener, public IPC::Sender {
IPC::Message* reply_message);
gpu::GpuChannel* const channel_;
base::UnguessableToken channel_token_;
scoped_refptr<MediaGpuChannelFilter> filter_;
std::unique_ptr<GpuJpegDecodeAccelerator> jpeg_decoder_;
AndroidOverlayMojoFactoryCB overlay_factory_cb_;
DISALLOW_COPY_AND_ASSIGN(MediaGpuChannel);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment