Home | History | Annotate | Download | only in android
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/renderer/media/android/stream_texture_factory_impl.h"
      6 
      7 #include "cc/output/context_provider.h"
      8 #include "content/common/gpu/client/gpu_channel_host.h"
      9 #include "content/common/gpu/gpu_messages.h"
     10 #include "content/renderer/gpu/stream_texture_host_android.h"
     11 #include "gpu/command_buffer/client/gles2_interface.h"
     12 #include "ui/gfx/size.h"
     13 
     14 namespace content {
     15 
     16 namespace {
     17 
     18 class StreamTextureProxyImpl : public StreamTextureProxy,
     19                                public StreamTextureHost::Listener {
     20  public:
     21   explicit StreamTextureProxyImpl(StreamTextureHost* host);
     22   virtual ~StreamTextureProxyImpl();
     23 
     24   // StreamTextureProxy implementation:
     25   virtual void BindToLoop(int32 stream_id,
     26                           cc::VideoFrameProvider::Client* client,
     27                           scoped_refptr<base::MessageLoopProxy> loop) OVERRIDE;
     28   virtual void Release() OVERRIDE;
     29 
     30   // StreamTextureHost::Listener implementation:
     31   virtual void OnFrameAvailable() OVERRIDE;
     32   virtual void OnMatrixChanged(const float matrix[16]) OVERRIDE;
     33 
     34  private:
     35   void BindOnThread(int32 stream_id);
     36 
     37   const scoped_ptr<StreamTextureHost> host_;
     38 
     39   base::Lock lock_;
     40   cc::VideoFrameProvider::Client* client_;
     41   scoped_refptr<base::MessageLoopProxy> loop_;
     42 
     43   DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl);
     44 };
     45 
     46 StreamTextureProxyImpl::StreamTextureProxyImpl(StreamTextureHost* host)
     47     : host_(host), client_(NULL) {}
     48 
     49 StreamTextureProxyImpl::~StreamTextureProxyImpl() {}
     50 
     51 void StreamTextureProxyImpl::Release() {
     52   {
     53     base::AutoLock lock(lock_);
     54     client_ = NULL;
     55   }
     56   // Assumes this is the last reference to this object. So no need to acquire
     57   // lock.
     58   if (!loop_.get() || loop_->BelongsToCurrentThread() ||
     59       !loop_->DeleteSoon(FROM_HERE, this)) {
     60     delete this;
     61   }
     62 }
     63 
     64 void StreamTextureProxyImpl::BindToLoop(
     65     int32 stream_id,
     66     cc::VideoFrameProvider::Client* client,
     67     scoped_refptr<base::MessageLoopProxy> loop) {
     68   DCHECK(loop);
     69 
     70   {
     71     base::AutoLock lock(lock_);
     72     DCHECK(!loop_ || (loop == loop_));
     73     loop_ = loop;
     74     client_ = client;
     75   }
     76 
     77   if (loop->BelongsToCurrentThread()) {
     78     BindOnThread(stream_id);
     79     return;
     80   }
     81   // Unretained is safe here only because the object is deleted on |loop_|
     82   // thread.
     83   loop->PostTask(FROM_HERE,
     84                  base::Bind(&StreamTextureProxyImpl::BindOnThread,
     85                             base::Unretained(this),
     86                             stream_id));
     87 }
     88 
     89 void StreamTextureProxyImpl::BindOnThread(int32 stream_id) {
     90   host_->BindToCurrentThread(stream_id, this);
     91 }
     92 
     93 void StreamTextureProxyImpl::OnFrameAvailable() {
     94   base::AutoLock lock(lock_);
     95   if (client_)
     96     client_->DidReceiveFrame();
     97 }
     98 
     99 void StreamTextureProxyImpl::OnMatrixChanged(const float matrix[16]) {
    100   base::AutoLock lock(lock_);
    101   if (client_)
    102     client_->DidUpdateMatrix(matrix);
    103 }
    104 
    105 }  // namespace
    106 
    107 // static
    108 scoped_refptr<StreamTextureFactoryImpl> StreamTextureFactoryImpl::Create(
    109     const scoped_refptr<cc::ContextProvider>& context_provider,
    110     GpuChannelHost* channel,
    111     int frame_id) {
    112   return new StreamTextureFactoryImpl(context_provider, channel, frame_id);
    113 }
    114 
    115 StreamTextureFactoryImpl::StreamTextureFactoryImpl(
    116     const scoped_refptr<cc::ContextProvider>& context_provider,
    117     GpuChannelHost* channel,
    118     int frame_id)
    119     : context_provider_(context_provider),
    120       channel_(channel),
    121       frame_id_(frame_id) {
    122   DCHECK(channel);
    123 }
    124 
    125 StreamTextureFactoryImpl::~StreamTextureFactoryImpl() {}
    126 
    127 StreamTextureProxy* StreamTextureFactoryImpl::CreateProxy() {
    128   DCHECK(channel_.get());
    129   StreamTextureHost* host = new StreamTextureHost(channel_.get());
    130   return new StreamTextureProxyImpl(host);
    131 }
    132 
    133 void StreamTextureFactoryImpl::EstablishPeer(int32 stream_id, int player_id) {
    134   DCHECK(channel_.get());
    135   channel_->Send(
    136       new GpuStreamTextureMsg_EstablishPeer(stream_id, frame_id_, player_id));
    137 }
    138 
    139 unsigned StreamTextureFactoryImpl::CreateStreamTexture(
    140     unsigned texture_target,
    141     unsigned* texture_id,
    142     gpu::Mailbox* texture_mailbox) {
    143   GLuint stream_id = 0;
    144   gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
    145   gl->GenTextures(1, texture_id);
    146 
    147   stream_id = gl->CreateStreamTextureCHROMIUM(*texture_id);
    148 
    149   gl->GenMailboxCHROMIUM(texture_mailbox->name);
    150   gl->BindTexture(texture_target, *texture_id);
    151   gl->ProduceTextureCHROMIUM(texture_target, texture_mailbox->name);
    152   return stream_id;
    153 }
    154 
    155 void StreamTextureFactoryImpl::SetStreamTextureSize(int32 stream_id,
    156                                                     const gfx::Size& size) {
    157   channel_->Send(new GpuStreamTextureMsg_SetSize(stream_id, size));
    158 }
    159 
    160 gpu::gles2::GLES2Interface* StreamTextureFactoryImpl::ContextGL() {
    161   return context_provider_->ContextGL();
    162 }
    163 
    164 void StreamTextureFactoryImpl::AddObserver(
    165     StreamTextureFactoryContextObserver* obs) {
    166 }
    167 
    168 void StreamTextureFactoryImpl::RemoveObserver(
    169     StreamTextureFactoryContextObserver* obs) {
    170 }
    171 
    172 }  // namespace content
    173