diff options
author | 2016-10-25 10:27:33 -0400 | |
---|---|---|
committer | 2016-10-25 17:30:38 +0000 | |
commit | aebfb45104eeb6dab5dbbedda13c2eaa7b7f7868 (patch) | |
tree | 7dcbf9bf86bd1b9fad0048dccbabb11e47a1d3fb /src/core | |
parent | cc813ae9a0afe4259f12b655d9336662a6e2c100 (diff) |
Move SkRasterPipeline further into SkOpts.
The portable code now becomes entirely focused on enum+ptr descriptions, leaving the concrete implementation of the pipeline to SkOpts::run_pipeline().
As implemented, the concrete implementation is basically the same, with a little more type safety.
Speed is essentially unchanged on my laptop, and that's having run_pipeline() rebuild its concrete state every call. There's room for improvement there if we split this into a compile_pipeline() / run_pipeline() sort of thing, which is my next planned CL.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3920
CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot
Change-Id: Ie4c554f51040426de7c5c144afa5d9d9d8938012
Reviewed-on: https://skia-review.googlesource.com/3920
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkOpts.cpp | 102 | ||||
-rw-r--r-- | src/core/SkOpts.h | 8 | ||||
-rw-r--r-- | src/core/SkRasterPipeline.cpp | 36 | ||||
-rw-r--r-- | src/core/SkRasterPipeline.h | 98 |
4 files changed, 40 insertions, 204 deletions
diff --git a/src/core/SkOpts.cpp b/src/core/SkOpts.cpp index 16389484b4..c082b160ee 100644 --- a/src/core/SkOpts.cpp +++ b/src/core/SkOpts.cpp @@ -92,108 +92,6 @@ namespace SkOpts { DEFINE_DEFAULT(run_pipeline); #undef DEFINE_DEFAULT - SkOpts::VoidFn body[] = { - (SkOpts::VoidFn)SK_OPTS_NS::just_return, - (SkOpts::VoidFn)SK_OPTS_NS::swap_src_dst, - - (SkOpts::VoidFn)SK_OPTS_NS::store_565, - (SkOpts::VoidFn)SK_OPTS_NS::store_srgb, - (SkOpts::VoidFn)SK_OPTS_NS::store_f16, - - (SkOpts::VoidFn)SK_OPTS_NS::load_s_565, - (SkOpts::VoidFn)SK_OPTS_NS::load_s_srgb, - (SkOpts::VoidFn)SK_OPTS_NS::load_s_f16, - - (SkOpts::VoidFn)SK_OPTS_NS::load_d_565, - (SkOpts::VoidFn)SK_OPTS_NS::load_d_srgb, - (SkOpts::VoidFn)SK_OPTS_NS::load_d_f16, - - (SkOpts::VoidFn)SK_OPTS_NS::scale_u8, - - (SkOpts::VoidFn)SK_OPTS_NS::lerp_u8, - (SkOpts::VoidFn)SK_OPTS_NS::lerp_565, - (SkOpts::VoidFn)SK_OPTS_NS::lerp_constant_float, - - (SkOpts::VoidFn)SK_OPTS_NS::constant_color, - - (SkOpts::VoidFn)SK_OPTS_NS::dst, - (SkOpts::VoidFn)SK_OPTS_NS::dstatop, - (SkOpts::VoidFn)SK_OPTS_NS::dstin, - (SkOpts::VoidFn)SK_OPTS_NS::dstout, - (SkOpts::VoidFn)SK_OPTS_NS::dstover, - (SkOpts::VoidFn)SK_OPTS_NS::srcatop, - (SkOpts::VoidFn)SK_OPTS_NS::srcin, - (SkOpts::VoidFn)SK_OPTS_NS::srcout, - (SkOpts::VoidFn)SK_OPTS_NS::srcover, - (SkOpts::VoidFn)SK_OPTS_NS::clear, - (SkOpts::VoidFn)SK_OPTS_NS::modulate, - (SkOpts::VoidFn)SK_OPTS_NS::multiply, - (SkOpts::VoidFn)SK_OPTS_NS::plus_, - (SkOpts::VoidFn)SK_OPTS_NS::screen, - (SkOpts::VoidFn)SK_OPTS_NS::xor_, - (SkOpts::VoidFn)SK_OPTS_NS::colorburn, - (SkOpts::VoidFn)SK_OPTS_NS::colordodge, - (SkOpts::VoidFn)SK_OPTS_NS::darken, - (SkOpts::VoidFn)SK_OPTS_NS::difference, - (SkOpts::VoidFn)SK_OPTS_NS::exclusion, - (SkOpts::VoidFn)SK_OPTS_NS::hardlight, - (SkOpts::VoidFn)SK_OPTS_NS::lighten, - (SkOpts::VoidFn)SK_OPTS_NS::overlay, - (SkOpts::VoidFn)SK_OPTS_NS::softlight, - }; - static_assert(SK_ARRAY_COUNT(body) == SkRasterPipeline::kNumStockStages, ""); - - SkOpts::VoidFn tail[] = { - (SkOpts::VoidFn)SK_OPTS_NS::just_return_tail, - (SkOpts::VoidFn)SK_OPTS_NS::swap_src_dst_tail, - - (SkOpts::VoidFn)SK_OPTS_NS::store_565_tail, - (SkOpts::VoidFn)SK_OPTS_NS::store_srgb_tail, - (SkOpts::VoidFn)SK_OPTS_NS::store_f16_tail, - - (SkOpts::VoidFn)SK_OPTS_NS::load_s_565_tail, - (SkOpts::VoidFn)SK_OPTS_NS::load_s_srgb_tail, - (SkOpts::VoidFn)SK_OPTS_NS::load_s_f16_tail, - - (SkOpts::VoidFn)SK_OPTS_NS::load_d_565_tail, - (SkOpts::VoidFn)SK_OPTS_NS::load_d_srgb_tail, - (SkOpts::VoidFn)SK_OPTS_NS::load_d_f16_tail, - - (SkOpts::VoidFn)SK_OPTS_NS::scale_u8_tail, - - (SkOpts::VoidFn)SK_OPTS_NS::lerp_u8_tail, - (SkOpts::VoidFn)SK_OPTS_NS::lerp_565_tail, - (SkOpts::VoidFn)SK_OPTS_NS::lerp_constant_float_tail, - - (SkOpts::VoidFn)SK_OPTS_NS::constant_color_tail, - - (SkOpts::VoidFn)SK_OPTS_NS::dst_tail, - (SkOpts::VoidFn)SK_OPTS_NS::dstatop_tail, - (SkOpts::VoidFn)SK_OPTS_NS::dstin_tail, - (SkOpts::VoidFn)SK_OPTS_NS::dstout_tail, - (SkOpts::VoidFn)SK_OPTS_NS::dstover_tail, - (SkOpts::VoidFn)SK_OPTS_NS::srcatop_tail, - (SkOpts::VoidFn)SK_OPTS_NS::srcin_tail, - (SkOpts::VoidFn)SK_OPTS_NS::srcout_tail, - (SkOpts::VoidFn)SK_OPTS_NS::srcover_tail, - (SkOpts::VoidFn)SK_OPTS_NS::clear_tail, - (SkOpts::VoidFn)SK_OPTS_NS::modulate_tail, - (SkOpts::VoidFn)SK_OPTS_NS::multiply_tail, - (SkOpts::VoidFn)SK_OPTS_NS::plus__tail, - (SkOpts::VoidFn)SK_OPTS_NS::screen_tail, - (SkOpts::VoidFn)SK_OPTS_NS::xor__tail, - (SkOpts::VoidFn)SK_OPTS_NS::colorburn_tail, - (SkOpts::VoidFn)SK_OPTS_NS::colordodge_tail, - (SkOpts::VoidFn)SK_OPTS_NS::darken_tail, - (SkOpts::VoidFn)SK_OPTS_NS::difference_tail, - (SkOpts::VoidFn)SK_OPTS_NS::exclusion_tail, - (SkOpts::VoidFn)SK_OPTS_NS::hardlight_tail, - (SkOpts::VoidFn)SK_OPTS_NS::lighten_tail, - (SkOpts::VoidFn)SK_OPTS_NS::overlay_tail, - (SkOpts::VoidFn)SK_OPTS_NS::softlight_tail, - }; - static_assert(SK_ARRAY_COUNT(tail) == SkRasterPipeline::kNumStockStages, ""); - // Each Init_foo() is defined in src/opts/SkOpts_foo.cpp. void Init_ssse3(); void Init_sse41(); diff --git a/src/core/SkOpts.h b/src/core/SkOpts.h index 4685d86691..7283030068 100644 --- a/src/core/SkOpts.h +++ b/src/core/SkOpts.h @@ -73,13 +73,7 @@ namespace SkOpts { return hash_fn(data, bytes, seed); } - // SkRasterPipeline::Fn has different types in different files (notably, in SkOpts_hsw.cpp - // they're all in terms of Sk8f.) We store them with a type everyone can agree on, void(*)(). - using VoidFn = void(*)(); - extern VoidFn body[SkRasterPipeline::kNumStockStages], - tail[SkRasterPipeline::kNumStockStages]; - extern void (*run_pipeline)(size_t, size_t, void(*)(), SkRasterPipeline::Stage*, - void(*)(), SkRasterPipeline::Stage*); + extern void (*run_pipeline)(size_t, size_t, const SkRasterPipeline::Stage*, int); } #endif//SkOpts_DEFINED diff --git a/src/core/SkRasterPipeline.cpp b/src/core/SkRasterPipeline.cpp index bc7feaccc7..707a33ae6f 100644 --- a/src/core/SkRasterPipeline.cpp +++ b/src/core/SkRasterPipeline.cpp @@ -8,40 +8,20 @@ #include "SkOpts.h" #include "SkRasterPipeline.h" -SkRasterPipeline::SkRasterPipeline() { - fBodyStart = SkOpts::body[just_return]; - fTailStart = SkOpts::tail[just_return]; -} - -void SkRasterPipeline::append(void (*body)(), void (*tail)(), void* ctx) { - // Each stage holds its own context and the next function to call. - // So the pipeline itself has to hold onto the first function that starts the pipeline. - (fBody.empty() ? fBodyStart : fBody.back().fNext) = body; - (fTail.empty() ? fTailStart : fTail.back().fNext) = tail; - - // Each last stage starts with its next function set to JustReturn as a safety net. - // It'll be overwritten by the next call to append(). - fBody.push_back({ SkOpts::body[just_return], ctx }); - fTail.push_back({ SkOpts::tail[just_return], ctx }); -} +SkRasterPipeline::SkRasterPipeline() {} void SkRasterPipeline::append(StockStage stage, void* ctx) { - this->append(SkOpts::body[stage], SkOpts::tail[stage], ctx); + SkASSERT(fNum < (int)SK_ARRAY_COUNT(fStages)); + fStages[fNum++] = { stage, ctx }; } void SkRasterPipeline::extend(const SkRasterPipeline& src) { - SkASSERT(src.fBody.count() == src.fTail.count()); - - auto body = src.fBodyStart, - tail = src.fTailStart; - for (int i = 0; i < src.fBody.count(); i++) { - SkASSERT(src.fBody[i].fCtx == src.fTail[i].fCtx); - this->append(body, tail, src.fBody[i].fCtx); - body = src.fBody[i].fNext; - tail = src.fTail[i].fNext; + for (int i = 0; i < src.fNum; i++) { + const Stage& s = src.fStages[i]; + this->append(s.stage, s.ctx); } } -void SkRasterPipeline::run(size_t x, size_t n) { - SkOpts::run_pipeline(x,n, fBodyStart,fBody.begin(), fTailStart,fTail.begin()); +void SkRasterPipeline::run(size_t x, size_t n) const { + SkOpts::run_pipeline(x,n, fStages, fNum); } diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h index 525a8dbe72..60279dd168 100644 --- a/src/core/SkRasterPipeline.h +++ b/src/core/SkRasterPipeline.h @@ -53,72 +53,31 @@ // TODO: There may be a better place to stuff tail, e.g. in the bottom alignment bits of // the Stage*. This mostly matters on 64-bit Windows where every register is precious. +#define SK_RASTER_PIPELINE_STAGES(M) \ + M(swap_src_dst) M(constant_color) \ + M(load_s_565) M(load_d_565) M(store_565) \ + M(load_s_srgb) M(load_d_srgb) M(store_srgb) \ + M(load_s_f16) M(load_d_f16) M(store_f16) \ + M(scale_u8) \ + M(lerp_u8) M(lerp_565) M(lerp_constant_float) \ + M(dst) \ + M(dstatop) M(dstin) M(dstout) M(dstover) \ + M(srcatop) M(srcin) M(srcout) M(srcover) \ + M(clear) M(modulate) M(multiply) M(plus_) M(screen) M(xor_) \ + M(colorburn) M(colordodge) M(darken) M(difference) \ + M(exclusion) M(hardlight) M(lighten) M(overlay) M(softlight) + class SkRasterPipeline { public: - struct Stage { - // It makes next() a good bit cheaper if we hold the next function to call here, - // rather than logically simpler choice of the function implementing this stage. - void (*fNext)(); - void* fCtx; - }; + // No pipeline may be more than kMaxStages long. + static const int kMaxStages = 32; SkRasterPipeline(); - // Run the pipeline constructed with append(), walking x through [x,x+n), - // generally in 4-pixel steps, with perhaps one jagged tail step. - void run(size_t x, size_t n); - void run(size_t n) { this->run(0, n); } - enum StockStage { - just_return, - swap_src_dst, - - store_565, - store_srgb, - store_f16, - - load_s_565, - load_s_srgb, - load_s_f16, - - load_d_565, - load_d_srgb, - load_d_f16, - - scale_u8, - - lerp_u8, - lerp_565, - lerp_constant_float, - - constant_color, - - dst, - dstatop, - dstin, - dstout, - dstover, - srcatop, - srcin, - srcout, - srcover, - clear, - modulate, - multiply, - plus_, - screen, - xor_, - colorburn, - colordodge, - darken, - difference, - exclusion, - hardlight, - lighten, - overlay, - softlight, - - kNumStockStages, + #define M(stage) stage, + SK_RASTER_PIPELINE_STAGES(M) + #undef M }; void append(StockStage, void* = nullptr); void append(StockStage stage, const void* ctx) { this->append(stage, const_cast<void*>(ctx)); } @@ -126,15 +85,20 @@ public: // Append all stages to this pipeline. void extend(const SkRasterPipeline&); -private: - using Stages = SkSTArray<10, Stage, /*MEM_COPY=*/true>; + // Run the pipeline constructed with append(), walking x through [x,x+n), + // generally in 4-pixel steps, with perhaps one jagged tail step. + void run(size_t x, size_t n) const; + void run(size_t n) const { this->run(0, n); } - void append(void (*body)(), void (*tail)(), void*); - Stages fBody, - fTail; - void (*fBodyStart)() = nullptr; - void (*fTailStart)() = nullptr; + struct Stage { + StockStage stage; + void* ctx; + }; + +private: + int fNum = 0; + Stage fStages[kMaxStages]; }; #endif//SkRasterPipeline_DEFINED |