Great question. The best explanation I've found of how the end-to-end display pipeline works on mac is this comment, which I will summarize and expand upon below.
Basically, there are 4 components at play: we have "logical pixels", which is the coordinate system as seen by apps (for instance, if you use cmd+shift+4 screen capture, the width/height dimensions given are in units of "logical pixels"). Next you have the backing pixel store. The relationship between "logical pixels" and the backing pixel store is given by the backingScaleFactor
property of an NSWindow. OSX composites the backing stores of all windows together into a final "virtual" framebuffer. Next we have the actual "frame buffer" which represents the actual signal that would get sent to the monitor (the virtual and actual frame buffer need not be the same, as we will see shortly). Finally we have the monitor itself, which has a "native pixel resolution": if the signal sent to the monitor differs from the native pixel resolution, the monitor must perform upscaling/downscaling (or if it's a fancy monitor it might support 1:1 mode where it displays the image with borders, without applying upscaling).
So all this raises the question: how exactly does the resolution you set in system preferences ultimately get mapped to the signal that is sent? The short answer is that the resolution you set there is the "logical" resolution, and hidpi (or non-dpi) controls the backingScaleFactor
(and accordingly whether 2x assets are used or not). But there's an additional catch: when you use the hiDPI modes, if the virtual framebuffer resolution does not match the native display resolution, macOS will downscale/upscale as needed so that the output signal is always at the native resolution. (If on the other hand you use a non-hiDPI mode, then you have logical resolution = framebuffer resolution = output signal resolution, so it's the display itself that does any upscaling).
Let's consider some concrete scenarios: we have a QHD monitor (2560x1440 native resolution). Within system preferences we select a non hi-dpi resolution of 2560x1440. Then the logical resolution = frame buffer resolution = signal sent to display = 2560x1440. If we instead selected a 1920x1080 resolution, then the three are all equal to 1920x1080, and this is e.g. reflected in the monitor's OSD.
Now within system preferences, say we select a resolution of 1920x1080 (hidpi). When you choose a "hidpi" display mode, this means that the backing store of each window and composited frame buffer is at 2x the logical resolution. You can see this in system profiler: it states "resolution 3840x2160" but "ui looks like: 1920x1080". In this hidpi mode, AppKit automatically selects the @2x version of sprites, thus scaling things such that even though the backing store is twice the resolution, the size of things is also now doubled making things "logically" appear as 1920x1080.
But we don't have a 3840x2160 screen, we only have a 2560x1440 screen. macOS now resamples/downscales the virtual framebuffer to 1440p before sending it to the display. This rescaling is where blurriness is introduced: because it is a non-integral multiple, we get the messy artifacting as described by other posts like this or this. Moreover, no matter what hidpi resolution you select, the signal sent ultimately always matches the native resolution of the monitor.
The benefit of this display-scaling approach is that apps don't have to account for arbitrary scale factors: as long as they work with 1x and 2x, the scaling to other resolutions is handled transparently and system wide. The downside is that besides the blurriness, it means that an application actually has no easy way of identifying what the end-resolution the user physically sees is (which is partly the point, the application should not care about it). Consider the case of a image-viewer: the input image might be 1080p, but if we have hiDPI mode enabled backingScaleFactor = 2
then the system will actually give us a 2160p frame buffer to render into, for which we'll need to do upscaling ourselves (pretend we're using raw OpenGL or something to avoid any Cocoa layers). But that's not the end of the story, the system may transparently rescale the frame buffer to the native display resolution. In fact if enabled 1080p-hiDPI mode on a 1080p display, the system would downscale the framebuffer back to 1080p, so the resolution as seen by the viewer would only be 1080p.