Chromium Code Reviews| Index: content/common/gpu/media/rendering_helper.cc |
| diff --git a/content/common/gpu/media/rendering_helper.cc b/content/common/gpu/media/rendering_helper.cc |
| index 5870ceef564638b48b1c5c9b19c132a95c6f80bb..36d545e44d15a71f726704e8d86fb8b5c4a66add 100644 |
| --- a/content/common/gpu/media/rendering_helper.cc |
| +++ b/content/common/gpu/media/rendering_helper.cc |
| @@ -19,8 +19,6 @@ |
| #include "ui/gl/gl_context.h" |
| #include "ui/gl/gl_implementation.h" |
| #include "ui/gl/gl_surface.h" |
| -#include "ui/gl/gl_surface_egl.h" |
| -#include "ui/gl/gl_surface_glx.h" |
| #if defined(OS_WIN) |
| #include <windows.h> |
| @@ -28,14 +26,20 @@ |
| #if defined(USE_X11) |
| #include "ui/gfx/x/x11_types.h" |
| -#endif |
| - |
| -#if !defined(OS_WIN) && defined(ARCH_CPU_X86_FAMILY) |
| +#include "ui/gl/gl_surface_glx.h" |
| #define GL_VARIANT_GLX 1 |
| #else |
| +#include "ui/gl/gl_surface_egl.h" |
| #define GL_VARIANT_EGL 1 |
| #endif |
| +#if defined(USE_OZONE) |
| +#include "ui/ozone/public/ozone_platform.h" |
| +#include "ui/ozone/public/ui_thread_gpu.h" |
| +#include "ui/platform_window/platform_window.h" |
| +#include "ui/platform_window/platform_window_delegate.h" |
| +#endif |
| + |
| // Helper for Shader creation. |
| static void CreateShader(GLuint program, |
| GLenum type, |
| @@ -58,6 +62,54 @@ static void CreateShader(GLuint program, |
| namespace content { |
| +#if defined(USE_OZONE) |
| + |
| +// Ozone Gbm Surfaces are always created to the size of the screen, so |
| +// it doesn't matter what size we are passing here, we will update it |
| +// once the surface is created. |
| +const int kTestWindowWidth = 1; |
| +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
|
| + |
| +class RenderingHelper::StubOzoneDelegate : public ui::PlatformWindowDelegate { |
| + public: |
| + StubOzoneDelegate() : widget_(gfx::kNullAcceleratedWidget) { |
| + platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow( |
| + this, gfx::Rect(kTestWindowWidth, kTestWindowHeight)); |
| + } |
| + virtual ~StubOzoneDelegate() {} |
| + |
| + virtual void OnBoundsChanged(const gfx::Rect& new_bounds) override {} |
| + |
| + virtual void OnDamageRect(const gfx::Rect& damaged_region) override {} |
| + |
| + virtual void DispatchEvent(ui::Event* event) override {} |
| + |
| + virtual void OnCloseRequest() override {} |
| + virtual void OnClosed() override {} |
| + |
| + virtual void OnWindowStateChanged( |
| + ui::PlatformWindowState new_state) override {}; |
| + |
| + virtual void OnLostCapture() override {}; |
| + |
| + virtual void OnAcceleratedWidgetAvailable( |
| + gfx::AcceleratedWidget widget) override { |
| + widget_ = widget; |
| + }; |
| + |
| + virtual void OnActivationChanged(bool active) override {}; |
| + |
| + gfx::AcceleratedWidget GetAcceleratedWidget() const { return widget_; } |
| + |
| + gfx::Size GetSize() { return platform_window_->GetBounds().size(); } |
| + |
| + private: |
| + scoped_ptr<ui::PlatformWindow> platform_window_; |
| + gfx::AcceleratedWidget widget_; |
| +}; |
| + |
| +#endif // defined(USE_OZONE) |
| + |
| RenderingHelperParams::RenderingHelperParams() |
| : rendering_fps(0), warm_up_iterations(0), render_as_thumbnails(false) { |
| } |
| @@ -93,7 +145,14 @@ bool RenderingHelper::InitializeOneOff() { |
| #else |
| cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); |
| #endif |
| + |
| +#if defined(USE_OZONE) |
| + static ui::UiThreadGpu ui_thread_gpu; |
| + ui::OzonePlatform::InitializeForUI(); |
| + return gfx::GLSurface::InitializeOneOff() && ui_thread_gpu.Initialize(); |
| +#else |
| return gfx::GLSurface::InitializeOneOff(); |
| +#endif |
| } |
| RenderingHelper::RenderingHelper() { |
| @@ -170,15 +229,20 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, |
| XStoreName(display, window_, "VideoDecodeAcceleratorTest"); |
| XSelectInput(display, window_, ExposureMask); |
| XMapWindow(display, window_); |
| +#elif defined(USE_OZONE) |
| + platform_window_delegate_.reset(new RenderingHelper::StubOzoneDelegate()); |
| + window_ = platform_window_delegate_->GetAcceleratedWidget(); |
| #else |
| #error unknown platform |
| #endif |
| CHECK(window_ != gfx::kNullAcceleratedWidget); |
| gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); |
| + screen_size_ = gl_surface_->GetSize(); |
| + |
| gl_context_ = gfx::GLContext::CreateGLContext( |
| NULL, gl_surface_.get(), gfx::PreferIntegratedGpu); |
| - gl_context_->MakeCurrent(gl_surface_.get()); |
| + CHECK(gl_context_->MakeCurrent(gl_surface_.get())); |
| CHECK_GT(params.window_sizes.size(), 0U); |
| videos_.resize(params.window_sizes.size()); |
| @@ -304,8 +368,17 @@ void RenderingHelper::Initialize(const RenderingHelperParams& params, |
| glEnableVertexAttribArray(tc_location); |
| glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); |
| + int warm_up_iterations = 0; |
| if (frame_duration_ != base::TimeDelta()) |
| - WarmUpRendering(params.warm_up_iterations); |
| + warm_up_iterations = params.warm_up_iterations; |
| +#if defined(USE_OZONE) |
| + // On Ozone the VSyncProvider can't provide a vsync_internal until |
| + // we render at least a frame, so we warm up with at least one |
| + // frame. |
| + warm_up_iterations = std::max(1, warm_up_iterations); |
| +#endif |
| + if (warm_up_iterations > 0) |
| + WarmUpRendering(warm_up_iterations); |
| // It's safe to use Unretained here since |rendering_thread_| will be stopped |
| // in VideoDecodeAcceleratorTest.TearDown(), while the |rendering_helper_| is |
| @@ -463,7 +536,11 @@ void RenderingHelper::DeleteTexture(uint32 texture_id) { |
| CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
| } |
| -void* RenderingHelper::GetGLContext() { |
| +scoped_refptr<gfx::GLContext> RenderingHelper::GetGLContext() { |
| + return gl_context_; |
| +} |
| + |
| +void* RenderingHelper::GetGLContextHandle() { |
| return gl_context_->GetHandle(); |
| } |
| @@ -485,7 +562,7 @@ void RenderingHelper::Clear() { |
| #if defined(OS_WIN) |
| if (window_) |
| DestroyWindow(window_); |
| -#else |
| +#elif defined(USE_X11) |
| // Destroy resources acquired in Initialize, in reverse-acquisition order. |
| if (window_) { |
| CHECK(XUnmapWindow(gfx::GetXDisplay(), window_)); |
| @@ -562,6 +639,9 @@ void RenderingHelper::RenderContent() { |
| RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); |
| need_swap_buffer = true; |
| } else { |
| + GLSetViewPort(gfx::Rect(screen_size_)); |
| + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| + 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
|
| for (RenderedVideo& video : videos_) { |
| if (video.pending_frames.empty()) |
| continue; |
| @@ -649,17 +729,20 @@ void RenderingHelper::UpdateVSyncParameters(base::WaitableEvent* done, |
| done->Signal(); |
| } |
| -void RenderingHelper::DropOneFrameForAllVideos() { |
| +uint32 RenderingHelper::DropOneFrameForAllVideos() { |
| + uint32 frames_dropped = 0; |
| for (RenderedVideo& video : videos_) { |
| if (video.pending_frames.empty()) |
| continue; |
| if (video.pending_frames.size() > 1 || video.is_flushing) { |
| + frames_dropped++; |
| video.pending_frames.pop(); |
| } else { |
| ++video.frames_to_drop; |
| } |
| } |
| + return frames_dropped; |
| } |
| void RenderingHelper::ScheduleNextRenderContent() { |
| @@ -675,11 +758,17 @@ void RenderingHelper::ScheduleNextRenderContent() { |
| target = vsync_timebase_ + intervals * vsync_interval_; |
| // When the rendering falls behind, drops frames. |
| - while (scheduled_render_time_ < target) { |
| - scheduled_render_time_ += frame_duration_; |
| - DropOneFrameForAllVideos(); |
| + if (frame_duration_ > base::TimeDelta()) { |
| + while (scheduled_render_time_ < target) { |
| + scheduled_render_time_ += frame_duration_; |
| + DropOneFrameForAllVideos(); |
| + } |
| + } else { |
| + // 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.
|
| + // possible. |
| + while (DropOneFrameForAllVideos() > 0) |
| + ; |
| } |
| - |
| message_loop_->PostDelayedTask( |
| FROM_HERE, render_task_.callback(), target - now); |
| } |