Example #1
0
 bool willUseFilterColor() const {
     SkXfermode::Coeff dstCoeff;
     SkXfermode::Coeff srcCoeff;
     SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff));
     if (SkXfermode::kZero_Coeff == srcCoeff) {
         return GrBlendCoeffRefsSrc(sk_blend_to_grblend(dstCoeff));
     }
     return true;
 }
Example #2
0
void ModeColorFilterEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const {
    float inputColor[4];
    GrColorToRGBAFloat(inout->color(), inputColor);
    float filterColor[4];
    GrColorToRGBAFloat(fColor, filterColor);
    MaskedColorExpr result =
        color_filter_expression(fMode,
                                MaskedColorExpr(filterColor, kRGBA_GrColorComponentFlags),
                                MaskedColorExpr(inputColor, inout->validFlags()));

    // Check if we will use the input color
    SkXfermode::Coeff dstCoeff;
    SkXfermode::Coeff srcCoeff;
    SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff));
    GrInvariantOutput::ReadInput readInput = GrInvariantOutput::kWill_ReadInput;
    // These could be calculated from the blend equation with template trickery..
    if (SkXfermode::kZero_Coeff == dstCoeff &&
        !GrBlendCoeffRefsDst(sk_blend_to_grblend(srcCoeff))) {
        readInput = GrInvariantOutput::kWillNot_ReadInput;
    }
    inout->setToOther(result.getValidComponents(), result.getColor(), readInput);
}
bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
                                           const SkBitmap& src,
                                           const SkMatrix& ctm,
                                           SkBitmap* result,
                                           SkIPoint* offset) {
    SkBitmap background;
    SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
    if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &background,
                                               &backgroundOffset)) {
        return false;
    }
    GrTexture* backgroundTex = background.getTexture();
    SkBitmap foreground;
    SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
    if (!SkImageFilterUtils::GetInputResultGPU(getInput(1), proxy, src, ctm, &foreground,
                                               &foregroundOffset)) {
        return false;
    }
    GrTexture* foregroundTex = foreground.getTexture();
    GrContext* context = foregroundTex->getContext();

    GrEffectRef* xferEffect = NULL;

    GrTextureDesc desc;
    desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
    desc.fWidth = src.width();
    desc.fHeight = src.height();
    desc.fConfig = kSkia8888_GrPixelConfig;

    GrAutoScratchTexture ast(context, desc);
    SkAutoTUnref<GrTexture> dst(ast.detach());

    GrContext::AutoRenderTarget art(context, dst->asRenderTarget());

    SkXfermode::Coeff sm, dm;
    if (!SkXfermode::AsNewEffectOrCoeff(fMode, &xferEffect, &sm, &dm, backgroundTex)) {
        return false;
    }

    SkMatrix foregroundMatrix = GrEffect::MakeDivByTextureWHMatrix(foregroundTex);
    foregroundMatrix.preTranslate(SkIntToScalar(backgroundOffset.fX-foregroundOffset.fX),
                                  SkIntToScalar(backgroundOffset.fY-foregroundOffset.fY));


    SkRect srcRect;
    src.getBounds(&srcRect);
    if (NULL != xferEffect) {
        GrPaint paint;
        paint.addColorTextureEffect(foregroundTex, foregroundMatrix);
        paint.addColorEffect(xferEffect)->unref();
        context->drawRect(paint, srcRect);
    } else {
        GrPaint backgroundPaint;
        SkMatrix backgroundMatrix = GrEffect::MakeDivByTextureWHMatrix(backgroundTex);
        backgroundPaint.addColorTextureEffect(backgroundTex, backgroundMatrix);
        context->drawRect(backgroundPaint, srcRect);

        GrPaint foregroundPaint;
        foregroundPaint.setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
        foregroundPaint.addColorTextureEffect(foregroundTex, foregroundMatrix);
        context->drawRect(foregroundPaint, srcRect);
    }
    offset->fX += backgroundOffset.fX;
    offset->fY += backgroundOffset.fY;
    return SkImageFilterUtils::WrapTexture(dst, src.width(), src.height(), result);
}