Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(486)

Side by Side Diff: content/common/gpu/media/rendering_helper.cc

Issue 294663006: vda_unittest - Move the fps control from ThrottleVDAClient to RenderingHelper. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address review comments Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/mac/scoped_nsautorelease_pool.h" 8 #include "base/mac/scoped_nsautorelease_pool.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/stringize_macros.h" 10 #include "base/strings/stringize_macros.h"
11 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
12 #include "ui/gl/gl_context.h" 12 #include "ui/gl/gl_context.h"
13 #include "ui/gl/gl_context_stub_with_extensions.h" 13 #include "ui/gl/gl_context_stub_with_extensions.h"
14 #include "ui/gl/gl_implementation.h" 14 #include "ui/gl/gl_implementation.h"
15 #include "ui/gl/gl_surface.h" 15 #include "ui/gl/gl_surface.h"
16 16
17 #if defined(OS_WIN)
18 #include <windows.h>
19 #endif
20
17 #if defined(USE_X11) 21 #if defined(USE_X11)
18 #include "ui/gfx/x/x11_types.h" 22 #include "ui/gfx/x/x11_types.h"
19 #endif 23 #endif
20 24
21 #ifdef GL_VARIANT_GLX 25 #ifdef GL_VARIANT_GLX
22 typedef GLXWindow NativeWindowType; 26 typedef GLXWindow NativeWindowType;
23 struct XFreeDeleter { 27 struct XFreeDeleter {
24 void operator()(void* x) const { ::XFree(x); } 28 void operator()(void* x) const { ::XFree(x); }
25 }; 29 };
26 #else // EGL 30 #else // EGL
(...skipping 30 matching lines...) Expand all
57 #if defined(GL_VARIANT_GLX) 61 #if defined(GL_VARIANT_GLX)
58 gfx::kGLImplementationDesktopGL; 62 gfx::kGLImplementationDesktopGL;
59 #elif defined(GL_VARIANT_EGL) 63 #elif defined(GL_VARIANT_EGL)
60 gfx::kGLImplementationEGLGLES2; 64 gfx::kGLImplementationEGLGLES2;
61 #else 65 #else
62 -1; 66 -1;
63 #error "Unknown GL implementation." 67 #error "Unknown GL implementation."
64 #endif 68 #endif
65 69
66 RenderingHelper::RenderingHelper() { 70 RenderingHelper::RenderingHelper() {
71 #if defined(GL_VARIANT_EGL)
72 gl_surface_ = EGL_NO_SURFACE;
73 #endif
74
75 #if defined(OS_WIN)
76 window_ = NULL;
77 #else
78 x_window_ = (Window)0;
79 #endif
80
67 Clear(); 81 Clear();
68 } 82 }
69 83
70 RenderingHelper::~RenderingHelper() { 84 RenderingHelper::~RenderingHelper() {
71 CHECK_EQ(window_dimensions_.size(), 0U) << 85 CHECK_EQ(frame_dimensions_.size(), 0U)
72 "Must call UnInitialize before dtor."; 86 << "Must call UnInitialize before dtor.";
73 Clear(); 87 Clear();
74 } 88 }
75 89
76 void RenderingHelper::MakeCurrent(int window_id) {
77 #if GL_VARIANT_GLX
78 if (window_id < 0) {
79 CHECK(glXMakeContextCurrent(x_display_, GLX_NONE, GLX_NONE, NULL));
80 } else {
81 CHECK(glXMakeContextCurrent(
82 x_display_, x_windows_[window_id], x_windows_[window_id], gl_context_));
83 }
84 #else // EGL
85 if (window_id < 0) {
86 CHECK(eglMakeCurrent(gl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
87 EGL_NO_CONTEXT)) << eglGetError();
88 } else {
89 CHECK(eglMakeCurrent(gl_display_, gl_surfaces_[window_id],
90 gl_surfaces_[window_id], gl_context_))
91 << eglGetError();
92 }
93 #endif
94 }
95
96 void RenderingHelper::Initialize(const RenderingHelperParams& params, 90 void RenderingHelper::Initialize(const RenderingHelperParams& params,
97 base::WaitableEvent* done) { 91 base::WaitableEvent* done) {
98 // Use window_dimensions_.size() != 0 as a proxy for the class having already 92 // Use frame_dimensions_.size() != 0 as a proxy for the class having already
99 // been Initialize()'d, and UnInitialize() before continuing. 93 // been Initialize()'d, and UnInitialize() before continuing.
100 if (window_dimensions_.size()) { 94 if (frame_dimensions_.size()) {
101 base::WaitableEvent done(false, false); 95 base::WaitableEvent done(false, false);
102 UnInitialize(&done); 96 UnInitialize(&done);
103 done.Wait(); 97 done.Wait();
104 } 98 }
105 99
100 frame_duration_ = params.rendering_fps > 0
101 ? base::TimeDelta::FromSeconds(1) / params.rendering_fps
102 : base::TimeDelta();
103
106 gfx::InitializeStaticGLBindings(kGLImplementation); 104 gfx::InitializeStaticGLBindings(kGLImplementation);
107 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context( 105 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context(
108 new gfx::GLContextStubWithExtensions()); 106 new gfx::GLContextStubWithExtensions());
109 107
110 CHECK_GT(params.window_dimensions.size(), 0U); 108 CHECK_GT(params.window_dimensions.size(), 0U);
111 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size()); 109 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size());
112 window_dimensions_ = params.window_dimensions;
113 frame_dimensions_ = params.frame_dimensions; 110 frame_dimensions_ = params.frame_dimensions;
114 render_as_thumbnails_ = params.render_as_thumbnails; 111 render_as_thumbnails_ = params.render_as_thumbnails;
115 message_loop_ = base::MessageLoop::current(); 112 message_loop_ = base::MessageLoop::current();
116 CHECK_GT(params.num_windows, 0); 113 CHECK_GT(params.num_windows, 0);
117 114
115 gfx::Size window_size;
116
118 #if GL_VARIANT_GLX 117 #if GL_VARIANT_GLX
119 x_display_ = gfx::GetXDisplay(); 118 x_display_ = gfx::GetXDisplay();
120 CHECK(x_display_); 119 CHECK(x_display_);
121 CHECK(glXQueryVersion(x_display_, NULL, NULL)); 120 CHECK(glXQueryVersion(x_display_, NULL, NULL));
122 const int fbconfig_attr[] = { 121 const int fbconfig_attr[] = {
123 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 122 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
124 GLX_RENDER_TYPE, GLX_RGBA_BIT, 123 GLX_RENDER_TYPE, GLX_RGBA_BIT,
125 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, 124 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
126 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, 125 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE,
127 GLX_DOUBLEBUFFER, True, 126 GLX_DOUBLEBUFFER, True,
128 GL_NONE, 127 GL_NONE,
129 }; 128 };
130 int num_fbconfigs; 129 int num_fbconfigs;
131 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs( 130 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs(
132 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, 131 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr,
133 &num_fbconfigs)); 132 &num_fbconfigs));
134 CHECK(glx_fb_configs.get()); 133 CHECK(glx_fb_configs.get());
135 CHECK_GT(num_fbconfigs, 0); 134 CHECK_GT(num_fbconfigs, 0);
136 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]); 135 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]);
137 CHECK(x_visual_); 136 CHECK(x_visual_);
138 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true); 137 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true);
139 CHECK(gl_context_); 138 CHECK(gl_context_);
140 stub_context->AddExtensionsString( 139 stub_context->AddExtensionsString(
141 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 140 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
142 stub_context->SetGLVersionString( 141 stub_context->SetGLVersionString(
143 reinterpret_cast<const char*>(glGetString(GL_VERSION))); 142 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
144 143
144 Screen* screen = DefaultScreenOfDisplay(x_display_);
145 window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen));
145 #else // EGL 146 #else // EGL
146 EGLNativeDisplayType native_display; 147 EGLNativeDisplayType native_display;
147 148
148 #if defined(OS_WIN) 149 #if defined(OS_WIN)
149 native_display = EGL_DEFAULT_DISPLAY; 150 native_display = EGL_DEFAULT_DISPLAY;
151 window_size =
152 gfx::Size(GetSystemMetrics(SM_CXSREEN), GetSystemMetrics(SM_CY_SCREEN))
150 #else 153 #else
151 x_display_ = gfx::GetXDisplay(); 154 x_display_ = gfx::GetXDisplay();
152 CHECK(x_display_); 155 CHECK(x_display_);
153 native_display = x_display_; 156 native_display = x_display_;
157
158 Screen* screen = DefaultScreenOfDisplay(x_display_);
159 window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen));
154 #endif 160 #endif
155
156 gl_display_ = eglGetDisplay(native_display); 161 gl_display_ = eglGetDisplay(native_display);
157 CHECK(gl_display_); 162 CHECK(gl_display_);
158 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError(); 163 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError();
159 164
160 static EGLint rgba8888[] = { 165 static EGLint rgba8888[] = {
161 EGL_RED_SIZE, 8, 166 EGL_RED_SIZE, 8,
162 EGL_GREEN_SIZE, 8, 167 EGL_GREEN_SIZE, 8,
163 EGL_BLUE_SIZE, 8, 168 EGL_BLUE_SIZE, 8,
164 EGL_ALPHA_SIZE, 8, 169 EGL_ALPHA_SIZE, 8,
165 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 170 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
166 EGL_NONE, 171 EGL_NONE,
167 }; 172 };
168 EGLConfig egl_config; 173 EGLConfig egl_config;
169 int num_configs; 174 int num_configs;
170 CHECK(eglChooseConfig(gl_display_, rgba8888, &egl_config, 1, &num_configs)) 175 CHECK(eglChooseConfig(gl_display_, rgba8888, &egl_config, 1, &num_configs))
171 << eglGetError(); 176 << eglGetError();
172 CHECK_GE(num_configs, 1); 177 CHECK_GE(num_configs, 1);
173 static EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; 178 static EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
174 gl_context_ = eglCreateContext( 179 gl_context_ = eglCreateContext(
175 gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs); 180 gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs);
176 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError(); 181 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError();
177 stub_context->AddExtensionsString( 182 stub_context->AddExtensionsString(
178 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 183 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
179 stub_context->AddExtensionsString( 184 stub_context->AddExtensionsString(
180 eglQueryString(gl_display_, EGL_EXTENSIONS)); 185 eglQueryString(gl_display_, EGL_EXTENSIONS));
181 stub_context->SetGLVersionString( 186 stub_context->SetGLVersionString(
182 reinterpret_cast<const char*>(glGetString(GL_VERSION))); 187 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
183 #endif 188 #endif
184 189 clients_ = params.clients;
185 // Per-window/surface X11 & EGL initialization. 190 // Per-window/surface X11 & EGL initialization.
186 for (int i = 0; i < params.num_windows; ++i) { 191 for (int i = 0; i < params.num_windows; ++i) {
187 // Arrange X windows whimsically, with some padding. 192 // Arrange X windows whimsically, with some padding.
188 int j = i % window_dimensions_.size(); 193 int j = i % params.window_dimensions.size();
189 int width = window_dimensions_[j].width(); 194 int width = params.window_dimensions[j].width();
190 int height = window_dimensions_[j].height(); 195 int height = params.window_dimensions[j].height();
191 CHECK_GT(width, 0); 196 CHECK_GT(width, 0);
192 CHECK_GT(height, 0); 197 CHECK_GT(height, 0);
193 int top_left_x = (width + 20) * (i % 4); 198 int top_left_x = (width + 20) * (i % 4);
194 int top_left_y = (height + 12) * (i % 3); 199 int top_left_y = (height + 12) * (i % 3);
200 render_areas_.push_back(gfx::Rect(top_left_x, top_left_y, width, height));
201 }
195 202
196 #if defined(OS_WIN) 203 #if defined(OS_WIN)
197 NativeWindowType window = 204 window_ = CreateWindowEx(0,
198 CreateWindowEx(0, L"Static", L"VideoDecodeAcceleratorTest", 205 L"Static",
199 WS_OVERLAPPEDWINDOW | WS_VISIBLE, top_left_x, 206 L"VideoDecodeAcceleratorTest",
200 top_left_y, width, height, NULL, NULL, NULL, 207 WS_OVERLAPPEDWINDOW | WS_VISIBLE,
201 NULL); 208 0,
202 CHECK(window != NULL); 209 0,
203 windows_.push_back(window); 210 window_size.width(),
211 widow_size.height(),
212 NULL,
213 NULL,
214 NULL,
215 NULL);
216 CHECK(window_ != NULL);
204 #else 217 #else
205 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); 218 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_));
206 219
207 #if defined(GL_VARIANT_GLX) 220 #if defined(GL_VARIANT_GLX)
208 CHECK_EQ(depth, x_visual_->depth); 221 CHECK_EQ(depth, x_visual_->depth);
209 #endif 222 #endif
210 223
211 XSetWindowAttributes window_attributes; 224 XSetWindowAttributes window_attributes;
212 window_attributes.background_pixel = 225 window_attributes.background_pixel =
213 BlackPixel(x_display_, DefaultScreen(x_display_)); 226 BlackPixel(x_display_, DefaultScreen(x_display_));
214 window_attributes.override_redirect = true; 227 window_attributes.override_redirect = true;
215 228
216 NativeWindowType window = XCreateWindow( 229 x_window_ = XCreateWindow(x_display_,
217 x_display_, DefaultRootWindow(x_display_), 230 DefaultRootWindow(x_display_),
218 top_left_x, top_left_y, width, height, 231 0,
219 0 /* border width */, 232 0,
220 depth, CopyFromParent /* class */, CopyFromParent /* visual */, 233 window_size.width(),
221 (CWBackPixel | CWOverrideRedirect), &window_attributes); 234 window_size.height(),
222 XStoreName(x_display_, window, "VideoDecodeAcceleratorTest"); 235 0 /* border width */,
223 XSelectInput(x_display_, window, ExposureMask); 236 depth,
224 XMapWindow(x_display_, window); 237 CopyFromParent /* class */,
225 x_windows_.push_back(window); 238 CopyFromParent /* visual */,
239 (CWBackPixel | CWOverrideRedirect),
240 &window_attributes);
241 XStoreName(x_display_, x_window_, "VideoDecodeAcceleratorTest");
242 XSelectInput(x_display_, x_window_, ExposureMask);
243 XMapWindow(x_display_, x_window_);
226 #endif 244 #endif
227 245
228 #if GL_VARIANT_EGL 246 #if GL_VARIANT_EGL
229 EGLSurface egl_surface = 247 gl_surface_ =
230 eglCreateWindowSurface(gl_display_, egl_config, window, NULL); 248 eglCreateWindowSurface(gl_display_, egl_config, x_window_, NULL);
231 gl_surfaces_.push_back(egl_surface); 249 CHECK_NE(gl_surface_, EGL_NO_SURFACE);
232 CHECK_NE(egl_surface, EGL_NO_SURFACE);
233 #endif 250 #endif
234 MakeCurrent(i); 251
235 } 252 #if GL_VARIANT_GLX
253 CHECK(glXMakeContextCurrent(x_display_, x_window_, x_window_, gl_context_));
254 #else // EGL
255 CHECK(eglMakeCurrent(gl_display_, gl_surface_, gl_surface_, gl_context_))
256 << eglGetError();
257 #endif
236 258
237 // Must be done after a context is made current. 259 // Must be done after a context is made current.
238 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get()); 260 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get());
239 261
240 if (render_as_thumbnails_) { 262 if (render_as_thumbnails_) {
241 CHECK_EQ(window_dimensions_.size(), 1U); 263 CHECK_EQ(frame_dimensions_.size(), 1U);
242 264
243 GLint max_texture_size; 265 GLint max_texture_size;
244 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); 266 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
245 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); 267 CHECK_GE(max_texture_size, params.thumbnails_page_size.width());
246 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); 268 CHECK_GE(max_texture_size, params.thumbnails_page_size.height());
247 269
248 thumbnails_fbo_size_ = params.thumbnails_page_size; 270 thumbnails_fbo_size_ = params.thumbnails_page_size;
249 thumbnail_size_ = params.thumbnail_size; 271 thumbnail_size_ = params.thumbnail_size;
250 272
251 glGenFramebuffersEXT(1, &thumbnails_fbo_id_); 273 glGenFramebuffersEXT(1, &thumbnails_fbo_id_);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 GLint tex_external = glGetUniformLocation(program_, "tex_external"); 370 GLint tex_external = glGetUniformLocation(program_, "tex_external");
349 if (tex_external != -1) { 371 if (tex_external != -1) {
350 glUniform1i(tex_external, 1); 372 glUniform1i(tex_external, 1);
351 } 373 }
352 int pos_location = glGetAttribLocation(program_, "in_pos"); 374 int pos_location = glGetAttribLocation(program_, "in_pos");
353 glEnableVertexAttribArray(pos_location); 375 glEnableVertexAttribArray(pos_location);
354 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); 376 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
355 int tc_location = glGetAttribLocation(program_, "in_tc"); 377 int tc_location = glGetAttribLocation(program_, "in_tc");
356 glEnableVertexAttribArray(tc_location); 378 glEnableVertexAttribArray(tc_location);
357 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); 379 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords);
380
381 if (frame_duration_ != base::TimeDelta()) {
382 render_timer_.Start(
383 FROM_HERE, frame_duration_, this, &RenderingHelper::RenderContent);
384 }
358 done->Signal(); 385 done->Signal();
359 } 386 }
360 387
361 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { 388 void RenderingHelper::UnInitialize(base::WaitableEvent* done) {
362 CHECK_EQ(base::MessageLoop::current(), message_loop_); 389 CHECK_EQ(base::MessageLoop::current(), message_loop_);
390 render_timer_.Stop();
363 if (render_as_thumbnails_) { 391 if (render_as_thumbnails_) {
364 glDeleteTextures(1, &thumbnails_texture_id_); 392 glDeleteTextures(1, &thumbnails_texture_id_);
365 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); 393 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_);
366 } 394 }
367 #if GL_VARIANT_GLX 395 #if GL_VARIANT_GLX
368 396
369 glXDestroyContext(x_display_, gl_context_); 397 glXDestroyContext(x_display_, gl_context_);
370 #else // EGL 398 #else // EGL
371 MakeCurrent(-1);
372 CHECK(eglDestroyContext(gl_display_, gl_context_)); 399 CHECK(eglDestroyContext(gl_display_, gl_context_));
373 for (size_t i = 0; i < gl_surfaces_.size(); ++i) 400 CHECK(eglDestroySurface(gl_display_, gl_surface_));
374 CHECK(eglDestroySurface(gl_display_, gl_surfaces_[i]));
375 CHECK(eglTerminate(gl_display_)); 401 CHECK(eglTerminate(gl_display_));
376 #endif 402 #endif
377 gfx::ClearGLBindings(); 403 gfx::ClearGLBindings();
378 Clear(); 404 Clear();
379 done->Signal(); 405 done->Signal();
380 } 406 }
381 407
382 void RenderingHelper::CreateTexture(int window_id, 408 void RenderingHelper::CreateTexture(int window_id,
383 uint32 texture_target, 409 uint32 texture_target,
384 uint32* texture_id, 410 uint32* texture_id,
385 base::WaitableEvent* done) { 411 base::WaitableEvent* done) {
386 if (base::MessageLoop::current() != message_loop_) { 412 if (base::MessageLoop::current() != message_loop_) {
387 message_loop_->PostTask( 413 message_loop_->PostTask(
388 FROM_HERE, 414 FROM_HERE,
389 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), 415 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this),
390 window_id, texture_target, texture_id, done)); 416 window_id, texture_target, texture_id, done));
391 return; 417 return;
392 } 418 }
393 MakeCurrent(window_id);
394 glGenTextures(1, texture_id); 419 glGenTextures(1, texture_id);
395 glBindTexture(texture_target, *texture_id); 420 glBindTexture(texture_target, *texture_id);
396 int dimensions_id = window_id % frame_dimensions_.size(); 421 int dimensions_id = window_id % frame_dimensions_.size();
397 if (texture_target == GL_TEXTURE_2D) { 422 if (texture_target == GL_TEXTURE_2D) {
398 glTexImage2D(GL_TEXTURE_2D, 423 glTexImage2D(GL_TEXTURE_2D,
399 0, 424 0,
400 GL_RGBA, 425 GL_RGBA,
401 frame_dimensions_[dimensions_id].width(), 426 frame_dimensions_[dimensions_id].width(),
402 frame_dimensions_[dimensions_id].height(), 427 frame_dimensions_[dimensions_id].height(),
403 0, 428 0,
404 GL_RGBA, 429 GL_RGBA,
405 GL_UNSIGNED_BYTE, 430 GL_UNSIGNED_BYTE,
406 NULL); 431 NULL);
407 } 432 }
408 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 433 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
409 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 434 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
410 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. 435 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures.
411 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 436 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
412 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 437 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
413 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 438 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
414 CHECK(texture_id_to_surface_index_.insert( 439 CHECK(texture_id_to_surface_index_.insert(
415 std::make_pair(*texture_id, window_id)).second); 440 std::make_pair(*texture_id, window_id)).second);
416 done->Signal(); 441 done->Signal();
417 } 442 }
418 443
444 // Helper function to set GL viewport.
445 static inline void GLSetViewPort(const gfx::Rect& area) {
446 glViewport(area.x(), area.y(), area.width(), area.height());
447 glScissor(area.x(), area.y(), area.width(), area.height());
448 }
449
450 void RenderingHelper::RenderThumbnail(uint32 texture_target,
451 uint32 texture_id) {
452 CHECK_EQ(base::MessageLoop::current(), message_loop_);
453 const int width = thumbnail_size_.width();
454 const int height = thumbnail_size_.height();
455 const int thumbnails_in_row = thumbnails_fbo_size_.width() / width;
456 const int thumbnails_in_column = thumbnails_fbo_size_.height() / height;
457 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column;
458 const int col = frame_count_ % thumbnails_in_row;
459
460 gfx::Rect area(col * width, row * height, width, height);
461
462 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0);
463 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_);
464 GLSetViewPort(area);
465 RenderTexture(texture_target, texture_id);
466 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
467 ++frame_count_;
468 }
469
419 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { 470 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) {
420 CHECK_EQ(base::MessageLoop::current(), message_loop_);
421 size_t window_id = texture_id_to_surface_index_[texture_id];
422 MakeCurrent(window_id);
423
424 int dimensions_id = window_id % window_dimensions_.size();
425 int width = window_dimensions_[dimensions_id].width();
426 int height = window_dimensions_[dimensions_id].height();
427
428 if (render_as_thumbnails_) {
429 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_);
430 const int thumbnails_in_row =
431 thumbnails_fbo_size_.width() / thumbnail_size_.width();
432 const int thumbnails_in_column =
433 thumbnails_fbo_size_.height() / thumbnail_size_.height();
434 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column;
435 const int col = frame_count_ % thumbnails_in_row;
436 const int x = col * thumbnail_size_.width();
437 const int y = row * thumbnail_size_.height();
438
439 glViewport(x, y, thumbnail_size_.width(), thumbnail_size_.height());
440 glScissor(x, y, thumbnail_size_.width(), thumbnail_size_.height());
441 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0);
442 } else {
443 glViewport(0, 0, width, height);
444 glScissor(0, 0, width, height);
445 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1);
446 }
447
448 // Unbound texture samplers default to (0, 0, 0, 1). Use this fact to switch 471 // Unbound texture samplers default to (0, 0, 0, 1). Use this fact to switch
449 // between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES as appopriate. 472 // between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES as appopriate.
450 if (texture_target == GL_TEXTURE_2D) { 473 if (texture_target == GL_TEXTURE_2D) {
451 glActiveTexture(GL_TEXTURE0 + 0); 474 glActiveTexture(GL_TEXTURE0 + 0);
452 glBindTexture(GL_TEXTURE_2D, texture_id); 475 glBindTexture(GL_TEXTURE_2D, texture_id);
453 glActiveTexture(GL_TEXTURE0 + 1); 476 glActiveTexture(GL_TEXTURE0 + 1);
454 glBindTexture(texture_target, 0); 477 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
455 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) { 478 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) {
456 glActiveTexture(GL_TEXTURE0 + 0); 479 glActiveTexture(GL_TEXTURE0 + 0);
457 glBindTexture(GL_TEXTURE_2D, 0); 480 glBindTexture(GL_TEXTURE_2D, 0);
458 glActiveTexture(GL_TEXTURE0 + 1); 481 glActiveTexture(GL_TEXTURE0 + 1);
459 glBindTexture(texture_target, texture_id); 482 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
460 } 483 }
484
461 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 485 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
462 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 486 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
463
464 ++frame_count_;
465
466 if (render_as_thumbnails_) {
467 // Copy from FBO to screen
468 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1);
469 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
470 glViewport(0, 0, width, height);
471 glScissor(0, 0, width, height);
472 glActiveTexture(GL_TEXTURE0 + 0);
473 glBindTexture(GL_TEXTURE_2D, thumbnails_texture_id_);
474 glActiveTexture(GL_TEXTURE0 + 1);
475 glBindTexture(texture_target, 0);
476 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
477 }
478
479 #if GL_VARIANT_GLX
480 glXSwapBuffers(x_display_, x_windows_[window_id]);
481 #else // EGL
482 eglSwapBuffers(gl_display_, gl_surfaces_[window_id]);
483 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS);
484 #endif
485 } 487 }
486 488
487 void RenderingHelper::DeleteTexture(uint32 texture_id) { 489 void RenderingHelper::DeleteTexture(uint32 texture_id) {
488 glDeleteTextures(1, &texture_id); 490 glDeleteTextures(1, &texture_id);
489 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 491 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
490 } 492 }
491 493
492 NativeContextType RenderingHelper::GetGLContext() { return gl_context_; } 494 NativeContextType RenderingHelper::GetGLContext() { return gl_context_; }
493 495
494 void* RenderingHelper::GetGLDisplay() { 496 void* RenderingHelper::GetGLDisplay() {
495 #if GL_VARIANT_GLX 497 #if GL_VARIANT_GLX
496 return x_display_; 498 return x_display_;
497 #else // EGL 499 #else // EGL
498 return gl_display_; 500 return gl_display_;
499 #endif 501 #endif
500 } 502 }
501 503
502 void RenderingHelper::Clear() { 504 void RenderingHelper::Clear() {
503 window_dimensions_.clear();
504 frame_dimensions_.clear(); 505 frame_dimensions_.clear();
505 texture_id_to_surface_index_.clear(); 506 texture_id_to_surface_index_.clear();
506 message_loop_ = NULL; 507 message_loop_ = NULL;
507 gl_context_ = NULL; 508 gl_context_ = NULL;
508 #if GL_VARIANT_EGL 509 #if GL_VARIANT_EGL
509 gl_display_ = EGL_NO_DISPLAY; 510 gl_display_ = EGL_NO_DISPLAY;
510 gl_surfaces_.clear(); 511 gl_surface_ = EGL_NO_SURFACE;
511 #endif 512 #endif
512 render_as_thumbnails_ = false; 513 render_as_thumbnails_ = false;
513 frame_count_ = 0; 514 frame_count_ = 0;
514 thumbnails_fbo_id_ = 0; 515 thumbnails_fbo_id_ = 0;
515 thumbnails_texture_id_ = 0; 516 thumbnails_texture_id_ = 0;
516 517
517 #if defined(OS_WIN) 518 #if defined(OS_WIN)
518 for (size_t i = 0; i < windows_.size(); ++i) { 519 if (window_) {
519 DestroyWindow(windows_[i]); 520 DestroyWindow(window_);
521 window_ = NULL;
520 } 522 }
521 windows_.clear();
522 #else 523 #else
523 // Destroy resources acquired in Initialize, in reverse-acquisition order. 524 // Destroy resources acquired in Initialize, in reverse-acquisition order.
524 for (size_t i = 0; i < x_windows_.size(); ++i) { 525 if (x_window_) {
525 CHECK(XUnmapWindow(x_display_, x_windows_[i])); 526 CHECK(XUnmapWindow(x_display_, x_window_));
526 CHECK(XDestroyWindow(x_display_, x_windows_[i])); 527 CHECK(XDestroyWindow(x_display_, x_window_));
528 x_window_ = (Window)0;
527 } 529 }
528 // Mimic newly created object. 530 // Mimic newly created object.
529 x_display_ = NULL; 531 x_display_ = NULL;
530 x_windows_.clear();
531 #endif 532 #endif
532 } 533 }
533 534
534 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, 535 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
535 bool* alpha_solid, 536 bool* alpha_solid,
536 base::WaitableEvent* done) { 537 base::WaitableEvent* done) {
537 CHECK(render_as_thumbnails_); 538 CHECK(render_as_thumbnails_);
538 539
539 const size_t num_pixels = thumbnails_fbo_size_.GetArea(); 540 const size_t num_pixels = thumbnails_fbo_size_.GetArea();
540 std::vector<unsigned char> rgba; 541 std::vector<unsigned char> rgba;
(...skipping 19 matching lines...) Expand all
560 *rgb_ptr++ = *rgba_ptr++; 561 *rgb_ptr++ = *rgba_ptr++;
561 *rgb_ptr++ = *rgba_ptr++; 562 *rgb_ptr++ = *rgba_ptr++;
562 solid = solid && (*rgba_ptr == 0xff); 563 solid = solid && (*rgba_ptr == 0xff);
563 rgba_ptr++; 564 rgba_ptr++;
564 } 565 }
565 *alpha_solid = solid; 566 *alpha_solid = solid;
566 567
567 done->Signal(); 568 done->Signal();
568 } 569 }
569 570
571 void RenderingHelper::RenderContent() {
572 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1);
573
574 if (render_as_thumbnails_) {
575 // In render_as_thumbnails_ mode, we render the FBO content on the
576 // screen instead of the decoded textures.
577 GLSetViewPort(render_areas_[0]);
578 RenderTexture(GL_TEXTURE_2D, thumbnails_texture_id_);
579 } else {
580 for (size_t i = 0; i < clients_.size(); ++i) {
581 if (clients_[i]) {
582 GLSetViewPort(render_areas_[i]);
583 clients_[i]->RenderContent(this);
584 }
585 }
586 }
587
588 #if GL_VARIANT_GLX
589 glXSwapBuffers(x_display_, x_window_);
590 #else // EGL
591 eglSwapBuffers(gl_display_, gl_surface_);
592 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS);
593 #endif
594 }
570 } // namespace content 595 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698