Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / builders / GrGLFragmentOnlyProgramBuilder.cpp
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 "GrGLFragmentOnlyProgramBuilder.h"
9 #include "../GrGpuGL.h"
10
11 GrGLFragmentOnlyProgramBuilder::GrGLFragmentOnlyProgramBuilder(GrGpuGL* gpu,
12                                                                const GrGLProgramDesc& desc)
13     : INHERITED(gpu, desc) {
14     SkASSERT(desc.getHeader().fUseFragShaderOnly);
15     SkASSERT(gpu->glCaps().pathRenderingSupport());
16     SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
17     SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
18 }
19
20 int GrGLFragmentOnlyProgramBuilder::addTexCoordSets(int count) {
21     int firstFreeCoordSet = fTexCoordSetCnt;
22     fTexCoordSetCnt += count;
23     SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fTexCoordSetCnt);
24     return firstFreeCoordSet;
25 }
26
27 void
28 GrGLFragmentOnlyProgramBuilder::createAndEmitEffects(const GrGeometryStage* geometryProcessor,
29                                                      const GrFragmentStage* colorStages[],
30                                                      const GrFragmentStage* coverageStages[],
31                                                      GrGLSLExpr4* inputColor,
32                                                      GrGLSLExpr4* inputCoverage) {
33     ///////////////////////////////////////////////////////////////////////////
34     // emit the per-effect code for both color and coverage effects
35
36     EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_EffectType);
37     fColorEffects.reset(this->onCreateAndEmitEffects(colorStages,
38                                                      this->desc().numColorEffects(),
39                                                      colorKeyProvider,
40                                                      inputColor));
41
42     EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCoverage_EffectType);
43     fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages,
44                                                         this->desc().numCoverageEffects(),
45                                                         coverageKeyProvider,
46                                                         inputCoverage));
47 }
48
49 GrGLProgramEffects* GrGLFragmentOnlyProgramBuilder::onCreateAndEmitEffects(
50         const GrFragmentStage* effectStages[], int effectCnt,
51         const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* inOutFSColor) {
52     fProgramEffects.reset(SkNEW_ARGS(GrGLPathTexGenProgramEffects, (effectCnt)));
53     this->INHERITED::createAndEmitEffects(effectStages,
54                                           effectCnt,
55                                           keyProvider,
56                                           inOutFSColor);
57     return fProgramEffects.detach();
58 }
59
60 void GrGLFragmentOnlyProgramBuilder::emitEffect(const GrProcessorStage& stage,
61                                                 const GrProcessorKey& key,
62                                                 const char* outColor,
63                                                 const char* inColor,
64                                                 int stageIndex) {
65     SkASSERT(fProgramEffects.get());
66     const GrProcessor& effect = *stage.getProcessor();
67
68     SkSTArray<2, GrGLProcessor::TransformedCoords> coords(effect.numTransforms());
69     SkSTArray<4, GrGLProcessor::TextureSampler> samplers(effect.numTextures());
70
71     this->setupPathTexGen(stage, &coords);
72     this->emitSamplers(effect, &samplers);
73
74     SkASSERT(fEffectEmitter);
75     GrGLProcessor* glEffect = fEffectEmitter->createGLInstance();
76     fProgramEffects->addEffect(glEffect);
77
78     GrGLFragmentShaderBuilder* fsBuilder = this->getFragmentShaderBuilder();
79     // Enclose custom code in a block to avoid namespace conflicts
80     SkString openBrace;
81     openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name());
82     fsBuilder->codeAppend(openBrace.c_str());
83
84     fEffectEmitter->emit(key, outColor, inColor, coords, samplers);
85
86     fsBuilder->codeAppend("\t}\n");
87 }
88
89 void GrGLFragmentOnlyProgramBuilder::setupPathTexGen(
90         const GrProcessorStage& effectStage, GrGLProcessor::TransformedCoordsArray* outCoords) {
91     int numTransforms = effectStage.getProcessor()->numTransforms();
92     int texCoordIndex = this->addTexCoordSets(numTransforms);
93
94     fProgramEffects->addTransforms(texCoordIndex);
95
96     SkString name;
97     for (int t = 0; t < numTransforms; ++t) {
98         GrSLType type =
99                 effectStage.isPerspectiveCoordTransform(t, false) ?
100                         kVec3f_GrSLType :
101                         kVec2f_GrSLType;
102
103         name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++);
104         SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, (name, type));
105     }
106 }