Closed sam-falvo closed 8 years ago
I think a good simplification for the control flow above is to make each vector-get and vector-put operation a callback. That way, the software blitter is unaware of where the data came from, only that it now has it. Application of fringe masks and performing row shifting will be done by the soft-blitter, as that's entirely "inside" the blitter, as far as its concerned.
I still have not quite figured out how to handle the raster-op function yet; either JIT or not, it seems like supporting 256 ops is just too daunting a task. I may have to leave using D as a source out of the picture, and focus on 16 raster-ops between A and B only. Then, of this set of raster-ops functions, I invoke two of them. One will source bits for when the corresponding D bit is 0, and one will source bits for when the corresponding D bit is 1. Logically OR those two results, and that should give the expected results.
d1 = rasterop[opNotD](a, b)
d2 = rasterop[opD](a, b)
d = (!d & d1) | (d & d2)
It'd be interesting to benchmark this approach versus a soft-blitter that only provided one source and one destination, such as X11's BitBlt()
call.
This is still necessary, but is no longer a pressing issue. Closing this ticket for now.
After much design frustration, I've decided upon an interface that I'm more or less happy with.
The overall control flow of the blitter is as follows:
The interface to the blitter, from outside the library, should be expressed as simply as possible; so, given a bitmap A, we want to take bitmap data from (x1, y1)-(x1+W, y1+H), and merge it somehow with data from bitmap B at (x2, y2)-(x2+W, y2+H), and put the results in a destination bitmap at (x3, y3)-(x3+W, y3+H) using one of 256 possible functions. This requires bitmap address calculations, coordinate translations, etc. We definitely want to do this in the library, because if/when the blitter is put into hardware, the interface will likely change quite a bit. As long as client software deals with pixel subranges in a bitmap, software should continue to just work.
I'm thinking of using JIT to generate the minterm solver. Assuming we establish our registers ahead of time, I do not want to have to hand-write all 256 minterm solvers. Writing 16 (to handle two sources) is doable, yet tedious.
Between the need for temporary workspaces and generated code, I'm thinking we should make the blit context an abstract data type unto itself. E.g., to perform a blit, you first need to create a Blit object, adjust parameters as appropriate, then perform the blit. You can re-use this blit object as many times as needed by just adjusting the attributes. When you're done with the blit, you can dispose of it. (Interesting: this is how Smalltalk does it too.)