You're never going to get smooth scrolling if you need to hit the UI thread for every touch event. The platform UI frameworks use background threads for scrolling, directly in the OS compositor.
For most of time, ScrollWindow / ScrollWindowEx was how you scrolled. It doesn't know what to draw in the invalidated region because it's an immediate mode API.
In Direct2D you can use e.g. a translation to get the renderer to draw a bigger bitmap in a different section of the window, but you need to render the bigger bitmap (i.e. assemble your own retained mode). There's no free lunch.
The important part isn't the amount of work it takes to render, it's that event handling is serialized with all the other stuff happening on the main thread.