| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 : texture_target_(texture_target), | 67 : texture_target_(texture_target), |
| 68 texture_id_(texture_id), | 68 texture_id_(texture_id), |
| 69 no_longer_needed_cb_(no_longer_needed_cb) { | 69 no_longer_needed_cb_(no_longer_needed_cb) { |
| 70 DCHECK(!no_longer_needed_cb_.is_null()); | 70 DCHECK(!no_longer_needed_cb_.is_null()); |
| 71 } | 71 } |
| 72 | 72 |
| 73 VideoFrameTexture::~VideoFrameTexture() { | 73 VideoFrameTexture::~VideoFrameTexture() { |
| 74 base::ResetAndReturn(&no_longer_needed_cb_).Run(); | 74 base::ResetAndReturn(&no_longer_needed_cb_).Run(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 RenderingHelper::RenderedVideo::RenderedVideo() : last_frame_rendered(false) { | 77 RenderingHelper::RenderedVideo::RenderedVideo() |
| 78 : last_frame_rendered(false), is_flushing(false) { |
| 78 } | 79 } |
| 79 | 80 |
| 80 RenderingHelper::RenderedVideo::~RenderedVideo() { | 81 RenderingHelper::RenderedVideo::~RenderedVideo() { |
| 81 } | 82 } |
| 82 | 83 |
| 83 // static | 84 // static |
| 84 bool RenderingHelper::InitializeOneOff() { | 85 bool RenderingHelper::InitializeOneOff() { |
| 85 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 86 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
| 86 #if GL_VARIANT_GLX | 87 #if GL_VARIANT_GLX |
| 87 cmd_line->AppendSwitchASCII(switches::kUseGL, | 88 cmd_line->AppendSwitchASCII(switches::kUseGL, |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 // the decoder. | 389 // the decoder. |
| 389 glFlush(); | 390 glFlush(); |
| 390 ++frame_count_; | 391 ++frame_count_; |
| 391 } | 392 } |
| 392 | 393 |
| 393 void RenderingHelper::QueueVideoFrame( | 394 void RenderingHelper::QueueVideoFrame( |
| 394 size_t window_id, | 395 size_t window_id, |
| 395 scoped_refptr<VideoFrameTexture> video_frame) { | 396 scoped_refptr<VideoFrameTexture> video_frame) { |
| 396 CHECK_EQ(base::MessageLoop::current(), message_loop_); | 397 CHECK_EQ(base::MessageLoop::current(), message_loop_); |
| 397 RenderedVideo* video = &videos_[window_id]; | 398 RenderedVideo* video = &videos_[window_id]; |
| 399 DCHECK(!video->is_flushing); |
| 398 | 400 |
| 399 // Pop the last frame if it has been rendered. | 401 // Pop the last frame if it has been rendered. |
| 400 if (video->last_frame_rendered) { | 402 if (video->last_frame_rendered) { |
| 401 // When last_frame_rendered is true, we should have only one pending frame. | 403 // When last_frame_rendered is true, we should have only one pending frame. |
| 402 // Since we are going to have a new frame, we can release the pending one. | 404 // Since we are going to have a new frame, we can release the pending one. |
| 403 DCHECK(video->pending_frames.size() == 1); | 405 DCHECK(video->pending_frames.size() == 1); |
| 404 video->pending_frames.pop(); | 406 video->pending_frames.pop(); |
| 405 video->last_frame_rendered = false; | 407 video->last_frame_rendered = false; |
| 406 } | 408 } |
| 407 | 409 |
| 408 video->pending_frames.push(video_frame); | 410 video->pending_frames.push(video_frame); |
| 409 } | 411 } |
| 410 | 412 |
| 411 void RenderingHelper::DropPendingFrames(size_t window_id) { | |
| 412 CHECK_EQ(base::MessageLoop::current(), message_loop_); | |
| 413 RenderedVideo* video = &videos_[window_id]; | |
| 414 video->pending_frames = std::queue<scoped_refptr<VideoFrameTexture> >(); | |
| 415 video->last_frame_rendered = false; | |
| 416 } | |
| 417 | |
| 418 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { | 413 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { |
| 419 // The ExternalOES sampler is bound to GL_TEXTURE1 and the Texture2D sampler | 414 // The ExternalOES sampler is bound to GL_TEXTURE1 and the Texture2D sampler |
| 420 // is bound to GL_TEXTURE0. | 415 // is bound to GL_TEXTURE0. |
| 421 if (texture_target == GL_TEXTURE_2D) { | 416 if (texture_target == GL_TEXTURE_2D) { |
| 422 glActiveTexture(GL_TEXTURE0 + 0); | 417 glActiveTexture(GL_TEXTURE0 + 0); |
| 423 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) { | 418 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) { |
| 424 glActiveTexture(GL_TEXTURE0 + 1); | 419 glActiveTexture(GL_TEXTURE0 + 1); |
| 425 } | 420 } |
| 426 glBindTexture(texture_target, texture_id); | 421 glBindTexture(texture_target, texture_id); |
| 427 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 422 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 *rgb_ptr++ = *rgba_ptr++; | 491 *rgb_ptr++ = *rgba_ptr++; |
| 497 *rgb_ptr++ = *rgba_ptr++; | 492 *rgb_ptr++ = *rgba_ptr++; |
| 498 solid = solid && (*rgba_ptr == 0xff); | 493 solid = solid && (*rgba_ptr == 0xff); |
| 499 rgba_ptr++; | 494 rgba_ptr++; |
| 500 } | 495 } |
| 501 *alpha_solid = solid; | 496 *alpha_solid = solid; |
| 502 | 497 |
| 503 done->Signal(); | 498 done->Signal(); |
| 504 } | 499 } |
| 505 | 500 |
| 501 void RenderingHelper::Flush(size_t window_id) { |
| 502 videos_[window_id].is_flushing = true; |
| 503 } |
| 504 |
| 506 void RenderingHelper::RenderContent() { | 505 void RenderingHelper::RenderContent() { |
| 507 CHECK_EQ(base::MessageLoop::current(), message_loop_); | 506 CHECK_EQ(base::MessageLoop::current(), message_loop_); |
| 508 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); | 507 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); |
| 509 | 508 |
| 510 // Frames that will be returned to the client (via the no_longer_needed_cb) | 509 // Frames that will be returned to the client (via the no_longer_needed_cb) |
| 511 // after this vector falls out of scope at the end of this method. We need | 510 // after this vector falls out of scope at the end of this method. We need |
| 512 // to keep references to them until after SwapBuffers() call below. | 511 // to keep references to them until after SwapBuffers() call below. |
| 513 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; | 512 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; |
| 514 | 513 |
| 515 if (render_as_thumbnails_) { | 514 if (render_as_thumbnails_) { |
| 516 // In render_as_thumbnails_ mode, we render the FBO content on the | 515 // In render_as_thumbnails_ mode, we render the FBO content on the |
| 517 // screen instead of the decoded textures. | 516 // screen instead of the decoded textures. |
| 518 GLSetViewPort(videos_[0].render_area); | 517 GLSetViewPort(videos_[0].render_area); |
| 519 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); | 518 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); |
| 520 } else { | 519 } else { |
| 521 for (size_t i = 0; i < videos_.size(); ++i) { | 520 for (size_t i = 0; i < videos_.size(); ++i) { |
| 522 RenderedVideo* video = &videos_[i]; | 521 RenderedVideo* video = &videos_[i]; |
| 523 if (video->pending_frames.empty()) | 522 if (video->pending_frames.empty()) |
| 524 continue; | 523 continue; |
| 525 scoped_refptr<VideoFrameTexture> frame = video->pending_frames.front(); | 524 scoped_refptr<VideoFrameTexture> frame = video->pending_frames.front(); |
| 526 GLSetViewPort(video->render_area); | 525 GLSetViewPort(video->render_area); |
| 527 RenderTexture(frame->texture_target(), frame->texture_id()); | 526 RenderTexture(frame->texture_target(), frame->texture_id()); |
| 528 | 527 |
| 529 if (video->pending_frames.size() > 1) { | 528 if (video->pending_frames.size() > 1 || video->is_flushing) { |
| 530 frames_to_be_returned.push_back(video->pending_frames.front()); | 529 frames_to_be_returned.push_back(video->pending_frames.front()); |
| 531 video->pending_frames.pop(); | 530 video->pending_frames.pop(); |
| 531 video->last_frame_rendered = false; |
| 532 } else { | 532 } else { |
| 533 video->last_frame_rendered = true; | 533 video->last_frame_rendered = true; |
| 534 } | 534 } |
| 535 } | 535 } |
| 536 } | 536 } |
| 537 | 537 |
| 538 gl_surface_->SwapBuffers(); | 538 gl_surface_->SwapBuffers(); |
| 539 } | 539 } |
| 540 | 540 |
| 541 // Helper function for the LayoutRenderingAreas(). The |lengths| are the | 541 // Helper function for the LayoutRenderingAreas(). The |lengths| are the |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 scale = std::min(1.0f, scale); | 585 scale = std::min(1.0f, scale); |
| 586 | 586 |
| 587 size_t w = scale * size.width(); | 587 size_t w = scale * size.width(); |
| 588 size_t h = scale * size.height(); | 588 size_t h = scale * size.height(); |
| 589 size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; | 589 size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; |
| 590 size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; | 590 size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; |
| 591 videos_[i].render_area = gfx::Rect(x, y, w, h); | 591 videos_[i].render_area = gfx::Rect(x, y, w, h); |
| 592 } | 592 } |
| 593 } | 593 } |
| 594 } // namespace content | 594 } // namespace content |
| OLD | NEW |