diff options
author | Torne (Richard Coles) <torne@google.com> | 2014-08-28 12:05:23 +0100 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2014-08-28 12:05:23 +0100 |
commit | 03b57e008b61dfcb1fbad3aea950ae0e001748b0 (patch) | |
tree | 9a740c1a5fbe659ec83484b67cbc679332f5a408 /content/common/gpu/media/rendering_helper.cc | |
parent | ca7d0c81aa30d24514c34c963f43cd24da34a2bf (diff) | |
download | chromium_org-03b57e008b61dfcb1fbad3aea950ae0e001748b0.tar.gz |
Merge from Chromium at DEPS revision 291560
This commit was generated by merge_to_master.py.
Change-Id: Ic58269055810d51286b4109e59b90b6856887a30
Diffstat (limited to 'content/common/gpu/media/rendering_helper.cc')
-rw-r--r-- | content/common/gpu/media/rendering_helper.cc | 118 |
1 files changed, 89 insertions, 29 deletions
diff --git a/content/common/gpu/media/rendering_helper.cc b/content/common/gpu/media/rendering_helper.cc index 7ee940148d..ce2f94b16d 100644 --- a/content/common/gpu/media/rendering_helper.cc +++ b/content/common/gpu/media/rendering_helper.cc @@ -9,6 +9,7 @@ #include <vector> #include "base/bind.h" +#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/mac/scoped_nsautorelease_pool.h" #include "base/message_loop/message_loop.h" @@ -60,6 +61,25 @@ RenderingHelperParams::RenderingHelperParams() {} RenderingHelperParams::~RenderingHelperParams() {} +VideoFrameTexture::VideoFrameTexture(uint32 texture_target, + uint32 texture_id, + const base::Closure& no_longer_needed_cb) + : texture_target_(texture_target), + texture_id_(texture_id), + no_longer_needed_cb_(no_longer_needed_cb) { + DCHECK(!no_longer_needed_cb_.is_null()); +} + +VideoFrameTexture::~VideoFrameTexture() { + base::ResetAndReturn(&no_longer_needed_cb_).Run(); +} + +RenderingHelper::RenderedVideo::RenderedVideo() : last_frame_rendered(false) { +} + +RenderingHelper::RenderedVideo::~RenderedVideo() { +} + // static bool RenderingHelper::InitializeOneOff() { base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); @@ -78,15 +98,15 @@ RenderingHelper::RenderingHelper() { } RenderingHelper::~RenderingHelper() { - CHECK_EQ(clients_.size(), 0U) << "Must call UnInitialize before dtor."; + CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor."; Clear(); } void RenderingHelper::Initialize(const RenderingHelperParams& params, base::WaitableEvent* done) { - // Use cients_.size() != 0 as a proxy for the class having already been + // Use videos_.size() != 0 as a proxy for the class having already been // Initialize()'d, and UnInitialize() before continuing. - if (clients_.size()) { + if (videos_.size()) { base::WaitableEvent done(false, false); UnInitialize(&done); done.Wait(); @@ -153,12 +173,12 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, NULL, gl_surface_, gfx::PreferIntegratedGpu); gl_context_->MakeCurrent(gl_surface_); - clients_ = params.clients; - CHECK_GT(clients_.size(), 0U); - LayoutRenderingAreas(); + CHECK_GT(params.window_sizes.size(), 0U); + videos_.resize(params.window_sizes.size()); + LayoutRenderingAreas(params.window_sizes); if (render_as_thumbnails_) { - CHECK_EQ(clients_.size(), 1U); + CHECK_EQ(videos_.size(), 1U); GLint max_texture_size; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); @@ -370,6 +390,31 @@ void RenderingHelper::RenderThumbnail(uint32 texture_target, ++frame_count_; } +void RenderingHelper::QueueVideoFrame( + size_t window_id, + scoped_refptr<VideoFrameTexture> video_frame) { + CHECK_EQ(base::MessageLoop::current(), message_loop_); + RenderedVideo* video = &videos_[window_id]; + + // Pop the last frame if it has been rendered. + if (video->last_frame_rendered) { + // When last_frame_rendered is true, we should have only one pending frame. + // Since we are going to have a new frame, we can release the pending one. + DCHECK(video->pending_frames.size() == 1); + video->pending_frames.pop(); + video->last_frame_rendered = false; + } + + video->pending_frames.push(video_frame); +} + +void RenderingHelper::DropPendingFrames(size_t window_id) { + CHECK_EQ(base::MessageLoop::current(), message_loop_); + RenderedVideo* video = &videos_[window_id]; + video->pending_frames = std::queue<scoped_refptr<VideoFrameTexture> >(); + video->last_frame_rendered = false; +} + void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { // The ExternalOES sampler is bound to GL_TEXTURE1 and the Texture2D sampler // is bound to GL_TEXTURE0. @@ -385,6 +430,7 @@ void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { } void RenderingHelper::DeleteTexture(uint32 texture_id) { + CHECK_EQ(base::MessageLoop::current(), message_loop_); glDeleteTextures(1, &texture_id); CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); } @@ -398,7 +444,7 @@ void* RenderingHelper::GetGLDisplay() { } void RenderingHelper::Clear() { - clients_.clear(); + videos_.clear(); message_loop_ = NULL; gl_context_ = NULL; gl_surface_ = NULL; @@ -461,16 +507,30 @@ void RenderingHelper::RenderContent() { CHECK_EQ(base::MessageLoop::current(), message_loop_); glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); + // Frames that will be returned to the client (via the no_longer_needed_cb) + // after this vector falls out of scope at the end of this method. We need + // to keep references to them until after SwapBuffers() call below. + std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; + if (render_as_thumbnails_) { // In render_as_thumbnails_ mode, we render the FBO content on the // screen instead of the decoded textures. - GLSetViewPort(render_areas_[0]); + GLSetViewPort(videos_[0].render_area); RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); } else { - for (size_t i = 0; i < clients_.size(); ++i) { - if (clients_[i]) { - GLSetViewPort(render_areas_[i]); - clients_[i]->RenderContent(this); + for (size_t i = 0; i < videos_.size(); ++i) { + RenderedVideo* video = &videos_[i]; + if (video->pending_frames.empty()) + continue; + scoped_refptr<VideoFrameTexture> frame = video->pending_frames.front(); + GLSetViewPort(video->render_area); + RenderTexture(frame->texture_target(), frame->texture_id()); + + if (video->pending_frames.size() > 1) { + frames_to_be_returned.push_back(video->pending_frames.front()); + video->pending_frames.pop(); + } else { + video->last_frame_rendered = true; } } } @@ -492,11 +552,12 @@ static void ScaleAndCalculateOffsets(std::vector<int>* lengths, } } -void RenderingHelper::LayoutRenderingAreas() { +void RenderingHelper::LayoutRenderingAreas( + const std::vector<gfx::Size>& window_sizes) { // Find the number of colums and rows. - // The smallest n * n or n * (n + 1) > number of clients. - size_t cols = sqrt(clients_.size() - 1) + 1; - size_t rows = (clients_.size() + cols - 1) / cols; + // The smallest n * n or n * (n + 1) > number of windows. + size_t cols = sqrt(videos_.size() - 1) + 1; + size_t rows = (videos_.size() + cols - 1) / cols; // Find the widths and heights of the grid. std::vector<int> widths(cols); @@ -504,31 +565,30 @@ void RenderingHelper::LayoutRenderingAreas() { std::vector<int> offset_x(cols); std::vector<int> offset_y(rows); - for (size_t i = 0; i < clients_.size(); ++i) { - const gfx::Size& window_size = clients_[i]->GetWindowSize(); - widths[i % cols] = std::max(widths[i % cols], window_size.width()); - heights[i / cols] = std::max(heights[i / cols], window_size.height()); + for (size_t i = 0; i < window_sizes.size(); ++i) { + const gfx::Size& size = window_sizes[i]; + widths[i % cols] = std::max(widths[i % cols], size.width()); + heights[i / cols] = std::max(heights[i / cols], size.height()); } ScaleAndCalculateOffsets(&widths, &offset_x, screen_size_.width()); ScaleAndCalculateOffsets(&heights, &offset_y, screen_size_.height()); // Put each render_area_ in the center of each cell. - render_areas_.clear(); - for (size_t i = 0; i < clients_.size(); ++i) { - const gfx::Size& window_size = clients_[i]->GetWindowSize(); + for (size_t i = 0; i < window_sizes.size(); ++i) { + const gfx::Size& size = window_sizes[i]; float scale = - std::min(static_cast<float>(widths[i % cols]) / window_size.width(), - static_cast<float>(heights[i / cols]) / window_size.height()); + std::min(static_cast<float>(widths[i % cols]) / size.width(), + static_cast<float>(heights[i / cols]) / size.height()); // Don't scale up the texture. scale = std::min(1.0f, scale); - size_t w = scale * window_size.width(); - size_t h = scale * window_size.height(); + size_t w = scale * size.width(); + size_t h = scale * size.height(); size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; - render_areas_.push_back(gfx::Rect(x, y, w, h)); + videos_[i].render_area = gfx::Rect(x, y, w, h); } } } // namespace content |