/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gl/GrGLXferProcessor.h"

#include "GrXferProcessor.h"
#include "gl/builders/GrGLFragmentShaderBuilder.h"
#include "gl/builders/GrGLProgramBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"

void GrGLXferProcessor::emitCode(const EmitArgs& args) {
    if (!args.fXP.willReadDstColor()) {
        this->emitOutputsForBlendState(args);
        return;
    }

    GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
    const char* dstColor = fsBuilder->dstColor();

    if (args.fXP.getDstTexture()) {
        bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin();

        if (args.fXP.readsCoverage()) {
            // We don't think any shaders actually output negative coverage, but just as a safety
            // check for floating point precision errors we compare with <= here
            fsBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
                                   "    discard;"
                                   "}", args.fInputCoverage);
        }

        const char* dstTopLeftName;
        const char* dstCoordScaleName;

        fDstTopLeftUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                              kVec2f_GrSLType,
                                              kDefault_GrSLPrecision,
                                              "DstTextureUpperLeft",
                                              &dstTopLeftName);
        fDstScaleUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
                                            kVec2f_GrSLType,
                                            kDefault_GrSLPrecision,
                                            "DstTextureCoordScale",
                                            &dstCoordScaleName);
        const char* fragPos = fsBuilder->fragmentPosition();

        fsBuilder->codeAppend("// Read color from copy of the destination.\n");
        fsBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
                               fragPos, dstTopLeftName, dstCoordScaleName);

        if (!topDown) {
            fsBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
        }

        fsBuilder->codeAppendf("vec4 %s = ", dstColor);
        fsBuilder->appendTextureLookup(args.fSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
        fsBuilder->codeAppend(";");
    }

    this->emitBlendCodeForDstRead(args.fPB, args.fInputColor, dstColor, args.fOutputPrimary,
                                  args.fXP);

    // Apply coverage.
    if (args.fXP.dstReadUsesMixedSamples()) {
        if (args.fXP.readsCoverage()) {
            fsBuilder->codeAppendf("%s *= %s;", args.fOutputPrimary, args.fInputCoverage);
            fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage);
        } else {
            fsBuilder->codeAppendf("%s = vec4(1.0);", args.fOutputSecondary);
        }
    } else if (args.fXP.readsCoverage()) {
        fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
                               args.fOutputPrimary, args.fInputCoverage,
                               args.fOutputPrimary, args.fInputCoverage, dstColor);
    }
}

void GrGLXferProcessor::setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) {
    if (xp.getDstTexture()) {
        if (fDstTopLeftUni.isValid()) {
            pdm.set2f(fDstTopLeftUni, static_cast<float>(xp.dstTextureOffset().fX),
                      static_cast<float>(xp.dstTextureOffset().fY));
            pdm.set2f(fDstScaleUni, 1.f / xp.getDstTexture()->width(),
                      1.f / xp.getDstTexture()->height());
        } else {
            SkASSERT(!fDstScaleUni.isValid());
        }
    } else {
        SkASSERT(!fDstTopLeftUni.isValid());
        SkASSERT(!fDstScaleUni.isValid());
    }
    this->onSetData(pdm, xp);
}

