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

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

Issue 490233002: VaapiVideoAccelerator: make Vaapi accelerator work with ozone (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed commented code from VaapiWrapper Created 6 years, 1 month 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 <algorithm> 7 #include <algorithm>
8 #include <numeric> 8 #include <numeric>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/callback_helpers.h" 12 #include "base/callback_helpers.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/mac/scoped_nsautorelease_pool.h" 14 #include "base/mac/scoped_nsautorelease_pool.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/strings/stringize_macros.h" 16 #include "base/strings/stringize_macros.h"
17 #include "base/synchronization/waitable_event.h" 17 #include "base/synchronization/waitable_event.h"
18 #include "base/time/time.h" 18 #include "base/time/time.h"
19 #include "ui/gl/gl_context.h" 19 #include "ui/gl/gl_context.h"
20 #include "ui/gl/gl_implementation.h" 20 #include "ui/gl/gl_implementation.h"
21 #include "ui/gl/gl_surface.h" 21 #include "ui/gl/gl_surface.h"
22 #include "ui/gl/gl_surface_egl.h"
23 #include "ui/gl/gl_surface_glx.h"
24 22
25 #if defined(OS_WIN) 23 #if defined(OS_WIN)
26 #include <windows.h> 24 #include <windows.h>
27 #endif 25 #endif
28 26
29 #if defined(USE_X11) 27 #if defined(USE_X11)
30 #include "ui/gfx/x/x11_types.h" 28 #include "ui/gfx/x/x11_types.h"
29 #include "ui/gl/gl_surface_glx.h"
30 #define GL_VARIANT_GLX 1
31 #else
32 #include "ui/gl/gl_surface_egl.h"
33 #define GL_VARIANT_EGL 1
31 #endif 34 #endif
32 35
33 #if !defined(OS_WIN) && defined(ARCH_CPU_X86_FAMILY) 36 #if defined(USE_OZONE)
34 #define GL_VARIANT_GLX 1 37 #include "ui/ozone/public/ozone_platform.h"
35 #else 38 #include "ui/ozone/public/ui_thread_gpu.h"
36 #define GL_VARIANT_EGL 1 39 #include "ui/platform_window/platform_window.h"
40 #include "ui/platform_window/platform_window_delegate.h"
37 #endif 41 #endif
38 42
39 // Helper for Shader creation. 43 // Helper for Shader creation.
40 static void CreateShader(GLuint program, 44 static void CreateShader(GLuint program,
41 GLenum type, 45 GLenum type,
42 const char* source, 46 const char* source,
43 int size) { 47 int size) {
44 GLuint shader = glCreateShader(type); 48 GLuint shader = glCreateShader(type);
45 glShaderSource(shader, 1, &source, &size); 49 glShaderSource(shader, 1, &source, &size);
46 glCompileShader(shader); 50 glCompileShader(shader);
47 int result = GL_FALSE; 51 int result = GL_FALSE;
48 glGetShaderiv(shader, GL_COMPILE_STATUS, &result); 52 glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
49 if (!result) { 53 if (!result) {
50 char log[4096]; 54 char log[4096];
51 glGetShaderInfoLog(shader, arraysize(log), NULL, log); 55 glGetShaderInfoLog(shader, arraysize(log), NULL, log);
52 LOG(FATAL) << log; 56 LOG(FATAL) << log;
53 } 57 }
54 glAttachShader(program, shader); 58 glAttachShader(program, shader);
55 glDeleteShader(shader); 59 glDeleteShader(shader);
56 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 60 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
57 } 61 }
58 62
59 namespace content { 63 namespace content {
60 64
65 #if defined(USE_OZONE)
66
67 // Ozone Gbm Surfaces are always created to the size of the screen, so
68 // it doesn't matter what size we are passing here, we will update it
69 // once the surface is created.
70 const int kTestWindowWidth = 1;
71 const int kTestWindowHeight = 1;
Owen Lin 2014/11/06 05:45:01 How about const gfx::Rect kTestWindowSize(1, 1); ?
llandwerlin-old 2014/11/10 09:34:16 Added an empty Rect in the StubOzoneDelegate const
72
73 class RenderingHelper::StubOzoneDelegate : public ui::PlatformWindowDelegate {
74 public:
75 StubOzoneDelegate() : widget_(gfx::kNullAcceleratedWidget) {
76 platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow(
77 this, gfx::Rect(kTestWindowWidth, kTestWindowHeight));
78 }
79 virtual ~StubOzoneDelegate() {}
80
81 virtual void OnBoundsChanged(const gfx::Rect& new_bounds) override {}
82
83 virtual void OnDamageRect(const gfx::Rect& damaged_region) override {}
84
85 virtual void DispatchEvent(ui::Event* event) override {}
86
87 virtual void OnCloseRequest() override {}
88 virtual void OnClosed() override {}
89
90 virtual void OnWindowStateChanged(
91 ui::PlatformWindowState new_state) override {};
92
93 virtual void OnLostCapture() override {};
94
95 virtual void OnAcceleratedWidgetAvailable(
96 gfx::AcceleratedWidget widget) override {
97 widget_ = widget;
98 };
99
100 virtual void OnActivationChanged(bool active) override {};
101
102 gfx::AcceleratedWidget GetAcceleratedWidget() const { return widget_; }
103
104 gfx::Size GetSize() { return platform_window_->GetBounds().size(); }
105
106 private:
107 scoped_ptr<ui::PlatformWindow> platform_window_;
108 gfx::AcceleratedWidget widget_;
109 };
110
111 #endif // defined(USE_OZONE)
112
61 RenderingHelperParams::RenderingHelperParams() 113 RenderingHelperParams::RenderingHelperParams()
62 : rendering_fps(0), warm_up_iterations(0), render_as_thumbnails(false) { 114 : rendering_fps(0), warm_up_iterations(0), render_as_thumbnails(false) {
63 } 115 }
64 116
65 RenderingHelperParams::~RenderingHelperParams() {} 117 RenderingHelperParams::~RenderingHelperParams() {}
66 118
67 VideoFrameTexture::VideoFrameTexture(uint32 texture_target, 119 VideoFrameTexture::VideoFrameTexture(uint32 texture_target,
68 uint32 texture_id, 120 uint32 texture_id,
69 const base::Closure& no_longer_needed_cb) 121 const base::Closure& no_longer_needed_cb)
70 : texture_target_(texture_target), 122 : texture_target_(texture_target),
(...skipping 15 matching lines...) Expand all
86 138
87 // static 139 // static
88 bool RenderingHelper::InitializeOneOff() { 140 bool RenderingHelper::InitializeOneOff() {
89 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); 141 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
90 #if GL_VARIANT_GLX 142 #if GL_VARIANT_GLX
91 cmd_line->AppendSwitchASCII(switches::kUseGL, 143 cmd_line->AppendSwitchASCII(switches::kUseGL,
92 gfx::kGLImplementationDesktopName); 144 gfx::kGLImplementationDesktopName);
93 #else 145 #else
94 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); 146 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName);
95 #endif 147 #endif
148
149 #if defined(USE_OZONE)
150 static ui::UiThreadGpu ui_thread_gpu;
151 ui::OzonePlatform::InitializeForUI();
152 return gfx::GLSurface::InitializeOneOff() && ui_thread_gpu.Initialize();
153 #else
96 return gfx::GLSurface::InitializeOneOff(); 154 return gfx::GLSurface::InitializeOneOff();
155 #endif
97 } 156 }
98 157
99 RenderingHelper::RenderingHelper() { 158 RenderingHelper::RenderingHelper() {
100 window_ = gfx::kNullAcceleratedWidget; 159 window_ = gfx::kNullAcceleratedWidget;
101 Clear(); 160 Clear();
102 } 161 }
103 162
104 RenderingHelper::~RenderingHelper() { 163 RenderingHelper::~RenderingHelper() {
105 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor."; 164 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor.";
106 Clear(); 165 Clear();
(...skipping 21 matching lines...) Expand all
128 187
129 #if defined(OS_WIN) 188 #if defined(OS_WIN)
130 screen_size_ = 189 screen_size_ =
131 gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); 190 gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
132 window_ = CreateWindowEx(0, 191 window_ = CreateWindowEx(0,
133 L"Static", 192 L"Static",
134 L"VideoDecodeAcceleratorTest", 193 L"VideoDecodeAcceleratorTest",
135 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 194 WS_OVERLAPPEDWINDOW | WS_VISIBLE,
136 0, 195 0,
137 0, 196 0,
138 screen_size_.width(), 197 screen_size_.width(),
Owen Lin 2014/11/06 05:45:01 Remove line 189 (screen_size_ = ...) and just use
llandwerlin-old 2014/11/10 09:34:16 Done.
139 screen_size_.height(), 198 screen_size_.height(),
140 NULL, 199 NULL,
141 NULL, 200 NULL,
142 NULL, 201 NULL,
143 NULL); 202 NULL);
144 #elif defined(USE_X11) 203 #elif defined(USE_X11)
145 Display* display = gfx::GetXDisplay(); 204 Display* display = gfx::GetXDisplay();
146 Screen* screen = DefaultScreenOfDisplay(display); 205 Screen* screen = DefaultScreenOfDisplay(display);
147 screen_size_ = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); 206 screen_size_ = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen));
148 207
(...skipping 14 matching lines...) Expand all
163 screen_size_.height(), 222 screen_size_.height(),
164 0 /* border width */, 223 0 /* border width */,
165 depth, 224 depth,
166 CopyFromParent /* class */, 225 CopyFromParent /* class */,
167 CopyFromParent /* visual */, 226 CopyFromParent /* visual */,
168 (CWBackPixel | CWOverrideRedirect), 227 (CWBackPixel | CWOverrideRedirect),
169 &window_attributes); 228 &window_attributes);
170 XStoreName(display, window_, "VideoDecodeAcceleratorTest"); 229 XStoreName(display, window_, "VideoDecodeAcceleratorTest");
171 XSelectInput(display, window_, ExposureMask); 230 XSelectInput(display, window_, ExposureMask);
172 XMapWindow(display, window_); 231 XMapWindow(display, window_);
232 #elif defined(USE_OZONE)
233 platform_window_delegate_.reset(new RenderingHelper::StubOzoneDelegate());
234 window_ = platform_window_delegate_->GetAcceleratedWidget();
173 #else 235 #else
174 #error unknown platform 236 #error unknown platform
175 #endif 237 #endif
176 CHECK(window_ != gfx::kNullAcceleratedWidget); 238 CHECK(window_ != gfx::kNullAcceleratedWidget);
177 239
178 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); 240 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_);
241 screen_size_ = gl_surface_->GetSize();
242
179 gl_context_ = gfx::GLContext::CreateGLContext( 243 gl_context_ = gfx::GLContext::CreateGLContext(
180 NULL, gl_surface_.get(), gfx::PreferIntegratedGpu); 244 NULL, gl_surface_.get(), gfx::PreferIntegratedGpu);
181 gl_context_->MakeCurrent(gl_surface_.get()); 245 CHECK(gl_context_->MakeCurrent(gl_surface_.get()));
182 246
183 CHECK_GT(params.window_sizes.size(), 0U); 247 CHECK_GT(params.window_sizes.size(), 0U);
184 videos_.resize(params.window_sizes.size()); 248 videos_.resize(params.window_sizes.size());
185 LayoutRenderingAreas(params.window_sizes); 249 LayoutRenderingAreas(params.window_sizes);
186 250
187 if (render_as_thumbnails_) { 251 if (render_as_thumbnails_) {
188 CHECK_EQ(videos_.size(), 1U); 252 CHECK_EQ(videos_.size(), 1U);
189 253
190 GLint max_texture_size; 254 GLint max_texture_size;
191 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); 255 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 if (tex_external != -1) { 361 if (tex_external != -1) {
298 glUniform1i(tex_external, 1); 362 glUniform1i(tex_external, 1);
299 } 363 }
300 int pos_location = glGetAttribLocation(program_, "in_pos"); 364 int pos_location = glGetAttribLocation(program_, "in_pos");
301 glEnableVertexAttribArray(pos_location); 365 glEnableVertexAttribArray(pos_location);
302 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); 366 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
303 int tc_location = glGetAttribLocation(program_, "in_tc"); 367 int tc_location = glGetAttribLocation(program_, "in_tc");
304 glEnableVertexAttribArray(tc_location); 368 glEnableVertexAttribArray(tc_location);
305 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); 369 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords);
306 370
371 int warm_up_iterations = 0;
307 if (frame_duration_ != base::TimeDelta()) 372 if (frame_duration_ != base::TimeDelta())
308 WarmUpRendering(params.warm_up_iterations); 373 warm_up_iterations = params.warm_up_iterations;
374 #if defined(USE_OZONE)
375 // On Ozone the VSyncProvider can't provide a vsync_internal until
376 // we render at least a frame, so we warm up with at least one
377 // frame.
378 warm_up_iterations = std::max(1, warm_up_iterations);
379 #endif
380 if (warm_up_iterations > 0)
381 WarmUpRendering(warm_up_iterations);
309 382
310 // It's safe to use Unretained here since |rendering_thread_| will be stopped 383 // It's safe to use Unretained here since |rendering_thread_| will be stopped
311 // in VideoDecodeAcceleratorTest.TearDown(), while the |rendering_helper_| is 384 // in VideoDecodeAcceleratorTest.TearDown(), while the |rendering_helper_| is
312 // a member of that class. (See video_decode_accelerator_unittest.cc.) 385 // a member of that class. (See video_decode_accelerator_unittest.cc.)
313 gl_surface_->GetVSyncProvider()->GetVSyncParameters(base::Bind( 386 gl_surface_->GetVSyncProvider()->GetVSyncParameters(base::Bind(
Owen Lin 2014/11/06 05:45:01 I like your idea that don't call this function if
314 &RenderingHelper::UpdateVSyncParameters, base::Unretained(this), done)); 387 &RenderingHelper::UpdateVSyncParameters, base::Unretained(this), done));
315 } 388 }
316 389
317 // The rendering for the first few frames is slow (e.g., 100ms on Peach Pit). 390 // The rendering for the first few frames is slow (e.g., 100ms on Peach Pit).
318 // This affects the numbers measured in the performance test. We try to render 391 // This affects the numbers measured in the performance test. We try to render
319 // several frames here to warm up the rendering. 392 // several frames here to warm up the rendering.
320 void RenderingHelper::WarmUpRendering(int warm_up_iterations) { 393 void RenderingHelper::WarmUpRendering(int warm_up_iterations) {
321 unsigned int texture_id; 394 unsigned int texture_id;
322 scoped_ptr<GLubyte[]> emptyData(new GLubyte[screen_size_.GetArea() * 2]); 395 scoped_ptr<GLubyte[]> emptyData(new GLubyte[screen_size_.GetArea() * 2]);
323 glGenTextures(1, &texture_id); 396 glGenTextures(1, &texture_id);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 glBindTexture(texture_target, 0); 529 glBindTexture(texture_target, 0);
457 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 530 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
458 } 531 }
459 532
460 void RenderingHelper::DeleteTexture(uint32 texture_id) { 533 void RenderingHelper::DeleteTexture(uint32 texture_id) {
461 CHECK_EQ(base::MessageLoop::current(), message_loop_); 534 CHECK_EQ(base::MessageLoop::current(), message_loop_);
462 glDeleteTextures(1, &texture_id); 535 glDeleteTextures(1, &texture_id);
463 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 536 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
464 } 537 }
465 538
466 void* RenderingHelper::GetGLContext() { 539 scoped_refptr<gfx::GLContext> RenderingHelper::GetGLContext() {
540 return gl_context_;
541 }
542
543 void* RenderingHelper::GetGLContextHandle() {
467 return gl_context_->GetHandle(); 544 return gl_context_->GetHandle();
468 } 545 }
469 546
470 void* RenderingHelper::GetGLDisplay() { 547 void* RenderingHelper::GetGLDisplay() {
471 return gl_surface_->GetDisplay(); 548 return gl_surface_->GetDisplay();
472 } 549 }
473 550
474 void RenderingHelper::Clear() { 551 void RenderingHelper::Clear() {
475 videos_.clear(); 552 videos_.clear();
476 message_loop_ = NULL; 553 message_loop_ = NULL;
477 gl_context_ = NULL; 554 gl_context_ = NULL;
478 gl_surface_ = NULL; 555 gl_surface_ = NULL;
479 556
480 render_as_thumbnails_ = false; 557 render_as_thumbnails_ = false;
481 frame_count_ = 0; 558 frame_count_ = 0;
482 thumbnails_fbo_id_ = 0; 559 thumbnails_fbo_id_ = 0;
483 thumbnails_texture_id_ = 0; 560 thumbnails_texture_id_ = 0;
484 561
485 #if defined(OS_WIN) 562 #if defined(OS_WIN)
486 if (window_) 563 if (window_)
487 DestroyWindow(window_); 564 DestroyWindow(window_);
488 #else 565 #elif defined(USE_X11)
489 // Destroy resources acquired in Initialize, in reverse-acquisition order. 566 // Destroy resources acquired in Initialize, in reverse-acquisition order.
490 if (window_) { 567 if (window_) {
491 CHECK(XUnmapWindow(gfx::GetXDisplay(), window_)); 568 CHECK(XUnmapWindow(gfx::GetXDisplay(), window_));
492 CHECK(XDestroyWindow(gfx::GetXDisplay(), window_)); 569 CHECK(XDestroyWindow(gfx::GetXDisplay(), window_));
493 } 570 }
494 #endif 571 #endif
495 window_ = gfx::kNullAcceleratedWidget; 572 window_ = gfx::kNullAcceleratedWidget;
496 } 573 }
497 574
498 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, 575 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 // to keep references to them until after SwapBuffers() call below. 632 // to keep references to them until after SwapBuffers() call below.
556 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; 633 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned;
557 bool need_swap_buffer = false; 634 bool need_swap_buffer = false;
558 if (render_as_thumbnails_) { 635 if (render_as_thumbnails_) {
559 // In render_as_thumbnails_ mode, we render the FBO content on the 636 // In render_as_thumbnails_ mode, we render the FBO content on the
560 // screen instead of the decoded textures. 637 // screen instead of the decoded textures.
561 GLSetViewPort(videos_[0].render_area); 638 GLSetViewPort(videos_[0].render_area);
562 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); 639 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_);
563 need_swap_buffer = true; 640 need_swap_buffer = true;
564 } else { 641 } else {
642 GLSetViewPort(gfx::Rect(screen_size_));
643 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
644 glClear(GL_COLOR_BUFFER_BIT);
marcheu 2014/11/04 19:25:38 I'm not sure why this is needed now?
llandwerlin-old 2014/11/05 10:17:35 Yes, otherwise I can see the last frame of the pre
565 for (RenderedVideo& video : videos_) { 645 for (RenderedVideo& video : videos_) {
566 if (video.pending_frames.empty()) 646 if (video.pending_frames.empty())
567 continue; 647 continue;
568 need_swap_buffer = true; 648 need_swap_buffer = true;
569 scoped_refptr<VideoFrameTexture> frame = video.pending_frames.front(); 649 scoped_refptr<VideoFrameTexture> frame = video.pending_frames.front();
570 GLSetViewPort(video.render_area); 650 GLSetViewPort(video.render_area);
571 RenderTexture(frame->texture_target(), frame->texture_id()); 651 RenderTexture(frame->texture_target(), frame->texture_id());
572 652
573 if (video.pending_frames.size() > 1 || video.is_flushing) { 653 if (video.pending_frames.size() > 1 || video.is_flushing) {
574 frames_to_be_returned.push_back(video.pending_frames.front()); 654 frames_to_be_returned.push_back(video.pending_frames.front());
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 void RenderingHelper::UpdateVSyncParameters(base::WaitableEvent* done, 722 void RenderingHelper::UpdateVSyncParameters(base::WaitableEvent* done,
643 const base::TimeTicks timebase, 723 const base::TimeTicks timebase,
644 const base::TimeDelta interval) { 724 const base::TimeDelta interval) {
645 vsync_timebase_ = timebase; 725 vsync_timebase_ = timebase;
646 vsync_interval_ = interval; 726 vsync_interval_ = interval;
647 727
648 if (done) 728 if (done)
649 done->Signal(); 729 done->Signal();
650 } 730 }
651 731
652 void RenderingHelper::DropOneFrameForAllVideos() { 732 uint32 RenderingHelper::DropOneFrameForAllVideos() {
733 uint32 frames_dropped = 0;
653 for (RenderedVideo& video : videos_) { 734 for (RenderedVideo& video : videos_) {
654 if (video.pending_frames.empty()) 735 if (video.pending_frames.empty())
655 continue; 736 continue;
656 737
657 if (video.pending_frames.size() > 1 || video.is_flushing) { 738 if (video.pending_frames.size() > 1 || video.is_flushing) {
739 frames_dropped++;
658 video.pending_frames.pop(); 740 video.pending_frames.pop();
659 } else { 741 } else {
660 ++video.frames_to_drop; 742 ++video.frames_to_drop;
661 } 743 }
662 } 744 }
745 return frames_dropped;
663 } 746 }
664 747
665 void RenderingHelper::ScheduleNextRenderContent() { 748 void RenderingHelper::ScheduleNextRenderContent() {
666 scheduled_render_time_ += frame_duration_; 749 scheduled_render_time_ += frame_duration_;
667 750
668 // Schedules the next RenderContent() at latest VSYNC before the 751 // Schedules the next RenderContent() at latest VSYNC before the
669 // |scheduled_render_time_|. 752 // |scheduled_render_time_|.
670 base::TimeTicks now = base::TimeTicks::Now(); 753 base::TimeTicks now = base::TimeTicks::Now();
671 base::TimeTicks target = 754 base::TimeTicks target =
672 std::max(now + vsync_interval_, scheduled_render_time_); 755 std::max(now + vsync_interval_, scheduled_render_time_);
673 756
674 int64 intervals = (target - vsync_timebase_) / vsync_interval_; 757 int64 intervals = (target - vsync_timebase_) / vsync_interval_;
675 target = vsync_timebase_ + intervals * vsync_interval_; 758 target = vsync_timebase_ + intervals * vsync_interval_;
676 759
677 // When the rendering falls behind, drops frames. 760 // When the rendering falls behind, drops frames.
678 while (scheduled_render_time_ < target) { 761 if (frame_duration_ > base::TimeDelta()) {
679 scheduled_render_time_ += frame_duration_; 762 while (scheduled_render_time_ < target) {
680 DropOneFrameForAllVideos(); 763 scheduled_render_time_ += frame_duration_;
764 DropOneFrameForAllVideos();
765 }
766 } else {
767 // If we don't have a frame_duration_, just drop as many frames as
Owen Lin 2014/11/06 05:45:01 This is not needed. If frame_duration is null, we
llandwerlin-old 2014/11/10 09:34:16 Done.
768 // possible.
769 while (DropOneFrameForAllVideos() > 0)
770 ;
681 } 771 }
682
683 message_loop_->PostDelayedTask( 772 message_loop_->PostDelayedTask(
684 FROM_HERE, render_task_.callback(), target - now); 773 FROM_HERE, render_task_.callback(), target - now);
685 } 774 }
686 } // namespace content 775 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698