new Edge3x/2x filter
|Reported by:||SF/ewelsh42||Owned by:|
I have created a new anti-aliasing resize filter which I thought may be of interest to the ScummVM team. It includes a 3x and 2x nearest neighbor resizer, as well as a 2x interpolating resizer. It also detects when overlays are being drawn, such as the mouse, assumes that they have transparancy, and handles transparancy in a reasonable manner so that the anti-aliasing of mouse pointers looks good now (as compared to AdvMame). See the mouse pointer for Maniac Mansion for a good example. The overall image quality is higher than the AdvMame and HQ filters. More edges are anti-alised, fewer edge directions are mis-detected and anti-aliased in the wrong direction, and the shapes and shadings of the original image are better preserved. The new filters give sharpness without the common font edge direction misdetection artifacts of AdvMame, and good anti-aliasing without the common heavy blur of the HQ filters when they are unsure of how best to anti-alias a given pixel. The filters are also reasonably robust to various odd color and shading combinations that give the other filters difficulty. The improved image quality is worth the speed hit, at least to me.
Unfortunately, the improved accuracy comes at a hefty cost in speed. However, since many ScummVM supported games only redraw small amounts of the screen each frame, this is not so much of a problem. But the filter is slow enough that dirty rects still don't help it enough. To speed it up a bit more, the filter keeps local copies of the src and dst buffers so that it can do its own unchanged pixel detection and only redraw pixels that have actually changed between frames, even if a full screen refresh is requested due to color cycling, etc.. It detects all current instances of ScummVM writing to the screen outside of the filter and forces an internal full screen refresh when this occurs, so there should be no artifacts from messages, menus, etc. that get drawn outside of the filter. Unchanged pixel detection and skipping appears to be stable. The cached dst buffer lets it work with aspect ratio correction as well. If at any point this breaks in the future when ScummVM writes outside the filter in a way that the filter does not expect, unchanged pixel skipping can be disabled by simply setting the skip_unchanged_pixels_flag variable in the filter to 1, or figuring out what new case to check for in the function that contains the flag.
With the unchanged pixel detection, most games are smoothly playable for me on my 1.53 GHz Athlon. Full screen pans can get a little jerky, but they still aren't too bad. Modern CPUs should have no problems.
I have attached a diff of the changes, made from a snapshot a few months ago. I applied it to a fresh svn download tonight, and it patched and compiled without errors, so it should still be fine. Minimial changes were made to all of the existing files, just what was required to add basic support of a new filter. The new filter is included in graphics/scaler/edge3x.cpp. See code comments for better descriptions of the edge detection algorithms used, handling of transparancy, unchanged pixel skipping, etc.. The code enclosed in DEBUG defines can be removed, but I thought I would leave it in there for now, as those defines can be very interesting for visualizing which pixels are changing between frames and seeing the outlines of dirty rects.
The default hot-keys are ctl-alt-9, and ctl-alt- +/- switch between the 2x interpolating resizer and the 3x nearest neighbor resizer. It is impossible for a 2x nearest neighbor resizer to get diagonals correct, which is why I chose to default it to the 2x interpolating resizer instead of nearest neighbor.
I forsee the following objections being raised against including this filter in ScummVM:
We don't need yet another filter And I thought HQ3x was slow.... Unchanged pixel detection is a bit of a hack Transparancy handling is also a bit of a hack
I don't necessarily disagree with the last three of those, but I think that the much increased image quality at least warrants giving it a try before turning it down.
Ticket imported from: #1574256. Ticket imported from: patches/683.