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