| 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 if (frame_->format() == media::VideoFrame::NATIVE_TEXTURE) |
| 98 // TODO(danakj): To make this work for ubercomp, push this code out to | 97 external_resources = updater_->CreateForHardwarePlanes(frame_); |
| 99 // WebMediaPlayer and have it set a callback so it knows it can reuse the | 98 else |
| 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_); | 99 external_resources = updater_->CreateForSoftwarePlanes(frame_); |
| 106 } | |
| 107 | 100 |
| 108 frame_resource_type_ = external_resources.type; | 101 frame_resource_type_ = external_resources.type; |
| 109 | 102 |
| 110 if (external_resources.type == | 103 if (external_resources.type == |
| 111 VideoFrameExternalResources::SOFTWARE_RESOURCE) { | 104 VideoFrameExternalResources::SOFTWARE_RESOURCE) { |
| 112 software_resources_ = external_resources.software_resources; | 105 software_resources_ = external_resources.software_resources; |
| 113 software_release_callback_ = | 106 software_release_callback_ = |
| 114 external_resources.software_release_callback; | 107 external_resources.software_release_callback; |
| 115 return; | 108 return; |
| 116 } | 109 } |
| 117 | 110 |
| 111 if (external_resources.hardware_resource) { |
| 112 hardware_resource_ = external_resources.hardware_resource; |
| 113 hardware_release_callback_ = |
| 114 external_resources.hardware_release_callback; |
| 115 return; |
| 116 } |
| 117 |
| 118 for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) { | 118 for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) { |
| 119 frame_resources_.push_back( | 119 frame_resources_.push_back( |
| 120 resource_provider->CreateResourceFromTextureMailbox( | 120 resource_provider->CreateResourceFromTextureMailbox( |
| 121 external_resources.mailboxes[i])); | 121 external_resources.mailboxes[i])); |
| 122 } | 122 } |
| 123 } | 123 } |
| 124 | 124 |
| 125 void VideoLayerImpl::AppendQuads(QuadSink* quad_sink, | 125 void VideoLayerImpl::AppendQuads(QuadSink* quad_sink, |
| 126 AppendQuadsData* append_quads_data) { | 126 AppendQuadsData* append_quads_data) { |
| 127 if (!frame_) | 127 if (!frame_) |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 quad_rect, | 177 quad_rect, |
| 178 opaque_rect, | 178 opaque_rect, |
| 179 tex_scale, | 179 tex_scale, |
| 180 frame_resources_[0], | 180 frame_resources_[0], |
| 181 frame_resources_[1], | 181 frame_resources_[1], |
| 182 frame_resources_[2]); | 182 frame_resources_[2]); |
| 183 quad_sink->Append(yuv_video_quad.PassAs<DrawQuad>(), append_quads_data); | 183 quad_sink->Append(yuv_video_quad.PassAs<DrawQuad>(), append_quads_data); |
| 184 break; | 184 break; |
| 185 } | 185 } |
| 186 case VideoFrameExternalResources::RGB_RESOURCE: { | 186 case VideoFrameExternalResources::RGB_RESOURCE: { |
| 187 DCHECK_EQ(frame_resources_.size(), 1u); | 187 if (!hardware_resource_) { |
| 188 if (frame_resources_.size() < 1u) | 188 DCHECK_EQ(frame_resources_.size(), 1u); |
| 189 break; | 189 if (frame_resources_.size() < 1u) |
| 190 break; |
| 191 } |
| 190 bool premultiplied_alpha = true; | 192 bool premultiplied_alpha = true; |
| 191 gfx::PointF uv_top_left(0.f, 0.f); | 193 gfx::PointF uv_top_left(0.f, 0.f); |
| 192 gfx::PointF uv_bottom_right(tex_width_scale, tex_height_scale); | 194 gfx::PointF uv_bottom_right(tex_width_scale, tex_height_scale); |
| 193 float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; | 195 float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| 194 bool flipped = false; | 196 bool flipped = false; |
| 195 scoped_ptr<TextureDrawQuad> texture_quad = TextureDrawQuad::Create(); | 197 scoped_ptr<TextureDrawQuad> texture_quad = TextureDrawQuad::Create(); |
| 196 texture_quad->SetNew(shared_quad_state, | 198 texture_quad->SetNew(shared_quad_state, |
| 197 quad_rect, | 199 quad_rect, |
| 198 opaque_rect, | 200 opaque_rect, |
| 199 frame_resources_[0], | 201 hardware_resource_ ? hardware_resource_ |
| 202 : frame_resources_[0], |
| 200 premultiplied_alpha, | 203 premultiplied_alpha, |
| 201 uv_top_left, | 204 uv_top_left, |
| 202 uv_bottom_right, | 205 uv_bottom_right, |
| 203 opacity, | 206 opacity, |
| 204 flipped); | 207 flipped); |
| 205 quad_sink->Append(texture_quad.PassAs<DrawQuad>(), append_quads_data); | 208 quad_sink->Append(texture_quad.PassAs<DrawQuad>(), append_quads_data); |
| 206 break; | 209 break; |
| 207 } | 210 } |
| 208 case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE: { | 211 case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE: { |
| 209 DCHECK_EQ(frame_resources_.size(), 1u); | 212 if (!hardware_resource_) { |
| 210 if (frame_resources_.size() < 1u) | 213 DCHECK_EQ(frame_resources_.size(), 1u); |
| 211 break; | 214 if (frame_resources_.size() < 1u) |
| 215 break; |
| 216 } |
| 212 gfx::Transform transform( | 217 gfx::Transform transform( |
| 213 provider_client_impl_->stream_texture_matrix()); | 218 provider_client_impl_->stream_texture_matrix()); |
| 214 transform.Scale(tex_width_scale, tex_height_scale); | 219 transform.Scale(tex_width_scale, tex_height_scale); |
| 215 scoped_ptr<StreamVideoDrawQuad> stream_video_quad = | 220 scoped_ptr<StreamVideoDrawQuad> stream_video_quad = |
| 216 StreamVideoDrawQuad::Create(); | 221 StreamVideoDrawQuad::Create(); |
| 217 stream_video_quad->SetNew(shared_quad_state, | 222 stream_video_quad->SetNew(shared_quad_state, |
| 218 quad_rect, | 223 quad_rect, |
| 219 opaque_rect, | 224 opaque_rect, |
| 220 frame_resources_[0], | 225 hardware_resource_ ? hardware_resource_ |
| 226 : frame_resources_[0], |
| 221 transform); | 227 transform); |
| 222 quad_sink->Append(stream_video_quad.PassAs<DrawQuad>(), | 228 quad_sink->Append(stream_video_quad.PassAs<DrawQuad>(), |
| 223 append_quads_data); | 229 append_quads_data); |
| 224 break; | 230 break; |
| 225 } | 231 } |
| 226 case VideoFrameExternalResources::IO_SURFACE: { | 232 case VideoFrameExternalResources::IO_SURFACE: { |
| 227 DCHECK_EQ(frame_resources_.size(), 1u); | 233 if (!hardware_resource_) { |
| 228 if (frame_resources_.size() < 1u) | 234 DCHECK_EQ(frame_resources_.size(), 1u); |
| 229 break; | 235 if (frame_resources_.size() < 1u) |
| 236 break; |
| 237 } |
| 230 gfx::Size visible_size(visible_rect.width(), visible_rect.height()); | 238 gfx::Size visible_size(visible_rect.width(), visible_rect.height()); |
| 231 scoped_ptr<IOSurfaceDrawQuad> io_surface_quad = | 239 scoped_ptr<IOSurfaceDrawQuad> io_surface_quad = |
| 232 IOSurfaceDrawQuad::Create(); | 240 IOSurfaceDrawQuad::Create(); |
| 233 io_surface_quad->SetNew(shared_quad_state, | 241 io_surface_quad->SetNew(shared_quad_state, |
| 234 quad_rect, | 242 quad_rect, |
| 235 opaque_rect, | 243 opaque_rect, |
| 236 visible_size, | 244 visible_size, |
| 237 frame_resources_[0], | 245 hardware_resource_ ? hardware_resource_ |
| 246 : frame_resources_[0], |
| 238 IOSurfaceDrawQuad::UNFLIPPED); | 247 IOSurfaceDrawQuad::UNFLIPPED); |
| 239 quad_sink->Append(io_surface_quad.PassAs<DrawQuad>(), | 248 quad_sink->Append(io_surface_quad.PassAs<DrawQuad>(), |
| 240 append_quads_data); | 249 append_quads_data); |
| 241 break; | 250 break; |
| 242 } | 251 } |
| 243 #if defined(GOOGLE_TV) | 252 #if defined(GOOGLE_TV) |
| 244 // This block and other blocks wrapped around #if defined(GOOGLE_TV) is not | 253 // This block and other blocks wrapped around #if defined(GOOGLE_TV) is not |
| 245 // maintained by the general compositor team. Please contact the following | 254 // maintained by the general compositor team. Please contact the following |
| 246 // people instead: | 255 // people instead: |
| 247 // | 256 // |
| (...skipping 25 matching lines...) Expand all Loading... |
| 273 if (!frame_) | 282 if (!frame_) |
| 274 return; | 283 return; |
| 275 | 284 |
| 276 if (frame_resource_type_ == | 285 if (frame_resource_type_ == |
| 277 VideoFrameExternalResources::SOFTWARE_RESOURCE) { | 286 VideoFrameExternalResources::SOFTWARE_RESOURCE) { |
| 278 for (size_t i = 0; i < software_resources_.size(); ++i) | 287 for (size_t i = 0; i < software_resources_.size(); ++i) |
| 279 software_release_callback_.Run(0, false); | 288 software_release_callback_.Run(0, false); |
| 280 | 289 |
| 281 software_resources_.clear(); | 290 software_resources_.clear(); |
| 282 software_release_callback_.Reset(); | 291 software_release_callback_.Reset(); |
| 292 } else if (hardware_resource_) { |
| 293 hardware_release_callback_.Run(0, false); |
| 294 hardware_resource_ = 0; |
| 295 hardware_release_callback_.Reset(); |
| 283 } else { | 296 } else { |
| 284 for (size_t i = 0; i < frame_resources_.size(); ++i) | 297 for (size_t i = 0; i < frame_resources_.size(); ++i) |
| 285 resource_provider->DeleteResource(frame_resources_[i]); | 298 resource_provider->DeleteResource(frame_resources_[i]); |
| 286 frame_resources_.clear(); | 299 frame_resources_.clear(); |
| 287 } | 300 } |
| 288 | 301 |
| 289 provider_client_impl_->PutCurrentFrame(frame_); | 302 provider_client_impl_->PutCurrentFrame(frame_); |
| 290 frame_ = NULL; | 303 frame_ = NULL; |
| 291 | 304 |
| 292 provider_client_impl_->ReleaseLock(); | 305 provider_client_impl_->ReleaseLock(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 304 void VideoLayerImpl::SetProviderClientImpl( | 317 void VideoLayerImpl::SetProviderClientImpl( |
| 305 scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl) { | 318 scoped_refptr<VideoFrameProviderClientImpl> provider_client_impl) { |
| 306 provider_client_impl_ = provider_client_impl; | 319 provider_client_impl_ = provider_client_impl; |
| 307 } | 320 } |
| 308 | 321 |
| 309 const char* VideoLayerImpl::LayerTypeAsString() const { | 322 const char* VideoLayerImpl::LayerTypeAsString() const { |
| 310 return "VideoLayer"; | 323 return "VideoLayer"; |
| 311 } | 324 } |
| 312 | 325 |
| 313 } // namespace cc | 326 } // namespace cc |
| OLD | NEW |