aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2019-08-02 23:21:57 +0200
committerHanspeter Portner <dev@open-music-kontrollers.ch>2019-08-02 23:21:57 +0200
commit1f6ef418f3d7d8b474afe7c8e24dd0bdad7f86af (patch)
tree46309aa5c700190ece10d7780d35bf031f87737f
parentc60df2e686613bf9f495cbcc76c92753803c8f98 (diff)
downloadsynthpod-1f6ef418f3d7d8b474afe7c8e24dd0bdad7f86af.tar.xz
Squashed 'subprojects/d2tk/' changes from 15c59a14..25ed6fac
25ed6fac hash: speed up foreach and add dict alterantive. 9c6d3986 core: speed up fillin/clearing bitmap mask. 6dd47cfd Merge commit 'a65cb3f8c62fc9db16e70699613329d29b726898' a65cb3f8 Squashed 'nanovg/' changes from 75dbf61..997c861 ca9607d2 core: only update dirty part of mask. git-subtree-dir: subprojects/d2tk git-subtree-split: 25ed6fac428124f667a86312ae919e5c012598c1
-rw-r--r--VERSION2
-rw-r--r--d2tk/hash.h10
-rw-r--r--nanovg/src/nanovg.c5
-rw-r--r--nanovg/src/nanovg.h3
-rw-r--r--src/backend_cairo.c10
-rw-r--r--src/backend_nanovg.c14
-rw-r--r--src/base.c17
-rw-r--r--src/core.c57
-rw-r--r--src/core_internal.h2
-rw-r--r--src/mum.c68
-rw-r--r--test/mock.c4
11 files changed, 124 insertions, 68 deletions
diff --git a/VERSION b/VERSION
index d958a5fd..e9d95802 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.749
+0.1.759
diff --git a/d2tk/hash.h b/d2tk/hash.h
index fc8d70f3..be69e927 100644
--- a/d2tk/hash.h
+++ b/d2tk/hash.h
@@ -27,12 +27,22 @@
extern "C" {
#endif
+typedef struct _d2tk_hash_dict_t d2tk_hash_dict_t;
+
+struct _d2tk_hash_dict_t {
+ const void *key;
+ size_t len;
+};
+
D2TK_API uint64_t
d2tk_hash(const void *data, ssize_t nbytes);
D2TK_API uint64_t
d2tk_hash_foreach(const void *data, ssize_t nbytes, ...) __attribute__((sentinel));
+D2TK_API uint64_t
+d2tk_hash_dict(const d2tk_hash_dict_t *dict);
+
#ifdef __cplusplus
}
#endif
diff --git a/nanovg/src/nanovg.c b/nanovg/src/nanovg.c
index f82f76c1..f6427882 100644
--- a/nanovg/src/nanovg.c
+++ b/nanovg/src/nanovg.c
@@ -841,6 +841,11 @@ void nvgUpdateImage(NVGcontext* ctx, int image, const unsigned char* data)
ctx->params.renderUpdateTexture(ctx->params.userPtr, image, 0,0, w,h, data);
}
+void nvgUpdateSubImage(NVGcontext* ctx, int image, const unsigned char* data, int x, int y, int w, int h)
+{
+ ctx->params.renderUpdateTexture(ctx->params.userPtr, image, x,y, w,h, data);
+}
+
void nvgImageSize(NVGcontext* ctx, int image, int* w, int* h)
{
ctx->params.renderGetTextureSize(ctx->params.userPtr, image, w, h);
diff --git a/nanovg/src/nanovg.h b/nanovg/src/nanovg.h
index e3d7ee1c..8aaec30e 100644
--- a/nanovg/src/nanovg.h
+++ b/nanovg/src/nanovg.h
@@ -386,6 +386,9 @@ int nvgCreateImageARGB(NVGcontext* ctx, int w, int h, int imageFlags, const unsi
// Updates image data specified by image handle.
void nvgUpdateImage(NVGcontext* ctx, int image, const unsigned char* data);
+// Updates part image data specified by image handle.
+void nvgUpdateSubImage(NVGcontext* ctx, int image, const unsigned char* data, int x, int y, int w, int h);
+
// Returns the dimensions of a created image.
void nvgImageSize(NVGcontext* ctx, int image, int* w, int* h);
diff --git a/src/backend_cairo.c b/src/backend_cairo.c
index b1a8deef..a96d8314 100644
--- a/src/backend_cairo.c
+++ b/src/backend_cairo.c
@@ -100,12 +100,14 @@ d2tk_cairo_pre(void *data, d2tk_core_t *core __attribute((unused)),
cairo_save(ctx);
{
- uint32_t *pixels = d2tk_core_get_pixels(core);
+ d2tk_rect_t rect;
+ uint32_t *pixels = d2tk_core_get_pixels(core, &rect);
cairo_surface_t *surf = cairo_image_surface_create_for_data(
(uint8_t *)pixels, CAIRO_FORMAT_ARGB32, w, h, w*sizeof(uint32_t));
+ //FIXME reuse/update surfaces
- cairo_rectangle(ctx, 0, 0, w, h);
+ cairo_rectangle(ctx, rect.x, rect.y, rect.w, rect.h);
cairo_clip(ctx);
cairo_new_sub_path(ctx);
@@ -132,7 +134,8 @@ d2tk_cairo_post(void *data, d2tk_core_t *core __attribute__((unused)),
#ifdef D2TK_DEBUG //FIXME needs multiple buffers to work
{
- uint32_t *pixels = d2tk_core_get_pixels(core);
+ d2tk_rect_t rect;
+ uint32_t *pixels = d2tk_core_get_pixels(core, &rect);
// brighten up the pixels for proper hilighting
for(d2tk_coord_t y = 0, Y = 0; y < h; y++, Y+=w)
@@ -148,6 +151,7 @@ d2tk_cairo_post(void *data, d2tk_core_t *core __attribute__((unused)),
cairo_surface_t *surf = cairo_image_surface_create_for_data(
(uint8_t *)pixels, CAIRO_FORMAT_ARGB32, w, h, w*sizeof(uint32_t));
+ //FIXME reuse/update suface
cairo_rectangle(ctx, 0, 0, w, h);
cairo_clip(ctx);
diff --git a/src/backend_nanovg.c b/src/backend_nanovg.c
index 6f9a4116..ad48e16c 100644
--- a/src/backend_nanovg.c
+++ b/src/backend_nanovg.c
@@ -210,21 +210,23 @@ d2tk_nanovg_pre(void *data, d2tk_core_t *core, d2tk_coord_t w, d2tk_coord_t h,
{
// draw mask
- uint32_t *pixels = d2tk_core_get_pixels(core);
+ d2tk_rect_t rect;
+ uint32_t *pixels = d2tk_core_get_pixels(core, &rect);
if(backend->mask)
{
- nvgUpdateImage(ctx, backend->mask, (const uint8_t *)pixels);
+ nvgUpdateSubImage(ctx, backend->mask, (const uint8_t *)pixels,
+ rect.x, rect.y, rect.w, rect.h);
}
else
{
backend->mask = nvgCreateImageRGBA(ctx, w, h, NVG_IMAGE_NEAREST,
(const uint8_t *)pixels);
}
-
+
const NVGpaint bg = nvgImagePattern(ctx, 0, 0, w, h, 0, backend->mask, 1.f);
nvgBeginPath(ctx);
- nvgRect(ctx, 0, 0, w, h);
+ nvgRect(ctx, rect.x, rect.y, rect.w, rect.h);
nvgStrokeWidth(ctx, 0);
nvgFillPaint(ctx, bg);
nvgFill(ctx);
@@ -271,7 +273,8 @@ d2tk_nanovg_post(void *data, d2tk_core_t *core __attribute__((unused)),
#ifdef D2TK_DEBUG
{
- uint32_t *pixels = d2tk_core_get_pixels(core);
+ d2tk_rect_t rect;
+ uint32_t *pixels = d2tk_core_get_pixels(core, &rect);
// brighten up the pixels for proper hilighting
for(d2tk_coord_t y = 0, Y = 0; y < h; y++, Y+=w)
@@ -284,6 +287,7 @@ d2tk_nanovg_post(void *data, d2tk_core_t *core __attribute__((unused)),
}
}
}
+
if(backend->mask)
{
nvgUpdateImage(ctx, backend->mask, (const uint8_t *)pixels);
diff --git a/src/base.c b/src/base.c
index 26ea8458..da1df31f 100644
--- a/src/base.c
+++ b/src/base.c
@@ -1673,13 +1673,16 @@ _d2tk_base_draw_button(d2tk_core_t *core, ssize_t lbl_len, const char *lbl,
path_len = strlen(path);
}
- const uint64_t hash = d2tk_hash_foreach(&triple, sizeof(d2tk_triple_t),
- rect, sizeof(d2tk_rect_t),
- style, sizeof(d2tk_style_t),
- &align, sizeof(d2tk_align_t),
- (lbl ? lbl : path), (lbl ? lbl_len : path_len),
- (path ? path : NULL), (path ? path_len : 0),
- NULL);
+ const d2tk_hash_dict_t dict [] = {
+ { &triple, sizeof(d2tk_triple_t) },
+ { rect, sizeof(d2tk_rect_t) },
+ { style, sizeof(d2tk_style_t) },
+ { &align, sizeof(d2tk_align_t) },
+ { (lbl ? lbl : path), (lbl ? lbl_len : path_len) },
+ { path, path_len },
+ { NULL, 0 }
+ };
+ const uint64_t hash = d2tk_hash_dict(dict);
D2TK_CORE_WIDGET(core, hash, widget)
{
diff --git a/src/core.c b/src/core.c
index 79e76af0..7910dd19 100644
--- a/src/core.c
+++ b/src/core.c
@@ -56,6 +56,7 @@ struct _d2tk_mem_t {
struct _d2tk_bitmap_t {
size_t size;
uint32_t *pixels;
+ uint32_t *template;
size_t nfills;
d2tk_coord_t x0;
d2tk_coord_t x1;
@@ -342,10 +343,26 @@ _d2tk_memcaches_gc(d2tk_core_t *core)
}
static inline void
-_d2tk_bitmap_resize(d2tk_bitmap_t *bitmap, d2tk_coord_t w, d2tk_coord_t h)
+_d2tk_bitmap_template_refill(d2tk_core_t *core)
{
- bitmap->size = w*h*sizeof(uint32_t);
+ d2tk_bitmap_t *bitmap = &core->bitmap;
+
+ for(d2tk_coord_t x = 0; x < core->w; x++)
+ {
+ bitmap->template[x] = core->bg_color;
+ }
+}
+
+static inline void
+_d2tk_bitmap_resize(d2tk_core_t *core, d2tk_coord_t w, d2tk_coord_t h)
+{
+ d2tk_bitmap_t *bitmap = &core->bitmap;
+
+ const size_t stride = w*sizeof(uint32_t);
+ bitmap->size = h*stride;
bitmap->pixels = realloc(bitmap->pixels, bitmap->size);
+ bitmap->template = realloc(bitmap->template, stride);
+ _d2tk_bitmap_template_refill(core);
}
static inline void
@@ -353,14 +370,24 @@ _d2tk_bitmap_deinit(d2tk_bitmap_t *bitmap)
{
free(bitmap->pixels);
bitmap->pixels = NULL;
+ free(bitmap->template);
+ bitmap->template = NULL;
bitmap->size = 0;
bitmap->nfills = 0;
}
static inline void
-_d2tk_bitmap_reset(d2tk_bitmap_t *bitmap)
+_d2tk_bitmap_reset(d2tk_core_t *core)
{
- memset(bitmap->pixels, 0x0, bitmap->size);
+ d2tk_bitmap_t *bitmap = &core->bitmap;
+
+ const size_t stride = (bitmap->x1 - bitmap->x0)*sizeof(uint32_t);
+
+ for(d2tk_coord_t y = bitmap->y0, Y = y*core->w; y < bitmap->y1; y++, Y+=core->w)
+ {
+ memset(&bitmap->pixels[Y + bitmap->x0], 0x0, stride);
+ }
+
bitmap->nfills = 0;
bitmap->x0 = INT_MAX;
bitmap->x1 = INT_MIN;
@@ -402,12 +429,11 @@ _d2tk_bitmap_fill(d2tk_core_t *core, const d2tk_clip_t *clip)
d2tk_clip_t dst;
_d2tk_clip_clip(core, &dst, clip);
+ const size_t stride = (dst.x1 - dst.x0)*sizeof(uint32_t);
+
for(d2tk_coord_t y = dst.y0, Y = y*core->w; y < dst.y1; y++, Y+=core->w)
{
- for(d2tk_coord_t x = dst.x0; x < dst.x1; x++)
- {
- bitmap->pixels[Y + x] = core->bg_color;
- }
+ memcpy(&bitmap->pixels[Y + dst.x0], bitmap->template, stride);
}
// update area of interest
@@ -455,8 +481,16 @@ _d2tk_bbox_mask(d2tk_core_t *core, d2tk_com_t *com)
}
uint32_t *
-d2tk_core_get_pixels(d2tk_core_t *core)
+d2tk_core_get_pixels(d2tk_core_t *core, d2tk_rect_t *rect)
{
+ if(rect)
+ {
+ rect->x = core->bitmap.x0;
+ rect->y = core->bitmap.y0;
+ rect->w = core->bitmap.x1 - core->bitmap.x0;
+ rect->h = core->bitmap.y1 - core->bitmap.y0;
+ }
+
return core->bitmap.pixels;
}
@@ -714,6 +748,7 @@ void
d2tk_core_set_bg_color(d2tk_core_t *core, uint32_t rgba)
{
core->bg_color = htonl(rgba);
+ _d2tk_bitmap_template_refill(core);
}
uint32_t
@@ -1304,7 +1339,7 @@ d2tk_core_post(d2tk_core_t *core)
d2tk_com_t *oldcom = _d2tk_mem_get_com(oldmem);
// reset num of clipping clips
- _d2tk_bitmap_reset(bitmap);
+ _d2tk_bitmap_reset(core);
if(core->full_refresh)
{
@@ -1516,7 +1551,7 @@ d2tk_core_set_dimensions(d2tk_core_t *core, d2tk_coord_t w, d2tk_coord_t h)
core->w = w;
core->h = h;
core->full_refresh = true;
- _d2tk_bitmap_resize(&core->bitmap, w, h);
+ _d2tk_bitmap_resize(core, w, h);
}
D2TK_API void
diff --git a/src/core_internal.h b/src/core_internal.h
index 91c1ef02..d875e8b7 100644
--- a/src/core_internal.h
+++ b/src/core_internal.h
@@ -295,7 +295,7 @@ d2tk_com_next(d2tk_com_t *bbox);
(BBOX) = d2tk_com_next((BBOX)))
uint32_t *
-d2tk_core_get_pixels(d2tk_core_t *core);
+d2tk_core_get_pixels(d2tk_core_t *core, d2tk_rect_t *rect);
void
d2tk_core_set_bg_color(d2tk_core_t *core, uint32_t rgba);
diff --git a/src/mum.c b/src/mum.c
index d988418a..146ea3c9 100644
--- a/src/mum.c
+++ b/src/mum.c
@@ -26,67 +26,57 @@
__attribute__((always_inline))
static inline size_t
-_sz(const void *data, ssize_t nbytes)
+_len(const void *key, ssize_t len)
{
- if(nbytes == -1) // is a null-terminated string
- {
- return strlen((const char *)data);
- }
+ return (len == -1) ? strlen((const char *)key) : (size_t)len;
+}
- return nbytes;
+__attribute__((always_inline))
+static inline uint64_t
+_d2tk_hash(uint64_t hash, const void *key, size_t len)
+{
+ return _mum_hash_aligned(hash + len, key, len);
}
D2TK_API uint64_t
-d2tk_hash(const void *data, ssize_t nbytes)
+d2tk_hash(const void *key, ssize_t len)
{
- nbytes = _sz(data, nbytes);
+ len = _len(key, len);
- return mum_hash(data, nbytes, SEED);
+ return mum_hash(key, len, SEED);
}
D2TK_API uint64_t
-d2tk_hash_foreach(const void *data, ssize_t nbytes, ...)
+d2tk_hash_foreach(const void *key, ssize_t len, ...)
{
va_list args;
- const void *src;
-
- nbytes = _sz(data, nbytes);
+ uint64_t hash = mum_hash_init(SEED);
- // derive total temporary buffer size
- size_t sz = nbytes;
+ len = _len(key, len); //FIXME remove
+ hash = _d2tk_hash(hash, key, len);
- va_start(args, nbytes);
+ va_start(args, len);
- while( (src = va_arg(args, const void *)) )
+ while( (key = va_arg(args, const void *)) )
{
- sz += _sz(src, va_arg(args, int));
+ len = _len(key, va_arg(args, int)); //FIXME remove
+ hash = _d2tk_hash(hash, key, len);
}
va_end(args);
- // fill temporary bufffer
- uint8_t *dst = alloca(sz);
- if(dst)
- {
- size_t off = 0;
-
- memcpy(&dst[off], data, nbytes);
- off += nbytes;
-
- va_start(args, nbytes);
-
- while( (src = va_arg(args, const void *)) )
- {
- nbytes = _sz(src, va_arg(args, int));
-
- memcpy(&dst[off], src, nbytes);
- off += nbytes;
- }
+ return mum_hash_finish(hash);
+}
- va_end(args);
+D2TK_API uint64_t
+d2tk_hash_dict(const d2tk_hash_dict_t *dict)
+{
+ uint64_t hash = mum_hash_init(SEED);
- return mum_hash(dst, sz, SEED);
+ for( ; dict->key; dict++)
+ {
+ hash = _d2tk_hash(hash, dict->key, dict->len);
}
- return 0;
+ return mum_hash_finish(hash);
}
diff --git a/test/mock.c b/test/mock.c
index 95ef6668..7e77a437 100644
--- a/test/mock.c
+++ b/test/mock.c
@@ -45,7 +45,9 @@ _d2tk_mock_post(void *data, d2tk_core_t *core, d2tk_coord_t w, d2tk_coord_t h,
assert(h == DIM_H);
assert(pass == 0);
- assert(d2tk_core_get_pixels(core));
+ d2tk_rect_t rect;
+ assert(d2tk_core_get_pixels(core, &rect));
+ assert( (rect.w != 0) && (rect.h != 0) );
return false; // do NOT enter 3rd pass
}