From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Chong Yidong Newsgroups: gmane.emacs.bugs Subject: bug#12463: 24.2; pos-visible-in-window-p gets slower over time Date: Sat, 22 Sep 2012 09:23:37 +0800 Message-ID: <87lig2q292.fsf@gnu.org> References: <87wqzs1a4c.fsf@queen.i-did-not-set--mail-host-address--so-tickle-me> <83mx0n22p0.fsf@gnu.org> <87d31jcqce.fsf@gnu.org> <4023344.MyoQPQRfcJ@queen> <87sjac1185.fsf@gnu.org> <878vc4ylr6.fsf@gnu.org> <87r4pvitjk.fsf@gnu.org> <838vc3xq8p.fsf@gnu.org> <83392bxobc.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1348277073 11085 80.91.229.3 (22 Sep 2012 01:24:33 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 22 Sep 2012 01:24:33 +0000 (UTC) Cc: Juanma Barranquero , jwalt@garni.ch, 12463@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Sep 22 03:24:36 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1TFESS-0007fq-Ds for geb-bug-gnu-emacs@m.gmane.org; Sat, 22 Sep 2012 03:24:36 +0200 Original-Received: from localhost ([::1]:57969 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TFESN-000311-Td for geb-bug-gnu-emacs@m.gmane.org; Fri, 21 Sep 2012 21:24:31 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:45237) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TFESI-0002xp-LQ for bug-gnu-emacs@gnu.org; Fri, 21 Sep 2012 21:24:28 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TFESE-0004fj-Tt for bug-gnu-emacs@gnu.org; Fri, 21 Sep 2012 21:24:26 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:38168) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TFESE-0004ff-Px for bug-gnu-emacs@gnu.org; Fri, 21 Sep 2012 21:24:22 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1TFETq-00015Z-91 for bug-gnu-emacs@gnu.org; Fri, 21 Sep 2012 21:26:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Chong Yidong Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 22 Sep 2012 01:26:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 12463 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 12463-submit@debbugs.gnu.org id=B12463.13482771284145 (code B ref 12463); Sat, 22 Sep 2012 01:26:02 +0000 Original-Received: (at 12463) by debbugs.gnu.org; 22 Sep 2012 01:25:28 +0000 Original-Received: from localhost ([127.0.0.1]:47714 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TFETH-00014n-2L for submit@debbugs.gnu.org; Fri, 21 Sep 2012 21:25:28 -0400 Original-Received: from mail-pb0-f44.google.com ([209.85.160.44]:63386) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TFETE-00014f-13 for 12463@debbugs.gnu.org; Fri, 21 Sep 2012 21:25:26 -0400 Original-Received: by pbbjt11 with SMTP id jt11so6458228pbb.3 for <12463@debbugs.gnu.org>; Fri, 21 Sep 2012 18:23:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; bh=aljom/1yjiNPX6Ii+UfthjVwPeSQPWecff/oY0mOlCE=; b=1Dfak91ELJ9JA9OI8nnf0ByhKQHYiGf+9yQMH6I1CK0tmWa4ueHNWSY7N3FkmLD+Wi qWCpZqFrxiKiOT5ciQwxKd3OTBag4Dq1yWpL82z2tZQmK4/hwnofmvdLvkOrpX2d2td0 OinMLx1y6o1iyqtbJCdsuGrJsVsn/WxXAPOXglOQ3Jg8GXcEJKHar+1XwVwpD5vKEopA nnDjJjP19Jg4E/8luMXOxgPo/eFcZOFqukLjiFz7jnC6cvvAmaQAVHPSWfssvGyEXAVA 8KrsnIEsviQdmn6JjbwMq4G8HCaEZrp4UFUwqoXuQsKLNjilkFGDvWGfWh0JdqUwxMeW cRBg== Original-Received: by 10.66.76.231 with SMTP id n7mr16930118paw.68.1348277023068; Fri, 21 Sep 2012 18:23:43 -0700 (PDT) Original-Received: from ulysses (cm162.gamma80.maxonline.com.sg. [202.156.80.162]) by mx.google.com with ESMTPS id s4sm4908594paw.35.2012.09.21.18.23.39 (version=SSLv3 cipher=OTHER); Fri, 21 Sep 2012 18:23:41 -0700 (PDT) In-Reply-To: <83392bxobc.fsf@gnu.org> (Eli Zaretskii's message of "Fri, 21 Sep 2012 20:45:11 +0300") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2.50 (gnu/linux) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:64710 Archived-At: --=-=-= Content-Type: text/plain Juanma helped me spot a few more errors in the patch off-list. Here's another iteration. I added a BLOCK_INPUT in define_image_type; this seems necessary because lookup_image_type can be called with input unblocked. If further testing does not turn up any issues, I'll commit it so that the Vlibrary_cache refactoring work can proceed. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=image.patch === modified file 'src/dispextern.h' *** src/dispextern.h 2012-09-13 02:21:28 +0000 --- src/dispextern.h 2012-09-21 09:29:26 +0000 *************** *** 2766,2771 **** --- 2766,2775 ---- /* Free resources of image IMG which is used on frame F. */ void (* free) (struct frame *f, struct image *img); + /* Initialization function (used for dynamic loading of image + libraries on Windows), or NULL if none. */ + int (* init) (Lisp_Object); + /* Next in list of all supported image types. */ struct image_type *next; }; === modified file 'src/image.c' *** src/image.c 2012-09-21 03:52:23 +0000 --- src/image.c 2012-09-22 01:19:13 +0000 *************** *** 561,568 **** /* Function prototypes. */ ! static Lisp_Object define_image_type (struct image_type *type, int loaded); ! static struct image_type *lookup_image_type (Lisp_Object symbol); static void image_error (const char *format, Lisp_Object, Lisp_Object); static void x_laplace (struct frame *, struct image *); static void x_emboss (struct frame *, struct image *); --- 561,568 ---- /* Function prototypes. */ ! static struct image_type *define_image_type (struct image_type *, Lisp_Object); ! static struct image_type *lookup_image_type (Lisp_Object, Lisp_Object); static void image_error (const char *format, Lisp_Object, Lisp_Object); static void x_laplace (struct frame *, struct image *); static void x_emboss (struct frame *, struct image *); *************** *** 579,632 **** do { Vimage_types = Fcons (type, Vimage_types); } while (0) /* Define a new image type from TYPE. This adds a copy of TYPE to ! image_types and caches the loading status of TYPE. */ ! static Lisp_Object ! define_image_type (struct image_type *type, int loaded) ! { ! Lisp_Object success; ! if (!loaded) ! success = Qnil; ! else { ! struct image_type *p; ! Lisp_Object target_type = *(type->type); ! for (p = image_types; p; p = p->next) ! if (EQ (*(p->type), target_type)) ! return Qt; /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. The initialized data segment is read-only. */ p = xmalloc (sizeof *p); *p = *type; p->next = image_types; image_types = p; - success = Qt; } ! CACHE_IMAGE_TYPE (*type->type, success); ! return success; ! } ! ! ! /* Look up image type SYMBOL, and return a pointer to its image_type ! structure. Value is null if SYMBOL is not a known image type. */ ! ! static inline struct image_type * ! lookup_image_type (Lisp_Object symbol) ! { ! struct image_type *type; ! ! /* We must initialize the image-type if it hasn't been already. */ ! if (NILP (Finit_image_library (symbol, Vdynamic_library_alist))) ! return 0; /* unimplemented */ ! ! for (type = image_types; type; type = type->next) ! if (EQ (symbol, *type->type)) ! break; ! ! return type; } --- 579,633 ---- do { Vimage_types = Fcons (type, Vimage_types); } while (0) /* Define a new image type from TYPE. This adds a copy of TYPE to ! image_types and caches the loading status of TYPE. ! LIBRARIES is an alist associating dynamic libraries to external ! files implementing them, which is passed to the image library ! initialization function if necessary. A nil value defaults to ! Vdynamic_library_alist. */ ! ! static struct image_type * ! define_image_type (struct image_type *type, Lisp_Object libraries) ! { ! struct image_type *p = NULL; ! Lisp_Object target_type = *type->type; ! int type_valid = 1; ! BLOCK_INPUT; ! ! for (p = image_types; p; p = p->next) ! if (EQ (*p->type, target_type)) ! goto done; ! ! if (type->init) { ! #ifdef HAVE_NTGUI ! /* If we failed to load the library before, don't try again. */ ! Lisp_Object tested = Fassq (target_type, Vlibrary_cache); ! if (CONSP (tested) && NILP (XCDR (tested))) ! type_valid = 0; ! else ! #endif ! { ! /* If the load failed, avoid trying again. */ ! type_valid = type->init (libraries); ! CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil); ! } ! } + if (type_valid) + { /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. The initialized data segment is read-only. */ p = xmalloc (sizeof *p); *p = *type; p->next = image_types; image_types = p; } ! done: ! UNBLOCK_INPUT; ! return p; } *************** *** 653,659 **** if (CONSP (tem) && SYMBOLP (XCAR (tem))) { struct image_type *type; ! type = lookup_image_type (XCAR (tem)); if (type) valid_p = type->valid_p (object); } --- 654,660 ---- if (CONSP (tem) && SYMBOLP (XCAR (tem))) { struct image_type *type; ! type = lookup_image_type (XCAR (tem), Qnil); if (type) valid_p = type->valid_p (object); } *************** *** 986,992 **** eassert (valid_image_p (spec)); img->dependencies = NILP (file) ? Qnil : list1 (file); ! img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL)); eassert (img->type != NULL); img->spec = spec; img->lisp_data = Qnil; --- 987,993 ---- eassert (valid_image_p (spec)); img->dependencies = NILP (file) ? Qnil : list1 (file); ! img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL), Qnil); eassert (img->type != NULL); img->spec = spec; img->lisp_data = Qnil; *************** *** 2262,2267 **** --- 2263,2269 ---- xbm_image_p, xbm_load, x_clear_image, + NULL, NULL }; *************** *** 3051,3056 **** --- 3053,3064 ---- {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; + #ifdef HAVE_NTGUI + static int init_xpm_functions (Lisp_Object); + #else + #define init_xpm_functions NULL + #endif + /* Structure describing the image type XPM. */ static struct image_type xpm_type = *************** *** 3059,3064 **** --- 3067,3073 ---- xpm_image_p, xpm_load, x_clear_image, + init_xpm_functions, NULL }; *************** *** 4981,4986 **** --- 4990,4996 ---- pbm_image_p, pbm_load, x_clear_image, + NULL, NULL }; *************** *** 5387,5392 **** --- 5397,5408 ---- {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; + #ifdef HAVE_NTGUI + static int init_png_functions (Lisp_Object); + #else + #define init_png_functions NULL + #endif + /* Structure describing the image type `png'. */ static struct image_type png_type = *************** *** 5395,5400 **** --- 5411,5417 ---- png_image_p, png_load, x_clear_image, + init_png_functions, NULL }; *************** *** 6039,6044 **** --- 6056,6067 ---- {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; + #ifdef HAVE_NTGUI + static int init_jpeg_functions (Lisp_Object); + #else + #define init_jpeg_functions NULL + #endif + /* Structure describing the image type `jpeg'. */ static struct image_type jpeg_type = *************** *** 6047,6052 **** --- 6070,6076 ---- jpeg_image_p, jpeg_load, x_clear_image, + init_jpeg_functions, NULL }; *************** *** 6624,6629 **** --- 6648,6659 ---- {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0} }; + #ifdef HAVE_NTGUI + static int init_tiff_functions (Lisp_Object); + #else + #define init_tiff_functions NULL + #endif + /* Structure describing the image type `tiff'. */ static struct image_type tiff_type = *************** *** 6632,6637 **** --- 6662,6668 ---- tiff_image_p, tiff_load, x_clear_image, + init_tiff_functions, NULL }; *************** *** 7072,7077 **** --- 7103,7114 ---- {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; + #ifdef HAVE_NTGUI + static int init_gif_functions (Lisp_Object); + #else + #define init_gif_functions NULL + #endif + /* Structure describing the image type `gif'. */ static struct image_type gif_type = *************** *** 7080,7085 **** --- 7117,7123 ---- gif_image_p, gif_load, gif_clear_image, + init_gif_functions, NULL }; *************** *** 7562,7567 **** --- 7600,7611 ---- {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0} }; + #ifdef HAVE_NTGUI + static int init_imagemagick_functions (Lisp_Object); + #else + #define init_imagemagick_functions NULL + #endif + /* Structure describing the image type for any image handled via ImageMagick. */ *************** *** 7571,7576 **** --- 7615,7621 ---- imagemagick_image_p, imagemagick_load, imagemagick_clear_image, + init_imagemagick_functions, NULL }; *************** *** 8109,8130 **** {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; /* Structure describing the image type `svg'. Its the same type of structure defined for all image formats, handled by emacs image functions. See struct image_type in dispextern.h. */ static struct image_type svg_type = { - /* An identifier showing that this is an image structure for the SVG format. */ &Qsvg, - /* Handle to a function that can be used to identify a SVG file. */ svg_image_p, - /* Handle to function used to load a SVG file. */ svg_load, - /* Handle to function to free sresources for SVG. */ x_clear_image, ! /* An internal field to link to the next image type in a list of ! image types, will be filled in when registering the format. */ NULL }; --- 8154,8176 ---- {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; + #ifdef HAVE_NTGUI + static int init_svg_functions (Lisp_Object); + #else + #define init_svg_functions NULL + #endif + /* Structure describing the image type `svg'. Its the same type of structure defined for all image formats, handled by emacs image functions. See struct image_type in dispextern.h. */ static struct image_type svg_type = { &Qsvg, svg_image_p, svg_load, x_clear_image, ! init_svg_functions, NULL }; *************** *** 8504,8509 **** --- 8550,8561 ---- {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; + #ifdef HAVE_NTGUI + static int init_gs_functions (Lisp_Object); + #else + #define init_gs_functions NULL + #endif + /* Structure describing the image type `ghostscript'. */ static struct image_type gs_type = *************** *** 8512,8517 **** --- 8564,8570 ---- gs_image_p, gs_load, gs_clear_image, + init_gs_functions, NULL }; *************** *** 8774,8789 **** Initialization ***********************************************************************/ - #ifdef HAVE_NTGUI - /* Image types that rely on external libraries are loaded dynamically - if the library is available. */ - #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \ - define_image_type (image_type, init_lib_fn (libraries)) - #else - #define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \ - define_image_type (image_type, 1) - #endif /* HAVE_NTGUI */ - DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0, doc: /* Initialize image library implementing image type TYPE. Return non-nil if TYPE is a supported image type. --- 8827,8832 ---- *************** *** 8793,8853 **** of `dynamic-library-alist', which see). */) (Lisp_Object type, Lisp_Object libraries) { ! #ifdef HAVE_NTGUI ! /* Don't try to reload the library. */ ! Lisp_Object tested = Fassq (type, Vlibrary_cache); ! if (CONSP (tested)) ! return XCDR (tested); ! #endif /* Types pbm and xbm are built-in and always available. */ ! if (EQ (type, Qpbm) || EQ (type, Qxbm)) ! return Qt; #if defined (HAVE_XPM) || defined (HAVE_NS) if (EQ (type, Qxpm)) ! return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries); #endif #if defined (HAVE_JPEG) || defined (HAVE_NS) if (EQ (type, Qjpeg)) ! return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries); #endif #if defined (HAVE_TIFF) || defined (HAVE_NS) if (EQ (type, Qtiff)) ! return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries); #endif #if defined (HAVE_GIF) || defined (HAVE_NS) if (EQ (type, Qgif)) ! return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries); #endif #if defined (HAVE_PNG) || defined (HAVE_NS) if (EQ (type, Qpng)) ! return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries); #endif #if defined (HAVE_RSVG) if (EQ (type, Qsvg)) ! return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries); #endif #if defined (HAVE_IMAGEMAGICK) if (EQ (type, Qimagemagick)) ! return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions, ! libraries); #endif #ifdef HAVE_GHOSTSCRIPT if (EQ (type, Qpostscript)) ! return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries); #endif ! /* If the type is not recognized, avoid testing it ever again. */ ! CACHE_IMAGE_TYPE (type, Qnil); ! return Qnil; } void --- 8836,8906 ---- of `dynamic-library-alist', which see). */) (Lisp_Object type, Lisp_Object libraries) { ! return lookup_image_type (type, libraries) ? Qt : Qnil; ! } ! ! /* Look up image type TYPE, and return a pointer to its image_type ! structure. Return 0 if TYPE is not a known image type. ! ! LIBRARIES is an alist associating dynamic libraries to external ! files implementing them, which is passed to the image library ! initialization function if necessary. A nil value defaults to ! Vdynamic_library_alist. */ ! ! static struct image_type * ! lookup_image_type (Lisp_Object type, Lisp_Object libraries) ! { ! if (NILP (libraries)) ! libraries = Vdynamic_library_alist; /* Types pbm and xbm are built-in and always available. */ ! if (EQ (type, Qpbm)) ! return define_image_type (&pbm_type, libraries); ! ! if (EQ (type, Qxbm)) ! return define_image_type (&xbm_type, libraries); #if defined (HAVE_XPM) || defined (HAVE_NS) if (EQ (type, Qxpm)) ! return define_image_type (&xpm_type, libraries); #endif #if defined (HAVE_JPEG) || defined (HAVE_NS) if (EQ (type, Qjpeg)) ! return define_image_type (&jpeg_type, libraries); #endif #if defined (HAVE_TIFF) || defined (HAVE_NS) if (EQ (type, Qtiff)) ! return define_image_type (&tiff_type, libraries); #endif #if defined (HAVE_GIF) || defined (HAVE_NS) if (EQ (type, Qgif)) ! return define_image_type (&gif_type, libraries); #endif #if defined (HAVE_PNG) || defined (HAVE_NS) if (EQ (type, Qpng)) ! return define_image_type (&png_type, libraries); #endif #if defined (HAVE_RSVG) if (EQ (type, Qsvg)) ! return define_image_type (&svg_type, libraries); #endif #if defined (HAVE_IMAGEMAGICK) if (EQ (type, Qimagemagick)) ! return define_image_type (&imagemagick_type, libraries); #endif #ifdef HAVE_GHOSTSCRIPT if (EQ (type, Qpostscript)) ! return define_image_type (&gs_type, libraries); #endif ! return NULL; } void *************** *** 8884,8892 **** DEFSYM (Qxbm, "xbm"); ADD_IMAGE_TYPE (Qxbm); - define_image_type (&xbm_type, 1); - define_image_type (&pbm_type, 1); - DEFSYM (Qcount, "count"); DEFSYM (Qextension_data, "extension-data"); DEFSYM (Qdelay, "delay"); --- 8937,8942 ---- --=-=-=--