After some thinking, I think the proper method of doing things is "go through pieces in order, if No Overdraw is selected simply blit underneath surface instead of on top".
Yep that's correct.̆ Your original two-canvas idea falls apart in the presence of subtractive pieces.̆ For example, say we have terrain pieces A, B, C, with A and C No-Overdraw and B black.̆ B only affects A, not C.
If you want to keep your two-canvas system, you will need to treat black pieces by saving partial results.̆ For example, say we have A,B,C,D,E with B and D black, and the rest No-Overdraw:
1) For the bottom-canvas list, you need to include black pieces as well, so the list you have after reversing is E,D,C,B,A.
2) Draw E on bottom canvas.
3) Since D is black:̆ capture the current pixels on bottom canvas which are in the subtractive area of D.
4) Draw C on bottom canvas overwriting.
5) Since B is black and there was previously another black piece (D):̆ draw the capture from D over the canvas.̆ This will erase everything except E, since we saved pixels of E during step 3. Another way to look at this is that instead of every subtractive pixel of D being black, the ones that overlap with E, you apply to the canvas the capture (which has E's pixel) instead of blackness.
After this, capture the current pixels on bottom canvas which are in the subtractive area of B, similar to step 3.
6) Draw A on bottom canvas overwriting.
7) We reached the end of list and there was an unhandled capture from step 5, so handle it by drawing the capture from B over the canvas.̆ This will erase everything except C and E, since pixels from those were saved during the capture in step 5.
Note that I haven't tested this, this just came straight off my head right now.̆ I think if the simple approach of always drawing No-Overdraw pieces behind existing terrain is fast enough, you should use that approach since it's guaranteed correct, easier to understand and therefore less likely to have bugs.