Exemplo n.º 1
0
void GrGLProgram::setFragmentData(const GrOptDrawState& optState) {
    int numProcessors = fFragmentProcessors->fProcs.count();
    for (int e = 0; e < numProcessors; ++e) {
        const GrPendingFragmentStage& stage = optState.getFragmentStage(e);
        const GrProcessor& processor = *stage.getProcessor();
        fFragmentProcessors->fProcs[e]->fGLProc->setData(fProgramDataManager, processor);
        this->setTransformData(stage, fFragmentProcessors->fProcs[e]);
        this->bindTextures(fFragmentProcessors->fProcs[e], processor);
    }
}
Exemplo n.º 2
0
bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
                            const GrProgramDesc::DescInfo& descInfo,
                            GrGpu::DrawType drawType,
                            GrGpuGL* gpu,
                            const GrDeviceCoordTexture* dstCopy,
                            GrProgramDesc* desc) {
    bool inputColorIsUsed = descInfo.fInputColorIsUsed;
    bool inputCoverageIsUsed = descInfo.fInputCoverageIsUsed;

    // The descriptor is used as a cache key. Thus when a field of the
    // descriptor will not affect program generation (because of the attribute
    // bindings in use or other descriptor field settings) it should be set
    // to a canonical value to avoid duplicate programs with different keys.

    bool requiresLocalCoordAttrib = descInfo.fRequiresLocalCoordAttrib;

    int numStages = optState.numTotalStages();

    GR_STATIC_ASSERT(0 == kProcessorKeyOffsetsAndLengthOffset % sizeof(uint32_t));
    // Make room for everything up to and including the array of offsets to effect keys.
    desc->fKey.reset();
    desc->fKey.push_back_n(kProcessorKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * numStages);

    int offsetAndSizeIndex = 0;

    // We can only have one effect which touches the vertex shader
    if (optState.hasGeometryProcessor()) {
        if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(*optState.getGeometryProcessor(),
                                                                  gpu->glCaps(),
                                                                  false,
                                                                  desc,
                                                                  &offsetAndSizeIndex)) {
            return false;
        }
    }

    for (int s = 0; s < optState.numFragmentStages(); ++s) {
        if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getFragmentStage(s),
                                                                  gpu->glCaps(),
                                                                  requiresLocalCoordAttrib,
                                                                  desc,
                                                                  &offsetAndSizeIndex)) {
            return false;
        }
    }

    // --------DO NOT MOVE HEADER ABOVE THIS LINE--------------------------------------------------
    // Because header is a pointer into the dynamic array, we can't push any new data into the key
    // below here.
    GLKeyHeader* header = desc->atOffset<GLKeyHeader, kHeaderOffset>();

    // make sure any padding in the header is zeroed.
    memset(header, 0, kHeaderSize);

    header->fHasGeometryProcessor = optState.hasGeometryProcessor();

    header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType;

    bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType);
    if (gpu->caps()->pathRenderingSupport() && isPathRendering) {
        header->fUseNvpr = true;
        SkASSERT(!optState.hasGeometryProcessor());
    } else {
        header->fUseNvpr = false;
    }

    bool hasUniformColor = inputColorIsUsed &&
                           (isPathRendering || !descInfo.hasColorVertexAttribute());

    bool hasUniformCoverage = inputCoverageIsUsed &&
                              (isPathRendering || !descInfo.hasCoverageVertexAttribute());

    if (!inputColorIsUsed) {
        header->fColorInput = GrProgramDesc::kAllOnes_ColorInput;
    } else if (hasUniformColor) {
        header->fColorInput = GrProgramDesc::kUniform_ColorInput;
    } else {
        header->fColorInput = GrProgramDesc::kAttribute_ColorInput;
        SkASSERT(!header->fUseNvpr);
    }

    bool covIsSolidWhite = !descInfo.hasCoverageVertexAttribute() &&
                           0xffffffff == optState.getCoverageColor();

    if (covIsSolidWhite || !inputCoverageIsUsed) {
        header->fCoverageInput = GrProgramDesc::kAllOnes_ColorInput;
    } else if (hasUniformCoverage) {
        header->fCoverageInput = GrProgramDesc::kUniform_ColorInput;
    } else {
        header->fCoverageInput = GrProgramDesc::kAttribute_ColorInput;
        SkASSERT(!header->fUseNvpr);
    }

    if (descInfo.fReadsDst) {
        SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport());
        const GrTexture* dstCopyTexture = NULL;
        if (dstCopy) {
            dstCopyTexture = dstCopy->texture();
        }
        header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
                                                                       gpu->glCaps());
        SkASSERT(0 != header->fDstReadKey);
    } else {
        header->fDstReadKey = 0;
    }

    if (descInfo.fReadsFragPosition) {
        header->fFragPosKey =
                GrGLFragmentShaderBuilder::KeyForFragmentPosition(optState.getRenderTarget(),
                                                                  gpu->glCaps());
    } else {
        header->fFragPosKey = 0;
    }

    // Record attribute indices
    header->fPositionAttributeIndex = descInfo.positionAttributeIndex();
    header->fLocalCoordAttributeIndex = descInfo.localCoordAttributeIndex();

    // For constant color and coverage we need an attribute with an index beyond those already set
    int availableAttributeIndex = optState.getVertexAttribCount();
    if (descInfo.hasColorVertexAttribute()) {
        header->fColorAttributeIndex = descInfo.colorVertexAttributeIndex();
    } else if (GrProgramDesc::kAttribute_ColorInput == header->fColorInput) {
        SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
        header->fColorAttributeIndex = availableAttributeIndex;
        availableAttributeIndex++;
    } else {
        header->fColorAttributeIndex = -1;
    }

    if (descInfo.hasCoverageVertexAttribute()) {
        header->fCoverageAttributeIndex = descInfo.coverageVertexAttributeIndex();
    } else if (GrProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
        SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
        header->fCoverageAttributeIndex = availableAttributeIndex;
    } else {
        header->fCoverageAttributeIndex = -1;
    }

    header->fPrimaryOutputType = descInfo.fPrimaryOutputType;
    header->fSecondaryOutputType = descInfo.fSecondaryOutputType;

    header->fColorEffectCnt = optState.numColorStages();
    header->fCoverageEffectCnt = optState.numCoverageStages();
    desc->finalize();
    return true;
}