Ejemplo n.º 1
0
SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
                                         const SkPaint& paint,
                                         const SkMatrix& ctm,
                                         SkArenaAlloc* alloc) {
    SkColorSpace* dstCS = dst.colorSpace();
    SkPM4f paintColor = SkPM4f_from_SkColor(paint.getColor(), dstCS);
    auto shader = as_SB(paint.getShader());

    SkRasterPipeline_<256> shaderPipeline;
    if (!shader) {
        // Having no shader makes things nice and easy... just use the paint color.
        shaderPipeline.append_uniform_color(alloc, paintColor);
        bool is_opaque    = paintColor.a() == 1.0f,
             is_constant  = true;
        return SkRasterPipelineBlitter::Create(dst, paint, alloc,
                                               shaderPipeline, nullptr,
                                               is_opaque, is_constant);
    }

    bool is_opaque    = shader->isOpaque() && paintColor.a() == 1.0f;
    bool is_constant  = shader->isConstant();

    // Check whether the shader prefers to run in burst mode.
    if (auto* burstCtx = shader->makeBurstPipelineContext(
        SkShaderBase::ContextRec(paint, ctm, nullptr, SkShaderBase::ContextRec::kPM4f_DstType,
                                 dstCS), alloc)) {
        return SkRasterPipelineBlitter::Create(dst, paint, alloc,
                                               shaderPipeline, burstCtx,
                                               is_opaque, is_constant);
    }

    if (shader->appendStages(&shaderPipeline, dstCS, alloc, ctm, paint)) {
        if (paintColor.a() != 1.0f) {
            shaderPipeline.append(SkRasterPipeline::scale_1_float,
                                  alloc->make<float>(paintColor.a()));
        }
        return SkRasterPipelineBlitter::Create(dst, paint, alloc, shaderPipeline, nullptr,
                                               is_opaque, is_constant);
    }

    // The shader has opted out of drawing anything.
    return alloc->make<SkNullBlitter>();
}
Ejemplo n.º 2
0
bool SkColorShader::onAppendStages(const StageRec& rec) const {
    rec.fPipeline->append_constant_color(rec.fAlloc, SkPM4f_from_SkColor(fColor, rec.fDstCS));
    return true;
}
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;
}