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/command_line.h" |
12 #include "base/mac/scoped_nsautorelease_pool.h" | 13 #include "base/mac/scoped_nsautorelease_pool.h" |
13 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
14 #include "base/strings/stringize_macros.h" | 15 #include "base/strings/stringize_macros.h" |
15 #include "base/synchronization/waitable_event.h" | 16 #include "base/synchronization/waitable_event.h" |
16 #include "ui/gl/gl_context.h" | 17 #include "ui/gl/gl_context.h" |
17 #include "ui/gl/gl_context_stub_with_extensions.h" | |
18 #include "ui/gl/gl_implementation.h" | 18 #include "ui/gl/gl_implementation.h" |
19 #include "ui/gl/gl_surface.h" | 19 #include "ui/gl/gl_surface.h" |
| 20 #include "ui/gl/gl_surface_egl.h" |
| 21 #include "ui/gl/gl_surface_glx.h" |
20 | 22 |
21 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
22 #include <windows.h> | 24 #include <windows.h> |
23 #endif | 25 #endif |
24 | 26 |
25 #if defined(USE_X11) | 27 #if defined(USE_X11) |
26 #include "ui/gfx/x/x11_types.h" | 28 #include "ui/gfx/x/x11_types.h" |
27 #endif | 29 #endif |
28 | 30 |
29 #ifdef GL_VARIANT_GLX | 31 #if !defined(OS_WIN) && defined(ARCH_CPU_X86_FAMILY) |
30 struct XFreeDeleter { | 32 #define GL_VARIANT_GLX 1 |
31 void operator()(void* x) const { ::XFree(x); } | 33 #else |
32 }; | 34 #define GL_VARIANT_EGL 1 |
33 #endif | 35 #endif |
34 | 36 |
35 // Helper for Shader creation. | 37 // Helper for Shader creation. |
36 static void CreateShader(GLuint program, | 38 static void CreateShader(GLuint program, |
37 GLenum type, | 39 GLenum type, |
38 const char* source, | 40 const char* source, |
39 int size) { | 41 int size) { |
40 GLuint shader = glCreateShader(type); | 42 GLuint shader = glCreateShader(type); |
41 glShaderSource(shader, 1, &source, &size); | 43 glShaderSource(shader, 1, &source, &size); |
42 glCompileShader(shader); | 44 glCompileShader(shader); |
43 int result = GL_FALSE; | 45 int result = GL_FALSE; |
44 glGetShaderiv(shader, GL_COMPILE_STATUS, &result); | 46 glGetShaderiv(shader, GL_COMPILE_STATUS, &result); |
45 if (!result) { | 47 if (!result) { |
46 char log[4096]; | 48 char log[4096]; |
47 glGetShaderInfoLog(shader, arraysize(log), NULL, log); | 49 glGetShaderInfoLog(shader, arraysize(log), NULL, log); |
48 LOG(FATAL) << log; | 50 LOG(FATAL) << log; |
49 } | 51 } |
50 glAttachShader(program, shader); | 52 glAttachShader(program, shader); |
51 glDeleteShader(shader); | 53 glDeleteShader(shader); |
52 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 54 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
53 } | 55 } |
54 | 56 |
55 namespace content { | 57 namespace content { |
56 | 58 |
57 RenderingHelperParams::RenderingHelperParams() {} | 59 RenderingHelperParams::RenderingHelperParams() {} |
58 | 60 |
59 RenderingHelperParams::~RenderingHelperParams() {} | 61 RenderingHelperParams::~RenderingHelperParams() {} |
60 | 62 |
61 static const gfx::GLImplementation kGLImplementation = | 63 // static |
62 #if defined(GL_VARIANT_GLX) | 64 bool RenderingHelper::InitializeOneOff() { |
63 gfx::kGLImplementationDesktopGL; | 65 CommandLine* cmd_line = CommandLine::ForCurrentProcess(); |
64 #elif defined(GL_VARIANT_EGL) | 66 #if GL_VARIANT_GLX |
65 gfx::kGLImplementationEGLGLES2; | 67 cmd_line->AppendSwitchASCII(switches::kUseGL, |
| 68 gfx::kGLImplementationDesktopName); |
66 #else | 69 #else |
67 -1; | 70 cmd_line->AppendSwitchASCII(switches::kUseGL, gfx::kGLImplementationEGLName); |
68 #error "Unknown GL implementation." | |
69 #endif | 71 #endif |
| 72 return gfx::GLSurface::InitializeOneOff(); |
| 73 } |
70 | 74 |
71 RenderingHelper::RenderingHelper() { | 75 RenderingHelper::RenderingHelper() { |
72 #if defined(GL_VARIANT_EGL) | 76 window_ = gfx::kNullAcceleratedWidget; |
73 gl_surface_ = EGL_NO_SURFACE; | |
74 #endif | |
75 | |
76 #if defined(OS_WIN) | |
77 window_ = NULL; | |
78 #else | |
79 x_window_ = (Window)0; | |
80 #endif | |
81 | |
82 Clear(); | 77 Clear(); |
83 } | 78 } |
84 | 79 |
85 RenderingHelper::~RenderingHelper() { | 80 RenderingHelper::~RenderingHelper() { |
86 CHECK_EQ(clients_.size(), 0U) << "Must call UnInitialize before dtor."; | 81 CHECK_EQ(clients_.size(), 0U) << "Must call UnInitialize before dtor."; |
87 Clear(); | 82 Clear(); |
88 } | 83 } |
89 | 84 |
90 void RenderingHelper::Initialize(const RenderingHelperParams& params, | 85 void RenderingHelper::Initialize(const RenderingHelperParams& params, |
91 base::WaitableEvent* done) { | 86 base::WaitableEvent* done) { |
92 // Use cients_.size() != 0 as a proxy for the class having already been | 87 // Use cients_.size() != 0 as a proxy for the class having already been |
93 // Initialize()'d, and UnInitialize() before continuing. | 88 // Initialize()'d, and UnInitialize() before continuing. |
94 if (clients_.size()) { | 89 if (clients_.size()) { |
95 base::WaitableEvent done(false, false); | 90 base::WaitableEvent done(false, false); |
96 UnInitialize(&done); | 91 UnInitialize(&done); |
97 done.Wait(); | 92 done.Wait(); |
98 } | 93 } |
99 | 94 |
100 frame_duration_ = params.rendering_fps > 0 | 95 frame_duration_ = params.rendering_fps > 0 |
101 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps | 96 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps |
102 : base::TimeDelta(); | 97 : base::TimeDelta(); |
103 | 98 |
104 gfx::InitializeStaticGLBindings(kGLImplementation); | |
105 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context( | |
106 new gfx::GLContextStubWithExtensions()); | |
107 | |
108 render_as_thumbnails_ = params.render_as_thumbnails; | 99 render_as_thumbnails_ = params.render_as_thumbnails; |
109 message_loop_ = base::MessageLoop::current(); | 100 message_loop_ = base::MessageLoop::current(); |
110 | 101 |
111 #if GL_VARIANT_GLX | |
112 x_display_ = gfx::GetXDisplay(); | |
113 CHECK(x_display_); | |
114 CHECK(glXQueryVersion(x_display_, NULL, NULL)); | |
115 const int fbconfig_attr[] = { | |
116 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, | |
117 GLX_RENDER_TYPE, GLX_RGBA_BIT, | |
118 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, | |
119 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, | |
120 GLX_DOUBLEBUFFER, True, | |
121 GL_NONE, | |
122 }; | |
123 int num_fbconfigs; | |
124 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs( | |
125 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, | |
126 &num_fbconfigs)); | |
127 CHECK(glx_fb_configs.get()); | |
128 CHECK_GT(num_fbconfigs, 0); | |
129 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]); | |
130 CHECK(x_visual_); | |
131 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true); | |
132 CHECK(gl_context_); | |
133 stub_context->AddExtensionsString( | |
134 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); | |
135 stub_context->SetGLVersionString( | |
136 reinterpret_cast<const char*>(glGetString(GL_VERSION))); | |
137 | |
138 Screen* screen = DefaultScreenOfDisplay(x_display_); | |
139 screen_size_ = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); | |
140 #else // EGL | |
141 EGLNativeDisplayType native_display; | |
142 | |
143 #if defined(OS_WIN) | 102 #if defined(OS_WIN) |
144 native_display = EGL_DEFAULT_DISPLAY; | |
145 screen_size_ = | 103 screen_size_ = |
146 gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); | 104 gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); |
147 #else | |
148 x_display_ = gfx::GetXDisplay(); | |
149 CHECK(x_display_); | |
150 native_display = x_display_; | |
151 | |
152 Screen* screen = DefaultScreenOfDisplay(x_display_); | |
153 screen_size_ = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); | |
154 #endif | |
155 gl_display_ = eglGetDisplay(native_display); | |
156 CHECK(gl_display_); | |
157 CHECK(eglInitialize(gl_display_, NULL, NULL)) << eglGetError(); | |
158 | |
159 static EGLint rgba8888[] = { | |
160 EGL_RED_SIZE, 8, | |
161 EGL_GREEN_SIZE, 8, | |
162 EGL_BLUE_SIZE, 8, | |
163 EGL_ALPHA_SIZE, 8, | |
164 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, | |
165 EGL_NONE, | |
166 }; | |
167 EGLConfig egl_config; | |
168 int num_configs; | |
169 CHECK(eglChooseConfig(gl_display_, rgba8888, &egl_config, 1, &num_configs)) | |
170 << eglGetError(); | |
171 CHECK_GE(num_configs, 1); | |
172 static EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; | |
173 gl_context_ = eglCreateContext( | |
174 gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs); | |
175 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError(); | |
176 stub_context->AddExtensionsString( | |
177 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); | |
178 stub_context->AddExtensionsString( | |
179 eglQueryString(gl_display_, EGL_EXTENSIONS)); | |
180 stub_context->SetGLVersionString( | |
181 reinterpret_cast<const char*>(glGetString(GL_VERSION))); | |
182 #endif | |
183 clients_ = params.clients; | |
184 CHECK_GT(clients_.size(), 0U); | |
185 LayoutRenderingAreas(); | |
186 | |
187 #if defined(OS_WIN) | |
188 window_ = CreateWindowEx(0, | 105 window_ = CreateWindowEx(0, |
189 L"Static", | 106 L"Static", |
190 L"VideoDecodeAcceleratorTest", | 107 L"VideoDecodeAcceleratorTest", |
191 WS_OVERLAPPEDWINDOW | WS_VISIBLE, | 108 WS_OVERLAPPEDWINDOW | WS_VISIBLE, |
192 0, | 109 0, |
193 0, | 110 0, |
194 screen_size_.width(), | 111 screen_size_.width(), |
195 screen_size_.height(), | 112 screen_size_.height(), |
196 NULL, | 113 NULL, |
197 NULL, | 114 NULL, |
198 NULL, | 115 NULL, |
199 NULL); | 116 NULL); |
200 CHECK(window_ != NULL); | 117 #elif defined(USE_X11) |
201 #else | 118 Display* display = gfx::GetXDisplay(); |
202 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); | 119 Screen* screen = DefaultScreenOfDisplay(display); |
| 120 screen_size_ = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen)); |
203 | 121 |
204 #if defined(GL_VARIANT_GLX) | 122 CHECK(display); |
205 CHECK_EQ(depth, x_visual_->depth); | |
206 #endif | |
207 | 123 |
208 XSetWindowAttributes window_attributes; | 124 XSetWindowAttributes window_attributes; |
| 125 memset(&window_attributes, 0, sizeof(window_attributes)); |
209 window_attributes.background_pixel = | 126 window_attributes.background_pixel = |
210 BlackPixel(x_display_, DefaultScreen(x_display_)); | 127 BlackPixel(display, DefaultScreen(display)); |
211 window_attributes.override_redirect = true; | 128 window_attributes.override_redirect = true; |
| 129 int depth = DefaultDepth(display, DefaultScreen(display)); |
212 | 130 |
213 x_window_ = XCreateWindow(x_display_, | 131 window_ = XCreateWindow(display, |
214 DefaultRootWindow(x_display_), | 132 DefaultRootWindow(display), |
215 0, | 133 0, |
216 0, | 134 0, |
217 screen_size_.width(), | 135 screen_size_.width(), |
218 screen_size_.height(), | 136 screen_size_.height(), |
219 0 /* border width */, | 137 0 /* border width */, |
220 depth, | 138 depth, |
221 CopyFromParent /* class */, | 139 CopyFromParent /* class */, |
222 CopyFromParent /* visual */, | 140 CopyFromParent /* visual */, |
223 (CWBackPixel | CWOverrideRedirect), | 141 (CWBackPixel | CWOverrideRedirect), |
224 &window_attributes); | 142 &window_attributes); |
225 XStoreName(x_display_, x_window_, "VideoDecodeAcceleratorTest"); | 143 XStoreName(display, window_, "VideoDecodeAcceleratorTest"); |
226 XSelectInput(x_display_, x_window_, ExposureMask); | 144 XSelectInput(display, window_, ExposureMask); |
227 XMapWindow(x_display_, x_window_); | 145 XMapWindow(display, window_); |
| 146 #else |
| 147 #error unknown platform |
228 #endif | 148 #endif |
| 149 CHECK(window_ != gfx::kNullAcceleratedWidget); |
229 | 150 |
230 #if GL_VARIANT_EGL | 151 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(window_); |
231 #if defined(OS_WIN) | 152 gl_context_ = gfx::GLContext::CreateGLContext( |
232 gl_surface_ = | 153 NULL, gl_surface_, gfx::PreferIntegratedGpu); |
233 eglCreateWindowSurface(gl_display_, egl_config, window_, NULL); | 154 gl_context_->MakeCurrent(gl_surface_); |
234 #else | |
235 gl_surface_ = | |
236 eglCreateWindowSurface(gl_display_, egl_config, x_window_, NULL); | |
237 #endif | |
238 CHECK_NE(gl_surface_, EGL_NO_SURFACE); | |
239 #endif | |
240 | 155 |
241 #if GL_VARIANT_GLX | 156 clients_ = params.clients; |
242 CHECK(glXMakeContextCurrent(x_display_, x_window_, x_window_, gl_context_)); | 157 CHECK_GT(clients_.size(), 0U); |
243 #else // EGL | 158 LayoutRenderingAreas(); |
244 CHECK(eglMakeCurrent(gl_display_, gl_surface_, gl_surface_, gl_context_)) | |
245 << eglGetError(); | |
246 #endif | |
247 | |
248 // Must be done after a context is made current. | |
249 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get()); | |
250 | 159 |
251 if (render_as_thumbnails_) { | 160 if (render_as_thumbnails_) { |
252 CHECK_EQ(clients_.size(), 1U); | 161 CHECK_EQ(clients_.size(), 1U); |
253 | 162 |
254 GLint max_texture_size; | 163 GLint max_texture_size; |
255 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); | 164 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); |
256 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); | 165 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); |
257 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); | 166 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); |
258 | 167 |
259 thumbnails_fbo_size_ = params.thumbnails_page_size; | 168 thumbnails_fbo_size_ = params.thumbnails_page_size; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { | 288 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { |
380 CHECK_EQ(base::MessageLoop::current(), message_loop_); | 289 CHECK_EQ(base::MessageLoop::current(), message_loop_); |
381 | 290 |
382 // Deletion will also stop the timer. | 291 // Deletion will also stop the timer. |
383 render_timer_.reset(); | 292 render_timer_.reset(); |
384 | 293 |
385 if (render_as_thumbnails_) { | 294 if (render_as_thumbnails_) { |
386 glDeleteTextures(1, &thumbnails_texture_id_); | 295 glDeleteTextures(1, &thumbnails_texture_id_); |
387 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); | 296 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); |
388 } | 297 } |
389 #if GL_VARIANT_GLX | |
390 | 298 |
391 glXDestroyContext(x_display_, gl_context_); | 299 gl_context_->ReleaseCurrent(gl_surface_); |
392 #else // EGL | 300 gl_context_ = NULL; |
393 CHECK(eglMakeCurrent( | 301 gl_surface_ = NULL; |
394 gl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) | 302 |
395 << eglGetError(); | |
396 CHECK(eglDestroyContext(gl_display_, gl_context_)); | |
397 CHECK(eglDestroySurface(gl_display_, gl_surface_)); | |
398 CHECK(eglTerminate(gl_display_)); | |
399 #endif | |
400 gfx::ClearGLBindings(); | |
401 Clear(); | 303 Clear(); |
402 done->Signal(); | 304 done->Signal(); |
403 } | 305 } |
404 | 306 |
405 void RenderingHelper::CreateTexture(uint32 texture_target, | 307 void RenderingHelper::CreateTexture(uint32 texture_target, |
406 uint32* texture_id, | 308 uint32* texture_id, |
407 const gfx::Size& size, | 309 const gfx::Size& size, |
408 base::WaitableEvent* done) { | 310 base::WaitableEvent* done) { |
409 if (base::MessageLoop::current() != message_loop_) { | 311 if (base::MessageLoop::current() != message_loop_) { |
410 message_loop_->PostTask(FROM_HERE, | 312 message_loop_->PostTask(FROM_HERE, |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 378 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
477 glBindTexture(texture_target, 0); | 379 glBindTexture(texture_target, 0); |
478 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 380 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
479 } | 381 } |
480 | 382 |
481 void RenderingHelper::DeleteTexture(uint32 texture_id) { | 383 void RenderingHelper::DeleteTexture(uint32 texture_id) { |
482 glDeleteTextures(1, &texture_id); | 384 glDeleteTextures(1, &texture_id); |
483 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 385 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
484 } | 386 } |
485 | 387 |
486 NativeContextType RenderingHelper::GetGLContext() { return gl_context_; } | 388 void* RenderingHelper::GetGLContext() { |
| 389 return gl_context_->GetHandle(); |
| 390 } |
487 | 391 |
488 void* RenderingHelper::GetGLDisplay() { | 392 void* RenderingHelper::GetGLDisplay() { |
489 #if GL_VARIANT_GLX | 393 return gl_surface_->GetDisplay(); |
490 return x_display_; | |
491 #else // EGL | |
492 return gl_display_; | |
493 #endif | |
494 } | 394 } |
495 | 395 |
496 void RenderingHelper::Clear() { | 396 void RenderingHelper::Clear() { |
497 clients_.clear(); | 397 clients_.clear(); |
498 message_loop_ = NULL; | 398 message_loop_ = NULL; |
499 gl_context_ = NULL; | 399 gl_context_ = NULL; |
500 #if GL_VARIANT_EGL | 400 gl_surface_ = NULL; |
501 gl_display_ = EGL_NO_DISPLAY; | 401 |
502 gl_surface_ = EGL_NO_SURFACE; | |
503 #endif | |
504 render_as_thumbnails_ = false; | 402 render_as_thumbnails_ = false; |
505 frame_count_ = 0; | 403 frame_count_ = 0; |
506 thumbnails_fbo_id_ = 0; | 404 thumbnails_fbo_id_ = 0; |
507 thumbnails_texture_id_ = 0; | 405 thumbnails_texture_id_ = 0; |
508 | 406 |
509 #if defined(OS_WIN) | 407 #if defined(OS_WIN) |
510 if (window_) { | 408 if (window_) |
511 DestroyWindow(window_); | 409 DestroyWindow(window_); |
512 window_ = NULL; | |
513 } | |
514 #else | 410 #else |
515 // Destroy resources acquired in Initialize, in reverse-acquisition order. | 411 // Destroy resources acquired in Initialize, in reverse-acquisition order. |
516 if (x_window_) { | 412 if (window_) { |
517 CHECK(XUnmapWindow(x_display_, x_window_)); | 413 CHECK(XUnmapWindow(gfx::GetXDisplay(), window_)); |
518 CHECK(XDestroyWindow(x_display_, x_window_)); | 414 CHECK(XDestroyWindow(gfx::GetXDisplay(), window_)); |
519 x_window_ = (Window)0; | |
520 } | 415 } |
521 // Mimic newly created object. | |
522 x_display_ = NULL; | |
523 #endif | 416 #endif |
| 417 window_ = gfx::kNullAcceleratedWidget; |
524 } | 418 } |
525 | 419 |
526 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, | 420 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, |
527 bool* alpha_solid, | 421 bool* alpha_solid, |
528 base::WaitableEvent* done) { | 422 base::WaitableEvent* done) { |
529 CHECK(render_as_thumbnails_); | 423 CHECK(render_as_thumbnails_); |
530 | 424 |
531 const size_t num_pixels = thumbnails_fbo_size_.GetArea(); | 425 const size_t num_pixels = thumbnails_fbo_size_.GetArea(); |
532 std::vector<unsigned char> rgba; | 426 std::vector<unsigned char> rgba; |
533 rgba.resize(num_pixels * 4); | 427 rgba.resize(num_pixels * 4); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); | 464 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_); |
571 } else { | 465 } else { |
572 for (size_t i = 0; i < clients_.size(); ++i) { | 466 for (size_t i = 0; i < clients_.size(); ++i) { |
573 if (clients_[i]) { | 467 if (clients_[i]) { |
574 GLSetViewPort(render_areas_[i]); | 468 GLSetViewPort(render_areas_[i]); |
575 clients_[i]->RenderContent(this); | 469 clients_[i]->RenderContent(this); |
576 } | 470 } |
577 } | 471 } |
578 } | 472 } |
579 | 473 |
580 #if GL_VARIANT_GLX | 474 gl_surface_->SwapBuffers(); |
581 glXSwapBuffers(x_display_, x_window_); | |
582 #else // EGL | |
583 eglSwapBuffers(gl_display_, gl_surface_); | |
584 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); | |
585 #endif | |
586 } | 475 } |
587 | 476 |
588 // Helper function for the LayoutRenderingAreas(). The |lengths| are the | 477 // Helper function for the LayoutRenderingAreas(). The |lengths| are the |
589 // heights(widths) of the rows(columns). It scales the elements in | 478 // heights(widths) of the rows(columns). It scales the elements in |
590 // |lengths| proportionally so that the sum of them equal to |total_length|. | 479 // |lengths| proportionally so that the sum of them equal to |total_length|. |
591 // It also outputs the coordinates of the rows(columns) to |offsets|. | 480 // It also outputs the coordinates of the rows(columns) to |offsets|. |
592 static void ScaleAndCalculateOffsets(std::vector<int>* lengths, | 481 static void ScaleAndCalculateOffsets(std::vector<int>* lengths, |
593 std::vector<int>* offsets, | 482 std::vector<int>* offsets, |
594 int total_length) { | 483 int total_length) { |
595 int sum = std::accumulate(lengths->begin(), lengths->end(), 0); | 484 int sum = std::accumulate(lengths->begin(), lengths->end(), 0); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 scale = std::min(1.0f, scale); | 521 scale = std::min(1.0f, scale); |
633 | 522 |
634 size_t w = scale * window_size.width(); | 523 size_t w = scale * window_size.width(); |
635 size_t h = scale * window_size.height(); | 524 size_t h = scale * window_size.height(); |
636 size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; | 525 size_t x = offset_x[i % cols] + (widths[i % cols] - w) / 2; |
637 size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; | 526 size_t y = offset_y[i / cols] + (heights[i / cols] - h) / 2; |
638 render_areas_.push_back(gfx::Rect(x, y, w, h)); | 527 render_areas_.push_back(gfx::Rect(x, y, w, h)); |
639 } | 528 } |
640 } | 529 } |
641 } // namespace content | 530 } // namespace content |
OLD | NEW |