SkRasterPipeline.cpp revision f6a1a2179ad6bf37dd81a658b30d12bfbdfa5c3f
1/* 2 * Copyright 2016 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkOpts.h" 9#include "SkRasterPipeline.h" 10 11SkRasterPipeline::SkRasterPipeline() {} 12 13void SkRasterPipeline::append(StockStage stage, void* ctx) { 14 SkASSERT(stage != from_srgb); 15 fStages.push_back({stage, ctx}); 16} 17 18void SkRasterPipeline::extend(const SkRasterPipeline& src) { 19 fStages.insert(fStages.end(), 20 src.fStages.begin(), src.fStages.end()); 21} 22 23void SkRasterPipeline::run(size_t x, size_t n) const { 24 if (!fStages.empty()) { 25 SkOpts::run_pipeline(x,n, fStages.data(), SkToInt(fStages.size())); 26 } 27} 28 29std::function<void(size_t, size_t)> SkRasterPipeline::compile() const { 30 return SkOpts::compile_pipeline(fStages.data(), SkToInt(fStages.size())); 31} 32 33void SkRasterPipeline::dump() const { 34 SkDebugf("SkRasterPipeline, %d stages\n", SkToInt(fStages.size())); 35 for (auto&& st : fStages) { 36 const char* name = ""; 37 switch (st.stage) { 38 #define M(x) case x: name = #x; break; 39 SK_RASTER_PIPELINE_STAGES(M) 40 #undef M 41 } 42 SkDebugf("\t%s\n", name); 43 } 44 SkDebugf("\n"); 45} 46 47// It's pretty easy to start with sound premultiplied linear floats, pack those 48// to sRGB encoded bytes, then read them back to linear floats and find them not 49// quite premultiplied, with a color channel just a smidge greater than the alpha 50// channel. This can happen basically any time we have different transfer 51// functions for alpha and colors... sRGB being the only one we draw into. 52 53// This is an annoying problem with no known good solution. So apply the clamp hammer. 54 55void SkRasterPipeline::append_from_srgb(SkAlphaType at) { 56 //this->append(from_srgb); 57 fStages.push_back({from_srgb, nullptr}); 58 59 if (at == kPremul_SkAlphaType) { 60 this->append(SkRasterPipeline::clamp_a); 61 } 62} 63