Re: Does the timing of composition need to be moved from dcomp.dll to win32u?

zhengxianwei <[email protected]> Thu, 19 Jun 2025 16:28:44 +0800
Newsgroups gmane.comp.emulators.wine.devel
Message-ID <CABeGAqWEfptLGVbWFv3dnV3334w2WUyypieNQQsU1_cDLjV5jg@mail.gmail.com>
  The part that confuses me here is that, in *win32u*, it doesn't seem
convenient to manipulate data structures like *swapchain*.

  In *dcomp.dll*, I can use a large number of COM interface functions, such
as IDXGISwapChain1_GetDesc and IDXGISwapChain1_GetBuffer. But is this
allowed in *win32u*? If I were to heavily use COM interfaces within *win32u*,
would that cause any issues?



On Thu, Jun 19, 2025 at 3:48 PM Zhiyi Zhang <[email protected]> wrote:

>
>
> On 6/19/25 14:13, zhengxianwei wrote:
> > Zhiyi Zhang provided an implementation of DComp composition:
> >
> https://gitlab.winehq.org/zhiyi/wine/-/commit/ef4f90c2ae909f4a732f0ebeae3b7e98479cd63d
> <
> https://gitlab.winehq.org/zhiyi/wine/-/commit/ef4f90c2ae909f4a732f0ebeae3b7e98479cd63d
> >
> >
> > I created a simple sample that renders three equally sized red circles
> with varying alpha values on a plain white background window.
> >
> > On Windows, it displays as follows.
> >
> > dcomp_test_window.png
> >
> > But on Linux, it display as follows.
> > dcomp_test_wine.png
> >
> > One of the main issues here is that the background turns black. This is
> because the foreground (swapchain) is not alpha-blended with the background
> (GDI); instead, it is simply overlaid using BitBlt.
> >
> > ```
> > *    BitBlt(dst_dc, 0, 0, rect.right - rect.left, rect.bottom -
> rect.top, src_dc, 0, 0, SRCCOPY);
> > *
> > ```
> >
> > So I added an alpha_blend step here instead of simply using the original
> BitBlt.
> >
> > ```
> >     s1 = src_data;
> >     d1 = dst_data;
> >     for (int i = 0; i < height; i++)
> >     {
> >         for (int j = 0; j < width; j++)
> >         {
> >             // src is alpha pre multiple
> >             float bg_alpha = ((255.f - s1[3])) / 255;
> >             d1[0] = (d1[0] * bg_alpha) + s1[0];
> >             d1[1] = (d1[1] * bg_alpha) + s1[1];
> >             d1[2] = (d1[2] * bg_alpha) + s1[2];
> >
> >             s1 += 4;
> >             d1 += 4;
> >         }
> >     }
> >
> >     //iret = SetDIBits(dst_hdc, dst_bitmap, 0, height, dst_data, &bmi,
> DIB_RGB_COLORS);
> >     iret = SetDIBitsToDevice(dst_hdc, 0, 0, width, height,
> >         0, 0, 0, height, dst_data, &bmi, DIB_RGB_COLORS);
> > ```
> > The new display effect is as follows.
> > dcomp_test_wine_alpha_blend.png
> > It looks like basic blending is working, but the alpha values of the
> circles are lost. After analyzing the issue, I found the following cause.
> >
> >
> > I'll draw a diagram to briefly illustrate the cause of this issue.
> >
> > My original expectation of the image generation process
> >
> > flush1.png
> >
> > But the actual process is as follows
> >
> > image.png
> >
> > After the bitmap is alpha-blended and displayed on the screen, it is
> retrieved again in the next frame and repeatedly involved in alpha blending
> — resulting in redundant computations.
> >
> >
> >
> > I personally think that a more reasonable solution would be to insert
> |window_surface_composition| within |window_surface_flush| to more
> thoroughly resolve these kinds of issues
> >
> > image.png
> >
> >
> > During |window_surface_flush|, composite the current surface with the
> swapchain's surface into an offscreen surface, then flush that to the
> screen. This way, the original window surface won't be affected.
>
>
> Sounds reasonable.
>
>
> >
> > I'm trying to fix this issue now — do you have any suggestions?
> >
> >
> >
>
>
>
>