• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
StreamTextureProxyImpl(StreamTextureHost * host)46 StreamTextureProxyImpl::StreamTextureProxyImpl(StreamTextureHost* host)
47     : host_(host), client_(NULL) {}
48 
~StreamTextureProxyImpl()49 StreamTextureProxyImpl::~StreamTextureProxyImpl() {}
50 
Release()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 
BindToLoop(int32 stream_id,cc::VideoFrameProvider::Client * client,scoped_refptr<base::MessageLoopProxy> loop)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 
BindOnThread(int32 stream_id)89 void StreamTextureProxyImpl::BindOnThread(int32 stream_id) {
90   host_->BindToCurrentThread(stream_id, this);
91 }
92 
OnFrameAvailable()93 void StreamTextureProxyImpl::OnFrameAvailable() {
94   base::AutoLock lock(lock_);
95   if (client_)
96     client_->DidReceiveFrame();
97 }
98 
OnMatrixChanged(const float matrix[16])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
Create(const scoped_refptr<cc::ContextProvider> & context_provider,GpuChannelHost * channel,int frame_id)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 
StreamTextureFactoryImpl(const scoped_refptr<cc::ContextProvider> & context_provider,GpuChannelHost * channel,int frame_id)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 
~StreamTextureFactoryImpl()125 StreamTextureFactoryImpl::~StreamTextureFactoryImpl() {}
126 
CreateProxy()127 StreamTextureProxy* StreamTextureFactoryImpl::CreateProxy() {
128   DCHECK(channel_.get());
129   StreamTextureHost* host = new StreamTextureHost(channel_.get());
130   return new StreamTextureProxyImpl(host);
131 }
132 
EstablishPeer(int32 stream_id,int player_id)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 
CreateStreamTexture(unsigned texture_target,unsigned * texture_id,gpu::Mailbox * texture_mailbox)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 
SetStreamTextureSize(int32 stream_id,const gfx::Size & size)155 void StreamTextureFactoryImpl::SetStreamTextureSize(int32 stream_id,
156                                                     const gfx::Size& size) {
157   channel_->Send(new GpuStreamTextureMsg_SetSize(stream_id, size));
158 }
159 
ContextGL()160 gpu::gles2::GLES2Interface* StreamTextureFactoryImpl::ContextGL() {
161   return context_provider_->ContextGL();
162 }
163 
AddObserver(StreamTextureFactoryContextObserver * obs)164 void StreamTextureFactoryImpl::AddObserver(
165     StreamTextureFactoryContextObserver* obs) {
166 }
167 
RemoveObserver(StreamTextureFactoryContextObserver * obs)168 void StreamTextureFactoryImpl::RemoveObserver(
169     StreamTextureFactoryContextObserver* obs) {
170 }
171 
172 }  // namespace content
173