Index: content/renderer/gpu/frame_swap_message_queue.cc |
diff --git a/content/renderer/gpu/frame_swap_message_queue.cc b/content/renderer/gpu/frame_swap_message_queue.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c85a928f798312000594f012ebf394793166666c |
--- /dev/null |
+++ b/content/renderer/gpu/frame_swap_message_queue.cc |
@@ -0,0 +1,108 @@ |
+// Copyright 2014 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/renderer/gpu/frame_swap_message_queue.h" |
+ |
+#include <limits> |
+ |
+#include "base/logging.h" |
+#include "base/stl_util.h" |
+#include "ipc/ipc_message.h" |
+ |
+using std::vector; |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+class SendMessageScopeImpl : public FrameSwapMessageQueue::SendMessageScope { |
+ public: |
+ SendMessageScopeImpl(base::Lock* lock) : auto_lock_(*lock) {} |
+ virtual ~SendMessageScopeImpl() OVERRIDE {} |
+ |
+ private: |
+ base::AutoLock auto_lock_; |
+}; |
+ |
+} // namespace |
+ |
+FrameSwapMessageQueue::FrameSwapMessageQueue() |
+ : highest_swapped_source_frame_number_(std::numeric_limits< |
+ typeof(highest_swapped_source_frame_number_)>::min()) { |
+} |
+ |
+FrameSwapMessageQueue::~FrameSwapMessageQueue() { |
+ for (FrameQueueMap::iterator i = queued_messages_.begin(); |
+ i != queued_messages_.end(); |
+ i++) { |
+ STLDeleteElements(&i->second); |
+ } |
+} |
+ |
+bool FrameSwapMessageQueue::Empty() const { |
+ base::AutoLock lock(lock_); |
+ return queued_messages_.empty() && next_drain_messages_.empty(); |
+} |
+ |
+void FrameSwapMessageQueue::QueueMessage(scoped_ptr<IPC::Message> msg) { |
+ base::AutoLock lock(lock_); |
+ next_drain_messages_.push_back(msg.release()); |
+} |
+ |
+void FrameSwapMessageQueue::QueueMessageForFrame(int source_frame_number, |
+ scoped_ptr<IPC::Message> msg, |
+ bool* is_first) { |
+ base::AutoLock lock(lock_); |
+ DCHECK(source_frame_number >= highest_swapped_source_frame_number_); |
+ |
+ if (is_first) |
+ *is_first = (queued_messages_.count(source_frame_number) == 0); |
+ |
+ queued_messages_[source_frame_number].push_back(msg.release()); |
+} |
+ |
+void FrameSwapMessageQueue::AdvanceToFrame(int source_frame_number) { |
+ base::AutoLock lock(lock_); |
+ |
+ if (highest_swapped_source_frame_number_ > source_frame_number) |
+ return; |
+ highest_swapped_source_frame_number_ = source_frame_number; |
+ |
+ FrameQueueMap::iterator end = |
+ queued_messages_.upper_bound(source_frame_number); |
+ for (FrameQueueMap::iterator i = queued_messages_.begin(); i != end; i++) { |
+ DCHECK(i->first <= source_frame_number); |
+ next_drain_messages_.insert( |
+ next_drain_messages_.end(), i->second.begin(), i->second.end()); |
+ i->second.clear(); |
+ } |
+ queued_messages_.erase(queued_messages_.begin(), end); |
+} |
+ |
+void FrameSwapMessageQueue::DrainMessages( |
+ ScopedVector<IPC::Message>* messages) { |
+ lock_.AssertAcquired(); |
+ messages->swap(next_drain_messages_); |
+ next_drain_messages_.clear(); |
+} |
+ |
+scoped_ptr<FrameSwapMessageQueue::SendMessageScope> |
+FrameSwapMessageQueue::AcquireSendMessageScope() { |
+ return make_scoped_ptr(new SendMessageScopeImpl(&lock_)) |
+ .PassAs<SendMessageScope>(); |
+} |
+ |
+// static |
+void FrameSwapMessageQueue::TransferMessages(ScopedVector<IPC::Message>& source, |
+ vector<IPC::Message>* dest) { |
+ for (vector<IPC::Message*>::iterator i = source.begin(); i != source.end(); |
+ ++i) { |
+ IPC::Message* m(*i); |
+ dest->push_back(*m); |
+ delete m; |
+ } |
+ source.weak_clear(); |
+} |
+ |
+} // namespace content |