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

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: Created 6 years, 7 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(USE_X11) 17 #if defined(USE_X11)
18 #include "ui/gfx/x/x11_types.h" 18 #include "ui/gfx/x/x11_types.h"
19 #endif 19 #endif
20 20
21 const int kDefaultWindowWidth = 1280;
22 const int kDefaultWindowHeight = 720;
Ami GONE FROM CHROMIUM 2014/05/08 21:15:09 Can you drop these in favor of WIN APIs for discov
Owen Lin 2014/05/09 10:25:03 Done.
23
21 #ifdef GL_VARIANT_GLX 24 #ifdef GL_VARIANT_GLX
22 typedef GLXWindow NativeWindowType; 25 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 29 #else // EGL
27 typedef EGLNativeWindowType NativeWindowType; 30 typedef EGLNativeWindowType NativeWindowType;
28 #endif 31 #endif
29 32
30 // Helper for Shader creation. 33 // Helper for Shader creation.
(...skipping 26 matching lines...) Expand all
57 #if defined(GL_VARIANT_GLX) 60 #if defined(GL_VARIANT_GLX)
58 gfx::kGLImplementationDesktopGL; 61 gfx::kGLImplementationDesktopGL;
59 #elif defined(GL_VARIANT_EGL) 62 #elif defined(GL_VARIANT_EGL)
60 gfx::kGLImplementationEGLGLES2; 63 gfx::kGLImplementationEGLGLES2;
61 #else 64 #else
62 -1; 65 -1;
63 #error "Unknown GL implementation." 66 #error "Unknown GL implementation."
64 #endif 67 #endif
65 68
66 RenderingHelper::RenderingHelper() { 69 RenderingHelper::RenderingHelper() {
70 #if defined(GL_VARIANT_EGL)
71 gl_surface_ = EGL_NO_SURFACE;
72 #endif
73
74 #if defined(OS_WIN)
75 window_ = NULL;
76 #else
77 x_window_ = (Window) 0;
78 #endif
79
80 rendering_state_ = RENDERING_STOPPED;
81
67 Clear(); 82 Clear();
68 } 83 }
69 84
70 RenderingHelper::~RenderingHelper() { 85 RenderingHelper::~RenderingHelper() {
71 CHECK_EQ(window_dimensions_.size(), 0U) << 86 CHECK_EQ(frame_dimensions_.size(), 0U) <<
72 "Must call UnInitialize before dtor."; 87 "Must call UnInitialize before dtor.";
73 Clear(); 88 Clear();
74 } 89 }
75 90
76 void RenderingHelper::MakeCurrent(int window_id) { 91 void RenderingHelper::MakeCurrent(int window_id) {
77 #if GL_VARIANT_GLX 92 #if GL_VARIANT_GLX
78 if (window_id < 0) { 93 if (window_id < 0) {
79 CHECK(glXMakeContextCurrent(x_display_, GLX_NONE, GLX_NONE, NULL)); 94 CHECK(glXMakeContextCurrent(x_display_, GLX_NONE, GLX_NONE, NULL));
80 } else { 95 } else {
81 CHECK(glXMakeContextCurrent( 96 CHECK(glXMakeContextCurrent(
82 x_display_, x_windows_[window_id], x_windows_[window_id], gl_context_)); 97 x_display_, x_window_, x_window_, gl_context_));
83 } 98 }
84 #else // EGL 99 #else // EGL
85 if (window_id < 0) { 100 if (window_id < 0) {
86 CHECK(eglMakeCurrent(gl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, 101 CHECK(eglMakeCurrent(gl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
87 EGL_NO_CONTEXT)) << eglGetError(); 102 EGL_NO_CONTEXT)) << eglGetError();
88 } else { 103 } else {
89 CHECK(eglMakeCurrent(gl_display_, gl_surfaces_[window_id], 104 CHECK(eglMakeCurrent(gl_display_, gl_surface_, gl_surface_,
90 gl_surfaces_[window_id], gl_context_)) 105 gl_context_)) << eglGetError();
91 << eglGetError();
92 } 106 }
93 #endif 107 #endif
94 } 108 }
95 109
96 void RenderingHelper::Initialize(const RenderingHelperParams& params, 110 void RenderingHelper::Initialize(const RenderingHelperParams& params,
97 base::WaitableEvent* done) { 111 base::WaitableEvent* done) {
98 // Use window_dimensions_.size() != 0 as a proxy for the class having already 112 // Use frame_dimensions_.size() != 0 as a proxy for the class having already
99 // been Initialize()'d, and UnInitialize() before continuing. 113 // been Initialize()'d, and UnInitialize() before continuing.
100 if (window_dimensions_.size()) { 114 if (frame_dimensions_.size()) {
101 base::WaitableEvent done(false, false); 115 base::WaitableEvent done(false, false);
102 UnInitialize(&done); 116 UnInitialize(&done);
103 done.Wait(); 117 done.Wait();
104 } 118 }
105 119
120 // TODO(owenlin): pass fps from params
121 frame_duration_ = base::TimeDelta::FromSeconds(1) / 60;
122
106 gfx::InitializeStaticGLBindings(kGLImplementation); 123 gfx::InitializeStaticGLBindings(kGLImplementation);
107 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context( 124 scoped_refptr<gfx::GLContextStubWithExtensions> stub_context(
108 new gfx::GLContextStubWithExtensions()); 125 new gfx::GLContextStubWithExtensions());
109 126
110 CHECK_GT(params.window_dimensions.size(), 0U); 127 CHECK_GT(params.window_dimensions.size(), 0U);
111 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size()); 128 CHECK_EQ(params.frame_dimensions.size(), params.window_dimensions.size());
112 window_dimensions_ = params.window_dimensions;
113 frame_dimensions_ = params.frame_dimensions; 129 frame_dimensions_ = params.frame_dimensions;
114 render_as_thumbnails_ = params.render_as_thumbnails; 130 render_as_thumbnails_ = params.render_as_thumbnails;
115 message_loop_ = base::MessageLoop::current(); 131 message_loop_ = base::MessageLoop::current();
116 CHECK_GT(params.num_windows, 0); 132 CHECK_GT(params.num_windows, 0);
117 133
134 gfx::Size window_size(kDefaultWindowWidth, kDefaultWindowHeight);
135
118 #if GL_VARIANT_GLX 136 #if GL_VARIANT_GLX
119 x_display_ = gfx::GetXDisplay(); 137 x_display_ = gfx::GetXDisplay();
120 CHECK(x_display_); 138 CHECK(x_display_);
121 CHECK(glXQueryVersion(x_display_, NULL, NULL)); 139 CHECK(glXQueryVersion(x_display_, NULL, NULL));
122 const int fbconfig_attr[] = { 140 const int fbconfig_attr[] = {
123 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 141 GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
124 GLX_RENDER_TYPE, GLX_RGBA_BIT, 142 GLX_RENDER_TYPE, GLX_RGBA_BIT,
125 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, 143 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
126 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE, 144 GLX_BIND_TO_TEXTURE_RGB_EXT, GL_TRUE,
127 GLX_DOUBLEBUFFER, True, 145 GLX_DOUBLEBUFFER, True,
128 GL_NONE, 146 GL_NONE,
129 }; 147 };
130 int num_fbconfigs; 148 int num_fbconfigs;
131 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs( 149 scoped_ptr<GLXFBConfig, XFreeDeleter> glx_fb_configs(
132 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr, 150 glXChooseFBConfig(x_display_, DefaultScreen(x_display_), fbconfig_attr,
133 &num_fbconfigs)); 151 &num_fbconfigs));
134 CHECK(glx_fb_configs.get()); 152 CHECK(glx_fb_configs.get());
135 CHECK_GT(num_fbconfigs, 0); 153 CHECK_GT(num_fbconfigs, 0);
136 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]); 154 x_visual_ = glXGetVisualFromFBConfig(x_display_, glx_fb_configs.get()[0]);
137 CHECK(x_visual_); 155 CHECK(x_visual_);
138 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true); 156 gl_context_ = glXCreateContext(x_display_, x_visual_, 0, true);
139 CHECK(gl_context_); 157 CHECK(gl_context_);
140 stub_context->AddExtensionsString( 158 stub_context->AddExtensionsString(
141 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 159 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
142 stub_context->SetGLVersionString( 160 stub_context->SetGLVersionString(
143 reinterpret_cast<const char*>(glGetString(GL_VERSION))); 161 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
144 162
163 Screen *scrn = DefaultScreenOfDisplay(x_display_);
Ami GONE FROM CHROMIUM 2014/05/08 21:15:09 s/scrn/screen/ (ditto elsewhere chromium & google
Owen Lin 2014/05/09 10:25:03 Done.
164 window_size = gfx::Size(XWidthOfScreen(scrn), XHeightOfScreen(scrn));
145 #else // EGL 165 #else // EGL
146 EGLNativeDisplayType native_display; 166 EGLNativeDisplayType native_display;
147 167
148 #if defined(OS_WIN) 168 #if defined(OS_WIN)
149 native_display = EGL_DEFAULT_DISPLAY; 169 native_display = EGL_DEFAULT_DISPLAY;
150 #else 170 #else
151 x_display_ = gfx::GetXDisplay(); 171 x_display_ = gfx::GetXDisplay();
152 CHECK(x_display_); 172 CHECK(x_display_);
153 native_display = x_display_; 173 native_display = x_display_;
174
175 Screen *scrn = DefaultScreenOfDisplay(x_display_);
176 window_size = gfx::Size(XWidthOfScreen(scrn), XHeightOfScreen(scrn));
154 #endif 177 #endif
155 178
156 gl_display_ = eglGetDisplay(native_display); 179 gl_display_ = eglGetDisplay(native_display);
157 CHECK(gl_display_); 180 CHECK(gl_display_);
158 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError(); 181 CHECK(eglInitialize(gl_display_, NULL, NULL)) << glGetError();
159 182
160 static EGLint rgba8888[] = { 183 static EGLint rgba8888[] = {
161 EGL_RED_SIZE, 8, 184 EGL_RED_SIZE, 8,
162 EGL_GREEN_SIZE, 8, 185 EGL_GREEN_SIZE, 8,
163 EGL_BLUE_SIZE, 8, 186 EGL_BLUE_SIZE, 8,
(...skipping 14 matching lines...) Expand all
178 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); 201 reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)));
179 stub_context->AddExtensionsString( 202 stub_context->AddExtensionsString(
180 eglQueryString(gl_display_, EGL_EXTENSIONS)); 203 eglQueryString(gl_display_, EGL_EXTENSIONS));
181 stub_context->SetGLVersionString( 204 stub_context->SetGLVersionString(
182 reinterpret_cast<const char*>(glGetString(GL_VERSION))); 205 reinterpret_cast<const char*>(glGetString(GL_VERSION)));
183 #endif 206 #endif
184 207
185 // Per-window/surface X11 & EGL initialization. 208 // Per-window/surface X11 & EGL initialization.
186 for (int i = 0; i < params.num_windows; ++i) { 209 for (int i = 0; i < params.num_windows; ++i) {
187 // Arrange X windows whimsically, with some padding. 210 // Arrange X windows whimsically, with some padding.
188 int j = i % window_dimensions_.size(); 211 int j = i % params.window_dimensions.size();
189 int width = window_dimensions_[j].width(); 212 int width = params.window_dimensions[j].width();
190 int height = window_dimensions_[j].height(); 213 int height = params.window_dimensions[j].height();
191 CHECK_GT(width, 0); 214 CHECK_GT(width, 0);
192 CHECK_GT(height, 0); 215 CHECK_GT(height, 0);
193 int top_left_x = (width + 20) * (i % 4); 216 int top_left_x = (width + 20) * (i % 4);
194 int top_left_y = (height + 12) * (i % 3); 217 int top_left_y = (height + 12) * (i % 3);
218 render_areas_.push_back(gfx::Rect(
219 top_left_x, top_left_y, width, height));
220 texture_ids_.push_back(0);
221 texture_targets_.push_back(0);
Ami GONE FROM CHROMIUM 2014/05/08 21:15:09 These two lines look strange. Can you doco why th
Owen Lin 2014/05/09 10:25:03 Comments added.
222 }
195 223
196 #if defined(OS_WIN) 224 #if defined(OS_WIN)
197 NativeWindowType window = 225 window_ = CreateWindowEx(0, L"Static", L"VideoDecodeAcceleratorTest",
198 CreateWindowEx(0, L"Static", L"VideoDecodeAcceleratorTest", 226 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0,
199 WS_OVERLAPPEDWINDOW | WS_VISIBLE, top_left_x, 227 window_size.width(), widow_size.height(),
200 top_left_y, width, height, NULL, NULL, NULL, 228 NULL, NULL, NULL, NULL);
201 NULL); 229 CHECK(window_ != NULL);
202 CHECK(window != NULL);
203 windows_.push_back(window);
204 #else 230 #else
205 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_)); 231 int depth = DefaultDepth(x_display_, DefaultScreen(x_display_));
206 232
207 #if defined(GL_VARIANT_GLX) 233 #if defined(GL_VARIANT_GLX)
208 CHECK_EQ(depth, x_visual_->depth); 234 CHECK_EQ(depth, x_visual_->depth);
209 #endif 235 #endif
210 236
211 XSetWindowAttributes window_attributes; 237 XSetWindowAttributes window_attributes;
212 window_attributes.background_pixel = 238 window_attributes.background_pixel =
213 BlackPixel(x_display_, DefaultScreen(x_display_)); 239 BlackPixel(x_display_, DefaultScreen(x_display_));
214 window_attributes.override_redirect = true; 240 window_attributes.override_redirect = true;
215 241
216 NativeWindowType window = XCreateWindow( 242 x_window_ = XCreateWindow(
217 x_display_, DefaultRootWindow(x_display_), 243 x_display_, DefaultRootWindow(x_display_),
218 top_left_x, top_left_y, width, height, 244 0, 0, window_size.width(), window_size.height(), 0 /* border width */,
219 0 /* border width */, 245 depth, CopyFromParent /* class */, CopyFromParent /* visual */,
220 depth, CopyFromParent /* class */, CopyFromParent /* visual */, 246 (CWBackPixel | CWOverrideRedirect), &window_attributes);
221 (CWBackPixel | CWOverrideRedirect), &window_attributes); 247 XStoreName(x_display_, x_window_, "VideoDecodeAcceleratorTest");
222 XStoreName(x_display_, window, "VideoDecodeAcceleratorTest"); 248 XSelectInput(x_display_, x_window_, ExposureMask);
223 XSelectInput(x_display_, window, ExposureMask); 249 XMapWindow(x_display_, x_window_);
224 XMapWindow(x_display_, window);
225 x_windows_.push_back(window);
226 #endif 250 #endif
227 251
228 #if GL_VARIANT_EGL 252 #if GL_VARIANT_EGL
229 EGLSurface egl_surface = 253 gl_surface_ =
230 eglCreateWindowSurface(gl_display_, egl_config, window, NULL); 254 eglCreateWindowSurface(gl_display_, egl_config, x_window_, NULL);
231 gl_surfaces_.push_back(egl_surface); 255 CHECK_NE(gl_surface_, EGL_NO_SURFACE);
232 CHECK_NE(egl_surface, EGL_NO_SURFACE);
233 #endif 256 #endif
234 MakeCurrent(i); 257 // TODO (owenlin): Do we still this if we have only one context?
Ami GONE FROM CHROMIUM 2014/05/08 21:15:09 probably not
Owen Lin 2014/05/09 10:25:03 I just test it, we still need to make it current o
235 } 258 MakeCurrent(0);
236 259
237 // Must be done after a context is made current. 260 // Must be done after a context is made current.
238 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get()); 261 gfx::InitializeDynamicGLBindings(kGLImplementation, stub_context.get());
239 262
240 if (render_as_thumbnails_) { 263 if (render_as_thumbnails_) {
241 CHECK_EQ(window_dimensions_.size(), 1U); 264 CHECK_EQ(frame_dimensions_.size(), 1U);
242 265
243 GLint max_texture_size; 266 GLint max_texture_size;
244 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); 267 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
245 CHECK_GE(max_texture_size, params.thumbnails_page_size.width()); 268 CHECK_GE(max_texture_size, params.thumbnails_page_size.width());
246 CHECK_GE(max_texture_size, params.thumbnails_page_size.height()); 269 CHECK_GE(max_texture_size, params.thumbnails_page_size.height());
247 270
248 thumbnails_fbo_size_ = params.thumbnails_page_size; 271 thumbnails_fbo_size_ = params.thumbnails_page_size;
249 thumbnail_size_ = params.thumbnail_size; 272 thumbnail_size_ = params.thumbnail_size;
250 273
251 glGenFramebuffersEXT(1, &thumbnails_fbo_id_); 274 glGenFramebuffersEXT(1, &thumbnails_fbo_id_);
(...skipping 18 matching lines...) Expand all
270 GL_COLOR_ATTACHMENT0, 293 GL_COLOR_ATTACHMENT0,
271 GL_TEXTURE_2D, 294 GL_TEXTURE_2D,
272 thumbnails_texture_id_, 295 thumbnails_texture_id_,
273 0); 296 0);
274 297
275 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 298 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
276 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status; 299 CHECK(fb_status == GL_FRAMEBUFFER_COMPLETE) << fb_status;
277 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 300 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
278 glClear(GL_COLOR_BUFFER_BIT); 301 glClear(GL_COLOR_BUFFER_BIT);
279 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 302 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
303
304 texture_targets_[0] = GL_TEXTURE_2D;
305 texture_ids_[0] = thumbnails_texture_id_;
Ami GONE FROM CHROMIUM 2014/05/08 21:15:09 ditto unclear what these lines are about.
Owen Lin 2014/05/09 10:25:03 Document added.
280 } 306 }
281 307
282 // These vertices and texture coords. map (0,0) in the texture to the 308 // 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 309 // 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 310 // 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. 311 // 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 312 // 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. 313 // to render the FBO the screen, where we do not want this flipping.
288 static const float kVertices[] = 314 static const float kVertices[] =
289 { -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f, }; 315 { -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"); 374 GLint tex_external = glGetUniformLocation(program_, "tex_external");
349 if (tex_external != -1) { 375 if (tex_external != -1) {
350 glUniform1i(tex_external, 1); 376 glUniform1i(tex_external, 1);
351 } 377 }
352 int pos_location = glGetAttribLocation(program_, "in_pos"); 378 int pos_location = glGetAttribLocation(program_, "in_pos");
353 glEnableVertexAttribArray(pos_location); 379 glEnableVertexAttribArray(pos_location);
354 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); 380 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
355 int tc_location = glGetAttribLocation(program_, "in_tc"); 381 int tc_location = glGetAttribLocation(program_, "in_tc");
356 glEnableVertexAttribArray(tc_location); 382 glEnableVertexAttribArray(tc_location);
357 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); 383 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords);
384
385 StartRendering();
358 done->Signal(); 386 done->Signal();
359 } 387 }
360 388
361 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { 389 void RenderingHelper::UnInitialize(base::WaitableEvent* done) {
362 CHECK_EQ(base::MessageLoop::current(), message_loop_); 390 CHECK_EQ(base::MessageLoop::current(), message_loop_);
391 StopRendering();
363 if (render_as_thumbnails_) { 392 if (render_as_thumbnails_) {
364 glDeleteTextures(1, &thumbnails_texture_id_); 393 glDeleteTextures(1, &thumbnails_texture_id_);
365 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_); 394 glDeleteFramebuffersEXT(1, &thumbnails_fbo_id_);
366 } 395 }
367 #if GL_VARIANT_GLX 396 #if GL_VARIANT_GLX
368 397
369 glXDestroyContext(x_display_, gl_context_); 398 glXDestroyContext(x_display_, gl_context_);
370 #else // EGL 399 #else // EGL
371 MakeCurrent(-1); 400 MakeCurrent(-1);
372 CHECK(eglDestroyContext(gl_display_, gl_context_)); 401 CHECK(eglDestroyContext(gl_display_, gl_context_));
373 for (size_t i = 0; i < gl_surfaces_.size(); ++i) 402 CHECK(eglDestroySurface(gl_display_, gl_surface_));
374 CHECK(eglDestroySurface(gl_display_, gl_surfaces_[i]));
375 CHECK(eglTerminate(gl_display_)); 403 CHECK(eglTerminate(gl_display_));
376 #endif 404 #endif
377 gfx::ClearGLBindings(); 405 gfx::ClearGLBindings();
378 Clear(); 406 Clear();
379 done->Signal(); 407 done->Signal();
380 } 408 }
381 409
382 void RenderingHelper::CreateTexture(int window_id, 410 void RenderingHelper::CreateTexture(int window_id,
383 uint32 texture_target, 411 uint32 texture_target,
384 uint32* texture_id, 412 uint32* texture_id,
385 base::WaitableEvent* done) { 413 base::WaitableEvent* done) {
386 if (base::MessageLoop::current() != message_loop_) { 414 if (base::MessageLoop::current() != message_loop_) {
387 message_loop_->PostTask( 415 message_loop_->PostTask(
388 FROM_HERE, 416 FROM_HERE,
389 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), 417 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this),
390 window_id, texture_target, texture_id, done)); 418 window_id, texture_target, texture_id, done));
391 return; 419 return;
392 } 420 }
393 MakeCurrent(window_id);
394 glGenTextures(1, texture_id); 421 glGenTextures(1, texture_id);
395 glBindTexture(texture_target, *texture_id); 422 glBindTexture(texture_target, *texture_id);
396 int dimensions_id = window_id % frame_dimensions_.size(); 423 int dimensions_id = window_id % frame_dimensions_.size();
397 if (texture_target == GL_TEXTURE_2D) { 424 if (texture_target == GL_TEXTURE_2D) {
398 glTexImage2D(GL_TEXTURE_2D, 425 glTexImage2D(GL_TEXTURE_2D,
399 0, 426 0,
400 GL_RGBA, 427 GL_RGBA,
401 frame_dimensions_[dimensions_id].width(), 428 frame_dimensions_[dimensions_id].width(),
402 frame_dimensions_[dimensions_id].height(), 429 frame_dimensions_[dimensions_id].height(),
403 0, 430 0,
404 GL_RGBA, 431 GL_RGBA,
405 GL_UNSIGNED_BYTE, 432 GL_UNSIGNED_BYTE,
406 NULL); 433 NULL);
407 } 434 }
408 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 435 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
409 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 436 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
410 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. 437 // 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); 438 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
412 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 439 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
413 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 440 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
414 CHECK(texture_id_to_surface_index_.insert( 441 CHECK(texture_id_to_surface_index_.insert(
415 std::make_pair(*texture_id, window_id)).second); 442 std::make_pair(*texture_id, window_id)).second);
416 done->Signal(); 443 done->Signal();
417 } 444 }
418 445
446
419 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { 447 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) {
420 CHECK_EQ(base::MessageLoop::current(), message_loop_); 448 CHECK_EQ(base::MessageLoop::current(), message_loop_);
421 size_t window_id = texture_id_to_surface_index_[texture_id]; 449 if (texture_id == 0)
422 MakeCurrent(window_id); 450 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 451
428 if (render_as_thumbnails_) { 452 if (render_as_thumbnails_) {
429 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); 453 const int width = thumbnail_size_.width();
430 const int thumbnails_in_row = 454 const int height = thumbnail_size_.height();
431 thumbnails_fbo_size_.width() / thumbnail_size_.width(); 455 const int thumbnails_in_row = thumbnails_fbo_size_.width() / width;
432 const int thumbnails_in_column = 456 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; 457 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column;
435 const int col = frame_count_ % thumbnails_in_row; 458 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 459
439 glViewport(x, y, thumbnail_size_.width(), thumbnail_size_.height()); 460 gfx::Rect area(col * width, row * height, width, height);
440 glScissor(x, y, thumbnail_size_.width(), thumbnail_size_.height()); 461
441 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); 462 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0);
463 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_);
464 DrawTexture(area, texture_target, texture_id);
465 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
466 ++frame_count_;
442 } else { 467 } else {
443 glViewport(0, 0, width, height); 468 size_t window_id = texture_id_to_surface_index_[texture_id];
444 glScissor(0, 0, width, height); 469 texture_targets_[window_id] = texture_target;
445 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); 470 texture_ids_[window_id] = texture_id;
446 } 471 }
472 }
473
474 void RenderingHelper::DrawTexture(const gfx::Rect& area,
475 uint32 texture_target,
476 uint32 texture_id) {
477 glViewport(area.x(), area.y(), area.width(), area.height());
478 glScissor(area.x(), area.y(), area.width(), area.height());
447 479
448 // Unbound texture samplers default to (0, 0, 0, 1). Use this fact to switch 480 // 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. 481 // between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES as appopriate.
450 if (texture_target == GL_TEXTURE_2D) { 482 if (texture_target == GL_TEXTURE_2D) {
451 glActiveTexture(GL_TEXTURE0 + 0); 483 glActiveTexture(GL_TEXTURE0 + 0);
452 glBindTexture(GL_TEXTURE_2D, texture_id); 484 glBindTexture(GL_TEXTURE_2D, texture_id);
453 glActiveTexture(GL_TEXTURE0 + 1); 485 glActiveTexture(GL_TEXTURE0 + 1);
454 glBindTexture(texture_target, 0); 486 glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
455 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) { 487 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) {
456 glActiveTexture(GL_TEXTURE0 + 0); 488 glActiveTexture(GL_TEXTURE0 + 0);
457 glBindTexture(GL_TEXTURE_2D, 0); 489 glBindTexture(GL_TEXTURE_2D, 0);
458 glActiveTexture(GL_TEXTURE0 + 1); 490 glActiveTexture(GL_TEXTURE0 + 1);
459 glBindTexture(texture_target, texture_id); 491 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
460 } 492 }
493
461 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 494 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
462 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 495 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 } 496 }
486 497
487 void RenderingHelper::DeleteTexture(uint32 texture_id) { 498 void RenderingHelper::DeleteTexture(uint32 texture_id) {
488 glDeleteTextures(1, &texture_id); 499 glDeleteTextures(1, &texture_id);
489 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); 500 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR);
490 } 501 }
491 502
492 NativeContextType RenderingHelper::GetGLContext() { return gl_context_; } 503 NativeContextType RenderingHelper::GetGLContext() { return gl_context_; }
493 504
494 void* RenderingHelper::GetGLDisplay() { 505 void* RenderingHelper::GetGLDisplay() {
495 #if GL_VARIANT_GLX 506 #if GL_VARIANT_GLX
496 return x_display_; 507 return x_display_;
497 #else // EGL 508 #else // EGL
498 return gl_display_; 509 return gl_display_;
499 #endif 510 #endif
500 } 511 }
501 512
502 void RenderingHelper::Clear() { 513 void RenderingHelper::Clear() {
503 window_dimensions_.clear();
504 frame_dimensions_.clear(); 514 frame_dimensions_.clear();
505 texture_id_to_surface_index_.clear(); 515 texture_id_to_surface_index_.clear();
506 message_loop_ = NULL; 516 message_loop_ = NULL;
507 gl_context_ = NULL; 517 gl_context_ = NULL;
508 #if GL_VARIANT_EGL 518 #if GL_VARIANT_EGL
509 gl_display_ = EGL_NO_DISPLAY; 519 gl_display_ = EGL_NO_DISPLAY;
510 gl_surfaces_.clear(); 520 gl_surface_ = EGL_NO_SURFACE;
511 #endif 521 #endif
512 render_as_thumbnails_ = false; 522 render_as_thumbnails_ = false;
513 frame_count_ = 0; 523 frame_count_ = 0;
514 thumbnails_fbo_id_ = 0; 524 thumbnails_fbo_id_ = 0;
515 thumbnails_texture_id_ = 0; 525 thumbnails_texture_id_ = 0;
516 526
517 #if defined(OS_WIN) 527 #if defined(OS_WIN)
518 for (size_t i = 0; i < windows_.size(); ++i) { 528 if (window_) {
519 DestroyWindow(windows_[i]); 529 DestroyWindow(window_);
530 window_ = NULL;
520 } 531 }
521 windows_.clear();
522 #else 532 #else
523 // Destroy resources acquired in Initialize, in reverse-acquisition order. 533 // Destroy resources acquired in Initialize, in reverse-acquisition order.
524 for (size_t i = 0; i < x_windows_.size(); ++i) { 534 if (x_window_) {
525 CHECK(XUnmapWindow(x_display_, x_windows_[i])); 535 CHECK(XUnmapWindow(x_display_, x_window_));
526 CHECK(XDestroyWindow(x_display_, x_windows_[i])); 536 CHECK(XDestroyWindow(x_display_, x_window_));
537 x_window_ = (Window) 0;
527 } 538 }
528 // Mimic newly created object. 539 // Mimic newly created object.
529 x_display_ = NULL; 540 x_display_ = NULL;
530 x_windows_.clear();
531 #endif 541 #endif
532 } 542 }
533 543
534 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb, 544 void RenderingHelper::GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
535 bool* alpha_solid, 545 bool* alpha_solid,
536 base::WaitableEvent* done) { 546 base::WaitableEvent* done) {
537 CHECK(render_as_thumbnails_); 547 CHECK(render_as_thumbnails_);
538 548
539 const size_t num_pixels = thumbnails_fbo_size_.GetArea(); 549 const size_t num_pixels = thumbnails_fbo_size_.GetArea();
540 std::vector<unsigned char> rgba; 550 std::vector<unsigned char> rgba;
(...skipping 19 matching lines...) Expand all
560 *rgb_ptr++ = *rgba_ptr++; 570 *rgb_ptr++ = *rgba_ptr++;
561 *rgb_ptr++ = *rgba_ptr++; 571 *rgb_ptr++ = *rgba_ptr++;
562 solid = solid && (*rgba_ptr == 0xff); 572 solid = solid && (*rgba_ptr == 0xff);
563 rgba_ptr++; 573 rgba_ptr++;
564 } 574 }
565 *alpha_solid = solid; 575 *alpha_solid = solid;
566 576
567 done->Signal(); 577 done->Signal();
568 } 578 }
569 579
580 void RenderingHelper::RenderContent() {
581 if (!rendering_state_ == RENDERING_STOPPING) {
Ami GONE FROM CHROMIUM 2014/05/08 21:15:09 !foo==blah doesn't look right...
Owen Lin 2014/05/09 10:25:03 :) Thanks.
582 rendering_state_ = RENDERING_STOPPED;
583 return;
584 }
585
586 // Schedule the next rednering at begining of the function to
587 // esure the fps
Ami GONE FROM CHROMIUM 2014/05/08 21:15:09 typo: esure
Ami GONE FROM CHROMIUM 2014/05/08 21:15:09 end sentences with periods
Owen Lin 2014/05/09 10:25:03 Done.
Owen Lin 2014/05/09 10:25:03 Done.
588 message_loop_->PostDelayedTask(
589 FROM_HERE,
590 base::Bind(&RenderingHelper::RenderContent, base::Unretained(this)),
591 frame_duration_);
592
593 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1);
594 for (size_t i = 0; i < render_areas_.size(); ++i) {
595 DrawTexture(render_areas_[i], texture_targets_[i], texture_ids_[i]);
596 }
597
598 #if GL_VARIANT_GLX
599 glXSwapBuffers(x_display_, x_window_);
600 #else // EGL
601 eglSwapBuffers(gl_display_, gl_surface_);
602 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS);
603 #endif
604 }
605
606 void RenderingHelper::StartRendering() {
Ami GONE FROM CHROMIUM 2014/05/08 21:15:09 This start/stop/PostDelayedTask scheme seems a bit
Owen Lin 2014/05/09 10:25:03 Thanks. It is a nice tool.
607 if (rendering_state_ == RENDERING_STOPPED) {
608 rendering_state_ = RENDERING_START;
609 RenderContent();
610 return;
611 }
612 rendering_state_ = RENDERING_START;
613 }
614
615 void RenderingHelper::StopRendering() {
616 rendering_state_ = RENDERING_STOPPING;
617 }
570 } // namespace content 618 } // 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