| OLD | NEW |
| 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 "cc/resources/video_resource_updater.h" | 5 #include "cc/resources/video_resource_updater.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "cc/output/gl_renderer.h" | 8 #include "cc/output/gl_renderer.h" |
| 9 #include "cc/resources/resource_provider.h" | 9 #include "cc/resources/resource_provider.h" |
| 10 #include "gpu/GLES2/gl2extchromium.h" | 10 #include "gpu/GLES2/gl2extchromium.h" |
| 11 #include "media/base/video_frame.h" | 11 #include "media/base/video_frame.h" |
| 12 #include "media/filters/skcanvas_video_renderer.h" | 12 #include "media/filters/skcanvas_video_renderer.h" |
| 13 #include "third_party/khronos/GLES2/gl2.h" | 13 #include "third_party/khronos/GLES2/gl2.h" |
| 14 #include "third_party/khronos/GLES2/gl2ext.h" | 14 #include "third_party/khronos/GLES2/gl2ext.h" |
| 15 #include "ui/gfx/size_conversions.h" | 15 #include "ui/gfx/size_conversions.h" |
| 16 | 16 |
| 17 const unsigned kYUVResourceFormat = GL_LUMINANCE; | 17 const unsigned kYUVResourceFormat = GL_LUMINANCE; |
| 18 const unsigned kRGBResourceFormat = GL_RGBA; | 18 const unsigned kRGBResourceFormat = GL_RGBA; |
| 19 | 19 |
| 20 namespace cc { | 20 namespace cc { |
| 21 | 21 |
| 22 VideoFrameExternalResources::VideoFrameExternalResources() | 22 VideoFrameExternalResources::VideoFrameExternalResources() : type(NONE) {} |
| 23 : type(NONE), hardware_resource(0) {} | |
| 24 | 23 |
| 25 VideoFrameExternalResources::~VideoFrameExternalResources() {} | 24 VideoFrameExternalResources::~VideoFrameExternalResources() {} |
| 26 | 25 |
| 27 VideoResourceUpdater::VideoResourceUpdater(ResourceProvider* resource_provider) | 26 VideoResourceUpdater::VideoResourceUpdater(ResourceProvider* resource_provider) |
| 28 : resource_provider_(resource_provider) { | 27 : resource_provider_(resource_provider) { |
| 29 } | 28 } |
| 30 | 29 |
| 31 VideoResourceUpdater::~VideoResourceUpdater() { | 30 VideoResourceUpdater::~VideoResourceUpdater() { |
| 32 while (!all_resources_.empty()) { | 31 while (!all_resources_.empty()) { |
| 33 resource_provider_->DeleteResource(all_resources_.back()); | 32 resource_provider_->DeleteResource(all_resources_.back()); |
| 34 all_resources_.pop_back(); | 33 all_resources_.pop_back(); |
| 35 } | 34 } |
| 36 } | 35 } |
| 37 | 36 |
| 38 void VideoResourceUpdater::DeleteResource(unsigned resource_id) { | 37 void VideoResourceUpdater::DeleteResource(unsigned resource_id) { |
| 39 resource_provider_->DeleteResource(resource_id); | 38 resource_provider_->DeleteResource(resource_id); |
| 40 all_resources_.erase(std::remove(all_resources_.begin(), | 39 all_resources_.erase(std::remove(all_resources_.begin(), |
| 41 all_resources_.end(), | 40 all_resources_.end(), |
| 42 resource_id)); | 41 resource_id)); |
| 43 } | 42 } |
| 44 | 43 |
| 44 VideoFrameExternalResources VideoResourceUpdater:: |
| 45 CreateExternalResourcesFromVideoFrame( |
| 46 const scoped_refptr<media::VideoFrame>& video_frame) { |
| 47 if (!VerifyFrame(video_frame)) |
| 48 return VideoFrameExternalResources(); |
| 49 |
| 50 if (video_frame->format() == media::VideoFrame::NATIVE_TEXTURE) |
| 51 return CreateForHardwarePlanes(video_frame); |
| 52 else |
| 53 return CreateForSoftwarePlanes(video_frame); |
| 54 } |
| 55 |
| 45 bool VideoResourceUpdater::VerifyFrame( | 56 bool VideoResourceUpdater::VerifyFrame( |
| 46 const scoped_refptr<media::VideoFrame>& video_frame) { | 57 const scoped_refptr<media::VideoFrame>& video_frame) { |
| 47 // If these fail, we'll have to add logic that handles offset bitmap/texture | 58 // If these fail, we'll have to add logic that handles offset bitmap/texture |
| 48 // UVs. For now, just expect (0, 0) offset, since all our decoders so far | 59 // UVs. For now, just expect (0, 0) offset, since all our decoders so far |
| 49 // don't offset. | 60 // don't offset. |
| 50 DCHECK_EQ(video_frame->visible_rect().x(), 0); | 61 DCHECK_EQ(video_frame->visible_rect().x(), 0); |
| 51 DCHECK_EQ(video_frame->visible_rect().y(), 0); | 62 DCHECK_EQ(video_frame->visible_rect().y(), 0); |
| 52 | 63 |
| 53 switch (video_frame->format()) { | 64 switch (video_frame->format()) { |
| 54 // Acceptable inputs. | 65 // Acceptable inputs. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 NOTREACHED(); | 111 NOTREACHED(); |
| 101 } | 112 } |
| 102 } | 113 } |
| 103 | 114 |
| 104 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat)); | 115 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat)); |
| 105 return coded_size; | 116 return coded_size; |
| 106 } | 117 } |
| 107 | 118 |
| 108 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 119 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
| 109 const scoped_refptr<media::VideoFrame>& video_frame) { | 120 const scoped_refptr<media::VideoFrame>& video_frame) { |
| 110 if (!VerifyFrame(video_frame)) | |
| 111 return VideoFrameExternalResources(); | |
| 112 | |
| 113 media::VideoFrame::Format input_frame_format = video_frame->format(); | 121 media::VideoFrame::Format input_frame_format = video_frame->format(); |
| 114 | 122 |
| 115 #if defined(GOOGLE_TV) | 123 #if defined(GOOGLE_TV) |
| 116 if (input_frame_format == media::VideoFrame::HOLE) { | 124 if (input_frame_format == media::VideoFrame::HOLE) { |
| 117 VideoFrameExternalResources external_resources; | 125 VideoFrameExternalResources external_resources; |
| 118 external_resources.type = VideoFrameExternalResources::HOLE; | 126 external_resources.type = VideoFrameExternalResources::HOLE; |
| 119 return external_resources; | 127 return external_resources; |
| 120 } | 128 } |
| 121 #endif | 129 #endif |
| 122 | 130 |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 if (!mailbox_success) { | 312 if (!mailbox_success) { |
| 305 for (size_t i = 0; i < plane_resources.size(); ++i) | 313 for (size_t i = 0; i < plane_resources.size(); ++i) |
| 306 DeleteResource(plane_resources[i].resource_id); | 314 DeleteResource(plane_resources[i].resource_id); |
| 307 return VideoFrameExternalResources(); | 315 return VideoFrameExternalResources(); |
| 308 } | 316 } |
| 309 | 317 |
| 310 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; | 318 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; |
| 311 return external_resources; | 319 return external_resources; |
| 312 } | 320 } |
| 313 | 321 |
| 322 static void ReturnTexture( |
| 323 scoped_refptr<media::VideoFrame::MailboxHolder> mailbox_holder, |
| 324 unsigned sync_point, |
| 325 bool lost_resource) { |
| 326 mailbox_holder->Return(sync_point); |
| 327 } |
| 328 |
| 314 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( | 329 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( |
| 315 const scoped_refptr<media::VideoFrame>& video_frame) { | 330 const scoped_refptr<media::VideoFrame>& video_frame) { |
| 316 if (!VerifyFrame(video_frame)) | |
| 317 return VideoFrameExternalResources(); | |
| 318 | |
| 319 media::VideoFrame::Format frame_format = video_frame->format(); | 331 media::VideoFrame::Format frame_format = video_frame->format(); |
| 320 | 332 |
| 321 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE); | 333 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE); |
| 322 if (frame_format != media::VideoFrame::NATIVE_TEXTURE) | 334 if (frame_format != media::VideoFrame::NATIVE_TEXTURE) |
| 323 return VideoFrameExternalResources(); | 335 return VideoFrameExternalResources(); |
| 324 | 336 |
| 325 WebKit::WebGraphicsContext3D* context = | 337 WebKit::WebGraphicsContext3D* context = |
| 326 resource_provider_->GraphicsContext3D(); | 338 resource_provider_->GraphicsContext3D(); |
| 327 if (!context) | 339 if (!context) |
| 328 return VideoFrameExternalResources(); | 340 return VideoFrameExternalResources(); |
| 329 | 341 |
| 330 VideoFrameExternalResources external_resources; | 342 VideoFrameExternalResources external_resources; |
| 331 switch (video_frame->texture_target()) { | 343 switch (video_frame->texture_target()) { |
| 332 case GL_TEXTURE_2D: | 344 case GL_TEXTURE_2D: |
| 333 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE; | 345 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE; |
| 334 break; | 346 break; |
| 335 case GL_TEXTURE_EXTERNAL_OES: | 347 case GL_TEXTURE_EXTERNAL_OES: |
| 336 external_resources.type = | 348 external_resources.type = |
| 337 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE; | 349 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE; |
| 338 break; | 350 break; |
| 339 case GL_TEXTURE_RECTANGLE_ARB: | 351 case GL_TEXTURE_RECTANGLE_ARB: |
| 340 external_resources.type = VideoFrameExternalResources::IO_SURFACE; | 352 external_resources.type = VideoFrameExternalResources::IO_SURFACE; |
| 341 break; | 353 break; |
| 342 default: | 354 default: |
| 343 NOTREACHED(); | 355 NOTREACHED(); |
| 344 return VideoFrameExternalResources(); | 356 return VideoFrameExternalResources(); |
| 345 } | 357 } |
| 346 | 358 |
| 347 external_resources.hardware_resource = | 359 scoped_refptr<media::VideoFrame::MailboxHolder> mailbox_holder = |
| 348 resource_provider_->CreateResourceFromExternalTexture( | 360 video_frame->texture_mailbox(); |
| 349 video_frame->texture_target(), | |
| 350 video_frame->texture_id()); | |
| 351 if (external_resources.hardware_resource) | |
| 352 all_resources_.push_back(external_resources.hardware_resource); | |
| 353 | 361 |
| 354 TextureMailbox::ReleaseCallback callback_to_return_resource = | 362 TextureMailbox::ReleaseCallback callback_to_return_resource = |
| 355 base::Bind(&ReturnTexture, | 363 base::Bind(&ReturnTexture, mailbox_holder); |
| 356 AsWeakPtr(), | 364 |
| 357 external_resources.hardware_resource); | 365 external_resources.mailboxes.push_back( |
| 358 external_resources.hardware_release_callback = callback_to_return_resource; | 366 TextureMailbox(mailbox_holder->mailbox(), |
| 367 callback_to_return_resource, |
| 368 video_frame->texture_target(), |
| 369 mailbox_holder->sync_point())); |
| 359 return external_resources; | 370 return external_resources; |
| 360 } | 371 } |
| 361 | 372 |
| 362 // static | 373 // static |
| 363 void VideoResourceUpdater::ReturnTexture( | |
| 364 base::WeakPtr<VideoResourceUpdater> updater, | |
| 365 unsigned resource_id, | |
| 366 unsigned sync_point, | |
| 367 bool lost_resource) { | |
| 368 if (!updater.get()) { | |
| 369 // Resource was already deleted. | |
| 370 return; | |
| 371 } | |
| 372 | |
| 373 updater->DeleteResource(resource_id); | |
| 374 } | |
| 375 | |
| 376 // static | |
| 377 void VideoResourceUpdater::RecycleResource( | 374 void VideoResourceUpdater::RecycleResource( |
| 378 base::WeakPtr<VideoResourceUpdater> updater, | 375 base::WeakPtr<VideoResourceUpdater> updater, |
| 379 RecycleResourceData data, | 376 RecycleResourceData data, |
| 380 unsigned sync_point, | 377 unsigned sync_point, |
| 381 bool lost_resource) { | 378 bool lost_resource) { |
| 382 if (!updater.get()) { | 379 if (!updater.get()) { |
| 383 // Resource was already deleted. | 380 // Resource was already deleted. |
| 384 return; | 381 return; |
| 385 } | 382 } |
| 386 | 383 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 411 } | 408 } |
| 412 | 409 |
| 413 PlaneResource recycled_resource(data.resource_id, | 410 PlaneResource recycled_resource(data.resource_id, |
| 414 data.resource_size, | 411 data.resource_size, |
| 415 data.resource_format, | 412 data.resource_format, |
| 416 sync_point); | 413 sync_point); |
| 417 updater->recycled_resources_.push_back(recycled_resource); | 414 updater->recycled_resources_.push_back(recycled_resource); |
| 418 } | 415 } |
| 419 | 416 |
| 420 } // namespace cc | 417 } // namespace cc |
| OLD | NEW |