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" |
(...skipping 16 matching lines...) Expand all Loading... | |
27 : resource_provider_(resource_provider) { | 27 : resource_provider_(resource_provider) { |
28 } | 28 } |
29 | 29 |
30 VideoResourceUpdater::~VideoResourceUpdater() { | 30 VideoResourceUpdater::~VideoResourceUpdater() { |
31 while (!recycled_resources_.empty()) { | 31 while (!recycled_resources_.empty()) { |
32 resource_provider_->DeleteResource(recycled_resources_.back().resource_id); | 32 resource_provider_->DeleteResource(recycled_resources_.back().resource_id); |
33 recycled_resources_.pop_back(); | 33 recycled_resources_.pop_back(); |
34 } | 34 } |
35 } | 35 } |
36 | 36 |
37 VideoFrameExternalResources VideoResourceUpdater:: | |
38 CreateExternalResourcesFromVideoFrame( | |
39 const scoped_refptr<media::VideoFrame>& video_frame) { | |
40 if (!VerifyFrame(video_frame)) | |
41 return VideoFrameExternalResources(); | |
42 | |
43 if (video_frame->format() == media::VideoFrame::NATIVE_TEXTURE) | |
44 return CreateForHardwarePlanes(video_frame); | |
45 else | |
46 return CreateForSoftwarePlanes(video_frame); | |
47 } | |
48 | |
37 bool VideoResourceUpdater::VerifyFrame( | 49 bool VideoResourceUpdater::VerifyFrame( |
38 const scoped_refptr<media::VideoFrame>& video_frame) { | 50 const scoped_refptr<media::VideoFrame>& video_frame) { |
39 // If these fail, we'll have to add logic that handles offset bitmap/texture | 51 // If these fail, we'll have to add logic that handles offset bitmap/texture |
40 // UVs. For now, just expect (0, 0) offset, since all our decoders so far | 52 // UVs. For now, just expect (0, 0) offset, since all our decoders so far |
41 // don't offset. | 53 // don't offset. |
42 DCHECK_EQ(video_frame->visible_rect().x(), 0); | 54 DCHECK_EQ(video_frame->visible_rect().x(), 0); |
43 DCHECK_EQ(video_frame->visible_rect().y(), 0); | 55 DCHECK_EQ(video_frame->visible_rect().y(), 0); |
44 | 56 |
45 switch (video_frame->format()) { | 57 switch (video_frame->format()) { |
46 // Acceptable inputs. | 58 // Acceptable inputs. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 NOTREACHED(); | 102 NOTREACHED(); |
91 } | 103 } |
92 } | 104 } |
93 | 105 |
94 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat)); | 106 DCHECK_EQ(output_resource_format, static_cast<unsigned>(kRGBResourceFormat)); |
95 return coded_size; | 107 return coded_size; |
96 } | 108 } |
97 | 109 |
98 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( | 110 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( |
99 const scoped_refptr<media::VideoFrame>& video_frame) { | 111 const scoped_refptr<media::VideoFrame>& video_frame) { |
100 if (!VerifyFrame(video_frame)) | |
101 return VideoFrameExternalResources(); | |
102 | |
103 media::VideoFrame::Format input_frame_format = video_frame->format(); | 112 media::VideoFrame::Format input_frame_format = video_frame->format(); |
104 | 113 |
105 #if defined(GOOGLE_TV) | 114 #if defined(GOOGLE_TV) |
106 if (input_frame_format == media::VideoFrame::HOLE) { | 115 if (input_frame_format == media::VideoFrame::HOLE) { |
107 VideoFrameExternalResources external_resources; | 116 VideoFrameExternalResources external_resources; |
108 external_resources.type = VideoFrameExternalResources::HOLE; | 117 external_resources.type = VideoFrameExternalResources::HOLE; |
109 return external_resources; | 118 return external_resources; |
110 } | 119 } |
111 #endif | 120 #endif |
112 | 121 |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 TextureMailbox(mailbox, | 291 TextureMailbox(mailbox, |
283 callback_to_free_resource, | 292 callback_to_free_resource, |
284 plane_resources[i].sync_point)); | 293 plane_resources[i].sync_point)); |
285 } | 294 } |
286 | 295 |
287 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; | 296 external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; |
288 return external_resources; | 297 return external_resources; |
289 } | 298 } |
290 | 299 |
291 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( | 300 VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( |
292 const scoped_refptr<media::VideoFrame>& video_frame, | 301 const scoped_refptr<media::VideoFrame>& video_frame) { |
293 const TextureMailbox::ReleaseCallback& release_callback) { | |
294 if (!VerifyFrame(video_frame)) | |
295 return VideoFrameExternalResources(); | |
296 | |
297 media::VideoFrame::Format frame_format = video_frame->format(); | 302 media::VideoFrame::Format frame_format = video_frame->format(); |
298 | 303 |
299 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE); | 304 DCHECK_EQ(frame_format, media::VideoFrame::NATIVE_TEXTURE); |
300 if (frame_format != media::VideoFrame::NATIVE_TEXTURE) | 305 if (frame_format != media::VideoFrame::NATIVE_TEXTURE) |
301 return VideoFrameExternalResources(); | 306 return VideoFrameExternalResources(); |
302 | 307 |
303 WebKit::WebGraphicsContext3D* context = | 308 WebKit::WebGraphicsContext3D* context = |
304 resource_provider_->GraphicsContext3D(); | 309 resource_provider_->GraphicsContext3D(); |
305 if (!context) | 310 if (!context) |
306 return VideoFrameExternalResources(); | 311 return VideoFrameExternalResources(); |
307 | 312 |
308 VideoFrameExternalResources external_resources; | 313 VideoFrameExternalResources external_resources; |
309 switch (video_frame->texture_target()) { | 314 switch (video_frame->texture_target()) { |
310 case GL_TEXTURE_2D: | 315 case GL_TEXTURE_2D: |
311 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE; | 316 external_resources.type = VideoFrameExternalResources::RGB_RESOURCE; |
312 break; | 317 break; |
313 case GL_TEXTURE_EXTERNAL_OES: | 318 case GL_TEXTURE_EXTERNAL_OES: |
314 external_resources.type = | 319 external_resources.type = |
315 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE; | 320 VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE; |
316 break; | 321 break; |
317 case GL_TEXTURE_RECTANGLE_ARB: | 322 case GL_TEXTURE_RECTANGLE_ARB: |
318 external_resources.type = VideoFrameExternalResources::IO_SURFACE; | 323 external_resources.type = VideoFrameExternalResources::IO_SURFACE; |
319 break; | 324 break; |
320 default: | 325 default: |
321 NOTREACHED(); | 326 NOTREACHED(); |
322 return VideoFrameExternalResources(); | 327 return VideoFrameExternalResources(); |
323 } | 328 } |
324 | 329 |
325 gpu::Mailbox mailbox; | 330 // Hold a reference to the VideoFrame in the callback, so the frame stays |
326 GLC(context, context->genMailboxCHROMIUM(mailbox.name)); | 331 // alive while the texture is in use. As long as the frame is alive, the |
327 GLC(context, context->bindTexture(GL_TEXTURE_2D, video_frame->texture_id())); | 332 // texture inside it will not be reused by the decoder. |
328 GLC(context, context->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name)); | |
329 GLC(context, context->bindTexture(GL_TEXTURE_2D, 0)); | |
330 | |
331 TextureMailbox::ReleaseCallback callback_to_return_resource = | 333 TextureMailbox::ReleaseCallback callback_to_return_resource = |
332 base::Bind(&ReturnTexture, | 334 base::Bind(&ReturnTexture, |
333 base::Unretained(resource_provider_), | 335 base::Unretained(resource_provider_), |
334 release_callback, | 336 video_frame); |
335 video_frame->texture_id(), | |
336 mailbox); | |
337 external_resources.mailboxes.push_back( | 337 external_resources.mailboxes.push_back( |
338 TextureMailbox(mailbox, callback_to_return_resource)); | 338 TextureMailbox(video_frame->texture_mailbox(), |
339 callback_to_return_resource)); | |
339 return external_resources; | 340 return external_resources; |
340 } | 341 } |
341 | 342 |
342 // static | 343 // static |
343 void VideoResourceUpdater::ReturnTexture( | 344 void VideoResourceUpdater::ReturnTexture( |
344 ResourceProvider* resource_provider, | 345 ResourceProvider* resource_provider, |
345 TextureMailbox::ReleaseCallback callback, | 346 scoped_refptr<media::VideoFrame> video_frame, |
346 unsigned texture_id, | |
347 gpu::Mailbox mailbox, | |
348 unsigned sync_point, | 347 unsigned sync_point, |
349 bool lost_resource) { | 348 bool lost_resource) { |
350 WebKit::WebGraphicsContext3D* context = | 349 if (sync_point) { |
351 resource_provider->GraphicsContext3D(); | 350 WebKit::WebGraphicsContext3D* context = |
352 GLC(context, context->bindTexture(GL_TEXTURE_2D, texture_id)); | 351 resource_provider->GraphicsContext3D(); |
353 GLC(context, context->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name)); | 352 GLC(context, context->waitSyncPoint(sync_point)); |
piman
2013/04/11 22:57:58
You need to (shallow) flush here to ensure the vid
| |
354 GLC(context, context->bindTexture(GL_TEXTURE_2D, 0)); | 353 } |
355 callback.Run(sync_point, lost_resource); | 354 |
355 // Dropping the reference to VideoFrame here releases the texture back to the | |
356 // decoder. | |
356 } | 357 } |
357 | 358 |
358 // static | 359 // static |
359 void VideoResourceUpdater::RecycleResource( | 360 void VideoResourceUpdater::RecycleResource( |
360 base::WeakPtr<VideoResourceUpdater> updater, | 361 base::WeakPtr<VideoResourceUpdater> updater, |
361 ResourceProvider* resource_provider, | 362 ResourceProvider* resource_provider, |
362 RecycleResourceData data, | 363 RecycleResourceData data, |
363 unsigned sync_point, | 364 unsigned sync_point, |
364 bool lost_resource) { | 365 bool lost_resource) { |
365 WebKit::WebGraphicsContext3D* context = | 366 WebKit::WebGraphicsContext3D* context = |
(...skipping 24 matching lines...) Expand all Loading... | |
390 } | 391 } |
391 | 392 |
392 PlaneResource recycled_resource(data.resource_id, | 393 PlaneResource recycled_resource(data.resource_id, |
393 data.resource_size, | 394 data.resource_size, |
394 data.resource_format, | 395 data.resource_format, |
395 sync_point); | 396 sync_point); |
396 updater->recycled_resources_.push_back(recycled_resource); | 397 updater->recycled_resources_.push_back(recycled_resource); |
397 } | 398 } |
398 | 399 |
399 } // namespace cc | 400 } // namespace cc |
OLD | NEW |