| 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> |
| 8 #include <numeric> |
| 9 #include <vector> |
| 10 |
| 7 #include "base/bind.h" | 11 #include "base/bind.h" |
| 8 #include "base/mac/scoped_nsautorelease_pool.h" | 12 #include "base/mac/scoped_nsautorelease_pool.h" |
| 9 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 10 #include "base/strings/stringize_macros.h" | 14 #include "base/strings/stringize_macros.h" |
| 11 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
| 12 #include "ui/gl/gl_context.h" | 16 #include "ui/gl/gl_context.h" |
| 13 #include "ui/gl/gl_context_stub_with_extensions.h" | 17 #include "ui/gl/gl_context_stub_with_extensions.h" |
| 14 #include "ui/gl/gl_implementation.h" | 18 #include "ui/gl/gl_implementation.h" |
| 15 #include "ui/gl/gl_surface.h" | 19 #include "ui/gl/gl_surface.h" |
| 16 | 20 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 #if defined(OS_WIN) | 76 #if defined(OS_WIN) |
| 73 window_ = NULL; | 77 window_ = NULL; |
| 74 #else | 78 #else |
| 75 x_window_ = (Window)0; | 79 x_window_ = (Window)0; |
| 76 #endif | 80 #endif |
| 77 | 81 |
| 78 Clear(); | 82 Clear(); |
| 79 } | 83 } |
| 80 | 84 |
| 81 RenderingHelper::~RenderingHelper() { | 85 RenderingHelper::~RenderingHelper() { |
| 82 CHECK_EQ(frame_dimensions_.size(), 0U) | 86 CHECK_EQ(clients_.size(), 0U) << "Must call UnInitialize before dtor."; |
| 83 << "Must call UnInitialize before dtor."; | |
| 84 Clear(); | 87 Clear(); |
| 85 } | 88 } |
| 86 | 89 |
| 87 void RenderingHelper::Initialize(const RenderingHelperParams& params, | 90 void RenderingHelper::Initialize(const RenderingHelperParams& params, |
| 88 base::WaitableEvent* done) { | 91 base::WaitableEvent* done) { |
| 89 // Use frame_dimensions_.size() != 0 as a proxy for the class having already | 92 // Use cients_.size() != 0 as a proxy for the class having already been |
| 90 // been Initialize()'d, and UnInitialize() before continuing. | 93 // Initialize()'d, and UnInitialize() before continuing. |
| 91 if (frame_dimensions_.size()) { | 94 if (clients_.size()) { |
| 92 base::WaitableEvent done(false, false); | 95 base::WaitableEvent done(false, false); |
| 93 UnInitialize(&done); | 96 UnInitialize(&done); |
| 94 done.Wait(); | 97 done.Wait(); |
| 95 } | 98 } |
| 96 | 99 |
| 97 frame_duration_ = params.rendering_fps > 0 | 100 frame_duration_ = params.rendering_fps > 0 |
| 98 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps | 101 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps |
| 99 : base::TimeDelta(); | 102 : base::TimeDelta(); |
| 100 | 103 |
| 101 gfx::InitializeStaticGLBindings(kGLImplementation); | 104 gfx::InitializeStaticGLBindings(kGLImplementation); |
| 102 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context( | 105 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context( |
| 103 new gfx::GLContextStubWithExtensions()); | 106 new gfx::GLContextStubWithExtensions()); |
| 104 | 107 |
| 105 CHECK_GT(params.window_dimensions.size(), 0U); | |
| 106 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size()); | |
| 107 frame_dimensions_ = params.frame_dimensions; | |
| 108 render_as_thumbnails_ = params.render_as_thumbnails; | 108 render_as_thumbnails_ = params.render_as_thumbnails; |
| 109 message_loop_ = base::MessageLoop::current(); | 109 message_loop_ = base::MessageLoop::current(); |
| 110 CHECK_GT(params.num_windows, 0); | |
| 111 | |
| 112 gfx::Size window_size; | |
| 113 | 110 |
| 114 #if GL_VARIANT_GLX | 111 #if GL_VARIANT_GLX |
| 115 x_display_ = gfx::GetXDisplay(); | 112 x_display_ = gfx::GetXDisplay(); |
| 116 CHECK(x_display_); | 113 CHECK(x_display_); |
| 117 CHECK(glXQueryVersion(x_display_, NULL, NULL)); | 114 CHECK(glXQueryVersion(x_display_, NULL, NULL)); |
| 118 const int fbconfig_attr[] = { | 115 const int fbconfig_attr[] = { |
| 119 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, | 116 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, |
| 120 GLX_RENDER_TYPE, GLX_RGBA_BIT, | 117 GLX_RENDER_TYPE, GLX_RGBA_BIT, |
| 121 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, | 118 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, |
| 122 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, | 119 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, |
| 123 GLX_DOUBLEBUFFER, True, | 120 GLX_DOUBLEBUFFER, True, |
| 124 GL_NONE, | 121 GL_NONE, |
| 125 }; | 122 }; |
| 126 int num_fbconfigs; | 123 int num_fbconfigs; |
| 127 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs( | 124 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs( |
| 128 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, | 125 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, |
| 129 &num_fbconfigs)); | 126 &num_fbconfigs)); |
| 130 CHECK(glx_fb_configs.get()); | 127 CHECK(glx_fb_configs.get()); |
| 131 CHECK_GT(num_fbconfigs, 0); | 128 CHECK_GT(num_fbconfigs, 0); |
| 132 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]); | 129 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]); |
| 133 CHECK(x_visual_); | 130 CHECK(x_visual_); |
| 134 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true); | 131 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true); |
| 135 CHECK(gl_context_); | 132 CHECK(gl_context_); |
| 136 stub_context->AddExtensionsString( | 133 stub_context->AddExtensionsString( |
| 137 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); | 134 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); |
| 138 stub_context->SetGLVersionString( | 135 stub_context->SetGLVersionString( |
| 139 reinterpret_cast<const char*>(glGetString(GL_VERSION))); | 136 reinterpret_cast<const char*>(glGetString(GL_VERSION))); |
| 140 | 137 |
| 141 Screen* screen = DefaultScreenOfDisplay(x_display_); | 138 Screen* screen = DefaultScreenOfDisplay(x_display_); |
| 142 window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); | 139 screen_size_ = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); |
| 143 #else // EGL | 140 #else // EGL |
| 144 EGLNativeDisplayType native_display; | 141 EGLNativeDisplayType native_display; |
| 145 | 142 |
| 146 #if defined(OS_WIN) | 143 #if defined(OS_WIN) |
| 147 native_display = EGL_DEFAULT_DISPLAY; | 144 native_display = EGL_DEFAULT_DISPLAY; |
| 148 window_size = | 145 screen_size_ = |
| 149 gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); | 146 gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); |
| 150 #else | 147 #else |
| 151 x_display_ = gfx::GetXDisplay(); | 148 x_display_ = gfx::GetXDisplay(); |
| 152 CHECK(x_display_); | 149 CHECK(x_display_); |
| 153 native_display = x_display_; | 150 native_display = x_display_; |
| 154 | 151 |
| 155 Screen* screen = DefaultScreenOfDisplay(x_display_); | 152 Screen* screen = DefaultScreenOfDisplay(x_display_); |
| 156 window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); | 153 screen_size_ = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); |
| 157 #endif | 154 #endif |
| 158 gl_display_ = eglGetDisplay(native_display); | 155 gl_display_ = eglGetDisplay(native_display); |
| 159 CHECK(gl_display_); | 156 CHECK(gl_display_); |
| 160 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError(); | 157 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError(); |
| 161 | 158 |
| 162 static EGLint rgba8888[] = { | 159 static EGLint rgba8888[] = { |
| 163 EGL_RED_SIZE, 8, | 160 EGL_RED_SIZE, 8, |
| 164 EGL_GREEN_SIZE, 8, | 161 EGL_GREEN_SIZE, 8, |
| 165 EGL_BLUE_SIZE, 8, | 162 EGL_BLUE_SIZE, 8, |
| 166 EGL_ALPHA_SIZE, 8, | 163 EGL_ALPHA_SIZE, 8, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 177 gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs); | 174 gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs); |
| 178 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError(); | 175 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError(); |
| 179 stub_context->AddExtensionsString( | 176 stub_context->AddExtensionsString( |
| 180 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); | 177 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); |
| 181 stub_context->AddExtensionsString( | 178 stub_context->AddExtensionsString( |
| 182 eglQueryString(gl_display_, EGL_EXTENSIONS)); | 179 eglQueryString(gl_display_, EGL_EXTENSIONS)); |
| 183 stub_context->SetGLVersionString( | 180 stub_context->SetGLVersionString( |
| 184 reinterpret_cast<const char*>(glGetString(GL_VERSION))); | 181 reinterpret_cast<const char*>(glGetString(GL_VERSION))); |
| 185 #endif | 182 #endif |
| 186 clients_ = params.clients; | 183 clients_ = params.clients; |
| 187 // Per-window/surface X11 & EGL initialization. | 184 CHECK_GT(clients_.size(), 0U); |
| 188 for (int i = 0; i < params.num_windows; ++i) { | 185 LayoutRenderingAreas(); |
| 189 // Arrange X windows whimsically, with some padding. | |
| 190 int j = i % params.window_dimensions.size(); | |
| 191 int width = params.window_dimensions[j].width(); | |
| 192 int height = params.window_dimensions[j].height(); | |
| 193 CHECK_GT(width, 0); | |
| 194 CHECK_GT(height, 0); | |
| 195 int top_left_x = (width + 20) * (i % 4); | |
| 196 int top_left_y = (height + 12) * (i % 3); | |
| 197 render_areas_.push_back(gfx::Rect(top_left_x, top_left_y, width, height)); | |
| 198 } | |
| 199 | 186 |
| 200 #if defined(OS_WIN) | 187 #if defined(OS_WIN) |
| 201 window_ = CreateWindowEx(0, | 188 window_ = CreateWindowEx(0, |
| 202 L"Static", | 189 L"Static", |
| 203 L"VideoDecodeAcceleratorTest", | 190 L"VideoDecodeAcceleratorTest", |
| 204 WS_OVERLAPPEDWINDOW | WS_VISIBLE, | 191 WS_OVERLAPPEDWINDOW | WS_VISIBLE, |
| 205 0, | 192 0, |
| 206 0, | 193 0, |
| 207 window_size.width(), | 194 screen_size_.width(), |
| 208 window_size.height(), | 195 screen_size_.height(), |
| 209 NULL, | 196 NULL, |
| 210 NULL, | 197 NULL, |
| 211 NULL, | 198 NULL, |
| 212 NULL); | 199 NULL); |
| 213 CHECK(window_ != NULL); | 200 CHECK(window_ != NULL); |
| 214 #else | 201 #else |
| 215 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); | 202 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); |
| 216 | 203 |
| 217 #if defined(GL_VARIANT_GLX) | 204 #if defined(GL_VARIANT_GLX) |
| 218 CHECK_EQ(depth, x_visual_->depth); | 205 CHECK_EQ(depth, x_visual_->depth); |
| 219 #endif | 206 #endif |
| 220 | 207 |
| 221 XSetWindowAttributes window_attributes; | 208 XSetWindowAttributes window_attributes; |
| 222 window_attributes.background_pixel = | 209 window_attributes.background_pixel = |
| 223 BlackPixel(x_display_, DefaultScreen(x_display_)); | 210 BlackPixel(x_display_, DefaultScreen(x_display_)); |
| 224 window_attributes.override_redirect = true; | 211 window_attributes.override_redirect = true; |
| 225 | 212 |
| 226 x_window_ = XCreateWindow(x_display_, | 213 x_window_ = XCreateWindow(x_display_, |
| 227 DefaultRootWindow(x_display_), | 214 DefaultRootWindow(x_display_), |
| 228 0, | 215 0, |
| 229 0, | 216 0, |
| 230 window_size.width(), | 217 screen_size_.width(), |
| 231 window_size.height(), | 218 screen_size_.height(), |
| 232 0 /* border width */, | 219 0 /* border width */, |
| 233 depth, | 220 depth, |
| 234 CopyFromParent /* class */, | 221 CopyFromParent /* class */, |
| 235 CopyFromParent /* visual */, | 222 CopyFromParent /* visual */, |
| 236 (CWBackPixel | CWOverrideRedirect), | 223 (CWBackPixel | CWOverrideRedirect), |
| 237 &window_attributes); | 224 &window_attributes); |
| 238 XStoreName(x_display_, x_window_, "VideoDecodeAcceleratorTest"); | 225 XStoreName(x_display_, x_window_, "VideoDecodeAcceleratorTest"); |
| 239 XSelectInput(x_display_, x_window_, ExposureMask); | 226 XSelectInput(x_display_, x_window_, ExposureMask); |
| 240 XMapWindow(x_display_, x_window_); | 227 XMapWindow(x_display_, x_window_); |
| 241 #endif | 228 #endif |
| (...skipping 13 matching lines...) Expand all Loading... |
| 255 CHECK(glXMakeContextCurrent(x_display_, x_window_, x_window_, gl_context_)); | 242 CHECK(glXMakeContextCurrent(x_display_, x_window_, x_window_, gl_context_)); |
| 256 #else // EGL | 243 #else // EGL |
| 257 CHECK(eglMakeCurrent(gl_display_, gl_surface_, gl_surface_, gl_context_)) | 244 CHECK(eglMakeCurrent(gl_display_, gl_surface_, gl_surface_, gl_context_)) |
| 258 << eglGetError(); | 245 << eglGetError(); |
| 259 #endif | 246 #endif |
| 260 | 247 |
| 261 // Must be done after a context is made current. | 248 // Must be done after a context is made current. |
| 262 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get()); | 249 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get()); |
| 263 | 250 |
| 264 if (render_as_thumbnails_) { | 251 if (render_as_thumbnails_) { |
| 265 CHECK_EQ(frame_dimensions_.size(), 1U); | 252 CHECK_EQ(clients_.size(), 1U); |
| 266 | 253 |
| 267 GLint max_texture_size; | 254 GLint max_texture_size; |
| 268 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); | 255 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); |
| 269 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); | 256 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); |
| 270 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); | 257 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); |
| 271 | 258 |
| 272 thumbnails_fbo_size_ = params.thumbnails_page_size; | 259 thumbnails_fbo_size_ = params.thumbnails_page_size; |
| 273 thumbnail_size_ = params.thumbnail_size; | 260 thumbnail_size_ = params.thumbnail_size; |
| 274 | 261 |
| 275 glGenFramebuffersEXT(1, &thumbnails_fbo_id_); | 262 glGenFramebuffersEXT(1, &thumbnails_fbo_id_); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 #else // EGL | 387 #else // EGL |
| 401 CHECK(eglDestroyContext(gl_display_, gl_context_)); | 388 CHECK(eglDestroyContext(gl_display_, gl_context_)); |
| 402 CHECK(eglDestroySurface(gl_display_, gl_surface_)); | 389 CHECK(eglDestroySurface(gl_display_, gl_surface_)); |
| 403 CHECK(eglTerminate(gl_display_)); | 390 CHECK(eglTerminate(gl_display_)); |
| 404 #endif | 391 #endif |
| 405 gfx::ClearGLBindings(); | 392 gfx::ClearGLBindings(); |
| 406 Clear(); | 393 Clear(); |
| 407 done->Signal(); | 394 done->Signal(); |
| 408 } | 395 } |
| 409 | 396 |
| 410 void RenderingHelper::CreateTexture(int window_id, | 397 void RenderingHelper::CreateTexture(uint32 texture_target, |
| 411 uint32 texture_target, | |
| 412 uint32* texture_id, | 398 uint32* texture_id, |
| 399 const gfx::Size& size, |
| 413 base::WaitableEvent* done) { | 400 base::WaitableEvent* done) { |
| 414 if (base::MessageLoop::current() != message_loop_) { | 401 if (base::MessageLoop::current() != message_loop_) { |
| 415 message_loop_->PostTask( | 402 message_loop_->PostTask(FROM_HERE, |
| 416 FROM_HERE, | 403 base::Bind(&RenderingHelper::CreateTexture, |
| 417 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), | 404 base::Unretained(this), |
| 418 window_id, texture_target, texture_id, done)); | 405 texture_target, |
| 406 texture_id, |
| 407 size, |
| 408 done)); |
| 419 return; | 409 return; |
| 420 } | 410 } |
| 421 glGenTextures(1, texture_id); | 411 glGenTextures(1, texture_id); |
| 422 glBindTexture(texture_target, *texture_id); | 412 glBindTexture(texture_target, *texture_id); |
| 423 int dimensions_id = window_id % frame_dimensions_.size(); | |
| 424 if (texture_target == GL_TEXTURE_2D) { | 413 if (texture_target == GL_TEXTURE_2D) { |
| 425 glTexImage2D(GL_TEXTURE_2D, | 414 glTexImage2D(GL_TEXTURE_2D, |
| 426 0, | 415 0, |
| 427 GL_RGBA, | 416 GL_RGBA, |
| 428 frame_dimensions_[dimensions_id].width(), | 417 size.width(), |
| 429 frame_dimensions_[dimensions_id].height(), | 418 size.height(), |
| 430 0, | 419 0, |
| 431 GL_RGBA, | 420 GL_RGBA, |
| 432 GL_UNSIGNED_BYTE, | 421 GL_UNSIGNED_BYTE, |
| 433 NULL); | 422 NULL); |
| 434 } | 423 } |
| 435 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 424 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 436 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 425 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 437 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. | 426 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. |
| 438 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 427 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 439 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 428 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 440 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 429 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
| 441 CHECK(texture_id_to_surface_index_.insert( | |
| 442 std::make_pair(*texture_id, window_id)).second); | |
| 443 done->Signal(); | 430 done->Signal(); |
| 444 } | 431 } |
| 445 | 432 |
| 446 // Helper function to set GL viewport. | 433 // Helper function to set GL viewport. |
| 447 static inline void GLSetViewPort(const gfx::Rect& area) { | 434 static inline void GLSetViewPort(const gfx::Rect& area) { |
| 448 glViewport(area.x(), area.y(), area.width(), area.height()); | 435 glViewport(area.x(), area.y(), area.width(), area.height()); |
| 449 glScissor(area.x(), area.y(), area.width(), area.height()); | 436 glScissor(area.x(), area.y(), area.width(), area.height()); |
| 450 } | 437 } |
| 451 | 438 |
| 452 void RenderingHelper::RenderThumbnail(uint32 texture_target, | 439 void RenderingHelper::RenderThumbnail(uint32 texture_target, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 | 484 |
| 498 void* RenderingHelper::GetGLDisplay() { | 485 void* RenderingHelper::GetGLDisplay() { |
| 499 #if GL_VARIANT_GLX | 486 #if GL_VARIANT_GLX |
| 500 return x_display_; | 487 return x_display_; |
| 501 #else // EGL | 488 #else // EGL |
| 502 return gl_display_; | 489 return gl_display_; |
| 503 #endif | 490 #endif |
| 504 } | 491 } |
| 505 | 492 |
| 506 void RenderingHelper::Clear() { | 493 void RenderingHelper::Clear() { |
| 507 frame_dimensions_.clear(); | 494 clients_.clear(); |
| 508 texture_id_to_surface_index_.clear(); | |
| 509 message_loop_ = NULL; | 495 message_loop_ = NULL; |
| 510 gl_context_ = NULL; | 496 gl_context_ = NULL; |
| 511 #if GL_VARIANT_EGL | 497 #if GL_VARIANT_EGL |
| 512 gl_display_ = EGL_NO_DISPLAY; | 498 gl_display_ = EGL_NO_DISPLAY; |
| 513 gl_surface_ = EGL_NO_SURFACE; | 499 gl_surface_ = EGL_NO_SURFACE; |
| 514 #endif | 500 #endif |
| 515 render_as_thumbnails_ = false; | 501 render_as_thumbnails_ = false; |
| 516 frame_count_ = 0; | 502 frame_count_ = 0; |
| 517 thumbnails_fbo_id_ = 0; | 503 thumbnails_fbo_id_ = 0; |
| 518 thumbnails_texture_id_ = 0; | 504 thumbnails_texture_id_ = 0; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 } | 573 } |
| 588 } | 574 } |
| 589 | 575 |
| 590 #if GL_VARIANT_GLX | 576 #if GL_VARIANT_GLX |
| 591 glXSwapBuffers(x_display_, x_window_); | 577 glXSwapBuffers(x_display_, x_window_); |
| 592 #else // EGL | 578 #else // EGL |
| 593 eglSwapBuffers(gl_display_, gl_surface_); | 579 eglSwapBuffers(gl_display_, gl_surface_); |
| 594 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); | 580 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); |
| 595 #endif | 581 #endif |
| 596 } | 582 } |
| 583 |
| 584 // Helper function for the LayoutRenderingAreas(). The |lengths| are the |
| 585 // heights(widths) of the rows(columns). It scales the elements in |
| 586 // |lengths| proportionally so that the sum of them equal to |total_length|. |
| 587 // It also outputs the coordinates of the rows(columns) to |offsets|. |
| 588 static void ScaleAndCalculateOffsets(std::vector<int>* lengths, |
| 589 std::vector<int>* offsets, |
| 590 int total_length) { |
| 591 int sum = std::accumulate(lengths->begin(), lengths->end(), 0); |
| 592 for (size_t i = 0; i < lengths->size(); ++i) { |
| 593 lengths->at(i) = lengths->at(i) * total_length / sum; |
| 594 offsets->at(i) = (i == 0) ? 0 : offsets->at(i - 1) + lengths->at(i - 1); |
| 595 } |
| 596 } |
| 597 |
| 598 void RenderingHelper::LayoutRenderingAreas() { |
| 599 // Find the number of colums and rows. |
| 600 // The smallest n * n or n * (n + 1) > number of clients. |
| 601 size_t cols = sqrt(clients_.size() - 1) + 1; |
| 602 size_t rows = (clients_.size() + cols - 1) / cols; |
| 603 |
| 604 // Find the widths and heights of the grid. |
| 605 std::vector<int> widths(cols); |
| 606 std::vector<int> heights(rows); |
| 607 std::vector<int> offset_x(cols); |
| 608 std::vector<int> offset_y(rows); |
| 609 |
| 610 for (size_t i = 0; i < clients_.size(); ++i) { |
| 611 const gfx::Size& window_size = clients_[i]->GetWindowSize(); |
| 612 widths[i % cols] = std::max(widths[i % cols], window_size.width()); |
| 613 heights[i / cols] = std::max(heights[i / cols], window_size.height()); |
| 614 } |
| 615 |
| 616 ScaleAndCalculateOffsets(&widths, &offset_x, screen_size_.width()); |
| 617 ScaleAndCalculateOffsets(&heights, &offset_y, screen_size_.height()); |
| 618 |
| 619 // Put each render_area_ in the center of each cell. |
| 620 render_areas_.clear(); |
| 621 for (size_t i = 0; i < clients_.size(); ++i) { |
| 622 const gfx::Size& window_size = clients_[i]->GetWindowSize(); |
| 623 float scale = |
| 624 std::min(static_cast<float>(widths[i % cols]) / window_size.width(), |
| 625 static_cast<float>(heights[i / cols]) / window_size.height()); |
| 626 |
| 627 // Don't scale up the texture. |
| 628 scale = std::min(1.0f, scale); |
| 629 |
| 630 size_t w = scale * window_size.width(); |
| 631 size_t h = scale * window_size.height(); |
| 632 size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; |
| 633 size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; |
| 634 render_areas_.push_back(gfx::Rect(x, y, w, h)); |
| 635 } |
| 636 } |
| 597 } // namespace content | 637 } // namespace content |
| OLD | NEW |