Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/gpu/media/rendering_helper.h" | 5 #include "content/common/gpu/media/rendering_helper.h" |
| 6 | 6 |
| 7 #include "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" |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 uniform bool tex_flip; | 323 uniform bool tex_flip; |
| 324 void main() { | 324 void main() { |
| 325 if (tex_flip) | 325 if (tex_flip) |
| 326 interp_tc = vec2(in_tc.x, 1.0 - in_tc.y); | 326 interp_tc = vec2(in_tc.x, 1.0 - in_tc.y); |
| 327 else | 327 else |
| 328 interp_tc = in_tc; | 328 interp_tc = in_tc; |
| 329 gl_Position = in_pos; | 329 gl_Position = in_pos; |
| 330 }); | 330 }); |
| 331 | 331 |
| 332 #if GL_VARIANT_EGL | 332 #if GL_VARIANT_EGL |
| 333 static const char kFragmentShader[] = STRINGIZE( | 333 static const char kFragmentShader[] = |
| 334 precision mediump float; | 334 "#extension GL_OES_EGL_image_external : enable\n" |
|
Ami GONE FROM CHROMIUM
2013/11/12 19:36:44
Sure would be nice if you could use STRINGIZE
Ami GONE FROM CHROMIUM
2013/11/12 19:36:44
This works on windows/angle?
sheu
2013/11/12 19:41:45
Can't, since we have an "#extension" preprocessor
sheu
2013/11/12 19:41:45
It should. To the trybot!
| |
| 335 varying vec2 interp_tc; | 335 "precision mediump float;\n" |
| 336 uniform sampler2D tex; | 336 "varying vec2 interp_tc;\n" |
| 337 void main() { | 337 "uniform sampler2D tex;\n" |
| 338 gl_FragColor = texture2D(tex, interp_tc); | 338 "#ifdef GL_OES_EGL_image_external\n" |
| 339 }); | 339 "uniform samplerExternalOES tex_external;\n" |
| 340 "#endif\n" | |
| 341 "void main() {\n" | |
| 342 " vec4 color = texture2D(tex, interp_tc);\n" | |
| 343 "#ifdef GL_OES_EGL_image_external\n" | |
| 344 " color += texture2D(tex_external, interp_tc);\n" | |
| 345 "#endif\n" | |
| 346 " gl_FragColor = color;\n" | |
| 347 "}\n"; | |
| 340 #else | 348 #else |
| 341 static const char kFragmentShader[] = STRINGIZE( | 349 static const char kFragmentShader[] = STRINGIZE( |
| 342 varying vec2 interp_tc; | 350 varying vec2 interp_tc; |
| 343 uniform sampler2D tex; | 351 uniform sampler2D tex; |
| 344 void main() { | 352 void main() { |
| 345 gl_FragColor = texture2D(tex, interp_tc); | 353 gl_FragColor = texture2D(tex, interp_tc); |
| 346 }); | 354 }); |
| 347 #endif | 355 #endif |
| 348 program_ = glCreateProgram(); | 356 program_ = glCreateProgram(); |
| 349 CreateShader( | 357 CreateShader( |
| 350 program_, GL_VERTEX_SHADER, kVertexShader, arraysize(kVertexShader)); | 358 program_, GL_VERTEX_SHADER, kVertexShader, arraysize(kVertexShader)); |
| 351 CreateShader(program_, | 359 CreateShader(program_, |
| 352 GL_FRAGMENT_SHADER, | 360 GL_FRAGMENT_SHADER, |
| 353 kFragmentShader, | 361 kFragmentShader, |
| 354 arraysize(kFragmentShader)); | 362 arraysize(kFragmentShader)); |
| 355 glLinkProgram(program_); | 363 glLinkProgram(program_); |
| 356 int result = GL_FALSE; | 364 int result = GL_FALSE; |
| 357 glGetProgramiv(program_, GL_LINK_STATUS, &result); | 365 glGetProgramiv(program_, GL_LINK_STATUS, &result); |
| 358 if (!result) { | 366 if (!result) { |
| 359 char log[4096]; | 367 char log[4096]; |
| 360 glGetShaderInfoLog(program_, arraysize(log), NULL, log); | 368 glGetShaderInfoLog(program_, arraysize(log), NULL, log); |
| 361 LOG(FATAL) << log; | 369 LOG(FATAL) << log; |
| 362 } | 370 } |
| 363 glUseProgram(program_); | 371 glUseProgram(program_); |
| 364 glDeleteProgram(program_); | 372 glDeleteProgram(program_); |
| 365 | 373 |
| 366 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); | 374 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); |
| 367 glUniform1i(glGetUniformLocation(program_, "tex"), 0); | 375 glUniform1i(glGetUniformLocation(program_, "tex"), 0); |
| 376 GLint tex_external = glGetUniformLocation(program_, "tex_external"); | |
| 377 if (tex_external != -1) { | |
| 378 glUniform1i(tex_external, 1); | |
| 379 } | |
| 368 int pos_location = glGetAttribLocation(program_, "in_pos"); | 380 int pos_location = glGetAttribLocation(program_, "in_pos"); |
| 369 glEnableVertexAttribArray(pos_location); | 381 glEnableVertexAttribArray(pos_location); |
| 370 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); | 382 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, kVertices); |
| 371 int tc_location = glGetAttribLocation(program_, "in_tc"); | 383 int tc_location = glGetAttribLocation(program_, "in_tc"); |
| 372 glEnableVertexAttribArray(tc_location); | 384 glEnableVertexAttribArray(tc_location); |
| 373 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); | 385 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0, kTextureCoords); |
| 374 done->Signal(); | 386 done->Signal(); |
| 375 } | 387 } |
| 376 | 388 |
| 377 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { | 389 void RenderingHelper::UnInitialize(base::WaitableEvent* done) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 399 uint32 texture_target, | 411 uint32 texture_target, |
| 400 uint32* texture_id, | 412 uint32* texture_id, |
| 401 base::WaitableEvent* done) { | 413 base::WaitableEvent* done) { |
| 402 if (base::MessageLoop::current() != message_loop_) { | 414 if (base::MessageLoop::current() != message_loop_) { |
| 403 message_loop_->PostTask( | 415 message_loop_->PostTask( |
| 404 FROM_HERE, | 416 FROM_HERE, |
| 405 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), | 417 base::Bind(&RenderingHelper::CreateTexture, base::Unretained(this), |
| 406 window_id, texture_target, texture_id, done)); | 418 window_id, texture_target, texture_id, done)); |
| 407 return; | 419 return; |
| 408 } | 420 } |
| 409 CHECK_EQ(static_cast<uint32>(GL_TEXTURE_2D), texture_target); | |
| 410 MakeCurrent(window_id); | 421 MakeCurrent(window_id); |
| 411 glGenTextures(1, texture_id); | 422 glGenTextures(1, texture_id); |
| 412 glBindTexture(GL_TEXTURE_2D, *texture_id); | 423 glBindTexture(texture_target, *texture_id); |
| 413 int dimensions_id = window_id % frame_dimensions_.size(); | 424 int dimensions_id = window_id % frame_dimensions_.size(); |
| 414 glTexImage2D(GL_TEXTURE_2D, | 425 if (texture_target == GL_TEXTURE_2D) { |
| 415 0, | 426 glTexImage2D(GL_TEXTURE_2D, |
| 416 GL_RGBA, | 427 0, |
| 417 frame_dimensions_[dimensions_id].width(), | 428 GL_RGBA, |
| 418 frame_dimensions_[dimensions_id].height(), | 429 frame_dimensions_[dimensions_id].width(), |
| 419 0, | 430 frame_dimensions_[dimensions_id].height(), |
| 420 GL_RGBA, | 431 0, |
| 421 GL_UNSIGNED_BYTE, | 432 GL_RGBA, |
| 422 NULL); | 433 GL_UNSIGNED_BYTE, |
| 423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 434 NULL); |
| 424 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 435 } |
| 436 glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 437 glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 425 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. | 438 // OpenGLES2.0.25 section 3.8.2 requires CLAMP_TO_EDGE for NPOT textures. |
| 426 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 439 glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 427 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 440 glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 428 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 441 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
| 429 CHECK(texture_id_to_surface_index_.insert( | 442 CHECK(texture_id_to_surface_index_.insert( |
| 430 std::make_pair(*texture_id, window_id)).second); | 443 std::make_pair(*texture_id, window_id)).second); |
| 431 done->Signal(); | 444 done->Signal(); |
| 432 } | 445 } |
| 433 | 446 |
| 434 void RenderingHelper::RenderTexture(uint32 texture_id) { | 447 void RenderingHelper::RenderTexture(uint32 texture_target, uint32 texture_id) { |
| 435 CHECK_EQ(base::MessageLoop::current(), message_loop_); | 448 CHECK_EQ(base::MessageLoop::current(), message_loop_); |
| 436 size_t window_id = texture_id_to_surface_index_[texture_id]; | 449 size_t window_id = texture_id_to_surface_index_[texture_id]; |
| 437 MakeCurrent(window_id); | 450 MakeCurrent(window_id); |
| 438 | 451 |
| 439 int dimensions_id = window_id % window_dimensions_.size(); | 452 int dimensions_id = window_id % window_dimensions_.size(); |
| 440 int width = window_dimensions_[dimensions_id].width(); | 453 int width = window_dimensions_[dimensions_id].width(); |
| 441 int height = window_dimensions_[dimensions_id].height(); | 454 int height = window_dimensions_[dimensions_id].height(); |
| 442 | 455 |
| 443 if (render_as_thumbnails_) { | 456 if (render_as_thumbnails_) { |
| 444 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); | 457 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); |
| 445 const int thumbnails_in_row = | 458 const int thumbnails_in_row = |
| 446 thumbnails_fbo_size_.width() / thumbnail_size_.width(); | 459 thumbnails_fbo_size_.width() / thumbnail_size_.width(); |
| 447 const int thumbnails_in_column = | 460 const int thumbnails_in_column = |
| 448 thumbnails_fbo_size_.height() / thumbnail_size_.height(); | 461 thumbnails_fbo_size_.height() / thumbnail_size_.height(); |
| 449 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column; | 462 const int row = (frame_count_ / thumbnails_in_row) % thumbnails_in_column; |
| 450 const int col = frame_count_ % thumbnails_in_row; | 463 const int col = frame_count_ % thumbnails_in_row; |
| 451 const int x = col * thumbnail_size_.width(); | 464 const int x = col * thumbnail_size_.width(); |
| 452 const int y = row * thumbnail_size_.height(); | 465 const int y = row * thumbnail_size_.height(); |
| 453 | 466 |
| 454 glViewport(x, y, thumbnail_size_.width(), thumbnail_size_.height()); | 467 glViewport(x, y, thumbnail_size_.width(), thumbnail_size_.height()); |
| 455 glScissor(x, y, thumbnail_size_.width(), thumbnail_size_.height()); | 468 glScissor(x, y, thumbnail_size_.width(), thumbnail_size_.height()); |
| 456 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); | 469 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 0); |
| 457 } else { | 470 } else { |
| 458 glViewport(0, 0, width, height); | 471 glViewport(0, 0, width, height); |
| 459 glScissor(0, 0, width, height); | 472 glScissor(0, 0, width, height); |
| 460 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); | 473 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); |
| 461 } | 474 } |
| 462 | 475 |
| 463 glActiveTexture(GL_TEXTURE0); | 476 // Unbound texture samplers default to (0, 0, 0, 1). Use this fact to switch |
| 464 glBindTexture(GL_TEXTURE_2D, texture_id); | 477 // between GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES as appopriate. |
| 478 if (texture_target == GL_TEXTURE_2D) { | |
| 479 glActiveTexture(GL_TEXTURE0 + 0); | |
| 480 glBindTexture(GL_TEXTURE_2D, texture_id); | |
| 481 glActiveTexture(GL_TEXTURE0 + 1); | |
| 482 glBindTexture(texture_target, 0); | |
| 483 } else if (texture_target == GL_TEXTURE_EXTERNAL_OES) { | |
| 484 glActiveTexture(GL_TEXTURE0 + 0); | |
| 485 glBindTexture(GL_TEXTURE_2D, 0); | |
| 486 glActiveTexture(GL_TEXTURE0 + 1); | |
| 487 glBindTexture(texture_target, texture_id); | |
| 488 } | |
| 465 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 489 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 466 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); | 490 CHECK_EQ(static_cast<int>(glGetError()), GL_NO_ERROR); |
| 467 | 491 |
| 468 ++frame_count_; | 492 ++frame_count_; |
| 469 | 493 |
| 470 if (render_as_thumbnails_) { | 494 if (render_as_thumbnails_) { |
| 471 // Copy from FBO to screen | 495 // Copy from FBO to screen |
| 472 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); | 496 glUniform1i(glGetUniformLocation(program_, "tex_flip"), 1); |
| 473 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | 497 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); |
| 474 glViewport(0, 0, width, height); | 498 glViewport(0, 0, width, height); |
| 475 glScissor(0, 0, width, height); | 499 glScissor(0, 0, width, height); |
| 500 glActiveTexture(GL_TEXTURE0 + 0); | |
| 476 glBindTexture(GL_TEXTURE_2D, thumbnails_texture_id_); | 501 glBindTexture(GL_TEXTURE_2D, thumbnails_texture_id_); |
| 502 glActiveTexture(GL_TEXTURE0 + 1); | |
| 503 glBindTexture(texture_target, 0); | |
| 477 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 504 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 478 } | 505 } |
| 479 | 506 |
| 480 #if GL_VARIANT_GLX | 507 #if GL_VARIANT_GLX |
| 481 glXSwapBuffers(x_display_, x_windows_[window_id]); | 508 glXSwapBuffers(x_display_, x_windows_[window_id]); |
| 482 #else // EGL | 509 #else // EGL |
| 483 eglSwapBuffers(gl_display_, gl_surfaces_[window_id]); | 510 eglSwapBuffers(gl_display_, gl_surfaces_[window_id]); |
| 484 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); | 511 CHECK_EQ(static_cast<int>(eglGetError()), EGL_SUCCESS); |
| 485 #endif | 512 #endif |
| 486 } | 513 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); | 572 glBindFramebufferEXT(GL_FRAMEBUFFER, thumbnails_fbo_id_); |
| 546 glPixelStorei(GL_PACK_ALIGNMENT, 1); | 573 glPixelStorei(GL_PACK_ALIGNMENT, 1); |
| 547 // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support. | 574 // We can only count on GL_RGBA/GL_UNSIGNED_BYTE support. |
| 548 glReadPixels(0, | 575 glReadPixels(0, |
| 549 0, | 576 0, |
| 550 thumbnails_fbo_size_.width(), | 577 thumbnails_fbo_size_.width(), |
| 551 thumbnails_fbo_size_.height(), | 578 thumbnails_fbo_size_.height(), |
| 552 GL_RGBA, | 579 GL_RGBA, |
| 553 GL_UNSIGNED_BYTE, | 580 GL_UNSIGNED_BYTE, |
| 554 &rgba[0]); | 581 &rgba[0]); |
| 582 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | |
| 555 rgb->resize(num_pixels * 3); | 583 rgb->resize(num_pixels * 3); |
| 556 // Drop the alpha channel, but check as we go that it is all 0xff. | 584 // Drop the alpha channel, but check as we go that it is all 0xff. |
| 557 bool solid = true; | 585 bool solid = true; |
| 558 unsigned char* rgb_ptr = &((*rgb)[0]); | 586 unsigned char* rgb_ptr = &((*rgb)[0]); |
| 559 unsigned char* rgba_ptr = &rgba[0]; | 587 unsigned char* rgba_ptr = &rgba[0]; |
| 560 for (size_t i = 0; i < num_pixels; ++i) { | 588 for (size_t i = 0; i < num_pixels; ++i) { |
| 561 *rgb_ptr++ = *rgba_ptr++; | 589 *rgb_ptr++ = *rgba_ptr++; |
| 562 *rgb_ptr++ = *rgba_ptr++; | 590 *rgb_ptr++ = *rgba_ptr++; |
| 563 *rgb_ptr++ = *rgba_ptr++; | 591 *rgb_ptr++ = *rgba_ptr++; |
| 564 solid = solid && (*rgba_ptr == 0xff); | 592 solid = solid && (*rgba_ptr == 0xff); |
| 565 rgba_ptr++; | 593 rgba_ptr++; |
| 566 } | 594 } |
| 567 *alpha_solid = solid; | 595 *alpha_solid = solid; |
| 568 | 596 |
| 569 done->Signal(); | 597 done->Signal(); |
| 570 } | 598 } |
| 571 | 599 |
| 572 } // namespace content | 600 } // namespace content |
| OLD | NEW |