Exemple #1
0
void GrGLProgram::setData(const GrOptDrawState& optState,
                          GrGpu::DrawType drawType,
                          const GrDeviceCoordTexture* dstCopy) {
    GrColor color = optState.getColor();
    uint8_t coverage = optState.getCoverage();

    this->setColor(optState, color);
    this->setCoverage(optState, coverage);
    this->setMatrixAndRenderTargetHeight(drawType, optState);

    if (dstCopy) {
        if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) {
            fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyTopLeftUni,
                                       static_cast<GrGLfloat>(dstCopy->offset().fX),
                                       static_cast<GrGLfloat>(dstCopy->offset().fY));
            fProgramDataManager.set2f(fBuiltinUniformHandles.fDstCopyScaleUni,
                                       1.f / dstCopy->texture()->width(),
                                       1.f / dstCopy->texture()->height());
            GrGLTexture* texture = static_cast<GrGLTexture*>(dstCopy->texture());
            static GrTextureParams kParams; // the default is clamp, nearest filtering.
            fGpu->bindTexture(fDstCopyTexUnit, kParams, texture);
        } else {
            SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
            SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
        }
    } else {
        SkASSERT(!fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid());
        SkASSERT(!fBuiltinUniformHandles.fDstCopyScaleUni.isValid());
        SkASSERT(!fBuiltinUniformHandles.fDstCopySamplerUni.isValid());
    }

    // we set the textures, and uniforms for installed processors in a generic way, but subclasses
    // of GLProgram determine how to set coord transforms
    if (fGeometryProcessor.get()) {
        SkASSERT(optState.hasGeometryProcessor());
        const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
        fGeometryProcessor->fGLProc->setData(fProgramDataManager, gp);
        this->bindTextures(fGeometryProcessor, gp);
    }
    this->setFragmentData(optState);

    // Some of GrGLProgram subclasses need to update state here
    this->didSetData(drawType);
}
Exemple #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;
}