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