Chromium Code Reviews| 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 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, | 359 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
| 360 GL_COLOR_ATTACHMENT0, | 360 GL_COLOR_ATTACHMENT0, |
| 361 GL_TEXTURE_2D, | 361 GL_TEXTURE_2D, |
| 362 thumbnails_texture_id_, | 362 thumbnails_texture_id_, |
| 363 0); | 363 0); |
| 364 | 364 |
| 365 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 365 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| 366 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; | 366 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; |
| 367 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | 367 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| 368 glClear(GL_COLOR_BUFFER_BIT); | 368 glClear(GL_COLOR_BUFFER_BIT); |
| 369 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | 369 glBindFramebufferEXT(GL_FRAMEBUFFER, |
| 370 gl_surface_->GetBackingFrameBufferObject()); | |
| 370 } | 371 } |
| 371 | 372 |
| 372 // 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 |
| 373 // 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 |
| 374 // 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 |
| 375 // 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. |
| 376 // 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 |
| 377 // 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. |
| 378 static const float kVertices[] = | 379 static const float kVertices[] = |
| 379 { -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 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 565 const int thumbnails_in_column = thumbnails_fbo_size_.height() / height; | 566 const int thumbnails_in_column = thumbnails_fbo_size_.height() / height; |
| 566 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column; | 567 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column; |
| 567 const int col = frame_count_ % thumbnails_in_row; | 568 const int col = frame_count_ % thumbnails_in_row; |
| 568 | 569 |
| 569 gfx::Rect area(col * width, row * height, width, height); | 570 gfx::Rect area(col * width, row * height, width, height); |
| 570 | 571 |
| 571 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); | 572 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); |
| 572 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); | 573 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); |
| 573 GLSetViewPort(area); | 574 GLSetViewPort(area); |
| 574 RenderTexture(texture_target, texture_id); | 575 RenderTexture(texture_target, texture_id); |
| 575 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | 576 glBindFramebufferEXT(GL_FRAMEBUFFER, |
| 577 gl_surface_->GetBackingFrameBufferObject()); | |
| 576 | 578 |
| 577 // 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 |
| 578 // the decoder. | 580 // the decoder. |
| 579 glFlush(); | 581 glFlush(); |
| 580 ++frame_count_; | 582 ++frame_count_; |
| 581 } | 583 } |
| 582 | 584 |
| 583 void RenderingHelper::QueueVideoFrame( | 585 void RenderingHelper::QueueVideoFrame( |
| 584 size_t window_id, | 586 size_t window_id, |
| 585 scoped_refptr<VideoFrameTexture> video_frame) { | 587 scoped_refptr<VideoFrameTexture> video_frame) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 656 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); | 658 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); |
| 657 glPixelStorei(GL_PACK_ALIGNMENT, 1); | 659 glPixelStorei(GL_PACK_ALIGNMENT, 1); |
| 658 // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support. | 660 // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support. |
| 659 glReadPixels(0, | 661 glReadPixels(0, |
| 660 0, | 662 0, |
| 661 thumbnails_fbo_size_.width(), | 663 thumbnails_fbo_size_.width(), |
| 662 thumbnails_fbo_size_.height(), | 664 thumbnails_fbo_size_.height(), |
| 663 GL_RGBA, | 665 GL_RGBA, |
| 664 GL_UNSIGNED_BYTE, | 666 GL_UNSIGNED_BYTE, |
| 665 &rgba[0]); | 667 &rgba[0]); |
| 666 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | 668 glBindFramebufferEXT(GL_FRAMEBUFFER, |
| 669 gl_surface_->GetBackingFrameBufferObject()); | |
| 667 rgb->resize(num_pixels * 3); | 670 rgb->resize(num_pixels * 3); |
| 668 // 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. |
| 669 bool solid = true; | 672 bool solid = true; |
| 670 unsigned char* rgb_ptr = &((*rgb)[0]); | 673 unsigned char* rgb_ptr = &((*rgb)[0]); |
| 671 unsigned char* rgba_ptr = &rgba[0]; | 674 unsigned char* rgba_ptr = &rgba[0]; |
| 672 for (size_t i = 0; i < num_pixels; ++i) { | 675 for (size_t i = 0; i < num_pixels; ++i) { |
| 673 *rgb_ptr++ = *rgba_ptr++; | 676 *rgb_ptr++ = *rgba_ptr++; |
| 674 *rgb_ptr++ = *rgba_ptr++; | 677 *rgb_ptr++ = *rgba_ptr++; |
| 675 *rgb_ptr++ = *rgba_ptr++; | 678 *rgb_ptr++ = *rgba_ptr++; |
| 676 solid = solid && (*rgba_ptr == 0xff); | 679 solid = solid && (*rgba_ptr == 0xff); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 693 // 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 |
| 694 // in VideoDecodeAcceleratorTest.TearDown(), while the |rendering_helper_| is | 697 // in VideoDecodeAcceleratorTest.TearDown(), while the |rendering_helper_| is |
| 695 // a member of that class. (See video_decode_accelerator_unittest.cc.) | 698 // a member of that class. (See video_decode_accelerator_unittest.cc.) |
| 696 gfx::VSyncProvider* vsync_provider = gl_surface_->GetVSyncProvider(); | 699 gfx::VSyncProvider* vsync_provider = gl_surface_->GetVSyncProvider(); |
| 697 if (vsync_provider) { | 700 if (vsync_provider) { |
| 698 vsync_provider->GetVSyncParameters(base::Bind( | 701 vsync_provider->GetVSyncParameters(base::Bind( |
| 699 &RenderingHelper::UpdateVSyncParameters, base::Unretained(this), | 702 &RenderingHelper::UpdateVSyncParameters, base::Unretained(this), |
| 700 static_cast<base::WaitableEvent*>(NULL))); | 703 static_cast<base::WaitableEvent*>(NULL))); |
| 701 } | 704 } |
| 702 | 705 |
| 703 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); | 706 int tex_flip = 1; |
| 707 #if 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; | |
|
spang
2015/02/19 00:49:26
What if it's not surfaceless?
achaulk
2015/02/19 00:54:50
Hmm, I could add a property to GLSurface to indica
| |
| 711 #endif | |
| 712 glUniform1i(glGetUniformLocation(program_, "tex_flip"), tex_flip); | |
| 704 | 713 |
| 705 // 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) |
| 706 // 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 |
| 707 // to keep references to them until after SwapBuffers() call below. | 716 // to keep references to them until after SwapBuffers() call below. |
| 708 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; | 717 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; |
| 709 bool need_swap_buffer = false; | 718 bool need_swap_buffer = false; |
| 710 if (render_as_thumbnails_) { | 719 if (render_as_thumbnails_) { |
| 711 // 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 |
| 712 // screen instead of the decoded textures. | 721 // screen instead of the decoded textures. |
| 713 GLSetViewPort(videos_[0].render_area); | 722 GLSetViewPort(videos_[0].render_area); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 833 // When the rendering falls behind, drops frames. | 842 // When the rendering falls behind, drops frames. |
| 834 while (scheduled_render_time_ < target) { | 843 while (scheduled_render_time_ < target) { |
| 835 scheduled_render_time_ += frame_duration_; | 844 scheduled_render_time_ += frame_duration_; |
| 836 DropOneFrameForAllVideos(); | 845 DropOneFrameForAllVideos(); |
| 837 } | 846 } |
| 838 | 847 |
| 839 message_loop_->PostDelayedTask( | 848 message_loop_->PostDelayedTask( |
| 840 FROM_HERE, render_task_.callback(), target - now); | 849 FROM_HERE, render_task_.callback(), target - now); |
| 841 } | 850 } |
| 842 } // namespace content | 851 } // namespace content |
| OLD | NEW |