diff options
author | ahze <ahze@df743ca5-7f9a-e211-a948-0013205c9059> | 2007-09-11 00:26:50 +0800 |
---|---|---|
committer | ahze <ahze@df743ca5-7f9a-e211-a948-0013205c9059> | 2007-09-11 00:26:50 +0800 |
commit | d48a46571bd96ee505054c0a0e84bd325ca0eb9f (patch) | |
tree | 46707b70770ce3675c8348014f68fc55da61ac53 /www | |
parent | 4a53ee49a47f4f5932b8198e3e1c9cc4922f0631 (diff) | |
download | marcuscom-ports-d48a46571bd96ee505054c0a0e84bd325ca0eb9f.tar marcuscom-ports-d48a46571bd96ee505054c0a0e84bd325ca0eb9f.tar.gz marcuscom-ports-d48a46571bd96ee505054c0a0e84bd325ca0eb9f.tar.bz2 marcuscom-ports-d48a46571bd96ee505054c0a0e84bd325ca0eb9f.tar.lz marcuscom-ports-d48a46571bd96ee505054c0a0e84bd325ca0eb9f.tar.xz marcuscom-ports-d48a46571bd96ee505054c0a0e84bd325ca0eb9f.tar.zst marcuscom-ports-d48a46571bd96ee505054c0a0e84bd325ca0eb9f.zip |
- Update to 3.0 alpha 7
- Add a patch that fixes the image loader that discards JPEG and PNG images
after a few seconds of inactivity.
See http://primates.ximian.com/~federico/news-2007-09.html#firefox-memory-2
for more info.
Obtained from: https://bugzilla.mozilla.org/show_bug.cgi?id=296818
git-svn-id: svn://creme-brulee.marcuscom.com/ports/trunk@9560 df743ca5-7f9a-e211-a948-0013205c9059
Diffstat (limited to 'www')
-rw-r--r-- | www/firefox-devel/Makefile | 16 | ||||
-rw-r--r-- | www/firefox-devel/distinfo | 6 | ||||
-rw-r--r-- | www/firefox-devel/files/patch-bugzilla296818 | 1621 | ||||
-rw-r--r-- | www/firefox-devel/files/patch-sysnss | 20 | ||||
-rw-r--r-- | www/firefox-devel/files/patch-toolkit_xre_Makefile.in | 8 | ||||
-rw-r--r-- | www/firefox-devel/files/patch-toolkit_xre_nsXREDirProvider.cpp | 19 | ||||
-rw-r--r-- | www/firefox3-devel/Makefile | 16 | ||||
-rw-r--r-- | www/firefox3-devel/distinfo | 6 | ||||
-rw-r--r-- | www/firefox3-devel/files/patch-bugzilla296818 | 1621 | ||||
-rw-r--r-- | www/firefox3-devel/files/patch-sysnss | 20 | ||||
-rw-r--r-- | www/firefox3-devel/files/patch-toolkit_xre_Makefile.in | 8 | ||||
-rw-r--r-- | www/firefox3-devel/files/patch-toolkit_xre_nsXREDirProvider.cpp | 19 |
12 files changed, 3306 insertions, 74 deletions
diff --git a/www/firefox-devel/Makefile b/www/firefox-devel/Makefile index e73df790b..cc8e6b375 100644 --- a/www/firefox-devel/Makefile +++ b/www/firefox-devel/Makefile @@ -6,13 +6,13 @@ # $MCom: ports/www/firefox-devel/Makefile,v 1.38 2007/07/05 16:52:19 ahze Exp $ PORTNAME= firefox -DISTVERSION= 3.0.a6 +DISTVERSION= 3.0.a7 PORTEPOCH= 1 CATEGORIES= www ipv6 MASTER_SITES= ${MASTER_SITE_MOZILLA} -MASTER_SITE_SUBDIR= ${PORTNAME}/releases/granparadiso/alpha6/source/ +MASTER_SITE_SUBDIR= ${PORTNAME}/releases/granparadiso/alpha7/source/ #MASTER_SITE_SUBDIR= ${PORTNAME}/releases/${DISTVERSION}/source -DISTNAME= granparadiso-alpha6-source +DISTNAME= granparadiso-alpha7-source #DISTNAME= ${PORTNAME}-${DISTVERSION}-source MAINTAINER= gnome@FreeBSD.org @@ -21,7 +21,8 @@ COMMENT= Web browser based on the browser portion of Mozilla MOZILLA_NAME= Firefox-${MOZILLA_SUFX} MOZILLA_SUFX= -devel MOZILLA= ${PORTNAME}${MOZILLA_SUFX} -MOZ_OPTIONS= --program-transform-name='s/firefox/${MOZILLA}/' +MOZ_OPTIONS= --program-transform-name='s/firefox/${MOZILLA}/' \ + --enable-svg --enable-svg-renderer=cairo MOZ_TOOLKIT= cairo-gtk2 WANT_GNOME= yes @@ -52,12 +53,6 @@ OPTIONS= NEWTAB "Open external links in a new tab" on \ GECKO_PTHREAD_LIBS!=${CC} -dumpspecs | ${GREP} -m 1 pthread | ${SED} -e 's|^.*%{\!pg: %{pthread:|| ; s|}.*$$||' || ${TRUE} -MOZ_OPTIONS+= --disable-svg -#.if ${OSVERSION} >= 600000 -# Needs MOZ_TOOLKIT=cairo-gtk2 -#MOZ_OPTIONS+= --enable-svg --enable-svg-renderer=cairo -#.endif - post-extract:: @${SED} -e 's|@FIREFOX_ICON@|${FIREFOX_ICON}|' -e 's|@MOZILLA@|${MOZILLA}|' \ -e 's|@MOZILLA_NAME@|${MOZILLA_NAME}|' \ @@ -75,6 +70,7 @@ post-patch: .endfor port-pre-install: + ${SED} -e 's|1.9a7|0|' ${WRKSRC}/dist/bin/application.ini ${FAKEDIR}/lib ${ECHO_CMD} 'share/applications/${MOZILLA}.desktop' >> ${PLIST} ${ECHO_CMD} "@unexec ${RMDIR} %D/share/applications 2>/dev/null || ${TRUE}" >> ${PLIST} ${ECHO_CMD} 'share/pixmaps/${FIREFOX_ICON}' >> ${PLIST} diff --git a/www/firefox-devel/distinfo b/www/firefox-devel/distinfo index 23ffc5599..1340a04a1 100644 --- a/www/firefox-devel/distinfo +++ b/www/firefox-devel/distinfo @@ -1,3 +1,3 @@ -MD5 (granparadiso-alpha6-source.tar.bz2) = 9b892de32d4067824eeea00d45d475de -SHA256 (granparadiso-alpha6-source.tar.bz2) = 57d5de020b439be173a6a1a13e11903d113240c45fd04b63ff12cc61edf89059 -SIZE (granparadiso-alpha6-source.tar.bz2) = 33740574 +MD5 (granparadiso-alpha7-source.tar.bz2) = cd692127775b55f5e64685ef49788c1c +SHA256 (granparadiso-alpha7-source.tar.bz2) = 91369eff2bba6b0ef3a9b5a40a1585b27f66a670f1a96299852f2595bd96f209 +SIZE (granparadiso-alpha7-source.tar.bz2) = 35319889 diff --git a/www/firefox-devel/files/patch-bugzilla296818 b/www/firefox-devel/files/patch-bugzilla296818 new file mode 100644 index 000000000..a7f22b4eb --- /dev/null +++ b/www/firefox-devel/files/patch-bugzilla296818 @@ -0,0 +1,1621 @@ +diff --git ChangeLog ChangeLog +new file mode 100644 +index 0000000..c9c7dce +--- /dev/null ++++ ChangeLog +@@ -0,0 +1,277 @@ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Write the restore data regardless of ++ the state we are in, right when we first fill the buffer. ++ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::RestoreDataDone): Print the first four bytes of the ++ restore data, to check it later. ++ (imgContainer::ReloadImages): Likewise. ++ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/png/nsPNGDecoder.cpp (info_callback): ++ Reuse the image container if the loader has one; don't always ++ create a new one. This lets containers reload themselves. ++ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::AppendFrame): Unconditionally increment mNumFrames! ++ (imgContainer::RestoreDiscardedData): Check the number of restored ++ frames here. ++ (imgContainer::ReloadImages): Flush and close the decoder. ++ (imgContainer::RestoreDataDone): No-op if we are already restoring ++ the data. ++ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/png/nsPNGDecoder.cpp (*): Print the ++ imgContainer pointers when logging. ++ ++ * modules/libpr0n/src/imgContainer.cpp (*): Likewise. ++ ++2007-09-04 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::ReloadImages): Oops, use an nsCOMPtr<> for the ++ ContainerLoader, not a direct pointer. ++ (ContainerLoader NS_IMPL_ISUPPORTS3): Oops, we also implement ++ imgIContainerObserver. ++ (class ContainerLoader): Implement nsISupportsWeakReference as ++ well; imgContainer needs it from the observer. ++ (imgContainer::RestoreDiscardedData): Log how many frames we got ++ and how many we expected. ++ (imgContainer::ReloadImages): Assert that we got the right number ++ of frames. ++ (imgContainer::GetCurrentFrameNoRef): Log failures from ++ RestoreDiscardedData(). ++ ++ * modules/libpr0n/decoders/png/nsPNGDecoder.cpp (end_callback): ++ Don't tell the container that the restore data is done here... ++ (nsPNGDecoder::Close): ... but do it here instead. This is ++ because end_callback() gets called from within ReadDataOut(); we ++ don't want end_callback() to inform the container that the restore ++ data is done before actually writing the restore data to it! ++ ++2007-09-04 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/png/nsPNGDecoder.cpp (info_callback): ++ Set the image container as discardable. ++ (ReadDataOut): Store the compressed data in the image container to ++ restore from it later. ++ (end_callback): Tell the image container that we finished feeding ++ it the restore data. ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::SetDiscardable): Log the MIME type of the ++ discardable container. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Clean up a printf format, and do the ++ logging only on success. ++ ++ * gfx/thebes/public/gfxXlibSurface.h: Add myself to the contributors. ++ * modules/libpr0n/public/imgIContainer.idl: Likewise. ++ * modules/libpr0n/src/imgContainer.cpp: Likewise. ++ * modules/libpr0n/src/imgContainer.h: Likewise. ++ ++2007-09-03 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::AddRestoreData): No-op if we are being called ++ during the restore process (we already have the data; there is no ++ need to save it again). ++ (class ContainerLoader): Put the macro to implement QI for ++ imgILoad and imgIDecoderObserver. ++ (imgContainer::AppendFrame): Don't increment mNumFrames if we are ++ restoring the image data. Fix the use of the frame counters. ++ (imgContainer::sDiscardTimerCallback): Implement. ++ (imgContainer::GetCurrentFrame): Oops, preserve the semantics of ++ the original function --- if the actual getter gives us a null ++ frame, return NS_ERROR_FAILURE. ++ ++2007-08-31 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.h (class imgContainer): New ++ prototype for a ReloadImages() method. ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::RestoreDiscardedData): Call ReloadImages(). ++ (imgContainer::ReloadImages): Implement. ++ (class ContainerLoader): New helper class that implements ++ imgILoader and imgIDecoderObserver. We'll use this to re-load the ++ imgContainer from an image decoder. ++ ++2007-08-31 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::RestoreDiscardedData): Reset the timer; if we got ++ here it means that the data may be used again soon. ++ ++2007-08-30 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.h (class imgContainer): Add an ++ mDiscarded field. We'll use it to know if the uncompressed image ++ data has been discarded already and needs to be regenerated on ++ demand. ++ (class imgContainer): New prototype for a RestoreDiscardedData() method. ++ ++ * modules/libpr0n/src/imgContainer.cpp (imgContainer): Initialize ++ mDiscarded. ++ (imgContainer::GetCurrentFrameNoRef): Return an nsresult rather ++ than the image frame; return the actual image frame as a ++ reference. Ensure that the discarded data gets restored. ++ (imgContainer::GetCurrentFrame): Return the error from ++ GetCurrentFrameNoRef() if it fails. ++ (imgContainer::StartAnimation): Likewise. ++ (imgContainer::GetFrameAt): Ensure that the discarded data gets restored. ++ (imgContainer::ResetAnimation): Likewise. ++ (imgContainer::Notify): Likewise. ++ (imgContainer::RestoreDiscardedData): Just a stub for now. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Oops, use "count" for the restore ++ data, not "mBufferLen". ++ ++2007-08-29 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.h (class imgContainer): Add a ++ mNumFrames field. Since we'll discard the contents of mFrames, we ++ can't rely on mFrames.Count() for the frame count. ++ ++ * modules/libpr0n/src/imgContainer.cpp (imgContainer): Initialize mNumFrames. ++ (imgContainer::AppendFrame): Maintain the frame count in mNumFrames. ++ (imgContainer::GetNumFrames): Use mNumFrames instead of mFrames.Count(). ++ (imgContainer::GetFrameAt): Likewise. ++ (imgContainer::DecodingComplete): Likewise. ++ (imgContainer::SetAnimationMode): Likewise. ++ (imgContainer::StartAnimation): Likewise. ++ (imgContainer::Notify): Likewise. ++ ++2007-08-29 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.h ++ (imgContainer::inlinedGetCurrentFrame): Removed to make it not ++ inline. ++ (imgContainer::GetCurrentFrameNoRef): New prototype. ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::GetCurrentFrameNoRef): Implement this here. ++ (imgContainer::GetCurrentFrame, imgContainer::StartAnimation): Use ++ GetCurrentFrameNoRef() instead of inlinedGetCurrentFrame(). ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/public/imgIContainer.idl (restoreDataDone): New ++ method. We'll use this to tell the container when we finish ++ feeding it the compressed data. After that, it can begin its ++ discard process whenever it wants. ++ ++ * modules/libpr0n/src/imgContainer.h (class imgContainer): Add ++ mRestoreDataDone and mDiscardTimer fields. ++ ++ * modules/libpr0n/src/imgContainer.cpp (imgContainer): Initialize ++ the new fields. ++ (imgContainer::RestoreDataDone): Implement. When turned on, we ++ start the discard timer. ++ (imgContainer::ResetDiscardTimer): New method. ++ (~imgContainer): Cancel and destroy the timer. ++ (imgContainer::sDiscardTimerCallback): New callback. Here we'll ++ discard the uncompressed image data in the image frames. For now ++ this is just a stub. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Tell the imgContainer when we are done ++ feeding data to it. ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp (discarding_is_enabled): ++ Stub function, to be replaced with something better in the ++ future. This lets us disable image discarding by setting a ++ MOZ_DISABLE_IMAGE_DISCARD environment variable. ++ (imgContainer::SetDiscardable): Noop if discarding is disabled. ++ (imgContainer::AddRestoreData): Likewise. ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Mark the imgContainer as discardable ++ when we create it. And when writing to the JPEG decoder, add the ++ compressed data to the imgContainer so that it can restore itself ++ later. ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (gCompressedImageAccountingLog): Create a ++ "CompressedImageAccounting" log domain. ++ (~imgContainer): Log the destruction of compressed data. ++ (imgContainer::AddRestoreData): Log the addition of compressed data. ++ (imgContainer::SetDiscardable): Log the creation of a compressed imgContainer. ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ ++ * modules/libpr0n/src/imgContainer.cpp (~imgContainer): Free the ++ restore data and the MIME type. ++ ++2007-08-22 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/public/imgIContainer.idl (setDiscardable): New ++ method. When this is called (can be called only once) from an ++ image decoder, the image container will discard its uncompressed ++ image data after a timeout. ++ (addRestoreData): New method. Image decoders should call this ++ repeatedly after calling setDiscardable(); this is used to feed ++ the original, compressed image data to the image container so that ++ it can uncompress it on demand after discarding it. ++ ++ * modules/libpr0n/src/imgContainer.cpp (imgContainer::SetDiscardable): ++ Implement. ++ (imgContainer::AddRestoreData): Implement. ++ ++2007-08-20 Federico Mena Quintero <federico@novell.com> ++ ++ * gfx/thebes/src/gfxXlibSurface.cpp ++ (gfxXlibSurface::LogSurfaceCreation, surface_destroy_func): Count ++ the number of surfaces in addition to the number of pixels. ++ ++2007-08-17 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/public/ImageLogging.h: Remove gImgAccountingLog ++ from here. ++ ++ * modules/libpr0n/src/imgRequest.cpp: Likewise. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (gJPEGDecodeAccountingLog): Create a "JPEGDecoderAccounting" log domain. ++ (nsJPEGDecoder::WriteFrom): Use that log domain. ++ ++ * gfx/thebes/src/gfxXlibSurface.cpp (gXlibSurfaceAccountingLog): ++ Define a "XlibSurfaceAccounting" log domain. ++ (gfxXlibSurface::LogSurfaceCreation): New method to log when an ++ Xlib surface is created from a pixmap. Keeps a counter of how ++ many pixels are allocated globally. ++ (gfxXlibSurface::HookSurfaceDestructionForLogging): Utility method ++ to set user data on the cairo surface, so that we can know when it ++ is destroyed. ++ (gfxXlibSurface::gfxXlibSurface): Log the creation of the surface, ++ and hook it so that we can know when it is destroyed. ++ ++2007-08-17 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgRequest.cpp (gImgAccountingLog): New ++ logging domain "imgAccounting". We'll use this to log when images ++ get allocated, freed, requested, etc. ++ ++ * modules/libpr0n/public/ImageLogging.h (gImgAccountingLog): ++ Declare this. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Log the creation of an image frame. ++ +diff --git gfx/thebes/public/gfxXlibSurface.h gfx/thebes/public/gfxXlibSurface.h +index 078dc73..ea7ba24 100644 +--- gfx/thebes/public/gfxXlibSurface.h ++++ gfx/thebes/public/gfxXlibSurface.h +@@ -21,6 +21,7 @@ + * Contributor(s): + * Stuart Parmenter <pavlov@pavlov.net> + * Vladimir Vukicevic <vladimir@pobox.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -85,6 +86,9 @@ public: + // when the gfxXlibSurface is destroyed. + void TakePixmap(); + ++ void LogSurfaceCreation (); ++ void HookSurfaceDestructionForLogging (); ++ + protected: + // if TakePixmap() was already called on this + PRBool mPixmapTaken; +diff --git gfx/thebes/src/gfxXlibSurface.cpp gfx/thebes/src/gfxXlibSurface.cpp +index dc2a19f..f9c191c 100644 +--- gfx/thebes/src/gfxXlibSurface.cpp ++++ gfx/thebes/src/gfxXlibSurface.cpp +@@ -21,6 +21,7 @@ + * Contributor(s): + * Stuart Parmenter <pavlov@pavlov.net> + * Vladimir Vukicevic <vladimir@pobox.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -37,6 +38,7 @@ + * ***** END LICENSE BLOCK ***** */ + + #include "gfxXlibSurface.h" ++#include "prlog.h" + + #include "cairo.h" + #include "cairo-xlib.h" +@@ -51,6 +53,18 @@ typedef struct { + + static void pixmap_free_func (void *); + ++ ++#if defined(PR_LOGGING) ++static PRLogModuleInfo *gXlibSurfaceAccountingLog = PR_NewLogModule ("XlibSurfaceAccounting"); ++#else ++#define gXlibSurfaceAccountingLog ++#endif ++ ++static cairo_user_data_key_t surface_free_key; ++static int num_surfaces_allocated; ++static PRInt64 pixels_allocated; ++ ++ + #define XLIB_IMAGE_SIDE_SIZE_LIMIT 0xffff + + gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual) +@@ -59,6 +73,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual) + DoSizeQuery(); + cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, mSize.width, mSize.height); + Init(surf); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfxIntSize& size) +@@ -69,6 +86,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, + + cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, mSize.width, mSize.height); + Init(surf); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size) +@@ -87,6 +107,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& s + + Init(surf); + TakePixmap(); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, XRenderPictFormat *format, +@@ -100,6 +123,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, XRenderPictForma + ScreenOfDisplay(dpy,DefaultScreen(dpy)), + format, mSize.width, mSize.height); + Init(surf); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(Display *dpy, XRenderPictFormat *format, const gfxIntSize& size) +@@ -115,6 +141,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, XRenderPictFormat *format, const gf + format, mSize.width, mSize.height); + Init(surf); + TakePixmap(); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf) +@@ -124,6 +153,9 @@ gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf) + mDisplay = cairo_xlib_surface_get_display(csurf); + + Init(csurf, PR_TRUE); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::~gfxXlibSurface() +@@ -198,3 +230,63 @@ pixmap_free_func (void *data) + + delete pfs; + } ++ ++void ++gfxXlibSurface::LogSurfaceCreation () ++{ ++ gfxIntSize size; ++ ++ size = GetSize (); ++ ++ num_surfaces_allocated++; ++ pixels_allocated += (PRInt64) size.width * size.height; ++ ++ PR_LOG (gXlibSurfaceAccountingLog, PR_LOG_DEBUG, ++ ("XlibSurfaceAccounting: Xlib surface %p created, %ux%u pixels - %d surfaces with %lld global pixels allocated", ++ CairoSurface (), ++ size.width, ++ size.height, ++ num_surfaces_allocated, ++ pixels_allocated)); ++} ++ ++struct SurfaceFreeData { ++ gfxIntSize size; ++ cairo_surface_t *surface; ++}; ++ ++static void ++surface_destroy_func (void *closure) ++{ ++ SurfaceFreeData *data; ++ ++ data = (SurfaceFreeData *) closure; ++ ++ num_surfaces_allocated--; ++ pixels_allocated -= (PRInt64) data->size.width * data->size.height; ++ ++ PR_LOG (gXlibSurfaceAccountingLog, PR_LOG_DEBUG, ++ ("XlibSurfaceAccounting: Destroying Xlib surface %p, %dx%d pixels - %d surfaces with %lld global pixels allocated", ++ data->surface, ++ data->size.width, ++ data->size.height, ++ num_surfaces_allocated, ++ pixels_allocated)); ++ ++ delete data; ++} ++ ++void ++gfxXlibSurface::HookSurfaceDestructionForLogging () ++{ ++ SurfaceFreeData *data; ++ ++ data = new SurfaceFreeData; ++ data->size = GetSize (); ++ data->surface = CairoSurface (); ++ ++ cairo_surface_set_user_data (data->surface, ++ &surface_free_key, ++ data, ++ surface_destroy_func); ++} +diff --git modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp +index 16b9fd8..48431e4 100644 +--- modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++++ modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp +@@ -22,6 +22,7 @@ + * + * Contributor(s): + * Stuart Parmenter <stuart@mozilla.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -63,8 +64,10 @@ NS_IMPL_ISUPPORTS1(nsJPEGDecoder, imgIDecoder) + + #if defined(PR_LOGGING) + PRLogModuleInfo *gJPEGlog = PR_NewLogModule("JPEGDecoder"); ++static PRLogModuleInfo *gJPEGDecoderAccountingLog = PR_NewLogModule ("JPEGDecoderAccounting"); + #else + #define gJPEGlog ++#define gJPEGDecoderAccountingLog + #endif + + +@@ -208,6 +211,15 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + nsresult rv = inStr->Read((char*)mBuffer, count, &mBufferLen); + *_retval = mBufferLen; + ++ if (mImage) { ++ nsresult result = mImage->AddRestoreData ((char *) mBuffer, count); ++ ++ if (NS_FAILED (result)) { ++ mState = JPEG_ERROR; ++ return result; ++ } ++ } ++ + NS_ASSERTION(NS_SUCCEEDED(rv), "nsJPEGDecoder::WriteFrom -- inStr->Read failed"); + } + // else no input stream.. Flush() ? +@@ -357,6 +369,9 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + /* Check if the request already has an image container. + this is the case when multipart/x-mixed-replace is being downloaded + if we already have one and it has the same width and height, reuse it. ++ ++ This is also the case when an existing container is reloading itself from ++ us. + */ + mImageLoad->GetImage(getter_AddRefs(mImage)); + if (mImage) { +@@ -370,6 +385,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + } + + if (!mImage) { ++ nsresult result; ++ + mImage = do_CreateInstance("@mozilla.org/image/container;1"); + if (!mImage) { + mState = JPEG_ERROR; +@@ -377,6 +394,18 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + } + mImageLoad->SetImage(mImage); + mImage->Init(mInfo.image_width, mInfo.image_height, mObserver); ++ ++ result = mImage->SetDiscardable ("image/jpeg"); /* FIXME: is this MIME type always right for this decoder? */ ++ if (NS_FAILED (result)) { ++ mState = JPEG_ERROR; ++ return result; ++ } ++ ++ result = mImage->AddRestoreData ((char *) mBuffer, count); ++ if (NS_FAILED (result)) { ++ mState = JPEG_ERROR; ++ return result; ++ } + } + + mObserver->OnStartContainer(nsnull, mImage); +@@ -416,7 +445,11 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + } + + mImage->AppendFrame(mFrame); +- } ++ ++ PR_LOG (gJPEGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("JPEGDecoderAccounting: nsJPEGDecoder::WriteFrom -- created image frame with %ux%u pixels", ++ mInfo.image_width, mInfo.image_height)); ++ } + + mObserver->OnStartFrame(nsnull, mFrame); + +@@ -538,6 +571,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + + case JPEG_DONE: + { ++ nsresult result; ++ + LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_DONE case"); + + /* Step 7: Finish decompression */ +@@ -547,6 +582,12 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + + mState = JPEG_SINK_NON_JPEG_TRAILER; + ++ result = mImage->RestoreDataDone (); ++ if (NS_FAILED (result)) { ++ mState = JPEG_ERROR; ++ return result; ++ } ++ + /* we're done dude */ + break; + } +diff --git modules/libpr0n/decoders/png/nsPNGDecoder.cpp modules/libpr0n/decoders/png/nsPNGDecoder.cpp +index 85f0216..15abc9f 100644 +--- modules/libpr0n/decoders/png/nsPNGDecoder.cpp ++++ modules/libpr0n/decoders/png/nsPNGDecoder.cpp +@@ -23,6 +23,7 @@ + * Contributor(s): + * Stuart Parmenter <stuart@mozilla.com> + * Andrew Smith ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -73,6 +74,7 @@ static void PNGAPI warning_callback(png_structp png_ptr, png_const_charp warning + + #ifdef PR_LOGGING + PRLogModuleInfo *gPNGLog = PR_NewLogModule("PNGDecoder"); ++static PRLogModuleInfo *gPNGDecoderAccountingLog = PR_NewLogModule ("PNGDecoderAccounting"); + #endif + + NS_IMPL_ISUPPORTS1(nsPNGDecoder, imgIDecoder) +@@ -119,6 +121,11 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, + + if (mObserver) + mObserver->OnStartFrame(nsnull, mFrame); ++ ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created image frame with %dx%d pixels in container %p", ++ width, height, ++ mImage.get ())); + } + + // set timeout and frame disposal method for the current frame +@@ -213,9 +220,25 @@ NS_IMETHODIMP nsPNGDecoder::Init(imgILoad *aLoad) + /* void close (); */ + NS_IMETHODIMP nsPNGDecoder::Close() + { ++ nsresult result; ++ + if (mPNG) + png_destroy_read_struct(&mPNG, mInfo ? &mInfo : NULL, NULL); + ++ result = mImage->RestoreDataDone (); ++ if (NS_FAILED (result)) { ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: nsPNGDecoder::Close(): failure in RestoreDataDone() for image container %p", ++ mImage.get ())); ++ ++ mError = PR_TRUE; ++ return result; ++ } ++ ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: nsPNGDecoder::Close(): image container %p is now with RestoreDataDone", ++ mImage.get ())); ++ + return NS_OK; + } + +@@ -234,6 +257,7 @@ static NS_METHOD ReadDataOut(nsIInputStream* in, + PRUint32 *writeCount) + { + nsPNGDecoder *decoder = static_cast<nsPNGDecoder*>(closure); ++ nsresult result; + + if (decoder->mError) { + *writeCount = 0; +@@ -248,10 +272,24 @@ static NS_METHOD ReadDataOut(nsIInputStream* in, + *writeCount = 0; + return NS_ERROR_FAILURE; + } +- + png_process_data(decoder->mPNG, decoder->mInfo, + reinterpret_cast<unsigned char *>(const_cast<char *>(fromRawSegment)), count); + ++ result = decoder->mImage->AddRestoreData ((char *) fromRawSegment, count); ++ if (NS_FAILED (result)) { ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: ReadDataOut(): failed to add restore data to image container %p", ++ decoder->mImage.get ())); ++ ++ decoder->mError = PR_TRUE; ++ *writeCount = 0; ++ return result; ++ } ++ ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: ReadDataOut(): Added restore data to image container %p", ++ decoder->mImage.get ())); ++ + *writeCount = count; + return NS_OK; + } +@@ -525,13 +563,41 @@ info_callback(png_structp png_ptr, png_infop info_ptr) + if (decoder->mObserver) + decoder->mObserver->OnStartDecode(nsnull); + +- decoder->mImage = do_CreateInstance("@mozilla.org/image/container;1"); +- if (!decoder->mImage) +- longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY ++ /* The image container may already exist if it is reloading itself from us. ++ * Check that it has the same width/height; otherwise create a new container. ++ */ ++ decoder->mImageLoad->GetImage (getter_AddRefs (decoder->mImage)); ++ if (decoder->mImage) { ++ PRInt32 container_width, container_height; ++ ++ decoder->mImage->GetWidth (&container_width); ++ decoder->mImage->GetHeight (&container_height); + +- decoder->mImageLoad->SetImage(decoder->mImage); ++ if (container_width != width || container_height != height) ++ decoder->mImage = nsnull; ++ } + +- decoder->mImage->Init(width, height, decoder->mObserver); ++ if (!decoder->mImage) { ++ decoder->mImage = do_CreateInstance("@mozilla.org/image/container;1"); ++ if (!decoder->mImage) ++ longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY ++ ++ decoder->mImageLoad->SetImage(decoder->mImage); ++ ++ decoder->mImage->Init(width, height, decoder->mObserver); ++ ++ /* FIXME: is this MIME type always right for this decoder? */ ++ if (NS_FAILED (decoder->mImage->SetDiscardable ("image/png"))) { ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: info_callback(): failed to set image container %p as discardable", ++ decoder->mImage.get ())); ++ longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY ++ } ++ ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: info_callback(): set image container %p as discardable", ++ decoder->mImage.get ())); ++ } + + if (decoder->mObserver) + decoder->mObserver->OnStartContainer(nsnull, decoder->mImage); +@@ -757,7 +823,7 @@ end_callback(png_structp png_ptr, png_infop info_ptr) + } + + decoder->mImage->DecodingComplete(); +- ++ + if (decoder->mObserver) { + if (!(decoder->apngFlags & FRAME_HIDDEN)) + decoder->mObserver->OnStopFrame(nsnull, decoder->mFrame); +diff --git modules/libpr0n/public/imgIContainer.idl modules/libpr0n/public/imgIContainer.idl +index fc42335..524af96 100644 +--- modules/libpr0n/public/imgIContainer.idl ++++ modules/libpr0n/public/imgIContainer.idl +@@ -22,6 +22,7 @@ + * + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -144,4 +145,10 @@ interface imgIContainer : nsISupports + * @note -1 means forever. + */ + attribute long loopCount; ++ ++ /* Methods to discard uncompressed images and restore them again */ ++ [noscript] void setDiscardable(in string aMimeType); ++ [noscript] void addRestoreData(in charPtr aBuffer, ++ in unsigned long aCount); ++ [noscript] void restoreDataDone(); + }; +diff --git modules/libpr0n/src/imgContainer.cpp modules/libpr0n/src/imgContainer.cpp +index 776c4ee..22d8735 100644 +--- modules/libpr0n/src/imgContainer.cpp ++++ modules/libpr0n/src/imgContainer.cpp +@@ -25,6 +25,7 @@ + * Asko Tontti <atontti@cc.hut.fi> + * Arron Mogge <paper@animecity.nu> + * Andrew Smith ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -42,23 +43,49 @@ + + #include "nsComponentManagerUtils.h" + #include "imgIContainerObserver.h" ++#include "ImageErrors.h" + #include "nsIImage.h" ++#include "imgILoad.h" ++#include "imgIDecoder.h" ++#include "imgIDecoderObserver.h" + #include "imgContainer.h" + #include "nsIInterfaceRequestor.h" + #include "nsIInterfaceRequestorUtils.h" + #include "nsAutoPtr.h" ++#include "nsStringStream.h" ++#include "prmem.h" ++#include "prlog.h" + + #include "gfxContext.h" + ++/* Accounting for compressed data */ ++#if defined(PR_LOGGING) ++static PRLogModuleInfo *gCompressedImageAccountingLog = PR_NewLogModule ("CompressedImageAccounting"); ++#else ++#define gCompressedImageAccountingLog ++#endif ++ ++static int num_containers_with_discardable_data; ++static PRInt64 num_compressed_image_bytes; ++ ++ + NS_IMPL_ISUPPORTS3(imgContainer, imgIContainer, nsITimerCallback, nsIProperties) + + //****************************************************************************** + imgContainer::imgContainer() : + mSize(0,0), ++ mNumFrames(0), + mAnim(nsnull), + mAnimationMode(kNormalAnimMode), + mLoopCount(-1), +- mObserver(nsnull) ++ mObserver(nsnull), ++ mDiscardable(PR_FALSE), ++ mDiscarded(PR_FALSE), ++ mDiscardableMimeType(nsnull), ++ mRestoreData(nsnull), ++ mRestoreDataLength(0), ++ mRestoreDataDone(PR_FALSE), ++ mDiscardTimer(nsnull) + { + } + +@@ -67,6 +94,32 @@ imgContainer::~imgContainer() + { + if (mAnim) + delete mAnim; ++ ++ if (mDiscardableMimeType) { ++ free (mDiscardableMimeType); ++ mDiscardableMimeType = nsnull; ++ } ++ ++ if (mRestoreData) { ++ PR_Free (mRestoreData); ++ ++ num_containers_with_discardable_data--; ++ num_compressed_image_bytes -= mRestoreDataLength; ++ ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: destroying imgContainer %p. " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ this, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++ ++ mRestoreDataLength = 0; ++ } ++ ++ if (mDiscardTimer) { ++ mDiscardTimer->Cancel (); ++ mDiscardTimer = nsnull; ++ } + } + + //****************************************************************************** +@@ -124,15 +177,53 @@ NS_IMETHODIMP imgContainer::GetHeight(PRInt32 *aHeight) + return NS_OK; + } + ++nsresult imgContainer::GetCurrentFrameNoRef (gfxIImageFrame** aFrame) ++{ ++ nsresult result; ++ ++ result = RestoreDiscardedData (); ++ if (NS_FAILED (result)) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::GetCurrentFrameNoRef(): error %d in RestoreDiscardedData(); " ++ "returning a null frame from imgContainer %p", ++ result, ++ this)); ++ ++ *aFrame = nsnull; ++ return result; ++ } ++ ++ if (!mAnim) ++ *aFrame = mFrames.SafeObjectAt(0); ++ else if (mAnim->lastCompositedFrameIndex == mAnim->currentAnimationFrameIndex) ++ *aFrame = mAnim->compositingFrame; ++ else ++ *aFrame = mFrames.SafeObjectAt(mAnim->currentAnimationFrameIndex); ++ ++ if (!*aFrame) ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::GetCurrentFrameNoRef(): returning null frame from imgContainer %p " ++ "(no errors when restoring data)", ++ this)); ++ ++ return NS_OK; ++} ++ + //****************************************************************************** + /* readonly attribute gfxIImageFrame currentFrame; */ + NS_IMETHODIMP imgContainer::GetCurrentFrame(gfxIImageFrame **aCurrentFrame) + { ++ nsresult result; ++ + NS_ASSERTION(aCurrentFrame, "imgContainer::GetCurrentFrame; Invalid Arg"); + if (!aCurrentFrame) + return NS_ERROR_INVALID_POINTER; + +- if (!(*aCurrentFrame = inlinedGetCurrentFrame())) ++ result = GetCurrentFrameNoRef (aCurrentFrame); ++ if (NS_FAILED (result)) ++ return result; ++ ++ if (!*aCurrentFrame) + return NS_ERROR_FAILURE; + + NS_ADDREF(*aCurrentFrame); +@@ -148,7 +239,7 @@ NS_IMETHODIMP imgContainer::GetNumFrames(PRUint32 *aNumFrames) + if (!aNumFrames) + return NS_ERROR_INVALID_ARG; + +- *aNumFrames = mFrames.Count(); ++ *aNumFrames = mNumFrames; + + return NS_OK; + } +@@ -157,16 +248,24 @@ NS_IMETHODIMP imgContainer::GetNumFrames(PRUint32 *aNumFrames) + /* gfxIImageFrame getFrameAt (in unsigned long index); */ + NS_IMETHODIMP imgContainer::GetFrameAt(PRUint32 index, gfxIImageFrame **_retval) + { ++ nsresult result; ++ + NS_ASSERTION(_retval, "imgContainer::GetFrameAt; Invalid Arg"); + if (!_retval) + return NS_ERROR_INVALID_POINTER; + +- if (!mFrames.Count()) { ++ if (mNumFrames == 0) { + *_retval = nsnull; + return NS_OK; + } + +- NS_ENSURE_ARG(index < static_cast<PRUint32>(mFrames.Count())); ++ NS_ENSURE_ARG((int) index < mNumFrames); ++ ++ result = RestoreDiscardedData (); ++ if (NS_FAILED (result)) { ++ *_retval = nsnull; ++ return result; ++ } + + if (!(*_retval = mFrames[index])) + return NS_ERROR_FAILURE; +@@ -183,16 +282,17 @@ NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item) + NS_ASSERTION(item, "imgContainer::AppendFrame; Invalid Arg"); + if (!item) + return NS_ERROR_INVALID_ARG; +- +- PRInt32 numFrames = mFrames.Count(); +- +- if (numFrames == 0) { ++ ++ if (mFrames.Count () == 0) { + // This may not be an animated image, don't do all the animation stuff. + mFrames.AppendObject(item); ++ ++ mNumFrames++; ++ + return NS_OK; + } + +- if (numFrames == 1) { ++ if (mFrames.Count () == 1) { + // Now that we got a second frame, initialize animation stuff. + if (!ensureAnimExists()) + return NS_ERROR_OUT_OF_MEMORY; +@@ -216,11 +316,13 @@ NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item) + itemRect); + + mFrames.AppendObject(item); ++ ++ mNumFrames++; + + // If this is our second frame, start the animation. + // Must be called after AppendObject because StartAnimation checks for > 1 + // frame +- if (numFrames == 1) ++ if (mFrames.Count () == 1) + StartAnimation(); + + return NS_OK; +@@ -230,6 +332,7 @@ NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item) + /* void removeFrame (in gfxIImageFrame item); */ + NS_IMETHODIMP imgContainer::RemoveFrame(gfxIImageFrame *item) + { ++ /* Remember to decrement mNumFrames if you implement this */ + return NS_ERROR_NOT_IMPLEMENTED; + } + +@@ -253,7 +356,7 @@ NS_IMETHODIMP imgContainer::DecodingComplete(void) + mAnim->doneDecoding = PR_TRUE; + // If there's only 1 frame, optimize it. + // Optimizing animated images is not supported +- if (mFrames.Count() == 1) ++ if (mNumFrames == 1) + mFrames[0]->SetMutable(PR_FALSE); + return NS_OK; + } +@@ -292,11 +395,11 @@ NS_IMETHODIMP imgContainer::SetAnimationMode(PRUint16 aAnimationMode) + break; + case kNormalAnimMode: + if (mLoopCount != 0 || +- (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mFrames.Count()))) ++ (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mNumFrames))) + StartAnimation(); + break; + case kLoopOnceAnimMode: +- if (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mFrames.Count())) ++ if (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mNumFrames)) + StartAnimation(); + break; + } +@@ -312,12 +415,18 @@ NS_IMETHODIMP imgContainer::StartAnimation() + (mAnim && (mAnim->timer || mAnim->animating))) + return NS_OK; + +- if (mFrames.Count() > 1) { ++ if (mNumFrames > 1) { + if (!ensureAnimExists()) + return NS_ERROR_OUT_OF_MEMORY; + + PRInt32 timeout; +- gfxIImageFrame *currentFrame = inlinedGetCurrentFrame(); ++ nsresult result; ++ gfxIImageFrame *currentFrame; ++ ++ result = GetCurrentFrameNoRef (¤tFrame); ++ if (NS_FAILED (result)) ++ return result; ++ + if (currentFrame) { + currentFrame->GetTimeout(&timeout); + if (timeout <= 0) // -1 means display this frame forever +@@ -376,8 +485,15 @@ NS_IMETHODIMP imgContainer::ResetAnimation() + mAnim->currentAnimationFrameIndex = 0; + // Update display + nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver)); +- if (observer) ++ if (observer) { ++ nsresult result; ++ ++ result = RestoreDiscardedData (); ++ if (NS_FAILED (result)) ++ return result; ++ + observer->FrameChanged(this, mFrames[0], &(mAnim->firstFrameRefreshArea)); ++ } + + if (oldAnimating) + return StartAnimation(); +@@ -411,10 +527,161 @@ NS_IMETHODIMP imgContainer::SetLoopCount(PRInt32 aLoopCount) + return NS_OK; + } + ++static PRBool ++discarding_is_enabled (void) ++{ ++ static PRBool inited; ++ static PRBool enabled; ++ ++ if (!inited) { ++ inited = PR_TRUE; ++ ++ enabled = (getenv ("MOZ_DISABLE_IMAGE_DISCARD") == nsnull); ++ } ++ ++ return enabled; ++} ++ ++//****************************************************************************** ++/* void setDiscardable(in string mime_type); */ ++NS_IMETHODIMP imgContainer::SetDiscardable (const char* aMimeType) ++{ ++ NS_ASSERTION(aMimeType, "imgContainer::SetDiscardable() called with null aMimeType"); ++ ++ if (!discarding_is_enabled ()) ++ return NS_OK; ++ ++ if (mDiscardable) { ++ NS_WARNING ("imgContainer::SetDiscardable(): cannot change an imgContainer which is already discardable"); ++ return NS_ERROR_FAILURE; ++ } ++ ++ mDiscardableMimeType = strdup (aMimeType); ++ if (!mDiscardableMimeType) ++ return NS_ERROR_OUT_OF_MEMORY; ++ ++ mDiscardable = PR_TRUE; ++ ++ num_containers_with_discardable_data++; ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: Making imgContainer %p (%s) discardable. " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ this, ++ aMimeType, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++ ++ return NS_OK; ++} ++ ++//****************************************************************************** ++/* void addRestoreData(in nsIInputStream aInputStream, in unsigned long aCount); */ ++NS_IMETHODIMP imgContainer::AddRestoreData (char *aBuffer, PRUint32 aCount) ++{ ++ PRSize new_size; ++ char *new_buffer; ++ ++ NS_ASSERTION(aBuffer, "imgContainer::AddRestoreData() called with null aBuffer"); ++ ++ if (!discarding_is_enabled ()) ++ return NS_OK; ++ ++ if (!mDiscardable) { ++ NS_WARNING ("imgContainer::AddRestoreData() can only be called if SetDiscardable is called first"); ++ return NS_ERROR_FAILURE; ++ } ++ ++ if (mRestoreDataDone) { ++ /* We are being called from the decoder while the data is being restored ++ * (i.e. we were fully loaded once, then we discarded the image data, then ++ * we are being restored). We don't want to save the compressed data again, ++ * since we already have it. ++ */ ++ return NS_OK; ++ } ++ ++ new_size = mRestoreDataLength + aCount; ++ ++ new_buffer = (char *) PR_Realloc (mRestoreData, new_size); ++ if (new_buffer) ++ mRestoreData = new_buffer; ++ else { ++ /* Hmm, should we discard the whole buffer? The caller isn't going to be able to recover... */ ++ return NS_ERROR_OUT_OF_MEMORY; ++ } ++ ++ memcpy (mRestoreData + mRestoreDataLength, aBuffer, aCount); ++ mRestoreDataLength = new_size; ++ ++ num_compressed_image_bytes += aCount; ++ ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: Added compressed data to imgContainer %p (%s). " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ this, ++ mDiscardableMimeType, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++ ++ return NS_OK; ++} ++ ++/* Note! buf must be declared as char buf[9]; */ ++static void ++get_header_str (char *buf, char *data, PRSize data_len) ++{ ++ int i; ++ int n; ++ static char hex[] = "0123456789abcdef"; ++ ++ n = data_len < 4 ? data_len : 4; ++ ++ for (i = 0; i < n; i++) { ++ buf[i * 2] = hex[(data[i] >> 4) & 0x0f]; ++ buf[i * 2 + 1] = hex[data[i] & 0x0f]; ++ } ++ ++ buf[i * 2] = 0; ++} ++ ++//****************************************************************************** ++/* void restoreDataDone(); */ ++NS_IMETHODIMP imgContainer::RestoreDataDone (void) ++{ ++ char buf[9]; ++ ++ if (!discarding_is_enabled ()) ++ return NS_OK; ++ ++ if (mRestoreDataDone) ++ return NS_OK; ++ ++ mRestoreDataDone = PR_TRUE; ++ ++ get_header_str (buf, mRestoreData, mRestoreDataLength); ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::RestoreDataDone() - data is done for container %p (%s), %d real frames (cached as %d frames) - header %p is 0x%s (length %d)", ++ this, ++ mDiscardableMimeType, ++ mFrames.Count (), ++ mNumFrames, ++ mRestoreData, ++ buf, ++ (int) mRestoreDataLength)); ++ ++ return ResetDiscardTimer (); ++} ++ + //****************************************************************************** + /* void notify(in nsITimer timer); */ + NS_IMETHODIMP imgContainer::Notify(nsITimer *timer) + { ++ nsresult result; ++ ++ result = RestoreDiscardedData (); ++ if (NS_FAILED (result)) ++ return result; ++ + // This should never happen since the timer is only set up in StartAnimation() + // after mAnim is checked to exist. + NS_ASSERTION(mAnim, "imgContainer::Notify() called but mAnim is null"); +@@ -433,8 +700,7 @@ NS_IMETHODIMP imgContainer::Notify(nsITimer *timer) + return NS_OK; + } + +- PRInt32 numFrames = mFrames.Count(); +- if (!numFrames) ++ if (mNumFrames == 0) + return NS_OK; + + gfxIImageFrame *nextFrame = nsnull; +@@ -448,7 +714,7 @@ NS_IMETHODIMP imgContainer::Notify(nsITimer *timer) + // finished decoding (see EndFrameDecode) + if (mAnim->doneDecoding || + (nextFrameIndex < mAnim->currentDecodingFrameIndex)) { +- if (numFrames == nextFrameIndex) { ++ if (mNumFrames == nextFrameIndex) { + // End of Animation + + // If animation mode is "loop once", it's time to stop animating +@@ -875,3 +1141,328 @@ NS_IMETHODIMP imgContainer::GetKeys(PRUint32 *count, char ***keys) + } + return mProperties->GetKeys(count, keys); + } ++ ++static int ++get_discard_timer_ms (void) ++{ ++ /* FIXME: don't hardcode this */ ++ return 5000; /* 5 seconds */ ++} ++ ++void ++imgContainer::sDiscardTimerCallback (nsITimer *aTimer, void *aClosure) ++{ ++ imgContainer *self = (imgContainer *) aClosure; ++ int old_frame_count; ++ ++ NS_ASSERTION (aTimer == self->mDiscardTimer, ++ "imgContainer::DiscardTimerCallback() got a callback for an unknown timer"); ++ ++ self->mDiscardTimer = nsnull; ++ ++ old_frame_count = self->mFrames.Count (); ++ ++ if (self->mAnim) { ++ delete self->mAnim; ++ self->mAnim = nsnull; ++ } ++ ++ self->mFrames.Clear (); ++ ++ self->mDiscarded = PR_TRUE; ++ ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: discarded uncompressed image data from imgContainer %p (%s) - %d frames (cached count: %d); " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ self, ++ self->mDiscardableMimeType, ++ old_frame_count, ++ self->mNumFrames, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++} ++ ++nsresult ++imgContainer::ResetDiscardTimer (void) ++{ ++ if (!discarding_is_enabled ()) ++ return NS_OK; ++ ++ if (!mDiscardTimer) { ++ mDiscardTimer = do_CreateInstance("@mozilla.org/timer;1"); ++ ++ if (!mDiscardTimer) ++ return NS_ERROR_OUT_OF_MEMORY; ++ } else { ++ if (NS_FAILED (mDiscardTimer->Cancel ())) ++ return NS_ERROR_FAILURE; ++ } ++ ++ return mDiscardTimer->InitWithFuncCallback (sDiscardTimerCallback, ++ (void *) this, ++ get_discard_timer_ms (), ++ nsITimer::TYPE_ONE_SHOT); ++} ++ ++nsresult ++imgContainer::RestoreDiscardedData (void) ++{ ++ nsresult result; ++ int num_expected_frames; ++ ++ if (!mDiscarded) ++ return NS_OK; ++ ++ result = ResetDiscardTimer (); ++ if (NS_FAILED (result)) ++ return result; ++ ++ num_expected_frames = mNumFrames; ++ ++ result = ReloadImages (); ++ if (NS_FAILED (result)) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::RestoreDiscardedData() for container %p failed to ReloadImages()", ++ this)); ++ return result; ++ } ++ ++ mDiscarded = PR_FALSE; ++ ++ NS_ASSERTION (mNumFrames == mFrames.Count (), ++ "number of restored image frames doesn't match"); ++ NS_ASSERTION (num_expected_frames == mNumFrames, ++ "number of restored image frames doesn't match the original number of frames!"); ++ ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::RestoreDiscardedData() restored discarded data " ++ "for imgContainer %p (%s) - %d image frames. " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ this, ++ mDiscardableMimeType, ++ mNumFrames, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++ ++ return NS_OK; ++} ++ ++class ContainerLoader : public imgILoad, ++ public imgIDecoderObserver, ++ public nsSupportsWeakReference ++{ ++public: ++ ++ NS_DECL_ISUPPORTS ++ NS_DECL_IMGILOAD ++ NS_DECL_IMGIDECODEROBSERVER ++ NS_DECL_IMGICONTAINEROBSERVER ++ ++ ContainerLoader (void); ++ ++private: ++ ++ imgIContainer *mContainer; ++}; ++ ++NS_IMPL_ISUPPORTS4 (ContainerLoader, imgILoad, imgIDecoderObserver, imgIContainerObserver, nsISupportsWeakReference) ++ ++ContainerLoader::ContainerLoader (void) ++{ ++} ++ ++/* Implement imgILoad::image getter */ ++NS_IMETHODIMP ++ContainerLoader::GetImage(imgIContainer **aImage) ++{ ++ *aImage = mContainer; ++ NS_IF_ADDREF (*aImage); ++ return NS_OK; ++} ++ ++/* Implement imgILoad::image setter */ ++NS_IMETHODIMP ++ContainerLoader::SetImage(imgIContainer *aImage) ++{ ++ mContainer = aImage; ++ return NS_OK; ++} ++ ++/* Implement imgILoad::isMultiPartChannel getter */ ++NS_IMETHODIMP ++ContainerLoader::GetIsMultiPartChannel(PRBool *aIsMultiPartChannel) ++{ ++ *aIsMultiPartChannel = PR_FALSE; /* FIXME: is this always right? */ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStartRequest() */ ++NS_IMETHODIMP ++ContainerLoader::OnStartRequest (imgIRequest *aRequest) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStartDecode() */ ++NS_IMETHODIMP ++ContainerLoader::OnStartDecode (imgIRequest *aRequest) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStartContainer() */ ++NS_IMETHODIMP ++ContainerLoader::OnStartContainer (imgIRequest *aRequest, imgIContainer *aContainer) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStartFrame() */ ++NS_IMETHODIMP ++ContainerLoader::OnStartFrame (imgIRequest *aRequest, gfxIImageFrame *aFrame) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onDataAvailable() */ ++NS_IMETHODIMP ++ContainerLoader::OnDataAvailable (imgIRequest *aRequest, gfxIImageFrame *aFrame, const nsIntRect * aRect) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStopFrame() */ ++NS_IMETHODIMP ++ContainerLoader::OnStopFrame (imgIRequest *aRequest, gfxIImageFrame *aFrame) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStopContainer() */ ++NS_IMETHODIMP ++ContainerLoader::OnStopContainer (imgIRequest *aRequest, imgIContainer *aContainer) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStopDecode() */ ++NS_IMETHODIMP ++ContainerLoader::OnStopDecode (imgIRequest *aRequest, nsresult status, const PRUnichar *statusArg) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStopRequest() */ ++NS_IMETHODIMP ++ContainerLoader::OnStopRequest (imgIRequest *aRequest, PRBool aIsLastPart) ++{ ++ return NS_OK; ++} ++ ++/* implement imgIContainerObserver::frameChanged() */ ++NS_IMETHODIMP ++ContainerLoader::FrameChanged (imgIContainer *aContainer, gfxIImageFrame *aFrame, nsIntRect * aDirtyRect) ++{ ++ return NS_OK; ++} ++ ++static char * ++make_id_from_mime_type (char *mime_type) ++{ ++ const char idbase[] = "@mozilla.org/image/decoder;2?type="; ++ int idbase_len = strlen (idbase); ++ char *id; ++ ++ id = (char *) PR_Malloc (strlen (mime_type) + idbase_len + 1); ++ if (!id) ++ return nsnull; ++ ++ strcpy (id, idbase); ++ strcpy (id + idbase_len, mime_type); ++ ++ return id; ++} ++ ++nsresult ++imgContainer::ReloadImages (void) ++{ ++ char *id; ++ nsCOMPtr<imgILoad> loader; ++ nsCOMPtr<imgIDecoder> decoder; ++ nsresult result; ++ PRUint32 written; ++ nsCOMPtr<nsIInputStream> stream; ++ char buf[9]; ++ ++ NS_ASSERTION (mRestoreData, ++ "imgContainer::ReloadImages(): mRestoreData should not be null"); ++ NS_ASSERTION (mRestoreDataDone, ++ "imgContainer::ReloadImages(): mRestoreDataDone shoudl be true!"); ++ ++ id = make_id_from_mime_type (mDiscardableMimeType); ++ if (!id) ++ return NS_ERROR_OUT_OF_MEMORY; ++ ++ mNumFrames = 0; ++ NS_ASSERTION (mFrames.Count() == 0, ++ "imgContainer::ReloadImages(): mFrames should be empty"); ++ ++ decoder = do_CreateInstance (id); ++ PR_Free (id); ++ ++ if (!decoder) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_WARNING, ++ ("CompressedImageAccounting: imgContainer::ReloadImages() could not create decoder for %s", ++ mDiscardableMimeType)); ++ return NS_IMAGELIB_ERROR_NO_DECODER; ++ } ++ ++ loader = new ContainerLoader (); ++ if (!loader) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_WARNING, ++ ("CompressedImageAccounting: imgContainer::ReloadImages() could not allocate ContainerLoader " ++ "when reloading the images for container %p", ++ this)); ++ return NS_ERROR_OUT_OF_MEMORY; ++ } ++ ++ loader->SetImage (this); ++ ++ result = decoder->Init (loader); ++ if (NS_FAILED (result)) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_WARNING, ++ ("CompressedImageAccounting: imgContainer::ReloadImages() image container %p " ++ "failed to initialize the decoder (%s)", ++ this, ++ mDiscardableMimeType)); ++ return result; ++ } ++ ++ result = NS_NewByteInputStream (getter_AddRefs (stream), mRestoreData, mRestoreDataLength, NS_ASSIGNMENT_DEPEND); ++ NS_ENSURE_SUCCESS (result, result); ++ ++ get_header_str (buf, mRestoreData, mRestoreDataLength); ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_WARNING, ++ ("CompressedImageAccounting: imgContainer::ReloadImages() starting to restore images for container %p (%s) - " ++ "header %p is 0x%s (length %d)", ++ this, ++ mDiscardableMimeType, ++ mRestoreData, ++ buf, ++ (int) mRestoreDataLength)); ++ ++ result = decoder->WriteFrom (stream, mRestoreDataLength, &written); ++ NS_ENSURE_SUCCESS (result, result); ++ ++ result = decoder->Flush (); ++ if (!(result == NS_OK || result == NS_ERROR_NOT_IMPLEMENTED)) /* PNG doesn't implement Flush(), for example */ ++ return result; ++ ++ result = decoder->Close (); ++ NS_ENSURE_SUCCESS (result, result); ++ ++ NS_ASSERTION (mFrames.Count() == mNumFrames, ++ "imgContainer::ReloadImages(): the restored mFrames.Count() doesn't match mNumFrames!"); ++ ++ return result; ++} +diff --git modules/libpr0n/src/imgContainer.h modules/libpr0n/src/imgContainer.h +index 3db7034..aa56939 100644 +--- modules/libpr0n/src/imgContainer.h ++++ modules/libpr0n/src/imgContainer.h +@@ -23,6 +23,7 @@ + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> + * Chris Saari <saari@netscape.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -194,14 +195,8 @@ private: + timer->Cancel(); + } + }; +- +- inline gfxIImageFrame* inlinedGetCurrentFrame() { +- if (!mAnim) +- return mFrames.SafeObjectAt(0); +- if (mAnim->lastCompositedFrameIndex == mAnim->currentAnimationFrameIndex) +- return mAnim->compositingFrame; +- return mFrames.SafeObjectAt(mAnim->currentAnimationFrameIndex); +- } ++ ++ nsresult GetCurrentFrameNoRef(gfxIImageFrame** aFrame); + + inline Anim* ensureAnimExists() { + if (!mAnim) +@@ -274,10 +269,15 @@ private: + nsIntSize mSize; + + //! All the <gfxIImageFrame>s of the PNG ++ // *** IMPORTANT: if you use mFrames in a method, call RestoreDiscardedData() first to ensure ++ // that the frames actually exist (they may have been discarded to save memory). + nsCOMArray<gfxIImageFrame> mFrames; ++ int mNumFrames; /* stored separately from mFrames.Count() to support discarded images */ + + nsCOMPtr<nsIProperties> mProperties; +- ++ ++ // *** IMPORTANT: if you use mAnim in a method, call RestoreDiscardedData() first to ensure ++ // that the frames actually exist (they may have been discarded to save memory). + imgContainer::Anim* mAnim; + + //! See imgIContainer for mode constants +@@ -288,6 +288,19 @@ private: + + //! imgIContainerObserver + nsWeakPtr mObserver; ++ ++ PRBool mDiscardable; ++ PRBool mDiscarded; ++ char* mDiscardableMimeType; ++ char* mRestoreData; ++ PRSize mRestoreDataLength; ++ PRBool mRestoreDataDone; ++ nsCOMPtr<nsITimer> mDiscardTimer; ++ ++ nsresult ResetDiscardTimer (void); ++ nsresult RestoreDiscardedData (void); ++ nsresult ReloadImages (void); ++ static void sDiscardTimerCallback (nsITimer *aTimer, void *aClosure); + }; + + #endif /* __imgContainer_h__ */ diff --git a/www/firefox-devel/files/patch-sysnss b/www/firefox-devel/files/patch-sysnss index 025d43c3d..6f3d06298 100644 --- a/www/firefox-devel/files/patch-sysnss +++ b/www/firefox-devel/files/patch-sysnss @@ -1,11 +1,11 @@ ---- security/manager/ssl/src/Makefile.in.orig Mon Aug 14 19:22:52 2006 -+++ security/manager/ssl/src/Makefile.in Thu Aug 31 15:17:20 2006 -@@ -124,19 +124,19 @@ +--- security/manager/ssl/src/Makefile.in.orig 2007-07-23 15:03:01.000000000 -0400 ++++ security/manager/ssl/src/Makefile.in 2007-09-04 20:47:03.000000000 -0400 +@@ -125,13 +125,11 @@ pipboot \ $(NULL) -EXTRA_DEPS = $(NSS_DEP_LIBS) - +- DEFINES += -DNSS_ENABLE_ECC # Use local includes because they are inserted before INCLUDES @@ -13,8 +13,9 @@ -LOCAL_INCLUDES += $(NSS_CFLAGS) +LOCAL_INCLUDES += -I%%LOCALBASE%%/include/nss/nss + ifeq ($(OS_ARCH),Darwin) EXTRA_DSO_LDOPTS += \ - $(MOZ_UNICHARUTIL_LIBS) \ +@@ -143,6 +141,7 @@ $(MOZ_COMPONENT_LIBS) \ $(MOZ_JS_LIBS) \ $(NSS_LIBS) \ @@ -22,3 +23,12 @@ $(NULL) include $(topsrcdir)/config/rules.mk +--- toolkit/components/url-classifier/src/Makefile.in.orig 2007-09-05 09:00:23.000000000 -0400 ++++ toolkit/components/url-classifier/src/Makefile.in 2007-09-05 09:00:27.000000000 -0400 +@@ -36,6 +36,3 @@ + $(NULL) + + include $(topsrcdir)/config/rules.mk +- +-export:: $(topsrcdir)/security/nss/lib/freebl/sha512.c +- $(INSTALL) $^ . diff --git a/www/firefox-devel/files/patch-toolkit_xre_Makefile.in b/www/firefox-devel/files/patch-toolkit_xre_Makefile.in new file mode 100644 index 000000000..4a9c8533a --- /dev/null +++ b/www/firefox-devel/files/patch-toolkit_xre_Makefile.in @@ -0,0 +1,8 @@ +--- toolkit/xre/Makefile.in.orig 2007-09-10 10:31:53.000000000 -0400 ++++ toolkit/xre/Makefile.in 2007-09-10 10:35:00.000000000 -0400 +@@ -263,5 +263,3 @@ + libs:: platform.ini + $(INSTALL) $^ $(DIST)/bin + +-install:: +- $(INSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir) diff --git a/www/firefox-devel/files/patch-toolkit_xre_nsXREDirProvider.cpp b/www/firefox-devel/files/patch-toolkit_xre_nsXREDirProvider.cpp deleted file mode 100644 index 0c5a07ab2..000000000 --- a/www/firefox-devel/files/patch-toolkit_xre_nsXREDirProvider.cpp +++ /dev/null @@ -1,19 +0,0 @@ ---- toolkit/xre/nsXREDirProvider.cpp.orig Tue Oct 4 11:46:26 2005 -+++ toolkit/xre/nsXREDirProvider.cpp Sun Feb 5 23:54:31 2006 -@@ -820,6 +820,7 @@ - - char* appNameFolder = nsnull; - char profileFolderName[MAXPATHLEN] = "."; -+ char temp[MAXPATHLEN]; - - // Offset 1 for the outermost folder to make it hidden (i.e. using the ".") - char* writing = profileFolderName + 1; -@@ -829,7 +830,6 @@ - rv = localDir->AppendNative(nsDependentCString(profileFolderName)); - NS_ENSURE_SUCCESS(rv, rv); - -- char temp[MAXPATHLEN]; - GetProfileFolderName(temp, gAppData->name); - appNameFolder = temp; - } - diff --git a/www/firefox3-devel/Makefile b/www/firefox3-devel/Makefile index e73df790b..cc8e6b375 100644 --- a/www/firefox3-devel/Makefile +++ b/www/firefox3-devel/Makefile @@ -6,13 +6,13 @@ # $MCom: ports/www/firefox-devel/Makefile,v 1.38 2007/07/05 16:52:19 ahze Exp $ PORTNAME= firefox -DISTVERSION= 3.0.a6 +DISTVERSION= 3.0.a7 PORTEPOCH= 1 CATEGORIES= www ipv6 MASTER_SITES= ${MASTER_SITE_MOZILLA} -MASTER_SITE_SUBDIR= ${PORTNAME}/releases/granparadiso/alpha6/source/ +MASTER_SITE_SUBDIR= ${PORTNAME}/releases/granparadiso/alpha7/source/ #MASTER_SITE_SUBDIR= ${PORTNAME}/releases/${DISTVERSION}/source -DISTNAME= granparadiso-alpha6-source +DISTNAME= granparadiso-alpha7-source #DISTNAME= ${PORTNAME}-${DISTVERSION}-source MAINTAINER= gnome@FreeBSD.org @@ -21,7 +21,8 @@ COMMENT= Web browser based on the browser portion of Mozilla MOZILLA_NAME= Firefox-${MOZILLA_SUFX} MOZILLA_SUFX= -devel MOZILLA= ${PORTNAME}${MOZILLA_SUFX} -MOZ_OPTIONS= --program-transform-name='s/firefox/${MOZILLA}/' +MOZ_OPTIONS= --program-transform-name='s/firefox/${MOZILLA}/' \ + --enable-svg --enable-svg-renderer=cairo MOZ_TOOLKIT= cairo-gtk2 WANT_GNOME= yes @@ -52,12 +53,6 @@ OPTIONS= NEWTAB "Open external links in a new tab" on \ GECKO_PTHREAD_LIBS!=${CC} -dumpspecs | ${GREP} -m 1 pthread | ${SED} -e 's|^.*%{\!pg: %{pthread:|| ; s|}.*$$||' || ${TRUE} -MOZ_OPTIONS+= --disable-svg -#.if ${OSVERSION} >= 600000 -# Needs MOZ_TOOLKIT=cairo-gtk2 -#MOZ_OPTIONS+= --enable-svg --enable-svg-renderer=cairo -#.endif - post-extract:: @${SED} -e 's|@FIREFOX_ICON@|${FIREFOX_ICON}|' -e 's|@MOZILLA@|${MOZILLA}|' \ -e 's|@MOZILLA_NAME@|${MOZILLA_NAME}|' \ @@ -75,6 +70,7 @@ post-patch: .endfor port-pre-install: + ${SED} -e 's|1.9a7|0|' ${WRKSRC}/dist/bin/application.ini ${FAKEDIR}/lib ${ECHO_CMD} 'share/applications/${MOZILLA}.desktop' >> ${PLIST} ${ECHO_CMD} "@unexec ${RMDIR} %D/share/applications 2>/dev/null || ${TRUE}" >> ${PLIST} ${ECHO_CMD} 'share/pixmaps/${FIREFOX_ICON}' >> ${PLIST} diff --git a/www/firefox3-devel/distinfo b/www/firefox3-devel/distinfo index 23ffc5599..1340a04a1 100644 --- a/www/firefox3-devel/distinfo +++ b/www/firefox3-devel/distinfo @@ -1,3 +1,3 @@ -MD5 (granparadiso-alpha6-source.tar.bz2) = 9b892de32d4067824eeea00d45d475de -SHA256 (granparadiso-alpha6-source.tar.bz2) = 57d5de020b439be173a6a1a13e11903d113240c45fd04b63ff12cc61edf89059 -SIZE (granparadiso-alpha6-source.tar.bz2) = 33740574 +MD5 (granparadiso-alpha7-source.tar.bz2) = cd692127775b55f5e64685ef49788c1c +SHA256 (granparadiso-alpha7-source.tar.bz2) = 91369eff2bba6b0ef3a9b5a40a1585b27f66a670f1a96299852f2595bd96f209 +SIZE (granparadiso-alpha7-source.tar.bz2) = 35319889 diff --git a/www/firefox3-devel/files/patch-bugzilla296818 b/www/firefox3-devel/files/patch-bugzilla296818 new file mode 100644 index 000000000..a7f22b4eb --- /dev/null +++ b/www/firefox3-devel/files/patch-bugzilla296818 @@ -0,0 +1,1621 @@ +diff --git ChangeLog ChangeLog +new file mode 100644 +index 0000000..c9c7dce +--- /dev/null ++++ ChangeLog +@@ -0,0 +1,277 @@ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Write the restore data regardless of ++ the state we are in, right when we first fill the buffer. ++ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::RestoreDataDone): Print the first four bytes of the ++ restore data, to check it later. ++ (imgContainer::ReloadImages): Likewise. ++ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/png/nsPNGDecoder.cpp (info_callback): ++ Reuse the image container if the loader has one; don't always ++ create a new one. This lets containers reload themselves. ++ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::AppendFrame): Unconditionally increment mNumFrames! ++ (imgContainer::RestoreDiscardedData): Check the number of restored ++ frames here. ++ (imgContainer::ReloadImages): Flush and close the decoder. ++ (imgContainer::RestoreDataDone): No-op if we are already restoring ++ the data. ++ ++2007-09-06 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/png/nsPNGDecoder.cpp (*): Print the ++ imgContainer pointers when logging. ++ ++ * modules/libpr0n/src/imgContainer.cpp (*): Likewise. ++ ++2007-09-04 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::ReloadImages): Oops, use an nsCOMPtr<> for the ++ ContainerLoader, not a direct pointer. ++ (ContainerLoader NS_IMPL_ISUPPORTS3): Oops, we also implement ++ imgIContainerObserver. ++ (class ContainerLoader): Implement nsISupportsWeakReference as ++ well; imgContainer needs it from the observer. ++ (imgContainer::RestoreDiscardedData): Log how many frames we got ++ and how many we expected. ++ (imgContainer::ReloadImages): Assert that we got the right number ++ of frames. ++ (imgContainer::GetCurrentFrameNoRef): Log failures from ++ RestoreDiscardedData(). ++ ++ * modules/libpr0n/decoders/png/nsPNGDecoder.cpp (end_callback): ++ Don't tell the container that the restore data is done here... ++ (nsPNGDecoder::Close): ... but do it here instead. This is ++ because end_callback() gets called from within ReadDataOut(); we ++ don't want end_callback() to inform the container that the restore ++ data is done before actually writing the restore data to it! ++ ++2007-09-04 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/png/nsPNGDecoder.cpp (info_callback): ++ Set the image container as discardable. ++ (ReadDataOut): Store the compressed data in the image container to ++ restore from it later. ++ (end_callback): Tell the image container that we finished feeding ++ it the restore data. ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::SetDiscardable): Log the MIME type of the ++ discardable container. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Clean up a printf format, and do the ++ logging only on success. ++ ++ * gfx/thebes/public/gfxXlibSurface.h: Add myself to the contributors. ++ * modules/libpr0n/public/imgIContainer.idl: Likewise. ++ * modules/libpr0n/src/imgContainer.cpp: Likewise. ++ * modules/libpr0n/src/imgContainer.h: Likewise. ++ ++2007-09-03 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::AddRestoreData): No-op if we are being called ++ during the restore process (we already have the data; there is no ++ need to save it again). ++ (class ContainerLoader): Put the macro to implement QI for ++ imgILoad and imgIDecoderObserver. ++ (imgContainer::AppendFrame): Don't increment mNumFrames if we are ++ restoring the image data. Fix the use of the frame counters. ++ (imgContainer::sDiscardTimerCallback): Implement. ++ (imgContainer::GetCurrentFrame): Oops, preserve the semantics of ++ the original function --- if the actual getter gives us a null ++ frame, return NS_ERROR_FAILURE. ++ ++2007-08-31 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.h (class imgContainer): New ++ prototype for a ReloadImages() method. ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::RestoreDiscardedData): Call ReloadImages(). ++ (imgContainer::ReloadImages): Implement. ++ (class ContainerLoader): New helper class that implements ++ imgILoader and imgIDecoderObserver. We'll use this to re-load the ++ imgContainer from an image decoder. ++ ++2007-08-31 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::RestoreDiscardedData): Reset the timer; if we got ++ here it means that the data may be used again soon. ++ ++2007-08-30 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.h (class imgContainer): Add an ++ mDiscarded field. We'll use it to know if the uncompressed image ++ data has been discarded already and needs to be regenerated on ++ demand. ++ (class imgContainer): New prototype for a RestoreDiscardedData() method. ++ ++ * modules/libpr0n/src/imgContainer.cpp (imgContainer): Initialize ++ mDiscarded. ++ (imgContainer::GetCurrentFrameNoRef): Return an nsresult rather ++ than the image frame; return the actual image frame as a ++ reference. Ensure that the discarded data gets restored. ++ (imgContainer::GetCurrentFrame): Return the error from ++ GetCurrentFrameNoRef() if it fails. ++ (imgContainer::StartAnimation): Likewise. ++ (imgContainer::GetFrameAt): Ensure that the discarded data gets restored. ++ (imgContainer::ResetAnimation): Likewise. ++ (imgContainer::Notify): Likewise. ++ (imgContainer::RestoreDiscardedData): Just a stub for now. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Oops, use "count" for the restore ++ data, not "mBufferLen". ++ ++2007-08-29 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.h (class imgContainer): Add a ++ mNumFrames field. Since we'll discard the contents of mFrames, we ++ can't rely on mFrames.Count() for the frame count. ++ ++ * modules/libpr0n/src/imgContainer.cpp (imgContainer): Initialize mNumFrames. ++ (imgContainer::AppendFrame): Maintain the frame count in mNumFrames. ++ (imgContainer::GetNumFrames): Use mNumFrames instead of mFrames.Count(). ++ (imgContainer::GetFrameAt): Likewise. ++ (imgContainer::DecodingComplete): Likewise. ++ (imgContainer::SetAnimationMode): Likewise. ++ (imgContainer::StartAnimation): Likewise. ++ (imgContainer::Notify): Likewise. ++ ++2007-08-29 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.h ++ (imgContainer::inlinedGetCurrentFrame): Removed to make it not ++ inline. ++ (imgContainer::GetCurrentFrameNoRef): New prototype. ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (imgContainer::GetCurrentFrameNoRef): Implement this here. ++ (imgContainer::GetCurrentFrame, imgContainer::StartAnimation): Use ++ GetCurrentFrameNoRef() instead of inlinedGetCurrentFrame(). ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/public/imgIContainer.idl (restoreDataDone): New ++ method. We'll use this to tell the container when we finish ++ feeding it the compressed data. After that, it can begin its ++ discard process whenever it wants. ++ ++ * modules/libpr0n/src/imgContainer.h (class imgContainer): Add ++ mRestoreDataDone and mDiscardTimer fields. ++ ++ * modules/libpr0n/src/imgContainer.cpp (imgContainer): Initialize ++ the new fields. ++ (imgContainer::RestoreDataDone): Implement. When turned on, we ++ start the discard timer. ++ (imgContainer::ResetDiscardTimer): New method. ++ (~imgContainer): Cancel and destroy the timer. ++ (imgContainer::sDiscardTimerCallback): New callback. Here we'll ++ discard the uncompressed image data in the image frames. For now ++ this is just a stub. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Tell the imgContainer when we are done ++ feeding data to it. ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp (discarding_is_enabled): ++ Stub function, to be replaced with something better in the ++ future. This lets us disable image discarding by setting a ++ MOZ_DISABLE_IMAGE_DISCARD environment variable. ++ (imgContainer::SetDiscardable): Noop if discarding is disabled. ++ (imgContainer::AddRestoreData): Likewise. ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Mark the imgContainer as discardable ++ when we create it. And when writing to the JPEG decoder, add the ++ compressed data to the imgContainer so that it can restore itself ++ later. ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgContainer.cpp ++ (gCompressedImageAccountingLog): Create a ++ "CompressedImageAccounting" log domain. ++ (~imgContainer): Log the destruction of compressed data. ++ (imgContainer::AddRestoreData): Log the addition of compressed data. ++ (imgContainer::SetDiscardable): Log the creation of a compressed imgContainer. ++ ++2007-08-28 Federico Mena Quintero <federico@novell.com> ++ ++ ++ * modules/libpr0n/src/imgContainer.cpp (~imgContainer): Free the ++ restore data and the MIME type. ++ ++2007-08-22 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/public/imgIContainer.idl (setDiscardable): New ++ method. When this is called (can be called only once) from an ++ image decoder, the image container will discard its uncompressed ++ image data after a timeout. ++ (addRestoreData): New method. Image decoders should call this ++ repeatedly after calling setDiscardable(); this is used to feed ++ the original, compressed image data to the image container so that ++ it can uncompress it on demand after discarding it. ++ ++ * modules/libpr0n/src/imgContainer.cpp (imgContainer::SetDiscardable): ++ Implement. ++ (imgContainer::AddRestoreData): Implement. ++ ++2007-08-20 Federico Mena Quintero <federico@novell.com> ++ ++ * gfx/thebes/src/gfxXlibSurface.cpp ++ (gfxXlibSurface::LogSurfaceCreation, surface_destroy_func): Count ++ the number of surfaces in addition to the number of pixels. ++ ++2007-08-17 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/public/ImageLogging.h: Remove gImgAccountingLog ++ from here. ++ ++ * modules/libpr0n/src/imgRequest.cpp: Likewise. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (gJPEGDecodeAccountingLog): Create a "JPEGDecoderAccounting" log domain. ++ (nsJPEGDecoder::WriteFrom): Use that log domain. ++ ++ * gfx/thebes/src/gfxXlibSurface.cpp (gXlibSurfaceAccountingLog): ++ Define a "XlibSurfaceAccounting" log domain. ++ (gfxXlibSurface::LogSurfaceCreation): New method to log when an ++ Xlib surface is created from a pixmap. Keeps a counter of how ++ many pixels are allocated globally. ++ (gfxXlibSurface::HookSurfaceDestructionForLogging): Utility method ++ to set user data on the cairo surface, so that we can know when it ++ is destroyed. ++ (gfxXlibSurface::gfxXlibSurface): Log the creation of the surface, ++ and hook it so that we can know when it is destroyed. ++ ++2007-08-17 Federico Mena Quintero <federico@novell.com> ++ ++ * modules/libpr0n/src/imgRequest.cpp (gImgAccountingLog): New ++ logging domain "imgAccounting". We'll use this to log when images ++ get allocated, freed, requested, etc. ++ ++ * modules/libpr0n/public/ImageLogging.h (gImgAccountingLog): ++ Declare this. ++ ++ * modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++ (nsJPEGDecoder::WriteFrom): Log the creation of an image frame. ++ +diff --git gfx/thebes/public/gfxXlibSurface.h gfx/thebes/public/gfxXlibSurface.h +index 078dc73..ea7ba24 100644 +--- gfx/thebes/public/gfxXlibSurface.h ++++ gfx/thebes/public/gfxXlibSurface.h +@@ -21,6 +21,7 @@ + * Contributor(s): + * Stuart Parmenter <pavlov@pavlov.net> + * Vladimir Vukicevic <vladimir@pobox.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -85,6 +86,9 @@ public: + // when the gfxXlibSurface is destroyed. + void TakePixmap(); + ++ void LogSurfaceCreation (); ++ void HookSurfaceDestructionForLogging (); ++ + protected: + // if TakePixmap() was already called on this + PRBool mPixmapTaken; +diff --git gfx/thebes/src/gfxXlibSurface.cpp gfx/thebes/src/gfxXlibSurface.cpp +index dc2a19f..f9c191c 100644 +--- gfx/thebes/src/gfxXlibSurface.cpp ++++ gfx/thebes/src/gfxXlibSurface.cpp +@@ -21,6 +21,7 @@ + * Contributor(s): + * Stuart Parmenter <pavlov@pavlov.net> + * Vladimir Vukicevic <vladimir@pobox.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -37,6 +38,7 @@ + * ***** END LICENSE BLOCK ***** */ + + #include "gfxXlibSurface.h" ++#include "prlog.h" + + #include "cairo.h" + #include "cairo-xlib.h" +@@ -51,6 +53,18 @@ typedef struct { + + static void pixmap_free_func (void *); + ++ ++#if defined(PR_LOGGING) ++static PRLogModuleInfo *gXlibSurfaceAccountingLog = PR_NewLogModule ("XlibSurfaceAccounting"); ++#else ++#define gXlibSurfaceAccountingLog ++#endif ++ ++static cairo_user_data_key_t surface_free_key; ++static int num_surfaces_allocated; ++static PRInt64 pixels_allocated; ++ ++ + #define XLIB_IMAGE_SIDE_SIZE_LIMIT 0xffff + + gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual) +@@ -59,6 +73,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual) + DoSizeQuery(); + cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, mSize.width, mSize.height); + Init(surf); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, const gfxIntSize& size) +@@ -69,6 +86,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, Visual *visual, + + cairo_surface_t *surf = cairo_xlib_surface_create(dpy, drawable, visual, mSize.width, mSize.height); + Init(surf); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& size) +@@ -87,6 +107,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Visual *visual, const gfxIntSize& s + + Init(surf); + TakePixmap(); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, XRenderPictFormat *format, +@@ -100,6 +123,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, Drawable drawable, XRenderPictForma + ScreenOfDisplay(dpy,DefaultScreen(dpy)), + format, mSize.width, mSize.height); + Init(surf); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(Display *dpy, XRenderPictFormat *format, const gfxIntSize& size) +@@ -115,6 +141,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, XRenderPictFormat *format, const gf + format, mSize.width, mSize.height); + Init(surf); + TakePixmap(); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf) +@@ -124,6 +153,9 @@ gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf) + mDisplay = cairo_xlib_surface_get_display(csurf); + + Init(csurf, PR_TRUE); ++ ++ LogSurfaceCreation (); ++ HookSurfaceDestructionForLogging(); + } + + gfxXlibSurface::~gfxXlibSurface() +@@ -198,3 +230,63 @@ pixmap_free_func (void *data) + + delete pfs; + } ++ ++void ++gfxXlibSurface::LogSurfaceCreation () ++{ ++ gfxIntSize size; ++ ++ size = GetSize (); ++ ++ num_surfaces_allocated++; ++ pixels_allocated += (PRInt64) size.width * size.height; ++ ++ PR_LOG (gXlibSurfaceAccountingLog, PR_LOG_DEBUG, ++ ("XlibSurfaceAccounting: Xlib surface %p created, %ux%u pixels - %d surfaces with %lld global pixels allocated", ++ CairoSurface (), ++ size.width, ++ size.height, ++ num_surfaces_allocated, ++ pixels_allocated)); ++} ++ ++struct SurfaceFreeData { ++ gfxIntSize size; ++ cairo_surface_t *surface; ++}; ++ ++static void ++surface_destroy_func (void *closure) ++{ ++ SurfaceFreeData *data; ++ ++ data = (SurfaceFreeData *) closure; ++ ++ num_surfaces_allocated--; ++ pixels_allocated -= (PRInt64) data->size.width * data->size.height; ++ ++ PR_LOG (gXlibSurfaceAccountingLog, PR_LOG_DEBUG, ++ ("XlibSurfaceAccounting: Destroying Xlib surface %p, %dx%d pixels - %d surfaces with %lld global pixels allocated", ++ data->surface, ++ data->size.width, ++ data->size.height, ++ num_surfaces_allocated, ++ pixels_allocated)); ++ ++ delete data; ++} ++ ++void ++gfxXlibSurface::HookSurfaceDestructionForLogging () ++{ ++ SurfaceFreeData *data; ++ ++ data = new SurfaceFreeData; ++ data->size = GetSize (); ++ data->surface = CairoSurface (); ++ ++ cairo_surface_set_user_data (data->surface, ++ &surface_free_key, ++ data, ++ surface_destroy_func); ++} +diff --git modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp +index 16b9fd8..48431e4 100644 +--- modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp ++++ modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp +@@ -22,6 +22,7 @@ + * + * Contributor(s): + * Stuart Parmenter <stuart@mozilla.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -63,8 +64,10 @@ NS_IMPL_ISUPPORTS1(nsJPEGDecoder, imgIDecoder) + + #if defined(PR_LOGGING) + PRLogModuleInfo *gJPEGlog = PR_NewLogModule("JPEGDecoder"); ++static PRLogModuleInfo *gJPEGDecoderAccountingLog = PR_NewLogModule ("JPEGDecoderAccounting"); + #else + #define gJPEGlog ++#define gJPEGDecoderAccountingLog + #endif + + +@@ -208,6 +211,15 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + nsresult rv = inStr->Read((char*)mBuffer, count, &mBufferLen); + *_retval = mBufferLen; + ++ if (mImage) { ++ nsresult result = mImage->AddRestoreData ((char *) mBuffer, count); ++ ++ if (NS_FAILED (result)) { ++ mState = JPEG_ERROR; ++ return result; ++ } ++ } ++ + NS_ASSERTION(NS_SUCCEEDED(rv), "nsJPEGDecoder::WriteFrom -- inStr->Read failed"); + } + // else no input stream.. Flush() ? +@@ -357,6 +369,9 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + /* Check if the request already has an image container. + this is the case when multipart/x-mixed-replace is being downloaded + if we already have one and it has the same width and height, reuse it. ++ ++ This is also the case when an existing container is reloading itself from ++ us. + */ + mImageLoad->GetImage(getter_AddRefs(mImage)); + if (mImage) { +@@ -370,6 +385,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + } + + if (!mImage) { ++ nsresult result; ++ + mImage = do_CreateInstance("@mozilla.org/image/container;1"); + if (!mImage) { + mState = JPEG_ERROR; +@@ -377,6 +394,18 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + } + mImageLoad->SetImage(mImage); + mImage->Init(mInfo.image_width, mInfo.image_height, mObserver); ++ ++ result = mImage->SetDiscardable ("image/jpeg"); /* FIXME: is this MIME type always right for this decoder? */ ++ if (NS_FAILED (result)) { ++ mState = JPEG_ERROR; ++ return result; ++ } ++ ++ result = mImage->AddRestoreData ((char *) mBuffer, count); ++ if (NS_FAILED (result)) { ++ mState = JPEG_ERROR; ++ return result; ++ } + } + + mObserver->OnStartContainer(nsnull, mImage); +@@ -416,7 +445,11 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + } + + mImage->AppendFrame(mFrame); +- } ++ ++ PR_LOG (gJPEGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("JPEGDecoderAccounting: nsJPEGDecoder::WriteFrom -- created image frame with %ux%u pixels", ++ mInfo.image_width, mInfo.image_height)); ++ } + + mObserver->OnStartFrame(nsnull, mFrame); + +@@ -538,6 +571,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + + case JPEG_DONE: + { ++ nsresult result; ++ + LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_DONE case"); + + /* Step 7: Finish decompression */ +@@ -547,6 +582,12 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR + + mState = JPEG_SINK_NON_JPEG_TRAILER; + ++ result = mImage->RestoreDataDone (); ++ if (NS_FAILED (result)) { ++ mState = JPEG_ERROR; ++ return result; ++ } ++ + /* we're done dude */ + break; + } +diff --git modules/libpr0n/decoders/png/nsPNGDecoder.cpp modules/libpr0n/decoders/png/nsPNGDecoder.cpp +index 85f0216..15abc9f 100644 +--- modules/libpr0n/decoders/png/nsPNGDecoder.cpp ++++ modules/libpr0n/decoders/png/nsPNGDecoder.cpp +@@ -23,6 +23,7 @@ + * Contributor(s): + * Stuart Parmenter <stuart@mozilla.com> + * Andrew Smith ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -73,6 +74,7 @@ static void PNGAPI warning_callback(png_structp png_ptr, png_const_charp warning + + #ifdef PR_LOGGING + PRLogModuleInfo *gPNGLog = PR_NewLogModule("PNGDecoder"); ++static PRLogModuleInfo *gPNGDecoderAccountingLog = PR_NewLogModule ("PNGDecoderAccounting"); + #endif + + NS_IMPL_ISUPPORTS1(nsPNGDecoder, imgIDecoder) +@@ -119,6 +121,11 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, + + if (mObserver) + mObserver->OnStartFrame(nsnull, mFrame); ++ ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created image frame with %dx%d pixels in container %p", ++ width, height, ++ mImage.get ())); + } + + // set timeout and frame disposal method for the current frame +@@ -213,9 +220,25 @@ NS_IMETHODIMP nsPNGDecoder::Init(imgILoad *aLoad) + /* void close (); */ + NS_IMETHODIMP nsPNGDecoder::Close() + { ++ nsresult result; ++ + if (mPNG) + png_destroy_read_struct(&mPNG, mInfo ? &mInfo : NULL, NULL); + ++ result = mImage->RestoreDataDone (); ++ if (NS_FAILED (result)) { ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: nsPNGDecoder::Close(): failure in RestoreDataDone() for image container %p", ++ mImage.get ())); ++ ++ mError = PR_TRUE; ++ return result; ++ } ++ ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: nsPNGDecoder::Close(): image container %p is now with RestoreDataDone", ++ mImage.get ())); ++ + return NS_OK; + } + +@@ -234,6 +257,7 @@ static NS_METHOD ReadDataOut(nsIInputStream* in, + PRUint32 *writeCount) + { + nsPNGDecoder *decoder = static_cast<nsPNGDecoder*>(closure); ++ nsresult result; + + if (decoder->mError) { + *writeCount = 0; +@@ -248,10 +272,24 @@ static NS_METHOD ReadDataOut(nsIInputStream* in, + *writeCount = 0; + return NS_ERROR_FAILURE; + } +- + png_process_data(decoder->mPNG, decoder->mInfo, + reinterpret_cast<unsigned char *>(const_cast<char *>(fromRawSegment)), count); + ++ result = decoder->mImage->AddRestoreData ((char *) fromRawSegment, count); ++ if (NS_FAILED (result)) { ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: ReadDataOut(): failed to add restore data to image container %p", ++ decoder->mImage.get ())); ++ ++ decoder->mError = PR_TRUE; ++ *writeCount = 0; ++ return result; ++ } ++ ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: ReadDataOut(): Added restore data to image container %p", ++ decoder->mImage.get ())); ++ + *writeCount = count; + return NS_OK; + } +@@ -525,13 +563,41 @@ info_callback(png_structp png_ptr, png_infop info_ptr) + if (decoder->mObserver) + decoder->mObserver->OnStartDecode(nsnull); + +- decoder->mImage = do_CreateInstance("@mozilla.org/image/container;1"); +- if (!decoder->mImage) +- longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY ++ /* The image container may already exist if it is reloading itself from us. ++ * Check that it has the same width/height; otherwise create a new container. ++ */ ++ decoder->mImageLoad->GetImage (getter_AddRefs (decoder->mImage)); ++ if (decoder->mImage) { ++ PRInt32 container_width, container_height; ++ ++ decoder->mImage->GetWidth (&container_width); ++ decoder->mImage->GetHeight (&container_height); + +- decoder->mImageLoad->SetImage(decoder->mImage); ++ if (container_width != width || container_height != height) ++ decoder->mImage = nsnull; ++ } + +- decoder->mImage->Init(width, height, decoder->mObserver); ++ if (!decoder->mImage) { ++ decoder->mImage = do_CreateInstance("@mozilla.org/image/container;1"); ++ if (!decoder->mImage) ++ longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY ++ ++ decoder->mImageLoad->SetImage(decoder->mImage); ++ ++ decoder->mImage->Init(width, height, decoder->mObserver); ++ ++ /* FIXME: is this MIME type always right for this decoder? */ ++ if (NS_FAILED (decoder->mImage->SetDiscardable ("image/png"))) { ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: info_callback(): failed to set image container %p as discardable", ++ decoder->mImage.get ())); ++ longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY ++ } ++ ++ PR_LOG (gPNGDecoderAccountingLog, PR_LOG_DEBUG, ++ ("PNGDecoderAccounting: info_callback(): set image container %p as discardable", ++ decoder->mImage.get ())); ++ } + + if (decoder->mObserver) + decoder->mObserver->OnStartContainer(nsnull, decoder->mImage); +@@ -757,7 +823,7 @@ end_callback(png_structp png_ptr, png_infop info_ptr) + } + + decoder->mImage->DecodingComplete(); +- ++ + if (decoder->mObserver) { + if (!(decoder->apngFlags & FRAME_HIDDEN)) + decoder->mObserver->OnStopFrame(nsnull, decoder->mFrame); +diff --git modules/libpr0n/public/imgIContainer.idl modules/libpr0n/public/imgIContainer.idl +index fc42335..524af96 100644 +--- modules/libpr0n/public/imgIContainer.idl ++++ modules/libpr0n/public/imgIContainer.idl +@@ -22,6 +22,7 @@ + * + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -144,4 +145,10 @@ interface imgIContainer : nsISupports + * @note -1 means forever. + */ + attribute long loopCount; ++ ++ /* Methods to discard uncompressed images and restore them again */ ++ [noscript] void setDiscardable(in string aMimeType); ++ [noscript] void addRestoreData(in charPtr aBuffer, ++ in unsigned long aCount); ++ [noscript] void restoreDataDone(); + }; +diff --git modules/libpr0n/src/imgContainer.cpp modules/libpr0n/src/imgContainer.cpp +index 776c4ee..22d8735 100644 +--- modules/libpr0n/src/imgContainer.cpp ++++ modules/libpr0n/src/imgContainer.cpp +@@ -25,6 +25,7 @@ + * Asko Tontti <atontti@cc.hut.fi> + * Arron Mogge <paper@animecity.nu> + * Andrew Smith ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -42,23 +43,49 @@ + + #include "nsComponentManagerUtils.h" + #include "imgIContainerObserver.h" ++#include "ImageErrors.h" + #include "nsIImage.h" ++#include "imgILoad.h" ++#include "imgIDecoder.h" ++#include "imgIDecoderObserver.h" + #include "imgContainer.h" + #include "nsIInterfaceRequestor.h" + #include "nsIInterfaceRequestorUtils.h" + #include "nsAutoPtr.h" ++#include "nsStringStream.h" ++#include "prmem.h" ++#include "prlog.h" + + #include "gfxContext.h" + ++/* Accounting for compressed data */ ++#if defined(PR_LOGGING) ++static PRLogModuleInfo *gCompressedImageAccountingLog = PR_NewLogModule ("CompressedImageAccounting"); ++#else ++#define gCompressedImageAccountingLog ++#endif ++ ++static int num_containers_with_discardable_data; ++static PRInt64 num_compressed_image_bytes; ++ ++ + NS_IMPL_ISUPPORTS3(imgContainer, imgIContainer, nsITimerCallback, nsIProperties) + + //****************************************************************************** + imgContainer::imgContainer() : + mSize(0,0), ++ mNumFrames(0), + mAnim(nsnull), + mAnimationMode(kNormalAnimMode), + mLoopCount(-1), +- mObserver(nsnull) ++ mObserver(nsnull), ++ mDiscardable(PR_FALSE), ++ mDiscarded(PR_FALSE), ++ mDiscardableMimeType(nsnull), ++ mRestoreData(nsnull), ++ mRestoreDataLength(0), ++ mRestoreDataDone(PR_FALSE), ++ mDiscardTimer(nsnull) + { + } + +@@ -67,6 +94,32 @@ imgContainer::~imgContainer() + { + if (mAnim) + delete mAnim; ++ ++ if (mDiscardableMimeType) { ++ free (mDiscardableMimeType); ++ mDiscardableMimeType = nsnull; ++ } ++ ++ if (mRestoreData) { ++ PR_Free (mRestoreData); ++ ++ num_containers_with_discardable_data--; ++ num_compressed_image_bytes -= mRestoreDataLength; ++ ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: destroying imgContainer %p. " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ this, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++ ++ mRestoreDataLength = 0; ++ } ++ ++ if (mDiscardTimer) { ++ mDiscardTimer->Cancel (); ++ mDiscardTimer = nsnull; ++ } + } + + //****************************************************************************** +@@ -124,15 +177,53 @@ NS_IMETHODIMP imgContainer::GetHeight(PRInt32 *aHeight) + return NS_OK; + } + ++nsresult imgContainer::GetCurrentFrameNoRef (gfxIImageFrame** aFrame) ++{ ++ nsresult result; ++ ++ result = RestoreDiscardedData (); ++ if (NS_FAILED (result)) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::GetCurrentFrameNoRef(): error %d in RestoreDiscardedData(); " ++ "returning a null frame from imgContainer %p", ++ result, ++ this)); ++ ++ *aFrame = nsnull; ++ return result; ++ } ++ ++ if (!mAnim) ++ *aFrame = mFrames.SafeObjectAt(0); ++ else if (mAnim->lastCompositedFrameIndex == mAnim->currentAnimationFrameIndex) ++ *aFrame = mAnim->compositingFrame; ++ else ++ *aFrame = mFrames.SafeObjectAt(mAnim->currentAnimationFrameIndex); ++ ++ if (!*aFrame) ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::GetCurrentFrameNoRef(): returning null frame from imgContainer %p " ++ "(no errors when restoring data)", ++ this)); ++ ++ return NS_OK; ++} ++ + //****************************************************************************** + /* readonly attribute gfxIImageFrame currentFrame; */ + NS_IMETHODIMP imgContainer::GetCurrentFrame(gfxIImageFrame **aCurrentFrame) + { ++ nsresult result; ++ + NS_ASSERTION(aCurrentFrame, "imgContainer::GetCurrentFrame; Invalid Arg"); + if (!aCurrentFrame) + return NS_ERROR_INVALID_POINTER; + +- if (!(*aCurrentFrame = inlinedGetCurrentFrame())) ++ result = GetCurrentFrameNoRef (aCurrentFrame); ++ if (NS_FAILED (result)) ++ return result; ++ ++ if (!*aCurrentFrame) + return NS_ERROR_FAILURE; + + NS_ADDREF(*aCurrentFrame); +@@ -148,7 +239,7 @@ NS_IMETHODIMP imgContainer::GetNumFrames(PRUint32 *aNumFrames) + if (!aNumFrames) + return NS_ERROR_INVALID_ARG; + +- *aNumFrames = mFrames.Count(); ++ *aNumFrames = mNumFrames; + + return NS_OK; + } +@@ -157,16 +248,24 @@ NS_IMETHODIMP imgContainer::GetNumFrames(PRUint32 *aNumFrames) + /* gfxIImageFrame getFrameAt (in unsigned long index); */ + NS_IMETHODIMP imgContainer::GetFrameAt(PRUint32 index, gfxIImageFrame **_retval) + { ++ nsresult result; ++ + NS_ASSERTION(_retval, "imgContainer::GetFrameAt; Invalid Arg"); + if (!_retval) + return NS_ERROR_INVALID_POINTER; + +- if (!mFrames.Count()) { ++ if (mNumFrames == 0) { + *_retval = nsnull; + return NS_OK; + } + +- NS_ENSURE_ARG(index < static_cast<PRUint32>(mFrames.Count())); ++ NS_ENSURE_ARG((int) index < mNumFrames); ++ ++ result = RestoreDiscardedData (); ++ if (NS_FAILED (result)) { ++ *_retval = nsnull; ++ return result; ++ } + + if (!(*_retval = mFrames[index])) + return NS_ERROR_FAILURE; +@@ -183,16 +282,17 @@ NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item) + NS_ASSERTION(item, "imgContainer::AppendFrame; Invalid Arg"); + if (!item) + return NS_ERROR_INVALID_ARG; +- +- PRInt32 numFrames = mFrames.Count(); +- +- if (numFrames == 0) { ++ ++ if (mFrames.Count () == 0) { + // This may not be an animated image, don't do all the animation stuff. + mFrames.AppendObject(item); ++ ++ mNumFrames++; ++ + return NS_OK; + } + +- if (numFrames == 1) { ++ if (mFrames.Count () == 1) { + // Now that we got a second frame, initialize animation stuff. + if (!ensureAnimExists()) + return NS_ERROR_OUT_OF_MEMORY; +@@ -216,11 +316,13 @@ NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item) + itemRect); + + mFrames.AppendObject(item); ++ ++ mNumFrames++; + + // If this is our second frame, start the animation. + // Must be called after AppendObject because StartAnimation checks for > 1 + // frame +- if (numFrames == 1) ++ if (mFrames.Count () == 1) + StartAnimation(); + + return NS_OK; +@@ -230,6 +332,7 @@ NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item) + /* void removeFrame (in gfxIImageFrame item); */ + NS_IMETHODIMP imgContainer::RemoveFrame(gfxIImageFrame *item) + { ++ /* Remember to decrement mNumFrames if you implement this */ + return NS_ERROR_NOT_IMPLEMENTED; + } + +@@ -253,7 +356,7 @@ NS_IMETHODIMP imgContainer::DecodingComplete(void) + mAnim->doneDecoding = PR_TRUE; + // If there's only 1 frame, optimize it. + // Optimizing animated images is not supported +- if (mFrames.Count() == 1) ++ if (mNumFrames == 1) + mFrames[0]->SetMutable(PR_FALSE); + return NS_OK; + } +@@ -292,11 +395,11 @@ NS_IMETHODIMP imgContainer::SetAnimationMode(PRUint16 aAnimationMode) + break; + case kNormalAnimMode: + if (mLoopCount != 0 || +- (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mFrames.Count()))) ++ (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mNumFrames))) + StartAnimation(); + break; + case kLoopOnceAnimMode: +- if (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mFrames.Count())) ++ if (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mNumFrames)) + StartAnimation(); + break; + } +@@ -312,12 +415,18 @@ NS_IMETHODIMP imgContainer::StartAnimation() + (mAnim && (mAnim->timer || mAnim->animating))) + return NS_OK; + +- if (mFrames.Count() > 1) { ++ if (mNumFrames > 1) { + if (!ensureAnimExists()) + return NS_ERROR_OUT_OF_MEMORY; + + PRInt32 timeout; +- gfxIImageFrame *currentFrame = inlinedGetCurrentFrame(); ++ nsresult result; ++ gfxIImageFrame *currentFrame; ++ ++ result = GetCurrentFrameNoRef (¤tFrame); ++ if (NS_FAILED (result)) ++ return result; ++ + if (currentFrame) { + currentFrame->GetTimeout(&timeout); + if (timeout <= 0) // -1 means display this frame forever +@@ -376,8 +485,15 @@ NS_IMETHODIMP imgContainer::ResetAnimation() + mAnim->currentAnimationFrameIndex = 0; + // Update display + nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver)); +- if (observer) ++ if (observer) { ++ nsresult result; ++ ++ result = RestoreDiscardedData (); ++ if (NS_FAILED (result)) ++ return result; ++ + observer->FrameChanged(this, mFrames[0], &(mAnim->firstFrameRefreshArea)); ++ } + + if (oldAnimating) + return StartAnimation(); +@@ -411,10 +527,161 @@ NS_IMETHODIMP imgContainer::SetLoopCount(PRInt32 aLoopCount) + return NS_OK; + } + ++static PRBool ++discarding_is_enabled (void) ++{ ++ static PRBool inited; ++ static PRBool enabled; ++ ++ if (!inited) { ++ inited = PR_TRUE; ++ ++ enabled = (getenv ("MOZ_DISABLE_IMAGE_DISCARD") == nsnull); ++ } ++ ++ return enabled; ++} ++ ++//****************************************************************************** ++/* void setDiscardable(in string mime_type); */ ++NS_IMETHODIMP imgContainer::SetDiscardable (const char* aMimeType) ++{ ++ NS_ASSERTION(aMimeType, "imgContainer::SetDiscardable() called with null aMimeType"); ++ ++ if (!discarding_is_enabled ()) ++ return NS_OK; ++ ++ if (mDiscardable) { ++ NS_WARNING ("imgContainer::SetDiscardable(): cannot change an imgContainer which is already discardable"); ++ return NS_ERROR_FAILURE; ++ } ++ ++ mDiscardableMimeType = strdup (aMimeType); ++ if (!mDiscardableMimeType) ++ return NS_ERROR_OUT_OF_MEMORY; ++ ++ mDiscardable = PR_TRUE; ++ ++ num_containers_with_discardable_data++; ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: Making imgContainer %p (%s) discardable. " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ this, ++ aMimeType, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++ ++ return NS_OK; ++} ++ ++//****************************************************************************** ++/* void addRestoreData(in nsIInputStream aInputStream, in unsigned long aCount); */ ++NS_IMETHODIMP imgContainer::AddRestoreData (char *aBuffer, PRUint32 aCount) ++{ ++ PRSize new_size; ++ char *new_buffer; ++ ++ NS_ASSERTION(aBuffer, "imgContainer::AddRestoreData() called with null aBuffer"); ++ ++ if (!discarding_is_enabled ()) ++ return NS_OK; ++ ++ if (!mDiscardable) { ++ NS_WARNING ("imgContainer::AddRestoreData() can only be called if SetDiscardable is called first"); ++ return NS_ERROR_FAILURE; ++ } ++ ++ if (mRestoreDataDone) { ++ /* We are being called from the decoder while the data is being restored ++ * (i.e. we were fully loaded once, then we discarded the image data, then ++ * we are being restored). We don't want to save the compressed data again, ++ * since we already have it. ++ */ ++ return NS_OK; ++ } ++ ++ new_size = mRestoreDataLength + aCount; ++ ++ new_buffer = (char *) PR_Realloc (mRestoreData, new_size); ++ if (new_buffer) ++ mRestoreData = new_buffer; ++ else { ++ /* Hmm, should we discard the whole buffer? The caller isn't going to be able to recover... */ ++ return NS_ERROR_OUT_OF_MEMORY; ++ } ++ ++ memcpy (mRestoreData + mRestoreDataLength, aBuffer, aCount); ++ mRestoreDataLength = new_size; ++ ++ num_compressed_image_bytes += aCount; ++ ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: Added compressed data to imgContainer %p (%s). " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ this, ++ mDiscardableMimeType, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++ ++ return NS_OK; ++} ++ ++/* Note! buf must be declared as char buf[9]; */ ++static void ++get_header_str (char *buf, char *data, PRSize data_len) ++{ ++ int i; ++ int n; ++ static char hex[] = "0123456789abcdef"; ++ ++ n = data_len < 4 ? data_len : 4; ++ ++ for (i = 0; i < n; i++) { ++ buf[i * 2] = hex[(data[i] >> 4) & 0x0f]; ++ buf[i * 2 + 1] = hex[data[i] & 0x0f]; ++ } ++ ++ buf[i * 2] = 0; ++} ++ ++//****************************************************************************** ++/* void restoreDataDone(); */ ++NS_IMETHODIMP imgContainer::RestoreDataDone (void) ++{ ++ char buf[9]; ++ ++ if (!discarding_is_enabled ()) ++ return NS_OK; ++ ++ if (mRestoreDataDone) ++ return NS_OK; ++ ++ mRestoreDataDone = PR_TRUE; ++ ++ get_header_str (buf, mRestoreData, mRestoreDataLength); ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::RestoreDataDone() - data is done for container %p (%s), %d real frames (cached as %d frames) - header %p is 0x%s (length %d)", ++ this, ++ mDiscardableMimeType, ++ mFrames.Count (), ++ mNumFrames, ++ mRestoreData, ++ buf, ++ (int) mRestoreDataLength)); ++ ++ return ResetDiscardTimer (); ++} ++ + //****************************************************************************** + /* void notify(in nsITimer timer); */ + NS_IMETHODIMP imgContainer::Notify(nsITimer *timer) + { ++ nsresult result; ++ ++ result = RestoreDiscardedData (); ++ if (NS_FAILED (result)) ++ return result; ++ + // This should never happen since the timer is only set up in StartAnimation() + // after mAnim is checked to exist. + NS_ASSERTION(mAnim, "imgContainer::Notify() called but mAnim is null"); +@@ -433,8 +700,7 @@ NS_IMETHODIMP imgContainer::Notify(nsITimer *timer) + return NS_OK; + } + +- PRInt32 numFrames = mFrames.Count(); +- if (!numFrames) ++ if (mNumFrames == 0) + return NS_OK; + + gfxIImageFrame *nextFrame = nsnull; +@@ -448,7 +714,7 @@ NS_IMETHODIMP imgContainer::Notify(nsITimer *timer) + // finished decoding (see EndFrameDecode) + if (mAnim->doneDecoding || + (nextFrameIndex < mAnim->currentDecodingFrameIndex)) { +- if (numFrames == nextFrameIndex) { ++ if (mNumFrames == nextFrameIndex) { + // End of Animation + + // If animation mode is "loop once", it's time to stop animating +@@ -875,3 +1141,328 @@ NS_IMETHODIMP imgContainer::GetKeys(PRUint32 *count, char ***keys) + } + return mProperties->GetKeys(count, keys); + } ++ ++static int ++get_discard_timer_ms (void) ++{ ++ /* FIXME: don't hardcode this */ ++ return 5000; /* 5 seconds */ ++} ++ ++void ++imgContainer::sDiscardTimerCallback (nsITimer *aTimer, void *aClosure) ++{ ++ imgContainer *self = (imgContainer *) aClosure; ++ int old_frame_count; ++ ++ NS_ASSERTION (aTimer == self->mDiscardTimer, ++ "imgContainer::DiscardTimerCallback() got a callback for an unknown timer"); ++ ++ self->mDiscardTimer = nsnull; ++ ++ old_frame_count = self->mFrames.Count (); ++ ++ if (self->mAnim) { ++ delete self->mAnim; ++ self->mAnim = nsnull; ++ } ++ ++ self->mFrames.Clear (); ++ ++ self->mDiscarded = PR_TRUE; ++ ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: discarded uncompressed image data from imgContainer %p (%s) - %d frames (cached count: %d); " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ self, ++ self->mDiscardableMimeType, ++ old_frame_count, ++ self->mNumFrames, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++} ++ ++nsresult ++imgContainer::ResetDiscardTimer (void) ++{ ++ if (!discarding_is_enabled ()) ++ return NS_OK; ++ ++ if (!mDiscardTimer) { ++ mDiscardTimer = do_CreateInstance("@mozilla.org/timer;1"); ++ ++ if (!mDiscardTimer) ++ return NS_ERROR_OUT_OF_MEMORY; ++ } else { ++ if (NS_FAILED (mDiscardTimer->Cancel ())) ++ return NS_ERROR_FAILURE; ++ } ++ ++ return mDiscardTimer->InitWithFuncCallback (sDiscardTimerCallback, ++ (void *) this, ++ get_discard_timer_ms (), ++ nsITimer::TYPE_ONE_SHOT); ++} ++ ++nsresult ++imgContainer::RestoreDiscardedData (void) ++{ ++ nsresult result; ++ int num_expected_frames; ++ ++ if (!mDiscarded) ++ return NS_OK; ++ ++ result = ResetDiscardTimer (); ++ if (NS_FAILED (result)) ++ return result; ++ ++ num_expected_frames = mNumFrames; ++ ++ result = ReloadImages (); ++ if (NS_FAILED (result)) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::RestoreDiscardedData() for container %p failed to ReloadImages()", ++ this)); ++ return result; ++ } ++ ++ mDiscarded = PR_FALSE; ++ ++ NS_ASSERTION (mNumFrames == mFrames.Count (), ++ "number of restored image frames doesn't match"); ++ NS_ASSERTION (num_expected_frames == mNumFrames, ++ "number of restored image frames doesn't match the original number of frames!"); ++ ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, ++ ("CompressedImageAccounting: imgContainer::RestoreDiscardedData() restored discarded data " ++ "for imgContainer %p (%s) - %d image frames. " ++ "Compressed containers: %d, Compressed data bytes: %lld", ++ this, ++ mDiscardableMimeType, ++ mNumFrames, ++ num_containers_with_discardable_data, ++ num_compressed_image_bytes)); ++ ++ return NS_OK; ++} ++ ++class ContainerLoader : public imgILoad, ++ public imgIDecoderObserver, ++ public nsSupportsWeakReference ++{ ++public: ++ ++ NS_DECL_ISUPPORTS ++ NS_DECL_IMGILOAD ++ NS_DECL_IMGIDECODEROBSERVER ++ NS_DECL_IMGICONTAINEROBSERVER ++ ++ ContainerLoader (void); ++ ++private: ++ ++ imgIContainer *mContainer; ++}; ++ ++NS_IMPL_ISUPPORTS4 (ContainerLoader, imgILoad, imgIDecoderObserver, imgIContainerObserver, nsISupportsWeakReference) ++ ++ContainerLoader::ContainerLoader (void) ++{ ++} ++ ++/* Implement imgILoad::image getter */ ++NS_IMETHODIMP ++ContainerLoader::GetImage(imgIContainer **aImage) ++{ ++ *aImage = mContainer; ++ NS_IF_ADDREF (*aImage); ++ return NS_OK; ++} ++ ++/* Implement imgILoad::image setter */ ++NS_IMETHODIMP ++ContainerLoader::SetImage(imgIContainer *aImage) ++{ ++ mContainer = aImage; ++ return NS_OK; ++} ++ ++/* Implement imgILoad::isMultiPartChannel getter */ ++NS_IMETHODIMP ++ContainerLoader::GetIsMultiPartChannel(PRBool *aIsMultiPartChannel) ++{ ++ *aIsMultiPartChannel = PR_FALSE; /* FIXME: is this always right? */ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStartRequest() */ ++NS_IMETHODIMP ++ContainerLoader::OnStartRequest (imgIRequest *aRequest) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStartDecode() */ ++NS_IMETHODIMP ++ContainerLoader::OnStartDecode (imgIRequest *aRequest) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStartContainer() */ ++NS_IMETHODIMP ++ContainerLoader::OnStartContainer (imgIRequest *aRequest, imgIContainer *aContainer) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStartFrame() */ ++NS_IMETHODIMP ++ContainerLoader::OnStartFrame (imgIRequest *aRequest, gfxIImageFrame *aFrame) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onDataAvailable() */ ++NS_IMETHODIMP ++ContainerLoader::OnDataAvailable (imgIRequest *aRequest, gfxIImageFrame *aFrame, const nsIntRect * aRect) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStopFrame() */ ++NS_IMETHODIMP ++ContainerLoader::OnStopFrame (imgIRequest *aRequest, gfxIImageFrame *aFrame) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStopContainer() */ ++NS_IMETHODIMP ++ContainerLoader::OnStopContainer (imgIRequest *aRequest, imgIContainer *aContainer) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStopDecode() */ ++NS_IMETHODIMP ++ContainerLoader::OnStopDecode (imgIRequest *aRequest, nsresult status, const PRUnichar *statusArg) ++{ ++ return NS_OK; ++} ++ ++/* Implement imgIDecoderObserver::onStopRequest() */ ++NS_IMETHODIMP ++ContainerLoader::OnStopRequest (imgIRequest *aRequest, PRBool aIsLastPart) ++{ ++ return NS_OK; ++} ++ ++/* implement imgIContainerObserver::frameChanged() */ ++NS_IMETHODIMP ++ContainerLoader::FrameChanged (imgIContainer *aContainer, gfxIImageFrame *aFrame, nsIntRect * aDirtyRect) ++{ ++ return NS_OK; ++} ++ ++static char * ++make_id_from_mime_type (char *mime_type) ++{ ++ const char idbase[] = "@mozilla.org/image/decoder;2?type="; ++ int idbase_len = strlen (idbase); ++ char *id; ++ ++ id = (char *) PR_Malloc (strlen (mime_type) + idbase_len + 1); ++ if (!id) ++ return nsnull; ++ ++ strcpy (id, idbase); ++ strcpy (id + idbase_len, mime_type); ++ ++ return id; ++} ++ ++nsresult ++imgContainer::ReloadImages (void) ++{ ++ char *id; ++ nsCOMPtr<imgILoad> loader; ++ nsCOMPtr<imgIDecoder> decoder; ++ nsresult result; ++ PRUint32 written; ++ nsCOMPtr<nsIInputStream> stream; ++ char buf[9]; ++ ++ NS_ASSERTION (mRestoreData, ++ "imgContainer::ReloadImages(): mRestoreData should not be null"); ++ NS_ASSERTION (mRestoreDataDone, ++ "imgContainer::ReloadImages(): mRestoreDataDone shoudl be true!"); ++ ++ id = make_id_from_mime_type (mDiscardableMimeType); ++ if (!id) ++ return NS_ERROR_OUT_OF_MEMORY; ++ ++ mNumFrames = 0; ++ NS_ASSERTION (mFrames.Count() == 0, ++ "imgContainer::ReloadImages(): mFrames should be empty"); ++ ++ decoder = do_CreateInstance (id); ++ PR_Free (id); ++ ++ if (!decoder) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_WARNING, ++ ("CompressedImageAccounting: imgContainer::ReloadImages() could not create decoder for %s", ++ mDiscardableMimeType)); ++ return NS_IMAGELIB_ERROR_NO_DECODER; ++ } ++ ++ loader = new ContainerLoader (); ++ if (!loader) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_WARNING, ++ ("CompressedImageAccounting: imgContainer::ReloadImages() could not allocate ContainerLoader " ++ "when reloading the images for container %p", ++ this)); ++ return NS_ERROR_OUT_OF_MEMORY; ++ } ++ ++ loader->SetImage (this); ++ ++ result = decoder->Init (loader); ++ if (NS_FAILED (result)) { ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_WARNING, ++ ("CompressedImageAccounting: imgContainer::ReloadImages() image container %p " ++ "failed to initialize the decoder (%s)", ++ this, ++ mDiscardableMimeType)); ++ return result; ++ } ++ ++ result = NS_NewByteInputStream (getter_AddRefs (stream), mRestoreData, mRestoreDataLength, NS_ASSIGNMENT_DEPEND); ++ NS_ENSURE_SUCCESS (result, result); ++ ++ get_header_str (buf, mRestoreData, mRestoreDataLength); ++ PR_LOG (gCompressedImageAccountingLog, PR_LOG_WARNING, ++ ("CompressedImageAccounting: imgContainer::ReloadImages() starting to restore images for container %p (%s) - " ++ "header %p is 0x%s (length %d)", ++ this, ++ mDiscardableMimeType, ++ mRestoreData, ++ buf, ++ (int) mRestoreDataLength)); ++ ++ result = decoder->WriteFrom (stream, mRestoreDataLength, &written); ++ NS_ENSURE_SUCCESS (result, result); ++ ++ result = decoder->Flush (); ++ if (!(result == NS_OK || result == NS_ERROR_NOT_IMPLEMENTED)) /* PNG doesn't implement Flush(), for example */ ++ return result; ++ ++ result = decoder->Close (); ++ NS_ENSURE_SUCCESS (result, result); ++ ++ NS_ASSERTION (mFrames.Count() == mNumFrames, ++ "imgContainer::ReloadImages(): the restored mFrames.Count() doesn't match mNumFrames!"); ++ ++ return result; ++} +diff --git modules/libpr0n/src/imgContainer.h modules/libpr0n/src/imgContainer.h +index 3db7034..aa56939 100644 +--- modules/libpr0n/src/imgContainer.h ++++ modules/libpr0n/src/imgContainer.h +@@ -23,6 +23,7 @@ + * Contributor(s): + * Stuart Parmenter <pavlov@netscape.com> + * Chris Saari <saari@netscape.com> ++ * Federico Mena-Quintero <federico@novell.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or +@@ -194,14 +195,8 @@ private: + timer->Cancel(); + } + }; +- +- inline gfxIImageFrame* inlinedGetCurrentFrame() { +- if (!mAnim) +- return mFrames.SafeObjectAt(0); +- if (mAnim->lastCompositedFrameIndex == mAnim->currentAnimationFrameIndex) +- return mAnim->compositingFrame; +- return mFrames.SafeObjectAt(mAnim->currentAnimationFrameIndex); +- } ++ ++ nsresult GetCurrentFrameNoRef(gfxIImageFrame** aFrame); + + inline Anim* ensureAnimExists() { + if (!mAnim) +@@ -274,10 +269,15 @@ private: + nsIntSize mSize; + + //! All the <gfxIImageFrame>s of the PNG ++ // *** IMPORTANT: if you use mFrames in a method, call RestoreDiscardedData() first to ensure ++ // that the frames actually exist (they may have been discarded to save memory). + nsCOMArray<gfxIImageFrame> mFrames; ++ int mNumFrames; /* stored separately from mFrames.Count() to support discarded images */ + + nsCOMPtr<nsIProperties> mProperties; +- ++ ++ // *** IMPORTANT: if you use mAnim in a method, call RestoreDiscardedData() first to ensure ++ // that the frames actually exist (they may have been discarded to save memory). + imgContainer::Anim* mAnim; + + //! See imgIContainer for mode constants +@@ -288,6 +288,19 @@ private: + + //! imgIContainerObserver + nsWeakPtr mObserver; ++ ++ PRBool mDiscardable; ++ PRBool mDiscarded; ++ char* mDiscardableMimeType; ++ char* mRestoreData; ++ PRSize mRestoreDataLength; ++ PRBool mRestoreDataDone; ++ nsCOMPtr<nsITimer> mDiscardTimer; ++ ++ nsresult ResetDiscardTimer (void); ++ nsresult RestoreDiscardedData (void); ++ nsresult ReloadImages (void); ++ static void sDiscardTimerCallback (nsITimer *aTimer, void *aClosure); + }; + + #endif /* __imgContainer_h__ */ diff --git a/www/firefox3-devel/files/patch-sysnss b/www/firefox3-devel/files/patch-sysnss index 025d43c3d..6f3d06298 100644 --- a/www/firefox3-devel/files/patch-sysnss +++ b/www/firefox3-devel/files/patch-sysnss @@ -1,11 +1,11 @@ ---- security/manager/ssl/src/Makefile.in.orig Mon Aug 14 19:22:52 2006 -+++ security/manager/ssl/src/Makefile.in Thu Aug 31 15:17:20 2006 -@@ -124,19 +124,19 @@ +--- security/manager/ssl/src/Makefile.in.orig 2007-07-23 15:03:01.000000000 -0400 ++++ security/manager/ssl/src/Makefile.in 2007-09-04 20:47:03.000000000 -0400 +@@ -125,13 +125,11 @@ pipboot \ $(NULL) -EXTRA_DEPS = $(NSS_DEP_LIBS) - +- DEFINES += -DNSS_ENABLE_ECC # Use local includes because they are inserted before INCLUDES @@ -13,8 +13,9 @@ -LOCAL_INCLUDES += $(NSS_CFLAGS) +LOCAL_INCLUDES += -I%%LOCALBASE%%/include/nss/nss + ifeq ($(OS_ARCH),Darwin) EXTRA_DSO_LDOPTS += \ - $(MOZ_UNICHARUTIL_LIBS) \ +@@ -143,6 +141,7 @@ $(MOZ_COMPONENT_LIBS) \ $(MOZ_JS_LIBS) \ $(NSS_LIBS) \ @@ -22,3 +23,12 @@ $(NULL) include $(topsrcdir)/config/rules.mk +--- toolkit/components/url-classifier/src/Makefile.in.orig 2007-09-05 09:00:23.000000000 -0400 ++++ toolkit/components/url-classifier/src/Makefile.in 2007-09-05 09:00:27.000000000 -0400 +@@ -36,6 +36,3 @@ + $(NULL) + + include $(topsrcdir)/config/rules.mk +- +-export:: $(topsrcdir)/security/nss/lib/freebl/sha512.c +- $(INSTALL) $^ . diff --git a/www/firefox3-devel/files/patch-toolkit_xre_Makefile.in b/www/firefox3-devel/files/patch-toolkit_xre_Makefile.in new file mode 100644 index 000000000..4a9c8533a --- /dev/null +++ b/www/firefox3-devel/files/patch-toolkit_xre_Makefile.in @@ -0,0 +1,8 @@ +--- toolkit/xre/Makefile.in.orig 2007-09-10 10:31:53.000000000 -0400 ++++ toolkit/xre/Makefile.in 2007-09-10 10:35:00.000000000 -0400 +@@ -263,5 +263,3 @@ + libs:: platform.ini + $(INSTALL) $^ $(DIST)/bin + +-install:: +- $(INSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir) diff --git a/www/firefox3-devel/files/patch-toolkit_xre_nsXREDirProvider.cpp b/www/firefox3-devel/files/patch-toolkit_xre_nsXREDirProvider.cpp deleted file mode 100644 index 0c5a07ab2..000000000 --- a/www/firefox3-devel/files/patch-toolkit_xre_nsXREDirProvider.cpp +++ /dev/null @@ -1,19 +0,0 @@ ---- toolkit/xre/nsXREDirProvider.cpp.orig Tue Oct 4 11:46:26 2005 -+++ toolkit/xre/nsXREDirProvider.cpp Sun Feb 5 23:54:31 2006 -@@ -820,6 +820,7 @@ - - char* appNameFolder = nsnull; - char profileFolderName[MAXPATHLEN] = "."; -+ char temp[MAXPATHLEN]; - - // Offset 1 for the outermost folder to make it hidden (i.e. using the ".") - char* writing = profileFolderName + 1; -@@ -829,7 +830,6 @@ - rv = localDir->AppendNative(nsDependentCString(profileFolderName)); - NS_ENSURE_SUCCESS(rv, rv); - -- char temp[MAXPATHLEN]; - GetProfileFolderName(temp, gAppData->name); - appNameFolder = temp; - } - |