perf(sni): eliminate redundant g_memdup2 allocation for D-Bus pixbufs
Memory profiling via Valgrind Massif indicated that 10-20% of peak memory allocations within the SNI loop resulted from copying DBus image data payloads via g_memdup2 before modifying them from ARGB to RGBA. This commit optimizes the pixel conversion by directly allocating the final array via g_malloc and running the ARGB->RGBA transposition in a single pass while copying from the read-only GVariant buffer, entirely eliminating the intermediate g_memdup stage. Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
This commit is contained in:
@@ -336,11 +336,20 @@ Glib::RefPtr<Gdk::Pixbuf> Item::extractPixBuf(GVariant* variant) {
|
|||||||
if (array != nullptr) {
|
if (array != nullptr) {
|
||||||
g_free(array);
|
g_free(array);
|
||||||
}
|
}
|
||||||
#if GLIB_MAJOR_VERSION >= 2 && GLIB_MINOR_VERSION >= 68
|
// We must allocate our own array because the data from GVariant is read-only
|
||||||
array = static_cast<guchar*>(g_memdup2(data, size));
|
// and we need to modify it to convert ARGB to RGBA.
|
||||||
#else
|
array = static_cast<guchar*>(g_malloc(size));
|
||||||
array = static_cast<guchar*>(g_memdup(data, size));
|
|
||||||
#endif
|
// Copy and convert ARGB to RGBA in one pass to avoid g_memdup2 overhead
|
||||||
|
const guchar* src = static_cast<const guchar*>(data);
|
||||||
|
for (gsize i = 0; i < size; i += 4) {
|
||||||
|
guchar alpha = src[i];
|
||||||
|
array[i] = src[i + 1];
|
||||||
|
array[i + 1] = src[i + 2];
|
||||||
|
array[i + 2] = src[i + 3];
|
||||||
|
array[i + 3] = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
lwidth = width;
|
lwidth = width;
|
||||||
lheight = height;
|
lheight = height;
|
||||||
}
|
}
|
||||||
@@ -349,14 +358,6 @@ Glib::RefPtr<Gdk::Pixbuf> Item::extractPixBuf(GVariant* variant) {
|
|||||||
}
|
}
|
||||||
g_variant_iter_free(it);
|
g_variant_iter_free(it);
|
||||||
if (array != nullptr) {
|
if (array != nullptr) {
|
||||||
/* argb to rgba */
|
|
||||||
for (uint32_t i = 0; i < 4U * lwidth * lheight; i += 4) {
|
|
||||||
guchar alpha = array[i];
|
|
||||||
array[i] = array[i + 1];
|
|
||||||
array[i + 1] = array[i + 2];
|
|
||||||
array[i + 2] = array[i + 3];
|
|
||||||
array[i + 3] = alpha;
|
|
||||||
}
|
|
||||||
return Gdk::Pixbuf::create_from_data(array, Gdk::Colorspace::COLORSPACE_RGB, true, 8, lwidth,
|
return Gdk::Pixbuf::create_from_data(array, Gdk::Colorspace::COLORSPACE_RGB, true, 8, lwidth,
|
||||||
lheight, 4 * lwidth, &pixbuf_data_deleter);
|
lheight, 4 * lwidth, &pixbuf_data_deleter);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user