OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |