Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "chrome/browser/android/vr_shell/vr_shell_renderer.h" | 5 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 #define SHADER(Src) #Src | 68 #define SHADER(Src) #Src |
| 69 #define OEIE_SHADER(Src) "#extension GL_OES_EGL_image_external : require\n" #Src | 69 #define OEIE_SHADER(Src) "#extension GL_OES_EGL_image_external : require\n" #Src |
| 70 #define VOID_OFFSET(x) reinterpret_cast<void*>(x) | 70 #define VOID_OFFSET(x) reinterpret_cast<void*>(x) |
| 71 | 71 |
| 72 const char* GetShaderSource(vr_shell::ShaderID shader) { | 72 const char* GetShaderSource(vr_shell::ShaderID shader) { |
| 73 switch (shader) { | 73 switch (shader) { |
| 74 case vr_shell::ShaderID::TEXTURE_QUAD_VERTEX_SHADER: | 74 case vr_shell::ShaderID::TEXTURE_QUAD_VERTEX_SHADER: |
| 75 case vr_shell::ShaderID::RETICLE_VERTEX_SHADER: | 75 case vr_shell::ShaderID::RETICLE_VERTEX_SHADER: |
| 76 case vr_shell::ShaderID::LASER_VERTEX_SHADER: | 76 case vr_shell::ShaderID::LASER_VERTEX_SHADER: |
| 77 case vr_shell::ShaderID::CONTROLLER_VERTEX_SHADER: | 77 case vr_shell::ShaderID::CONTROLLER_VERTEX_SHADER: |
| 78 case vr_shell::ShaderID::SKIA_QUAD_VERTEX_SHADER: | |
| 78 return SHADER( | 79 return SHADER( |
| 79 /* clang-format off */ | 80 /* clang-format off */ |
| 80 uniform mat4 u_ModelViewProjMatrix; | 81 uniform mat4 u_ModelViewProjMatrix; |
| 81 attribute vec4 a_Position; | 82 attribute vec4 a_Position; |
| 82 attribute vec2 a_TexCoordinate; | 83 attribute vec2 a_TexCoordinate; |
| 83 varying vec2 v_TexCoordinate; | 84 varying vec2 v_TexCoordinate; |
| 84 | 85 |
| 85 void main() { | 86 void main() { |
| 86 v_TexCoordinate = a_TexCoordinate; | 87 v_TexCoordinate = a_TexCoordinate; |
| 87 gl_Position = u_ModelViewProjMatrix * a_Position; | 88 gl_Position = u_ModelViewProjMatrix * a_Position; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 112 uniform mediump float opacity; | 113 uniform mediump float opacity; |
| 113 | 114 |
| 114 void main() { | 115 void main() { |
| 115 vec2 scaledTex = | 116 vec2 scaledTex = |
| 116 vec2(u_CopyRect[0] + v_TexCoordinate.x * u_CopyRect[2], | 117 vec2(u_CopyRect[0] + v_TexCoordinate.x * u_CopyRect[2], |
| 117 u_CopyRect[1] + v_TexCoordinate.y * u_CopyRect[3]); | 118 u_CopyRect[1] + v_TexCoordinate.y * u_CopyRect[3]); |
| 118 lowp vec4 color = texture2D(u_Texture, scaledTex); | 119 lowp vec4 color = texture2D(u_Texture, scaledTex); |
| 119 gl_FragColor = vec4(color.xyz, color.w * opacity); | 120 gl_FragColor = vec4(color.xyz, color.w * opacity); |
| 120 } | 121 } |
| 121 /* clang-format on */); | 122 /* clang-format on */); |
| 123 case vr_shell::ShaderID::SKIA_QUAD_FRAGMENT_SHADER: | |
| 124 return OEIE_SHADER( | |
|
acondor_
2017/04/21 15:04:23
No need for OEIE
mthiesse
2017/04/21 17:17:30
Good catch
| |
| 125 /* clang-format off */ | |
| 126 precision highp float; | |
| 127 uniform sampler2D u_Texture; | |
| 128 uniform vec4 u_CopyRect; // rectangle | |
| 129 varying vec2 v_TexCoordinate; | |
| 130 uniform lowp vec4 color; | |
| 131 uniform mediump float opacity; | |
| 132 | |
| 133 void main() { | |
| 134 vec2 scaledTex = | |
| 135 vec2(u_CopyRect[0] + v_TexCoordinate.x * u_CopyRect[2], | |
| 136 u_CopyRect[1] + v_TexCoordinate.y * u_CopyRect[3]); | |
| 137 lowp vec4 color = texture2D(u_Texture, scaledTex); | |
| 138 gl_FragColor = vec4(color.xyz, color.w * opacity); | |
| 139 } | |
| 140 /* clang-format on */); | |
| 122 case vr_shell::ShaderID::WEBVR_VERTEX_SHADER: | 141 case vr_shell::ShaderID::WEBVR_VERTEX_SHADER: |
| 123 return SHADER( | 142 return SHADER( |
| 124 /* clang-format off */ | 143 /* clang-format off */ |
| 125 attribute vec3 a_Position; | 144 attribute vec3 a_Position; |
| 126 attribute vec2 a_TexCoordinate; | 145 attribute vec2 a_TexCoordinate; |
| 127 varying vec2 v_TexCoordinate; | 146 varying vec2 v_TexCoordinate; |
| 128 | 147 |
| 129 void main() { | 148 void main() { |
| 130 v_TexCoordinate = a_TexCoordinate; | 149 v_TexCoordinate = a_TexCoordinate; |
| 131 gl_Position = vec4(a_Position * 2.0, 1.0); | 150 gl_Position = vec4(a_Position * 2.0, 1.0); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 303 : BaseQuadRenderer(TEXTURE_QUAD_VERTEX_SHADER, | 322 : BaseQuadRenderer(TEXTURE_QUAD_VERTEX_SHADER, |
| 304 TEXTURE_QUAD_FRAGMENT_SHADER) { | 323 TEXTURE_QUAD_FRAGMENT_SHADER) { |
| 305 model_view_proj_matrix_handle_ = | 324 model_view_proj_matrix_handle_ = |
| 306 glGetUniformLocation(program_handle_, "u_ModelViewProjMatrix"); | 325 glGetUniformLocation(program_handle_, "u_ModelViewProjMatrix"); |
| 307 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); | 326 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); |
| 308 copy_rect_uniform_handle_ = | 327 copy_rect_uniform_handle_ = |
| 309 glGetUniformLocation(program_handle_, "u_CopyRect"); | 328 glGetUniformLocation(program_handle_, "u_CopyRect"); |
| 310 opacity_handle_ = glGetUniformLocation(program_handle_, "opacity"); | 329 opacity_handle_ = glGetUniformLocation(program_handle_, "opacity"); |
| 311 } | 330 } |
| 312 | 331 |
| 313 void TexturedQuadRenderer::AddQuad(int texture_data_handle, | 332 void TexturedQuadRenderer::Draw(int texture_data_handle, |
| 314 const vr::Mat4f& view_proj_matrix, | 333 const vr::Mat4f& view_proj_matrix, |
| 315 const gfx::RectF& copy_rect, | 334 const gfx::RectF& copy_rect, |
| 316 float opacity) { | 335 float opacity) { |
| 317 TexturedQuad quad; | 336 PrepareToDraw(model_view_proj_matrix_handle_, view_proj_matrix); |
| 337 | |
| 338 // Link texture data with texture unit. | |
| 339 glActiveTexture(GL_TEXTURE0); | |
| 340 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_data_handle); | |
| 341 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 342 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 343 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 344 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
| 345 | |
| 346 glUniform1i(tex_uniform_handle_, 0); | |
| 347 glUniform4fv(copy_rect_uniform_handle_, 1, | |
| 348 reinterpret_cast<const float*>(©_rect)); | |
| 349 glUniform1f(opacity_handle_, opacity); | |
| 350 | |
| 351 glDrawArrays(GL_TRIANGLES, 0, kVerticesNumber); | |
| 352 | |
| 353 glDisableVertexAttribArray(position_handle_); | |
| 354 glDisableVertexAttribArray(tex_coord_handle_); | |
| 355 } | |
| 356 | |
| 357 TexturedQuadRenderer::~TexturedQuadRenderer() = default; | |
| 358 | |
| 359 SkiaQuadRenderer::SkiaQuadRenderer() | |
| 360 : BaseQuadRenderer(SKIA_QUAD_VERTEX_SHADER, SKIA_QUAD_FRAGMENT_SHADER) { | |
| 361 model_view_proj_matrix_handle_ = | |
| 362 glGetUniformLocation(program_handle_, "u_ModelViewProjMatrix"); | |
| 363 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); | |
| 364 copy_rect_uniform_handle_ = | |
| 365 glGetUniformLocation(program_handle_, "u_CopyRect"); | |
| 366 opacity_handle_ = glGetUniformLocation(program_handle_, "opacity"); | |
| 367 } | |
| 368 | |
| 369 void SkiaQuadRenderer::AddQuad(int texture_data_handle, | |
| 370 const vr::Mat4f& view_proj_matrix, | |
| 371 const gfx::RectF& copy_rect, | |
| 372 float opacity) { | |
| 373 SkiaQuad quad; | |
| 318 quad.texture_data_handle = texture_data_handle; | 374 quad.texture_data_handle = texture_data_handle; |
| 319 quad.view_proj_matrix = view_proj_matrix; | 375 quad.view_proj_matrix = view_proj_matrix; |
| 320 quad.copy_rect = {copy_rect.x(), copy_rect.y(), copy_rect.width(), | 376 quad.copy_rect = {copy_rect.x(), copy_rect.y(), copy_rect.width(), |
| 321 copy_rect.height()}; | 377 copy_rect.height()}; |
| 322 quad.opacity = opacity; | 378 quad.opacity = opacity; |
| 323 quad_queue_.push(quad); | 379 quad_queue_.push(quad); |
| 324 } | 380 } |
| 325 | 381 |
| 326 void TexturedQuadRenderer::Flush() { | 382 void SkiaQuadRenderer::Flush() { |
| 327 if (quad_queue_.empty()) | 383 if (quad_queue_.empty()) |
| 328 return; | 384 return; |
| 329 | 385 |
| 330 int last_texture = 0; | 386 int last_texture = 0; |
| 331 float last_opacity = -1.0f; | 387 float last_opacity = -1.0f; |
| 332 | 388 |
| 333 // Set up GL state that doesn't change between draw calls. | 389 // Set up GL state that doesn't change between draw calls. |
| 334 glUseProgram(program_handle_); | 390 glUseProgram(program_handle_); |
| 335 | 391 |
| 336 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | 392 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 351 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 407 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
| 352 | 408 |
| 353 // Link texture data with texture unit. | 409 // Link texture data with texture unit. |
| 354 glActiveTexture(GL_TEXTURE0); | 410 glActiveTexture(GL_TEXTURE0); |
| 355 glUniform1i(tex_uniform_handle_, 0); | 411 glUniform1i(tex_uniform_handle_, 0); |
| 356 | 412 |
| 357 // TODO(bajones): This should eventually be changed to use instancing so that | 413 // TODO(bajones): This should eventually be changed to use instancing so that |
| 358 // the entire queue can be processed in one draw call. For now this still | 414 // the entire queue can be processed in one draw call. For now this still |
| 359 // significantly reduces the amount of state changes made per draw. | 415 // significantly reduces the amount of state changes made per draw. |
| 360 while (!quad_queue_.empty()) { | 416 while (!quad_queue_.empty()) { |
| 361 const TexturedQuad& quad = quad_queue_.front(); | 417 const SkiaQuad& quad = quad_queue_.front(); |
| 362 | 418 |
| 363 // Only change texture ID or opacity when they differ between quads. | 419 // Only change texture ID or opacity when they differ between quads. |
| 364 if (last_texture != quad.texture_data_handle) { | 420 if (last_texture != quad.texture_data_handle) { |
| 365 last_texture = quad.texture_data_handle; | 421 last_texture = quad.texture_data_handle; |
| 366 glBindTexture(GL_TEXTURE_EXTERNAL_OES, last_texture); | 422 glBindTexture(GL_TEXTURE_2D, last_texture); |
| 367 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, | 423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
|
cjgrant
2017/04/21 14:30:13
I recall Aldo saying we didn't need these values s
acondor_
2017/04/21 15:04:23
We don't :)
mthiesse
2017/04/21 17:17:30
Done.
| |
| 368 GL_CLAMP_TO_EDGE); | 424 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 369 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, | 425 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 370 GL_CLAMP_TO_EDGE); | 426 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 371 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, | |
| 372 GL_LINEAR); | |
| 373 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, | |
| 374 GL_NEAREST); | |
| 375 } | 427 } |
| 376 | 428 |
| 377 if (last_opacity != quad.opacity) { | 429 if (last_opacity != quad.opacity) { |
| 378 last_opacity = quad.opacity; | 430 last_opacity = quad.opacity; |
| 379 glUniform1f(opacity_handle_, last_opacity); | 431 glUniform1f(opacity_handle_, last_opacity); |
| 380 } | 432 } |
| 381 | 433 |
| 382 // Pass in model view project matrix. | 434 // Pass in model view project matrix. |
| 383 glUniformMatrix4fv(model_view_proj_matrix_handle_, 1, false, | 435 glUniformMatrix4fv(model_view_proj_matrix_handle_, 1, false, |
| 384 MatrixToGLArray(quad.view_proj_matrix).data()); | 436 MatrixToGLArray(quad.view_proj_matrix).data()); |
| 385 | 437 |
| 386 // Pass in the copy rect. | 438 // Pass in the copy rect. |
| 387 glUniform4fv(copy_rect_uniform_handle_, 1, | 439 glUniform4fv(copy_rect_uniform_handle_, 1, |
| 388 reinterpret_cast<const float*>(&quad.copy_rect)); | 440 reinterpret_cast<const float*>(&quad.copy_rect)); |
| 389 | 441 |
| 390 glDrawArrays(GL_TRIANGLES, 0, kVerticesNumber); | 442 glDrawArrays(GL_TRIANGLES, 0, kVerticesNumber); |
| 391 | 443 |
| 392 quad_queue_.pop(); | 444 quad_queue_.pop(); |
| 393 } | 445 } |
| 394 | 446 |
| 395 glDisableVertexAttribArray(position_handle_); | 447 glDisableVertexAttribArray(position_handle_); |
| 396 glDisableVertexAttribArray(tex_coord_handle_); | 448 glDisableVertexAttribArray(tex_coord_handle_); |
| 397 } | 449 } |
| 398 | 450 |
| 399 TexturedQuadRenderer::~TexturedQuadRenderer() = default; | 451 SkiaQuadRenderer::~SkiaQuadRenderer() = default; |
| 400 | 452 |
| 401 WebVrRenderer::WebVrRenderer() | 453 WebVrRenderer::WebVrRenderer() |
| 402 : BaseQuadRenderer(WEBVR_VERTEX_SHADER, WEBVR_FRAGMENT_SHADER) { | 454 : BaseQuadRenderer(WEBVR_VERTEX_SHADER, WEBVR_FRAGMENT_SHADER) { |
| 403 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); | 455 tex_uniform_handle_ = glGetUniformLocation(program_handle_, "u_Texture"); |
| 404 } | 456 } |
| 405 | 457 |
| 406 // Draw the stereo WebVR frame | 458 // Draw the stereo WebVR frame |
| 407 void WebVrRenderer::Draw(int texture_handle) { | 459 void WebVrRenderer::Draw(int texture_handle) { |
| 408 glUseProgram(program_handle_); | 460 glUseProgram(program_handle_); |
| 409 | 461 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 723 size_t vertex_buffer_size = sizeof(Line3d) * linesNumber; | 775 size_t vertex_buffer_size = sizeof(Line3d) * linesNumber; |
| 724 | 776 |
| 725 glGenBuffersARB(1, &vertex_buffer_); | 777 glGenBuffersARB(1, &vertex_buffer_); |
| 726 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | 778 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); |
| 727 glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, grid_lines_.data(), | 779 glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, grid_lines_.data(), |
| 728 GL_STATIC_DRAW); | 780 GL_STATIC_DRAW); |
| 729 } | 781 } |
| 730 | 782 |
| 731 VrShellRenderer::VrShellRenderer() | 783 VrShellRenderer::VrShellRenderer() |
| 732 : textured_quad_renderer_(base::MakeUnique<TexturedQuadRenderer>()), | 784 : textured_quad_renderer_(base::MakeUnique<TexturedQuadRenderer>()), |
| 785 skia_quad_renderer_(base::MakeUnique<SkiaQuadRenderer>()), | |
| 733 webvr_renderer_(base::MakeUnique<WebVrRenderer>()), | 786 webvr_renderer_(base::MakeUnique<WebVrRenderer>()), |
| 734 reticle_renderer_(base::MakeUnique<ReticleRenderer>()), | 787 reticle_renderer_(base::MakeUnique<ReticleRenderer>()), |
| 735 laser_renderer_(base::MakeUnique<LaserRenderer>()), | 788 laser_renderer_(base::MakeUnique<LaserRenderer>()), |
| 736 controller_renderer_(base::MakeUnique<ControllerRenderer>()), | 789 controller_renderer_(base::MakeUnique<ControllerRenderer>()), |
| 737 gradient_quad_renderer_(base::MakeUnique<GradientQuadRenderer>()), | 790 gradient_quad_renderer_(base::MakeUnique<GradientQuadRenderer>()), |
| 738 gradient_grid_renderer_(base::MakeUnique<GradientGridRenderer>()) { | 791 gradient_grid_renderer_(base::MakeUnique<GradientGridRenderer>()) { |
| 739 BaseQuadRenderer::SetVertexBuffer(); | 792 BaseQuadRenderer::SetVertexBuffer(); |
| 740 } | 793 } |
| 741 | 794 |
| 742 VrShellRenderer::~VrShellRenderer() = default; | 795 VrShellRenderer::~VrShellRenderer() = default; |
| 743 | 796 |
| 797 TexturedQuadRenderer* VrShellRenderer::GetTexturedQuadRenderer() { | |
| 798 skia_quad_renderer_->Flush(); | |
|
cjgrant
2017/04/21 14:30:13
I'm not sure this approach is much better than bef
mthiesse
2017/04/21 15:05:12
Yeah, right now we don't hold onto pointers, and w
cjgrant
2017/04/21 15:19:33
Agreed.
| |
| 799 return textured_quad_renderer_.get(); | |
| 800 } | |
| 801 | |
| 802 SkiaQuadRenderer* VrShellRenderer::GetSkiaQuadRenderer() { | |
| 803 return skia_quad_renderer_.get(); | |
| 804 } | |
| 805 | |
| 806 WebVrRenderer* VrShellRenderer::GetWebVrRenderer() { | |
| 807 skia_quad_renderer_->Flush(); | |
| 808 return webvr_renderer_.get(); | |
| 809 } | |
| 810 | |
| 811 ReticleRenderer* VrShellRenderer::GetReticleRenderer() { | |
| 812 skia_quad_renderer_->Flush(); | |
| 813 return reticle_renderer_.get(); | |
| 814 } | |
| 815 | |
| 816 LaserRenderer* VrShellRenderer::GetLaserRenderer() { | |
| 817 skia_quad_renderer_->Flush(); | |
| 818 return laser_renderer_.get(); | |
| 819 } | |
| 820 | |
| 821 ControllerRenderer* VrShellRenderer::GetControllerRenderer() { | |
| 822 skia_quad_renderer_->Flush(); | |
| 823 return controller_renderer_.get(); | |
| 824 } | |
| 825 | |
| 826 GradientQuadRenderer* VrShellRenderer::GetGradientQuadRenderer() { | |
| 827 skia_quad_renderer_->Flush(); | |
| 828 return gradient_quad_renderer_.get(); | |
| 829 } | |
| 830 | |
| 831 GradientGridRenderer* VrShellRenderer::GetGradientGridRenderer() { | |
| 832 skia_quad_renderer_->Flush(); | |
| 833 return gradient_grid_renderer_.get(); | |
| 834 } | |
| 835 | |
| 744 } // namespace vr_shell | 836 } // namespace vr_shell |
| OLD | NEW |