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