| 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 "media/gpu/rendering_helper.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <numeric> | 11 #include <numeric> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/bind.h" | 14 #include "base/bind.h" |
| 15 #include "base/callback_helpers.h" | 15 #include "base/callback_helpers.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 if (!result) { | 65 if (!result) { |
| 66 char log[4096]; | 66 char log[4096]; |
| 67 glGetShaderInfoLog(shader, arraysize(log), NULL, log); | 67 glGetShaderInfoLog(shader, arraysize(log), NULL, log); |
| 68 LOG(FATAL) << log; | 68 LOG(FATAL) << log; |
| 69 } | 69 } |
| 70 glAttachShader(program, shader); | 70 glAttachShader(program, shader); |
| 71 glDeleteShader(shader); | 71 glDeleteShader(shader); |
| 72 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 72 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
| 73 } | 73 } |
| 74 | 74 |
| 75 namespace content { | 75 namespace media { |
| 76 namespace { | 76 namespace { |
| 77 | 77 |
| 78 void WaitForSwapAck(const base::Closure& callback, gfx::SwapResult result) { | 78 void WaitForSwapAck(const base::Closure& callback, gfx::SwapResult result) { |
| 79 callback.Run(); | 79 callback.Run(); |
| 80 } | 80 } |
| 81 | 81 |
| 82 } // namespace | 82 } // namespace |
| 83 | 83 |
| 84 #if defined(USE_OZONE) | 84 #if defined(USE_OZONE) |
| 85 | 85 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 | 120 |
| 121 void OnDamageRect(const gfx::Rect& damaged_region) override {} | 121 void OnDamageRect(const gfx::Rect& damaged_region) override {} |
| 122 | 122 |
| 123 void DispatchEvent(ui::Event* event) override {} | 123 void DispatchEvent(ui::Event* event) override {} |
| 124 | 124 |
| 125 void OnCloseRequest() override {} | 125 void OnCloseRequest() override {} |
| 126 void OnClosed() override {} | 126 void OnClosed() override {} |
| 127 | 127 |
| 128 void OnWindowStateChanged(ui::PlatformWindowState new_state) override {} | 128 void OnWindowStateChanged(ui::PlatformWindowState new_state) override {} |
| 129 | 129 |
| 130 void OnLostCapture() override {}; | 130 void OnLostCapture() override{}; |
| 131 | 131 |
| 132 void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget, | 132 void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget, |
| 133 float device_pixel_ratio) override { | 133 float device_pixel_ratio) override { |
| 134 accelerated_widget_ = widget; | 134 accelerated_widget_ = widget; |
| 135 } | 135 } |
| 136 | 136 |
| 137 void OnAcceleratedWidgetDestroyed() override { | 137 void OnAcceleratedWidgetDestroyed() override { NOTREACHED(); } |
| 138 NOTREACHED(); | |
| 139 } | |
| 140 | 138 |
| 141 void OnActivationChanged(bool active) override {}; | 139 void OnActivationChanged(bool active) override{}; |
| 142 | 140 |
| 143 gfx::AcceleratedWidget accelerated_widget() const { | 141 gfx::AcceleratedWidget accelerated_widget() const { |
| 144 return accelerated_widget_; | 142 return accelerated_widget_; |
| 145 } | 143 } |
| 146 | 144 |
| 147 gfx::Size GetSize() { return platform_window_->GetBounds().size(); } | 145 gfx::Size GetSize() { return platform_window_->GetBounds().size(); } |
| 148 | 146 |
| 149 ui::PlatformWindow* platform_window() const { return platform_window_.get(); } | 147 ui::PlatformWindow* platform_window() const { return platform_window_.get(); } |
| 150 | 148 |
| 151 private: | 149 private: |
| 152 std::unique_ptr<ui::PlatformWindow> platform_window_; | 150 std::unique_ptr<ui::PlatformWindow> platform_window_; |
| 153 gfx::AcceleratedWidget accelerated_widget_; | 151 gfx::AcceleratedWidget accelerated_widget_; |
| 154 | 152 |
| 155 DISALLOW_COPY_AND_ASSIGN(StubOzoneDelegate); | 153 DISALLOW_COPY_AND_ASSIGN(StubOzoneDelegate); |
| 156 }; | 154 }; |
| 157 | 155 |
| 158 #endif // defined(USE_OZONE) | 156 #endif // defined(USE_OZONE) |
| 159 | 157 |
| 160 RenderingHelperParams::RenderingHelperParams() | 158 RenderingHelperParams::RenderingHelperParams() |
| 161 : rendering_fps(0), warm_up_iterations(0), render_as_thumbnails(false) { | 159 : rendering_fps(0), warm_up_iterations(0), render_as_thumbnails(false) {} |
| 162 } | |
| 163 | 160 |
| 164 RenderingHelperParams::RenderingHelperParams( | 161 RenderingHelperParams::RenderingHelperParams( |
| 165 const RenderingHelperParams& other) = default; | 162 const RenderingHelperParams& other) = default; |
| 166 | 163 |
| 167 RenderingHelperParams::~RenderingHelperParams() {} | 164 RenderingHelperParams::~RenderingHelperParams() {} |
| 168 | 165 |
| 169 VideoFrameTexture::VideoFrameTexture(uint32_t texture_target, | 166 VideoFrameTexture::VideoFrameTexture(uint32_t texture_target, |
| 170 uint32_t texture_id, | 167 uint32_t texture_id, |
| 171 const base::Closure& no_longer_needed_cb) | 168 const base::Closure& no_longer_needed_cb) |
| 172 : texture_target_(texture_target), | 169 : texture_target_(texture_target), |
| 173 texture_id_(texture_id), | 170 texture_id_(texture_id), |
| 174 no_longer_needed_cb_(no_longer_needed_cb) { | 171 no_longer_needed_cb_(no_longer_needed_cb) { |
| 175 DCHECK(!no_longer_needed_cb_.is_null()); | 172 DCHECK(!no_longer_needed_cb_.is_null()); |
| 176 } | 173 } |
| 177 | 174 |
| 178 VideoFrameTexture::~VideoFrameTexture() { | 175 VideoFrameTexture::~VideoFrameTexture() { |
| 179 base::ResetAndReturn(&no_longer_needed_cb_).Run(); | 176 base::ResetAndReturn(&no_longer_needed_cb_).Run(); |
| 180 } | 177 } |
| 181 | 178 |
| 182 RenderingHelper::RenderedVideo::RenderedVideo() | 179 RenderingHelper::RenderedVideo::RenderedVideo() |
| 183 : is_flushing(false), frames_to_drop(0) { | 180 : is_flushing(false), frames_to_drop(0) {} |
| 184 } | |
| 185 | 181 |
| 186 RenderingHelper::RenderedVideo::RenderedVideo(const RenderedVideo& other) = | 182 RenderingHelper::RenderedVideo::RenderedVideo(const RenderedVideo& other) = |
| 187 default; | 183 default; |
| 188 | 184 |
| 189 RenderingHelper::RenderedVideo::~RenderedVideo() { | 185 RenderingHelper::RenderedVideo::~RenderedVideo() {} |
| 190 } | |
| 191 | 186 |
| 192 // static | 187 // static |
| 193 void RenderingHelper::InitializeOneOff(base::WaitableEvent* done) { | 188 void RenderingHelper::InitializeOneOff(base::WaitableEvent* done) { |
| 194 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); | 189 base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); |
| 195 #if GL_VARIANT_GLX | 190 #if GL_VARIANT_GLX |
| 196 cmd_line->AppendSwitchASCII(switches::kUseGL, | 191 cmd_line->AppendSwitchASCII(switches::kUseGL, |
| 197 gfx::kGLImplementationDesktopName); | 192 gfx::kGLImplementationDesktopName); |
| 198 #else | 193 #else |
| 199 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); | 194 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); |
| 200 #endif | 195 #endif |
| 201 | 196 |
| 202 if (!gfx::GLSurface::InitializeOneOff()) | 197 if (!gfx::GLSurface::InitializeOneOff()) |
| 203 LOG(FATAL) << "Could not initialize GL"; | 198 LOG(FATAL) << "Could not initialize GL"; |
| 204 done->Signal(); | 199 done->Signal(); |
| 205 } | 200 } |
| 206 | 201 |
| 207 RenderingHelper::RenderingHelper() : ignore_vsync_(false) { | 202 RenderingHelper::RenderingHelper() : ignore_vsync_(false) { |
| 208 window_ = gfx::kNullAcceleratedWidget; | 203 window_ = gfx::kNullAcceleratedWidget; |
| 209 Clear(); | 204 Clear(); |
| 210 } | 205 } |
| 211 | 206 |
| 212 RenderingHelper::~RenderingHelper() { | 207 RenderingHelper::~RenderingHelper() { |
| 213 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor."; | 208 CHECK_EQ(videos_.size(), 0U) << "Must call UnInitialize before dtor."; |
| 214 Clear(); | 209 Clear(); |
| 215 } | 210 } |
| 216 | 211 |
| 217 void RenderingHelper::Setup() { | 212 void RenderingHelper::Setup() { |
| 218 #if defined(OS_WIN) | 213 #if defined(OS_WIN) |
| 219 window_ = CreateWindowEx(0, | 214 window_ = CreateWindowEx( |
| 220 L"Static", | 215 0, L"Static", L"VideoDecodeAcceleratorTest", |
| 221 L"VideoDecodeAcceleratorTest", | 216 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, GetSystemMetrics(SM_CXSCREEN), |
| 222 WS_OVERLAPPEDWINDOW | WS_VISIBLE, | 217 GetSystemMetrics(SM_CYSCREEN), NULL, NULL, NULL, NULL); |
| 223 0, | |
| 224 0, | |
| 225 GetSystemMetrics(SM_CXSCREEN), | |
| 226 GetSystemMetrics(SM_CYSCREEN), | |
| 227 NULL, | |
| 228 NULL, | |
| 229 NULL, | |
| 230 NULL); | |
| 231 #elif defined(USE_X11) | 218 #elif defined(USE_X11) |
| 232 Display* display = gfx::GetXDisplay(); | 219 Display* display = gfx::GetXDisplay(); |
| 233 Screen* screen = DefaultScreenOfDisplay(display); | 220 Screen* screen = DefaultScreenOfDisplay(display); |
| 234 | 221 |
| 235 CHECK(display); | 222 CHECK(display); |
| 236 | 223 |
| 237 XSetWindowAttributes window_attributes; | 224 XSetWindowAttributes window_attributes; |
| 238 memset(&window_attributes, 0, sizeof(window_attributes)); | 225 memset(&window_attributes, 0, sizeof(window_attributes)); |
| 239 window_attributes.background_pixel = | 226 window_attributes.background_pixel = |
| 240 BlackPixel(display, DefaultScreen(display)); | 227 BlackPixel(display, DefaultScreen(display)); |
| 241 window_attributes.override_redirect = true; | 228 window_attributes.override_redirect = true; |
| 242 int depth = DefaultDepth(display, DefaultScreen(display)); | 229 int depth = DefaultDepth(display, DefaultScreen(display)); |
| 243 | 230 |
| 244 window_ = XCreateWindow(display, | 231 window_ = XCreateWindow( |
| 245 DefaultRootWindow(display), | 232 display, DefaultRootWindow(display), 0, 0, XWidthOfScreen(screen), |
| 246 0, | 233 XHeightOfScreen(screen), 0 /* border width */, depth, |
| 247 0, | 234 CopyFromParent /* class */, CopyFromParent /* visual */, |
| 248 XWidthOfScreen(screen), | 235 (CWBackPixel | CWOverrideRedirect), &window_attributes); |
| 249 XHeightOfScreen(screen), | |
| 250 0 /* border width */, | |
| 251 depth, | |
| 252 CopyFromParent /* class */, | |
| 253 CopyFromParent /* visual */, | |
| 254 (CWBackPixel | CWOverrideRedirect), | |
| 255 &window_attributes); | |
| 256 XStoreName(display, window_, "VideoDecodeAcceleratorTest"); | 236 XStoreName(display, window_, "VideoDecodeAcceleratorTest"); |
| 257 XSelectInput(display, window_, ExposureMask); | 237 XSelectInput(display, window_, ExposureMask); |
| 258 XMapWindow(display, window_); | 238 XMapWindow(display, window_); |
| 259 #elif defined(USE_OZONE) | 239 #elif defined(USE_OZONE) |
| 260 base::MessageLoop::ScopedNestableTaskAllower nest_loop( | 240 base::MessageLoop::ScopedNestableTaskAllower nest_loop( |
| 261 base::MessageLoop::current()); | 241 base::MessageLoop::current()); |
| 262 base::RunLoop wait_window_resize; | 242 base::RunLoop wait_window_resize; |
| 263 | 243 |
| 264 platform_window_delegate_.reset(new RenderingHelper::StubOzoneDelegate()); | 244 platform_window_delegate_.reset(new RenderingHelper::StubOzoneDelegate()); |
| 265 window_ = platform_window_delegate_->accelerated_widget(); | 245 window_ = platform_window_delegate_->accelerated_widget(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 | 329 |
| 350 render_as_thumbnails_ = params.render_as_thumbnails; | 330 render_as_thumbnails_ = params.render_as_thumbnails; |
| 351 message_loop_ = base::MessageLoop::current(); | 331 message_loop_ = base::MessageLoop::current(); |
| 352 | 332 |
| 353 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); | 333 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); |
| 354 #if defined(USE_OZONE) | 334 #if defined(USE_OZONE) |
| 355 gl_surface_->Resize(platform_window_delegate_->GetSize(), 1.f, true); | 335 gl_surface_->Resize(platform_window_delegate_->GetSize(), 1.f, true); |
| 356 #endif // defined(USE_OZONE) | 336 #endif // defined(USE_OZONE) |
| 357 screen_size_ = gl_surface_->GetSize(); | 337 screen_size_ = gl_surface_->GetSize(); |
| 358 | 338 |
| 359 gl_context_ = gfx::GLContext::CreateGLContext( | 339 gl_context_ = gfx::GLContext::CreateGLContext(NULL, gl_surface_.get(), |
| 360 NULL, gl_surface_.get(), gfx::PreferIntegratedGpu); | 340 gfx::PreferIntegratedGpu); |
| 361 CHECK(gl_context_->MakeCurrent(gl_surface_.get())); | 341 CHECK(gl_context_->MakeCurrent(gl_surface_.get())); |
| 362 | 342 |
| 363 CHECK_GT(params.window_sizes.size(), 0U); | 343 CHECK_GT(params.window_sizes.size(), 0U); |
| 364 videos_.resize(params.window_sizes.size()); | 344 videos_.resize(params.window_sizes.size()); |
| 365 LayoutRenderingAreas(params.window_sizes); | 345 LayoutRenderingAreas(params.window_sizes); |
| 366 | 346 |
| 367 if (render_as_thumbnails_) { | 347 if (render_as_thumbnails_) { |
| 368 CHECK_EQ(videos_.size(), 1U); | 348 CHECK_EQ(videos_.size(), 1U); |
| 369 | 349 |
| 370 GLint max_texture_size; | 350 GLint max_texture_size; |
| 371 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); | 351 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); |
| 372 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); | 352 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); |
| 373 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); | 353 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); |
| 374 | 354 |
| 375 thumbnails_fbo_size_ = params.thumbnails_page_size; | 355 thumbnails_fbo_size_ = params.thumbnails_page_size; |
| 376 thumbnail_size_ = params.thumbnail_size; | 356 thumbnail_size_ = params.thumbnail_size; |
| 377 | 357 |
| 378 glGenFramebuffersEXT(1, &thumbnails_fbo_id_); | 358 glGenFramebuffersEXT(1, &thumbnails_fbo_id_); |
| 379 glGenTextures(1, &thumbnails_texture_id_); | 359 glGenTextures(1, &thumbnails_texture_id_); |
| 380 glBindTexture(GL_TEXTURE_2D, thumbnails_texture_id_); | 360 glBindTexture(GL_TEXTURE_2D, thumbnails_texture_id_); |
| 381 glTexImage2D(GL_TEXTURE_2D, | 361 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, thumbnails_fbo_size_.width(), |
| 382 0, | 362 thumbnails_fbo_size_.height(), 0, GL_RGB, |
| 383 GL_RGB, | 363 GL_UNSIGNED_SHORT_5_6_5, NULL); |
| 384 thumbnails_fbo_size_.width(), | |
| 385 thumbnails_fbo_size_.height(), | |
| 386 0, | |
| 387 GL_RGB, | |
| 388 GL_UNSIGNED_SHORT_5_6_5, | |
| 389 NULL); | |
| 390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 364 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 365 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 392 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 366 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 393 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 367 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 394 glBindTexture(GL_TEXTURE_2D, 0); | 368 glBindTexture(GL_TEXTURE_2D, 0); |
| 395 | 369 |
| 396 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); | 370 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); |
| 397 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, | 371 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
| 398 GL_COLOR_ATTACHMENT0, | 372 GL_TEXTURE_2D, thumbnails_texture_id_, 0); |
| 399 GL_TEXTURE_2D, | |
| 400 thumbnails_texture_id_, | |
| 401 0); | |
| 402 | 373 |
| 403 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 374 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| 404 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; | 375 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; |
| 405 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | 376 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |
| 406 glClear(GL_COLOR_BUFFER_BIT); | 377 glClear(GL_COLOR_BUFFER_BIT); |
| 407 glBindFramebufferEXT(GL_FRAMEBUFFER, | 378 glBindFramebufferEXT(GL_FRAMEBUFFER, |
| 408 gl_surface_->GetBackingFrameBufferObject()); | 379 gl_surface_->GetBackingFrameBufferObject()); |
| 409 } | 380 } |
| 410 | 381 |
| 411 // These vertices and texture coords. map (0,0) in the texture to the | 382 // These vertices and texture coords. map (0,0) in the texture to the |
| 412 // bottom left of the viewport. Since we get the video frames with the | 383 // bottom left of the viewport. Since we get the video frames with the |
| 413 // the top left at (0,0) we need to flip the texture y coordinate | 384 // the top left at (0,0) we need to flip the texture y coordinate |
| 414 // in the vertex shader for this to be rendered the right way up. | 385 // in the vertex shader for this to be rendered the right way up. |
| 415 // In the case of thumbnail rendering we use the same vertex shader | 386 // In the case of thumbnail rendering we use the same vertex shader |
| 416 // to render the FBO the screen, where we do not want this flipping. | 387 // to render the FBO the screen, where we do not want this flipping. |
| 417 static const float kVertices[] = | 388 static const float kVertices[] = { |
| 418 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, }; | 389 -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, |
| 419 static const float kTextureCoords[] = { 0, 1, 0, 0, 1, 1, 1, 0, }; | 390 }; |
| 420 static const char kVertexShader[] = STRINGIZE( | 391 static const float kTextureCoords[] = { |
| 421 varying vec2 interp_tc; | 392 0, 1, 0, 0, 1, 1, 1, 0, |
| 422 attribute vec4 in_pos; | 393 }; |
| 423 attribute vec2 in_tc; | 394 static const char kVertexShader[] = |
| 424 uniform bool tex_flip; | 395 STRINGIZE(varying vec2 interp_tc; attribute vec4 in_pos; |
| 425 void main() { | 396 attribute vec2 in_tc; uniform bool tex_flip; void main() { |
| 426 if (tex_flip) | 397 if (tex_flip) |
| 427 interp_tc = vec2(in_tc.x, 1.0 - in_tc.y); | 398 interp_tc = vec2(in_tc.x, 1.0 - in_tc.y); |
| 428 else | 399 else |
| 429 interp_tc = in_tc; | 400 interp_tc = in_tc; |
| 430 gl_Position = in_pos; | 401 gl_Position = in_pos; |
| 431 }); | 402 }); |
| 432 | 403 |
| 433 #if GL_VARIANT_EGL | 404 #if GL_VARIANT_EGL |
| 434 static const char kFragmentShader[] = | 405 static const char kFragmentShader[] = |
| 435 "#extension GL_OES_EGL_image_external : enable\n" | 406 "#extension GL_OES_EGL_image_external : enable\n" |
| 436 "precision mediump float;\n" | 407 "precision mediump float;\n" |
| 437 "varying vec2 interp_tc;\n" | 408 "varying vec2 interp_tc;\n" |
| 438 "uniform sampler2D tex;\n" | 409 "uniform sampler2D tex;\n" |
| 439 "#ifdef GL_OES_EGL_image_external\n" | 410 "#ifdef GL_OES_EGL_image_external\n" |
| 440 "uniform samplerExternalOES tex_external;\n" | 411 "uniform samplerExternalOES tex_external;\n" |
| 441 "#endif\n" | 412 "#endif\n" |
| 442 "void main() {\n" | 413 "void main() {\n" |
| 443 " vec4 color = texture2D(tex, interp_tc);\n" | 414 " vec4 color = texture2D(tex, interp_tc);\n" |
| 444 "#ifdef GL_OES_EGL_image_external\n" | 415 "#ifdef GL_OES_EGL_image_external\n" |
| 445 " color += texture2D(tex_external, interp_tc);\n" | 416 " color += texture2D(tex_external, interp_tc);\n" |
| 446 "#endif\n" | 417 "#endif\n" |
| 447 " gl_FragColor = color;\n" | 418 " gl_FragColor = color;\n" |
| 448 "}\n"; | 419 "}\n"; |
| 449 #else | 420 #else |
| 450 static const char kFragmentShader[] = STRINGIZE( | 421 static const char kFragmentShader[] = |
| 451 varying vec2 interp_tc; | 422 STRINGIZE(varying vec2 interp_tc; uniform sampler2D tex; |
| 452 uniform sampler2D tex; | 423 void main() { gl_FragColor = texture2D(tex, interp_tc); }); |
| 453 void main() { | |
| 454 gl_FragColor = texture2D(tex, interp_tc); | |
| 455 }); | |
| 456 #endif | 424 #endif |
| 457 program_ = glCreateProgram(); | 425 program_ = glCreateProgram(); |
| 458 CreateShader( | 426 CreateShader(program_, GL_VERTEX_SHADER, kVertexShader, |
| 459 program_, GL_VERTEX_SHADER, kVertexShader, arraysize(kVertexShader)); | 427 arraysize(kVertexShader)); |
| 460 CreateShader(program_, | 428 CreateShader(program_, GL_FRAGMENT_SHADER, kFragmentShader, |
| 461 GL_FRAGMENT_SHADER, | |
| 462 kFragmentShader, | |
| 463 arraysize(kFragmentShader)); | 429 arraysize(kFragmentShader)); |
| 464 glLinkProgram(program_); | 430 glLinkProgram(program_); |
| 465 int result = GL_FALSE; | 431 int result = GL_FALSE; |
| 466 glGetProgramiv(program_, GL_LINK_STATUS, &result); | 432 glGetProgramiv(program_, GL_LINK_STATUS, &result); |
| 467 if (!result) { | 433 if (!result) { |
| 468 char log[4096]; | 434 char log[4096]; |
| 469 glGetShaderInfoLog(program_, arraysize(log), NULL, log); | 435 glGetShaderInfoLog(program_, arraysize(log), NULL, log); |
| 470 LOG(FATAL) << log; | 436 LOG(FATAL) << log; |
| 471 } | 437 } |
| 472 glUseProgram(program_); | 438 glUseProgram(program_); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 | 484 |
| 519 // The rendering for the first few frames is slow (e.g., 100ms on Peach Pit). | 485 // The rendering for the first few frames is slow (e.g., 100ms on Peach Pit). |
| 520 // This affects the numbers measured in the performance test. We try to render | 486 // This affects the numbers measured in the performance test. We try to render |
| 521 // several frames here to warm up the rendering. | 487 // several frames here to warm up the rendering. |
| 522 void RenderingHelper::WarmUpRendering(int warm_up_iterations) { | 488 void RenderingHelper::WarmUpRendering(int warm_up_iterations) { |
| 523 unsigned int texture_id; | 489 unsigned int texture_id; |
| 524 std::unique_ptr<GLubyte[]> emptyData( | 490 std::unique_ptr<GLubyte[]> emptyData( |
| 525 new GLubyte[screen_size_.GetArea() * 2]()); | 491 new GLubyte[screen_size_.GetArea() * 2]()); |
| 526 glGenTextures(1, &texture_id); | 492 glGenTextures(1, &texture_id); |
| 527 glBindTexture(GL_TEXTURE_2D, texture_id); | 493 glBindTexture(GL_TEXTURE_2D, texture_id); |
| 528 glTexImage2D(GL_TEXTURE_2D, | 494 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_size_.width(), |
| 529 0, | 495 screen_size_.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, |
| 530 GL_RGB, | |
| 531 screen_size_.width(), | |
| 532 screen_size_.height(), | |
| 533 0, | |
| 534 GL_RGB, | |
| 535 GL_UNSIGNED_SHORT_5_6_5, | |
| 536 emptyData.get()); | 496 emptyData.get()); |
| 537 for (int i = 0; i < warm_up_iterations; ++i) { | 497 for (int i = 0; i < warm_up_iterations; ++i) { |
| 538 RenderTexture(GL_TEXTURE_2D, texture_id); | 498 RenderTexture(GL_TEXTURE_2D, texture_id); |
| 539 | 499 |
| 540 // Need to allow nestable tasks since WarmUpRendering() is called from | 500 // Need to allow nestable tasks since WarmUpRendering() is called from |
| 541 // within another task on the renderer thread. | 501 // within another task on the renderer thread. |
| 542 base::MessageLoop::ScopedNestableTaskAllower allow( | 502 base::MessageLoop::ScopedNestableTaskAllower allow( |
| 543 base::MessageLoop::current()); | 503 base::MessageLoop::current()); |
| 544 base::RunLoop wait_for_swap_ack; | 504 base::RunLoop wait_for_swap_ack; |
| 545 gl_surface_->SwapBuffersAsync( | 505 gl_surface_->SwapBuffersAsync( |
| (...skipping 19 matching lines...) Expand all Loading... |
| 565 | 525 |
| 566 Clear(); | 526 Clear(); |
| 567 done->Signal(); | 527 done->Signal(); |
| 568 } | 528 } |
| 569 | 529 |
| 570 void RenderingHelper::CreateTexture(uint32_t texture_target, | 530 void RenderingHelper::CreateTexture(uint32_t texture_target, |
| 571 uint32_t* texture_id, | 531 uint32_t* texture_id, |
| 572 const gfx::Size& size, | 532 const gfx::Size& size, |
| 573 base::WaitableEvent* done) { | 533 base::WaitableEvent* done) { |
| 574 if (base::MessageLoop::current() != message_loop_) { | 534 if (base::MessageLoop::current() != message_loop_) { |
| 575 message_loop_->PostTask(FROM_HERE, | 535 message_loop_->PostTask( |
| 576 base::Bind(&RenderingHelper::CreateTexture, | 536 FROM_HERE, |
| 577 base::Unretained(this), | 537 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), |
| 578 texture_target, | 538 texture_target, texture_id, size, done)); |
| 579 texture_id, | |
| 580 size, | |
| 581 done)); | |
| 582 return; | 539 return; |
| 583 } | 540 } |
| 584 glGenTextures(1, texture_id); | 541 glGenTextures(1, texture_id); |
| 585 glBindTexture(texture_target, *texture_id); | 542 glBindTexture(texture_target, *texture_id); |
| 586 if (texture_target == GL_TEXTURE_2D) { | 543 if (texture_target == GL_TEXTURE_2D) { |
| 587 glTexImage2D(GL_TEXTURE_2D, | 544 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, |
| 588 0, | 545 GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
| 589 GL_RGBA, | |
| 590 size.width(), | |
| 591 size.height(), | |
| 592 0, | |
| 593 GL_RGBA, | |
| 594 GL_UNSIGNED_BYTE, | |
| 595 NULL); | |
| 596 } | 546 } |
| 597 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 547 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 598 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 548 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 599 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. | 549 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. |
| 600 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 550 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 601 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 551 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 602 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 552 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
| 603 done->Signal(); | 553 done->Signal(); |
| 604 } | 554 } |
| 605 | 555 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 bool* alpha_solid, | 650 bool* alpha_solid, |
| 701 base::WaitableEvent* done) { | 651 base::WaitableEvent* done) { |
| 702 CHECK(render_as_thumbnails_); | 652 CHECK(render_as_thumbnails_); |
| 703 | 653 |
| 704 const size_t num_pixels = thumbnails_fbo_size_.GetArea(); | 654 const size_t num_pixels = thumbnails_fbo_size_.GetArea(); |
| 705 std::vector<unsigned char> rgba; | 655 std::vector<unsigned char> rgba; |
| 706 rgba.resize(num_pixels * 4); | 656 rgba.resize(num_pixels * 4); |
| 707 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); | 657 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); |
| 708 glPixelStorei(GL_PACK_ALIGNMENT, 1); | 658 glPixelStorei(GL_PACK_ALIGNMENT, 1); |
| 709 // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support. | 659 // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support. |
| 710 glReadPixels(0, | 660 glReadPixels(0, 0, thumbnails_fbo_size_.width(), |
| 711 0, | 661 thumbnails_fbo_size_.height(), GL_RGBA, GL_UNSIGNED_BYTE, |
| 712 thumbnails_fbo_size_.width(), | |
| 713 thumbnails_fbo_size_.height(), | |
| 714 GL_RGBA, | |
| 715 GL_UNSIGNED_BYTE, | |
| 716 &rgba[0]); | 662 &rgba[0]); |
| 717 glBindFramebufferEXT(GL_FRAMEBUFFER, | 663 glBindFramebufferEXT(GL_FRAMEBUFFER, |
| 718 gl_surface_->GetBackingFrameBufferObject()); | 664 gl_surface_->GetBackingFrameBufferObject()); |
| 719 rgb->resize(num_pixels * 3); | 665 rgb->resize(num_pixels * 3); |
| 720 // Drop the alpha channel, but check as we go that it is all 0xff. | 666 // Drop the alpha channel, but check as we go that it is all 0xff. |
| 721 bool solid = true; | 667 bool solid = true; |
| 722 unsigned char* rgb_ptr = &((*rgb)[0]); | 668 unsigned char* rgb_ptr = &((*rgb)[0]); |
| 723 unsigned char* rgba_ptr = &rgba[0]; | 669 unsigned char* rgba_ptr = &rgba[0]; |
| 724 for (size_t i = 0; i < num_pixels; ++i) { | 670 for (size_t i = 0; i < num_pixels; ++i) { |
| 725 *rgb_ptr++ = *rgba_ptr++; | 671 *rgb_ptr++ = *rgba_ptr++; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 756 #if defined(USE_OZONE) | 702 #if defined(USE_OZONE) |
| 757 // Ozone surfaceless renders flipped from normal GL, so there's no need to | 703 // Ozone surfaceless renders flipped from normal GL, so there's no need to |
| 758 // do an extra flip. | 704 // do an extra flip. |
| 759 tex_flip = 0; | 705 tex_flip = 0; |
| 760 #endif // defined(USE_OZONE) | 706 #endif // defined(USE_OZONE) |
| 761 glUniform1i(glGetUniformLocation(program_, "tex_flip"), tex_flip); | 707 glUniform1i(glGetUniformLocation(program_, "tex_flip"), tex_flip); |
| 762 | 708 |
| 763 // Frames that will be returned to the client (via the no_longer_needed_cb) | 709 // Frames that will be returned to the client (via the no_longer_needed_cb) |
| 764 // after this vector falls out of scope at the end of this method. We need | 710 // after this vector falls out of scope at the end of this method. We need |
| 765 // to keep references to them until after SwapBuffers() call below. | 711 // to keep references to them until after SwapBuffers() call below. |
| 766 std::vector<scoped_refptr<VideoFrameTexture> > frames_to_be_returned; | 712 std::vector<scoped_refptr<VideoFrameTexture>> frames_to_be_returned; |
| 767 bool need_swap_buffer = false; | 713 bool need_swap_buffer = false; |
| 768 if (render_as_thumbnails_) { | 714 if (render_as_thumbnails_) { |
| 769 // In render_as_thumbnails_ mode, we render the FBO content on the | 715 // In render_as_thumbnails_ mode, we render the FBO content on the |
| 770 // screen instead of the decoded textures. | 716 // screen instead of the decoded textures. |
| 771 GLSetViewPort(videos_[0].render_area); | 717 GLSetViewPort(videos_[0].render_area); |
| 772 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); | 718 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); |
| 773 need_swap_buffer = true; | 719 need_swap_buffer = true; |
| 774 } else { | 720 } else { |
| 775 for (RenderedVideo& video : videos_) { | 721 for (RenderedVideo& video : videos_) { |
| 776 if (video.pending_frames.empty()) | 722 if (video.pending_frames.empty()) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 789 } | 735 } |
| 790 } | 736 } |
| 791 | 737 |
| 792 base::Closure schedule_frame = base::Bind( | 738 base::Closure schedule_frame = base::Bind( |
| 793 &RenderingHelper::ScheduleNextRenderContent, base::Unretained(this)); | 739 &RenderingHelper::ScheduleNextRenderContent, base::Unretained(this)); |
| 794 if (!need_swap_buffer) { | 740 if (!need_swap_buffer) { |
| 795 schedule_frame.Run(); | 741 schedule_frame.Run(); |
| 796 return; | 742 return; |
| 797 } | 743 } |
| 798 | 744 |
| 799 gl_surface_->SwapBuffersAsync( | 745 gl_surface_->SwapBuffersAsync(base::Bind(&WaitForSwapAck, schedule_frame)); |
| 800 base::Bind(&WaitForSwapAck, schedule_frame)); | |
| 801 } | 746 } |
| 802 | 747 |
| 803 // Helper function for the LayoutRenderingAreas(). The |lengths| are the | 748 // Helper function for the LayoutRenderingAreas(). The |lengths| are the |
| 804 // heights(widths) of the rows(columns). It scales the elements in | 749 // heights(widths) of the rows(columns). It scales the elements in |
| 805 // |lengths| proportionally so that the sum of them equal to |total_length|. | 750 // |lengths| proportionally so that the sum of them equal to |total_length|. |
| 806 // It also outputs the coordinates of the rows(columns) to |offsets|. | 751 // It also outputs the coordinates of the rows(columns) to |offsets|. |
| 807 static void ScaleAndCalculateOffsets(std::vector<int>* lengths, | 752 static void ScaleAndCalculateOffsets(std::vector<int>* lengths, |
| 808 std::vector<int>* offsets, | 753 std::vector<int>* offsets, |
| 809 int total_length) { | 754 int total_length) { |
| 810 int sum = std::accumulate(lengths->begin(), lengths->end(), 0); | 755 int sum = std::accumulate(lengths->begin(), lengths->end(), 0); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 int64_t intervals = (target - vsync_timebase_) / vsync_interval_; | 837 int64_t intervals = (target - vsync_timebase_) / vsync_interval_; |
| 893 target = vsync_timebase_ + intervals * vsync_interval_; | 838 target = vsync_timebase_ + intervals * vsync_interval_; |
| 894 } | 839 } |
| 895 | 840 |
| 896 // When the rendering falls behind, drops frames. | 841 // When the rendering falls behind, drops frames. |
| 897 while (scheduled_render_time_ < target) { | 842 while (scheduled_render_time_ < target) { |
| 898 scheduled_render_time_ += frame_duration_; | 843 scheduled_render_time_ += frame_duration_; |
| 899 DropOneFrameForAllVideos(); | 844 DropOneFrameForAllVideos(); |
| 900 } | 845 } |
| 901 | 846 |
| 902 message_loop_->PostDelayedTask( | 847 message_loop_->PostDelayedTask(FROM_HERE, render_task_.callback(), |
| 903 FROM_HERE, render_task_.callback(), target - now); | 848 target - now); |
| 904 } | 849 } |
| 905 } // namespace content | 850 } // namespace media |
| OLD | NEW |