Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / android / stream_texture_factory_impl.cc
index da9a70f..4e62088 100644 (file)
@@ -22,8 +22,9 @@ class StreamTextureProxyImpl : public StreamTextureProxy,
   virtual ~StreamTextureProxyImpl();
 
   // StreamTextureProxy implementation:
-  virtual void BindToCurrentThread(int32 stream_id) OVERRIDE;
-  virtual void SetClient(cc::VideoFrameProvider::Client* client) OVERRIDE;
+  virtual void BindToLoop(int32 stream_id,
+                          cc::VideoFrameProvider::Client* client,
+                          scoped_refptr<base::MessageLoopProxy> loop) OVERRIDE;
   virtual void Release() OVERRIDE;
 
   // StreamTextureHost::Listener implementation:
@@ -31,11 +32,14 @@ class StreamTextureProxyImpl : public StreamTextureProxy,
   virtual void OnMatrixChanged(const float matrix[16]) OVERRIDE;
 
  private:
-  scoped_ptr<StreamTextureHost> host_;
-  scoped_refptr<base::MessageLoopProxy> loop_;
+  void BindOnThread(int32 stream_id);
+
+  const scoped_ptr<StreamTextureHost> host_;
 
-  base::Lock client_lock_;
+  // Protects access to |client_| and |loop_|.
+  base::Lock lock_;
   cc::VideoFrameProvider::Client* client_;
+  scoped_refptr<base::MessageLoopProxy> loop_;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl);
 };
@@ -46,31 +50,58 @@ StreamTextureProxyImpl::StreamTextureProxyImpl(StreamTextureHost* host)
 StreamTextureProxyImpl::~StreamTextureProxyImpl() {}
 
 void StreamTextureProxyImpl::Release() {
-  SetClient(NULL);
-  if (loop_.get() && loop_.get() != base::MessageLoopProxy::current())
-    loop_->DeleteSoon(FROM_HERE, this);
-  else
+  {
+    // Cannot call into |client_| anymore (from any thread) after returning
+    // from here.
+    base::AutoLock lock(lock_);
+    client_ = NULL;
+  }
+  // Release is analogous to the destructor, so there should be no more external
+  // calls to this object in Release. Therefore there is no need to acquire the
+  // lock to access |loop_|.
+  if (!loop_.get() || loop_->BelongsToCurrentThread() ||
+      !loop_->DeleteSoon(FROM_HERE, this)) {
     delete this;
+  }
 }
 
-void StreamTextureProxyImpl::SetClient(cc::VideoFrameProvider::Client* client) {
-  base::AutoLock lock(client_lock_);
-  client_ = client;
+void StreamTextureProxyImpl::BindToLoop(
+    int32 stream_id,
+    cc::VideoFrameProvider::Client* client,
+    scoped_refptr<base::MessageLoopProxy> loop) {
+  DCHECK(loop);
+
+  {
+    base::AutoLock lock(lock_);
+    DCHECK(!loop_ || (loop == loop_));
+    loop_ = loop;
+    client_ = client;
+  }
+
+  if (loop->BelongsToCurrentThread()) {
+    BindOnThread(stream_id);
+    return;
+  }
+  // Unretained is safe here only because the object is deleted on |loop_|
+  // thread.
+  loop->PostTask(FROM_HERE,
+                 base::Bind(&StreamTextureProxyImpl::BindOnThread,
+                            base::Unretained(this),
+                            stream_id));
 }
 
-void StreamTextureProxyImpl::BindToCurrentThread(int stream_id) {
-  loop_ = base::MessageLoopProxy::current();
+void StreamTextureProxyImpl::BindOnThread(int32 stream_id) {
   host_->BindToCurrentThread(stream_id, this);
 }
 
 void StreamTextureProxyImpl::OnFrameAvailable() {
-  base::AutoLock lock(client_lock_);
+  base::AutoLock lock(lock_);
   if (client_)
     client_->DidReceiveFrame();
 }
 
 void StreamTextureProxyImpl::OnMatrixChanged(const float matrix[16]) {
-  base::AutoLock lock(client_lock_);
+  base::AutoLock lock(lock_);
   if (client_)
     client_->DidUpdateMatrix(matrix);
 }
@@ -134,4 +165,12 @@ gpu::gles2::GLES2Interface* StreamTextureFactoryImpl::ContextGL() {
   return context_provider_->ContextGL();
 }
 
+void StreamTextureFactoryImpl::AddObserver(
+    StreamTextureFactoryContextObserver* obs) {
+}
+
+void StreamTextureFactoryImpl::RemoveObserver(
+    StreamTextureFactoryContextObserver* obs) {
+}
+
 }  // namespace content