Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(678)

Side by Side Diff: content/renderer/media/android/stream_texture_factory_android_synchronous_impl.cc

Issue 23234003: Support stream textures with the synchronous compositor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/android/stream_texture_factory_android_synchron ous_impl.h" 5 #include "content/renderer/media/android/stream_texture_factory_android_synchron ous_impl.h"
6 6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/location.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/process/process.h"
15 #include "base/synchronization/lock.h"
16 #include "cc/output/context_provider.h"
17 #include "content/common/android/surface_texture_peer.h"
18 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
19 #include "ui/gl/android/surface_texture_bridge.h"
20
7 namespace content { 21 namespace content {
8 22
9 StreamTextureFactorySynchronousImpl::StreamTextureFactorySynchronousImpl() {} 23 namespace {
24
25 class StreamTextureProxyImpl
26 : public StreamTextureProxy,
27 public base::SupportsWeakPtr<StreamTextureProxyImpl> {
28 public:
29 explicit StreamTextureProxyImpl(
30 StreamTextureFactorySynchronousImpl::ContextProvider* provider);
31 virtual ~StreamTextureProxyImpl();
32
33 // StreamTextureProxy implementation:
34 virtual void BindToCurrentThread(int32 stream_id) OVERRIDE;
35 virtual bool IsBoundToThread() OVERRIDE { return loop_.get() != NULL; }
36 virtual void SetClient(cc::VideoFrameProvider::Client* client) OVERRIDE;
37 virtual void Release() OVERRIDE;
38
39 private:
40 void OnFrameAvailable();
41
42 scoped_refptr<base::MessageLoopProxy> loop_;
43 base::Lock client_lock_;
44 cc::VideoFrameProvider::Client* client_;
45 base::Closure callback_;
46
47 scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider>
48 context_provider_;
49 scoped_refptr<gfx::SurfaceTextureBridge> surface_texture_;
50
51 float current_matrix_[16];
52 bool has_updated_;
53
54 DISALLOW_IMPLICIT_CONSTRUCTORS(StreamTextureProxyImpl);
55 };
56
57 StreamTextureProxyImpl::StreamTextureProxyImpl(
58 StreamTextureFactorySynchronousImpl::ContextProvider* provider)
59 : context_provider_(provider), has_updated_(false) {
60 std::fill(current_matrix_, current_matrix_ + 16, 0);
61 }
62
63 StreamTextureProxyImpl::~StreamTextureProxyImpl() {}
64
65 void StreamTextureProxyImpl::Release() {
66 SetClient(NULL);
67 if (loop_.get() && loop_.get() != base::MessageLoopProxy::current())
68 loop_->DeleteSoon(FROM_HERE, this);
69 else
70 delete this;
71 }
72
73 void StreamTextureProxyImpl::SetClient(cc::VideoFrameProvider::Client* client) {
74 base::AutoLock lock(client_lock_);
75 client_ = client;
76 }
77
78 void StreamTextureProxyImpl::BindToCurrentThread(int stream_id) {
79 if (loop_) {
80 LOG(ERROR) << "Already bound to thread.";
boliu 2013/08/20 21:33:49 I think this can be called multiple times if the v
no sievers 2013/08/20 21:59:58 Argh, that was never intended, but ok.
81 return;
82 }
83 loop_ = base::MessageLoopProxy::current();
boliu 2013/08/20 21:33:49 Hmm...should we have two thread checkers, one for
no sievers 2013/08/20 21:59:58 Constructor, Release and SetClient can be called o
84 DCHECK(callback_.is_null());
85
86 surface_texture_ = context_provider_->GetSurfaceTexture(stream_id);
87 if (!surface_texture_) {
88 LOG(ERROR) << "Failed to get SurfaceTexture for stream.";
89 return;
90 }
91
92 callback_ =
93 base::Bind(&StreamTextureProxyImpl::OnFrameAvailable, AsWeakPtr());
94 surface_texture_->SetFrameAvailableCallback(callback_);
95 }
96
97 void StreamTextureProxyImpl::OnFrameAvailable() {
98 // GetTransformMatrix only returns something valid after both is true:
99 // - OnFrameAvailable was called
100 // - we called UpdateTexImage
101 if (has_updated_) {
102 float matrix[16];
103 surface_texture_->GetTransformMatrix(matrix);
104
105 if (memcmp(current_matrix_, matrix, sizeof(matrix)) != 0) {
106 memcpy(current_matrix_, matrix, sizeof(matrix));
107
108 base::AutoLock lock(client_lock_);
109 if (client_)
110 client_->DidUpdateMatrix(current_matrix_);
111 }
112 }
113 // OnFrameAvailable being called a second time implies that we called
114 // updateTexImage since after we received the first frame.
115 has_updated_ = true;
116
117 base::AutoLock lock(client_lock_);
118 if (client_)
119 client_->DidReceiveFrame();
120 }
121
122 } // namespace
123
124 StreamTextureFactorySynchronousImpl::StreamTextureFactorySynchronousImpl(
125 ContextProvider* context_provider,
126 int view_id)
127 : context_provider_(context_provider), view_id_(view_id) {}
128
10 StreamTextureFactorySynchronousImpl::~StreamTextureFactorySynchronousImpl() {} 129 StreamTextureFactorySynchronousImpl::~StreamTextureFactorySynchronousImpl() {}
11 130
12 StreamTextureProxy* StreamTextureFactorySynchronousImpl::CreateProxy() { 131 StreamTextureProxy* StreamTextureFactorySynchronousImpl::CreateProxy() {
13 return NULL; 132 return new StreamTextureProxyImpl(context_provider_);
14 } 133 }
15 134
16 void StreamTextureFactorySynchronousImpl::EstablishPeer(int32 stream_id, 135 void StreamTextureFactorySynchronousImpl::EstablishPeer(int32 stream_id,
17 int player_id) {} 136 int player_id) {
137 scoped_refptr<gfx::SurfaceTextureBridge> surface_texture =
138 context_provider_->GetSurfaceTexture(stream_id);
139 if (surface_texture) {
140 SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer(
141 base::Process::Current().handle(),
142 surface_texture,
143 view_id_,
144 player_id);
145 }
146 }
18 147
19 unsigned StreamTextureFactorySynchronousImpl::CreateStreamTexture( 148 unsigned StreamTextureFactorySynchronousImpl::CreateStreamTexture(
20 unsigned texture_target, 149 unsigned texture_target,
21 unsigned* texture_id, 150 unsigned* texture_id,
22 gpu::Mailbox* texture_mailbox, 151 gpu::Mailbox* texture_mailbox,
23 unsigned* texture_mailbox_sync_point) { 152 unsigned* texture_mailbox_sync_point) {
24 return 0; 153 WebKit::WebGraphicsContext3D* context = context_provider_->Context3d();
154 unsigned stream_id = 0;
155 if (context->makeContextCurrent()) {
156 *texture_id = context->createTexture();
157 stream_id = context->createStreamTextureCHROMIUM(*texture_id);
158
159 context->genMailboxCHROMIUM(texture_mailbox->name);
160 context->bindTexture(texture_target, *texture_id);
161 context->produceTextureCHROMIUM(texture_target, texture_mailbox->name);
162
163 context->flush();
164 *texture_mailbox_sync_point = context->insertSyncPoint();
165 }
166 return stream_id;
25 } 167 }
26 168
27 void StreamTextureFactorySynchronousImpl::DestroyStreamTexture( 169 void StreamTextureFactorySynchronousImpl::DestroyStreamTexture(
28 unsigned texture_id) {} 170 unsigned texture_id) {
171 WebKit::WebGraphicsContext3D* context = context_provider_->Context3d();
172 if (context->makeContextCurrent()) {
173 context->destroyStreamTextureCHROMIUM(texture_id);
174 context->deleteTexture(texture_id);
175 context->flush();
176 }
177 }
29 178
30 void StreamTextureFactorySynchronousImpl::SetStreamTextureSize( 179 void StreamTextureFactorySynchronousImpl::SetStreamTextureSize(
31 int32 texture_id, 180 int32 stream_id,
32 const gfx::Size& size) {} 181 const gfx::Size& size) {}
33 182
34 } // namespace content 183 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698