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.
5 #include "content/renderer/media/android/stream_texture_factory_impl.h"
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/geometry/size.h"
18 class StreamTextureProxyImpl
: public StreamTextureProxy
,
19 public StreamTextureHost::Listener
{
21 explicit StreamTextureProxyImpl(StreamTextureHost
* host
);
22 ~StreamTextureProxyImpl() override
;
24 // StreamTextureProxy implementation:
25 void BindToLoop(int32 stream_id
,
26 cc::VideoFrameProvider::Client
* client
,
27 scoped_refptr
<base::SingleThreadTaskRunner
> loop
) override
;
28 void Release() override
;
30 // StreamTextureHost::Listener implementation:
31 void OnFrameAvailable() override
;
32 void OnMatrixChanged(const float matrix
[16]) override
;
35 void BindOnThread(int32 stream_id
);
37 const scoped_ptr
<StreamTextureHost
> host_
;
39 // Protects access to |client_| and |loop_|.
41 cc::VideoFrameProvider::Client
* client_
;
42 scoped_refptr
<base::SingleThreadTaskRunner
> loop_
;
44 DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl
);
47 StreamTextureProxyImpl::StreamTextureProxyImpl(StreamTextureHost
* host
)
48 : host_(host
), client_(NULL
) {}
50 StreamTextureProxyImpl::~StreamTextureProxyImpl() {}
52 void StreamTextureProxyImpl::Release() {
54 // Cannot call into |client_| anymore (from any thread) after returning
56 base::AutoLock
lock(lock_
);
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)) {
68 void StreamTextureProxyImpl::BindToLoop(
70 cc::VideoFrameProvider::Client
* client
,
71 scoped_refptr
<base::SingleThreadTaskRunner
> loop
) {
75 base::AutoLock
lock(lock_
);
76 DCHECK(!loop_
.get() || (loop
.get() == loop_
.get()));
81 if (loop
->BelongsToCurrentThread()) {
82 BindOnThread(stream_id
);
85 // Unretained is safe here only because the object is deleted on |loop_|
87 loop
->PostTask(FROM_HERE
,
88 base::Bind(&StreamTextureProxyImpl::BindOnThread
,
89 base::Unretained(this),
93 void StreamTextureProxyImpl::BindOnThread(int32 stream_id
) {
94 host_
->BindToCurrentThread(stream_id
, this);
97 void StreamTextureProxyImpl::OnFrameAvailable() {
98 base::AutoLock
lock(lock_
);
100 client_
->DidReceiveFrame();
103 void StreamTextureProxyImpl::OnMatrixChanged(const float matrix
[16]) {
104 base::AutoLock
lock(lock_
);
106 client_
->DidUpdateMatrix(matrix
);
112 scoped_refptr
<StreamTextureFactoryImpl
> StreamTextureFactoryImpl::Create(
113 const scoped_refptr
<cc::ContextProvider
>& context_provider
,
114 GpuChannelHost
* channel
,
116 return new StreamTextureFactoryImpl(context_provider
, channel
, frame_id
);
119 StreamTextureFactoryImpl::StreamTextureFactoryImpl(
120 const scoped_refptr
<cc::ContextProvider
>& context_provider
,
121 GpuChannelHost
* channel
,
123 : context_provider_(context_provider
),
125 frame_id_(frame_id
) {
129 StreamTextureFactoryImpl::~StreamTextureFactoryImpl() {}
131 StreamTextureProxy
* StreamTextureFactoryImpl::CreateProxy() {
132 DCHECK(channel_
.get());
133 StreamTextureHost
* host
= new StreamTextureHost(channel_
.get());
134 return new StreamTextureProxyImpl(host
);
137 void StreamTextureFactoryImpl::EstablishPeer(int32 stream_id
, int player_id
) {
138 DCHECK(channel_
.get());
140 new GpuStreamTextureMsg_EstablishPeer(stream_id
, frame_id_
, player_id
));
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
);
151 stream_id
= gl
->CreateStreamTextureCHROMIUM(*texture_id
);
153 gl
->GenMailboxCHROMIUM(texture_mailbox
->name
);
154 gl
->ProduceTextureDirectCHROMIUM(
155 *texture_id
, texture_target
, texture_mailbox
->name
);
159 void StreamTextureFactoryImpl::SetStreamTextureSize(int32 stream_id
,
160 const gfx::Size
& size
) {
161 channel_
->Send(new GpuStreamTextureMsg_SetSize(stream_id
, size
));
164 gpu::gles2::GLES2Interface
* StreamTextureFactoryImpl::ContextGL() {
165 return context_provider_
->ContextGL();
168 void StreamTextureFactoryImpl::AddObserver(
169 StreamTextureFactoryContextObserver
* obs
) {
172 void StreamTextureFactoryImpl::RemoveObserver(
173 StreamTextureFactoryContextObserver
* obs
) {
176 } // namespace content