コード例 #1
0
ファイル: SkComposeShader.cpp プロジェクト: molikto/Skia
bool SkComposeShader::onAppendStages(const StageRec& rec) const {
    struct Storage {
        float   fRGBA[4 * SkJumper_kMaxStride];
        float   fAlpha;
    };
    auto storage = rec.fAlloc->make<Storage>();

    if (!as_SB(fSrc)->appendStages(rec)) {
        return false;
    }
    // This outputs r,g,b,a, which we'll need later when we apply the mode, but we save it off now
    // since fShaderB will overwrite them.
    rec.fPipeline->append(SkRasterPipeline::store_rgba, storage->fRGBA);

    if (!as_SB(fDst)->appendStages(rec)) {
        return false;
    }
    // We now have our logical 'dst' in r,g,b,a, but we need it in dr,dg,db,da for the mode/lerp
    // so we have to shuttle them. If we had a stage the would load_into_dst, then we could
    // reverse the two shader invocations, and avoid this move...
    rec.fPipeline->append(SkRasterPipeline::move_src_dst);
    rec.fPipeline->append(SkRasterPipeline::load_rgba, storage->fRGBA);

    if (!this->isJustLerp()) {
        SkBlendMode_AppendStages(fMode, rec.fPipeline);
    }
    if (!this->isJustMode()) {
        rec.fPipeline->append(SkRasterPipeline::lerp_1_float, &fLerpT);
    }
    return true;
}
コード例 #2
0
SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
                                           const SkPaint& paint,
                                           const SkMatrix& ctm,
                                           SkArenaAlloc* alloc) {
    auto blitter = alloc->make<SkRasterPipelineBlitter>(
            dst,
            paint.getBlendMode(),
            SkPM4f_from_SkColor(paint.getColor(), dst.colorSpace()));


    SkBlendMode*      blend       = &blitter->fBlend;
    SkPM4f*           paintColor  = &blitter->fPaintColor;
    SkRasterPipeline* pipeline    = &blitter->fShader;

    SkShader*      shader      = paint.getShader();
    SkColorFilter* colorFilter = paint.getColorFilter();

    // TODO: all temporary
    if (!supported(dst.info()) || !SkBlendMode_AppendStages(*blend)) {
        return nullptr;
    }

    bool is_opaque   = paintColor->a() == 1.0f,
         is_constant = true;
    if (shader) {
        pipeline->append(SkRasterPipeline::seed_shader, &blitter->fCurrentY);
        if (!shader->appendStages(pipeline, dst.colorSpace(), alloc, ctm, paint)) {
            return nullptr;
        }
        if (!is_opaque) {
            pipeline->append(SkRasterPipeline::scale_1_float,
                             &paintColor->fVec[SkPM4f::A]);
        }

        is_opaque   = is_opaque && shader->isOpaque();
        is_constant = shader->isConstant();
    } else {
        pipeline->append(SkRasterPipeline::constant_color, paintColor);
    }

    if (colorFilter) {
        if (!colorFilter->appendStages(pipeline, dst.colorSpace(), alloc, is_opaque)) {
            return nullptr;
        }
        is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
    }

    if (is_constant) {
        pipeline->append(SkRasterPipeline::store_f32, &paintColor);
        pipeline->run(0,1);

        *pipeline = SkRasterPipeline();
        pipeline->append(SkRasterPipeline::constant_color, paintColor);

        is_opaque = paintColor->a() == 1.0f;
    }

    if (is_opaque && *blend == SkBlendMode::kSrcOver) {
        *blend = SkBlendMode::kSrc;
    }

    if (is_constant && *blend == SkBlendMode::kSrc) {
        SkRasterPipeline p;
        p.extend(*pipeline);
        blitter->fDstPtr = &blitter->fMemsetColor;
        blitter->append_store(&p);
        p.run(0,1);

        blitter->fCanMemsetInBlitH = true;
    }

    return blitter;
}
コード例 #3
0
void SkRasterPipelineBlitter::append_blend(SkRasterPipeline* p) const {
    SkAssertResult(SkBlendMode_AppendStages(fBlend, p));
}