jcupitt / vipsdisp

Tiny libvips / gtk+4 image viewer
MIT License
130 stars 10 forks source link

Build VIPSDISP on windows #21

Closed euzada closed 5 months ago

euzada commented 11 months ago

Hi @jcupitt, is there any way I can build vipsdip on Windows? I successfully built it from source on ubuntu, and I tried to install everything I needed on MINGW64. The problem I faced is in meson.build find_library 'm', so I bypass it using cc.find_library('m', required: false). But when I try to run ninja I got a lot of errors. here a copy of part of errors: FAILED: src/vipsdisp.exe.p/meson-generated_.._vipsdispmarshal.c.obj "cl" "-Isrc/vipsdisp.exe.p" "-Isrc" "-I../src" "-IC:/msys64/mingw64/include/libgsf-1" "-IC:/msys64/m ingw64/include/libxml2" "-IC:/msys64/mingw64/include/" "-IC:/msys64/mingw64/include/pango-1.0" "-IC: /msys64/mingw64/include/harfbuzz" "-IC:/msys64/mingw64/include/fribidi" "-IC:/msys64/mingw64/include /librsvg-2.0" "-IC:/msys64/mingw64/include/gdk-pixbuf-2.0" "-IC:/msys64/mingw64/include/webp" "-IC:/ msys64/mingw64/include/cairo" "-IC:/msys64/mingw64/include/freetype2" "-IC:/msys64/mingw64/include/l ibpng16" "-IC:/msys64/mingw64/include/pixman-1" "-IC:/msys64/mingw64/include/OpenEXR" "-IC:/msys64/m ingw64/include/Imath" "-IC:/msys64/mingw64/include/openjpeg-2.5" "-IC:/msys64/mingw64/include/orc-0. 4" "-IC:/msys64/mingw64/include/glib-2.0" "-IC:/msys64/mingw64/lib/glib-2.0/include" "-IC:/msys64/mi ngw64/include/gtk-4.0" "-IC:/msys64/mingw64/include/graphene-1.0" "-IC:/msys64/mingw64/lib/graphene- 1.0/include" "-I." "/MDd" "/nologo" "/showIncludes" "/utf-8" "/W2" "/std:c11" "/Od" "/Zi" "-DHAVE_CO NFIG_H" "-mfpmath=sse" "-msse" "-msse2" "-DLIBDEFLATE_DLL" "/Fdsrc/vipsdisp.exe.p/meson-generated_.. _vipsdispmarshal.c.pdb" /Fosrc/vipsdisp.exe.p/meson-generated_.._vipsdispmarshal.c.obj "/c" src/vips dispmarshal.c CreateProcess failed: The system cannot find the file specified.

Any suggestions?

jcupitt commented 11 months ago

Hi @euzada,

I would start with the libvips build system:

https://github.com/libvips/build-win64-mxe

And add the various gtk4 binaries.

kleisauke commented 10 months ago

The vipsdisp branch adds support for this. It seems to build successfully and works as intended.

Screenshot 2023-10-26 184708

To build locally, you can use:

$ git clone -b vipsdisp https://github.com/libvips/build-win64-mxe.git
$ cd build-win64-mxe/
$ ./build.sh web x86_64 shared --with-disp
jcupitt commented 10 months ago

Woah, that's fantastic Kleis! Nice job!

What's performance like? Can you zoom smoothly on large images?

kleisauke commented 10 months ago

Zooming and panning on large images also appear to be seamless; I think the performance is on par with that on Linux. See for example this screencast:

https://github.com/jcupitt/vipsdisp/assets/12746591/69f28944-8e8d-4e83-9de4-0af529d2d219

The only minor thing I noticed is that the icon for the previous and next page is broken. Screenshot 2023-10-26 192319

jcupitt commented 10 months ago

I suppose that's a problem with the icon theme?

What if you hold down i? It's supposed to do a smooth 60fps zoom on the mouse pointer.

kleisauke commented 10 months ago

Yeah, it looks like a theme issue. Here's a screencast while holding down i.

https://github.com/jcupitt/vipsdisp/assets/12746591/896b8bc4-78f1-4a02-b0d0-d43dacb121f7

jcupitt commented 10 months ago

So ... hot. I'll try a build here.

jcupitt commented 10 months ago

I noticed a tiny thing on ubuntu 23.04 -- I see:

$ ./build.sh web x86_64 shared --with-disp
Error: short-name "buildpack-deps:bullseye" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"

I had to disable podman by editing build.sh.

euzada commented 10 months ago

What a good news. Thank you @kleisauke and @jcupitt for sharing. I will try to build it tomorrow on my windows and leave you feedback after building and testing.

euzada commented 10 months ago

The vipsdisp branch adds support for this. It seems to build successfully and works as intended.

Screenshot 2023-10-26 184708

To build locally, you can use:

$ git clone -b vipsdisp https://github.com/libvips/build-win64-mxe.git
$ cd build-win64-mxe/
$ ./build.sh web x86_64 shared --with-disp

Hi @kleisauke , is that branch on the top of 8.15.0 rc1 or 8.14?

kleisauke commented 10 months ago

is that branch on the top of 8.15.0 rc1 or 8.14?

It's based on top of v8.15.0-rc1, as required by vipsdisp v2.6.1. https://github.com/jcupitt/vipsdisp/blob/35496349adf6463f4ea2ac73c0049a05edfe7dc9/meson.build#L40-L41

kleisauke commented 10 months ago
$ ./build.sh web x86_64 shared --with-disp
Error: short-name "buildpack-deps:bullseye" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"

I had to disable podman by editing build.sh.

I think this patch would also fix that:

--- a/build.sh
+++ b/build.sh
@@ -186,7 +186,7 @@ fi
 mkdir -p $tmpdir

 # Ensure latest Debian stable base image
-$oci_runtime pull buildpack-deps:bullseye
+$oci_runtime pull docker.io/library/buildpack-deps:bullseye

 # Create a machine image with all the required build tools pre-installed
 $oci_runtime build -t libvips-build-win-mxe container
--- a/container/Dockerfile
+++ b/container/Dockerfile
@@ -1,4 +1,4 @@
-FROM buildpack-deps:bullseye
+FROM docker.io/library/buildpack-deps:bullseye

 RUN apt-get update \
   && apt-get install -y \

But indeed, perhaps I should disable that Podman in favor of Docker if-else statement, since Fedora/RHEL also have an RPM called podman-docker, which can be used as a drop-in placement for the docker utility.

euzada commented 10 months ago

The build was successful. It builds V8.15.0 rc1 and vipsdisp.exe (V2.6.0). Loaded a very large image (7.5GB ) with no issues. The previous and next page icons are missing as mentioned previously.

jcupitt commented 10 months ago

We should make a list of small issues with the win build, since we're all looking at it. I noticed:

Are there any others?

euzada commented 10 months ago

When I first open the executable I see terminal with: (vipsdisp.exe:17092): GLib-GIO-WARNING **: 15:06:47.724: win32 session dbus binary not found

Than when I tried to save an image in another tiff format, I got:

(vipsdisp.exe:17092): GLib-GObject-CRITICAL **: 15:06:57.945: ../glib-2.78.1/gobject/gsignal.c:2451: signal id '0' is invalid for instance '00000262ee2848b0'

(vipsdisp.exe:17092): GLib-GObject-CRITICAL **: 15:06:57.948: ../glib-2.78.1/gobject/gsignal.c:2451: signal id '0' is invalid for instance '00000262ee2849f0'

(vipsdisp.exe:17092): GLib-GObject-CRITICAL **: 15:06:58.056: ../glib-2.78.1/gobject/gsignal.c:2677: instance '00000262ee2849f0' has no handler with id '0'

(vipsdisp.exe:17092): GLib-GObject-CRITICAL **: 15:06:58.059: ../glib-2.78.1/gobject/gsignal.c:2730: instance '00000262ee2849f0' has no handler with id '0'
Unknown type for property "keep"
kleisauke commented 10 months ago

I also noticed:

  • no dbus.exe, leading to slow startup ... we could disable dbus integration (is it useful on win? I'm not sure) or include the exe in the build (probably not worth it)

I've tentatively "fixed" this with commit https://github.com/libvips/build-win64-mxe/commit/6ad6917957f93b16e33b953c3e0a8d716ec2d8c4. I'm not sure if D-Bus integration can be disabled, it looks like a required thing.

(vipsdisp.exe:17092): GLib-GObject-CRITICAL **: 15:06:57.945: ../glib-2.78.1/gobject/gsignal.c:2451: signal id '0' is invalid for instance '00000262ee2848b0'

(vipsdisp.exe:17092): GLib-GObject-CRITICAL **: 15:06:57.948: ../glib-2.78.1/gobject/gsignal.c:2451: signal id '0' is invalid for instance '00000262ee2849f0'

(vipsdisp.exe:17092): GLib-GObject-CRITICAL **: 15:06:58.056: ../glib-2.78.1/gobject/gsignal.c:2677: instance '00000262ee2849f0' has no handler with id '0'

(vipsdisp.exe:17092): GLib-GObject-CRITICAL **: 15:06:58.059: ../glib-2.78.1/gobject/gsignal.c:2730: instance '00000262ee2849f0' has no handler with id '0'
Unknown type for property "keep"

I'm not sure about those gsignal errors, but the Unknown type for property "keep" warning can be fixed by adding a case for G_IS_PARAM_SPEC_FLAGS( pspec ) in save_options_add_option(), similar to G_IS_PARAM_SPEC_ENUM( pspec ). https://github.com/jcupitt/vipsdisp/blob/02b5250c602d062b2908db987bd3ea381b890971/src/saveoptions.c#L377 (adding support for flags as save option would also make VipsForeignPngFilter work)

jcupitt commented 10 months ago

Ah you're right, the save-as dialog is missing some stuff, and doesn't resize too well. I have to make a long train journey today, I'll have a poke at it.

jcupitt commented 10 months ago

I fixed up sizing and added flags support, so that resolved the keep message, I think.

jcupitt commented 10 months ago

Save as TIFF seems to work fine on linux, perhaps there's a win issue here?

euzada commented 10 months ago

I build the latest update.

  1. Now, the gdbus.exe is compiled and created in the bin folder and the first error (vipsdisp.exe:17092): GLib-GIO-WARNING **: 15:06:47.724: win32 session dbus binary not found is fixed.

  2. The template icons are now working.

  3. The Unknown type for property "keep" is also fixed.

  4. Saving the Tiff (or tif) is completed successfully with these information in terminal. but the save works. Hope this is helpful.

(vipsdisp.exe:22024): GLib-GObject-CRITICAL **: 09:38:38.900: ../glib-2.78.1/gobject/gsignal.c:2451: signal id '0' is invalid for instance '0000022ea0be0a10'

(vipsdisp.exe:22024): GLib-GObject-CRITICAL **: 09:38:38.905: ../glib-2.78.1/gobject/gsignal.c:2451: signal id '0' is invalid for instance '0000022ea0be0910'

(vipsdisp.exe:22024): GLib-GObject-CRITICAL **: 09:38:38.996: ../glib-2.78.1/gobject/gsignal.c:2677: instance '0000022ea0be0910' has no handler with id '0'

(vipsdisp.exe:22024): GLib-GObject-CRITICAL **: 09:38:38.998: ../glib-2.78.1/gobject/gsignal.c:2730: instance '0000022ea0be0910' has no handler with id '0'
  1. Notice that "i" and "o" are not smooth anymore. it zoom/dezoom with glitch/freeze for fraction of second from time to time.
jcupitt commented 10 months ago

That's great! Is app startup faster? It was quite slow before. It ought to pop up a window almost instantly.

I don't know what's causing the signal errors, I don't see them here :( Some gtk/glib compat issue, perhaps?

i/o not being smooth can happen with some file formats. Are files that were smooth before hitching now?

euzada commented 10 months ago

That's great! Is app startup faster? It was quite slow before. It ought to pop up a window almost instantly.

I don't know what's causing the signal errors, I don't see them here :( Some gtk/glib compat issue, perhaps?

i/o not being smooth can happen with some file formats. Are files that were smooth before hitching now?

I check the previous version, the i/o where not smooth. So maybe it is my file size. Will generate smaller file and test again. Is there any way to load it without opening Terminal first?

jcupitt commented 10 months ago

Windows .exe files have a special flag inside for "I'm a GUI app". If this is not set, Windows will automatically make a terminal and display program input and output.

We just need to set a compiler flag when linking vipsdisp.exe ... I forget what it's called.

jcupitt commented 10 months ago

Ah, setting -mwindows when linking vipsdisp.exe, I think. We might also need to define WinMain(), I'm not sure.

kleisauke commented 10 months ago

It looks like specifying win_subsystem: 'windows' in Meson's executable() function would fix that. https://mesonbuild.com/Reference-manual_functions.html#executable_win_subsystem https://github.com/GNOME/gtk/blob/020ef51cb00fdf0e4a440468d41ed8256881da17/demos/widget-factory/meson.build#L71

I'll try a patch and also investigate those signal errors.

euzada commented 10 months ago

That's great! Is app startup faster? It was quite slow before. It ought to pop up a window almost instantly.

I did some test using the following command in bash for windows and did not see any difference in the latest version. time "E:\vips-dev-8.15\bin\vipsdisp.exe" | ps ax | grep vipsdisp | grep -v grep | awk '{print $1}' | xargs kill

I don't know if I should run a different command.

The output was something like that for both versions:

real    0m1.080s
user    0m0.015s
sys     0m0.321s
jcupitt commented 10 months ago

Oh, clever idea. Perhaps it's just slow to load all those DLLs? There are a lot of them. A static build might be faster.

euzada commented 10 months ago

I build it with the following command:

./build.sh web x86_64 shared --with-disp

Do I try static build?

jcupitt commented 10 months ago

Yes, try static.

I tried this in vipsdispapp.c:

static void
vipsdisp_app_activate( GApplication *app )
{
    ImageWindow *win;

    win = image_window_new( VIPSDISP_APP( app ) );
    gtk_window_present( GTK_WINDOW( win ) );
    process_events();
    exit(0);
}

ie. on startup, show the main window, process a few events, then quit. On ubuntu I see:

$ time vipsdisp 

real    0m0.200s
user    0m0.160s
sys 0m0.075s

which feels fast.

euzada commented 10 months ago

Yes, try static.

I tried this in vipsdispapp.c:

static void
vipsdisp_app_activate( GApplication *app )
{
    ImageWindow *win;

    win = image_window_new( VIPSDISP_APP( app ) );
    gtk_window_present( GTK_WINDOW( win ) );
    process_events();
    exit(0);
}

ie. on startup, show the main window, process a few events, then quit. On ubuntu I see:

$ time vipsdisp 

real  0m0.200s
user  0m0.160s
sys   0m0.075s

which feels fast.

I am getting this error trying to build it with static flag like that: ./build.sh web x86_64 static --with-disp

ERROR: GTK cannot be built as a statically linked library on Windows.

jcupitt commented 10 months ago

You need to build libvips static, then vipsdisp dynamic.

kleisauke commented 10 months ago

The vipsdisp branch has been updated to incorporate this. I'll have a look at the disabled static build and GUI app hint tomorrow.

jcupitt commented 10 months ago

It looks like specifying win_subsystem: 'windows' in Meson's executable() function would fix that.

Oh nice find, I added that to src/meson.build

kleisauke commented 10 months ago

Great! I can confirm that commit ff7b8cb76134226af8cfb14a28c7af30dda68b75 removes the stray terminal window.

To avoid having to spend any extra CPU time building these binaries, I've uploaded the 64-bit libvips 8.15.0-rc1 Windows binaries with vipsdisp here: https://libvips-packaging.s3.amazonaws.com/vips-dev-w64-web-8.15.0-rc1-disp.zip https://libvips-packaging.s3.amazonaws.com/vips-dev-w64-all-8.15.0-rc1-disp.zip (these binaries were built against commit https://github.com/libvips/build-win64-mxe/commit/9c86ee10cf999711eb69178c16c96ce3c52c1680)

euzada commented 10 months ago

I can confirm no Terminal at the start. and Save windows use Windows explorer. I will do some test for the speed later today.

Thank you.

jcupitt commented 10 months ago

I tried out "loupe", the new gtk4 image viewer that gnome have made:

https://gitlab.gnome.org/GNOME/loupe

With st-francis.jpg:

$ vipsheader st-francis.jpg
st-francis.jpg: 30000x26319 uchar, 3 bands, srgb, jpegload

The version in ubuntu 23.10 loads the image in 13.5s and needs 7.5gb of memory. Panning needs maybe 8% of CPU on my PC. It's nice and smooth.

The Gnome nightly build of Loupe loads in 13.5s again, but only needs 2.3gb of memory, so they've made some good improvements there. CPU use seems about the same.

On this ubuntu 23.10 PC, a release build of vipsdisp loads the image in 8s and needs 1.3gb of memory. Panning is about 15% of CPU. We're a little less smooth.

So we win on load speed and memory use, as you'd hope heh. We could probably get CPU use down --- at the moment, vipsdisp culls tiles to the viewport every frame, but we only really need to cull on tile boundaries. It might improve the frame rate too.

They have much slower mousewheel zoom, so we could maybe tune that.

jcupitt commented 10 months ago

... I tuned the zoom speed and initial window size to match loupe.

euzada commented 10 months ago

I don't know if on windows it is the same. When I try to zoom on my PC, The GPU is the one how manage the zoom and increased to almost 10% while zooming (I believe it is good things) . Do you see any GPU increase on Linux?

jcupitt commented 10 months ago

Yes, it uses the GPU on linux too.

euzada commented 10 months ago

I start a fresh build. I am not sure it will apply to the loupe integration. It will take time to build llvm. I use git config pull.rebase true and it said:

Updating 7681c50a..c185fad1
Fast-forward
 docs/build-matrix.html | 6 +++---
 docs/packages.json     | 6 +++---
 src/freetds.mk         | 4 ++--
 src/libjpeg-turbo.mk   | 4 ++--
 src/openssl.mk         | 4 ++--
 5 files changed, 12 insertions(+), 12 deletions(-)

Do you know if this will apply to loupe integration?

jcupitt commented 10 months ago

There's no loupe integration, I was just benchmarking it for comparison.

jcupitt commented 10 months ago

Oh, you mean the changes to vipsdisp to match loupe? You'd need to change vipsdisp.mk to build git master.

euzada commented 10 months ago

Yes, this is what I meant. I test the last build and it takes 70ms for the GUI to start. I used Measure-Command {.\vipsdisp.exe} in PowerShell.

euzada commented 10 months ago
  • if you fullscreen, the right-click menu stops working (why?? how odd) and you have to press F11 to get back to windowed mode

In Full screen with F11, the menu will be hidden behind the GUI in the background. If you do "Windows + d" to see the desktop than do it again "Win + d" the menu will appear on the front. I believe the solution is to force the right-click menu to always be on the top.

We should probably add something like that for the menu: gtk_window_set_keep_above(GTK_WINDOW(window), TRUE); as explained in the following link: [Bug 171456](https://bugzilla.gnome.org/show_bug.cgi?id=171456) - "Keep Above" option in Gimp broken on Win32

jcupitt commented 9 months ago

In Full screen with F11, the menu will be hidden behind the GUI in the background. If you do "Windows + d" to see the desktop than do it again "Win + d" the menu will appear on the front.

Ah, interesting!

gtk4 doesn't have keep_above (gimp is still on gtk2 I think):

https://docs.gtk.org/gtk4/class.Window.html

vipsdisp uses the same menu for the burger button on the header bar, and right-click on the image. Maybe this is the cause? Perhaps we ought to use separate menus, or remove the right-click menu?

jcupitt commented 5 months ago

I think this is all done now.