Home | History | Annotate | Download | only in glsl
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "glsl/GrGLSLXferProcessor.h"
      9 
     10 #include "GrShaderCaps.h"
     11 #include "GrXferProcessor.h"
     12 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     13 #include "glsl/GrGLSLProgramDataManager.h"
     14 #include "glsl/GrGLSLUniformHandler.h"
     15 
     16 void GrGLSLXferProcessor::emitCode(const EmitArgs& args) {
     17     if (!args.fXP.willReadDstColor()) {
     18         this->emitOutputsForBlendState(args);
     19         return;
     20     }
     21 
     22     GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
     23     GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
     24     const char* dstColor = fragBuilder->dstColor();
     25 
     26     bool needsLocalOutColor = false;
     27 
     28     if (args.fXP.getDstTexture()) {
     29         bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin();
     30 
     31         if (args.fInputCoverage) {
     32             // We don't think any shaders actually output negative coverage, but just as a safety
     33             // check for floating point precision errors we compare with <= here
     34             fragBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
     35                                      "    discard;"
     36                                      "}", args.fInputCoverage);
     37         }
     38 
     39         const char* dstTopLeftName;
     40         const char* dstCoordScaleName;
     41 
     42         fDstTopLeftUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
     43                                                     kVec2f_GrSLType,
     44                                                     kDefault_GrSLPrecision,
     45                                                     "DstTextureUpperLeft",
     46                                                     &dstTopLeftName);
     47         fDstScaleUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
     48                                                   kVec2f_GrSLType,
     49                                                   kDefault_GrSLPrecision,
     50                                                   "DstTextureCoordScale",
     51                                                   &dstCoordScaleName);
     52 
     53         fragBuilder->codeAppend("// Read color from copy of the destination.\n");
     54         fragBuilder->codeAppendf("vec2 _dstTexCoord = (sk_FragCoord.xy - %s) * %s;",
     55                                  dstTopLeftName, dstCoordScaleName);
     56 
     57         if (!topDown) {
     58             fragBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
     59         }
     60 
     61         fragBuilder->codeAppendf("vec4 %s = ", dstColor);
     62         fragBuilder->appendTextureLookup(args.fTexSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
     63         fragBuilder->codeAppend(";");
     64     } else {
     65         needsLocalOutColor = args.fShaderCaps->requiresLocalOutputColorForFBFetch();
     66     }
     67 
     68     const char* outColor = "_localColorOut";
     69     if (!needsLocalOutColor) {
     70         outColor = args.fOutputPrimary;
     71     } else {
     72         fragBuilder->codeAppendf("vec4 %s;", outColor);
     73     }
     74 
     75     this->emitBlendCodeForDstRead(fragBuilder,
     76                                   uniformHandler,
     77                                   args.fInputColor,
     78                                   args.fInputCoverage,
     79                                   dstColor,
     80                                   outColor,
     81                                   args.fOutputSecondary,
     82                                   args.fXP);
     83     if (needsLocalOutColor) {
     84         fragBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, outColor);
     85     }
     86 }
     87 
     88 void GrGLSLXferProcessor::setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) {
     89     if (xp.getDstTexture()) {
     90         if (fDstTopLeftUni.isValid()) {
     91             pdm.set2f(fDstTopLeftUni, static_cast<float>(xp.dstTextureOffset().fX),
     92                       static_cast<float>(xp.dstTextureOffset().fY));
     93             pdm.set2f(fDstScaleUni, 1.f / xp.getDstTexture()->width(),
     94                       1.f / xp.getDstTexture()->height());
     95         } else {
     96             SkASSERT(!fDstScaleUni.isValid());
     97         }
     98     } else {
     99         SkASSERT(!fDstTopLeftUni.isValid());
    100         SkASSERT(!fDstScaleUni.isValid());
    101     }
    102     this->onSetData(pdm, xp);
    103 }
    104 
    105 void GrGLSLXferProcessor::DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fragBuilder,
    106                                                     const char* srcCoverage,
    107                                                     const char* dstColor,
    108                                                     const char* outColor,
    109                                                     const char* outColorSecondary,
    110                                                     const GrXferProcessor& proc) {
    111     if (proc.dstReadUsesMixedSamples()) {
    112         if (srcCoverage) {
    113             fragBuilder->codeAppendf("%s *= %s;", outColor, srcCoverage);
    114             fragBuilder->codeAppendf("%s = %s;", outColorSecondary, srcCoverage);
    115         } else {
    116             fragBuilder->codeAppendf("%s = vec4(1.0);", outColorSecondary);
    117         }
    118     } else if (srcCoverage) {
    119         fragBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
    120                                  outColor, srcCoverage, outColor, srcCoverage, dstColor);
    121     }
    122 }
    123