Zhiyi Zhang provided an implementation of DComp composition:
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.

I'm trying to fix this issue now — do you have any suggestions?