| 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_ = |
| 73 ui::OzonePlatform::GetInstance()->CreatePlatformWindow( |
| 74 this, gfx::Rect(kTestWindowWidth, kTestWindowHeight)); |
| 75 } |
| 76 virtual ~StubOzoneDelegate() {} |
| 77 |
| 78 virtual void OnBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE {} |
| 79 |
| 80 virtual void OnDamageRect(const gfx::Rect& damaged_region) OVERRIDE {} |
| 81 |
| 82 virtual void DispatchEvent(ui::Event* event) OVERRIDE {} |
| 83 |
| 84 virtual void OnCloseRequest() OVERRIDE {} |
| 85 virtual void OnClosed() OVERRIDE {} |
| 86 |
| 87 virtual void OnWindowStateChanged( |
| 88 ui::PlatformWindowState new_state) OVERRIDE {}; |
| 89 |
| 90 virtual void OnLostCapture() OVERRIDE {}; |
| 91 |
| 92 virtual void OnAcceleratedWidgetAvailable( |
| 93 gfx::AcceleratedWidget widget) OVERRIDE { |
| 94 widget_ = widget; |
| 95 }; |
| 96 |
| 97 virtual void OnActivationChanged(bool active) OVERRIDE {}; |
| 98 |
| 99 gfx::AcceleratedWidget GetAcceleratedWidget() const { return widget_; } |
| 100 |
| 101 gfx::Size GetSize() { return platform_window_->GetBounds().size(); } |
| 102 |
| 103 private: |
| 104 scoped_ptr<ui::PlatformWindow> platform_window_; |
| 105 gfx::AcceleratedWidget widget_; |
| 106 }; |
| 107 |
| 108 #endif |
| 109 |
| 110 |
| 60 RenderingHelperParams::RenderingHelperParams() {} | 111 RenderingHelperParams::RenderingHelperParams() {} |
| 61 | 112 |
| 62 RenderingHelperParams::~RenderingHelperParams() {} | 113 RenderingHelperParams::~RenderingHelperParams() {} |
| 63 | 114 |
| 64 VideoFrameTexture::VideoFrameTexture(uint32 texture_target, | 115 VideoFrameTexture::VideoFrameTexture(uint32 texture_target, |
| 65 uint32 texture_id, | 116 uint32 texture_id, |
| 66 const base::Closure& no_longer_needed_cb) | 117 const base::Closure& no_longer_needed_cb) |
| 67 : texture_target_(texture_target), | 118 : texture_target_(texture_target), |
| 68 texture_id_(texture_id), | 119 texture_id_(texture_id), |
| 69 no_longer_needed_cb_(no_longer_needed_cb) { | 120 no_longer_needed_cb_(no_longer_needed_cb) { |
| 70 DCHECK(!no_longer_needed_cb_.is_null()); | 121 DCHECK(!no_longer_needed_cb_.is_null()); |
| 71 } | 122 } |
| 72 | 123 |
| 73 VideoFrameTexture::~VideoFrameTexture() { | 124 VideoFrameTexture::~VideoFrameTexture() { |
| 74 base::ResetAndReturn(&no_longer_needed_cb_).Run(); | 125 base::ResetAndReturn(&no_longer_needed_cb_).Run(); |
| 75 } | 126 } |
| 76 | 127 |
| 77 RenderingHelper::RenderedVideo::RenderedVideo() | 128 RenderingHelper::RenderedVideo::RenderedVideo() |
| 78 : last_frame_rendered(false), is_flushing(false) { | 129 : last_frame_rendered(false), is_flushing(false) { |
| 79 } | 130 } |
| 80 | 131 |
| 81 RenderingHelper::RenderedVideo::~RenderedVideo() { | 132 RenderingHelper::RenderedVideo::~RenderedVideo() { |
| 82 } | 133 } |
| 83 | 134 |
| 84 // static | 135 // static |
| 85 bool RenderingHelper::InitializeOneOff() { | 136 bool RenderingHelper::InitializeOneOff() { |
| 86 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 137 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
| 138 |
| 87 #if GL_VARIANT_GLX | 139 #if GL_VARIANT_GLX |
| 88 cmd_line->AppendSwitchASCII(switches::kUseGL, | 140 cmd_line->AppendSwitchASCII(switches::kUseGL, |
| 89 gfx::kGLImplementationDesktopName); | 141 gfx::kGLImplementationDesktopName); |
| 90 #else | 142 #else |
| 91 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); | 143 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); |
| 92 #endif | 144 #endif |
| 145 |
| 146 #if defined(USE_OZONE) |
| 147 static ui::UiThreadGpu ui_thread_gpu; |
| 148 ui::OzonePlatform::InitializeForUI(); |
| 149 return gfx::GLSurface::InitializeOneOff() && ui_thread_gpu.Initialize(); |
| 150 #else |
| 93 return gfx::GLSurface::InitializeOneOff(); | 151 return gfx::GLSurface::InitializeOneOff(); |
| 152 #endif |
| 94 } | 153 } |
| 95 | 154 |
| 96 RenderingHelper::RenderingHelper() { | 155 RenderingHelper::RenderingHelper() { |
| 97 window_ = gfx::kNullAcceleratedWidget; | 156 window_ = gfx::kNullAcceleratedWidget; |
| 98 Clear(); | 157 Clear(); |
| 99 } | 158 } |
| 100 | 159 |
| 101 RenderingHelper::~RenderingHelper() { | 160 RenderingHelper::~RenderingHelper() { |
| 102 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor."; | 161 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor."; |
| 103 Clear(); | 162 Clear(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 screen_size_.height(), | 216 screen_size_.height(), |
| 158 0 /* border width */, | 217 0 /* border width */, |
| 159 depth, | 218 depth, |
| 160 CopyFromParent /* class */, | 219 CopyFromParent /* class */, |
| 161 CopyFromParent /* visual */, | 220 CopyFromParent /* visual */, |
| 162 (CWBackPixel | CWOverrideRedirect), | 221 (CWBackPixel | CWOverrideRedirect), |
| 163 &window_attributes); | 222 &window_attributes); |
| 164 XStoreName(display, window_, "VideoDecodeAcceleratorTest"); | 223 XStoreName(display, window_, "VideoDecodeAcceleratorTest"); |
| 165 XSelectInput(display, window_, ExposureMask); | 224 XSelectInput(display, window_, ExposureMask); |
| 166 XMapWindow(display, window_); | 225 XMapWindow(display, window_); |
| 226 #elif defined(USE_OZONE) |
| 227 platform_window_delegate_.reset(new RenderingHelper::StubOzoneDelegate()); |
| 228 window_ = platform_window_delegate_->GetAcceleratedWidget(); |
| 229 |
| 230 screen_size_ = platform_window_delegate_->GetSize(); |
| 167 #else | 231 #else |
| 168 #error unknown platform | 232 #error unknown platform |
| 169 #endif | 233 #endif |
| 170 CHECK(window_ != gfx::kNullAcceleratedWidget); | 234 CHECK(window_ != gfx::kNullAcceleratedWidget); |
| 171 | 235 |
| 172 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); | 236 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); |
| 173 gl_context_ = gfx::GLContext::CreateGLContext( | 237 gl_context_ = gfx::GLContext::CreateGLContext( |
| 174 NULL, gl_surface_, gfx::PreferIntegratedGpu); | 238 NULL, gl_surface_, gfx::PreferIntegratedGpu); |
| 175 gl_context_->MakeCurrent(gl_surface_); | 239 gl_context_->MakeCurrent(gl_surface_); |
| 176 | 240 |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 glBindTexture(texture_target, 0); | 487 glBindTexture(texture_target, 0); |
| 424 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 488 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
| 425 } | 489 } |
| 426 | 490 |
| 427 void RenderingHelper::DeleteTexture(uint32 texture_id) { | 491 void RenderingHelper::DeleteTexture(uint32 texture_id) { |
| 428 CHECK_EQ(base::MessageLoop::current(), message_loop_); | 492 CHECK_EQ(base::MessageLoop::current(), message_loop_); |
| 429 glDeleteTextures(1, &texture_id); | 493 glDeleteTextures(1, &texture_id); |
| 430 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 494 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
| 431 } | 495 } |
| 432 | 496 |
| 433 void* RenderingHelper::GetGLContext() { | 497 scoped_refptr<gfx::GLContext> RenderingHelper::GetGLContext() { |
| 498 return gl_context_; |
| 499 } |
| 500 |
| 501 void* RenderingHelper::GetGLContextHandle() { |
| 434 return gl_context_->GetHandle(); | 502 return gl_context_->GetHandle(); |
| 435 } | 503 } |
| 436 | 504 |
| 437 void* RenderingHelper::GetGLDisplay() { | 505 void* RenderingHelper::GetGLDisplay() { |
| 438 return gl_surface_->GetDisplay(); | 506 return gl_surface_->GetDisplay(); |
| 439 } | 507 } |
| 440 | 508 |
| 441 void RenderingHelper::Clear() { | 509 void RenderingHelper::Clear() { |
| 442 videos_.clear(); | 510 videos_.clear(); |
| 443 message_loop_ = NULL; | 511 message_loop_ = NULL; |
| 444 gl_context_ = NULL; | 512 gl_context_ = NULL; |
| 445 gl_surface_ = NULL; | 513 gl_surface_ = NULL; |
| 446 | 514 |
| 447 render_as_thumbnails_ = false; | 515 render_as_thumbnails_ = false; |
| 448 frame_count_ = 0; | 516 frame_count_ = 0; |
| 449 thumbnails_fbo_id_ = 0; | 517 thumbnails_fbo_id_ = 0; |
| 450 thumbnails_texture_id_ = 0; | 518 thumbnails_texture_id_ = 0; |
| 451 | 519 |
| 452 #if defined(OS_WIN) | 520 #if defined(OS_WIN) |
| 453 if (window_) | 521 if (window_) |
| 454 DestroyWindow(window_); | 522 DestroyWindow(window_); |
| 455 #else | 523 #elif defined(USE_X11) |
| 456 // Destroy resources acquired in Initialize, in reverse-acquisition order. | 524 // Destroy resources acquired in Initialize, in reverse-acquisition order. |
| 457 if (window_) { | 525 if (window_) { |
| 458 CHECK(XUnmapWindow(gfx::GetXDisplay(), window_)); | 526 CHECK(XUnmapWindow(gfx::GetXDisplay(), window_)); |
| 459 CHECK(XDestroyWindow(gfx::GetXDisplay(), window_)); | 527 CHECK(XDestroyWindow(gfx::GetXDisplay(), window_)); |
| 460 } | 528 } |
| 461 #endif | 529 #endif |
| 462 window_ = gfx::kNullAcceleratedWidget; | 530 window_ = gfx::kNullAcceleratedWidget; |
| 463 } | 531 } |
| 464 | 532 |
| 465 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, | 533 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 | 565 |
| 498 done->Signal(); | 566 done->Signal(); |
| 499 } | 567 } |
| 500 | 568 |
| 501 void RenderingHelper::Flush(size_t window_id) { | 569 void RenderingHelper::Flush(size_t window_id) { |
| 502 videos_[window_id].is_flushing = true; | 570 videos_[window_id].is_flushing = true; |
| 503 } | 571 } |
| 504 | 572 |
| 505 void RenderingHelper::RenderContent() { | 573 void RenderingHelper::RenderContent() { |
| 506 CHECK_EQ(base::MessageLoop::current(), message_loop_); | 574 CHECK_EQ(base::MessageLoop::current(), message_loop_); |
| 575 |
| 507 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); | 576 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); |
| 508 | 577 |
| 509 // Frames that will be returned to the client (via the no_longer_needed_cb) | 578 // 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 | 579 // 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. | 580 // to keep references to them until after SwapBuffers() call below. |
| 512 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; | 581 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; |
| 513 | 582 |
| 514 if (render_as_thumbnails_) { | 583 if (render_as_thumbnails_) { |
| 515 // In render_as_thumbnails_ mode, we render the FBO content on the | 584 // In render_as_thumbnails_ mode, we render the FBO content on the |
| 516 // screen instead of the decoded textures. | 585 // screen instead of the decoded textures. |
| 517 GLSetViewPort(videos_[0].render_area); | 586 GLSetViewPort(videos_[0].render_area); |
| 587 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| 588 glClear(GL_COLOR_BUFFER_BIT); |
| 518 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); | 589 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); |
| 519 } else { | 590 } else { |
| 591 GLSetViewPort(gfx::Rect(screen_size_)); |
| 592 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| 593 glClear(GL_COLOR_BUFFER_BIT); |
| 594 |
| 520 for (size_t i = 0; i < videos_.size(); ++i) { | 595 for (size_t i = 0; i < videos_.size(); ++i) { |
| 521 RenderedVideo* video = &videos_[i]; | 596 RenderedVideo* video = &videos_[i]; |
| 522 if (video->pending_frames.empty()) | 597 if (video->pending_frames.empty()) |
| 523 continue; | 598 continue; |
| 524 scoped_refptr<VideoFrameTexture> frame = video->pending_frames.front(); | 599 scoped_refptr<VideoFrameTexture> frame = video->pending_frames.front(); |
| 525 GLSetViewPort(video->render_area); | 600 GLSetViewPort(video->render_area); |
| 526 RenderTexture(frame->texture_target(), frame->texture_id()); | 601 RenderTexture(frame->texture_target(), frame->texture_id()); |
| 527 | 602 |
| 528 if (video->pending_frames.size() > 1 || video->is_flushing) { | 603 if (video->pending_frames.size() > 1 || video->is_flushing) { |
| 529 frames_to_be_returned.push_back(video->pending_frames.front()); | 604 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); | 660 scale = std::min(1.0f, scale); |
| 586 | 661 |
| 587 size_t w = scale * size.width(); | 662 size_t w = scale * size.width(); |
| 588 size_t h = scale * size.height(); | 663 size_t h = scale * size.height(); |
| 589 size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; | 664 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; | 665 size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; |
| 591 videos_[i].render_area = gfx::Rect(x, y, w, h); | 666 videos_[i].render_area = gfx::Rect(x, y, w, h); |
| 592 } | 667 } |
| 593 } | 668 } |
| 594 } // namespace content | 669 } // namespace content |
| OLD | NEW |