Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: content/common/gpu/media/rendering_helper.cc

Issue 294663006: vda_unittest - Move the fps control from ThrottleVDAClient to RenderingHelper. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/mac/scoped_nsautorelease_pool.h" 8 #include "base/mac/scoped_nsautorelease_pool.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/stringize_macros.h" 10 #include "base/strings/stringize_macros.h"
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 void RenderingHelper::Initialize(const RenderingHelperParams& params, 87 void RenderingHelper::Initialize(const RenderingHelperParams& params,
88 base::WaitableEvent* done) { 88 base::WaitableEvent* done) {
89 // Use frame_dimensions_.size() != 0 as a proxy for the class having already 89 // Use frame_dimensions_.size() != 0 as a proxy for the class having already
90 // been Initialize()'d, and UnInitialize() before continuing. 90 // been Initialize()'d, and UnInitialize() before continuing.
91 if (frame_dimensions_.size()) { 91 if (frame_dimensions_.size()) {
92 base::WaitableEvent done(false, false); 92 base::WaitableEvent done(false, false);
93 UnInitialize(&done); 93 UnInitialize(&done);
94 done.Wait(); 94 done.Wait();
95 } 95 }
96 96
97 // TODO(owenlin): pass fps from params 97 frame_duration_ = params.rendering_fps > 0
98 frame_duration_ = base::TimeDelta::FromSeconds(1) / 60; 98 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps
99 : base::TimeDelta();
99 100
100 gfx::InitializeStaticGLBindings(kGLImplementation); 101 gfx::InitializeStaticGLBindings(kGLImplementation);
101 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context( 102 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context(
102 new gfx::GLContextStubWithExtensions()); 103 new gfx::GLContextStubWithExtensions());
103 104
104 CHECK_GT(params.window_dimensions.size(), 0U); 105 CHECK_GT(params.window_dimensions.size(), 0U);
105 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size()); 106 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size());
106 frame_dimensions_ = params.frame_dimensions; 107 frame_dimensions_ = params.frame_dimensions;
107 render_as_thumbnails_ = params.render_as_thumbnails; 108 render_as_thumbnails_ = params.render_as_thumbnails;
108 message_loop_ = base::MessageLoop::current(); 109 message_loop_ = base::MessageLoop::current();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 gl_context_ = eglCreateContext( 176 gl_context_ = eglCreateContext(
176 gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs); 177 gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs);
177 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError(); 178 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError();
178 stub_context->AddExtensionsString( 179 stub_context->AddExtensionsString(
179 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 180 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
180 stub_context->AddExtensionsString( 181 stub_context->AddExtensionsString(
181 eglQueryString(gl_display_, EGL_EXTENSIONS)); 182 eglQueryString(gl_display_, EGL_EXTENSIONS));
182 stub_context->SetGLVersionString( 183 stub_context->SetGLVersionString(
183 reinterpret_cast<const char*>(glGetString(GL_VERSION))); 184 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
184 #endif 185 #endif
185 186 clients_ = params.clients;
186 // Per-window/surface X11 & EGL initialization. 187 // Per-window/surface X11 & EGL initialization.
187 CHECK(texture_ids_.empty());
188 CHECK(texture_targets_.empty());
189
190 // Initialize to an invalid texture id: 0 to indicate no texture
191 // for rendering.
192 texture_ids_.resize(params.num_windows, 0);
193 texture_targets_.resize(params.num_windows, 0);
194
195 for (int i = 0; i < params.num_windows; ++i) { 188 for (int i = 0; i < params.num_windows; ++i) {
196 // Arrange X windows whimsically, with some padding. 189 // Arrange X windows whimsically, with some padding.
197 int j = i % params.window_dimensions.size(); 190 int j = i % params.window_dimensions.size();
198 int width = params.window_dimensions[j].width(); 191 int width = params.window_dimensions[j].width();
199 int height = params.window_dimensions[j].height(); 192 int height = params.window_dimensions[j].height();
200 CHECK_GT(width, 0); 193 CHECK_GT(width, 0);
201 CHECK_GT(height, 0); 194 CHECK_GT(height, 0);
202 int top_left_x = (width + 20) * (i % 4); 195 int top_left_x = (width + 20) * (i % 4);
203 int top_left_y = (height + 12) * (i % 3); 196 int top_left_y = (height + 12) * (i % 3);
204 render_areas_.push_back(gfx::Rect(top_left_x, top_left_y, width, height)); 197 render_areas_.push_back(gfx::Rect(top_left_x, top_left_y, width, height));
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 GL_COLOR_ATTACHMENT0, 294 GL_COLOR_ATTACHMENT0,
302 GL_TEXTURE_2D, 295 GL_TEXTURE_2D,
303 thumbnails_texture_id_, 296 thumbnails_texture_id_,
304 0); 297 0);
305 298
306 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 299 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
307 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; 300 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status;
308 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 301 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
309 glClear(GL_COLOR_BUFFER_BIT); 302 glClear(GL_COLOR_BUFFER_BIT);
310 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 303 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
311
312 // In render_as_thumbnails_ mode, we render the FBO content on the
313 // screen instead of the decoded textures.
314 texture_targets_[0] = GL_TEXTURE_2D;
315 texture_ids_[0] = thumbnails_texture_id_;
316 } 304 }
317 305
318 // These vertices and texture coords. map (0,0) in the texture to the 306 // These vertices and texture coords. map (0,0) in the texture to the
319 // bottom left of the viewport. Since we get the video frames with the 307 // bottom left of the viewport. Since we get the video frames with the
320 // the top left at (0,0) we need to flip the texture y coordinate 308 // the top left at (0,0) we need to flip the texture y coordinate
321 // in the vertex shader for this to be rendered the right way up. 309 // in the vertex shader for this to be rendered the right way up.
322 // In the case of thumbnail rendering we use the same vertex shader 310 // In the case of thumbnail rendering we use the same vertex shader
323 // to render the FBO the screen, where we do not want this flipping. 311 // to render the FBO the screen, where we do not want this flipping.
324 static const float kVertices[] = 312 static const float kVertices[] =
325 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, }; 313 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, };
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 if (tex_external != -1) { 373 if (tex_external != -1) {
386 glUniform1i(tex_external, 1); 374 glUniform1i(tex_external, 1);
387 } 375 }
388 int pos_location = glGetAttribLocation(program_, "in_pos"); 376 int pos_location = glGetAttribLocation(program_, "in_pos");
389 glEnableVertexAttribArray(pos_location); 377 glEnableVertexAttribArray(pos_location);
390 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); 378 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
391 int tc_location = glGetAttribLocation(program_, "in_tc"); 379 int tc_location = glGetAttribLocation(program_, "in_tc");
392 glEnableVertexAttribArray(tc_location); 380 glEnableVertexAttribArray(tc_location);
393 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); 381 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords);
394 382
395 render_timer_.Start( 383 if (frame_duration_ != base::TimeDelta()) {
396 FROM_HERE, frame_duration_, this, &RenderingHelper::RenderContent); 384 render_timer_.Start(
385 FROM_HERE, frame_duration_, this, &RenderingHelper::RenderContent);
386 }
397 done->Signal(); 387 done->Signal();
398 } 388 }
399 389
400 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { 390 void RenderingHelper::UnInitialize(base::WaitableEvent* done) {
401 CHECK_EQ(base::MessageLoop::current(), message_loop_); 391 CHECK_EQ(base::MessageLoop::current(), message_loop_);
402 render_timer_.Stop(); 392 render_timer_.Stop();
403 if (render_as_thumbnails_) { 393 if (render_as_thumbnails_) {
404 glDeleteTextures(1, &thumbnails_texture_id_); 394 glDeleteTextures(1, &thumbnails_texture_id_);
405 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); 395 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_);
406 } 396 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 436 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
447 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. 437 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures.
448 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 438 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
449 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 439 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
450 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 440 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
451 CHECK(texture_id_to_surface_index_.insert( 441 CHECK(texture_id_to_surface_index_.insert(
452 std::make_pair(*texture_id, window_id)).second); 442 std::make_pair(*texture_id, window_id)).second);
453 done->Signal(); 443 done->Signal();
454 } 444 }
455 445
456 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { 446 // Helper function to set GL viewport.
457 CHECK_EQ(base::MessageLoop::current(), message_loop_); 447 static inline void GLSetViewPort(const gfx::Rect& area) {
458 if (texture_id == 0) 448 glViewport(area.x(), area.y(), area.width(), area.height());
459 return; 449 glScissor(area.x(), area.y(), area.width(), area.height());
460
461 if (render_as_thumbnails_) {
462 const int width = thumbnail_size_.width();
463 const int height = thumbnail_size_.height();
464 const int thumbnails_in_row = thumbnails_fbo_size_.width() / width;
465 const int thumbnails_in_column = thumbnails_fbo_size_.height() / height;
466 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column;
467 const int col = frame_count_ % thumbnails_in_row;
468
469 gfx::Rect area(col * width, row * height, width, height);
470
471 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0);
472 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_);
473 DrawTexture(area, texture_target, texture_id);
474 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
475 ++frame_count_;
476 } else {
477 size_t window_id = texture_id_to_surface_index_[texture_id];
478 texture_targets_[window_id] = texture_target;
479 texture_ids_[window_id] = texture_id;
480 }
481 } 450 }
482 451
483 void RenderingHelper::DrawTexture(const gfx::Rect& area, 452 void RenderingHelper::RenderThumbnail(uint32 texture_target,
484 uint32 texture_target, 453 uint32 texture_id) {
485 uint32 texture_id) { 454 CHECK_EQ(base::MessageLoop::current(), message_loop_);
486 glViewport(area.x(), area.y(), area.width(), area.height()); 455 const int width = thumbnail_size_.width();
487 glScissor(area.x(), area.y(), area.width(), area.height()); 456 const int height = thumbnail_size_.height();
457 const int thumbnails_in_row = thumbnails_fbo_size_.width() / width;
458 const int thumbnails_in_column = thumbnails_fbo_size_.height() / height;
459 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column;
460 const int col = frame_count_ % thumbnails_in_row;
488 461
462 gfx::Rect area(col * width, row * height, width, height);
463
464 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0);
465 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_);
466 GLSetViewPort(area);
467 RenderTexture(texture_target, texture_id);
468 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
469 ++frame_count_;
470 }
471
472 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) {
489 // Unbound texture samplers default to (0, 0, 0, 1). Use this fact to switch 473 // Unbound texture samplers default to (0, 0, 0, 1). Use this fact to switch
490 // between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES as appopriate. 474 // between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES as appopriate.
491 if (texture_target == GL_TEXTURE_2D) { 475 if (texture_target == GL_TEXTURE_2D) {
492 glActiveTexture(GL_TEXTURE0 + 0); 476 glActiveTexture(GL_TEXTURE0 + 0);
493 glBindTexture(GL_TEXTURE_2D, texture_id); 477 glBindTexture(GL_TEXTURE_2D, texture_id);
494 glActiveTexture(GL_TEXTURE0 + 1); 478 glActiveTexture(GL_TEXTURE0 + 1);
495 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); 479 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
496 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) { 480 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) {
497 glActiveTexture(GL_TEXTURE0 + 0); 481 glActiveTexture(GL_TEXTURE0 + 0);
498 glBindTexture(GL_TEXTURE_2D, 0); 482 glBindTexture(GL_TEXTURE_2D, 0);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 solid = solid && (*rgba_ptr == 0xff); 565 solid = solid && (*rgba_ptr == 0xff);
582 rgba_ptr++; 566 rgba_ptr++;
583 } 567 }
584 *alpha_solid = solid; 568 *alpha_solid = solid;
585 569
586 done->Signal(); 570 done->Signal();
587 } 571 }
588 572
589 void RenderingHelper::RenderContent() { 573 void RenderingHelper::RenderContent() {
590 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); 574 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1);
591 for (size_t i = 0; i < render_areas_.size(); ++i) { 575
592 DrawTexture(render_areas_[i], texture_targets_[i], texture_ids_[i]); 576 if (render_as_thumbnails_) {
577 // In render_as_thumbnails_ mode, we render the FBO content on the
578 // screen instead of the decoded textures.
579 GLSetViewPort(render_areas_[0]);
580 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_);
581 } else {
582 for (size_t i = 0; i < clients_.size(); ++i) {
583 if (clients_[i]) {
584 GLSetViewPort(render_areas_[i]);
585 clients_[i]->RenderContent(this);
586 }
587 }
593 } 588 }
594 589
595 #if GL_VARIANT_GLX 590 #if GL_VARIANT_GLX
596 glXSwapBuffers(x_display_, x_window_); 591 glXSwapBuffers(x_display_, x_window_);
597 #else // EGL 592 #else // EGL
598 eglSwapBuffers(gl_display_, gl_surface_); 593 eglSwapBuffers(gl_display_, gl_surface_);
599 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); 594 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS);
600 #endif 595 #endif
601 } 596 }
602 } // namespace content 597 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/rendering_helper.h ('k') | content/common/gpu/media/video_decode_accelerator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698