]> git.eshelyaron.com Git - emacs.git/commitdiff
image-cache-size improvements
authorMattias Engdegård <mattiase@acm.org>
Sat, 19 Dec 2020 15:47:32 +0000 (16:47 +0100)
committerMattias Engdegård <mattiase@acm.org>
Sun, 20 Dec 2020 17:17:17 +0000 (18:17 +0100)
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
src/nsimage.m
src/nsterm.h
src/w32gui.h
src/w32term.c

index dc06e9ce208ab426e45c946282d122a8b698369e..d0ae44e7df7e69c051add0bf8ba0195eea8fc84f 100644 (file)
@@ -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;
 }
 
index da6f01cf6a3a1258c866b3703c33ac5baa1afe20..f9fb368ba802532c504ea9dc554b4c152dd773d0 100644 (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
index f292993d8f74d4845373ab1ee674e4262c72a4a1..94472ec107047362e569ab4bbe3d83ea84df53cd 100644 (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;
index fc8131130fb73621d99be0906cea632584b2b1ac..f6cfa9fb87ece2128abc5525a470060fc1a4e53f 100644 (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)
 
index a038e4593f46f92e1ab16e244bd6c33b3f5b11f9..989b056ff2e8648534a4eb01ae07789670a7ab6a 100644 (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;
 }