Bug 1076820 - Redraw on resize performance for content is pretty bad with e10s r=billm

Modern OSs adjust process scheduling based on CPU-boundedness and Interface-boundedness.  A process performing a lot of UI tasks requires lower-latency than a CPU-bound process.  For this reason, at least on Windows (but probably also Linux and Mac), in e10s, resize events are sent at a much higher rate than non-e10s, where the main process has to do the work to respond to them.  This was supposed to be handled by the 'compress' option in IPDL but its duplicate-event test was very imprecise - it only tested the *oldest* message in the queue.  This patch searches the messagequeue/deque to remove *any* duplicate.  deque::erase is linear but this is a very uncommon case - currently only two compressed IPDL messages exist in the entire code base.  Also, these queues are small.
This commit is contained in:
David Parks 2014-11-07 14:21:08 -08:00
Родитель 322d5a421c
Коммит 4741aa886c
2 изменённых файлов: 29 добавлений и 11 удалений

Просмотреть файл

@ -469,9 +469,7 @@ child:
RealKeyEvent(WidgetKeyboardEvent event, MaybeNativeKeyBinding keyBinding);
MouseWheelEvent(WidgetWheelEvent event);
RealTouchEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
// We use a separate message for touchmove events only to apply
// compression to them.
RealTouchMoveEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid, uint64_t aInputBlockId) compress;
RealTouchMoveEvent(WidgetTouchEvent aEvent, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
/**
* @see nsIDOMWindowUtils sendKeyEvent.

Просмотреть файл

@ -583,6 +583,19 @@ MessageChannel::ShouldDeferMessage(const Message& aMsg)
return mSide == ParentSide && aMsg.transaction_id() != mCurrentTransaction;
}
// Predicate that is true for messages that should be consolidated if 'compress' is set.
class MatchingKinds {
typedef IPC::Message Message;
Message::msgid_t mType;
int32_t mRoutingId;
public:
MatchingKinds(Message::msgid_t aType, int32_t aRoutingId) :
mType(aType), mRoutingId(aRoutingId) {}
bool operator()(const Message &msg) {
return msg.type() == mType && msg.routing_id() == mRoutingId;
}
};
void
MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
{
@ -604,15 +617,22 @@ MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
// Prioritized messages cannot be compressed.
MOZ_ASSERT(!aMsg.compress() || aMsg.priority() == IPC::Message::PRIORITY_NORMAL);
bool compress = (aMsg.compress() && !mPending.empty() &&
mPending.back().type() == aMsg.type() &&
mPending.back().routing_id() == aMsg.routing_id());
bool compress = (aMsg.compress() && !mPending.empty());
if (compress) {
// This message type has compression enabled, and the back of the
// queue was the same message type and routed to the same destination.
// Replace it with the newer message.
MOZ_ASSERT(mPending.back().compress());
mPending.pop_back();
// Check the message queue for another message with this type/destination.
auto it = std::find_if(mPending.rbegin(), mPending.rend(),
MatchingKinds(aMsg.type(), aMsg.routing_id()));
if (it != mPending.rend()) {
// This message type has compression enabled, and the queue holds
// a message with the same message type and routed to the same destination.
// Erase it. Note that, since we always compress these redundancies, There Can
// Be Only One.
MOZ_ASSERT((*it).compress());
mPending.erase((++it).base());
} else {
// No other messages with the same type/destination exist.
compress = false;
}
}
bool shouldWakeUp = AwaitingInterruptReply() ||