OLD | NEW |
1 // Copyright 2010 The Chromium Authors. All rights reserved. | 1 // Copyright 2010 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 "cc/gl_renderer.h" | 5 #include "cc/gl_renderer.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string_split.h" | 9 #include "base/string_split.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 int matrixLocation; | 962 int matrixLocation; |
963 int alphaLocation; | 963 int alphaLocation; |
964 }; | 964 }; |
965 | 965 |
966 struct TexTransformTextureProgramBinding : TextureProgramBinding { | 966 struct TexTransformTextureProgramBinding : TextureProgramBinding { |
967 template<class Program> void set( | 967 template<class Program> void set( |
968 Program* program, WebKit::WebGraphicsContext3D* context) | 968 Program* program, WebKit::WebGraphicsContext3D* context) |
969 { | 969 { |
970 TextureProgramBinding::set(program, context); | 970 TextureProgramBinding::set(program, context); |
971 texTransformLocation = program->vertexShader().texTransformLocation(); | 971 texTransformLocation = program->vertexShader().texTransformLocation(); |
| 972 vertexOpacityLocation = program->vertexShader().vertexOpacityLocation(); |
972 } | 973 } |
973 int texTransformLocation; | 974 int texTransformLocation; |
| 975 int vertexOpacityLocation; |
974 }; | 976 }; |
975 | 977 |
976 void GLRenderer::flushTextureQuadCache() | 978 void GLRenderer::flushTextureQuadCache() |
977 { | 979 { |
978 // Check to see if we have anything to draw. | 980 // Check to see if we have anything to draw. |
979 if (m_drawCache.program_id == 0) | 981 if (m_drawCache.program_id == 0) |
980 return; | 982 return; |
981 | 983 |
982 // Set the correct blending mode. | 984 // Set the correct blending mode. |
983 setBlendEnabled(m_drawCache.needs_blending); | 985 setBlendEnabled(m_drawCache.needs_blending); |
(...skipping 11 matching lines...) Expand all Loading... |
995 // will never cause the alpha channel to be set to anything less than 1.
0 if it is | 997 // will never cause the alpha channel to be set to anything less than 1.
0 if it is |
996 // initialized to that value! Therefore, premultipliedAlpha being false
is the first | 998 // initialized to that value! Therefore, premultipliedAlpha being false
is the first |
997 // situation we can generally see an alpha channel less than 1.0 coming
out of the | 999 // situation we can generally see an alpha channel less than 1.0 coming
out of the |
998 // compositor. This is causing platform differences in some layout tests
(see | 1000 // compositor. This is causing platform differences in some layout tests
(see |
999 // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation,
use a separate | 1001 // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation,
use a separate |
1000 // blend function for the alpha channel to avoid modifying it. Don't use
colorMask for this | 1002 // blend function for the alpha channel to avoid modifying it. Don't use
colorMask for this |
1001 // as it has performance implications on some platforms. | 1003 // as it has performance implications on some platforms. |
1002 GLC(context(), context()->blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_S
RC_ALPHA, GL_ZERO, GL_ONE)); | 1004 GLC(context(), context()->blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_S
RC_ALPHA, GL_ZERO, GL_ONE)); |
1003 } | 1005 } |
1004 | 1006 |
1005 // Set the shader opacity. | |
1006 setShaderOpacity(m_drawCache.alpha, m_drawCache.alpha_location); | |
1007 | |
1008 COMPILE_ASSERT(sizeof(Float4) == 4 * sizeof(float), struct_is_densely_packed
); | 1007 COMPILE_ASSERT(sizeof(Float4) == 4 * sizeof(float), struct_is_densely_packed
); |
1009 COMPILE_ASSERT(sizeof(Float16) == 16 * sizeof(float), struct_is_densely_pack
ed); | 1008 COMPILE_ASSERT(sizeof(Float16) == 16 * sizeof(float), struct_is_densely_pack
ed); |
1010 | 1009 |
1011 // Upload the tranforms for both points and uvs. | 1010 // Upload the tranforms for both points and uvs. |
1012 GLC(m_context, m_context->uniformMatrix4fv((int)m_drawCache.matrix_location,
(int)m_drawCache.matrix_data.size(), false, (float*)&m_drawCache.matrix_data.fr
ont())); | 1011 GLC(m_context, m_context->uniformMatrix4fv(static_cast<int>(m_drawCache.matr
ix_location), static_cast<int>(m_drawCache.matrix_data.size()), false, reinterpr
et_cast<float*>(&m_drawCache.matrix_data.front()))); |
1013 GLC(m_context, m_context->uniform4fv((int)m_drawCache.uv_xform_location, (in
t)m_drawCache.uv_xform_data.size(), (float*)&m_drawCache.uv_xform_data.front()))
; | 1012 GLC(m_context, m_context->uniform4fv(static_cast<int>(m_drawCache.uv_xform_l
ocation), static_cast<int>(m_drawCache.uv_xform_data.size()), reinterpret_cast<f
loat*>(&m_drawCache.uv_xform_data.front()))); |
| 1013 GLC(m_context, m_context->uniform1fv(static_cast<int>(m_drawCache.vertex_opa
city_location), static_cast<int>(m_drawCache.vertex_opacity_data.size()), static
_cast<float*>(&m_drawCache.vertex_opacity_data.front()))); |
1014 | 1014 |
1015 // Draw the quads! | 1015 // Draw the quads! |
1016 GLC(m_context, m_context->drawElements(GL_TRIANGLES, 6 * m_drawCache.matrix_
data.size(), GL_UNSIGNED_SHORT, 0)); | 1016 GLC(m_context, m_context->drawElements(GL_TRIANGLES, 6 * m_drawCache.matrix_
data.size(), GL_UNSIGNED_SHORT, 0)); |
1017 | 1017 |
1018 // Clean up after ourselves (reset state set above). | 1018 // Clean up after ourselves (reset state set above). |
1019 if (!m_drawCache.use_premultiplied_alpha) | 1019 if (!m_drawCache.use_premultiplied_alpha) |
1020 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); | 1020 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); |
1021 | 1021 |
1022 // Clear the cache. | 1022 // Clear the cache. |
1023 m_drawCache.program_id = 0; | 1023 m_drawCache.program_id = 0; |
1024 m_drawCache.uv_xform_data.resize(0); | 1024 m_drawCache.uv_xform_data.resize(0); |
| 1025 m_drawCache.vertex_opacity_data.resize(0); |
1025 m_drawCache.matrix_data.resize(0); | 1026 m_drawCache.matrix_data.resize(0); |
1026 } | 1027 } |
1027 | 1028 |
1028 void GLRenderer::enqueueTextureQuad(const DrawingFrame& frame, const TextureDraw
Quad* quad) | 1029 void GLRenderer::enqueueTextureQuad(const DrawingFrame& frame, const TextureDraw
Quad* quad) |
1029 { | 1030 { |
1030 // Choose the correcte texture program binding | 1031 // Choose the correct texture program binding |
1031 TexTransformTextureProgramBinding binding; | 1032 TexTransformTextureProgramBinding binding; |
1032 if (quad->flipped) | 1033 if (quad->flipped) |
1033 binding.set(textureProgramFlip(), context()); | 1034 binding.set(textureProgramFlip(), context()); |
1034 else | 1035 else |
1035 binding.set(textureProgram(), context()); | 1036 binding.set(textureProgram(), context()); |
1036 | 1037 |
1037 int resourceID = quad->resource_id; | 1038 int resourceID = quad->resource_id; |
1038 | 1039 |
1039 if (m_drawCache.program_id != binding.programId || | 1040 if (m_drawCache.program_id != binding.programId || |
1040 m_drawCache.resource_id != resourceID || | 1041 m_drawCache.resource_id != resourceID || |
1041 m_drawCache.alpha != quad->opacity() || | |
1042 m_drawCache.use_premultiplied_alpha != quad->premultiplied_alpha || | 1042 m_drawCache.use_premultiplied_alpha != quad->premultiplied_alpha || |
1043 m_drawCache.needs_blending != quad->ShouldDrawWithBlending() || | 1043 m_drawCache.needs_blending != quad->ShouldDrawWithBlending() || |
1044 m_drawCache.matrix_data.size() >= 8) { | 1044 m_drawCache.matrix_data.size() >= 8) { |
1045 flushTextureQuadCache(); | 1045 flushTextureQuadCache(); |
1046 m_drawCache.program_id = binding.programId; | 1046 m_drawCache.program_id = binding.programId; |
1047 m_drawCache.resource_id = resourceID; | 1047 m_drawCache.resource_id = resourceID; |
1048 m_drawCache.alpha = quad->opacity(); | |
1049 m_drawCache.use_premultiplied_alpha = quad->premultiplied_alpha; | 1048 m_drawCache.use_premultiplied_alpha = quad->premultiplied_alpha; |
1050 m_drawCache.needs_blending = quad->ShouldDrawWithBlending(); | 1049 m_drawCache.needs_blending = quad->ShouldDrawWithBlending(); |
1051 | 1050 |
1052 m_drawCache.alpha_location = binding.alphaLocation; | |
1053 m_drawCache.uv_xform_location = binding.texTransformLocation; | 1051 m_drawCache.uv_xform_location = binding.texTransformLocation; |
| 1052 m_drawCache.vertex_opacity_location = binding.vertexOpacityLocation; |
1054 m_drawCache.matrix_location = binding.matrixLocation; | 1053 m_drawCache.matrix_location = binding.matrixLocation; |
1055 } | 1054 } |
1056 | 1055 |
1057 // Generate the uv-transform | 1056 // Generate the uv-transform |
1058 const gfx::RectF& uvRect = quad->uv_rect; | 1057 const gfx::RectF& uvRect = quad->uv_rect; |
1059 Float4 uv = {uvRect.x(), uvRect.y(), uvRect.width(), uvRect.height()}; | 1058 Float4 uv = {uvRect.x(), uvRect.y(), uvRect.width(), uvRect.height()}; |
1060 m_drawCache.uv_xform_data.push_back(uv); | 1059 m_drawCache.uv_xform_data.push_back(uv); |
1061 | 1060 |
| 1061 // Generate the vertex opacity |
| 1062 const float opacity = quad->opacity(); |
| 1063 m_drawCache.vertex_opacity_data.push_back(quad->vertex_opacity[0] * opacity)
; |
| 1064 m_drawCache.vertex_opacity_data.push_back(quad->vertex_opacity[1] * opacity)
; |
| 1065 m_drawCache.vertex_opacity_data.push_back(quad->vertex_opacity[2] * opacity)
; |
| 1066 m_drawCache.vertex_opacity_data.push_back(quad->vertex_opacity[3] * opacity)
; |
| 1067 |
1062 // Generate the transform matrix | 1068 // Generate the transform matrix |
1063 gfx::Transform quadRectMatrix; | 1069 gfx::Transform quadRectMatrix; |
1064 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->rect); | 1070 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->rect); |
1065 quadRectMatrix = frame.projectionMatrix * quadRectMatrix; | 1071 quadRectMatrix = frame.projectionMatrix * quadRectMatrix; |
1066 | 1072 |
1067 Float16 m; | 1073 Float16 m; |
1068 quadRectMatrix.matrix().asColMajorf(m.data); | 1074 quadRectMatrix.matrix().asColMajorf(m.data); |
1069 m_drawCache.matrix_data.push_back(m); | 1075 m_drawCache.matrix_data.push_back(m); |
1070 } | 1076 } |
1071 | 1077 |
1072 void GLRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQua
d* quad) | 1078 void GLRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQua
d* quad) |
1073 { | 1079 { |
1074 TexTransformTextureProgramBinding binding; | 1080 TexTransformTextureProgramBinding binding; |
1075 if (quad->flipped) | 1081 if (quad->flipped) |
1076 binding.set(textureProgramFlip(), context()); | 1082 binding.set(textureProgramFlip(), context()); |
1077 else | 1083 else |
1078 binding.set(textureProgram(), context()); | 1084 binding.set(textureProgram(), context()); |
1079 setUseProgram(binding.programId); | 1085 setUseProgram(binding.programId); |
1080 GLC(context(), context()->uniform1i(binding.samplerLocation, 0)); | 1086 GLC(context(), context()->uniform1i(binding.samplerLocation, 0)); |
1081 const gfx::RectF& uvRect = quad->uv_rect; | 1087 const gfx::RectF& uvRect = quad->uv_rect; |
1082 GLC(context(), context()->uniform4f(binding.texTransformLocation, uvRect.x()
, uvRect.y(), uvRect.width(), uvRect.height())); | 1088 GLC(context(), context()->uniform4f(binding.texTransformLocation, uvRect.x()
, uvRect.y(), uvRect.width(), uvRect.height())); |
1083 | 1089 |
| 1090 GLC(context(), context()->uniform1fv(binding.vertexOpacityLocation, 4, quad-
>vertex_opacity)); |
| 1091 |
1084 ResourceProvider::ScopedSamplerGL quadResourceLock(m_resourceProvider, quad-
>resource_id, GL_TEXTURE_2D, GL_LINEAR); | 1092 ResourceProvider::ScopedSamplerGL quadResourceLock(m_resourceProvider, quad-
>resource_id, GL_TEXTURE_2D, GL_LINEAR); |
1085 | 1093 |
1086 if (!quad->premultiplied_alpha) { | 1094 if (!quad->premultiplied_alpha) { |
1087 // As it turns out, the premultiplied alpha blending function (ONE, ONE_
MINUS_SRC_ALPHA) | 1095 // As it turns out, the premultiplied alpha blending function (ONE, ONE_
MINUS_SRC_ALPHA) |
1088 // will never cause the alpha channel to be set to anything less than 1.
0 if it is | 1096 // will never cause the alpha channel to be set to anything less than 1.
0 if it is |
1089 // initialized to that value! Therefore, premultipliedAlpha being false
is the first | 1097 // initialized to that value! Therefore, premultipliedAlpha being false
is the first |
1090 // situation we can generally see an alpha channel less than 1.0 coming
out of the | 1098 // situation we can generally see an alpha channel less than 1.0 coming
out of the |
1091 // compositor. This is causing platform differences in some layout tests
(see | 1099 // compositor. This is causing platform differences in some layout tests
(see |
1092 // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation,
use a separate | 1100 // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation,
use a separate |
1093 // blend function for the alpha channel to avoid modifying it. Don't use
colorMask for this | 1101 // blend function for the alpha channel to avoid modifying it. Don't use
colorMask for this |
1094 // as it has performance implications on some platforms. | 1102 // as it has performance implications on some platforms. |
1095 GLC(context(), context()->blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_S
RC_ALPHA, GL_ZERO, GL_ONE)); | 1103 GLC(context(), context()->blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_S
RC_ALPHA, GL_ZERO, GL_ONE)); |
1096 } | 1104 } |
1097 | 1105 |
1098 setShaderOpacity(quad->opacity(), binding.alphaLocation); | |
1099 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, binding.matrixLoc
ation); | 1106 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, binding.matrixLoc
ation); |
1100 | 1107 |
1101 if (!quad->premultiplied_alpha) | 1108 if (!quad->premultiplied_alpha) |
1102 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); | 1109 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); |
1103 } | 1110 } |
1104 | 1111 |
1105 void GLRenderer::drawIOSurfaceQuad(const DrawingFrame& frame, const IOSurfaceDra
wQuad* quad) | 1112 void GLRenderer::drawIOSurfaceQuad(const DrawingFrame& frame, const IOSurfaceDra
wQuad* quad) |
1106 { | 1113 { |
1107 TexTransformTextureProgramBinding binding; | 1114 TexTransformTextureProgramBinding binding; |
1108 binding.set(textureIOSurfaceProgram(), context()); | 1115 binding.set(textureIOSurfaceProgram(), context()); |
1109 | 1116 |
1110 setUseProgram(binding.programId); | 1117 setUseProgram(binding.programId); |
1111 GLC(context(), context()->uniform1i(binding.samplerLocation, 0)); | 1118 GLC(context(), context()->uniform1i(binding.samplerLocation, 0)); |
1112 if (quad->orientation == IOSurfaceDrawQuad::FLIPPED) | 1119 if (quad->orientation == IOSurfaceDrawQuad::FLIPPED) |
1113 GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, qua
d->io_surface_size.height(), quad->io_surface_size.width(), quad->io_surface_siz
e.height() * -1.0)); | 1120 GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, qua
d->io_surface_size.height(), quad->io_surface_size.width(), quad->io_surface_siz
e.height() * -1.0)); |
1114 else | 1121 else |
1115 GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, 0,
quad->io_surface_size.width(), quad->io_surface_size.height())); | 1122 GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, 0,
quad->io_surface_size.width(), quad->io_surface_size.height())); |
1116 | 1123 |
| 1124 const float vertex_opacity[] = {quad->opacity(), quad->opacity(), quad->opac
ity(), quad->opacity()}; |
| 1125 GLC(context(), context()->uniform1fv(binding.vertexOpacityLocation, 4, verte
x_opacity)); |
| 1126 |
1117 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, quad->io_sur
face_texture_id)); | 1127 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, quad->io_sur
face_texture_id)); |
1118 | 1128 |
1119 setShaderOpacity(quad->opacity(), binding.alphaLocation); | |
1120 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, binding.matrixLoc
ation); | 1129 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, binding.matrixLoc
ation); |
1121 | 1130 |
1122 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, 0)); | 1131 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, 0)); |
1123 } | 1132 } |
1124 | 1133 |
1125 void GLRenderer::finishDrawingFrame(DrawingFrame& frame) | 1134 void GLRenderer::finishDrawingFrame(DrawingFrame& frame) |
1126 { | 1135 { |
1127 m_currentFramebufferLock.reset(); | 1136 m_currentFramebufferLock.reset(); |
1128 m_swapBufferRect.Union(gfx::ToEnclosingRect(frame.rootDamageRect)); | 1137 m_swapBufferRect.Union(gfx::ToEnclosingRect(frame.rootDamageRect)); |
1129 | 1138 |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 | 1755 |
1747 releaseRenderPassTextures(); | 1756 releaseRenderPassTextures(); |
1748 } | 1757 } |
1749 | 1758 |
1750 bool GLRenderer::isContextLost() | 1759 bool GLRenderer::isContextLost() |
1751 { | 1760 { |
1752 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); | 1761 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); |
1753 } | 1762 } |
1754 | 1763 |
1755 } // namespace cc | 1764 } // namespace cc |
OLD | NEW |