GrGLSLXferProcessor.cpp revision 7ea439b2203855db97330b25945b87dd4b170b8b
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 "GrXferProcessor.h" 11#include "glsl/GrGLSLFragmentShaderBuilder.h" 12#include "glsl/GrGLSLProgramDataManager.h" 13#include "glsl/GrGLSLUniformHandler.h" 14 15void GrGLSLXferProcessor::emitCode(const EmitArgs& args) { 16 if (!args.fXP.willReadDstColor()) { 17 this->emitOutputsForBlendState(args); 18 return; 19 } 20 21 GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder; 22 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 23 const char* dstColor = fragBuilder->dstColor(); 24 25 if (args.fXP.getDstTexture()) { 26 bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin(); 27 28 if (args.fInputCoverage) { 29 // We don't think any shaders actually output negative coverage, but just as a safety 30 // check for floating point precision errors we compare with <= here 31 fragBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {" 32 " discard;" 33 "}", args.fInputCoverage); 34 } 35 36 const char* dstTopLeftName; 37 const char* dstCoordScaleName; 38 39 fDstTopLeftUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility, 40 kVec2f_GrSLType, 41 kDefault_GrSLPrecision, 42 "DstTextureUpperLeft", 43 &dstTopLeftName); 44 fDstScaleUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFragment_Visibility, 45 kVec2f_GrSLType, 46 kDefault_GrSLPrecision, 47 "DstTextureCoordScale", 48 &dstCoordScaleName); 49 const char* fragPos = fragBuilder->fragmentPosition(); 50 51 fragBuilder->codeAppend("// Read color from copy of the destination.\n"); 52 fragBuilder->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;", 53 fragPos, dstTopLeftName, dstCoordScaleName); 54 55 if (!topDown) { 56 fragBuilder->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;"); 57 } 58 59 fragBuilder->codeAppendf("vec4 %s = ", dstColor); 60 fragBuilder->appendTextureLookup(args.fSamplers[0], "_dstTexCoord", kVec2f_GrSLType); 61 fragBuilder->codeAppend(";"); 62 } 63 64 this->emitBlendCodeForDstRead(fragBuilder, 65 uniformHandler, 66 args.fInputColor, 67 args.fInputCoverage, 68 dstColor, 69 args.fOutputPrimary, 70 args.fOutputSecondary, 71 args.fXP); 72} 73 74void GrGLSLXferProcessor::setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) { 75 if (xp.getDstTexture()) { 76 if (fDstTopLeftUni.isValid()) { 77 pdm.set2f(fDstTopLeftUni, static_cast<float>(xp.dstTextureOffset().fX), 78 static_cast<float>(xp.dstTextureOffset().fY)); 79 pdm.set2f(fDstScaleUni, 1.f / xp.getDstTexture()->width(), 80 1.f / xp.getDstTexture()->height()); 81 } else { 82 SkASSERT(!fDstScaleUni.isValid()); 83 } 84 } else { 85 SkASSERT(!fDstTopLeftUni.isValid()); 86 SkASSERT(!fDstScaleUni.isValid()); 87 } 88 this->onSetData(pdm, xp); 89} 90 91