Mozilla is using a SIMD-accelerated JPEG decorder in Fx5. We should try to adapt this to VMX using what we will have learned from WebM. Medium as we're still reasonably fast at this even in C.
Comment #1
Posted on Jun 7, 2011 by Massive RhinoDropping milestone since we're not going to do this yet.
Comment #2
Posted on Jun 21, 2011 by Massive Rhino(No comment was entered for this change.)
Comment #3
Posted on Sep 12, 2011 by Happy RabbitWould be far to complex to implement all the SIMD code IMO.
But I noticed that Mac OS X (10.4 and 10.5) have a heavily Altivec accelerated version of libjpeg inside the ImageIO framework which is a sub framework of ApplicationServices framework. Disassembling shows clearly all the altivec acceleration code. I tried to link to that library instead of the one in the mozilla sources. All exported symbols are prefixed with cg so I had to create a modified header. It links without problems but TFF unfortunately crashes upon decoding JPEG files. Apples seems to have changed something with the buffers...
Alternatively one might adapt nsJPEGDecoder to use the ImageIO framework.
Comment #4
Posted on Sep 12, 2011 by Happy RabbitWould be far to complex to implement all the SIMD code IMO.
But I noticed that Mac OS X (10.4 and 10.5) have a heavily Altivec accelerated version of libjpeg inside the ImageIO framework which is a sub framework of ApplicationServices framework. Disassembling shows clearly all the altivec acceleration code. I tried to link to that library instead of the one in the mozilla sources. All exported symbols are prefixed with cg so I had to create a modified header. It links without problems but TFF unfortunately crashes upon decoding JPEG files. Apples seems to have changed something with the buffers...
Alternatively one might adapt nsJPEGDecoder to use the ImageIO framework.
Comment #5
Posted on Sep 13, 2011 by Happy RabbitThat code should help us in order to use the ImageIO framework for our purposes.
http://vlists.pepperfish.net/pipermail/netsurf-dev-netsurf-browser.org/2011-March/002398.html
It was implemented only months ago as the JPEG importer for the Mac OS X port of the netsurf browser (interesting project!).
Comment #6
Posted on Sep 13, 2011 by Happy RabbitSome success in directly using the libJPEG.dylib from ImageIO.framework: the djpeg command line decompressor works with the altivec accelerated libJPEG (verified by setting a breakpoint in the altivec accelerated IDCT function). So I'll continue with that path...
Comment #7
Posted on Sep 13, 2011 by Massive RhinoThe only worry I have about that is that if there's a bug or security flaw in Apple's libJPEG, it's not going to get fixed. I think using this is worthwhile in the near term, but we need to have a fallback (I presume back to the Mozilla in-tree libjpeg with or without AltiVec) if a security issue crops up.
Comment #8
Posted on Sep 13, 2011 by Happy RabbitWell, I'm actually using the configure flag "--with-system-libjpeg" (don't know if written correctly), so I only have to supply a modified header adding the "cg" prefix to the libjpeg function calls and a link to the library.
For now I simply added both the headers and the library to the Xcode SDK and reconfigured with "--with-system-libjpeg". So that's pretty clean.
Comment #9
Posted on Sep 13, 2011 by Happy RabbitMore success! Decoding JPEGs actually works as long as all the data is actually loaded completely upon decoding. So I can view images I load from the hard disk and also from the web as long as I set the inital paint delay high enough! I also think I already discovered the issue; libjpeg decompressing is called although there isn't any new data available. This seems to happen because an internal counter indicates the contrary. libjpeg should in fact recognize that situation, I think. I'll introduce further controls before the function calls to the library.
Comment #10
Posted on Sep 13, 2011 by Happy RabbitIt does finally work, with an extra check that the image stream source address passed to libjpeg isn't NULL!
The attached patch works provided you're linking against the Mac OS X 10.4 SDK which must be located at "/Developer/SDKs/MacOS10.4u.sdk". The symlink that's included in the patch might not be created the right way - if not you'll have to manually construct it (in the file "jpeg-imageio/lib/libjpeg.dylib" you see the path to link to).
Furthermore you have to add "ac_add_options --with-system-jpeg=$topsrcdir/jpeg-imageio" to your mozconfig in order to activate it.
That extra check for the source address not being NULL to me seems to be a good idea anyway and even in case the mozilla libjpeg (or any other one) is used it saves the function call that would return some cycles later with the information that there wasn't any data available.
I did a speed test by dragging and dropping a large jpeg file into a TFF7 window. By simple counting the seconds it needed to appear on my PowerBook Wallstreet G4/500 there was an improvement of roughly 20%.
- jpeg-imageio.patch 84.52KB
Comment #11
Posted on Sep 14, 2011 by Happy RabbitTODO: - the verification might be done in an inline function in the "jpeglib.h" header, also doing the wrapping - the jpeg compressor isn't tested yet (where is it used?)
Comment #12
Posted on Sep 14, 2011 by Massive RhinoDamn, that's pretty nice work. I'm still nervous about this for 7, especially since 7 final is pretty close, but let's get this into 8 along with the other proposed optimizations.
Comment #13
Posted on Sep 14, 2011 by Massive Rhino(No comment was entered for this change.)
Comment #14
Posted on Sep 14, 2011 by Massive RhinoOne thing. If I read your patch right, we should be able to use this on all architectures; we let the SDK determine if AltiVec gets enabled, yes? We can just add this and let OS X sort it out for G3 vs G4/G5.
Comment #15
Posted on Sep 18, 2011 by Happy RabbitYes, the Apple jpeg lib should determine the CPU type and choose altivec acceleration according to it. I didn't test it but I have a G3 CPU to put in my PowerBook Wallstreet to test it with - but I would have to rebuild the entire sources because I bult with auto-vectorization enabled.
As for the release version: Why don't make an intermediate version based on 7? That would have the benefit of having less parts changed at once than releasing it with 8.
Comment #16
Posted on Sep 19, 2011 by Massive RhinoThere might be a 7.0.1 if I don't get the 8 widget changes rewritten in time, and it would appear in that if we have to go that route.
I'm trying to eliminate the symlink, however: that doesn't fit nicely with our change sets or hg. If we have to have it, it's probably better to have the build system generate it and do so in an unmonitored directory like obj-ff-*. Have you tried pointing --with-system-libjpeg directly to the directory with the dylib instead of symlinking it? I'm out of town or I'd try this myself right now.
Comment #17
Posted on Sep 19, 2011 by Happy RabbitThe lib has to reside in a sub-directory "lib" inside the path passed to "--with-system-libjpeg" and as well the headers but in a sub-directory "include".
All that can be worked around by making the build system place the headers and shared library or symlinks to them in the directories "obj-ff-/dist/include" or "obj-ff-/dist/lib" respectively.
Comment #18
Posted on Sep 19, 2011 by Happy RabbitNow a reworked version that does the necessary verification for null pointers in an inlined function in the jpeglib header. It does verify for encoding as well as for decoding although encoding remains untested because I don't know where it is used in firefox.
It doesn't need the symlink to the libjpeg any longer but just the headers.
You activate it by adding just "ac_add_options --with-system-jpeg" without a path to your mozconfig.
- jpeg-imageio_2.patch 84.87KB
Comment #19
Posted on Sep 19, 2011 by Happy RabbitI experience the issue that with certain large jpeg images there is a long delay (a minute or so here) after the first lines of image data are decoded.
Comment #20
Posted on Sep 21, 2011 by Happy RabbitHere a release candidate version of the patch.
The decoder now works for the files that previously didn't load correctly. The reason is basically an error in the mozilla sources because it sometimes passes a non-zero number of bytes available in the buffer while the buffer pointer indeed is a NULL pointer. This gets solved by resetting the number of bytes in the buffer to zero and calling the mozilla JPEG decoder to supply us with new data. Sounds logical and works!
I tested the JPEG encoder as well using a screenshot grabbing add-on. Using a breakpoint I verified it indeed uses the apple libjpeg.
So now I don't know of any more issues with that patch.
- jpeg-imageio_3.patch 85.14KB
Comment #21
Posted on Sep 22, 2011 by Massive RhinoLooks good. Mozilla has signed off on 7, so I'm already building it, but this will be in 7.0.1 or 8b1.
Comment #22
Posted on Sep 22, 2011 by Massive RhinoPromoting you to contributor so I can credit you for the issue internally.
Comment #23
Posted on Sep 25, 2011 by Happy RabbitSome simple speed comparisons done on a PowerBook Wallstreet G4 500 MHz:
using djpeg to convert a jpeg file (photo, 9.4 MB) to ppm format, destination /dev/null (default options):
libjpeg ImageIO
real 0m1.478s user 0m1.226s sys 0m0.148s
libjpeg 6b
real 0m3.979s user 0m3.708s sys 0m0.159s
libjpeg 8c
real 0m4.251s user 0m3.967s sys 0m0.173s
using cjpeg to convert the result from above (43 MB) back to jpeg format, destination /dev/null (default options):
libjpeg ImageIO
real 0m3.314s user 0m2.762s sys 0m0.479s
libjpeg 6b
real 0m3.668s user 0m3.077s sys 0m0.473s
libjpeg 8c
real 0m3.663s user 0m3.084s sys 0m0.472s
libjpeg 6b was built using gcc-4.6 with LTO and auto-vectorization enabled. cjpeg and djpeg to link against the ImageIO libJPEG were built with the same settings. libjpeg 8c was built by MacPorts.
The decompression speed is impressively improved while there's little improvement in compressing. I did this speed tests as measuring the improvement inside TFF isn't that trivial.
Comment #24
Posted on Sep 26, 2011 by Quick BirdAre you planning to use ImageIO for PNG decoding too?
Comment #25
Posted on Sep 26, 2011 by Massive RhinoFor PNG, never, as the libpng in 10.4 ImageIO has several known vulnerabilities. So we will only ever use our in-tree png (which doesn't have any form of SIMD acceleration anyway, so we're not losing anything; see M655693 and others).
To the best of my audit ability, the JPEG code does not (there was an exploit fixed in 10.4.6, and I have not been able to find a vulnerable exploit since), is the easiest to disable if one is found and has the most to gain from imageio, so we're going to do so for JPEG only right now. Other image types might be considered in the future, but PNG won't be one of them.
Comment #26
Posted on Sep 26, 2011 by Happy RabbitAlready thought of it but PNG decoding isn't altivec accelerated in ImageIO. TIFF and JPEG2000 are accelerated.
Comment #27
Posted on Sep 27, 2011 by Massive RhinoScheduled for 8
Comment #28
Posted on Oct 4, 2011 by Massive RhinoI landed this, but it isn't linking against libJPEG.dylib. What does otool -L say on your XUL?
I'm still fiddling with it.
Comment #29
Posted on Oct 4, 2011 by Happy RabbitYou don't need to fiddle - must be some simple issue.
You added "--with-system-jpeg" (WITHOUT any path argument!!!) to your mozconfig and reconfigured and rebuilt everything?
After configuring the source tree ("make -f client.mk configure") there must be the following lines in "config.status" in your build directory: "s%@JPEG_CFLAGS@%-I/Volumes/Programme/OpenSource/mozilla-beta/jpeg-imageio%g s%@JPEG_LIBS@%-L/System/Library/Frameworks/ApplicationServices.framework/Frameworks/ImageIO.framework/Resources -lJPEG%g"
Comment #30
Posted on Oct 4, 2011 by Massive RhinoYes, I'm not wholly incompetent as a project lead ;)
I don't see it linked to XUL or in the config.status, so something is wrong on this end. I'm rechecking the diff to make sure it landed right.
Comment #31
Posted on Oct 4, 2011 by Happy RabbitNo errors in "config.log" either?
Comment #32
Posted on Oct 4, 2011 by Happy RabbitStill working fine here.
configure must output the line: "checking for _cg_jpeg_destroy_compress in -lJPEG... yes"
You might actually have to delete "config.cache" in your build directory before reconfiguring (not to forget running "autoconf213" first).
Comment #33
Posted on Oct 4, 2011 by Happy RabbitOr just remove the lines: "ac_cv_lib_jpeg_jpeg_destroy_compress=${ac_cv_lib_jpeg_jpeg_destroy_compress=no}" and "ac_cv_lib_JPEG__cg_jpeg_destroy_compress=${ac_cv_lib_JPEG__cg_jpeg_destroy_compress=no}" from config.cache.
Comment #34
Posted on Oct 4, 2011 by Massive RhinoI see that configure line, but not the line in config.status. I'm going to try blasting everything out and rebuilding from the diffs. It is undoubtedly something stuck in the cache.
Comment #35
Posted on Oct 4, 2011 by Massive RhinoA slight tweak to configure.in was needed for 8. I'm waiting for it to rebuild and I'll test it tonight (I have a meeting shortly which will take up the rest of the day).
Comment #36
Posted on Oct 8, 2011 by Massive RhinoLanded in 8 beta. Overall improvement approximately 1.25x. Job well done.
Comment #37
Posted on Jul 16, 2012 by Happy Rabbitconfigure.in has to be tweaked once again for 16. Attached comes an updated patch (from my mercurial queue).
Comment #38
Posted on Jul 23, 2012 by Massive Rhino(No comment was entered for this change.)
Comment #39
Posted on Jul 27, 2012 by Happy RabbitThere was a bug in the previous patch so here a patch to the patch:
diff -r 2887b2e42a95 configure.in --- a/configure.in Mon Jul 23 13:19:43 2012 +0200 +++ b/configure.in Fri Jul 27 16:11:15 2012 +0200 @@ -4044,7 +4044,7 @@ dnl === TenFourFox issue 51 if test "$MOZ_NATIVE_JPEG" = 1 -a "${JPEG_DIR}" = "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/ImageIO.framework/Resources"; then MOZ_JPEG_CFLAGS="-I${topsrcdir}/jpeg-imageio" - MOZ_JPEG_LIBS="-L{JPEG_DIR} ${MOZ_JPEG_LIBS}" + MOZ_JPEG_LIBS="-L${JPEG_DIR} ${MOZ_JPEG_LIBS}" else
if test -n "${JPEG_DIR}" -a -d "${JPEG_DIR}" -a "$MOZ_NATIVE_JPEG" = 1; then
Comment #40
Posted on Sep 15, 2012 by Massive RhinoWorking on 17. I assume the configure.in is the only thing that needs to be changed for 16-17.
Comment #41
Posted on Oct 12, 2012 by Happy RabbitIn Aurora 18 a big number of JPEGs is displayed white.
Comment #42
Posted on Oct 12, 2012 by Massive RhinoThis could be bug 792199. It is being backed out.
Comment #43
Posted on Oct 12, 2012 by Happy RabbitMight also be that ImageIO libjpeg doesn't (fully) support JCS which was introduced with bug 791305.
Comment #44
Posted on Oct 12, 2012 by Happy RabbitIt was indeed some JCS extension. I managed to make some changes that simply don't use the additional JCS extensions the ImageIO libjpeg doesn't support. I also downgraded the libjpeg headers to that of version 6b (alias 62).
Attached comes a patch that has to be applied on top of the already existing changes.
- jpeg-imageio.diff 22.93KB
Comment #45
Posted on Oct 12, 2012 by Massive RhinoReopened for 18
Comment #46
Posted on Dec 3, 2012 by Massive RhinoLanded in 10.4Fx 19 tree
Comment #47
Posted on Dec 21, 2012 by Massive RhinoVerified working
Status: Verified
Labels:
Type-Enhancement
Priority-High
Milestone-Judgment-Day