Skip to content

Add OnAcceleratedPaint support with D3D11/GL interop for GPU-resident texture sharing#26

Draft
roxanneskelly wants to merge 10 commits into
masterfrom
roxie/accelerated
Draft

Add OnAcceleratedPaint support with D3D11/GL interop for GPU-resident texture sharing#26
roxanneskelly wants to merge 10 commits into
masterfrom
roxie/accelerated

Conversation

@roxanneskelly

Copy link
Copy Markdown

Enable CEF's shared texture mode and add an OnAcceleratedPaint override to dullahan_render_handler that passes the D3D11 shared texture handle through a new onAcceleratedPageChanged callback. On Windows, the opengl-example now uses WGL_NV_DX_interop2 to display the shared texture directly via GL without CPU readback. CEF's keyed-mutex shared textures are copied to a plain local D3D11 texture for interop compatibility. Mac/Linux accelerated paint paths are stubbed out.

Also extracts GetParentProcess into a shared dullahan_platform_utils.h header, adds RelWithDebInfo build support with /DEBUG:FULL PDBs, and links d3d11/dxgi for the opengl-example on Windows.

@callumlinden callumlinden self-requested a review April 16, 2026 18:13

@callumlinden callumlinden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good and I'm thrilled to hear that it works. Initial questions:

  • There is a lot happening in the original OnPaint() override that isn't present in your accelerated version. Code to take account of "popups" (PET_POPUP) for example - not what you might think - more for widgets like comboboxes that create an additional OS window to host parts of the widget - that needs to be dealt with. I'm about to build your branch to see it working - I'll try combo boxes - there is a section in the test bookmarks app for them.
  • Is there is complementary pattern for macOS - I think the answer is yes - or do we just fall back to the non-accelerated OnPaint for both macOS and Linux?
  • Do you foresee this being merged and added to a Viewer? I imagine the Viewer side work needs to land first if you do.

@callumlinden

Copy link
Copy Markdown
Contributor

After trying it in the test app, I noticed that for some sites, when you have 2 windows open, one of the instances stutters and stops rendering for a second or two, every few seconds.. WebGL and video sites were the ones I tried - some contention for the GPU perhaps?

@roxanneskelly

Copy link
Copy Markdown
Author

Yeah, the stutter is a problem. Geenz was going to look into it at some point, so no merging until then.

Unfortunately, Mac and Linux equivalent don't work. They used to, but due to some rearchitecting of CEF they don't any more.

@callumlinden

Copy link
Copy Markdown
Contributor

I confirmed that we do need the additional code in OnAcceleratedPaint to deal with edge cases like combo boxes.

There are a billion examples out there of course but this page, selected at random, illustrates the issue https://web.pdx.edu/~bjpd/cwbase/dijit/tests/form/test_ComboBox.html

(Only for some of them though which is surprising).

callumlinden and others added 7 commits July 10, 2026 10:53
…s and macOS by pulling in the updated CEF 150 autobuild package. (Linux to follow). Also update Dullahan version to 1.40.0 to disambiguate from versions with older CEFs
… texture sharing

Enable CEF's shared texture mode and add an OnAcceleratedPaint override to
dullahan_render_handler that passes the D3D11 shared texture handle through
a new onAcceleratedPageChanged callback. On Windows, the opengl-example now
uses WGL_NV_DX_interop2 to display the shared texture directly via GL without
CPU readback. CEF's keyed-mutex shared textures are copied to a plain local
D3D11 texture for interop compatibility. Mac/Linux accelerated paint paths
are stubbed out.

Also extracts GetParentProcess into a shared dullahan_platform_utils.h header,
adds RelWithDebInfo build support with /DEBUG:FULL PDBs, and links d3d11/dxgi
for the opengl-example on Windows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use shared_texture_io_surface on macOS instead of shared_texture_handle.
Linux does not support accelerated painting and falls back to OnPaint.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
LUIDs are a Windows-specific concept used by DXGI to identify GPU
adapters and have no equivalent on macOS or Linux.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously the accelerated (shared-texture) paint path ignored
flip_pixels_y and always forwarded CEF's top-down texture handle,
forcing every consumer to flip on its side. Now, when flip_pixels_y
is set, dullahan performs a GPU vertical flip on Windows and hands the
consumer a bottom-up texture instead.

The flip is done by a new WIN32-only dullahan_shared_texture_flipper
that owns a D3D11 device, a fullscreen-triangle flip pipeline, and a
reusable shareable destination texture. The device and pipeline are
created once; the destination is reallocated only when the incoming
texture's size or format changes. Transient per-frame failures skip
the frame without tearing down the device.

The device is created on the configured adapter LUID (when set) so the
CEF shared texture can be opened without a cross-adapter copy.

COORDINATION: this is a behavior change. Consumers that flip the
accelerated texture themselves must remove that flip when flip_pixels_y
is enabled or the image will be flipped twice. Documented in dullahan.h
on flip_pixels_y and setOnAcceleratedPageChangedCallback; new in 1.26.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
roxanneskelly and others added 3 commits July 10, 2026 15:41
The destination texture MiscFlags used D3D11_RESOURCE_MISC_SHARED_KEYED_MUTEX,
which is not a valid identifier (C2065). The correct enum is
D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX (no underscore between KEYED and MUTEX).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
dullahan_host.cpp defined its own GetParentProcess() while also including
dullahan_platform_utils.h, which declares an identical global
GetParentProcess(DWORD = SYNCHRONIZE). A zero-argument call was viable
against both overloads, so the call in WinMain() failed to compile as an
ambiguous call. Drop the host's local copy and use the shared header one;
behavior is unchanged (OpenProcess with SYNCHRONIZE).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants