1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-06 03:40:56 -08:00

image-cache-size improvements

Implement for non-Cairo X11 and NS.  Count masks as well, and
XImage objects on X11.

* src/image.c (image_size_in_bytes): New.
(image_frame_cache_size): Use image_size_in_bytes.
* src/nsterm.h:
* src/nsimage.m (ns_image_size_in_bytes, [EmacsImage sizeInBytes]):
New function and method.
* src/w32gui.h:
* src/w32term.c (w32_image_size): Update signature.
This commit is contained in:
Mattias Engdegård 2020-12-19 16:47:32 +01:00
parent 87b82a1969
commit 409a9dbe9d
5 changed files with 75 additions and 27 deletions

View file

@ -1792,38 +1792,62 @@ which is then usually a filename. */)
return Qnil;
}
static size_t
image_size_in_bytes (struct image *img)
{
size_t size = 0;
#if defined USE_CAIRO
Emacs_Pixmap pm = img->pixmap;
if (pm)
size += pm->height * pm->bytes_per_line;
Emacs_Pixmap msk = img->mask;
if (msk)
size += msk->height * msk->bytes_per_line;
#elif defined HAVE_X_WINDOWS
/* Use a nominal depth of 24 bpp for pixmap and 1 bpp for mask,
to avoid having to query the server. */
if (img->pixmap != NO_PIXMAP)
size += img->width * img->height * 3;
if (img->mask != NO_PIXMAP)
size += img->width * img->height / 8;
if (img->ximg && img->ximg->data)
size += img->ximg->bytes_per_line * img->ximg->height;
if (img->mask_img && img->mask_img->data)
size += img->mask_img->bytes_per_line * img->mask_img->height;
#elif defined HAVE_NS
if (img->pixmap)
size += ns_image_size_in_bytes (img->pixmap);
if (img->mask)
size += ns_image_size_in_bytes (img->mask);
#elif defined HAVE_NTGUI
if (img->pixmap)
size += w32_image_size (img->pixmap);
if (img->mask)
size += w32_image_size (img->mask);
#endif
return size;
}
static size_t
image_frame_cache_size (struct frame *f)
{
struct image_cache *c = FRAME_IMAGE_CACHE (f);
if (!c)
return 0;
size_t total = 0;
#if defined USE_CAIRO
struct image_cache *c = FRAME_IMAGE_CACHE (f);
if (!c)
return 0;
for (ptrdiff_t i = 0; i < c->used; ++i)
{
struct image *img = c->images[i];
if (img && img->pixmap && img->pixmap != NO_PIXMAP)
total += img->pixmap->width * img->pixmap->height *
img->pixmap->bits_per_pixel / 8;
total += img ? image_size_in_bytes (img) : 0;
}
#elif defined HAVE_NTGUI
struct image_cache *c = FRAME_IMAGE_CACHE (f);
if (!c)
return 0;
for (ptrdiff_t i = 0; i < c->used; ++i)
{
struct image *img = c->images[i];
if (img && img->pixmap && img->pixmap != NO_PIXMAP)
total += w32_image_size (img);
}
#endif
return total;
}

View file

@ -235,6 +235,11 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
[(EmacsImage *)img setAlphaAtX: x Y: y to: a];
}
size_t
ns_image_size_in_bytes (void *img)
{
return [(EmacsImage *)img sizeInBytes];
}
/* ==========================================================================
@ -610,5 +615,22 @@ ns_set_alpha (void *img, int x, int y, unsigned char a)
smoothing = s;
}
/* Approximate allocated size of image in bytes. */
- (size_t) sizeInBytes
{
size_t bytes = 0;
NSImageRep *rep;
NSEnumerator *reps = [[self representations] objectEnumerator];
while ((rep = (NSImageRep *) [reps nextObject]))
{
if ([rep respondsToSelector: @selector (bytesPerRow)])
{
NSBitmapImageRep *bmr = (NSBitmapImageRep *) rep;
bytes += [bmr bytesPerRow] * [bmr numberOfPlanes] * [bmr pixelsHigh];
}
}
return bytes;
}
@end

View file

@ -666,6 +666,7 @@ typedef id instancetype;
- (BOOL)setFrame: (unsigned int) index;
- (void)setTransform: (double[3][3]) m;
- (void)setSmoothing: (BOOL)s;
- (size_t)sizeInBytes;
@end
@ -1195,6 +1196,7 @@ extern void ns_set_alpha (void *img, int x, int y, unsigned char a);
extern int ns_display_pixel_height (struct ns_display_info *);
extern int ns_display_pixel_width (struct ns_display_info *);
extern size_t ns_image_size_in_bytes (void *img);
/* This in nsterm.m */
extern float ns_antialias_threshold;

View file

@ -46,7 +46,7 @@ extern int w32_load_image (struct frame *f, struct image *img,
Lisp_Object spec_file, Lisp_Object spec_data);
extern bool w32_can_use_native_image_api (Lisp_Object);
extern void w32_gdiplus_shutdown (void);
extern size_t w32_image_size (struct image *);
extern size_t w32_image_size (Emacs_Pixmap);
#define FACE_DEFAULT (~0)

View file

@ -1992,12 +1992,12 @@ w32_draw_image_foreground (struct glyph_string *s)
}
size_t
w32_image_size (struct image *img)
w32_image_size (Emacs_Pixmap pixmap)
{
BITMAP bm_info;
size_t rv = 0;
if (GetObject (img->pixmap, sizeof (BITMAP), &bm_info))
if (GetObject (pixmap, sizeof (BITMAP), &bm_info))
rv = bm_info.bmWidth * bm_info.bmHeight * bm_info.bmBitsPixel / 8;
return rv;
}