Exemplo n.º 1
0
void GrOptDrawState::getStageStats() {
    // We will need a local coord attrib if there is one currently set on the optState and we are
    // actually generating some effect code
    fRequiresLocalCoordAttrib = this->hasLocalCoordAttribute() && this->numTotalStages() > 0;

    fReadsDst = false;
    fReadsFragPosition = false;

    for (int s = 0; s < this->numColorStages(); ++s) {
        const GrFragmentStage& stage = this->getColorStage(s);
        get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
    }
    for (int s = 0; s < this->numCoverageStages(); ++s) {
        const GrFragmentStage& stage = this->getCoverageStage(s);
        get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
    }
    if (this->hasGeometryProcessor()) {
        const GrGeometryStage& stage = *this->getGeometryProcessor();
        fReadsFragPosition = fReadsFragPosition || stage.getProcessor()->willReadFragmentPosition();
    }
}
Exemplo n.º 2
0
bool GrGLProgramDesc::setRandom(SkRandom* random,
                                GrGpuGL* gpu,
                                const GrRenderTarget* dstRenderTarget,
                                const GrTexture* dstCopyTexture,
                                const GrGeometryStage* geometryProcessor,
                                const GrFragmentStage* stages[],
                                int numColorStages,
                                int numCoverageStages,
                                int currAttribIndex,
                                GrGpu::DrawType drawType) {
    bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType);
    bool useLocalCoords = !isPathRendering &&
                          random->nextBool() &&
                          currAttribIndex < GrDrawState::kMaxVertexAttribCnt;

    int numStages = numColorStages + numCoverageStages;
    fKey.reset();

    GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t));

    // Make room for everything up to and including the array of offsets to effect keys.
    fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * (numStages +
            (geometryProcessor ? 1 : 0)));

    bool dstRead = false;
    bool fragPos = false;
    bool vertexShader = SkToBool(geometryProcessor);
    int offset = 0;
    if (geometryProcessor) {
        const GrGeometryStage* stage = geometryProcessor;
        uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() +
                                                              kEffectKeyOffsetsAndLengthOffset +
                                                              offset * 2 * sizeof(uint16_t));
        uint32_t effectKeyOffset = fKey.count();
        if (effectKeyOffset > SK_MaxU16) {
            fKey.reset();
            return false;
        }
        GrProcessorKeyBuilder b(&fKey);
        uint16_t effectKeySize;
        if (!GetProcessorKey(*stage, gpu->glCaps(), useLocalCoords, &b, &effectKeySize)) {
            fKey.reset();
            return false;
        }
        vertexShader = true;
        fragPos = stage->getProcessor()->willReadFragmentPosition();
        offsetAndSize[0] = effectKeyOffset;
        offsetAndSize[1] = effectKeySize;
        offset++;
    }

    for (int s = 0; s < numStages; ++s, ++offset) {
        const GrFragmentStage* stage = stages[s];
        uint16_t* offsetAndSize = reinterpret_cast<uint16_t*>(fKey.begin() +
                                                              kEffectKeyOffsetsAndLengthOffset +
                                                              offset * 2 * sizeof(uint16_t));
        uint32_t effectKeyOffset = fKey.count();
        if (effectKeyOffset > SK_MaxU16) {
            fKey.reset();
            return false;
        }
        GrProcessorKeyBuilder b(&fKey);
        uint16_t effectKeySize;
        if (!GetProcessorKey(*stages[s], gpu->glCaps(), useLocalCoords, &b, &effectKeySize)) {
            fKey.reset();
            return false;
        }
        get_stage_stats(*stage, &dstRead, &fragPos, &vertexShader);
        offsetAndSize[0] = effectKeyOffset;
        offsetAndSize[1] = effectKeySize;
    }

    KeyHeader* header = this->header();
    memset(header, 0, kHeaderSize);
    header->fEmitsPointSize = random->nextBool();

    header->fPositionAttributeIndex = 0;

    // if the effects have used up all off the available attributes,
    // don't try to use color or coverage attributes as input
    do {
        header->fColorInput = static_cast<GrGLProgramDesc::ColorInput>(
                                     random->nextULessThan(kColorInputCnt));
    } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRendering) &&
             kAttribute_ColorInput == header->fColorInput);
    header->fColorAttributeIndex = (header->fColorInput == kAttribute_ColorInput) ?
                                        currAttribIndex++ :
                                        -1;

    do {
        header->fCoverageInput = static_cast<GrGLProgramDesc::ColorInput>(
                                     random->nextULessThan(kColorInputCnt));
    } while ((GrDrawState::kMaxVertexAttribCnt <= currAttribIndex || isPathRendering)  &&
             kAttribute_ColorInput == header->fCoverageInput);
    header->fCoverageAttributeIndex = (header->fCoverageInput == kAttribute_ColorInput) ?
                                        currAttribIndex++ :
                                        -1;
    bool useGS = random->nextBool();
#if GR_GL_EXPERIMENTAL_GS
    header->fExperimentalGS = gpu->caps()->geometryShaderSupport() && useGS;
#else
    (void) useGS;
#endif

    header->fLocalCoordAttributeIndex = useLocalCoords ? currAttribIndex++ : -1;

    header->fColorEffectCnt = numColorStages;
    header->fCoverageEffectCnt = numCoverageStages;

    if (dstRead) {
        header->fDstReadKey = SkToU8(GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
                                                                      gpu->glCaps()));
    } else {
        header->fDstReadKey = 0;
    }
    if (fragPos) {
        header->fFragPosKey = SkToU8(GrGLFragmentShaderBuilder::KeyForFragmentPosition(dstRenderTarget,
                                                                               gpu->glCaps()));
    } else {
        header->fFragPosKey = 0;
    }

    header->fUseFragShaderOnly = isPathRendering && gpu->glPathRendering()->texturingMode() ==
                                                    GrGLPathRendering::FixedFunction_TexturingMode;
    header->fHasGeometryProcessor = vertexShader;

    GrOptDrawState::PrimaryOutputType primaryOutput;
    GrOptDrawState::SecondaryOutputType secondaryOutput;
    if (!dstRead) {
        primaryOutput = GrOptDrawState::kModulate_PrimaryOutputType;
    } else {
        primaryOutput = static_cast<GrOptDrawState::PrimaryOutputType>(
            random->nextULessThan(GrOptDrawState::kPrimaryOutputTypeCnt));
    }

    if (GrOptDrawState::kCombineWithDst_PrimaryOutputType == primaryOutput ||
        !gpu->caps()->dualSourceBlendingSupport()) {
        secondaryOutput = GrOptDrawState::kNone_SecondaryOutputType;
    } else {
        secondaryOutput = static_cast<GrOptDrawState::SecondaryOutputType>(
            random->nextULessThan(GrOptDrawState::kSecondaryOutputTypeCnt));
    }

    header->fPrimaryOutputType = primaryOutput;
    header->fSecondaryOutputType = secondaryOutput;

    this->finalize();
    return true;
}