15ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen/*
25ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * Copyright (c) 2010, Google Inc. All rights reserved.
35ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *
45ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * Redistribution and use in source and binary forms, with or without
55ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * modification, are permitted provided that the following conditions are
65ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * met:
75ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *
85ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *     * Redistributions of source code must retain the above copyright
95ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * notice, this list of conditions and the following disclaimer.
105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *     * Redistributions in binary form must reproduce the above
115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * copyright notice, this list of conditions and the following disclaimer
125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * in the documentation and/or other materials provided with the
135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * distribution.
145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *     * Neither the name of Google Inc. nor the names of its
155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * contributors may be used to endorse or promote products derived from
165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * this software without specific prior written permission.
175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen *
185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen */
305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "config.h"
32a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
33a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#if ENABLE(ACCELERATED_2D_CANVAS)
34a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
355ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "Shader.h"
365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
375ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "AffineTransform.h"
385ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "GraphicsContext3D.h"
395ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
405ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include <wtf/text/CString.h>
412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include <wtf/text/StringBuilder.h>
425ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
435ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsennamespace WebCore {
445ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
455ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen// static
465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid Shader::affineTo3x3(const AffineTransform& transform, float mat[9])
475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
485ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    mat[0] = transform.a();
495ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    mat[1] = transform.b();
505ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    mat[2] = 0.0f;
515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    mat[3] = transform.c();
525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    mat[4] = transform.d();
535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    mat[5] = 0.0f;
545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    mat[6] = transform.e();
555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    mat[7] = transform.f();
565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    mat[8] = 1.0f;
575ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
585ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
595ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen// static
602fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid Shader::affineTo4x4(const AffineTransform& transform, float mat[16])
612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[0] = transform.a();
632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[1] = transform.b();
642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[2] = 0.0f;
652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[3] = 0.0f;
662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[4] = transform.c();
672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[5] = transform.d();
682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[6] = 0.0f;
692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[7] = 0.0f;
702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[8] = 0.0f;
712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[9] = 0.0f;
722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[10] = 1.0f;
732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[11] = 0.0f;
742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[12] = transform.e();
752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[13] = transform.f();
762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[14] = 0.0f;
772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    mat[15] = 1.0f;
782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// static
812fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockunsigned Shader::loadShader(GraphicsContext3D* context, unsigned type, const String& shaderSource)
825ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    unsigned shader = context->createShader(type);
845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (!shader)
855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return 0;
865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    context->shaderSource(shader, shaderSource);
885ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    context->compileShader(shader);
89f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int compileStatus = 0;
905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compileStatus);
915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (!compileStatus) {
925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        String infoLog = context->getShaderInfoLog(shader);
935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        LOG_ERROR("%s", infoLog.utf8().data());
945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        context->deleteShader(shader);
955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return 0;
965ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    }
975ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return shader;
985ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
995ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1005ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen// static
1012fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockunsigned Shader::loadProgram(GraphicsContext3D* context, const String& vertexShaderSource, const String& fragmentShaderSource)
1025ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1035ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource);
1045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (!vertexShader)
1055ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return 0;
1065ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    unsigned fragmentShader = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource);
1075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (!fragmentShader)
1085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return 0;
1095ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    unsigned program = context->createProgram();
1105ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (!program)
1115ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        return 0;
1125ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    context->attachShader(program, vertexShader);
1135ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    context->attachShader(program, fragmentShader);
1145ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    context->linkProgram(program);
115f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int linkStatus = 0;
1165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    context->getProgramiv(program, GraphicsContext3D::LINK_STATUS, &linkStatus);
1175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (!linkStatus)
1185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        context->deleteProgram(program);
1195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    context->deleteShader(vertexShader);
1205ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    context->deleteShader(fragmentShader);
1215ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return program;
1225ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1235ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1245ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenShader::Shader(GraphicsContext3D* context, unsigned program)
1255ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    : m_context(context)
1265ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    , m_program(program)
1275ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1285ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1295ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1305ddde30071f639962dd557c453f2ad01f8f0fd00Kristian MonsenShader::~Shader()
1315ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{
1325ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_context->deleteProgram(m_program);
1335ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
1345ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// static
1362fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockString Shader::generateVertex(Shader::VertexType vertexType, Shader::FillType fillType)
1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    StringBuilder builder;
1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    switch (vertexType) {
1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case TwoDimensional:
1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "uniform mat3 matrix;\n"
1432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            "attribute vec2 position;\n");
1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case LoopBlinnInterior:
1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "uniform mat4 worldViewProjection;\n"
1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "attribute vec2 position;\n");
1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case LoopBlinnExterior:
1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "uniform mat4 worldViewProjection;\n"
1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "attribute vec2 position;\n"
1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "attribute vec3 klm;\n"
1552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "varying vec3 v_klm;\n");
1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (fillType == TextureFill) {
1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
1612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "uniform mat3 texMatrix;\n"
1622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "varying vec3 texCoord;\n");
1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    builder.append(
1662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        "void main() {\n");
1672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (vertexType == TwoDimensional) {
1692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
1702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            "gl_Position = vec4(matrix * vec3(position, 1.0), 1.0);\n");
1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    } else {
1722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
1732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "gl_Position = worldViewProjection * vec4(position, 0.0, 1.0);\n");
1742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (vertexType == LoopBlinnExterior) {
1752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            builder.append(
1762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "v_klm = klm;\n");
1772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (fillType == TextureFill) {
1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
1822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            "texCoord = texMatrix * vec3(position, 1.0);\n");
1832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
1842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    builder.append(
1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        "}\n");
1872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return builder.toString();
1895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen}
190a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// static
1922fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockString Shader::generateFragment(Shader::VertexType vertexType, Shader::FillType fillType, Shader::AntialiasType antialiasType)
1932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
1942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    StringBuilder builder;
1952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    builder.append(
1962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        "#ifdef GL_ES\n"
1972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        "precision mediump float;\n"
1982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        "#endif\n");
1992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (vertexType == LoopBlinnExterior) {
2012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (antialiasType == Antialiased) {
2022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            builder.append(
2032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "#extension GL_OES_standard_derivatives : enable\n");
2042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
2052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
2062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "varying vec3 v_klm;\n");
2072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
2082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    switch (fillType) {
2102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case SolidFill:
2112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
2122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "uniform vec4 color;\n");
2132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
2142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case TextureFill:
2152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
2162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "uniform sampler2D sampler;\n"
2172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "uniform float globalAlpha;\n"
2182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "varying vec3 texCoord;\n");
2192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
2202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
2212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    builder.append(
2232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        "void main() {\n");
2242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (vertexType != LoopBlinnExterior) {
2262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
2272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "float alpha = 1.0;\n");
2282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    } else {
2292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (antialiasType == Antialiased) {
2302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            builder.append(
2312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  // Gradients\n"
2322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  vec3 px = dFdx(v_klm);\n"
2332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  vec3 py = dFdy(v_klm);\n"
2342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "\n"
2352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  // Chain rule\n"
2362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  float k2 = v_klm.x * v_klm.x;\n"
2372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  float c = k2 * v_klm.x - v_klm.y * v_klm.z;\n"
2382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  float k23 = 3.0 * k2;\n"
2392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  float cx = k23 * px.x - v_klm.z * px.y - v_klm.y * px.z;\n"
2402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  float cy = k23 * py.x - v_klm.z * py.y - v_klm.y * py.z;\n"
2412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "\n"
2422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  // Signed distance\n"
2432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  float sd = c / sqrt(cx * cx + cy * cy);\n"
2442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "\n"
2452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  // Linear alpha\n"
2462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  // FIXME: figure out why this needs to be\n"
2472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  // negated compared to the HLSL version, and also why\n"
2482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  // we need an adjustment by +1.0 for it to look good.\n"
2492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  // float alpha = clamp(0.5 - sd, 0.0, 1.0);\n"
2502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  float alpha = clamp(sd + 0.5, 0.0, 1.0);\n");
2512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        } else {
2522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            builder.append(
2532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  float t = v_klm.x * v_klm.x * v_klm.x - v_klm.y * v_klm.z;\n"
2542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                "  float alpha = clamp(sign(t), 0.0, 1.0);\n");
2552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
2562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
2572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    switch (fillType) {
2592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case SolidFill:
2602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
2612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "gl_FragColor = color * alpha;\n");
2622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
2632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    case TextureFill:
2642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        builder.append(
2652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            "gl_FragColor = texture2D(sampler, texCoord.xy) * alpha * globalAlpha;\n");
2662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        break;
2672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
2682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    builder.append(
2702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        "}\n");
2712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return builder.toString();
2732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
2742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} // namespace WebCore
2762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
277a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#endif
278