linebender / piet

An abstraction for 2D graphics.
Apache License 2.0
1.24k stars 93 forks source link

Disable the Direct2D debug layer in release mode. #517

Closed xStrom closed 2 years ago

xStrom commented 2 years ago

Overview

This PR provides a simple solution to a problem that has had some discussion across Druid and Piet already.

A symptom of the problem surfaced in druid#2062 where Druid apps on Windows can't be properly closed with Ctrl+C in the terminal.

@wspl tracked the issue down to Piet's configuration of the Direct2D debug layer. This led to an initial proposal in #479 to just disable the debug layer completely. It definitely solves the symptoms, but it's also a classic case of throwing the baby out with the bathwater.

There is also a key statement in the Microsoft docs for this debug layer. The debug layer should never be active in the release version of an application. I don't know of all the ramifications of having it enabled. Thus far we've connected the Ctrl+C issue to it, however I can imagine the effects being wider. Certainly easy to imagine performance taking a hit, although I haven't measured it.

Behavior goal

I think the goal here should be to have the debug layer enabled for debug builds, and disabled for release builds.

Potential solutions considered

Cargo features

As also suggested by @avitex in #479, one possible way to solve this is via Cargo features.

The most obvious problem with this approach is that it introduces a new task for developers. The additive nature of Cargo features can also make it tricky to turn off the debug layer if another dependency of the application imports Piet with the debug layer enabled.

Solving this with features is doable, but seems overly complex and brittle.

Runtime flag / variable

It could be an environment variable, or it could be a regular variable taken by Piet that indicates the debug level. This would also enable more granular control, as the D2D debug layer has four different levels (none, info, warning, error).

This solution brings plenty of benefits, however it would be a breaking change of the API and require plenty of plumbing. Might be worth it in the future, but for now I considered this too much to solve just this specific D2D issue.

The actual solution in this PR

Conditional compilation with debug_assertions

According to The Rust Reference debug_assertions can be used to enable extra debugging code in development but not in production. Indeed it seems to me to be the most canonical way to do standard conditional compilation for debug builds.

This means there are no API changes and no new tasks for developers. Instead we get the same old behavior with debug builds, and the new Microsoft-recommended behavior in release builds.