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. 4 5 #include "content/renderer/media/android/stream_texture_factory_android_impl.h" 6 7 #include "content/common/gpu/client/gpu_channel_host.h" 8 #include "content/common/gpu/gpu_messages.h" 9 #include "content/renderer/gpu/stream_texture_host_android.h" 10 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" 11 #include "ui/gfx/size.h" 12 13 namespace content { 14 15 namespace { 16 17 class StreamTextureProxyImpl : public StreamTextureProxy, 18 public StreamTextureHost::Listener { 19 public: 20 explicit StreamTextureProxyImpl(StreamTextureHost* host); 21 virtual ~StreamTextureProxyImpl(); 22 23 // StreamTextureProxy implementation: 24 virtual void BindToCurrentThread(int32 stream_id) OVERRIDE; 25 virtual bool IsBoundToThread() OVERRIDE { return loop_.get() != NULL; } 26 virtual void SetClient(cc::VideoFrameProvider::Client* client) OVERRIDE; 27 virtual void Release() OVERRIDE; 28 29 // StreamTextureHost::Listener implementation: 30 virtual void OnFrameAvailable() OVERRIDE; 31 virtual void OnMatrixChanged(const float matrix[16]) OVERRIDE; 32 33 private: 34 scoped_ptr<StreamTextureHost> host_; 35 scoped_refptr<base::MessageLoopProxy> loop_; 36 37 base::Lock client_lock_; 38 cc::VideoFrameProvider::Client* client_; 39 40 DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl); 41 }; 42 43 StreamTextureProxyImpl::StreamTextureProxyImpl(StreamTextureHost* host) 44 : host_(host), client_(NULL) { 45 host->SetListener(this); 46 } 47 48 StreamTextureProxyImpl::~StreamTextureProxyImpl() {} 49 50 void StreamTextureProxyImpl::Release() { 51 SetClient(NULL); 52 if (loop_.get() && loop_.get() != base::MessageLoopProxy::current()) 53 loop_->DeleteSoon(FROM_HERE, this); 54 else 55 delete this; 56 } 57 58 void StreamTextureProxyImpl::SetClient(cc::VideoFrameProvider::Client* client) { 59 base::AutoLock lock(client_lock_); 60 client_ = client; 61 } 62 63 void StreamTextureProxyImpl::BindToCurrentThread(int stream_id) { 64 loop_ = base::MessageLoopProxy::current(); 65 host_->Initialize(stream_id); 66 } 67 68 void StreamTextureProxyImpl::OnFrameAvailable() { 69 base::AutoLock lock(client_lock_); 70 if (client_) 71 client_->DidReceiveFrame(); 72 } 73 74 void StreamTextureProxyImpl::OnMatrixChanged(const float matrix[16]) { 75 base::AutoLock lock(client_lock_); 76 if (client_) 77 client_->DidUpdateMatrix(matrix); 78 } 79 80 } // namespace 81 82 StreamTextureFactoryImpl::StreamTextureFactoryImpl( 83 WebKit::WebGraphicsContext3D* context, 84 GpuChannelHost* channel, 85 int view_id) 86 : context_(context), channel_(channel), view_id_(view_id) { 87 DCHECK(context_); 88 DCHECK(channel); 89 } 90 91 StreamTextureFactoryImpl::~StreamTextureFactoryImpl() {} 92 93 StreamTextureProxy* StreamTextureFactoryImpl::CreateProxy() { 94 DCHECK(channel_.get()); 95 StreamTextureHost* host = new StreamTextureHost(channel_.get()); 96 return new StreamTextureProxyImpl(host); 97 } 98 99 void StreamTextureFactoryImpl::EstablishPeer(int32 stream_id, int player_id) { 100 DCHECK(channel_.get()); 101 channel_->Send( 102 new GpuChannelMsg_EstablishStreamTexture(stream_id, view_id_, player_id)); 103 } 104 105 unsigned StreamTextureFactoryImpl::CreateStreamTexture( 106 unsigned texture_target, 107 unsigned* texture_id, 108 gpu::Mailbox* texture_mailbox, 109 unsigned* texture_mailbox_sync_point) { 110 unsigned stream_id = 0; 111 if (context_->makeContextCurrent()) { 112 *texture_id = context_->createTexture(); 113 stream_id = context_->createStreamTextureCHROMIUM(*texture_id); 114 115 context_->genMailboxCHROMIUM(texture_mailbox->name); 116 context_->bindTexture(texture_target, *texture_id); 117 context_->produceTextureCHROMIUM(texture_target, texture_mailbox->name); 118 119 context_->flush(); 120 *texture_mailbox_sync_point = context_->insertSyncPoint(); 121 } 122 return stream_id; 123 } 124 125 void StreamTextureFactoryImpl::DestroyStreamTexture(unsigned texture_id) { 126 if (context_->makeContextCurrent()) { 127 // TODO(sievers): Make the destroyStreamTexture implicit when the last 128 // texture referencing it is lost. 129 context_->destroyStreamTextureCHROMIUM(texture_id); 130 context_->deleteTexture(texture_id); 131 context_->flush(); 132 } 133 } 134 135 void StreamTextureFactoryImpl::SetStreamTextureSize( 136 int32 stream_id, const gfx::Size& size) { 137 channel_->Send(new GpuChannelMsg_SetStreamTextureSize(stream_id, size)); 138 } 139 140 } // namespace content 141