Android Video: Don't destroy a video texture in the destructor until it's returned.
[chromium-blink-merge.git] / content / renderer / media / android / stream_texture_factory_android_impl.cc
blob79de97747c3a28e6f1aceffa7451866e81d40d89
1 // Copyright 2013 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_android_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/size.h"
14 namespace content {
16 namespace {
18 class StreamTextureProxyImpl : public StreamTextureProxy,
19 public StreamTextureHost::Listener {
20 public:
21 explicit StreamTextureProxyImpl(StreamTextureHost* host);
22 virtual ~StreamTextureProxyImpl();
24 // StreamTextureProxy implementation:
25 virtual void BindToCurrentThread(int32 stream_id) OVERRIDE;
26 virtual void SetClient(cc::VideoFrameProvider::Client* client) OVERRIDE;
27 virtual void Release() OVERRIDE;
29 // StreamTextureHost::Listener implementation:
30 virtual void OnFrameAvailable() OVERRIDE;
31 virtual void OnMatrixChanged(const float matrix[16]) OVERRIDE;
33 private:
34 scoped_ptr<StreamTextureHost> host_;
35 scoped_refptr<base::MessageLoopProxy> loop_;
37 base::Lock client_lock_;
38 cc::VideoFrameProvider::Client* client_;
40 DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl);
43 StreamTextureProxyImpl::StreamTextureProxyImpl(StreamTextureHost* host)
44 : host_(host), client_(NULL) {}
46 StreamTextureProxyImpl::~StreamTextureProxyImpl() {}
48 void StreamTextureProxyImpl::Release() {
49 SetClient(NULL);
50 if (loop_.get() && loop_.get() != base::MessageLoopProxy::current())
51 loop_->DeleteSoon(FROM_HERE, this);
52 else
53 delete this;
56 void StreamTextureProxyImpl::SetClient(cc::VideoFrameProvider::Client* client) {
57 base::AutoLock lock(client_lock_);
58 client_ = client;
61 void StreamTextureProxyImpl::BindToCurrentThread(int stream_id) {
62 loop_ = base::MessageLoopProxy::current();
63 host_->BindToCurrentThread(stream_id, this);
66 void StreamTextureProxyImpl::OnFrameAvailable() {
67 base::AutoLock lock(client_lock_);
68 if (client_)
69 client_->DidReceiveFrame();
72 void StreamTextureProxyImpl::OnMatrixChanged(const float matrix[16]) {
73 base::AutoLock lock(client_lock_);
74 if (client_)
75 client_->DidUpdateMatrix(matrix);
78 } // namespace
80 // static
81 scoped_refptr<StreamTextureFactoryImpl> StreamTextureFactoryImpl::Create(
82 const scoped_refptr<cc::ContextProvider>& context_provider,
83 GpuChannelHost* channel,
84 int view_id) {
85 return new StreamTextureFactoryImpl(context_provider, channel, view_id);
88 StreamTextureFactoryImpl::StreamTextureFactoryImpl(
89 const scoped_refptr<cc::ContextProvider>& context_provider,
90 GpuChannelHost* channel,
91 int view_id)
92 : context_provider_(context_provider),
93 channel_(channel),
94 view_id_(view_id) {
95 DCHECK(channel);
98 StreamTextureFactoryImpl::~StreamTextureFactoryImpl() {}
100 StreamTextureProxy* StreamTextureFactoryImpl::CreateProxy() {
101 DCHECK(channel_.get());
102 StreamTextureHost* host = new StreamTextureHost(channel_.get());
103 return new StreamTextureProxyImpl(host);
106 void StreamTextureFactoryImpl::EstablishPeer(int32 stream_id, int player_id) {
107 DCHECK(channel_.get());
108 channel_->Send(
109 new GpuStreamTextureMsg_EstablishPeer(stream_id, view_id_, player_id));
112 unsigned StreamTextureFactoryImpl::CreateStreamTexture(
113 unsigned texture_target,
114 unsigned* texture_id,
115 gpu::Mailbox* texture_mailbox) {
116 GLuint stream_id = 0;
117 gpu::gles2::GLES2Interface* gl = context_provider_->ContextGL();
118 gl->GenTextures(1, texture_id);
120 stream_id = gl->CreateStreamTextureCHROMIUM(*texture_id);
122 gl->GenMailboxCHROMIUM(texture_mailbox->name);
123 gl->BindTexture(texture_target, *texture_id);
124 gl->ProduceTextureCHROMIUM(texture_target, texture_mailbox->name);
125 return stream_id;
128 void StreamTextureFactoryImpl::SetStreamTextureSize(
129 int32 stream_id, const gfx::Size& size) {
130 channel_->Send(new GpuStreamTextureMsg_SetSize(stream_id, size));
133 gpu::gles2::GLES2Interface* StreamTextureFactoryImpl::ContextGL() {
134 return context_provider_->ContextGL();
137 } // namespace content