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.