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

Side by Side Diff: cc/layers/video_layer_impl.cc

Issue 14199002: Send hardware video frames with mailboxes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Ifdefed Created 7 years, 8 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 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 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 "cc/layers/video_layer_impl.h" 5 #include "cc/layers/video_layer_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "cc/layers/quad_sink.h" 9 #include "cc/layers/quad_sink.h"
10 #include "cc/layers/video_frame_provider_client_impl.h" 10 #include "cc/layers/video_frame_provider_client_impl.h"
(...skipping 19 matching lines...) Expand all
30 VideoFrameProvider* provider) { 30 VideoFrameProvider* provider) {
31 scoped_ptr<VideoLayerImpl> layer(new VideoLayerImpl(tree_impl, id)); 31 scoped_ptr<VideoLayerImpl> layer(new VideoLayerImpl(tree_impl, id));
32 layer->SetProviderClientImpl(VideoFrameProviderClientImpl::Create(provider)); 32 layer->SetProviderClientImpl(VideoFrameProviderClientImpl::Create(provider));
33 DCHECK(tree_impl->proxy()->IsImplThread()); 33 DCHECK(tree_impl->proxy()->IsImplThread());
34 DCHECK(tree_impl->proxy()->IsMainThreadBlocked()); 34 DCHECK(tree_impl->proxy()->IsMainThreadBlocked());
35 return layer.Pass(); 35 return layer.Pass();
36 } 36 }
37 37
38 VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* tree_impl, int id) 38 VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* tree_impl, int id)
39 : LayerImpl(tree_impl, id), 39 : LayerImpl(tree_impl, id),
40 frame_(NULL) {} 40 frame_(NULL),
41 hardware_resource_(0) {}
41 42
42 VideoLayerImpl::~VideoLayerImpl() { 43 VideoLayerImpl::~VideoLayerImpl() {
43 if (!provider_client_impl_->Stopped()) { 44 if (!provider_client_impl_->Stopped()) {
44 // In impl side painting, we may have a pending and active layer 45 // In impl side painting, we may have a pending and active layer
45 // associated with the video provider at the same time. Both have a ref 46 // associated with the video provider at the same time. Both have a ref
46 // on the VideoFrameProviderClientImpl, but we stop when the first 47 // on the VideoFrameProviderClientImpl, but we stop when the first
47 // LayerImpl (the one on the pending tree) is destroyed since we know 48 // LayerImpl (the one on the pending tree) is destroyed since we know
48 // the main thread is blocked for this commit. 49 // the main thread is blocked for this commit.
49 DCHECK(layer_tree_impl()->proxy()->IsImplThread()); 50 DCHECK(layer_tree_impl()->proxy()->IsImplThread());
50 DCHECK(layer_tree_impl()->proxy()->IsMainThreadBlocked()); 51 DCHECK(layer_tree_impl()->proxy()->IsMainThreadBlocked());
(...skipping 10 matching lines...) Expand all
61 LayerImpl::PushPropertiesTo(layer); 62 LayerImpl::PushPropertiesTo(layer);
62 63
63 VideoLayerImpl* other = static_cast<VideoLayerImpl*>(layer); 64 VideoLayerImpl* other = static_cast<VideoLayerImpl*>(layer);
64 other->SetProviderClientImpl(provider_client_impl_); 65 other->SetProviderClientImpl(provider_client_impl_);
65 } 66 }
66 67
67 void VideoLayerImpl::DidBecomeActive() { 68 void VideoLayerImpl::DidBecomeActive() {
68 provider_client_impl_->set_active_video_layer(this); 69 provider_client_impl_->set_active_video_layer(this);
69 } 70 }
70 71
71 static void EmptyCallback(unsigned sync_point, bool lost_resource) {}
72
73 void VideoLayerImpl::WillDraw(ResourceProvider* resource_provider) { 72 void VideoLayerImpl::WillDraw(ResourceProvider* resource_provider) {
74 LayerImpl::WillDraw(resource_provider); 73 LayerImpl::WillDraw(resource_provider);
75 74
76 // Explicitly acquire and release the provider mutex so it can be held from 75 // Explicitly acquire and release the provider mutex so it can be held from
77 // WillDraw to DidDraw. Since the compositor thread is in the middle of 76 // WillDraw to DidDraw. Since the compositor thread is in the middle of
78 // drawing, the layer will not be destroyed before DidDraw is called. 77 // drawing, the layer will not be destroyed before DidDraw is called.
79 // Therefore, the only thing that will prevent this lock from being released 78 // Therefore, the only thing that will prevent this lock from being released
80 // is the GPU process locking it. As the GPU process can't cause the 79 // is the GPU process locking it. As the GPU process can't cause the
81 // destruction of the provider (calling StopUsingProvider), holding this 80 // destruction of the provider (calling StopUsingProvider), holding this
82 // lock should not cause a deadlock. 81 // lock should not cause a deadlock.
83 frame_ = provider_client_impl_->AcquireLockAndCurrentFrame(); 82 frame_ = provider_client_impl_->AcquireLockAndCurrentFrame();
84 83
85 if (!frame_) { 84 if (!frame_) {
86 // Drop any resources used by the updater if there is no frame to display. 85 // Drop any resources used by the updater if there is no frame to display.
87 updater_.reset(); 86 updater_.reset();
88 87
89 provider_client_impl_->ReleaseLock(); 88 provider_client_impl_->ReleaseLock();
90 return; 89 return;
91 } 90 }
92 91
93 if (!updater_) 92 if (!updater_)
94 updater_.reset(new VideoResourceUpdater(resource_provider)); 93 updater_.reset(new VideoResourceUpdater(resource_provider));
95 94
96 VideoFrameExternalResources external_resources; 95 VideoFrameExternalResources external_resources =
97 if (frame_->format() == media::VideoFrame::NATIVE_TEXTURE) { 96 updater_->CreateExternalResourcesFromVideoFrame(frame_);
98 // TODO(danakj): To make this work for ubercomp, push this code out to
99 // WebMediaPlayer and have it set a callback so it knows it can reuse the
100 // texture.
101 TextureMailbox::ReleaseCallback empty_callback = base::Bind(&EmptyCallback);
102 external_resources = updater_->CreateForHardwarePlanes(
103 frame_, empty_callback);
104 } else {
105 external_resources = updater_->CreateForSoftwarePlanes(frame_);
106 }
107
108 frame_resource_type_ = external_resources.type; 97 frame_resource_type_ = external_resources.type;
109 98
110 if (external_resources.type == 99 if (external_resources.type ==
111 VideoFrameExternalResources::SOFTWARE_RESOURCE) { 100 VideoFrameExternalResources::SOFTWARE_RESOURCE) {
112 software_resources_ = external_resources.software_resources; 101 software_resources_ = external_resources.software_resources;
113 software_release_callback_ = 102 software_release_callback_ =
114 external_resources.software_release_callback; 103 external_resources.software_release_callback;
115 return; 104 return;
116 } 105 }
117 106
107 #ifndef VIDEO_FRAME_MAILBOX
108 if (external_resources.hardware_resource) {
109 hardware_resource_ = external_resources.hardware_resource;
110 hardware_release_callback_ =
111 external_resources.hardware_release_callback;
112 return;
113 }
114 #endif
115
118 for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) { 116 for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) {
119 frame_resources_.push_back( 117 frame_resources_.push_back(
120 resource_provider->CreateResourceFromTextureMailbox( 118 resource_provider->CreateResourceFromTextureMailbox(
121 external_resources.mailboxes[i])); 119 external_resources.mailboxes[i]));
122 } 120 }
123 } 121 }
124 122
125 void VideoLayerImpl::AppendQuads(QuadSink* quad_sink, 123 void VideoLayerImpl::AppendQuads(QuadSink* quad_sink,
126 AppendQuadsData* append_quads_data) { 124 AppendQuadsData* append_quads_data) {
127 if (!frame_) 125 if (!frame_)
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 quad_rect, 175 quad_rect,
178 opaque_rect, 176 opaque_rect,
179 tex_scale, 177 tex_scale,
180 frame_resources_[0], 178 frame_resources_[0],
181 frame_resources_[1], 179 frame_resources_[1],
182 frame_resources_[2]); 180 frame_resources_[2]);
183 quad_sink->Append(yuv_video_quad.PassAs<DrawQuad>(), append_quads_data); 181 quad_sink->Append(yuv_video_quad.PassAs<DrawQuad>(), append_quads_data);
184 break; 182 break;
185 } 183 }
186 case VideoFrameExternalResources::RGB_RESOURCE: { 184 case VideoFrameExternalResources::RGB_RESOURCE: {
187 DCHECK_EQ(frame_resources_.size(), 1u); 185 if (!hardware_resource_) {
188 if (frame_resources_.size() < 1u) 186 DCHECK_EQ(frame_resources_.size(), 1u);
189 break; 187 if (frame_resources_.size() < 1u)
188 break;
189 }
190 bool premultiplied_alpha = true; 190 bool premultiplied_alpha = true;
191 gfx::PointF uv_top_left(0.f, 0.f); 191 gfx::PointF uv_top_left(0.f, 0.f);
192 gfx::PointF uv_bottom_right(tex_width_scale, tex_height_scale); 192 gfx::PointF uv_bottom_right(tex_width_scale, tex_height_scale);
193 float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; 193 float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
194 bool flipped = false; 194 bool flipped = false;
195 scoped_ptr<TextureDrawQuad> texture_quad = TextureDrawQuad::Create(); 195 scoped_ptr<TextureDrawQuad> texture_quad = TextureDrawQuad::Create();
196 texture_quad->SetNew(shared_quad_state, 196 texture_quad->SetNew(shared_quad_state,
197 quad_rect, 197 quad_rect,
198 opaque_rect, 198 opaque_rect,
199 frame_resources_[0], 199 hardware_resource_ ? hardware_resource_
200 : frame_resources_[0],
200 premultiplied_alpha, 201 premultiplied_alpha,
201 uv_top_left, 202 uv_top_left,
202 uv_bottom_right, 203 uv_bottom_right,
203 opacity, 204 opacity,
204 flipped); 205 flipped);
205 quad_sink->Append(texture_quad.PassAs<DrawQuad>(), append_quads_data); 206 quad_sink->Append(texture_quad.PassAs<DrawQuad>(), append_quads_data);
206 break; 207 break;
207 } 208 }
208 case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE: { 209 case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE: {
209 DCHECK_EQ(frame_resources_.size(), 1u); 210 if (!hardware_resource_) {
210 if (frame_resources_.size() < 1u) 211 DCHECK_EQ(frame_resources_.size(), 1u);
211 break; 212 if (frame_resources_.size() < 1u)
213 break;
214 }
212 gfx::Transform transform( 215 gfx::Transform transform(
213 provider_client_impl_->stream_texture_matrix()); 216 provider_client_impl_->stream_texture_matrix());
214 transform.Scale(tex_width_scale, tex_height_scale); 217 transform.Scale(tex_width_scale, tex_height_scale);
215 scoped_ptr<StreamVideoDrawQuad> stream_video_quad = 218 scoped_ptr<StreamVideoDrawQuad> stream_video_quad =
216 StreamVideoDrawQuad::Create(); 219 StreamVideoDrawQuad::Create();
217 stream_video_quad->SetNew(shared_quad_state, 220 stream_video_quad->SetNew(shared_quad_state,
218 quad_rect, 221 quad_rect,
219 opaque_rect, 222 opaque_rect,
220 frame_resources_[0], 223 hardware_resource_ ? hardware_resource_
224 : frame_resources_[0],
221 transform); 225 transform);
222 quad_sink->Append(stream_video_quad.PassAs<DrawQuad>(), 226 quad_sink->Append(stream_video_quad.PassAs<DrawQuad>(),
223 append_quads_data); 227 append_quads_data);
224 break; 228 break;
225 } 229 }
226 case VideoFrameExternalResources::IO_SURFACE: { 230 case VideoFrameExternalResources::IO_SURFACE: {
227 DCHECK_EQ(frame_resources_.size(), 1u); 231 if (!hardware_resource_) {
228 if (frame_resources_.size() < 1u) 232 DCHECK_EQ(frame_resources_.size(), 1u);
229 break; 233 if (frame_resources_.size() < 1u)
234 break;
235 }
230 gfx::Size visible_size(visible_rect.width(), visible_rect.height()); 236 gfx::Size visible_size(visible_rect.width(), visible_rect.height());
231 scoped_ptr<IOSurfaceDrawQuad> io_surface_quad = 237 scoped_ptr<IOSurfaceDrawQuad> io_surface_quad =
232 IOSurfaceDrawQuad::Create(); 238 IOSurfaceDrawQuad::Create();
233 io_surface_quad->SetNew(shared_quad_state, 239 io_surface_quad->SetNew(shared_quad_state,
234 quad_rect, 240 quad_rect,
235 opaque_rect, 241 opaque_rect,
236 visible_size, 242 visible_size,
237 frame_resources_[0], 243 hardware_resource_ ? hardware_resource_
244 : frame_resources_[0],
238 IOSurfaceDrawQuad::UNFLIPPED); 245 IOSurfaceDrawQuad::UNFLIPPED);
239 quad_sink->Append(io_surface_quad.PassAs<DrawQuad>(), 246 quad_sink->Append(io_surface_quad.PassAs<DrawQuad>(),
240 append_quads_data); 247 append_quads_data);
241 break; 248 break;
242 } 249 }
243 #if defined(GOOGLE_TV) 250 #if defined(GOOGLE_TV)
244 // This block and other blocks wrapped around #if defined(GOOGLE_TV) is not 251 // This block and other blocks wrapped around #if defined(GOOGLE_TV) is not
245 // maintained by the general compositor team. Please contact the following 252 // maintained by the general compositor team. Please contact the following
246 // people instead: 253 // people instead:
247 // 254 //
(...skipping 25 matching lines...) Expand all
273 if (!frame_) 280 if (!frame_)
274 return; 281 return;
275 282
276 if (frame_resource_type_ == 283 if (frame_resource_type_ ==
277 VideoFrameExternalResources::SOFTWARE_RESOURCE) { 284 VideoFrameExternalResources::SOFTWARE_RESOURCE) {
278 for (size_t i = 0; i < software_resources_.size(); ++i) 285 for (size_t i = 0; i < software_resources_.size(); ++i)
279 software_release_callback_.Run(0, false); 286 software_release_callback_.Run(0, false);
280 287
281 software_resources_.clear(); 288 software_resources_.clear();
282 software_release_callback_.Reset(); 289 software_release_callback_.Reset();
290 } else if (hardware_resource_) {
291 hardware_release_callback_.Run(0, false);
292 hardware_resource_ = 0;
293 hardware_release_callback_.Reset();
283 } else { 294 } else {
284 for (size_t i = 0; i < frame_resources_.size(); ++i) 295 for (size_t i = 0; i < frame_resources_.size(); ++i)
285 resource_provider->DeleteResource(frame_resources_[i]); 296 resource_provider->DeleteResource(frame_resources_[i]);
286 frame_resources_.clear(); 297 frame_resources_.clear();
287 } 298 }
288 299
289 provider_client_impl_->PutCurrentFrame(frame_); 300 provider_client_impl_->PutCurrentFrame(frame_);
290 frame_ = NULL; 301 frame_ = NULL;
291 302
292 provider_client_impl_->ReleaseLock(); 303 provider_client_impl_->ReleaseLock();
(...skipping 11 matching lines...) Expand all
304 void VideoLayerImpl::SetProviderClientImpl( 315 void VideoLayerImpl::SetProviderClientImpl(
305 scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl) { 316 scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl) {
306 provider_client_impl_ = provider_client_impl; 317 provider_client_impl_ = provider_client_impl;
307 } 318 }
308 319
309 const char* VideoLayerImpl::LayerTypeAsString() const { 320 const char* VideoLayerImpl::LayerTypeAsString() const {
310 return "VideoLayer"; 321 return "VideoLayer";
311 } 322 }
312 323
313 } // namespace cc 324 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698