Re: How to implement
zhengxianwei <[email protected]> Tue, 3 Jun 2025 17:05:12 +0800
| Newsgroups | gmane.comp.emulators.wine.devel |
|---|---|
| Message-ID | <CABeGAqXgx0CQFHpC-VTJdsYULfstXbg+y5wOZKndDvXETKxkpg@mail.gmail.com> |
Sorry, I forgot to add the title How to Implement the Logic for Mixing DirectComposition with GDI? On Tue, Jun 3, 2025 at 5:02 PM zhengxianwei <[email protected]> wrote: > Hello, > > I would like to implement part of the logic within dcomp.dll in order to > properly support applications that depend on it. > > I found that Zhiyi Zhang has implemented some data structures and > interface stubs: > > > https://gitlab.winehq.org/zhiyi/wine/-/commits/directcomposition?ref_type=heads > > Among these, the only method with actual logic appears to be > IDCompositionDevice::Commit. > > However, after reviewing the implementation, I suspect there may be an > issue with the current approach. > > It seems that Zhiyi Zhang starts a separate thread for each > IDCompositionDevice, and this thread runs at a fixed refresh rate. > > But this approach appears to introduce a problem: from the window's (HWND) > perspective, there are now *two threads* concurrently updating its device > context. > > This results in a frame sequence similar to the following (note: the frame > intervals are illustrative only): > > gdi_frame | dcomp_frame | gdi_frame | gdi_frame | dcomp_frame > > In this model, GDI-generated frames and DComp-generated frames are > interleaved. > > Is my understanding correct? > > If so, I believe this method may lead to *inaccurate rendering results*, > although I am not entirely certain about the exact consequences (as I am > not an expert in this area). > > Therefore, I have decided to pursue an approach that produces a *standardized > frame stream* like the following: > > gdi_mix_dcomp_frame | gdi_mix_dcomp_frame | gdi_mix_dcomp_frame > > > In other words, I plan to merge GDI and DComp content before presenting > each frame, ensuring consistency in the final output. > > I’ve reviewed the normal GDI frame refresh process, and it seems to follow > this path: > > > --> flush_window_surfaces > --> window_surface_flush > --> x11drv_surface_flush > > > I’m planning to insert the following logic inside x11drv_surface_flush: > > > if (is_hwnd_bind_to_dcomp(hwnd)) > { > struct Surface *final = get_comp_surface(hwnd); > > blend_dcomp_surface_over_gdi(dest_surface, final); > > } > > > However, there’s still a question regarding *how to access the DComp data* > inside x11drv_surface_flush. > > One option is to do the composition inside IDCompositionDevice::Commit() > like this: > void IDCompositionDevice_Commit() > { > composite_proc(); > ... > ... > push_frame_to_x11drv(); > > } > > > Another option is to *directly call into DComp APIs from within x11drv* > to retrieve the surface data on demand. > > However, *both approaches feel somewhat unnatural*, and from what I can > tell, Windows seems to establish some kind of *internal channel* to pass > the composed content to the compositor. > > Is there a better or more canonical way to do this? > > Any suggestions or guidance would be greatly appreciated. > >