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 976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 int matrixLocation; | 987 int matrixLocation; |
988 int alphaLocation; | 988 int alphaLocation; |
989 }; | 989 }; |
990 | 990 |
991 struct TexTransformTextureProgramBinding : TextureProgramBinding { | 991 struct TexTransformTextureProgramBinding : TextureProgramBinding { |
992 template<class Program> void set( | 992 template<class Program> void set( |
993 Program* program, WebKit::WebGraphicsContext3D* context) | 993 Program* program, WebKit::WebGraphicsContext3D* context) |
994 { | 994 { |
995 TextureProgramBinding::set(program, context); | 995 TextureProgramBinding::set(program, context); |
996 texTransformLocation = program->vertexShader().texTransformLocation(); | 996 texTransformLocation = program->vertexShader().texTransformLocation(); |
| 997 vertexOpacityLocation = program->vertexShader().vertexOpacityLocation(); |
997 } | 998 } |
998 int texTransformLocation; | 999 int texTransformLocation; |
| 1000 int vertexOpacityLocation; |
999 }; | 1001 }; |
1000 | 1002 |
1001 void GLRenderer::flushTextureQuadCache() | 1003 void GLRenderer::flushTextureQuadCache() |
1002 { | 1004 { |
1003 // Check to see if we have anything to draw. | 1005 // Check to see if we have anything to draw. |
1004 if (m_drawCache.program_id == 0) | 1006 if (m_drawCache.program_id == 0) |
1005 return; | 1007 return; |
1006 | 1008 |
1007 // Set the correct blending mode. | 1009 // Set the correct blending mode. |
1008 setBlendEnabled(m_drawCache.needs_blending); | 1010 setBlendEnabled(m_drawCache.needs_blending); |
(...skipping 14 matching lines...) Expand all Loading... |
1023 // will never cause the alpha channel to be set to anything less than 1.
0 if it is | 1025 // will never cause the alpha channel to be set to anything less than 1.
0 if it is |
1024 // initialized to that value! Therefore, premultipliedAlpha being false
is the first | 1026 // initialized to that value! Therefore, premultipliedAlpha being false
is the first |
1025 // situation we can generally see an alpha channel less than 1.0 coming
out of the | 1027 // situation we can generally see an alpha channel less than 1.0 coming
out of the |
1026 // compositor. This is causing platform differences in some layout tests
(see | 1028 // compositor. This is causing platform differences in some layout tests
(see |
1027 // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation,
use a separate | 1029 // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation,
use a separate |
1028 // blend function for the alpha channel to avoid modifying it. Don't use
colorMask for this | 1030 // blend function for the alpha channel to avoid modifying it. Don't use
colorMask for this |
1029 // as it has performance implications on some platforms. | 1031 // as it has performance implications on some platforms. |
1030 GLC(context(), context()->blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_S
RC_ALPHA, GL_ZERO, GL_ONE)); | 1032 GLC(context(), context()->blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_S
RC_ALPHA, GL_ZERO, GL_ONE)); |
1031 } | 1033 } |
1032 | 1034 |
1033 // Set the shader opacity. | |
1034 setShaderOpacity(m_drawCache.alpha, m_drawCache.alpha_location); | |
1035 | |
1036 COMPILE_ASSERT(sizeof(Float4) == 4 * sizeof(float), struct_is_densely_packed
); | 1035 COMPILE_ASSERT(sizeof(Float4) == 4 * sizeof(float), struct_is_densely_packed
); |
1037 COMPILE_ASSERT(sizeof(Float16) == 16 * sizeof(float), struct_is_densely_pack
ed); | 1036 COMPILE_ASSERT(sizeof(Float16) == 16 * sizeof(float), struct_is_densely_pack
ed); |
1038 | 1037 |
1039 // Upload the tranforms for both points and uvs. | 1038 // Upload the tranforms for both points and uvs. |
1040 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())); | 1039 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()))); |
1041 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()))
; | 1040 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()))); |
| 1041 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()))); |
1042 | 1042 |
1043 // Draw the quads! | 1043 // Draw the quads! |
1044 GLC(m_context, m_context->drawElements(GL_TRIANGLES, 6 * m_drawCache.matrix_
data.size(), GL_UNSIGNED_SHORT, 0)); | 1044 GLC(m_context, m_context->drawElements(GL_TRIANGLES, 6 * m_drawCache.matrix_
data.size(), GL_UNSIGNED_SHORT, 0)); |
1045 | 1045 |
1046 // Clean up after ourselves (reset state set above). | 1046 // Clean up after ourselves (reset state set above). |
1047 if (!m_drawCache.use_premultiplied_alpha) | 1047 if (!m_drawCache.use_premultiplied_alpha) |
1048 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); | 1048 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); |
1049 | 1049 |
1050 // Clear the cache. | 1050 // Clear the cache. |
1051 m_drawCache.program_id = 0; | 1051 m_drawCache.program_id = 0; |
1052 m_drawCache.uv_xform_data.resize(0); | 1052 m_drawCache.uv_xform_data.resize(0); |
| 1053 m_drawCache.vertex_opacity_data.resize(0); |
1053 m_drawCache.matrix_data.resize(0); | 1054 m_drawCache.matrix_data.resize(0); |
1054 } | 1055 } |
1055 | 1056 |
1056 void GLRenderer::enqueueTextureQuad(const DrawingFrame& frame, const TextureDraw
Quad* quad) | 1057 void GLRenderer::enqueueTextureQuad(const DrawingFrame& frame, const TextureDraw
Quad* quad) |
1057 { | 1058 { |
1058 // Choose the correcte texture program binding | 1059 // Choose the correct texture program binding |
1059 TexTransformTextureProgramBinding binding; | 1060 TexTransformTextureProgramBinding binding; |
1060 if (quad->flipped) | 1061 if (quad->flipped) |
1061 binding.set(textureProgramFlip(), context()); | 1062 binding.set(textureProgramFlip(), context()); |
1062 else | 1063 else |
1063 binding.set(textureProgram(), context()); | 1064 binding.set(textureProgram(), context()); |
1064 | 1065 |
1065 int resourceID = quad->resource_id; | 1066 int resourceID = quad->resource_id; |
1066 | 1067 |
1067 if (m_drawCache.program_id != binding.programId || | 1068 if (m_drawCache.program_id != binding.programId || |
1068 m_drawCache.resource_id != resourceID || | 1069 m_drawCache.resource_id != resourceID || |
1069 m_drawCache.alpha != quad->opacity() || | |
1070 m_drawCache.use_premultiplied_alpha != quad->premultiplied_alpha || | 1070 m_drawCache.use_premultiplied_alpha != quad->premultiplied_alpha || |
1071 m_drawCache.needs_blending != quad->ShouldDrawWithBlending() || | 1071 m_drawCache.needs_blending != quad->ShouldDrawWithBlending() || |
1072 m_drawCache.matrix_data.size() >= 8) { | 1072 m_drawCache.matrix_data.size() >= 8) { |
1073 flushTextureQuadCache(); | 1073 flushTextureQuadCache(); |
1074 m_drawCache.program_id = binding.programId; | 1074 m_drawCache.program_id = binding.programId; |
1075 m_drawCache.resource_id = resourceID; | 1075 m_drawCache.resource_id = resourceID; |
1076 m_drawCache.alpha = quad->opacity(); | |
1077 m_drawCache.use_premultiplied_alpha = quad->premultiplied_alpha; | 1076 m_drawCache.use_premultiplied_alpha = quad->premultiplied_alpha; |
1078 m_drawCache.needs_blending = quad->ShouldDrawWithBlending(); | 1077 m_drawCache.needs_blending = quad->ShouldDrawWithBlending(); |
1079 | 1078 |
1080 m_drawCache.alpha_location = binding.alphaLocation; | |
1081 m_drawCache.uv_xform_location = binding.texTransformLocation; | 1079 m_drawCache.uv_xform_location = binding.texTransformLocation; |
| 1080 m_drawCache.vertex_opacity_location = binding.vertexOpacityLocation; |
1082 m_drawCache.matrix_location = binding.matrixLocation; | 1081 m_drawCache.matrix_location = binding.matrixLocation; |
1083 m_drawCache.sampler_location = binding.samplerLocation; | 1082 m_drawCache.sampler_location = binding.samplerLocation; |
1084 } | 1083 } |
1085 | 1084 |
1086 // Generate the uv-transform | 1085 // Generate the uv-transform |
1087 const gfx::RectF& uvRect = quad->uv_rect; | 1086 const gfx::RectF& uvRect = quad->uv_rect; |
1088 Float4 uv = {uvRect.x(), uvRect.y(), uvRect.width(), uvRect.height()}; | 1087 Float4 uv = {uvRect.x(), uvRect.y(), uvRect.width(), uvRect.height()}; |
1089 m_drawCache.uv_xform_data.push_back(uv); | 1088 m_drawCache.uv_xform_data.push_back(uv); |
1090 | 1089 |
| 1090 // Generate the vertex opacity |
| 1091 const float opacity = quad->opacity(); |
| 1092 m_drawCache.vertex_opacity_data.push_back(quad->vertex_opacity[0] * opacity)
; |
| 1093 m_drawCache.vertex_opacity_data.push_back(quad->vertex_opacity[1] * opacity)
; |
| 1094 m_drawCache.vertex_opacity_data.push_back(quad->vertex_opacity[2] * opacity)
; |
| 1095 m_drawCache.vertex_opacity_data.push_back(quad->vertex_opacity[3] * opacity)
; |
| 1096 |
1091 // Generate the transform matrix | 1097 // Generate the transform matrix |
1092 gfx::Transform quadRectMatrix; | 1098 gfx::Transform quadRectMatrix; |
1093 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->rect); | 1099 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->rect); |
1094 quadRectMatrix = frame.projectionMatrix * quadRectMatrix; | 1100 quadRectMatrix = frame.projectionMatrix * quadRectMatrix; |
1095 | 1101 |
1096 Float16 m; | 1102 Float16 m; |
1097 quadRectMatrix.matrix().asColMajorf(m.data); | 1103 quadRectMatrix.matrix().asColMajorf(m.data); |
1098 m_drawCache.matrix_data.push_back(m); | 1104 m_drawCache.matrix_data.push_back(m); |
1099 } | 1105 } |
1100 | 1106 |
1101 void GLRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQua
d* quad) | 1107 void GLRenderer::drawTextureQuad(const DrawingFrame& frame, const TextureDrawQua
d* quad) |
1102 { | 1108 { |
1103 TexTransformTextureProgramBinding binding; | 1109 TexTransformTextureProgramBinding binding; |
1104 if (quad->flipped) | 1110 if (quad->flipped) |
1105 binding.set(textureProgramFlip(), context()); | 1111 binding.set(textureProgramFlip(), context()); |
1106 else | 1112 else |
1107 binding.set(textureProgram(), context()); | 1113 binding.set(textureProgram(), context()); |
1108 setUseProgram(binding.programId); | 1114 setUseProgram(binding.programId); |
1109 GLC(context(), context()->uniform1i(binding.samplerLocation, 0)); | 1115 GLC(context(), context()->uniform1i(binding.samplerLocation, 0)); |
1110 const gfx::RectF& uvRect = quad->uv_rect; | 1116 const gfx::RectF& uvRect = quad->uv_rect; |
1111 GLC(context(), context()->uniform4f(binding.texTransformLocation, uvRect.x()
, uvRect.y(), uvRect.width(), uvRect.height())); | 1117 GLC(context(), context()->uniform4f(binding.texTransformLocation, uvRect.x()
, uvRect.y(), uvRect.width(), uvRect.height())); |
1112 | 1118 |
| 1119 GLC(context(), context()->uniform1fv(binding.vertexOpacityLocation, 4, quad-
>vertex_opacity)); |
| 1120 |
1113 ResourceProvider::ScopedSamplerGL quadResourceLock(m_resourceProvider, quad-
>resource_id, GL_TEXTURE_2D, GL_LINEAR); | 1121 ResourceProvider::ScopedSamplerGL quadResourceLock(m_resourceProvider, quad-
>resource_id, GL_TEXTURE_2D, GL_LINEAR); |
1114 | 1122 |
1115 if (!quad->premultiplied_alpha) { | 1123 if (!quad->premultiplied_alpha) { |
1116 // As it turns out, the premultiplied alpha blending function (ONE, ONE_
MINUS_SRC_ALPHA) | 1124 // As it turns out, the premultiplied alpha blending function (ONE, ONE_
MINUS_SRC_ALPHA) |
1117 // will never cause the alpha channel to be set to anything less than 1.
0 if it is | 1125 // will never cause the alpha channel to be set to anything less than 1.
0 if it is |
1118 // initialized to that value! Therefore, premultipliedAlpha being false
is the first | 1126 // initialized to that value! Therefore, premultipliedAlpha being false
is the first |
1119 // situation we can generally see an alpha channel less than 1.0 coming
out of the | 1127 // situation we can generally see an alpha channel less than 1.0 coming
out of the |
1120 // compositor. This is causing platform differences in some layout tests
(see | 1128 // compositor. This is causing platform differences in some layout tests
(see |
1121 // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation,
use a separate | 1129 // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation,
use a separate |
1122 // blend function for the alpha channel to avoid modifying it. Don't use
colorMask for this | 1130 // blend function for the alpha channel to avoid modifying it. Don't use
colorMask for this |
1123 // as it has performance implications on some platforms. | 1131 // as it has performance implications on some platforms. |
1124 GLC(context(), context()->blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_S
RC_ALPHA, GL_ZERO, GL_ONE)); | 1132 GLC(context(), context()->blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_S
RC_ALPHA, GL_ZERO, GL_ONE)); |
1125 } | 1133 } |
1126 | 1134 |
1127 setShaderOpacity(quad->opacity(), binding.alphaLocation); | |
1128 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, binding.matrixLoc
ation); | 1135 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, binding.matrixLoc
ation); |
1129 | 1136 |
1130 if (!quad->premultiplied_alpha) | 1137 if (!quad->premultiplied_alpha) |
1131 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); | 1138 GLC(m_context, m_context->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); |
1132 } | 1139 } |
1133 | 1140 |
1134 void GLRenderer::drawIOSurfaceQuad(const DrawingFrame& frame, const IOSurfaceDra
wQuad* quad) | 1141 void GLRenderer::drawIOSurfaceQuad(const DrawingFrame& frame, const IOSurfaceDra
wQuad* quad) |
1135 { | 1142 { |
1136 TexTransformTextureProgramBinding binding; | 1143 TexTransformTextureProgramBinding binding; |
1137 binding.set(textureIOSurfaceProgram(), context()); | 1144 binding.set(textureIOSurfaceProgram(), context()); |
1138 | 1145 |
1139 setUseProgram(binding.programId); | 1146 setUseProgram(binding.programId); |
1140 GLC(context(), context()->uniform1i(binding.samplerLocation, 0)); | 1147 GLC(context(), context()->uniform1i(binding.samplerLocation, 0)); |
1141 if (quad->orientation == IOSurfaceDrawQuad::FLIPPED) | 1148 if (quad->orientation == IOSurfaceDrawQuad::FLIPPED) |
1142 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)); | 1149 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)); |
1143 else | 1150 else |
1144 GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, 0,
quad->io_surface_size.width(), quad->io_surface_size.height())); | 1151 GLC(context(), context()->uniform4f(binding.texTransformLocation, 0, 0,
quad->io_surface_size.width(), quad->io_surface_size.height())); |
1145 | 1152 |
| 1153 const float vertex_opacity[] = {quad->opacity(), quad->opacity(), quad->opac
ity(), quad->opacity()}; |
| 1154 GLC(context(), context()->uniform1fv(binding.vertexOpacityLocation, 4, verte
x_opacity)); |
| 1155 |
1146 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, quad->io_sur
face_texture_id)); | 1156 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, quad->io_sur
face_texture_id)); |
1147 | 1157 |
1148 setShaderOpacity(quad->opacity(), binding.alphaLocation); | |
1149 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, binding.matrixLoc
ation); | 1158 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, binding.matrixLoc
ation); |
1150 | 1159 |
1151 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, 0)); | 1160 GLC(context(), context()->bindTexture(GL_TEXTURE_RECTANGLE_ARB, 0)); |
1152 } | 1161 } |
1153 | 1162 |
1154 void GLRenderer::finishDrawingFrame(DrawingFrame& frame) | 1163 void GLRenderer::finishDrawingFrame(DrawingFrame& frame) |
1155 { | 1164 { |
1156 m_currentFramebufferLock.reset(); | 1165 m_currentFramebufferLock.reset(); |
1157 m_swapBufferRect.Union(gfx::ToEnclosingRect(frame.rootDamageRect)); | 1166 m_swapBufferRect.Union(gfx::ToEnclosingRect(frame.rootDamageRect)); |
1158 | 1167 |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1775 | 1784 |
1776 releaseRenderPassTextures(); | 1785 releaseRenderPassTextures(); |
1777 } | 1786 } |
1778 | 1787 |
1779 bool GLRenderer::isContextLost() | 1788 bool GLRenderer::isContextLost() |
1780 { | 1789 { |
1781 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); | 1790 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); |
1782 } | 1791 } |
1783 | 1792 |
1784 } // namespace cc | 1793 } // namespace cc |
OLD | NEW |