In addition to Eli's advice, you might find some inspiration in the Mac port, a version of emacs for macOS that uses a different set of system APIs than the ns port, which is included in the mainline. It's available directly via mercurial:
 https://bitbucket.org/mituharu/emacs-mac/src/master/ 

Hope this helps,
~Chad


On Mon, May 11, 2020 at 9:50 AM Eli Zaretskii <eliz@gnu.org> wrote:
> From: Cecilio Pardo <cpardo@imayhem.com>
> Date: Mon, 11 May 2020 12:13:50 +0200
>
> I'm trying to implement double buffered painting for Windows, to
> eliminate flicker.

Thank you very much for working on this.

> - When to flip buffers? I have tried to attach the flip to
>   frame_up_to_date_hook on the 'terminal' struct, but it sometimes get
>   called when it should not, producing flicker.

Did you try doing something similar to what xterm.c does on X?  I mean
the block_buffer_flips trick.  If you did, and it didn't work, why not

> - What portion of the screen has been updated? I have seen no clear way
>   to find this out. I'm resorting to intercept calls to w32_fill_rect to
>   mark areas as invalidated, as it /seems/ to be always used to clean
>   the area before painting, but this is clearly not a solution.

Why not update the entire frame?  That's what the X code does, AFAIU.