Resample gainmaps during region decoding.
Implicitly, region decoding is a cropping operation, which previously
was introducing quality issues when decoding a gainmapped image. For
instance:
(a) Consider a 48x48 image with a 12x12 gainmap.
(b) Consider decoding a 10x10 region of the image. The decoder must choose
to either decode a 2x2 or 3x3 region of the gainmap, which does not
match the 4x scale ratio of the source, so either we decode too much
or too little of the image
(c) When displaying the image, we bilinearly scale both the image and
the gainmap to the destination, then apply the gainmap. But, because of
(b), the gainmap is misaligned with the base image, introducing haloing
artifacts.
To fix this, we change (b) by always decoding a slightly larger
region (in the examplar case, either a decode a 3x3 or 4x4 region), but
retain information about the "logical" region we intended. Then, we
resample from the "logical" region up to the decoded bounds.
In the above example, this means that we decode a 3x3 or 4x4 bitmap,
that holds the logical 2.5x2.5 region of the gainmap, ensuring that (0, 0)
in the resulting bitmap maps to (0, 0) in the bitmap for the decoded region
from the base image, so that the gainmap content lines up with the base
image after the gainmap is upsampled during rendering.
We do the actual resampling inside of the recycling allocator, since we
sometimes perform a bitmap copy there anyways, so we can resample during
the copy.
Hide this behind a flag, since I broke decoding in about 5 different
ways before settling on this.
Bug: 352847821
Flag: com.android.graphics.hwui.flags.resample_gainmap_regions
Test: Decoding works in Photos, Files, and modified SilkFX
Change-Id: Ic21d44011858619273b11c20ee746614a1749a73
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index d184f64..1217b47 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -42,6 +42,9 @@
constexpr bool initialize_gl_always() {
return false;
}
+constexpr bool resample_gainmap_regions() {
+ return false;
+}
} // namespace hwui_flags
#endif
@@ -100,6 +103,7 @@
bool Properties::clipSurfaceViews = false;
bool Properties::hdr10bitPlus = false;
+bool Properties::resampleGainmapRegions = false;
int Properties::timeoutMultiplier = 1;
@@ -175,6 +179,8 @@
clipSurfaceViews =
base::GetBoolProperty("debug.hwui.clip_surfaceviews", hwui_flags::clip_surfaceviews());
hdr10bitPlus = hwui_flags::hdr_10bit_plus();
+ resampleGainmapRegions = base::GetBoolProperty("debug.hwui.resample_gainmap_regions",
+ hwui_flags::resample_gainmap_regions());
timeoutMultiplier = android::base::GetIntProperty("ro.hw_timeout_multiplier", 1);