aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/jumper/SkJumper_stages.cpp
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-03-02 12:42:14 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-02 18:55:03 +0000
commit8e8e817cbf6c6e3df744dbaa070564c453b70a62 (patch)
tree70f20dd47b88a580660dcb8fce5fb5fc29358a7b /src/jumper/SkJumper_stages.cpp
parentcf2e8c6139ead6a64be743e5ab2a5517ac479aba (diff)
SkJumper: skip null contexts
This makes stages that don't use a context pointer look a little cleaner, especially on ARM. No interesting speed difference on x86. What do you think? Change-Id: I445472be2aa8a7c3bc8cba443fa477a3628118ba Reviewed-on: https://skia-review.googlesource.com/9155 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/jumper/SkJumper_stages.cpp')
-rw-r--r--src/jumper/SkJumper_stages.cpp37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/jumper/SkJumper_stages.cpp b/src/jumper/SkJumper_stages.cpp
index 88a1201809..ab942230d8 100644
--- a/src/jumper/SkJumper_stages.cpp
+++ b/src/jumper/SkJumper_stages.cpp
@@ -344,6 +344,27 @@ static void* load_and_inc(void**& program) {
#endif
}
+// Doesn't do anything unless you resolve it, either by casting to a pointer or calling load().
+// This makes it free in stages that have no context pointer to load (i.e. built with nullptr).
+struct LazyCtx {
+ void* ptr;
+ void**& program;
+
+ explicit LazyCtx(void**& p) : ptr(nullptr), program(p) {}
+
+ template <typename T>
+ operator T*() {
+ if (!ptr) { ptr = load_and_inc(program); }
+ return (T*)ptr;
+ }
+
+ template <typename T>
+ T load() {
+ if (!ptr) { ptr = load_and_inc(program); }
+ return unaligned_load<T>(ptr);
+ }
+};
+
#if defined(JUMPER) && defined(__AVX__)
// There's a big cost to switch between SSE and AVX+, so we do a little
// extra work to handle even the jagged <kStride tail in AVX+ mode.
@@ -366,16 +387,16 @@ static void* load_and_inc(void**& program) {
}
#define STAGE(name) \
- static void name##_k(size_t x, void* ctx, K* k, size_t tail, \
+ static void name##_k(size_t x, LazyCtx ctx, K* k, size_t tail, \
F& r, F& g, F& b, F& a, F& dr, F& dg, F& db, F& da); \
extern "C" void WRAP(name)(size_t x, void** program, K* k, size_t tail, \
F r, F g, F b, F a, F dr, F dg, F db, F da) { \
- auto ctx = load_and_inc(program); \
+ LazyCtx ctx(program); \
name##_k(x,ctx,k,tail, r,g,b,a, dr,dg,db,da); \
auto next = (Stage*)load_and_inc(program); \
next(x,program,k,tail, r,g,b,a, dr,dg,db,da); \
} \
- static void name##_k(size_t x, void* ctx, K* k, size_t tail, \
+ static void name##_k(size_t x, LazyCtx ctx, K* k, size_t tail, \
F& r, F& g, F& b, F& a, F& dr, F& dg, F& db, F& da)
#else
@@ -400,16 +421,16 @@ static void* load_and_inc(void**& program) {
}
#define STAGE(name) \
- static void name##_k(size_t x, void* ctx, K* k, size_t tail, \
+ static void name##_k(size_t x, LazyCtx ctx, K* k, size_t tail, \
F& r, F& g, F& b, F& a, F& dr, F& dg, F& db, F& da); \
extern "C" void WRAP(name)(size_t x, void** program, K* k, \
F r, F g, F b, F a, F dr, F dg, F db, F da) { \
- auto ctx = load_and_inc(program); \
+ LazyCtx ctx(program); \
name##_k(x,ctx,k,0, r,g,b,a, dr,dg,db,da); \
auto next = (Stage*)load_and_inc(program); \
next(x,program,k, r,g,b,a, dr,dg,db,da); \
} \
- static void name##_k(size_t x, void* ctx, K* k, size_t tail, \
+ static void name##_k(size_t x, LazyCtx ctx, K* k, size_t tail, \
F& r, F& g, F& b, F& a, F& dr, F& dg, F& db, F& da)
#endif
@@ -446,7 +467,7 @@ STAGE(seed_shader) {
}
STAGE(constant_color) {
- auto rgba = unaligned_load<F4>(ctx);
+ auto rgba = ctx.load<F4>();
r = rgba[0];
g = rgba[1];
b = rgba[2];
@@ -1003,7 +1024,7 @@ STAGE(matrix_perspective) {
STAGE(linear_gradient_2stops) {
struct Ctx { F4 c0, dc; };
- auto c = unaligned_load<Ctx>(ctx);
+ auto c = ctx.load<Ctx>();
auto t = r;
r = mad(t, c.dc[0], c.c0[0]);