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

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 typos and run git cl format 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 // TODO(owenlin): pass fps from params
101 frame_duration_ = base::TimeDelta::FromSeconds(1) / 60;
102
106 gfx::InitializeStaticGLBindings(kGLImplementation); 103 gfx::InitializeStaticGLBindings(kGLImplementation);
107 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context( 104 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context(
108 new gfx::GLContextStubWithExtensions()); 105 new gfx::GLContextStubWithExtensions());
109 106
110 CHECK_GT(params.window_dimensions.size(), 0U); 107 CHECK_GT(params.window_dimensions.size(), 0U);
111 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size()); 108 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size());
112 window_dimensions_ = params.window_dimensions;
113 frame_dimensions_ = params.frame_dimensions; 109 frame_dimensions_ = params.frame_dimensions;
114 render_as_thumbnails_ = params.render_as_thumbnails; 110 render_as_thumbnails_ = params.render_as_thumbnails;
115 message_loop_ = base::MessageLoop::current(); 111 message_loop_ = base::MessageLoop::current();
116 CHECK_GT(params.num_windows, 0); 112 CHECK_GT(params.num_windows, 0);
117 113
114 gfx::Size window_size;
115
118 #if GL_VARIANT_GLX 116 #if GL_VARIANT_GLX
119 x_display_ = gfx::GetXDisplay(); 117 x_display_ = gfx::GetXDisplay();
120 CHECK(x_display_); 118 CHECK(x_display_);
121 CHECK(glXQueryVersion(x_display_, NULL, NULL)); 119 CHECK(glXQueryVersion(x_display_, NULL, NULL));
122 const int fbconfig_attr[] = { 120 const int fbconfig_attr[] = {
123 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 121 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
124 GLX_RENDER_TYPE, GLX_RGBA_BIT, 122 GLX_RENDER_TYPE, GLX_RGBA_BIT,
125 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, 123 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
126 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, 124 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE,
127 GLX_DOUBLEBUFFER, True, 125 GLX_DOUBLEBUFFER, True,
128 GL_NONE, 126 GL_NONE,
129 }; 127 };
130 int num_fbconfigs; 128 int num_fbconfigs;
131 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs( 129 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs(
132 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, 130 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr,
133 &num_fbconfigs)); 131 &num_fbconfigs));
134 CHECK(glx_fb_configs.get()); 132 CHECK(glx_fb_configs.get());
135 CHECK_GT(num_fbconfigs, 0); 133 CHECK_GT(num_fbconfigs, 0);
136 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]); 134 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]);
137 CHECK(x_visual_); 135 CHECK(x_visual_);
138 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true); 136 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true);
139 CHECK(gl_context_); 137 CHECK(gl_context_);
140 stub_context->AddExtensionsString( 138 stub_context->AddExtensionsString(
141 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 139 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
142 stub_context->SetGLVersionString( 140 stub_context->SetGLVersionString(
143 reinterpret_cast<const char*>(glGetString(GL_VERSION))); 141 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
144 142
143 Screen* screen = DefaultScreenOfDisplay(x_display_);
144 window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen));
145 #else // EGL 145 #else // EGL
146 EGLNativeDisplayType native_display; 146 EGLNativeDisplayType native_display;
147 147
148 #if defined(OS_WIN) 148 #if defined(OS_WIN)
149 native_display = EGL_DEFAULT_DISPLAY; 149 native_display = EGL_DEFAULT_DISPLAY;
150 window_size =
151 gfx::Size(GetSystemMetrics(SM_CXSREEN), GetSystemMetrics(SM_CY_SCREEN));
150 #else 152 #else
151 x_display_ = gfx::GetXDisplay(); 153 x_display_ = gfx::GetXDisplay();
152 CHECK(x_display_); 154 CHECK(x_display_);
153 native_display = x_display_; 155 native_display = x_display_;
156
157 Screen* screen = DefaultScreenOfDisplay(x_display_);
158 window_size = gfx::Size(XWidthOfScreen(screen), XHeightOfScreen(screen));
154 #endif 159 #endif
155
156 gl_display_ = eglGetDisplay(native_display); 160 gl_display_ = eglGetDisplay(native_display);
157 CHECK(gl_display_); 161 CHECK(gl_display_);
158 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError(); 162 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError();
159 163
160 static EGLint rgba8888[] = { 164 static EGLint rgba8888[] = {
161 EGL_RED_SIZE, 8, 165 EGL_RED_SIZE, 8,
162 EGL_GREEN_SIZE, 8, 166 EGL_GREEN_SIZE, 8,
163 EGL_BLUE_SIZE, 8, 167 EGL_BLUE_SIZE, 8,
164 EGL_ALPHA_SIZE, 8, 168 EGL_ALPHA_SIZE, 8,
165 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 169 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
166 EGL_NONE, 170 EGL_NONE,
167 }; 171 };
168 EGLConfig egl_config; 172 EGLConfig egl_config;
169 int num_configs; 173 int num_configs;
170 CHECK(eglChooseConfig(gl_display_, rgba8888, &egl_config, 1, &num_configs)) 174 CHECK(eglChooseConfig(gl_display_, rgba8888, &egl_config, 1, &num_configs))
171 << eglGetError(); 175 << eglGetError();
172 CHECK_GE(num_configs, 1); 176 CHECK_GE(num_configs, 1);
173 static EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; 177 static EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
174 gl_context_ = eglCreateContext( 178 gl_context_ = eglCreateContext(
175 gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs); 179 gl_display_, egl_config, EGL_NO_CONTEXT, context_attribs);
176 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError(); 180 CHECK_NE(gl_context_, EGL_NO_CONTEXT) << eglGetError();
177 stub_context->AddExtensionsString( 181 stub_context->AddExtensionsString(
178 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 182 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
179 stub_context->AddExtensionsString( 183 stub_context->AddExtensionsString(
180 eglQueryString(gl_display_, EGL_EXTENSIONS)); 184 eglQueryString(gl_display_, EGL_EXTENSIONS));
181 stub_context->SetGLVersionString( 185 stub_context->SetGLVersionString(
182 reinterpret_cast<const char*>(glGetString(GL_VERSION))); 186 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
183 #endif 187 #endif
184 188
185 // Per-window/surface X11 & EGL initialization. 189 // Per-window/surface X11 & EGL initialization.
Pawel Osciak 2014/05/27 06:21:49 CHECK(texture_ids_.empty()); CHECK(texture_targets
186 for (int i = 0; i < params.num_windows; ++i) { 190 for (int i = 0; i < params.num_windows; ++i) {
187 // Arrange X windows whimsically, with some padding. 191 // Arrange X windows whimsically, with some padding.
188 int j = i % window_dimensions_.size(); 192 int j = i % params.window_dimensions.size();
189 int width = window_dimensions_[j].width(); 193 int width = params.window_dimensions[j].width();
190 int height = window_dimensions_[j].height(); 194 int height = params.window_dimensions[j].height();
191 CHECK_GT(width, 0); 195 CHECK_GT(width, 0);
192 CHECK_GT(height, 0); 196 CHECK_GT(height, 0);
193 int top_left_x = (width + 20) * (i % 4); 197 int top_left_x = (width + 20) * (i % 4);
194 int top_left_y = (height + 12) * (i % 3); 198 int top_left_y = (height + 12) * (i % 3);
199 render_areas_.push_back(gfx::Rect(top_left_x, top_left_y, width, height));
200
201 // Initialize to an invalid texture id: 0 to indicate no texture
202 // for rendering.
203 texture_ids_.push_back(0);
Pawel Osciak 2014/05/27 06:21:49 You could achieve the same by saying outside of th
Owen Lin 2014/05/27 07:33:51 Thanks.
204 texture_targets_.push_back(0);
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 gl_surface_ =
230 eglCreateWindowSurface(gl_display_, egl_config, window, NULL); 252 eglCreateWindowSurface(gl_display_, egl_config, x_window_, NULL);
231 gl_surfaces_.push_back(egl_surface); 253 CHECK_NE(gl_surface_, EGL_NO_SURFACE);
232 CHECK_NE(egl_surface, EGL_NO_SURFACE);
233 #endif 254 #endif
234 MakeCurrent(i); 255
235 } 256 #if GL_VARIANT_GLX
257 CHECK(glXMakeContextCurrent(x_display_, x_window_, x_window_, gl_context_));
258 #else // EGL
259 CHECK(eglMakeCurrent(gl_display_, gl_surface_, gl_surface_, gl_context_))
260 << eglGetError();
261 #endif
236 262
237 // Must be done after a context is made current. 263 // Must be done after a context is made current.
238 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get()); 264 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get());
239 265
240 if (render_as_thumbnails_) { 266 if (render_as_thumbnails_) {
241 CHECK_EQ(window_dimensions_.size(), 1U); 267 CHECK_EQ(frame_dimensions_.size(), 1U);
242 268
243 GLint max_texture_size; 269 GLint max_texture_size;
244 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); 270 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
245 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); 271 CHECK_GE(max_texture_size, params.thumbnails_page_size.width());
246 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); 272 CHECK_GE(max_texture_size, params.thumbnails_page_size.height());
247 273
248 thumbnails_fbo_size_ = params.thumbnails_page_size; 274 thumbnails_fbo_size_ = params.thumbnails_page_size;
249 thumbnail_size_ = params.thumbnail_size; 275 thumbnail_size_ = params.thumbnail_size;
250 276
251 glGenFramebuffersEXT(1, &thumbnails_fbo_id_); 277 glGenFramebuffersEXT(1, &thumbnails_fbo_id_);
(...skipping 18 matching lines...) Expand all
270 GL_COLOR_ATTACHMENT0, 296 GL_COLOR_ATTACHMENT0,
271 GL_TEXTURE_2D, 297 GL_TEXTURE_2D,
272 thumbnails_texture_id_, 298 thumbnails_texture_id_,
273 0); 299 0);
274 300
275 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 301 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
276 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; 302 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status;
277 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 303 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
278 glClear(GL_COLOR_BUFFER_BIT); 304 glClear(GL_COLOR_BUFFER_BIT);
279 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 305 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
306
307 // In render_as_thumbnails_ mode, we render the FBO content on the
308 // screen instead of the decoded textures.
309 texture_targets_[0] = GL_TEXTURE_2D;
310 texture_ids_[0] = thumbnails_texture_id_;
280 } 311 }
281 312
282 // These vertices and texture coords. map (0,0) in the texture to the 313 // 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 314 // 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 315 // 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. 316 // 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 317 // 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. 318 // to render the FBO the screen, where we do not want this flipping.
288 static const float kVertices[] = 319 static const float kVertices[] =
289 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, }; 320 { -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"); 379 GLint tex_external = glGetUniformLocation(program_, "tex_external");
349 if (tex_external != -1) { 380 if (tex_external != -1) {
350 glUniform1i(tex_external, 1); 381 glUniform1i(tex_external, 1);
351 } 382 }
352 int pos_location = glGetAttribLocation(program_, "in_pos"); 383 int pos_location = glGetAttribLocation(program_, "in_pos");
353 glEnableVertexAttribArray(pos_location); 384 glEnableVertexAttribArray(pos_location);
354 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); 385 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
355 int tc_location = glGetAttribLocation(program_, "in_tc"); 386 int tc_location = glGetAttribLocation(program_, "in_tc");
356 glEnableVertexAttribArray(tc_location); 387 glEnableVertexAttribArray(tc_location);
357 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); 388 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords);
389
390 render_timer_.Start(
391 FROM_HERE, frame_duration_, this, &RenderingHelper::RenderContent);
358 done->Signal(); 392 done->Signal();
359 } 393 }
360 394
361 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { 395 void RenderingHelper::UnInitialize(base::WaitableEvent* done) {
362 CHECK_EQ(base::MessageLoop::current(), message_loop_); 396 CHECK_EQ(base::MessageLoop::current(), message_loop_);
397 render_timer_.Stop();
363 if (render_as_thumbnails_) { 398 if (render_as_thumbnails_) {
364 glDeleteTextures(1, &thumbnails_texture_id_); 399 glDeleteTextures(1, &thumbnails_texture_id_);
365 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); 400 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_);
366 } 401 }
367 #if GL_VARIANT_GLX 402 #if GL_VARIANT_GLX
368 403
369 glXDestroyContext(x_display_, gl_context_); 404 glXDestroyContext(x_display_, gl_context_);
370 #else // EGL 405 #else // EGL
371 MakeCurrent(-1);
372 CHECK(eglDestroyContext(gl_display_, gl_context_)); 406 CHECK(eglDestroyContext(gl_display_, gl_context_));
373 for (size_t i = 0; i < gl_surfaces_.size(); ++i) 407 CHECK(eglDestroySurface(gl_display_, gl_surface_));
374 CHECK(eglDestroySurface(gl_display_, gl_surfaces_[i]));
375 CHECK(eglTerminate(gl_display_)); 408 CHECK(eglTerminate(gl_display_));
376 #endif 409 #endif
377 gfx::ClearGLBindings(); 410 gfx::ClearGLBindings();
378 Clear(); 411 Clear();
379 done->Signal(); 412 done->Signal();
380 } 413 }
381 414
382 void RenderingHelper::CreateTexture(int window_id, 415 void RenderingHelper::CreateTexture(int window_id,
383 uint32 texture_target, 416 uint32 texture_target,
384 uint32* texture_id, 417 uint32* texture_id,
385 base::WaitableEvent* done) { 418 base::WaitableEvent* done) {
386 if (base::MessageLoop::current() != message_loop_) { 419 if (base::MessageLoop::current() != message_loop_) {
387 message_loop_->PostTask( 420 message_loop_->PostTask(
388 FROM_HERE, 421 FROM_HERE,
389 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), 422 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this),
390 window_id, texture_target, texture_id, done)); 423 window_id, texture_target, texture_id, done));
391 return; 424 return;
392 } 425 }
393 MakeCurrent(window_id);
394 glGenTextures(1, texture_id); 426 glGenTextures(1, texture_id);
395 glBindTexture(texture_target, *texture_id); 427 glBindTexture(texture_target, *texture_id);
396 int dimensions_id = window_id % frame_dimensions_.size(); 428 int dimensions_id = window_id % frame_dimensions_.size();
397 if (texture_target == GL_TEXTURE_2D) { 429 if (texture_target == GL_TEXTURE_2D) {
398 glTexImage2D(GL_TEXTURE_2D, 430 glTexImage2D(GL_TEXTURE_2D,
399 0, 431 0,
400 GL_RGBA, 432 GL_RGBA,
401 frame_dimensions_[dimensions_id].width(), 433 frame_dimensions_[dimensions_id].width(),
402 frame_dimensions_[dimensions_id].height(), 434 frame_dimensions_[dimensions_id].height(),
403 0, 435 0,
404 GL_RGBA, 436 GL_RGBA,
405 GL_UNSIGNED_BYTE, 437 GL_UNSIGNED_BYTE,
406 NULL); 438 NULL);
407 } 439 }
408 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 440 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
409 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 441 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
410 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. 442 // 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); 443 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
412 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 444 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
413 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 445 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
414 CHECK(texture_id_to_surface_index_.insert( 446 CHECK(texture_id_to_surface_index_.insert(
415 std::make_pair(*texture_id, window_id)).second); 447 std::make_pair(*texture_id, window_id)).second);
416 done->Signal(); 448 done->Signal();
417 } 449 }
418 450
419 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { 451 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) {
420 CHECK_EQ(base::MessageLoop::current(), message_loop_); 452 CHECK_EQ(base::MessageLoop::current(), message_loop_);
421 size_t window_id = texture_id_to_surface_index_[texture_id]; 453 if (texture_id == 0)
422 MakeCurrent(window_id); 454 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 455
428 if (render_as_thumbnails_) { 456 if (render_as_thumbnails_) {
429 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); 457 const int width = thumbnail_size_.width();
430 const int thumbnails_in_row = 458 const int height = thumbnail_size_.height();
431 thumbnails_fbo_size_.width() / thumbnail_size_.width(); 459 const int thumbnails_in_row = thumbnails_fbo_size_.width() / width;
432 const int thumbnails_in_column = 460 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; 461 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column;
435 const int col = frame_count_ % thumbnails_in_row; 462 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 463
439 glViewport(x, y, thumbnail_size_.width(), thumbnail_size_.height()); 464 gfx::Rect area(col * width, row * height, width, height);
440 glScissor(x, y, thumbnail_size_.width(), thumbnail_size_.height()); 465
441 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); 466 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0);
467 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_);
468 DrawTexture(area, texture_target, texture_id);
469 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
470 ++frame_count_;
442 } else { 471 } else {
443 glViewport(0, 0, width, height); 472 size_t window_id = texture_id_to_surface_index_[texture_id];
444 glScissor(0, 0, width, height); 473 texture_targets_[window_id] = texture_target;
445 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); 474 texture_ids_[window_id] = texture_id;
Pawel Osciak 2014/05/27 06:21:49 It looks to me that RenderTexture() used to be syn
Owen Lin 2014/05/27 07:33:51 Ah, you are right. There is problem in this code.
Pawel Osciak 2014/05/28 05:45:52 Hm, I guess merging is probably better once we lgt
446 } 475 }
476 }
477
478 void RenderingHelper::DrawTexture(const gfx::Rect& area,
479 uint32 texture_target,
480 uint32 texture_id) {
481 glViewport(area.x(), area.y(), area.width(), area.height());
482 glScissor(area.x(), area.y(), area.width(), area.height());
447 483
448 // Unbound texture samplers default to (0, 0, 0, 1). Use this fact to switch 484 // 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. 485 // between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES as appopriate.
450 if (texture_target == GL_TEXTURE_2D) { 486 if (texture_target == GL_TEXTURE_2D) {
451 glActiveTexture(GL_TEXTURE0 + 0); 487 glActiveTexture(GL_TEXTURE0 + 0);
452 glBindTexture(GL_TEXTURE_2D, texture_id); 488 glBindTexture(GL_TEXTURE_2D, texture_id);
453 glActiveTexture(GL_TEXTURE0 + 1); 489 glActiveTexture(GL_TEXTURE0 + 1);
454 glBindTexture(texture_target, 0); 490 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
455 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) { 491 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) {
456 glActiveTexture(GL_TEXTURE0 + 0); 492 glActiveTexture(GL_TEXTURE0 + 0);
457 glBindTexture(GL_TEXTURE_2D, 0); 493 glBindTexture(GL_TEXTURE_2D, 0);
458 glActiveTexture(GL_TEXTURE0 + 1); 494 glActiveTexture(GL_TEXTURE0 + 1);
459 glBindTexture(texture_target, texture_id); 495 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
460 } 496 }
497
461 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 498 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
462 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 499 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 } 500 }
486 501
487 void RenderingHelper::DeleteTexture(uint32 texture_id) { 502 void RenderingHelper::DeleteTexture(uint32 texture_id) {
488 glDeleteTextures(1, &texture_id); 503 glDeleteTextures(1, &texture_id);
489 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 504 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
490 } 505 }
491 506
492 NativeContextType RenderingHelper::GetGLContext() { return gl_context_; } 507 NativeContextType RenderingHelper::GetGLContext() { return gl_context_; }
493 508
494 void* RenderingHelper::GetGLDisplay() { 509 void* RenderingHelper::GetGLDisplay() {
495 #if GL_VARIANT_GLX 510 #if GL_VARIANT_GLX
496 return x_display_; 511 return x_display_;
497 #else // EGL 512 #else // EGL
498 return gl_display_; 513 return gl_display_;
499 #endif 514 #endif
500 } 515 }
501 516
502 void RenderingHelper::Clear() { 517 void RenderingHelper::Clear() {
503 window_dimensions_.clear();
504 frame_dimensions_.clear(); 518 frame_dimensions_.clear();
505 texture_id_to_surface_index_.clear(); 519 texture_id_to_surface_index_.clear();
506 message_loop_ = NULL; 520 message_loop_ = NULL;
507 gl_context_ = NULL; 521 gl_context_ = NULL;
508 #if GL_VARIANT_EGL 522 #if GL_VARIANT_EGL
509 gl_display_ = EGL_NO_DISPLAY; 523 gl_display_ = EGL_NO_DISPLAY;
510 gl_surfaces_.clear(); 524 gl_surface_ = EGL_NO_SURFACE;
511 #endif 525 #endif
512 render_as_thumbnails_ = false; 526 render_as_thumbnails_ = false;
513 frame_count_ = 0; 527 frame_count_ = 0;
514 thumbnails_fbo_id_ = 0; 528 thumbnails_fbo_id_ = 0;
515 thumbnails_texture_id_ = 0; 529 thumbnails_texture_id_ = 0;
516 530
517 #if defined(OS_WIN) 531 #if defined(OS_WIN)
518 for (size_t i = 0; i < windows_.size(); ++i) { 532 if (window_) {
519 DestroyWindow(windows_[i]); 533 DestroyWindow(window_);
534 window_ = NULL;
520 } 535 }
521 windows_.clear();
522 #else 536 #else
523 // Destroy resources acquired in Initialize, in reverse-acquisition order. 537 // Destroy resources acquired in Initialize, in reverse-acquisition order.
524 for (size_t i = 0; i < x_windows_.size(); ++i) { 538 if (x_window_) {
525 CHECK(XUnmapWindow(x_display_, x_windows_[i])); 539 CHECK(XUnmapWindow(x_display_, x_window_));
526 CHECK(XDestroyWindow(x_display_, x_windows_[i])); 540 CHECK(XDestroyWindow(x_display_, x_window_));
541 x_window_ = (Window)0;
527 } 542 }
528 // Mimic newly created object. 543 // Mimic newly created object.
529 x_display_ = NULL; 544 x_display_ = NULL;
530 x_windows_.clear();
531 #endif 545 #endif
532 } 546 }
533 547
534 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, 548 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
535 bool* alpha_solid, 549 bool* alpha_solid,
536 base::WaitableEvent* done) { 550 base::WaitableEvent* done) {
537 CHECK(render_as_thumbnails_); 551 CHECK(render_as_thumbnails_);
538 552
539 const size_t num_pixels = thumbnails_fbo_size_.GetArea(); 553 const size_t num_pixels = thumbnails_fbo_size_.GetArea();
540 std::vector<unsigned char> rgba; 554 std::vector<unsigned char> rgba;
(...skipping 19 matching lines...) Expand all
560 *rgb_ptr++ = *rgba_ptr++; 574 *rgb_ptr++ = *rgba_ptr++;
561 *rgb_ptr++ = *rgba_ptr++; 575 *rgb_ptr++ = *rgba_ptr++;
562 solid = solid && (*rgba_ptr == 0xff); 576 solid = solid && (*rgba_ptr == 0xff);
563 rgba_ptr++; 577 rgba_ptr++;
564 } 578 }
565 *alpha_solid = solid; 579 *alpha_solid = solid;
566 580
567 done->Signal(); 581 done->Signal();
568 } 582 }
569 583
584 void RenderingHelper::RenderContent() {
585 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1);
586 for (size_t i = 0; i < render_areas_.size(); ++i) {
587 DrawTexture(render_areas_[i], texture_targets_[i], texture_ids_[i]);
588 }
589
590 #if GL_VARIANT_GLX
591 glXSwapBuffers(x_display_, x_window_);
592 #else // EGL
593 eglSwapBuffers(gl_display_, gl_surface_);
594 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS);
595 #endif
596 }
570 } // namespace content 597 } // namespace content
OLDNEW
« content/common/gpu/media/rendering_helper.h ('K') | « content/common/gpu/media/rendering_helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698