void inline_cnstr_jobdesc_hash(uint32_t *desc, const uint8_t *msg, uint32_t msgsz, uint8_t *digest, u32 alg_type, uint32_t alg_size, int sg_tbl) { /* SHA 256 , output is of length 32 words */ uint32_t storelen = alg_size; u32 options; dma_addr_t dma_addr_in, dma_addr_out; dma_addr_in = virt_to_phys((void *)msg); dma_addr_out = virt_to_phys((void *)digest); init_job_desc(desc, 0); append_operation(desc, OP_TYPE_CLASS2_ALG | OP_ALG_AAI_HASH | OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT | OP_ALG_ICV_OFF | alg_type); options = LDST_CLASS_2_CCB | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2; if (sg_tbl) options |= FIFOLDST_SGF; if (msgsz > 0xffff) { options |= FIFOLDST_EXT; append_fifo_load(desc, dma_addr_in, 0, options); append_cmd(desc, msgsz); } else { append_fifo_load(desc, dma_addr_in, msgsz, options); } append_store(desc, dma_addr_out, storelen, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT); }
SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst, const SkPaint& paint, SkArenaAlloc* alloc, const SkRasterPipeline& shaderPipeline, SkShaderBase::Context* burstCtx, bool is_opaque, bool is_constant) { auto blitter = alloc->make<SkRasterPipelineBlitter>(dst, paint.getBlendMode(), alloc, burstCtx); // Our job in this factory is to fill out the blitter's color pipeline. // This is the common front of the full blit pipelines, each constructed lazily on first use. // The full blit pipelines handle reading and writing the dst, blending, coverage, dithering. auto colorPipeline = &blitter->fColorPipeline; // Let's get the shader in first. if (burstCtx) { colorPipeline->append(SkRasterPipeline::load_f32, &blitter->fShaderOutput); } else { colorPipeline->extend(shaderPipeline); } // If there's a color filter it comes next. if (auto colorFilter = paint.getColorFilter()) { colorFilter->appendStages(colorPipeline, dst.colorSpace(), alloc, is_opaque); is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag); } // Not all formats make sense to dither (think, F16). We set their dither rate to zero. // We need to decide if we're going to dither now to keep is_constant accurate. if (paint.isDither()) { switch (dst.info().colorType()) { default: blitter->fDitherRate = 0.0f; break; case kARGB_4444_SkColorType: blitter->fDitherRate = 1/15.0f; break; case kRGB_565_SkColorType: blitter->fDitherRate = 1/63.0f; break; case kGray_8_SkColorType: case kRGBA_8888_SkColorType: case kBGRA_8888_SkColorType: blitter->fDitherRate = 1/255.0f; break; } // TODO: for constant colors, we could try to measure the effect of dithering, and if // it has no value (i.e. all variations result in the same 32bit color, then we // could disable it (for speed, by not adding the stage). } is_constant = is_constant && (blitter->fDitherRate == 0.0f); // We're logically done here. The code between here and return blitter is all optimization. // A pipeline that's still constant here can collapse back into a constant color. if (is_constant) { SkPM4f storage; SkPM4f* constantColor = &storage; colorPipeline->append(SkRasterPipeline::store_f32, &constantColor); colorPipeline->run(0,0,1); colorPipeline->reset(); colorPipeline->append_uniform_color(alloc, *constantColor); is_opaque = constantColor->a() == 1.0f; } // We can strength-reduce SrcOver into Src when opaque. if (is_opaque && blitter->fBlend == SkBlendMode::kSrcOver) { blitter->fBlend = SkBlendMode::kSrc; } // When we're drawing a constant color in Src mode, we can sometimes just memset. // (The previous two optimizations help find more opportunities for this one.) if (is_constant && blitter->fBlend == SkBlendMode::kSrc) { // Run our color pipeline all the way through to produce what we'd memset when we can. // Not all blits can memset, so we need to keep colorPipeline too. SkRasterPipeline_<256> p; p.extend(*colorPipeline); blitter->fDstPtr = &blitter->fMemsetColor; blitter->append_store(&p); p.run(0,0,1); blitter->fCanMemsetInBlitH = true; } return blitter; }
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; }