Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / android / stream_texture_factory_impl.cc
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   // Protects access to |client_| and |loop_|.
40   base::Lock lock_;
41   cc::VideoFrameProvider::Client* client_;
42   scoped_refptr<base::MessageLoopProxy> loop_;
43
44   DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl);
45 };
46
47 StreamTextureProxyImpl::StreamTextureProxyImpl(StreamTextureHost* host)
48     : host_(host), client_(NULL) {}
49
50 StreamTextureProxyImpl::~StreamTextureProxyImpl() {}
51
52 void StreamTextureProxyImpl::Release() {
53   {
54     // Cannot call into |client_| anymore (from any thread) after returning
55     // from here.
56     base::AutoLock lock(lock_);
57     client_ = NULL;
58   }
59   // Release is analogous to the destructor, so there should be no more external
60   // calls to this object in Release. Therefore there is no need to acquire the
61   // lock to access |loop_|.
62   if (!loop_.get() || loop_->BelongsToCurrentThread() ||
63       !loop_->DeleteSoon(FROM_HERE, this)) {
64     delete this;
65   }
66 }
67
68 void StreamTextureProxyImpl::BindToLoop(
69     int32 stream_id,
70     cc::VideoFrameProvider::Client* client,
71     scoped_refptr<base::MessageLoopProxy> loop) {
72   DCHECK(loop.get());
73
74   {
75     base::AutoLock lock(lock_);
76     DCHECK(!loop_.get() || (loop.get() == loop_.get()));
77     loop_ = loop;
78     client_ = client;
79   }
80
81   if (loop->BelongsToCurrentThread()) {
82     BindOnThread(stream_id);
83     return;
84   }
85   // Unretained is safe here only because the object is deleted on |loop_|
86   // thread.
87   loop->PostTask(FROM_HERE,
88                  base::Bind(&StreamTextureProxyImpl::BindOnThread,
89                             base::Unretained(this),
90                             stream_id));
91 }
92
93 void StreamTextureProxyImpl::BindOnThread(int32 stream_id) {
94   host_->BindToCurrentThread(stream_id, this);
95 }
96
97 void StreamTextureProxyImpl::OnFrameAvailable() {
98   base::AutoLock lock(lock_);
99   if (client_)
100     client_->DidReceiveFrame();
101 }
102
103 void StreamTextureProxyImpl::OnMatrixChanged(const float matrix[16]) {
104   base::AutoLock lock(lock_);
105   if (client_)
106     client_->DidUpdateMatrix(matrix);
107 }
108
109 }  // namespace
110
111 // static
112 scoped_refptr<StreamTextureFactoryImpl> StreamTextureFactoryImpl::Create(
113     const scoped_refptr<cc::ContextProvider>& context_provider,
114     GpuChannelHost* channel,
115     int frame_id) {
116   return new StreamTextureFactoryImpl(context_provider, channel, frame_id);
117 }
118
119 StreamTextureFactoryImpl::StreamTextureFactoryImpl(
120     const scoped_refptr<cc::ContextProvider>& context_provider,
121     GpuChannelHost* channel,
122     int frame_id)
123     : context_provider_(context_provider),
124       channel_(channel),
125       frame_id_(frame_id) {
126   DCHECK(channel);
127 }
128
129 StreamTextureFactoryImpl::~StreamTextureFactoryImpl() {}
130
131 StreamTextureProxy* StreamTextureFactoryImpl::CreateProxy() {
132   DCHECK(channel_.get());
133   StreamTextureHost* host = new StreamTextureHost(channel_.get());
134   return new StreamTextureProxyImpl(host);
135 }
136
137 void StreamTextureFactoryImpl::EstablishPeer(int32 stream_id, int player_id) {
138   DCHECK(channel_.get());
139   channel_->Send(
140       new GpuStreamTextureMsg_EstablishPeer(stream_id, frame_id_, player_id));
141 }
142
143 unsigned StreamTextureFactoryImpl::CreateStreamTexture(
144     unsigned texture_target,
145     unsigned* texture_id,
146     gpu::Mailbox* texture_mailbox) {
147   GLuint stream_id = 0;
148   gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
149   gl->GenTextures(1, texture_id);
150
151   stream_id = gl->CreateStreamTextureCHROMIUM(*texture_id);
152
153   gl->GenMailboxCHROMIUM(texture_mailbox->name);
154   gl->ProduceTextureDirectCHROMIUM(
155       *texture_id, texture_target, texture_mailbox->name);
156   return stream_id;
157 }
158
159 void StreamTextureFactoryImpl::SetStreamTextureSize(int32 stream_id,
160                                                     const gfx::Size& size) {
161   channel_->Send(new GpuStreamTextureMsg_SetSize(stream_id, size));
162 }
163
164 gpu::gles2::GLES2Interface* StreamTextureFactoryImpl::ContextGL() {
165   return context_provider_->ContextGL();
166 }
167
168 void StreamTextureFactoryImpl::AddObserver(
169     StreamTextureFactoryContextObserver* obs) {
170 }
171
172 void StreamTextureFactoryImpl::RemoveObserver(
173     StreamTextureFactoryContextObserver* obs) {
174 }
175
176 }  // namespace content