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 "content/common/gpu/media/rendering_helper.h" | 5 #include "content/common/gpu/media/rendering_helper.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <numeric> | 8 #include <numeric> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 base::Bind(&RenderingHelper::RenderContent, base::Unretained(this))); | 306 base::Bind(&RenderingHelper::RenderContent, base::Unretained(this))); |
307 | 307 |
308 frame_duration_ = params.rendering_fps > 0 | 308 frame_duration_ = params.rendering_fps > 0 |
309 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps | 309 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps |
310 : base::TimeDelta(); | 310 : base::TimeDelta(); |
311 | 311 |
312 render_as_thumbnails_ = params.render_as_thumbnails; | 312 render_as_thumbnails_ = params.render_as_thumbnails; |
313 message_loop_ = base::MessageLoop::current(); | 313 message_loop_ = base::MessageLoop::current(); |
314 | 314 |
315 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); | 315 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); |
| 316 #if defined(USE_OZONE) |
| 317 gl_surface_->Resize(platform_window_delegate_->GetSize()); |
| 318 #endif // defined(USE_OZONE) |
316 screen_size_ = gl_surface_->GetSize(); | 319 screen_size_ = gl_surface_->GetSize(); |
317 | 320 |
318 gl_context_ = gfx::GLContext::CreateGLContext( | 321 gl_context_ = gfx::GLContext::CreateGLContext( |
319 NULL, gl_surface_.get(), gfx::PreferIntegratedGpu); | 322 NULL, gl_surface_.get(), gfx::PreferIntegratedGpu); |
320 CHECK(gl_context_->MakeCurrent(gl_surface_.get())); | 323 CHECK(gl_context_->MakeCurrent(gl_surface_.get())); |
321 | 324 |
322 CHECK_GT(params.window_sizes.size(), 0U); | 325 CHECK_GT(params.window_sizes.size(), 0U); |
323 videos_.resize(params.window_sizes.size()); | 326 videos_.resize(params.window_sizes.size()); |
324 LayoutRenderingAreas(params.window_sizes); | 327 LayoutRenderingAreas(params.window_sizes); |
325 | 328 |
(...skipping 30 matching lines...) Expand all Loading... |
356 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, | 359 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
357 GL_COLOR_ATTACHMENT0, | 360 GL_COLOR_ATTACHMENT0, |
358 GL_TEXTURE_2D, | 361 GL_TEXTURE_2D, |
359 thumbnails_texture_id_, | 362 thumbnails_texture_id_, |
360 0); | 363 0); |
361 | 364 |
362 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 365 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
363 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; | 366 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; |
364 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | 367 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
365 glClear(GL_COLOR_BUFFER_BIT); | 368 glClear(GL_COLOR_BUFFER_BIT); |
366 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | 369 glBindFramebufferEXT(GL_FRAMEBUFFER, |
| 370 gl_surface_->GetBackingFrameBufferObject()); |
367 } | 371 } |
368 | 372 |
369 // These vertices and texture coords. map (0,0) in the texture to the | 373 // These vertices and texture coords. map (0,0) in the texture to the |
370 // bottom left of the viewport. Since we get the video frames with the | 374 // bottom left of the viewport. Since we get the video frames with the |
371 // the top left at (0,0) we need to flip the texture y coordinate | 375 // the top left at (0,0) we need to flip the texture y coordinate |
372 // in the vertex shader for this to be rendered the right way up. | 376 // in the vertex shader for this to be rendered the right way up. |
373 // In the case of thumbnail rendering we use the same vertex shader | 377 // In the case of thumbnail rendering we use the same vertex shader |
374 // to render the FBO the screen, where we do not want this flipping. | 378 // to render the FBO the screen, where we do not want this flipping. |
375 static const float kVertices[] = | 379 static const float kVertices[] = |
376 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, }; | 380 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, }; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { | 500 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { |
497 CHECK_EQ(base::MessageLoop::current(), message_loop_); | 501 CHECK_EQ(base::MessageLoop::current(), message_loop_); |
498 | 502 |
499 render_task_.Cancel(); | 503 render_task_.Cancel(); |
500 | 504 |
501 if (render_as_thumbnails_) { | 505 if (render_as_thumbnails_) { |
502 glDeleteTextures(1, &thumbnails_texture_id_); | 506 glDeleteTextures(1, &thumbnails_texture_id_); |
503 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); | 507 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); |
504 } | 508 } |
505 | 509 |
| 510 gl_surface_->Destroy(); |
506 gl_context_->ReleaseCurrent(gl_surface_.get()); | 511 gl_context_->ReleaseCurrent(gl_surface_.get()); |
507 gl_context_ = NULL; | 512 gl_context_ = NULL; |
508 gl_surface_ = NULL; | 513 gl_surface_ = NULL; |
509 | 514 |
510 Clear(); | 515 Clear(); |
511 done->Signal(); | 516 done->Signal(); |
512 } | 517 } |
513 | 518 |
514 void RenderingHelper::CreateTexture(uint32 texture_target, | 519 void RenderingHelper::CreateTexture(uint32 texture_target, |
515 uint32* texture_id, | 520 uint32* texture_id, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 const int thumbnails_in_column = thumbnails_fbo_size_.height() / height; | 567 const int thumbnails_in_column = thumbnails_fbo_size_.height() / height; |
563 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column; | 568 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column; |
564 const int col = frame_count_ % thumbnails_in_row; | 569 const int col = frame_count_ % thumbnails_in_row; |
565 | 570 |
566 gfx::Rect area(col * width, row * height, width, height); | 571 gfx::Rect area(col * width, row * height, width, height); |
567 | 572 |
568 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); | 573 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); |
569 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); | 574 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); |
570 GLSetViewPort(area); | 575 GLSetViewPort(area); |
571 RenderTexture(texture_target, texture_id); | 576 RenderTexture(texture_target, texture_id); |
572 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | 577 glBindFramebufferEXT(GL_FRAMEBUFFER, |
| 578 gl_surface_->GetBackingFrameBufferObject()); |
573 | 579 |
574 // Need to flush the GL commands before we return the tnumbnail texture to | 580 // Need to flush the GL commands before we return the tnumbnail texture to |
575 // the decoder. | 581 // the decoder. |
576 glFlush(); | 582 glFlush(); |
577 ++frame_count_; | 583 ++frame_count_; |
578 } | 584 } |
579 | 585 |
580 void RenderingHelper::QueueVideoFrame( | 586 void RenderingHelper::QueueVideoFrame( |
581 size_t window_id, | 587 size_t window_id, |
582 scoped_refptr<VideoFrameTexture> video_frame) { | 588 scoped_refptr<VideoFrameTexture> video_frame) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); | 659 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); |
654 glPixelStorei(GL_PACK_ALIGNMENT, 1); | 660 glPixelStorei(GL_PACK_ALIGNMENT, 1); |
655 // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support. | 661 // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support. |
656 glReadPixels(0, | 662 glReadPixels(0, |
657 0, | 663 0, |
658 thumbnails_fbo_size_.width(), | 664 thumbnails_fbo_size_.width(), |
659 thumbnails_fbo_size_.height(), | 665 thumbnails_fbo_size_.height(), |
660 GL_RGBA, | 666 GL_RGBA, |
661 GL_UNSIGNED_BYTE, | 667 GL_UNSIGNED_BYTE, |
662 &rgba[0]); | 668 &rgba[0]); |
663 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | 669 glBindFramebufferEXT(GL_FRAMEBUFFER, |
| 670 gl_surface_->GetBackingFrameBufferObject()); |
664 rgb->resize(num_pixels * 3); | 671 rgb->resize(num_pixels * 3); |
665 // Drop the alpha channel, but check as we go that it is all 0xff. | 672 // Drop the alpha channel, but check as we go that it is all 0xff. |
666 bool solid = true; | 673 bool solid = true; |
667 unsigned char* rgb_ptr = &((*rgb)[0]); | 674 unsigned char* rgb_ptr = &((*rgb)[0]); |
668 unsigned char* rgba_ptr = &rgba[0]; | 675 unsigned char* rgba_ptr = &rgba[0]; |
669 for (size_t i = 0; i < num_pixels; ++i) { | 676 for (size_t i = 0; i < num_pixels; ++i) { |
670 *rgb_ptr++ = *rgba_ptr++; | 677 *rgb_ptr++ = *rgba_ptr++; |
671 *rgb_ptr++ = *rgba_ptr++; | 678 *rgb_ptr++ = *rgba_ptr++; |
672 *rgb_ptr++ = *rgba_ptr++; | 679 *rgb_ptr++ = *rgba_ptr++; |
673 solid = solid && (*rgba_ptr == 0xff); | 680 solid = solid && (*rgba_ptr == 0xff); |
(...skipping 16 matching lines...) Expand all Loading... |
690 // It's safe to use Unretained here since |rendering_thread_| will be stopped | 697 // It's safe to use Unretained here since |rendering_thread_| will be stopped |
691 // in VideoDecodeAcceleratorTest.TearDown(), while the |rendering_helper_| is | 698 // in VideoDecodeAcceleratorTest.TearDown(), while the |rendering_helper_| is |
692 // a member of that class. (See video_decode_accelerator_unittest.cc.) | 699 // a member of that class. (See video_decode_accelerator_unittest.cc.) |
693 gfx::VSyncProvider* vsync_provider = gl_surface_->GetVSyncProvider(); | 700 gfx::VSyncProvider* vsync_provider = gl_surface_->GetVSyncProvider(); |
694 if (vsync_provider) { | 701 if (vsync_provider) { |
695 vsync_provider->GetVSyncParameters(base::Bind( | 702 vsync_provider->GetVSyncParameters(base::Bind( |
696 &RenderingHelper::UpdateVSyncParameters, base::Unretained(this), | 703 &RenderingHelper::UpdateVSyncParameters, base::Unretained(this), |
697 static_cast<base::WaitableEvent*>(NULL))); | 704 static_cast<base::WaitableEvent*>(NULL))); |
698 } | 705 } |
699 | 706 |
700 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); | 707 int tex_flip = 1; |
| 708 #if defined(USE_OZONE) |
| 709 // Ozone surfaceless renders flipped from normal GL, so there's no need to |
| 710 // do an extra flip. |
| 711 tex_flip = 0; |
| 712 #endif // defined(USE_OZONE) |
| 713 glUniform1i(glGetUniformLocation(program_, "tex_flip"), tex_flip); |
701 | 714 |
702 // Frames that will be returned to the client (via the no_longer_needed_cb) | 715 // Frames that will be returned to the client (via the no_longer_needed_cb) |
703 // after this vector falls out of scope at the end of this method. We need | 716 // after this vector falls out of scope at the end of this method. We need |
704 // to keep references to them until after SwapBuffers() call below. | 717 // to keep references to them until after SwapBuffers() call below. |
705 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; | 718 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; |
706 bool need_swap_buffer = false; | 719 bool need_swap_buffer = false; |
707 if (render_as_thumbnails_) { | 720 if (render_as_thumbnails_) { |
708 // In render_as_thumbnails_ mode, we render the FBO content on the | 721 // In render_as_thumbnails_ mode, we render the FBO content on the |
709 // screen instead of the decoded textures. | 722 // screen instead of the decoded textures. |
710 GLSetViewPort(videos_[0].render_area); | 723 GLSetViewPort(videos_[0].render_area); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 // When the rendering falls behind, drops frames. | 843 // When the rendering falls behind, drops frames. |
831 while (scheduled_render_time_ < target) { | 844 while (scheduled_render_time_ < target) { |
832 scheduled_render_time_ += frame_duration_; | 845 scheduled_render_time_ += frame_duration_; |
833 DropOneFrameForAllVideos(); | 846 DropOneFrameForAllVideos(); |
834 } | 847 } |
835 | 848 |
836 message_loop_->PostDelayedTask( | 849 message_loop_->PostDelayedTask( |
837 FROM_HERE, render_task_.callback(), target - now); | 850 FROM_HERE, render_task_.callback(), target - now); |
838 } | 851 } |
839 } // namespace content | 852 } // namespace content |
OLD | NEW |