DISTRHO / DPF

DISTRHO Plugin Framework
ISC License
645 stars 93 forks source link

[branch: latest develop from today] arch: Windows Issue: Cairo widgets going black #437

Open brummer10 opened 10 months ago

brummer10 commented 10 months ago

I noticed a issue with cairo based plugs [vst2/3] under windows. They goes black after a short while, how fast, depend on how often they get redrawn, it seems . To get them then repaint again the host [fruity loops] needs to be restarted. This could happen to single SubWidgets as well as to the complete UI. This issue didn't happen when run under linux.

AnClark commented 9 months ago

I have encounted a similar issue.

Besides UI going black, the UI may also misbehave: some parts goes black and unoperatable.

And it also affects my DAW's widgets: the Win32 native UI's fonts becomes Windows 95 style.

See: https://github.com/jpcima/string-machine/issues/33

falkTX commented 9 months ago

issues with host UI scale were solved a while ago, pugl was changing the global high-dpi process state which is not meant to happen for plugins.

regarding the black screen, I suspect this might be a redraw issue, with some areas not being repainted correctly (or rather, the request for repainting not taking into account the scaled resolution of the plugin GUI)

brummer10 commented 9 months ago

regarding the black screen, I suspect this might be a redraw issue, with some areas not being repainted correctly (or rather, the request for repainting not taking into account the scaled resolution of the plugin GUI)

Sure, the question is why that happen. It is not that some redraw operation fails, it is the complete draw connection is broken when that happen. As far I know the cairo_win32_surface is only valid during WM_PAINT, so it needs to be created and destroyed on each call to repaint(), otherwise it may lose the connection and drawing isn't possible any more. Here is how we handle painting with cairo under win32 within the GxPlugins, that worked as it should and is surprisingly fast. https://github.com/brummer10/GxVoodoFuzz.lv2/blob/master/gui/gx_platform_mswin.c#L277

brummer10 commented 9 months ago

So I found a solution. https://github.com/brummer10/StompTuner/blob/main/pugl.patch

This patch does basically what is shown in the link above. It create a cairo_image_surface on puglWinCairoEnter and provide the cairo_t* pointer for it as DrawContext. Now all cairo drawings happen outside WM_PAINT. Then, on puglWinCairoLeave we do the paint (BeginPaint -> create win32 surface, copy the image surface over, destroy anything and EndPaint.) I tested this on windows11 and it works perfect. Surly it could be optimized as we didn't relay need to create and destroy the cairo_image_surface on each WM_PAINT, this is only necessary on resize, otherwise we could reuse it. Just I can't see were resizing is handled in the win_cairo source.

falkTX commented 9 months ago

that needs to go into https://github.com/lv2/pugl which then also starts the discussion around it. I am not too familiar with cairo to know any good or bad sides about such changes, drobilla for sure will know more. Plus the idea is to use as much stock pugl as possible, preferably even the direct upstream version.