SkRasterPipeline.cpp revision c789b61167dd98efc3c3bfcf9673eef24c2e57f4
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#ifdef SK_DEBUG 15 if (fNum == (int)SK_ARRAY_COUNT(fStages)) { 16 this->dump(); 17 } 18#endif 19 SkASSERT(fNum < (int)SK_ARRAY_COUNT(fStages)); 20 fStages[fNum++] = { stage, ctx }; 21} 22 23void SkRasterPipeline::extend(const SkRasterPipeline& src) { 24 for (int i = 0; i < src.fNum; i++) { 25 const Stage& s = src.fStages[i]; 26 this->append(s.stage, s.ctx); 27 } 28} 29 30void SkRasterPipeline::run(size_t x, size_t y, size_t n) const { 31 SkOpts::run_pipeline(x,y,n, fStages, fNum); 32} 33 34std::function<void(size_t, size_t, size_t)> SkRasterPipeline::compile() const { 35 return SkOpts::compile_pipeline(fStages, fNum); 36} 37 38static bool invariant_in_x(const SkRasterPipeline::Stage& st) { 39 if (st.ctx == nullptr) { 40 // If a stage doesn't have a context pointer, it can't really do anything with x. 41 return true; 42 } 43 44 // This would be a lot more compact as a blacklist (the loads, the stores, the gathers), 45 // but it's safer to write as a whitelist. If we get it wrong this way, not a big deal. 46 switch (st.stage) { 47 default: return false; 48 49 case SkRasterPipeline::trace: 50 case SkRasterPipeline::set_rgb: 51 case SkRasterPipeline::constant_color: 52 case SkRasterPipeline::scale_constant_float: 53 case SkRasterPipeline::lerp_constant_float: 54 case SkRasterPipeline::matrix_2x3: 55 case SkRasterPipeline::matrix_3x4: 56 case SkRasterPipeline::matrix_4x5: 57 case SkRasterPipeline::matrix_perspective: 58 case SkRasterPipeline::parametric_r: 59 case SkRasterPipeline::parametric_g: 60 case SkRasterPipeline::parametric_b: 61 case SkRasterPipeline::table_r: 62 case SkRasterPipeline::table_g: 63 case SkRasterPipeline::table_b: 64 case SkRasterPipeline::color_lookup_table: 65 case SkRasterPipeline::lab_to_xyz: 66 case SkRasterPipeline::clamp_x: 67 case SkRasterPipeline::mirror_x: 68 case SkRasterPipeline::repeat_x: 69 case SkRasterPipeline::clamp_y: 70 case SkRasterPipeline::mirror_y: 71 case SkRasterPipeline::repeat_y: 72 case SkRasterPipeline::top_left: 73 case SkRasterPipeline::top_right: 74 case SkRasterPipeline::bottom_left: 75 case SkRasterPipeline::bottom_right: 76 case SkRasterPipeline::accumulate: 77 SkASSERT(st.ctx != nullptr); 78 return true; 79 } 80 return false; 81} 82 83void SkRasterPipeline::dump() const { 84 SkDebugf("SkRasterPipeline, %d stages\n", fNum); 85 bool in_constant_run = false; 86 for (int i = 0; i < fNum; i++) { 87 const char* name = ""; 88 switch (fStages[i].stage) { 89 #define M(x) case x: name = #x; break; 90 SK_RASTER_PIPELINE_STAGES(M) 91 #undef M 92 } 93 94 char mark = ' '; 95 if (fStages[i].stage == SkRasterPipeline::constant_color) { 96 mark = '*'; 97 in_constant_run = true; 98 } else if (in_constant_run && invariant_in_x(fStages[i])) { 99 mark = '|'; 100 } else { 101 mark = ' '; 102 in_constant_run = false; 103 } 104 SkDebugf("\t%c %s\n", mark, name); 105 } 106 SkDebugf("\n"); 107} 108