OLD | NEW |
---|---|
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 "ui/gl/gl_context.h" | 18 #include "ui/gl/gl_context.h" |
19 #include "ui/gl/gl_implementation.h" | 19 #include "ui/gl/gl_implementation.h" |
20 #include "ui/gl/gl_surface.h" | 20 #include "ui/gl/gl_surface.h" |
21 #include "ui/gl/gl_surface_egl.h" | 21 #include "ui/gl/gl_surface_egl.h" |
22 #include "ui/gl/gl_surface_glx.h" | |
23 | 22 |
24 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
25 #include <windows.h> | 24 #include <windows.h> |
26 #endif | 25 #endif |
27 | 26 |
28 #if defined(USE_X11) | 27 #if defined(USE_X11) |
29 #include "ui/gfx/x/x11_types.h" | 28 #include "ui/gfx/x/x11_types.h" |
30 #endif | 29 #include "ui/gl/gl_surface_glx.h" |
31 | |
32 #if !defined(OS_WIN) && defined(ARCH_CPU_X86_FAMILY) | |
33 #define GL_VARIANT_GLX 1 | 30 #define GL_VARIANT_GLX 1 |
34 #else | 31 #else |
35 #define GL_VARIANT_EGL 1 | 32 #define GL_VARIANT_EGL 1 |
36 #endif | 33 #endif |
37 | 34 |
35 #if defined(USE_OZONE) | |
36 #include "ui/ozone/public/ozone_platform.h" | |
37 #include "ui/ozone/public/ui_thread_gpu.h" | |
38 #include "ui/platform_window/platform_window.h" | |
39 #include "ui/platform_window/platform_window_delegate.h" | |
40 #endif | |
41 | |
38 // Helper for Shader creation. | 42 // Helper for Shader creation. |
39 static void CreateShader(GLuint program, | 43 static void CreateShader(GLuint program, |
40 GLenum type, | 44 GLenum type, |
41 const char* source, | 45 const char* source, |
42 int size) { | 46 int size) { |
43 GLuint shader = glCreateShader(type); | 47 GLuint shader = glCreateShader(type); |
44 glShaderSource(shader, 1, &source, &size); | 48 glShaderSource(shader, 1, &source, &size); |
45 glCompileShader(shader); | 49 glCompileShader(shader); |
46 int result = GL_FALSE; | 50 int result = GL_FALSE; |
47 glGetShaderiv(shader, GL_COMPILE_STATUS, &result); | 51 glGetShaderiv(shader, GL_COMPILE_STATUS, &result); |
48 if (!result) { | 52 if (!result) { |
49 char log[4096]; | 53 char log[4096]; |
50 glGetShaderInfoLog(shader, arraysize(log), NULL, log); | 54 glGetShaderInfoLog(shader, arraysize(log), NULL, log); |
51 LOG(FATAL) << log; | 55 LOG(FATAL) << log; |
52 } | 56 } |
53 glAttachShader(program, shader); | 57 glAttachShader(program, shader); |
54 glDeleteShader(shader); | 58 glDeleteShader(shader); |
55 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 59 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
56 } | 60 } |
57 | 61 |
58 namespace content { | 62 namespace content { |
59 | 63 |
64 #if defined(USE_OZONE) | |
65 | |
66 const int kTestWindowWidth = 800; | |
67 const int kTestWindowHeight = 600; | |
68 | |
69 class RenderingHelper::StubOzoneDelegate : public ui::PlatformWindowDelegate { | |
70 public: | |
71 StubOzoneDelegate() : widget_(gfx::kNullAcceleratedWidget) { | |
72 platform_window_ = ui::OzonePlatform::GetInstance()->CreatePlatformWindow( | |
73 this, gfx::Rect(kTestWindowWidth, kTestWindowHeight)); | |
74 } | |
75 virtual ~StubOzoneDelegate() {} | |
76 | |
77 virtual void OnBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE {} | |
78 | |
79 virtual void OnDamageRect(const gfx::Rect& damaged_region) OVERRIDE {} | |
80 | |
81 virtual void DispatchEvent(ui::Event* event) OVERRIDE {} | |
82 | |
83 virtual void OnCloseRequest() OVERRIDE {} | |
84 virtual void OnClosed() OVERRIDE {} | |
85 | |
86 virtual void OnWindowStateChanged( | |
87 ui::PlatformWindowState new_state) OVERRIDE{}; | |
Pawel Osciak
2014/10/08 08:17:21
I think we need a space before OVERRIDE (I may be
llandwerlin-old
2014/10/08 09:31:17
I did run git cl format and was a bit surprised th
| |
88 | |
89 virtual void OnLostCapture() OVERRIDE{}; | |
90 | |
91 virtual void OnAcceleratedWidgetAvailable( | |
92 gfx::AcceleratedWidget widget) OVERRIDE { | |
93 widget_ = widget; | |
94 }; | |
95 | |
96 virtual void OnActivationChanged(bool active) OVERRIDE{}; | |
97 | |
98 gfx::AcceleratedWidget GetAcceleratedWidget() const { return widget_; } | |
99 | |
100 gfx::Size GetSize() { return platform_window_->GetBounds().size(); } | |
101 | |
102 private: | |
103 scoped_ptr<ui::PlatformWindow> platform_window_; | |
104 gfx::AcceleratedWidget widget_; | |
105 }; | |
106 | |
107 #endif | |
108 | |
60 RenderingHelperParams::RenderingHelperParams() {} | 109 RenderingHelperParams::RenderingHelperParams() {} |
61 | 110 |
62 RenderingHelperParams::~RenderingHelperParams() {} | 111 RenderingHelperParams::~RenderingHelperParams() {} |
63 | 112 |
64 VideoFrameTexture::VideoFrameTexture(uint32 texture_target, | 113 VideoFrameTexture::VideoFrameTexture(uint32 texture_target, |
65 uint32 texture_id, | 114 uint32 texture_id, |
66 const base::Closure& no_longer_needed_cb) | 115 const base::Closure& no_longer_needed_cb) |
67 : texture_target_(texture_target), | 116 : texture_target_(texture_target), |
68 texture_id_(texture_id), | 117 texture_id_(texture_id), |
69 no_longer_needed_cb_(no_longer_needed_cb) { | 118 no_longer_needed_cb_(no_longer_needed_cb) { |
70 DCHECK(!no_longer_needed_cb_.is_null()); | 119 DCHECK(!no_longer_needed_cb_.is_null()); |
71 } | 120 } |
72 | 121 |
73 VideoFrameTexture::~VideoFrameTexture() { | 122 VideoFrameTexture::~VideoFrameTexture() { |
74 base::ResetAndReturn(&no_longer_needed_cb_).Run(); | 123 base::ResetAndReturn(&no_longer_needed_cb_).Run(); |
75 } | 124 } |
76 | 125 |
77 RenderingHelper::RenderedVideo::RenderedVideo() | 126 RenderingHelper::RenderedVideo::RenderedVideo() |
78 : last_frame_rendered(false), is_flushing(false) { | 127 : last_frame_rendered(false), is_flushing(false) { |
79 } | 128 } |
80 | 129 |
81 RenderingHelper::RenderedVideo::~RenderedVideo() { | 130 RenderingHelper::RenderedVideo::~RenderedVideo() { |
82 } | 131 } |
83 | 132 |
84 // static | 133 // static |
85 bool RenderingHelper::InitializeOneOff() { | 134 bool RenderingHelper::InitializeOneOff() { |
86 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 135 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
136 | |
87 #if GL_VARIANT_GLX | 137 #if GL_VARIANT_GLX |
88 cmd_line->AppendSwitchASCII(switches::kUseGL, | 138 cmd_line->AppendSwitchASCII(switches::kUseGL, |
89 gfx::kGLImplementationDesktopName); | 139 gfx::kGLImplementationDesktopName); |
90 #else | 140 #else |
91 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); | 141 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); |
92 #endif | 142 #endif |
143 | |
144 #if defined(USE_OZONE) | |
145 static ui::UiThreadGpu ui_thread_gpu; | |
146 ui::OzonePlatform::InitializeForUI(); | |
147 return gfx::GLSurface::InitializeOneOff() && ui_thread_gpu.Initialize(); | |
148 #else | |
93 return gfx::GLSurface::InitializeOneOff(); | 149 return gfx::GLSurface::InitializeOneOff(); |
150 #endif | |
94 } | 151 } |
95 | 152 |
96 RenderingHelper::RenderingHelper() { | 153 RenderingHelper::RenderingHelper() { |
97 window_ = gfx::kNullAcceleratedWidget; | 154 window_ = gfx::kNullAcceleratedWidget; |
98 Clear(); | 155 Clear(); |
99 } | 156 } |
100 | 157 |
101 RenderingHelper::~RenderingHelper() { | 158 RenderingHelper::~RenderingHelper() { |
102 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor."; | 159 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor."; |
103 Clear(); | 160 Clear(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 screen_size_.height(), | 214 screen_size_.height(), |
158 0 /* border width */, | 215 0 /* border width */, |
159 depth, | 216 depth, |
160 CopyFromParent /* class */, | 217 CopyFromParent /* class */, |
161 CopyFromParent /* visual */, | 218 CopyFromParent /* visual */, |
162 (CWBackPixel | CWOverrideRedirect), | 219 (CWBackPixel | CWOverrideRedirect), |
163 &window_attributes); | 220 &window_attributes); |
164 XStoreName(display, window_, "VideoDecodeAcceleratorTest"); | 221 XStoreName(display, window_, "VideoDecodeAcceleratorTest"); |
165 XSelectInput(display, window_, ExposureMask); | 222 XSelectInput(display, window_, ExposureMask); |
166 XMapWindow(display, window_); | 223 XMapWindow(display, window_); |
224 #elif defined(USE_OZONE) | |
225 platform_window_delegate_.reset(new RenderingHelper::StubOzoneDelegate()); | |
226 window_ = platform_window_delegate_->GetAcceleratedWidget(); | |
227 | |
228 screen_size_ = platform_window_delegate_->GetSize(); | |
167 #else | 229 #else |
168 #error unknown platform | 230 #error unknown platform |
169 #endif | 231 #endif |
170 CHECK(window_ != gfx::kNullAcceleratedWidget); | 232 CHECK(window_ != gfx::kNullAcceleratedWidget); |
171 | 233 |
172 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); | 234 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); |
173 gl_context_ = gfx::GLContext::CreateGLContext( | 235 gl_context_ = gfx::GLContext::CreateGLContext( |
174 NULL, gl_surface_, gfx::PreferIntegratedGpu); | 236 NULL, gl_surface_, gfx::PreferIntegratedGpu); |
175 gl_context_->MakeCurrent(gl_surface_); | 237 gl_context_->MakeCurrent(gl_surface_); |
176 | 238 |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 glBindTexture(texture_target, 0); | 485 glBindTexture(texture_target, 0); |
424 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 486 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
425 } | 487 } |
426 | 488 |
427 void RenderingHelper::DeleteTexture(uint32 texture_id) { | 489 void RenderingHelper::DeleteTexture(uint32 texture_id) { |
428 CHECK_EQ(base::MessageLoop::current(), message_loop_); | 490 CHECK_EQ(base::MessageLoop::current(), message_loop_); |
429 glDeleteTextures(1, &texture_id); | 491 glDeleteTextures(1, &texture_id); |
430 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 492 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
431 } | 493 } |
432 | 494 |
433 void* RenderingHelper::GetGLContext() { | 495 scoped_refptr<gfx::GLContext> RenderingHelper::GetGLContext() { |
496 return gl_context_; | |
497 } | |
498 | |
499 void* RenderingHelper::GetGLContextHandle() { | |
434 return gl_context_->GetHandle(); | 500 return gl_context_->GetHandle(); |
435 } | 501 } |
436 | 502 |
437 void* RenderingHelper::GetGLDisplay() { | 503 void* RenderingHelper::GetGLDisplay() { |
438 return gl_surface_->GetDisplay(); | 504 return gl_surface_->GetDisplay(); |
439 } | 505 } |
440 | 506 |
441 void RenderingHelper::Clear() { | 507 void RenderingHelper::Clear() { |
442 videos_.clear(); | 508 videos_.clear(); |
443 message_loop_ = NULL; | 509 message_loop_ = NULL; |
444 gl_context_ = NULL; | 510 gl_context_ = NULL; |
445 gl_surface_ = NULL; | 511 gl_surface_ = NULL; |
446 | 512 |
447 render_as_thumbnails_ = false; | 513 render_as_thumbnails_ = false; |
448 frame_count_ = 0; | 514 frame_count_ = 0; |
449 thumbnails_fbo_id_ = 0; | 515 thumbnails_fbo_id_ = 0; |
450 thumbnails_texture_id_ = 0; | 516 thumbnails_texture_id_ = 0; |
451 | 517 |
452 #if defined(OS_WIN) | 518 #if defined(OS_WIN) |
453 if (window_) | 519 if (window_) |
454 DestroyWindow(window_); | 520 DestroyWindow(window_); |
455 #else | 521 #elif defined(USE_X11) |
456 // Destroy resources acquired in Initialize, in reverse-acquisition order. | 522 // Destroy resources acquired in Initialize, in reverse-acquisition order. |
457 if (window_) { | 523 if (window_) { |
458 CHECK(XUnmapWindow(gfx::GetXDisplay(), window_)); | 524 CHECK(XUnmapWindow(gfx::GetXDisplay(), window_)); |
459 CHECK(XDestroyWindow(gfx::GetXDisplay(), window_)); | 525 CHECK(XDestroyWindow(gfx::GetXDisplay(), window_)); |
460 } | 526 } |
461 #endif | 527 #endif |
462 window_ = gfx::kNullAcceleratedWidget; | 528 window_ = gfx::kNullAcceleratedWidget; |
463 } | 529 } |
464 | 530 |
465 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, | 531 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
508 | 574 |
509 // Frames that will be returned to the client (via the no_longer_needed_cb) | 575 // Frames that will be returned to the client (via the no_longer_needed_cb) |
510 // after this vector falls out of scope at the end of this method. We need | 576 // after this vector falls out of scope at the end of this method. We need |
511 // to keep references to them until after SwapBuffers() call below. | 577 // to keep references to them until after SwapBuffers() call below. |
512 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; | 578 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; |
513 | 579 |
514 if (render_as_thumbnails_) { | 580 if (render_as_thumbnails_) { |
515 // In render_as_thumbnails_ mode, we render the FBO content on the | 581 // In render_as_thumbnails_ mode, we render the FBO content on the |
516 // screen instead of the decoded textures. | 582 // screen instead of the decoded textures. |
517 GLSetViewPort(videos_[0].render_area); | 583 GLSetViewPort(videos_[0].render_area); |
584 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
585 glClear(GL_COLOR_BUFFER_BIT); | |
518 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); | 586 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); |
519 } else { | 587 } else { |
588 GLSetViewPort(gfx::Rect(screen_size_)); | |
589 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
590 glClear(GL_COLOR_BUFFER_BIT); | |
591 | |
520 for (size_t i = 0; i < videos_.size(); ++i) { | 592 for (size_t i = 0; i < videos_.size(); ++i) { |
521 RenderedVideo* video = &videos_[i]; | 593 RenderedVideo* video = &videos_[i]; |
522 if (video->pending_frames.empty()) | 594 if (video->pending_frames.empty()) |
523 continue; | 595 continue; |
524 scoped_refptr<VideoFrameTexture> frame = video->pending_frames.front(); | 596 scoped_refptr<VideoFrameTexture> frame = video->pending_frames.front(); |
525 GLSetViewPort(video->render_area); | 597 GLSetViewPort(video->render_area); |
526 RenderTexture(frame->texture_target(), frame->texture_id()); | 598 RenderTexture(frame->texture_target(), frame->texture_id()); |
527 | 599 |
528 if (video->pending_frames.size() > 1 || video->is_flushing) { | 600 if (video->pending_frames.size() > 1 || video->is_flushing) { |
529 frames_to_be_returned.push_back(video->pending_frames.front()); | 601 frames_to_be_returned.push_back(video->pending_frames.front()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
585 scale = std::min(1.0f, scale); | 657 scale = std::min(1.0f, scale); |
586 | 658 |
587 size_t w = scale * size.width(); | 659 size_t w = scale * size.width(); |
588 size_t h = scale * size.height(); | 660 size_t h = scale * size.height(); |
589 size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; | 661 size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; |
590 size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; | 662 size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; |
591 videos_[i].render_area = gfx::Rect(x, y, w, h); | 663 videos_[i].render_area = gfx::Rect(x, y, w, h); |
592 } | 664 } |
593 } | 665 } |
594 } // namespace content | 666 } // namespace content |
OLD | NEW |