Avoid creating std::function in run_pipeline().
This avoids a malloc/free per SkRasterPipeline::run(), with no downside. $ out/nanobench --benchType skcolorcodec --colorImages images/colorspace/201293.jpg --skps noskps --xform_only --srgb --ms 10000 target: 273µs current: 395µs this CL: 375µs CQ_INCLUDE_TRYBOTS=skia.primary:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD Change-Id: Icd62f505f555ebf4ca66ee77a476f59cab68433d Reviewed-on: https://skia-review.googlesource.com/5447 Commit-Queue: Mike Klein <mtklein@chromium.org> Reviewed-by: Matt Sarett <msarett@google.com>
This commit is contained in:
parent
5476128f0a
commit
0c32496e77
@ -866,52 +866,54 @@ SI Fn enum_to_Fn(SkRasterPipeline::StockStage st) {
|
|||||||
return just_return;
|
return just_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct Compiled {
|
||||||
|
Compiled(const SkRasterPipeline::Stage* stages, int nstages) {
|
||||||
|
if (nstages == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fStart = enum_to_Fn(stages[0].stage);
|
||||||
|
for (int i = 0; i < nstages-1; i++) {
|
||||||
|
fStages[i].next = enum_to_Fn(stages[i+1].stage);
|
||||||
|
fStages[i].ctx = stages[i].ctx;
|
||||||
|
}
|
||||||
|
fStages[nstages-1].next = just_return;
|
||||||
|
fStages[nstages-1].ctx = stages[nstages-1].ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(size_t x, size_t y, size_t n) {
|
||||||
|
float dx[] = { 0,1,2,3,4,5,6,7 };
|
||||||
|
SkNf X = SkNf(x) + SkNf::Load(dx) + 0.5f,
|
||||||
|
Y = SkNf(y) + 0.5f,
|
||||||
|
_0 = SkNf(0),
|
||||||
|
_1 = SkNf(1);
|
||||||
|
|
||||||
|
while (n >= N) {
|
||||||
|
fStart(fStages, x*N, X,Y,_1,_0, _0,_0,_0,_0);
|
||||||
|
X += (float)N;
|
||||||
|
x += N;
|
||||||
|
n -= N;
|
||||||
|
}
|
||||||
|
if (n) {
|
||||||
|
fStart(fStages, x*N+n, X,Y,_1,_0, _0,_0,_0,_0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Fn fStart = just_return;
|
||||||
|
Stage fStages[SkRasterPipeline::kMaxStages];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace SK_OPTS_NS {
|
namespace SK_OPTS_NS {
|
||||||
|
|
||||||
SI std::function<void(size_t, size_t, size_t)>
|
SI std::function<void(size_t, size_t, size_t)>
|
||||||
compile_pipeline(const SkRasterPipeline::Stage* stages, int nstages) {
|
compile_pipeline(const SkRasterPipeline::Stage* stages, int nstages) {
|
||||||
struct Compiled {
|
return Compiled{stages,nstages};
|
||||||
Compiled(const SkRasterPipeline::Stage* stages, int nstages) {
|
|
||||||
if (nstages == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fStart = enum_to_Fn(stages[0].stage);
|
|
||||||
for (int i = 0; i < nstages-1; i++) {
|
|
||||||
fStages[i].next = enum_to_Fn(stages[i+1].stage);
|
|
||||||
fStages[i].ctx = stages[i].ctx;
|
|
||||||
}
|
|
||||||
fStages[nstages-1].next = just_return;
|
|
||||||
fStages[nstages-1].ctx = stages[nstages-1].ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(size_t x, size_t y, size_t n) {
|
|
||||||
float dx[] = { 0,1,2,3,4,5,6,7 };
|
|
||||||
SkNf X = SkNf(x) + SkNf::Load(dx) + 0.5f,
|
|
||||||
Y = SkNf(y) + 0.5f,
|
|
||||||
_0 = SkNf(0),
|
|
||||||
_1 = SkNf(1);
|
|
||||||
|
|
||||||
while (n >= N) {
|
|
||||||
fStart(fStages, x*N, X,Y,_1,_0, _0,_0,_0,_0);
|
|
||||||
X += (float)N;
|
|
||||||
x += N;
|
|
||||||
n -= N;
|
|
||||||
}
|
|
||||||
if (n) {
|
|
||||||
fStart(fStages, x*N+n, X,Y,_1,_0, _0,_0,_0,_0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Fn fStart = just_return;
|
|
||||||
Stage fStages[SkRasterPipeline::kMaxStages];
|
|
||||||
|
|
||||||
} fn { stages, nstages };
|
|
||||||
return fn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SI void run_pipeline(size_t x, size_t y, size_t n,
|
SI void run_pipeline(size_t x, size_t y, size_t n,
|
||||||
const SkRasterPipeline::Stage* stages, int nstages) {
|
const SkRasterPipeline::Stage* stages, int nstages) {
|
||||||
compile_pipeline(stages, nstages)(x,y,n);
|
Compiled{stages,nstages}(x,y,n);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace SK_OPTS_NS
|
} // namespace SK_OPTS_NS
|
||||||
|
Loading…
Reference in New Issue
Block a user