LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu/gl/builders - GrGLProgramBuilder.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 115 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "GrGLProgramBuilder.h"
       9             : 
      10             : #include "GrAutoLocaleSetter.h"
      11             : #include "GrCoordTransform.h"
      12             : #include "GrGLProgramBuilder.h"
      13             : #include "GrProgramDesc.h"
      14             : #include "GrShaderCaps.h"
      15             : #include "GrSwizzle.h"
      16             : #include "GrTexture.h"
      17             : #include "SkAutoMalloc.h"
      18             : #include "SkATrace.h"
      19             : #include "SkTraceEvent.h"
      20             : #include "gl/GrGLGpu.h"
      21             : #include "gl/GrGLProgram.h"
      22             : #include "gl/GrGLSLPrettyPrint.h"
      23             : #include "gl/builders/GrGLShaderStringBuilder.h"
      24             : #include "glsl/GrGLSLFragmentProcessor.h"
      25             : #include "glsl/GrGLSLGeometryProcessor.h"
      26             : #include "glsl/GrGLSLProgramDataManager.h"
      27             : #include "glsl/GrGLSLXferProcessor.h"
      28             : 
      29             : #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
      30             : #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
      31             : 
      32           0 : GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrPipeline& pipeline,
      33             :                                                const GrPrimitiveProcessor& primProc,
      34             :                                                GrProgramDesc* desc,
      35             :                                                GrGLGpu* gpu) {
      36             :     ATRACE_ANDROID_FRAMEWORK("Shader Compile");
      37           0 :     GrAutoLocaleSetter als("C");
      38             : 
      39             :     // create a builder.  This will be handed off to effects so they can use it to add
      40             :     // uniforms, varyings, textures, etc
      41           0 :     GrGLProgramBuilder builder(gpu, pipeline, primProc, desc);
      42             : 
      43             :     // TODO: Once all stages can handle taking a float or vec4 and correctly handling them we can
      44             :     // seed correctly here
      45           0 :     GrGLSLExpr4 inputColor;
      46           0 :     GrGLSLExpr4 inputCoverage;
      47             : 
      48           0 :     if (!builder.emitAndInstallProcs(&inputColor, &inputCoverage)) {
      49           0 :         builder.cleanupFragmentProcessors();
      50           0 :         return nullptr;
      51             :     }
      52             : 
      53           0 :     return builder.finalize();
      54             : }
      55             : 
      56             : /////////////////////////////////////////////////////////////////////////////
      57             : 
      58           0 : GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu,
      59             :                                        const GrPipeline& pipeline,
      60             :                                        const GrPrimitiveProcessor& primProc,
      61           0 :                                        GrProgramDesc* desc)
      62             :     : INHERITED(pipeline, primProc, desc)
      63             :     , fGpu(gpu)
      64             :     , fVaryingHandler(this)
      65           0 :     , fUniformHandler(this) {
      66           0 : }
      67             : 
      68           0 : const GrCaps* GrGLProgramBuilder::caps() const {
      69           0 :     return fGpu->caps();
      70             : }
      71             : 
      72           0 : bool GrGLProgramBuilder::compileAndAttachShaders(GrGLSLShaderBuilder& shader,
      73             :                                                  GrGLuint programId,
      74             :                                                  GrGLenum type,
      75             :                                                  SkTDArray<GrGLuint>* shaderIds,
      76             :                                                  const SkSL::Program::Settings& settings,
      77             :                                                  SkSL::Program::Inputs* outInputs) {
      78           0 :     GrGLGpu* gpu = this->gpu();
      79           0 :     GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(),
      80             :                                                    programId,
      81             :                                                    type,
      82             :                                                    shader.fCompilerStrings.begin(),
      83             :                                                    shader.fCompilerStringLengths.begin(),
      84             :                                                    shader.fCompilerStrings.count(),
      85             :                                                    gpu->stats(),
      86             :                                                    settings,
      87           0 :                                                    outInputs);
      88             : 
      89           0 :     if (!shaderId) {
      90           0 :         return false;
      91             :     }
      92             : 
      93           0 :     *shaderIds->append() = shaderId;
      94           0 :     if (outInputs->fFlipY) {
      95           0 :         GrProgramDesc* d = this->desc();
      96           0 :         d->setSurfaceOriginKey(GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(
      97           0 :                                                      this->pipeline().getRenderTarget()->origin()));
      98           0 :         d->finalize();
      99             :     }
     100             : 
     101           0 :     return true;
     102             : }
     103             : 
     104           0 : GrGLProgram* GrGLProgramBuilder::finalize() {
     105             :     // verify we can get a program id
     106             :     GrGLuint programID;
     107           0 :     GL_CALL_RET(programID, CreateProgram());
     108           0 :     if (0 == programID) {
     109           0 :         this->cleanupFragmentProcessors();
     110           0 :         return nullptr;
     111             :     }
     112             : 
     113           0 :     this->finalizeShaders();
     114             : 
     115             :     // compile shaders and bind attributes / uniforms
     116           0 :     SkSL::Program::Settings settings;
     117           0 :     settings.fCaps = this->gpu()->glCaps().shaderCaps();
     118           0 :     settings.fFlipY = this->pipeline().getRenderTarget()->origin() != kTopLeft_GrSurfaceOrigin;
     119             :     SkSL::Program::Inputs inputs;
     120           0 :     SkTDArray<GrGLuint> shadersToDelete;
     121           0 :     if (!this->compileAndAttachShaders(fVS, programID, GR_GL_VERTEX_SHADER, &shadersToDelete,
     122             :                                        settings, &inputs)) {
     123           0 :         this->cleanupProgram(programID, shadersToDelete);
     124           0 :         return nullptr;
     125             :     }
     126             : 
     127             :     // NVPR actually requires a vertex shader to compile
     128           0 :     const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
     129           0 :     bool useNvpr = primProc.isPathRendering();
     130           0 :     if (!useNvpr) {
     131           0 :         int vaCount = primProc.numAttribs();
     132           0 :         for (int i = 0; i < vaCount; i++) {
     133           0 :             GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName));
     134             :         }
     135             :     }
     136             : 
     137           0 :     if (primProc.willUseGeoShader() &&
     138           0 :         !this->compileAndAttachShaders(fGS, programID, GR_GL_GEOMETRY_SHADER, &shadersToDelete,
     139             :                                        settings, &inputs)) {
     140           0 :         this->cleanupProgram(programID, shadersToDelete);
     141           0 :         return nullptr;
     142             :     }
     143             : 
     144           0 :     if (!this->compileAndAttachShaders(fFS, programID, GR_GL_FRAGMENT_SHADER, &shadersToDelete,
     145             :                                        settings, &inputs)) {
     146           0 :         this->cleanupProgram(programID, shadersToDelete);
     147           0 :         return nullptr;
     148             :     }
     149             : 
     150           0 :     if (inputs.fRTHeight) {
     151           0 :         this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
     152             :     }
     153             : 
     154           0 :     this->bindProgramResourceLocations(programID);
     155             : 
     156           0 :     GL_CALL(LinkProgram(programID));
     157             : 
     158             :     // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
     159           0 :     bool checkLinked = kChromium_GrGLDriver != fGpu->ctxInfo().driver();
     160             : #ifdef SK_DEBUG
     161           0 :     checkLinked = true;
     162             : #endif
     163           0 :     if (checkLinked) {
     164           0 :         checkLinkStatus(programID);
     165             :     }
     166           0 :     this->resolveProgramResourceLocations(programID);
     167             : 
     168           0 :     this->cleanupShaders(shadersToDelete);
     169             : 
     170           0 :     return this->createProgram(programID);
     171             : }
     172             : 
     173           0 : void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) {
     174           0 :     fUniformHandler.bindUniformLocations(programID, fGpu->glCaps());
     175             : 
     176           0 :     const GrGLCaps& caps = this->gpu()->glCaps();
     177           0 :     if (fFS.hasCustomColorOutput() && caps.bindFragDataLocationSupport()) {
     178           0 :         GL_CALL(BindFragDataLocation(programID, 0,
     179             :                                      GrGLSLFragmentShaderBuilder::DeclaredColorOutputName()));
     180             :     }
     181           0 :     if (fFS.hasSecondaryOutput() && caps.shaderCaps()->mustDeclareFragmentShaderOutput()) {
     182           0 :         GL_CALL(BindFragDataLocationIndexed(programID, 0, 1,
     183             :                                   GrGLSLFragmentShaderBuilder::DeclaredSecondaryColorOutputName()));
     184             :     }
     185             : 
     186             :     // handle NVPR separable varyings
     187           0 :     if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() ||
     188           0 :         !fGpu->glPathRendering()->shouldBindFragmentInputs()) {
     189           0 :         return;
     190             :     }
     191           0 :     int count = fVaryingHandler.fPathProcVaryingInfos.count();
     192           0 :     for (int i = 0; i < count; ++i) {
     193           0 :         GL_CALL(BindFragmentInputLocation(programID, i,
     194             :                                        fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str()));
     195           0 :         fVaryingHandler.fPathProcVaryingInfos[i].fLocation = i;
     196             :     }
     197             : }
     198             : 
     199           0 : bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
     200           0 :     GrGLint linked = GR_GL_INIT_ZERO;
     201           0 :     GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
     202           0 :     if (!linked) {
     203           0 :         GrGLint infoLen = GR_GL_INIT_ZERO;
     204           0 :         GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
     205           0 :         SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
     206           0 :         if (infoLen > 0) {
     207             :             // retrieve length even though we don't need it to workaround
     208             :             // bug in chrome cmd buffer param validation.
     209           0 :             GrGLsizei length = GR_GL_INIT_ZERO;
     210           0 :             GL_CALL(GetProgramInfoLog(programID,
     211             :                                       infoLen+1,
     212             :                                       &length,
     213             :                                       (char*)log.get()));
     214           0 :             SkDebugf("%s", (char*)log.get());
     215             :         }
     216           0 :         SkDEBUGFAIL("Error linking program");
     217           0 :         GL_CALL(DeleteProgram(programID));
     218           0 :         programID = 0;
     219             :     }
     220           0 :     return SkToBool(linked);
     221             : }
     222             : 
     223           0 : void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) {
     224           0 :     fUniformHandler.getUniformLocations(programID, fGpu->glCaps());
     225             : 
     226             :     // handle NVPR separable varyings
     227           0 :     if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() ||
     228           0 :         fGpu->glPathRendering()->shouldBindFragmentInputs()) {
     229           0 :         return;
     230             :     }
     231           0 :     int count = fVaryingHandler.fPathProcVaryingInfos.count();
     232           0 :     for (int i = 0; i < count; ++i) {
     233             :         GrGLint location;
     234           0 :         GL_CALL_RET(location, GetProgramResourceLocation(
     235             :                                        programID,
     236             :                                        GR_GL_FRAGMENT_INPUT,
     237             :                                        fVaryingHandler.fPathProcVaryingInfos[i].fVariable.c_str()));
     238           0 :         fVaryingHandler.fPathProcVaryingInfos[i].fLocation = location;
     239             :     }
     240             : }
     241             : 
     242           0 : void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs) {
     243           0 :     GL_CALL(DeleteProgram(programID));
     244           0 :     this->cleanupShaders(shaderIDs);
     245           0 :     this->cleanupFragmentProcessors();
     246           0 : }
     247           0 : void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
     248           0 :     for (int i = 0; i < shaderIDs.count(); ++i) {
     249           0 :       GL_CALL(DeleteShader(shaderIDs[i]));
     250             :     }
     251           0 : }
     252             : 
     253           0 : GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
     254             :     return new GrGLProgram(fGpu,
     255           0 :                            *this->desc(),
     256             :                            fUniformHandles,
     257             :                            programID,
     258             :                            fUniformHandler.fUniforms,
     259             :                            fUniformHandler.fSamplers,
     260             :                            fUniformHandler.fImageStorages,
     261             :                            fVaryingHandler.fPathProcVaryingInfos,
     262             :                            fGeometryProcessor,
     263             :                            fXferProcessor,
     264           0 :                            fFragmentProcessors);
     265             : }

Generated by: LCOV version 1.13