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

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

Issue 271593010: rendering_helper - Replaces multiple windows by a full-screen window. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix compiling error. 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;
23 struct XFreeDeleter { 26 struct XFreeDeleter {
24 void operator()(void* x) const { ::XFree(x); } 27 void operator()(void* x) const { ::XFree(x); }
25 }; 28 };
26 #else // EGL
27 typedef EGLNativeWindowType NativeWindowType;
28 #endif 29 #endif
29 30
30 // Helper for Shader creation. 31 // Helper for Shader creation.
31 static void CreateShader(GLuint program, 32 static void CreateShader(GLuint program,
32 GLenum type, 33 GLenum type,
33 const char* source, 34 const char* source,
34 int size) { 35 int size) {
35 GLuint shader = glCreateShader(type); 36 GLuint shader = glCreateShader(type);
36 glShaderSource(shader, 1, &source, &size); 37 glShaderSource(shader, 1, &source, &size);
37 glCompileShader(shader); 38 glCompileShader(shader);
(...skipping 19 matching lines...) Expand all
57 #if defined(GL_VARIANT_GLX) 58 #if defined(GL_VARIANT_GLX)
58 gfx::kGLImplementationDesktopGL; 59 gfx::kGLImplementationDesktopGL;
59 #elif defined(GL_VARIANT_EGL) 60 #elif defined(GL_VARIANT_EGL)
60 gfx::kGLImplementationEGLGLES2; 61 gfx::kGLImplementationEGLGLES2;
61 #else 62 #else
62 -1; 63 -1;
63 #error "Unknown GL implementation." 64 #error "Unknown GL implementation."
64 #endif 65 #endif
65 66
66 RenderingHelper::RenderingHelper() { 67 RenderingHelper::RenderingHelper() {
68 #if defined(GL_VARIANT_EGL)
69 gl_surface_ = EGL_NO_SURFACE;
70 #endif
71
72 #if defined(OS_WIN)
73 window_ = NULL;
74 #else
75 x_window_ = (Window)0;
76 #endif
77
67 Clear(); 78 Clear();
68 } 79 }
69 80
70 RenderingHelper::~RenderingHelper() { 81 RenderingHelper::~RenderingHelper() {
71 CHECK_EQ(window_dimensions_.size(), 0U) << 82 CHECK_EQ(frame_dimensions_.size(), 0U)
72 "Must call UnInitialize before dtor."; 83 << "Must call UnInitialize before dtor.";
73 Clear(); 84 Clear();
74 } 85 }
75 86
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, 87 void RenderingHelper::Initialize(const RenderingHelperParams& params,
97 base::WaitableEvent* done) { 88 base::WaitableEvent* done) {
98 // Use window_dimensions_.size() != 0 as a proxy for the class having already 89 // Use frame_dimensions_.size() != 0 as a proxy for the class having already
99 // been Initialize()'d, and UnInitialize() before continuing. 90 // been Initialize()'d, and UnInitialize() before continuing.
100 if (window_dimensions_.size()) { 91 if (frame_dimensions_.size()) {
101 base::WaitableEvent done(false, false); 92 base::WaitableEvent done(false, false);
102 UnInitialize(&done); 93 UnInitialize(&done);
103 done.Wait(); 94 done.Wait();
104 } 95 }
105 96
97 // TODO(owenlin): pass fps from params
98 frame_duration_ = base::TimeDelta::FromSeconds(1) / 60;
99
106 gfx::InitializeStaticGLBindings(kGLImplementation); 100 gfx::InitializeStaticGLBindings(kGLImplementation);
107 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context( 101 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context(
108 new gfx::GLContextStubWithExtensions()); 102 new gfx::GLContextStubWithExtensions());
109 103
110 CHECK_GT(params.window_dimensions.size(), 0U); 104 CHECK_GT(params.window_dimensions.size(), 0U);
111 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size()); 105 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size());
112 window_dimensions_ = params.window_dimensions;
113 frame_dimensions_ = params.frame_dimensions; 106 frame_dimensions_ = params.frame_dimensions;
114 render_as_thumbnails_ = params.render_as_thumbnails; 107 render_as_thumbnails_ = params.render_as_thumbnails;
115 message_loop_ = base::MessageLoop::current(); 108 message_loop_ = base::MessageLoop::current();
116 CHECK_GT(params.num_windows, 0); 109 CHECK_GT(params.num_windows, 0);
117 110
111 gfx::Size window_size;
112
118 #if GL_VARIANT_GLX 113 #if GL_VARIANT_GLX
119 x_display_ = gfx::GetXDisplay(); 114 x_display_ = gfx::GetXDisplay();
120 CHECK(x_display_); 115 CHECK(x_display_);
121 CHECK(glXQueryVersion(x_display_, NULL, NULL)); 116 CHECK(glXQueryVersion(x_display_, NULL, NULL));
122 const int fbconfig_attr[] = { 117 const int fbconfig_attr[] = {
123 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 118 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
124 GLX_RENDER_TYPE, GLX_RGBA_BIT, 119 GLX_RENDER_TYPE, GLX_RGBA_BIT,
125 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, 120 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
126 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, 121 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE,
127 GLX_DOUBLEBUFFER, True, 122 GLX_DOUBLEBUFFER, True,
128 GL_NONE, 123 GL_NONE,
129 }; 124 };
130 int num_fbconfigs; 125 int num_fbconfigs;
131 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs( 126 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs(
132 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, 127 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr,
133 &num_fbconfigs)); 128 &num_fbconfigs));
134 CHECK(glx_fb_configs.get()); 129 CHECK(glx_fb_configs.get());
135 CHECK_GT(num_fbconfigs, 0); 130 CHECK_GT(num_fbconfigs, 0);
136 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]); 131 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]);
137 CHECK(x_visual_); 132 CHECK(x_visual_);
138 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true); 133 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true);
139 CHECK(gl_context_); 134 CHECK(gl_context_);
140 stub_context->AddExtensionsString( 135 stub_context->AddExtensionsString(
141 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 136 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
142 stub_context->SetGLVersionString( 137 stub_context->SetGLVersionString(
143 reinterpret_cast<const char*>(glGetString(GL_VERSION))); 138 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
144 139
140 Screen* screen = DefaultScreenOfDisplay(x_display_);
141 window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen));
145 #else // EGL 142 #else // EGL
146 EGLNativeDisplayType native_display; 143 EGLNativeDisplayType native_display;
147 144
148 #if defined(OS_WIN) 145 #if defined(OS_WIN)
149 native_display = EGL_DEFAULT_DISPLAY; 146 native_display = EGL_DEFAULT_DISPLAY;
147 window_size =
148 gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
150 #else 149 #else
151 x_display_ = gfx::GetXDisplay(); 150 x_display_ = gfx::GetXDisplay();
152 CHECK(x_display_); 151 CHECK(x_display_);
153 native_display = x_display_; 152 native_display = x_display_;
153
154 Screen* screen = DefaultScreenOfDisplay(x_display_);
155 window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen));
154 #endif 156 #endif
155
156 gl_display_ = eglGetDisplay(native_display); 157 gl_display_ = eglGetDisplay(native_display);
157 CHECK(gl_display_); 158 CHECK(gl_display_);
158 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError(); 159 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError();
159 160
160 static EGLint rgba8888[] = { 161 static EGLint rgba8888[] = {
161 EGL_RED_SIZE, 8, 162 EGL_RED_SIZE, 8,
162 EGL_GREEN_SIZE, 8, 163 EGL_GREEN_SIZE, 8,
163 EGL_BLUE_SIZE, 8, 164 EGL_BLUE_SIZE, 8,
164 EGL_ALPHA_SIZE, 8, 165 EGL_ALPHA_SIZE, 8,
165 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 166 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
(...skipping 10 matching lines...) Expand all
176 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError(); 177 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError();
177 stub_context->AddExtensionsString( 178 stub_context->AddExtensionsString(
178 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 179 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
179 stub_context->AddExtensionsString( 180 stub_context->AddExtensionsString(
180 eglQueryString(gl_display_, EGL_EXTENSIONS)); 181 eglQueryString(gl_display_, EGL_EXTENSIONS));
181 stub_context->SetGLVersionString( 182 stub_context->SetGLVersionString(
182 reinterpret_cast<const char*>(glGetString(GL_VERSION))); 183 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
183 #endif 184 #endif
184 185
185 // Per-window/surface X11 & EGL initialization. 186 // Per-window/surface X11 & EGL initialization.
187 CHECK(texture_ids_.empty());
188 CHECK(texture_targets_.empty());
189
190 // Initialize to an invalid texture id: 0 to indicate no texture
191 // for rendering.
192 texture_ids_.resize(params.num_windows, 0);
193 texture_targets_.resize(params.num_windows, 0);
194
186 for (int i = 0; i < params.num_windows; ++i) { 195 for (int i = 0; i < params.num_windows; ++i) {
187 // Arrange X windows whimsically, with some padding. 196 // Arrange X windows whimsically, with some padding.
188 int j = i % window_dimensions_.size(); 197 int j = i % params.window_dimensions.size();
189 int width = window_dimensions_[j].width(); 198 int width = params.window_dimensions[j].width();
190 int height = window_dimensions_[j].height(); 199 int height = params.window_dimensions[j].height();
191 CHECK_GT(width, 0); 200 CHECK_GT(width, 0);
192 CHECK_GT(height, 0); 201 CHECK_GT(height, 0);
193 int top_left_x = (width + 20) * (i % 4); 202 int top_left_x = (width + 20) * (i % 4);
194 int top_left_y = (height + 12) * (i % 3); 203 int top_left_y = (height + 12) * (i % 3);
204 render_areas_.push_back(gfx::Rect(top_left_x, top_left_y, width, height));
205 }
195 206
196 #if defined(OS_WIN) 207 #if defined(OS_WIN)
197 NativeWindowType window = 208 window_ = CreateWindowEx(0,
198 CreateWindowEx(0, L"Static", L"VideoDecodeAcceleratorTest", 209 L"Static",
199 WS_OVERLAPPEDWINDOW | WS_VISIBLE, top_left_x, 210 L"VideoDecodeAcceleratorTest",
200 top_left_y, width, height, NULL, NULL, NULL, 211 WS_OVERLAPPEDWINDOW | WS_VISIBLE,
201 NULL); 212 0,
202 CHECK(window != NULL); 213 0,
203 windows_.push_back(window); 214 window_size.width(),
215 window_size.height(),
216 NULL,
217 NULL,
218 NULL,
219 NULL);
220 CHECK(window_ != NULL);
204 #else 221 #else
205 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); 222 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_));
206 223
207 #if defined(GL_VARIANT_GLX) 224 #if defined(GL_VARIANT_GLX)
208 CHECK_EQ(depth, x_visual_->depth); 225 CHECK_EQ(depth, x_visual_->depth);
209 #endif 226 #endif
210 227
211 XSetWindowAttributes window_attributes; 228 XSetWindowAttributes window_attributes;
212 window_attributes.background_pixel = 229 window_attributes.background_pixel =
213 BlackPixel(x_display_, DefaultScreen(x_display_)); 230 BlackPixel(x_display_, DefaultScreen(x_display_));
214 window_attributes.override_redirect = true; 231 window_attributes.override_redirect = true;
215 232
216 NativeWindowType window = XCreateWindow( 233 x_window_ = XCreateWindow(x_display_,
217 x_display_, DefaultRootWindow(x_display_), 234 DefaultRootWindow(x_display_),
218 top_left_x, top_left_y, width, height, 235 0,
219 0 /* border width */, 236 0,
220 depth, CopyFromParent /* class */, CopyFromParent /* visual */, 237 window_size.width(),
221 (CWBackPixel | CWOverrideRedirect), &window_attributes); 238 window_size.height(),
222 XStoreName(x_display_, window, "VideoDecodeAcceleratorTest"); 239 0 /* border width */,
223 XSelectInput(x_display_, window, ExposureMask); 240 depth,
224 XMapWindow(x_display_, window); 241 CopyFromParent /* class */,
225 x_windows_.push_back(window); 242 CopyFromParent /* visual */,
243 (CWBackPixel | CWOverrideRedirect),
244 &window_attributes);
245 XStoreName(x_display_, x_window_, "VideoDecodeAcceleratorTest");
246 XSelectInput(x_display_, x_window_, ExposureMask);
247 XMapWindow(x_display_, x_window_);
226 #endif 248 #endif
227 249
228 #if GL_VARIANT_EGL 250 #if GL_VARIANT_EGL
229 EGLSurface egl_surface = 251 #if defined(OS_WIN)
230 eglCreateWindowSurface(gl_display_, egl_config, window, NULL); 252 gl_surface_ =
231 gl_surfaces_.push_back(egl_surface); 253 eglCreateWindowSurface(gl_display_, egl_config, window_, NULL);
232 CHECK_NE(egl_surface, EGL_NO_SURFACE); 254 #else
255 gl_surface_ =
256 eglCreateWindowSurface(gl_display_, egl_config, x_window_, NULL);
233 #endif 257 #endif
234 MakeCurrent(i); 258 CHECK_NE(gl_surface_, EGL_NO_SURFACE);
235 } 259 #endif
260
261 #if GL_VARIANT_GLX
262 CHECK(glXMakeContextCurrent(x_display_, x_window_, x_window_, gl_context_));
263 #else // EGL
264 CHECK(eglMakeCurrent(gl_display_, gl_surface_, gl_surface_, gl_context_))
265 << eglGetError();
266 #endif
236 267
237 // Must be done after a context is made current. 268 // Must be done after a context is made current.
238 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get()); 269 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get());
239 270
240 if (render_as_thumbnails_) { 271 if (render_as_thumbnails_) {
241 CHECK_EQ(window_dimensions_.size(), 1U); 272 CHECK_EQ(frame_dimensions_.size(), 1U);
242 273
243 GLint max_texture_size; 274 GLint max_texture_size;
244 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); 275 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
245 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); 276 CHECK_GE(max_texture_size, params.thumbnails_page_size.width());
246 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); 277 CHECK_GE(max_texture_size, params.thumbnails_page_size.height());
247 278
248 thumbnails_fbo_size_ = params.thumbnails_page_size; 279 thumbnails_fbo_size_ = params.thumbnails_page_size;
249 thumbnail_size_ = params.thumbnail_size; 280 thumbnail_size_ = params.thumbnail_size;
250 281
251 glGenFramebuffersEXT(1, &thumbnails_fbo_id_); 282 glGenFramebuffersEXT(1, &thumbnails_fbo_id_);
(...skipping 18 matching lines...) Expand all
270 GL_COLOR_ATTACHMENT0, 301 GL_COLOR_ATTACHMENT0,
271 GL_TEXTURE_2D, 302 GL_TEXTURE_2D,
272 thumbnails_texture_id_, 303 thumbnails_texture_id_,
273 0); 304 0);
274 305
275 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 306 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
276 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; 307 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status;
277 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 308 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
278 glClear(GL_COLOR_BUFFER_BIT); 309 glClear(GL_COLOR_BUFFER_BIT);
279 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 310 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
311
312 // In render_as_thumbnails_ mode, we render the FBO content on the
313 // screen instead of the decoded textures.
314 texture_targets_[0] = GL_TEXTURE_2D;
315 texture_ids_[0] = thumbnails_texture_id_;
280 } 316 }
281 317
282 // These vertices and texture coords. map (0,0) in the texture to the 318 // These vertices and texture coords. map (0,0) in the texture to the
283 // bottom left of the viewport. Since we get the video frames with the 319 // bottom left of the viewport. Since we get the video frames with the
284 // the top left at (0,0) we need to flip the texture y coordinate 320 // the top left at (0,0) we need to flip the texture y coordinate
285 // in the vertex shader for this to be rendered the right way up. 321 // in the vertex shader for this to be rendered the right way up.
286 // In the case of thumbnail rendering we use the same vertex shader 322 // In the case of thumbnail rendering we use the same vertex shader
287 // to render the FBO the screen, where we do not want this flipping. 323 // to render the FBO the screen, where we do not want this flipping.
288 static const float kVertices[] = 324 static const float kVertices[] =
289 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, }; 325 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, };
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 GLint tex_external = glGetUniformLocation(program_, "tex_external"); 384 GLint tex_external = glGetUniformLocation(program_, "tex_external");
349 if (tex_external != -1) { 385 if (tex_external != -1) {
350 glUniform1i(tex_external, 1); 386 glUniform1i(tex_external, 1);
351 } 387 }
352 int pos_location = glGetAttribLocation(program_, "in_pos"); 388 int pos_location = glGetAttribLocation(program_, "in_pos");
353 glEnableVertexAttribArray(pos_location); 389 glEnableVertexAttribArray(pos_location);
354 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); 390 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
355 int tc_location = glGetAttribLocation(program_, "in_tc"); 391 int tc_location = glGetAttribLocation(program_, "in_tc");
356 glEnableVertexAttribArray(tc_location); 392 glEnableVertexAttribArray(tc_location);
357 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); 393 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords);
394
395 render_timer_.Start(
396 FROM_HERE, frame_duration_, this, &RenderingHelper::RenderContent);
358 done->Signal(); 397 done->Signal();
359 } 398 }
360 399
361 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { 400 void RenderingHelper::UnInitialize(base::WaitableEvent* done) {
362 CHECK_EQ(base::MessageLoop::current(), message_loop_); 401 CHECK_EQ(base::MessageLoop::current(), message_loop_);
402 render_timer_.Stop();
363 if (render_as_thumbnails_) { 403 if (render_as_thumbnails_) {
364 glDeleteTextures(1, &thumbnails_texture_id_); 404 glDeleteTextures(1, &thumbnails_texture_id_);
365 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); 405 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_);
366 } 406 }
367 #if GL_VARIANT_GLX 407 #if GL_VARIANT_GLX
368 408
369 glXDestroyContext(x_display_, gl_context_); 409 glXDestroyContext(x_display_, gl_context_);
370 #else // EGL 410 #else // EGL
371 MakeCurrent(-1);
372 CHECK(eglDestroyContext(gl_display_, gl_context_)); 411 CHECK(eglDestroyContext(gl_display_, gl_context_));
373 for (size_t i = 0; i < gl_surfaces_.size(); ++i) 412 CHECK(eglDestroySurface(gl_display_, gl_surface_));
374 CHECK(eglDestroySurface(gl_display_, gl_surfaces_[i]));
375 CHECK(eglTerminate(gl_display_)); 413 CHECK(eglTerminate(gl_display_));
376 #endif 414 #endif
377 gfx::ClearGLBindings(); 415 gfx::ClearGLBindings();
378 Clear(); 416 Clear();
379 done->Signal(); 417 done->Signal();
380 } 418 }
381 419
382 void RenderingHelper::CreateTexture(int window_id, 420 void RenderingHelper::CreateTexture(int window_id,
383 uint32 texture_target, 421 uint32 texture_target,
384 uint32* texture_id, 422 uint32* texture_id,
385 base::WaitableEvent* done) { 423 base::WaitableEvent* done) {
386 if (base::MessageLoop::current() != message_loop_) { 424 if (base::MessageLoop::current() != message_loop_) {
387 message_loop_->PostTask( 425 message_loop_->PostTask(
388 FROM_HERE, 426 FROM_HERE,
389 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), 427 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this),
390 window_id, texture_target, texture_id, done)); 428 window_id, texture_target, texture_id, done));
391 return; 429 return;
392 } 430 }
393 MakeCurrent(window_id);
394 glGenTextures(1, texture_id); 431 glGenTextures(1, texture_id);
395 glBindTexture(texture_target, *texture_id); 432 glBindTexture(texture_target, *texture_id);
396 int dimensions_id = window_id % frame_dimensions_.size(); 433 int dimensions_id = window_id % frame_dimensions_.size();
397 if (texture_target == GL_TEXTURE_2D) { 434 if (texture_target == GL_TEXTURE_2D) {
398 glTexImage2D(GL_TEXTURE_2D, 435 glTexImage2D(GL_TEXTURE_2D,
399 0, 436 0,
400 GL_RGBA, 437 GL_RGBA,
401 frame_dimensions_[dimensions_id].width(), 438 frame_dimensions_[dimensions_id].width(),
402 frame_dimensions_[dimensions_id].height(), 439 frame_dimensions_[dimensions_id].height(),
403 0, 440 0,
404 GL_RGBA, 441 GL_RGBA,
405 GL_UNSIGNED_BYTE, 442 GL_UNSIGNED_BYTE,
406 NULL); 443 NULL);
407 } 444 }
408 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 445 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
409 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 446 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
410 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. 447 // 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); 448 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
412 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 449 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
413 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 450 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
414 CHECK(texture_id_to_surface_index_.insert( 451 CHECK(texture_id_to_surface_index_.insert(
415 std::make_pair(*texture_id, window_id)).second); 452 std::make_pair(*texture_id, window_id)).second);
416 done->Signal(); 453 done->Signal();
417 } 454 }
418 455
419 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { 456 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) {
420 CHECK_EQ(base::MessageLoop::current(), message_loop_); 457 CHECK_EQ(base::MessageLoop::current(), message_loop_);
421 size_t window_id = texture_id_to_surface_index_[texture_id]; 458 if (texture_id == 0)
422 MakeCurrent(window_id); 459 return;
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 460
428 if (render_as_thumbnails_) { 461 if (render_as_thumbnails_) {
429 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); 462 const int width = thumbnail_size_.width();
430 const int thumbnails_in_row = 463 const int height = thumbnail_size_.height();
431 thumbnails_fbo_size_.width() / thumbnail_size_.width(); 464 const int thumbnails_in_row = thumbnails_fbo_size_.width() / width;
432 const int thumbnails_in_column = 465 const int thumbnails_in_column = thumbnails_fbo_size_.height() / height;
433 thumbnails_fbo_size_.height() / thumbnail_size_.height();
434 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column; 466 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column;
435 const int col = frame_count_ % thumbnails_in_row; 467 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 468
439 glViewport(x, y, thumbnail_size_.width(), thumbnail_size_.height()); 469 gfx::Rect area(col * width, row * height, width, height);
440 glScissor(x, y, thumbnail_size_.width(), thumbnail_size_.height()); 470
441 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); 471 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0);
472 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_);
473 DrawTexture(area, texture_target, texture_id);
474 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
475 ++frame_count_;
442 } else { 476 } else {
443 glViewport(0, 0, width, height); 477 size_t window_id = texture_id_to_surface_index_[texture_id];
444 glScissor(0, 0, width, height); 478 texture_targets_[window_id] = texture_target;
445 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); 479 texture_ids_[window_id] = texture_id;
446 } 480 }
481 }
482
483 void RenderingHelper::DrawTexture(const gfx::Rect& area,
484 uint32 texture_target,
485 uint32 texture_id) {
486 glViewport(area.x(), area.y(), area.width(), area.height());
487 glScissor(area.x(), area.y(), area.width(), area.height());
447 488
448 // Unbound texture samplers default to (0, 0, 0, 1). Use this fact to switch 489 // 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. 490 // between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES as appopriate.
450 if (texture_target == GL_TEXTURE_2D) { 491 if (texture_target == GL_TEXTURE_2D) {
451 glActiveTexture(GL_TEXTURE0 + 0); 492 glActiveTexture(GL_TEXTURE0 + 0);
452 glBindTexture(GL_TEXTURE_2D, texture_id); 493 glBindTexture(GL_TEXTURE_2D, texture_id);
453 glActiveTexture(GL_TEXTURE0 + 1); 494 glActiveTexture(GL_TEXTURE0 + 1);
454 glBindTexture(texture_target, 0); 495 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
455 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) { 496 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) {
456 glActiveTexture(GL_TEXTURE0 + 0); 497 glActiveTexture(GL_TEXTURE0 + 0);
457 glBindTexture(GL_TEXTURE_2D, 0); 498 glBindTexture(GL_TEXTURE_2D, 0);
458 glActiveTexture(GL_TEXTURE0 + 1); 499 glActiveTexture(GL_TEXTURE0 + 1);
459 glBindTexture(texture_target, texture_id); 500 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
460 } 501 }
502
461 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 503 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
462 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 504 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 } 505 }
486 506
487 void RenderingHelper::DeleteTexture(uint32 texture_id) { 507 void RenderingHelper::DeleteTexture(uint32 texture_id) {
488 glDeleteTextures(1, &texture_id); 508 glDeleteTextures(1, &texture_id);
489 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 509 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
490 } 510 }
491 511
492 NativeContextType RenderingHelper::GetGLContext() { return gl_context_; } 512 NativeContextType RenderingHelper::GetGLContext() { return gl_context_; }
493 513
494 void* RenderingHelper::GetGLDisplay() { 514 void* RenderingHelper::GetGLDisplay() {
495 #if GL_VARIANT_GLX 515 #if GL_VARIANT_GLX
496 return x_display_; 516 return x_display_;
497 #else // EGL 517 #else // EGL
498 return gl_display_; 518 return gl_display_;
499 #endif 519 #endif
500 } 520 }
501 521
502 void RenderingHelper::Clear() { 522 void RenderingHelper::Clear() {
503 window_dimensions_.clear();
504 frame_dimensions_.clear(); 523 frame_dimensions_.clear();
505 texture_id_to_surface_index_.clear(); 524 texture_id_to_surface_index_.clear();
506 message_loop_ = NULL; 525 message_loop_ = NULL;
507 gl_context_ = NULL; 526 gl_context_ = NULL;
508 #if GL_VARIANT_EGL 527 #if GL_VARIANT_EGL
509 gl_display_ = EGL_NO_DISPLAY; 528 gl_display_ = EGL_NO_DISPLAY;
510 gl_surfaces_.clear(); 529 gl_surface_ = EGL_NO_SURFACE;
511 #endif 530 #endif
512 render_as_thumbnails_ = false; 531 render_as_thumbnails_ = false;
513 frame_count_ = 0; 532 frame_count_ = 0;
514 thumbnails_fbo_id_ = 0; 533 thumbnails_fbo_id_ = 0;
515 thumbnails_texture_id_ = 0; 534 thumbnails_texture_id_ = 0;
516 535
517 #if defined(OS_WIN) 536 #if defined(OS_WIN)
518 for (size_t i = 0; i < windows_.size(); ++i) { 537 if (window_) {
519 DestroyWindow(windows_[i]); 538 DestroyWindow(window_);
539 window_ = NULL;
520 } 540 }
521 windows_.clear();
522 #else 541 #else
523 // Destroy resources acquired in Initialize, in reverse-acquisition order. 542 // Destroy resources acquired in Initialize, in reverse-acquisition order.
524 for (size_t i = 0; i < x_windows_.size(); ++i) { 543 if (x_window_) {
525 CHECK(XUnmapWindow(x_display_, x_windows_[i])); 544 CHECK(XUnmapWindow(x_display_, x_window_));
526 CHECK(XDestroyWindow(x_display_, x_windows_[i])); 545 CHECK(XDestroyWindow(x_display_, x_window_));
546 x_window_ = (Window)0;
527 } 547 }
528 // Mimic newly created object. 548 // Mimic newly created object.
529 x_display_ = NULL; 549 x_display_ = NULL;
530 x_windows_.clear();
531 #endif 550 #endif
532 } 551 }
533 552
534 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, 553 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
535 bool* alpha_solid, 554 bool* alpha_solid,
536 base::WaitableEvent* done) { 555 base::WaitableEvent* done) {
537 CHECK(render_as_thumbnails_); 556 CHECK(render_as_thumbnails_);
538 557
539 const size_t num_pixels = thumbnails_fbo_size_.GetArea(); 558 const size_t num_pixels = thumbnails_fbo_size_.GetArea();
540 std::vector<unsigned char> rgba; 559 std::vector<unsigned char> rgba;
(...skipping 19 matching lines...) Expand all
560 *rgb_ptr++ = *rgba_ptr++; 579 *rgb_ptr++ = *rgba_ptr++;
561 *rgb_ptr++ = *rgba_ptr++; 580 *rgb_ptr++ = *rgba_ptr++;
562 solid = solid && (*rgba_ptr == 0xff); 581 solid = solid && (*rgba_ptr == 0xff);
563 rgba_ptr++; 582 rgba_ptr++;
564 } 583 }
565 *alpha_solid = solid; 584 *alpha_solid = solid;
566 585
567 done->Signal(); 586 done->Signal();
568 } 587 }
569 588
589 void RenderingHelper::RenderContent() {
590 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1);
591 for (size_t i = 0; i < render_areas_.size(); ++i) {
592 DrawTexture(render_areas_[i], texture_targets_[i], texture_ids_[i]);
593 }
594
595 #if GL_VARIANT_GLX
596 glXSwapBuffers(x_display_, x_window_);
597 #else // EGL
598 eglSwapBuffers(gl_display_, gl_surface_);
599 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS);
600 #endif
601 }
570 } // namespace content 602 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/rendering_helper.h ('k') | content/common/gpu/media/video_decode_accelerator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698