summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-24 00:44:21 +0000
committerwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-24 00:44:21 +0000
commit7920b9e040369926cf506bc27b70637320e4a2d6 (patch)
tree266f4e4518394007e3b695c5807412310c6fdf5d /remoting
parent2a48ad6626f754cd869515c0ead4b8a0e63eb05d (diff)
downloadchromium_src-7920b9e040369926cf506bc27b70637320e4a2d6.zip
chromium_src-7920b9e040369926cf506bc27b70637320e4a2d6.tar.gz
chromium_src-7920b9e040369926cf506bc27b70637320e4a2d6.tar.bz2
Re-instate part of PepperViewProxy as FrameConsumerProxy.
CL 8985007 removed PepperViewProxy, which is accessed both for UI and network activity from the Pepper thread. Except when it's accessed from the decoder thread - oops. This CL adds FrameConsumerProxy, which performs the necessary magic for the decode pipeline to access the PepperView's FrameConsumer interface safely. BUG=108490,93552 Review URL: http://codereview.chromium.org/9022024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@115745 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/client/frame_consumer_proxy.cc69
-rw-r--r--remoting/client/frame_consumer_proxy.h56
-rw-r--r--remoting/client/plugin/chromoting_instance.cc12
-rw-r--r--remoting/client/plugin/chromoting_instance.h2
-rw-r--r--remoting/remoting.gyp2
5 files changed, 140 insertions, 1 deletions
diff --git a/remoting/client/frame_consumer_proxy.cc b/remoting/client/frame_consumer_proxy.cc
new file mode 100644
index 0000000..3f7890a
--- /dev/null
+++ b/remoting/client/frame_consumer_proxy.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2011 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 "remoting/client/frame_consumer_proxy.h"
+
+#include "base/bind.h"
+#include "base/message_loop.h"
+
+namespace remoting {
+
+FrameConsumerProxy::FrameConsumerProxy(
+ FrameConsumer* frame_consumer,
+ base::MessageLoopProxy* frame_consumer_message_loop)
+ : frame_consumer_(frame_consumer),
+ frame_consumer_message_loop_(frame_consumer_message_loop) {
+}
+
+FrameConsumerProxy::~FrameConsumerProxy() {
+}
+
+void FrameConsumerProxy::AllocateFrame(
+ media::VideoFrame::Format format,
+ const SkISize& size,
+ scoped_refptr<media::VideoFrame>* frame_out,
+ const base::Closure& done) {
+ if (!frame_consumer_message_loop_->BelongsToCurrentThread()) {
+ frame_consumer_message_loop_->PostTask(FROM_HERE, base::Bind(
+ &FrameConsumerProxy::AllocateFrame, this, format, size, frame_out,
+ done));
+ return;
+ }
+
+ if (frame_consumer_) {
+ frame_consumer_->AllocateFrame(format, size, frame_out, done);
+ }
+}
+
+void FrameConsumerProxy::ReleaseFrame(media::VideoFrame* frame) {
+ if (!frame_consumer_message_loop_->BelongsToCurrentThread()) {
+ frame_consumer_message_loop_->PostTask(FROM_HERE, base::Bind(
+ &FrameConsumerProxy::ReleaseFrame, this, make_scoped_refptr(frame)));
+ return;
+ }
+
+ if (frame_consumer_)
+ frame_consumer_->ReleaseFrame(frame);
+}
+
+void FrameConsumerProxy::OnPartialFrameOutput(media::VideoFrame* frame,
+ RectVector* rects,
+ const base::Closure& done) {
+ if (!frame_consumer_message_loop_->BelongsToCurrentThread()) {
+ frame_consumer_message_loop_->PostTask(FROM_HERE, base::Bind(
+ &FrameConsumerProxy::OnPartialFrameOutput, this,
+ make_scoped_refptr(frame), rects, done));
+ return;
+ }
+
+ if (frame_consumer_)
+ frame_consumer_->OnPartialFrameOutput(frame, rects, done);
+}
+
+void FrameConsumerProxy::Detach() {
+ DCHECK(frame_consumer_message_loop_->BelongsToCurrentThread());
+ frame_consumer_ = NULL;
+}
+
+} // namespace remoting
diff --git a/remoting/client/frame_consumer_proxy.h b/remoting/client/frame_consumer_proxy.h
new file mode 100644
index 0000000..d3a88cc
--- /dev/null
+++ b/remoting/client/frame_consumer_proxy.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2011 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.
+
+// FrameConsumerProxy is used to allow a FrameConsumer on the UI thread to be
+// invoked by a Decoder on the decoder thread. The Detach() method is used by
+// the proxy's owner before tearing down the FrameConsumer, to prevent any
+// further invokations reaching it.
+
+#ifndef REMOTING_CLIENT_FRAME_CONSUMER_PROXY_H_
+#define REMOTING_CLIENT_FRAME_CONSUMER_PROXY_H_
+
+#include "base/memory/ref_counted.h"
+#include "remoting/client/frame_consumer.h"
+
+namespace base {
+class MessageLoopProxy;
+} // namespace base
+
+namespace remoting {
+
+class FrameConsumerProxy
+ : public base::RefCountedThreadSafe<FrameConsumerProxy>,
+ public FrameConsumer {
+ public:
+ // Constructs a proxy for |frame_consumer| which will trampoline invocations
+ // to |frame_consumer_message_loop|.
+ FrameConsumerProxy(FrameConsumer* frame_consumer,
+ base::MessageLoopProxy* frame_consumer_message_loop);
+ virtual ~FrameConsumerProxy();
+
+ // FrameConsumer implementation.
+ virtual void AllocateFrame(media::VideoFrame::Format format,
+ const SkISize& size,
+ scoped_refptr<media::VideoFrame>* frame_out,
+ const base::Closure& done) OVERRIDE;
+ virtual void ReleaseFrame(media::VideoFrame* frame) OVERRIDE;
+ virtual void OnPartialFrameOutput(media::VideoFrame* frame,
+ RectVector* rects,
+ const base::Closure& done) OVERRIDE;
+
+ // Detaches from |frame_consumer_|, ensuring no further calls reach it.
+ // This must only be called from |frame_consumer_message_loop_|.
+ void Detach();
+
+ private:
+ FrameConsumer* frame_consumer_;
+
+ scoped_refptr<base::MessageLoopProxy> frame_consumer_message_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameConsumerProxy);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_CLIENT_FRAME_CONSUMER_PROXY_H_
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index d3f7b62..3435185 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -24,6 +24,7 @@
#include "remoting/base/util.h"
#include "remoting/client/client_config.h"
#include "remoting/client/chromoting_client.h"
+#include "remoting/client/frame_consumer_proxy.h"
#include "remoting/client/mouse_input_filter.h"
#include "remoting/client/plugin/chromoting_scriptable_object.h"
#include "remoting/client/plugin/pepper_input_handler.h"
@@ -86,6 +87,12 @@ ChromotingInstance::~ChromotingInstance() {
// Stopping the context shuts down all chromoting threads.
context_.Stop();
+ // Detach the |consumer_proxy_|, so that any queued tasks don't touch |view_|
+ // after we've deleted it.
+ if (consumer_proxy_.get()) {
+ consumer_proxy_->Detach();
+ }
+
// Delete |thread_proxy_| before we detach |plugin_message_loop_|,
// otherwise ScopedThreadProxy may DCHECK when being destroyed.
thread_proxy_.reset();
@@ -112,9 +119,12 @@ bool ChromotingInstance::Init(uint32_t argc,
context_.Start();
// Create the chromoting objects that don't depend on the network connection.
+ // Because we decode on a separate thread we need a FrameConsumerProxy to
+ // bounce calls from the RectangleUpdateDecoder back to the plugin thread.
view_.reset(new PepperView(this, &context_));
+ consumer_proxy_ = new FrameConsumerProxy(view_.get(), plugin_message_loop_);
rectangle_decoder_ = new RectangleUpdateDecoder(
- context_.decode_message_loop(), view_.get());
+ context_.decode_message_loop(), consumer_proxy_.get());
// Default to a medium grey.
view_->SetSolidFill(0xFFCDCDCD);
diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h
index 2b11b5a..583e798 100644
--- a/remoting/client/plugin/chromoting_instance.h
+++ b/remoting/client/plugin/chromoting_instance.h
@@ -38,6 +38,7 @@ class KeyEventTracker;
class ChromotingClient;
class ChromotingStats;
class ClientContext;
+class FrameConsumerProxy;
class MouseInputFilter;
class PepperInputHandler;
class PepperView;
@@ -119,6 +120,7 @@ class ChromotingInstance : public pp::InstancePrivate {
// True if scale to fit is enabled.
bool scale_to_fit_;
+ scoped_refptr<FrameConsumerProxy> consumer_proxy_;
scoped_refptr<RectangleUpdateDecoder> rectangle_decoder_;
scoped_ptr<MouseInputFilter> mouse_input_filter_;
scoped_ptr<protocol::KeyEventTracker> key_event_tracker_;
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index eadc602..2735e64 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -636,6 +636,8 @@
'client/client_context.cc',
'client/client_context.h',
'client/frame_consumer.h',
+ 'client/frame_consumer_proxy.cc',
+ 'client/frame_consumer_proxy.h',
'client/mouse_input_filter.cc',
'client/mouse_input_filter.h',
'client/rectangle_update_decoder.cc',