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

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

Issue 835653005: gpu: media: RenderingHelper: wait for the display & window to be ready (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update after Owen's comments Created 5 years, 11 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 <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/run_loop.h"
16 #include "base/strings/stringize_macros.h" 17 #include "base/strings/stringize_macros.h"
17 #include "base/synchronization/waitable_event.h" 18 #include "base/synchronization/waitable_event.h"
18 #include "base/time/time.h" 19 #include "base/time/time.h"
19 #include "ui/gl/gl_context.h" 20 #include "ui/gl/gl_context.h"
20 #include "ui/gl/gl_implementation.h" 21 #include "ui/gl/gl_implementation.h"
21 #include "ui/gl/gl_surface.h" 22 #include "ui/gl/gl_surface.h"
22 23
23 #if defined(OS_WIN) 24 #if defined(OS_WIN)
24 #include <windows.h> 25 #include <windows.h>
25 #endif 26 #endif
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 } 64 }
64 glAttachShader(program, shader); 65 glAttachShader(program, shader);
65 glDeleteShader(shader); 66 glDeleteShader(shader);
66 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 67 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
67 } 68 }
68 69
69 namespace content { 70 namespace content {
70 71
71 #if defined(USE_OZONE) 72 #if defined(USE_OZONE)
72 73
74 class DisplayConfiguratorObserver : public ui::DisplayConfigurator::Observer {
75 public:
76 DisplayConfiguratorObserver(base::RunLoop* loop) : loop_(loop) {}
77 ~DisplayConfiguratorObserver() override {}
78
79 private:
80 // ui::DisplayConfigurator::Observer overrides:
81 void OnDisplayModeChanged(
82 const ui::DisplayConfigurator::DisplayStateList& outputs) override {
83 if (!loop_)
84 return;
85 loop_->Quit();
86 loop_ = nullptr;
87 }
88 void OnDisplayModeChangeFailed(
89 ui::MultipleDisplayState failed_new_state) override {
90 LOG(FATAL) << "Could not configure display";
91 }
92
93 base::RunLoop* loop_;
94
95 DISALLOW_COPY_AND_ASSIGN(DisplayConfiguratorObserver);
96 };
97
73 class RenderingHelper::StubOzoneDelegate : public ui::PlatformWindowDelegate { 98 class RenderingHelper::StubOzoneDelegate : public ui::PlatformWindowDelegate {
74 public: 99 public:
75 StubOzoneDelegate() : accelerated_widget_(gfx::kNullAcceleratedWidget) { 100 StubOzoneDelegate() : accelerated_widget_(gfx::kNullAcceleratedWidget) {
76 ui_thread_gpu_.Initialize(); 101 ui_thread_gpu_.Initialize();
77 platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow( 102 platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow(
78 this, gfx::Rect()); 103 this, gfx::Rect());
79 } 104 }
80 virtual ~StubOzoneDelegate() {} 105 virtual ~StubOzoneDelegate() {}
81 106
82 void OnBoundsChanged(const gfx::Rect& new_bounds) override {} 107 void OnBoundsChanged(const gfx::Rect& new_bounds) override {}
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 } 161 }
137 162
138 RenderingHelper::RenderedVideo::RenderedVideo() 163 RenderingHelper::RenderedVideo::RenderedVideo()
139 : is_flushing(false), frames_to_drop(0) { 164 : is_flushing(false), frames_to_drop(0) {
140 } 165 }
141 166
142 RenderingHelper::RenderedVideo::~RenderedVideo() { 167 RenderingHelper::RenderedVideo::~RenderedVideo() {
143 } 168 }
144 169
145 // static 170 // static
146 bool RenderingHelper::InitializeOneOff() { 171 void RenderingHelper::InitializeOneOff(base::WaitableEvent* done) {
147 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); 172 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
148 #if GL_VARIANT_GLX 173 #if GL_VARIANT_GLX
149 cmd_line->AppendSwitchASCII(switches::kUseGL, 174 cmd_line->AppendSwitchASCII(switches::kUseGL,
150 gfx::kGLImplementationDesktopName); 175 gfx::kGLImplementationDesktopName);
151 #else 176 #else
152 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); 177 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName);
153 #endif 178 #endif
154 #if defined(USE_OZONE) 179
155 ui::OzonePlatform::InitializeForUI(); 180 if (!gfx::GLSurface::InitializeOneOff())
156 #endif 181 LOG(FATAL) << "Could not initialize GL";
157 return gfx::GLSurface::InitializeOneOff(); 182 done->Signal();
158 } 183 }
159 184
160 RenderingHelper::RenderingHelper() { 185 RenderingHelper::RenderingHelper() {
161 window_ = gfx::kNullAcceleratedWidget; 186 window_ = gfx::kNullAcceleratedWidget;
162 Clear(); 187 Clear();
163 } 188 }
164 189
165 RenderingHelper::~RenderingHelper() { 190 RenderingHelper::~RenderingHelper() {
166 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor."; 191 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor.";
167 Clear(); 192 Clear();
168 } 193 }
169 194
170 void RenderingHelper::Initialize(const RenderingHelperParams& params, 195 void RenderingHelper::Setup() {
171 base::WaitableEvent* done) {
172 // Use videos_.size() != 0 as a proxy for the class having already been
173 // Initialize()'d, and UnInitialize() before continuing.
174 if (videos_.size()) {
175 base::WaitableEvent done(false, false);
176 UnInitialize(&done);
177 done.Wait();
178 }
179
180 render_task_.Reset(
181 base::Bind(&RenderingHelper::RenderContent, base::Unretained(this)));
182
183 frame_duration_ = params.rendering_fps > 0
184 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps
185 : base::TimeDelta();
186
187 render_as_thumbnails_ = params.render_as_thumbnails;
188 message_loop_ = base::MessageLoop::current();
189
190 #if defined(OS_WIN) 196 #if defined(OS_WIN)
191 window_ = CreateWindowEx(0, 197 window_ = CreateWindowEx(0,
192 L"Static", 198 L"Static",
193 L"VideoDecodeAcceleratorTest", 199 L"VideoDecodeAcceleratorTest",
194 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 200 WS_OVERLAPPEDWINDOW | WS_VISIBLE,
195 0, 201 0,
196 0, 202 0,
197 GetSystemMetrics(SM_CXSCREEN), 203 GetSystemMetrics(SM_CXSCREEN),
198 GetSystemMetrics(SM_CYSCREEN), 204 GetSystemMetrics(SM_CYSCREEN),
199 NULL, 205 NULL,
(...skipping 22 matching lines...) Expand all
222 0 /* border width */, 228 0 /* border width */,
223 depth, 229 depth,
224 CopyFromParent /* class */, 230 CopyFromParent /* class */,
225 CopyFromParent /* visual */, 231 CopyFromParent /* visual */,
226 (CWBackPixel | CWOverrideRedirect), 232 (CWBackPixel | CWOverrideRedirect),
227 &window_attributes); 233 &window_attributes);
228 XStoreName(display, window_, "VideoDecodeAcceleratorTest"); 234 XStoreName(display, window_, "VideoDecodeAcceleratorTest");
229 XSelectInput(display, window_, ExposureMask); 235 XSelectInput(display, window_, ExposureMask);
230 XMapWindow(display, window_); 236 XMapWindow(display, window_);
231 #elif defined(USE_OZONE) 237 #elif defined(USE_OZONE)
238 base::MessageLoop::ScopedNestableTaskAllower nest_loop(
239 base::MessageLoop::current());
240 base::RunLoop wait_window_resize;
241
232 platform_window_delegate_.reset(new RenderingHelper::StubOzoneDelegate()); 242 platform_window_delegate_.reset(new RenderingHelper::StubOzoneDelegate());
233 window_ = platform_window_delegate_->accelerated_widget(); 243 window_ = platform_window_delegate_->accelerated_widget();
234 #if defined(OS_CHROMEOS) 244 #if defined(OS_CHROMEOS)
245 // We hold onto the main loop here to wait for the DisplayController
246 // to give us the size of the display so we can create a window of
247 // the same size.
248 base::RunLoop wait_display_setup;
249 DisplayConfiguratorObserver display_setup_observer(&wait_display_setup);
235 display_configurator_.reset(new ui::DisplayConfigurator()); 250 display_configurator_.reset(new ui::DisplayConfigurator());
251 display_configurator_->AddObserver(&display_setup_observer);
236 display_configurator_->Init(true); 252 display_configurator_->Init(true);
237 display_configurator_->ForceInitialConfigure(0); 253 display_configurator_->ForceInitialConfigure(0);
254 // Make sure all the display configuration is applied.
255 wait_display_setup.Run();
256 display_configurator_->RemoveObserver(&display_setup_observer);
257
238 platform_window_delegate_->platform_window()->SetBounds( 258 platform_window_delegate_->platform_window()->SetBounds(
239 gfx::Rect(display_configurator_->framebuffer_size())); 259 gfx::Rect(display_configurator_->framebuffer_size()));
240 #else 260 #else
241 platform_window_delegate_->platform_window()->SetBounds(gfx::Rect(800, 600)); 261 platform_window_delegate_->platform_window()->SetBounds(gfx::Rect(800, 600));
242 #endif 262 #endif
263
264 // On Ozone/DRI, platform windows are associated with the physical
265 // outputs. Association is achieved by matching the bounds of the
266 // window with the origin & modeset of the display output. Until a
267 // window is associated with a display output, we cannot get vsync
268 // events, because there is no hardware to get events from. Here we
269 // wait for the window to resized and therefore associated with
270 // display output to be sure that we will get such events.
271 wait_window_resize.RunUntilIdle();
243 #else 272 #else
244 #error unknown platform 273 #error unknown platform
245 #endif 274 #endif
246 CHECK(window_ != gfx::kNullAcceleratedWidget); 275 CHECK(window_ != gfx::kNullAcceleratedWidget);
276 }
277
278 void RenderingHelper::TearDown() {
279 #if defined(OS_WIN)
280 if (window_)
281 DestroyWindow(window_);
282 #elif defined(USE_X11)
283 // Destroy resources acquired in Initialize, in reverse-acquisition order.
284 if (window_) {
285 CHECK(XUnmapWindow(gfx::GetXDisplay(), window_));
286 CHECK(XDestroyWindow(gfx::GetXDisplay(), window_));
287 }
288 #elif defined(USE_OZONE)
289 platform_window_delegate_.reset();
290 #if defined(OS_CHROMEOS)
291 display_configurator_->PrepareForExit();
292 display_configurator_.reset();
293 #endif
294 #endif
295 window_ = gfx::kNullAcceleratedWidget;
296 }
297
298 void RenderingHelper::Initialize(const RenderingHelperParams& params,
299 base::WaitableEvent* done) {
300 // Use videos_.size() != 0 as a proxy for the class having already been
301 // Initialize()'d, and UnInitialize() before continuing.
302 if (videos_.size()) {
303 base::WaitableEvent done(false, false);
304 UnInitialize(&done);
305 done.Wait();
306 }
307
308 render_task_.Reset(
309 base::Bind(&RenderingHelper::RenderContent, base::Unretained(this)));
310
311 frame_duration_ = params.rendering_fps > 0
312 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps
313 : base::TimeDelta();
314
315 render_as_thumbnails_ = params.render_as_thumbnails;
316 message_loop_ = base::MessageLoop::current();
247 317
248 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); 318 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_);
249 screen_size_ = gl_surface_->GetSize(); 319 screen_size_ = gl_surface_->GetSize();
250 320
251 gl_context_ = gfx::GLContext::CreateGLContext( 321 gl_context_ = gfx::GLContext::CreateGLContext(
252 NULL, gl_surface_.get(), gfx::PreferIntegratedGpu); 322 NULL, gl_surface_.get(), gfx::PreferIntegratedGpu);
253 CHECK(gl_context_->MakeCurrent(gl_surface_.get())); 323 CHECK(gl_context_->MakeCurrent(gl_surface_.get()));
254 324
255 CHECK_GT(params.window_sizes.size(), 0U); 325 CHECK_GT(params.window_sizes.size(), 0U);
256 videos_.resize(params.window_sizes.size()); 326 videos_.resize(params.window_sizes.size());
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 for (int i = 0; i < warm_up_iterations; ++i) { 492 for (int i = 0; i < warm_up_iterations; ++i) {
423 RenderTexture(GL_TEXTURE_2D, texture_id); 493 RenderTexture(GL_TEXTURE_2D, texture_id);
424 gl_surface_->SwapBuffers(); 494 gl_surface_->SwapBuffers();
425 } 495 }
426 glDeleteTextures(1, &texture_id); 496 glDeleteTextures(1, &texture_id);
427 } 497 }
428 498
429 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { 499 void RenderingHelper::UnInitialize(base::WaitableEvent* done) {
430 CHECK_EQ(base::MessageLoop::current(), message_loop_); 500 CHECK_EQ(base::MessageLoop::current(), message_loop_);
431 501
432 #if defined(USE_OZONE) && defined(OS_CHROMEOS)
433 display_configurator_->PrepareForExit();
434 display_configurator_.reset();
435 #endif
436
437 render_task_.Cancel(); 502 render_task_.Cancel();
438 503
439 if (render_as_thumbnails_) { 504 if (render_as_thumbnails_) {
440 glDeleteTextures(1, &thumbnails_texture_id_); 505 glDeleteTextures(1, &thumbnails_texture_id_);
441 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); 506 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_);
442 } 507 }
443 508
444 gl_context_->ReleaseCurrent(gl_surface_.get()); 509 gl_context_->ReleaseCurrent(gl_surface_.get());
445 gl_context_ = NULL; 510 gl_context_ = NULL;
446 gl_surface_ = NULL; 511 gl_surface_ = NULL;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 void RenderingHelper::Clear() { 636 void RenderingHelper::Clear() {
572 videos_.clear(); 637 videos_.clear();
573 message_loop_ = NULL; 638 message_loop_ = NULL;
574 gl_context_ = NULL; 639 gl_context_ = NULL;
575 gl_surface_ = NULL; 640 gl_surface_ = NULL;
576 641
577 render_as_thumbnails_ = false; 642 render_as_thumbnails_ = false;
578 frame_count_ = 0; 643 frame_count_ = 0;
579 thumbnails_fbo_id_ = 0; 644 thumbnails_fbo_id_ = 0;
580 thumbnails_texture_id_ = 0; 645 thumbnails_texture_id_ = 0;
581
582 #if defined(OS_WIN)
583 if (window_)
584 DestroyWindow(window_);
585 #elif defined(USE_X11)
586 // Destroy resources acquired in Initialize, in reverse-acquisition order.
587 if (window_) {
588 CHECK(XUnmapWindow(gfx::GetXDisplay(), window_));
589 CHECK(XDestroyWindow(gfx::GetXDisplay(), window_));
590 }
591 #elif defined(USE_OZONE)
592 platform_window_delegate_.reset();
593 #endif
594 window_ = gfx::kNullAcceleratedWidget;
595 } 646 }
596 647
597 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, 648 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
598 bool* alpha_solid, 649 bool* alpha_solid,
599 base::WaitableEvent* done) { 650 base::WaitableEvent* done) {
600 CHECK(render_as_thumbnails_); 651 CHECK(render_as_thumbnails_);
601 652
602 const size_t num_pixels = thumbnails_fbo_size_.GetArea(); 653 const size_t num_pixels = thumbnails_fbo_size_.GetArea();
603 std::vector<unsigned char> rgba; 654 std::vector<unsigned char> rgba;
604 rgba.resize(num_pixels * 4); 655 rgba.resize(num_pixels * 4);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 // When the rendering falls behind, drops frames. 833 // When the rendering falls behind, drops frames.
783 while (scheduled_render_time_ < target) { 834 while (scheduled_render_time_ < target) {
784 scheduled_render_time_ += frame_duration_; 835 scheduled_render_time_ += frame_duration_;
785 DropOneFrameForAllVideos(); 836 DropOneFrameForAllVideos();
786 } 837 }
787 838
788 message_loop_->PostDelayedTask( 839 message_loop_->PostDelayedTask(
789 FROM_HERE, render_task_.callback(), target - now); 840 FROM_HERE, render_task_.callback(), target - now);
790 } 841 }
791 } // namespace content 842 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698