emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 409a9db: image-cache-size improvements


From: Mattias Engdegård
Subject: master 409a9db: image-cache-size improvements
Date: Sun, 20 Dec 2020 12:19:24 -0500 (EST)

branch: master
commit 409a9dbe9da64b4d75fec1f511e168c94e60e35b
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    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.
---
 src/image.c   | 58 +++++++++++++++++++++++++++++++++++++++++-----------------
 src/nsimage.m | 22 ++++++++++++++++++++++
 src/nsterm.h  |  2 ++
 src/w32gui.h  |  2 +-
 src/w32term.c |  4 ++--
 5 files changed, 68 insertions(+), 20 deletions(-)

diff --git a/src/image.c b/src/image.c
index dc06e9c..d0ae44e 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1793,37 +1793,61 @@ which is then usually a filename.  */)
 }
 
 static size_t
-image_frame_cache_size (struct frame *f)
+image_size_in_bytes (struct image *img)
 {
-  size_t total = 0;
+  size_t size = 0;
+
 #if defined USE_CAIRO
-  struct image_cache *c = FRAME_IMAGE_CACHE (f);
+  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;
 
-  if (!c)
-    return 0;
+#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;
 
-  for (ptrdiff_t i = 0; i < c->used; ++i)
-    {
-      struct image *img = c->images[i];
+#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);
 
-      if (img && img->pixmap && img->pixmap != NO_PIXMAP)
-       total += img->pixmap->width * img->pixmap->height  *
-         img->pixmap->bits_per_pixel / 8;
-    }
 #elif defined HAVE_NTGUI
-  struct image_cache *c = FRAME_IMAGE_CACHE (f);
+  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;
   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);
+      total += img ? image_size_in_bytes (img) : 0;
     }
-#endif
   return total;
 }
 
diff --git a/src/nsimage.m b/src/nsimage.m
index da6f01c..f9fb368 100644
--- a/src/nsimage.m
+++ b/src/nsimage.m
@@ -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
diff --git a/src/nsterm.h b/src/nsterm.h
index f292993..94472ec 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -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;
diff --git a/src/w32gui.h b/src/w32gui.h
index fc81311..f6cfa9f 100644
--- a/src/w32gui.h
+++ b/src/w32gui.h
@@ -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)
 
diff --git a/src/w32term.c b/src/w32term.c
index a038e45..989b056 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -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;
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]