diff options
-rw-r--r-- | cc/output/gl_renderer.cc | 78 | ||||
-rw-r--r-- | cc/output/gl_renderer.h | 8 | ||||
-rw-r--r-- | cc/output/gl_renderer_draw_cache.h | 2 | ||||
-rw-r--r-- | cc/output/gl_renderer_unittest.cc | 2 | ||||
-rw-r--r-- | cc/output/shader.cc | 15 | ||||
-rw-r--r-- | cc/output/shader.h | 5 |
6 files changed, 65 insertions, 45 deletions
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 960198d..901ba9a 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -1686,23 +1686,6 @@ void GLRenderer::FlushTextureQuadCache() { GLC(Context(), Context()->bindTexture(GL_TEXTURE_2D, locked_quad.texture_id())); - // set up premultiplied alpha. - if (!draw_cache_.use_premultiplied_alpha) { - // As it turns out, the premultiplied alpha blending function (ONE, - // ONE_MINUS_SRC_ALPHA) will never cause the alpha channel to be set to - // anything less than 1.0f if it is initialized to that value! Therefore, - // premultiplied_alpha being false is the first situation we can generally - // see an alpha channel less than 1.0f coming out of the compositor. This is - // causing platform differences in some layout tests (see - // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation, use - // a separate blend function for the alpha channel to avoid modifying it. - // Don't use colorMask() for this as it has performance implications on some - // platforms. - GLC(Context(), - Context()->blendFuncSeparate( - GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE)); - } - COMPILE_ASSERT( sizeof(Float4) == 4 * sizeof(float), // NOLINT(runtime/sizeof) struct_is_densely_packed); @@ -1735,10 +1718,6 @@ void GLRenderer::FlushTextureQuadCache() { GL_UNSIGNED_SHORT, 0)); - // Clean up after ourselves (reset state set above). - if (!draw_cache_.use_premultiplied_alpha) - GLC(context_, context_->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); - // Clear the cache. draw_cache_.program_id = 0; draw_cache_.uv_xform_data.resize(0); @@ -1754,19 +1733,22 @@ void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame, // Choose the correct texture program binding TexTransformTextureProgramBinding binding; - binding.Set(GetTextureProgram(tex_coord_precision), Context()); + if (quad->premultiplied_alpha) { + binding.Set(GetTextureProgram(tex_coord_precision), Context()); + } else { + binding.Set(GetNonPremultipliedTextureProgram(tex_coord_precision), + Context()); + } int resource_id = quad->resource_id; if (draw_cache_.program_id != binding.program_id || draw_cache_.resource_id != resource_id || - draw_cache_.use_premultiplied_alpha != quad->premultiplied_alpha || draw_cache_.needs_blending != quad->ShouldDrawWithBlending() || draw_cache_.matrix_data.size() >= 8) { FlushTextureQuadCache(); draw_cache_.program_id = binding.program_id; draw_cache_.resource_id = resource_id; - draw_cache_.use_premultiplied_alpha = quad->premultiplied_alpha; draw_cache_.needs_blending = quad->ShouldDrawWithBlending(); draw_cache_.uv_xform_location = binding.tex_transform_location; @@ -1802,7 +1784,12 @@ void GLRenderer::DrawTextureQuad(const DrawingFrame* frame, quad->shared_quad_state->visible_content_rect.bottom_right()); TexTransformTextureProgramBinding binding; - binding.Set(GetTextureProgram(tex_coord_precision), Context()); + if (quad->premultiplied_alpha) { + binding.Set(GetTextureProgram(tex_coord_precision), Context()); + } else { + binding.Set(GetNonPremultipliedTextureProgram(tex_coord_precision), + Context()); + } SetUseProgram(binding.program_id); GLC(Context(), Context()->uniform1i(binding.sampler_location, 0)); Float4 uv_xform = UVTransform(quad); @@ -1820,27 +1807,8 @@ void GLRenderer::DrawTextureQuad(const DrawingFrame* frame, ResourceProvider::ScopedSamplerGL quad_resource_lock( resource_provider_, quad->resource_id, GL_TEXTURE_2D, GL_LINEAR); - if (!quad->premultiplied_alpha) { - // As it turns out, the premultiplied alpha blending function (ONE, - // ONE_MINUS_SRC_ALPHA) will never cause the alpha channel to be set to - // anything less than 1.0f if it is initialized to that value! Therefore, - // premultiplied_alpha being false is the first situation we can generally - // see an alpha channel less than 1.0f coming out of the compositor. This is - // causing platform differences in some layout tests (see - // https://bugs.webkit.org/show_bug.cgi?id=82412), so in this situation, use - // a separate blend function for the alpha channel to avoid modifying it. - // Don't use colorMask() for this as it has performance implications on some - // platforms. - GLC(Context(), - Context()->blendFuncSeparate( - GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE)); - } - DrawQuadGeometry( frame, quad->quadTransform(), quad->rect, binding.matrix_location); - - if (!quad->premultiplied_alpha) - GLC(context_, context_->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); } void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame, @@ -2824,6 +2792,24 @@ const GLRenderer::TextureProgram* GLRenderer::GetTextureProgram( return program.get(); } +const GLRenderer::NonPremultipliedTextureProgram* + GLRenderer::GetNonPremultipliedTextureProgram(TexCoordPrecision precision) { + scoped_ptr<NonPremultipliedTextureProgram>& program = + (precision == TexCoordPrecisionHigh) ? + nonpremultiplied_texture_program_highp_ : + nonpremultiplied_texture_program_; + if (!program) { + program = make_scoped_ptr( + new NonPremultipliedTextureProgram(context_, precision)); + } + if (!program->initialized()) { + TRACE_EVENT0("cc", + "GLRenderer::NonPremultipliedTextureProgram::Initialize"); + program->Initialize(context_, is_using_bind_uniform_); + } + return program.get(); +} + const GLRenderer::TextureIOSurfaceProgram* GLRenderer::GetTextureIOSurfaceProgram(TexCoordPrecision precision) { scoped_ptr<TextureIOSurfaceProgram>& program = @@ -2953,11 +2939,15 @@ void GLRenderer::CleanupSharedObjects() { if (texture_program_) texture_program_->Cleanup(context_); + if (nonpremultiplied_texture_program_) + nonpremultiplied_texture_program_->Cleanup(context_); if (texture_io_surface_program_) texture_io_surface_program_->Cleanup(context_); if (texture_program_highp_) texture_program_highp_->Cleanup(context_); + if (nonpremultiplied_texture_program_highp_) + nonpremultiplied_texture_program_highp_->Cleanup(context_); if (texture_io_surface_program_highp_) texture_io_surface_program_highp_->Cleanup(context_); diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index 32e89d3..db59e5b 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h @@ -265,6 +265,9 @@ class CC_EXPORT GLRenderer typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexVaryingAlpha> TextureProgram; typedef ProgramBinding<VertexShaderPosTexTransform, + FragmentShaderRGBATexPremultiplyAlpha> + NonPremultipliedTextureProgram; + typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexRectVaryingAlpha> TextureIOSurfaceProgram; @@ -337,6 +340,8 @@ class CC_EXPORT GLRenderer const TextureProgram* GetTextureProgram( TexCoordPrecision precision); + const NonPremultipliedTextureProgram* GetNonPremultipliedTextureProgram( + TexCoordPrecision precision); const TextureIOSurfaceProgram* GetTextureIOSurfaceProgram( TexCoordPrecision precision); @@ -367,9 +372,12 @@ class CC_EXPORT GLRenderer scoped_ptr<TileProgramSwizzleAA> tile_program_swizzle_aa_highp_; scoped_ptr<TextureProgram> texture_program_; + scoped_ptr<NonPremultipliedTextureProgram> nonpremultiplied_texture_program_; scoped_ptr<TextureIOSurfaceProgram> texture_io_surface_program_; scoped_ptr<TextureProgram> texture_program_highp_; + scoped_ptr<NonPremultipliedTextureProgram> + nonpremultiplied_texture_program_highp_; scoped_ptr<TextureIOSurfaceProgram> texture_io_surface_program_highp_; scoped_ptr<RenderPassProgram> render_pass_program_; diff --git a/cc/output/gl_renderer_draw_cache.h b/cc/output/gl_renderer_draw_cache.h index e99cc27..85369ef 100644 --- a/cc/output/gl_renderer_draw_cache.h +++ b/cc/output/gl_renderer_draw_cache.h @@ -31,7 +31,6 @@ struct TexturedQuadDrawCache { // Values tracked to determine if textured quads may be coalesced. int program_id; int resource_id; - bool use_premultiplied_alpha; bool needs_blending; // Information about the program binding that is required to draw. @@ -45,6 +44,7 @@ struct TexturedQuadDrawCache { std::vector<float> vertex_opacity_data; std::vector<Float16> matrix_data; + private: DISALLOW_COPY_AND_ASSIGN(TexturedQuadDrawCache); }; diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index 97c73fa..34443e3 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc @@ -93,6 +93,8 @@ class GLRendererShaderPixelTest : public GLRendererPixelTest { EXPECT_PROGRAM_VALID( renderer()->GetRenderPassMaskColorMatrixProgram(precision)); EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision)); + EXPECT_PROGRAM_VALID( + renderer()->GetNonPremultipliedTextureProgram(precision)); EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision)); EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision)); EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision)); diff --git a/cc/output/shader.cc b/cc/output/shader.cc index 385c72d..6e1f6c5 100644 --- a/cc/output/shader.cc +++ b/cc/output/shader.cc @@ -682,6 +682,21 @@ std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString( ); // NOLINT(whitespace/parens) } +std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString( + TexCoordPrecision precision) const { + return FRAGMENT_SHADER( + precision mediump float; + varying TexCoordPrecision vec2 v_texCoord; + varying float v_alpha; + uniform sampler2D s_texture; + void main() { + vec4 texColor = texture2D(s_texture, v_texCoord); + texColor.rgb *= texColor.a; + gl_FragColor = texColor * v_alpha; + } + ); // NOLINT(whitespace/parens) +} + std::string FragmentShaderRGBATexRectVaryingAlpha::GetShaderString( TexCoordPrecision precision) const { return "#extension GL_ARB_texture_rectangle : require\n" + diff --git a/cc/output/shader.h b/cc/output/shader.h index 44eedef..7910e59 100644 --- a/cc/output/shader.h +++ b/cc/output/shader.h @@ -283,6 +283,11 @@ class FragmentShaderRGBATexVaryingAlpha : public FragmentTexOpaqueBinding { std::string GetShaderString(TexCoordPrecision precision) const; }; +class FragmentShaderRGBATexPremultiplyAlpha : public FragmentTexOpaqueBinding { + public: + std::string GetShaderString(TexCoordPrecision precision) const; +}; + class FragmentShaderRGBATexAlpha : public FragmentTexAlphaBinding { public: std::string GetShaderString(TexCoordPrecision precision) const; |