Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transparent blitter stacking #1317

Merged
merged 16 commits into from Feb 2, 2021
Merged

Conversation

dankamongmen
Copy link
Owner

the basic problem can be stated thus: imagine we have two images, both two pixels tall and one pixel wide. image 1 is
above image 2. image 1 is a transparent pixel and a white pixel. image 2 is a blue pixel and a red pixel. what ought be the output? i'd think a blue pixel atop a white pixel, but the result could have been a red pixel atop a white pixel, because rendering is solved in terms of foreground and background, but here we want rendering in terms of occupied geometry.

as described at length in #1068 , the solution is to encode occupied area in the nccell, using previously-unused bits of the channels. when these bits are in play, render in terms of geometry. careful coding means we only do extra work when affected by this (infrequent) problem, and we require no extra state. there is no measurable delay in notcurses-demo.

this was important to fix because it otherwise causes clutter around sprites.

unit tests were added for this problem. they went from failure to success over the course of the fix.

Closes #1068.

For properly stacking transparent blittings (#1068), we
need tag those cells which both (1) originated in an
ncvisual operation and (2) have some transparency. For
the three affected blitters (halfblock, quadrant, and
sexblitter), call cell_set_blitted().
We need track whether we've entered blitterstacking
mode across the paint() of a given cell. This means
stashing it in the crender rvec #1068.
Iff cell_blitted_p() when we select the glyph in paint(),
we ought enter blitter stacking mode. Make this decision
in paint() #1068.
Reclaim the "blitted" and "full foreground" bits in the
channels. Instead, we now write four bits, encoding the
four quadrants we might occupy as the result of a blit.
These four imply the previous two, leaving us with four
free bits remaining in the channels. This opens a clear
path to O(1)-time, zero-space blitter stacking #1068.
w00t!
This completes the work for #1068. This addressed a subtle issue.
When we're using pixel->semigraphic art, we want slightly different
rendering. Essentially, imagine that we have two images, each two
pixels tall and one pixel wide. The top image is a transparent pixel
above a white pixel. The bottom image is a white pixel above a black
pixel. We'd expect the result to be two white pixels, but we can
instead get a black pixel above a white pixel. This is because the
*background* color is being merged from the bottom plane, but really
we want the *top* color. Ncvisuals are now blitted along with
information regarding which quadrants they draw over, and when
appropriate, we invert the foreground and background. Closes #1068.
@dankamongmen dankamongmen added the NOMERGE not ready for merge label Feb 1, 2021
@dankamongmen
Copy link
Owner Author

Hrmmm, I linked debwarrior against this, and am still seeing the original problem. I think maybe ncvisual_from_rgba() doesn't work properly for NCBLIT_2x2, and thus our unit tests aren't testing what we want them to.

@dankamongmen
Copy link
Owner Author

Resolved the problem we were seeing -- needed to invert the bits, not invert the logical status. ~, not !. All unit tests pass now, and debwarrior looks right. Finally!

@dankamongmen
Copy link
Owner Author

Wait, no, we're not yet quite there. Look at this output, and how ragged those diagonal lines are. What's happened? This oughtn't even be triggering stacked blitters; it's just plain ol' ncdisplay. master doesn't show this behavior at all. No merging until this is resolved.

2021-02-02-001208_802x1417_scrot

@dankamongmen
Copy link
Owner Author

Yeah, yeesh, raggedy as hell all along the exterior. The inner lines look right, interestingly.

@dankamongmen
Copy link
Owner Author

Sure enough, we're hitting the stackpath in ncdisplay, which can't be right.

@dankamongmen dankamongmen merged commit 2507a17 into master Feb 2, 2021
@dankamongmen dankamongmen deleted the dankamongmen/blitter-stacking branch February 2, 2021 05:58
@dankamongmen dankamongmen removed the NOMERGE not ready for merge label Feb 2, 2021
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.

Transparent blitting doesn't properly stack
2 participants