diff options
| -rw-r--r-- | core/api/current.txt | 6 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Gainmap.java | 93 | ||||
| -rw-r--r-- | libs/hwui/aconfig/hwui_flags.aconfig | 8 | ||||
| -rw-r--r-- | libs/hwui/jni/Gainmap.cpp | 60 |
4 files changed, 161 insertions, 6 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index baf142a0640c..e7089078a62f 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -16128,24 +16128,30 @@ package android.graphics { ctor public Gainmap(@NonNull android.graphics.Bitmap); ctor @FlaggedApi("com.android.graphics.hwui.flags.gainmap_constructor_with_metadata") public Gainmap(@NonNull android.graphics.Gainmap, @NonNull android.graphics.Bitmap); method public int describeContents(); + method @FlaggedApi("com.android.graphics.hwui.flags.iso_gainmap_apis") @Nullable public android.graphics.ColorSpace getAlternativeImagePrimaries(); method @NonNull public float getDisplayRatioForFullHdr(); method @NonNull public float[] getEpsilonHdr(); method @NonNull public float[] getEpsilonSdr(); method @NonNull public android.graphics.Bitmap getGainmapContents(); + method @FlaggedApi("com.android.graphics.hwui.flags.iso_gainmap_apis") public int getGainmapDirection(); method @NonNull public float[] getGamma(); method @NonNull public float getMinDisplayRatioForHdrTransition(); method @NonNull public float[] getRatioMax(); method @NonNull public float[] getRatioMin(); + method @FlaggedApi("com.android.graphics.hwui.flags.iso_gainmap_apis") public void setAlternativeImagePrimaries(@Nullable android.graphics.ColorSpace); method public void setDisplayRatioForFullHdr(@FloatRange(from=1.0f) float); method public void setEpsilonHdr(float, float, float); method public void setEpsilonSdr(float, float, float); method public void setGainmapContents(@NonNull android.graphics.Bitmap); + method @FlaggedApi("com.android.graphics.hwui.flags.iso_gainmap_apis") public void setGainmapDirection(int); method public void setGamma(float, float, float); method public void setMinDisplayRatioForHdrTransition(@FloatRange(from=1.0f) float); method public void setRatioMax(float, float, float); method public void setRatioMin(float, float, float); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.graphics.Gainmap> CREATOR; + field @FlaggedApi("com.android.graphics.hwui.flags.iso_gainmap_apis") public static final int GAINMAP_DIRECTION_HDR_TO_SDR = 1; // 0x1 + field @FlaggedApi("com.android.graphics.hwui.flags.iso_gainmap_apis") public static final int GAINMAP_DIRECTION_SDR_TO_HDR = 0; // 0x0 } public class HardwareBufferRenderer implements java.lang.AutoCloseable { diff --git a/graphics/java/android/graphics/Gainmap.java b/graphics/java/android/graphics/Gainmap.java index 0a6fb8424094..63ca3b8313ce 100644 --- a/graphics/java/android/graphics/Gainmap.java +++ b/graphics/java/android/graphics/Gainmap.java @@ -18,7 +18,9 @@ package android.graphics; import android.annotation.FlaggedApi; import android.annotation.FloatRange; +import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; @@ -26,6 +28,9 @@ import com.android.graphics.hwui.flags.Flags; import libcore.util.NativeAllocationRegistry; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Gainmap represents a mechanism for augmenting an SDR image to produce an HDR one with variable * display adjustment capability. It is a combination of a set of metadata describing how to apply @@ -83,6 +88,27 @@ import libcore.util.NativeAllocationRegistry; */ public final class Gainmap implements Parcelable { + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"GAINMAP_DIRECTION_"}, + value = {GAINMAP_DIRECTION_SDR_TO_HDR, + GAINMAP_DIRECTION_HDR_TO_SDR}) + public @interface GainmapDirection {} + + /** + * The gainmap will be applied as if the base image were SDR, and fully applying the gainmap + * results in an HDR image. + */ + @FlaggedApi(Flags.FLAG_ISO_GAINMAP_APIS) + public static final int GAINMAP_DIRECTION_SDR_TO_HDR = 0; + + /** + * The gainmap will be applied as if the base image were HDR, and fully applying the gainmap + * results in an SDR image. + */ + @FlaggedApi(Flags.FLAG_ISO_GAINMAP_APIS) + public static final int GAINMAP_DIRECTION_HDR_TO_SDR = 1; + // Use a Holder to allow static initialization of Gainmap in the boot image. private static class NoImagePreloadHolder { public static final NativeAllocationRegistry sRegistry = @@ -252,8 +278,9 @@ public final class Gainmap implements Parcelable { } /** - * Sets the hdr/sdr ratio at which point the gainmap is fully applied. - * @param max The hdr/sdr ratio at which the gainmap is fully applied. Must be >= 1.0f + * Sets the hdr/sdr ratio at which point applying the gainmap results in an HDR rendition. + * @param max The hdr/sdr ratio at which point applying the gainmap results in an HDR rendition. + * Must be >= 1.0f */ public void setDisplayRatioForFullHdr(@FloatRange(from = 1.0f) float max) { if (!Float.isFinite(max) || max < 1f) { @@ -264,7 +291,7 @@ public final class Gainmap implements Parcelable { } /** - * Gets the hdr/sdr ratio at which point the gainmap is fully applied. + * Gets the hdr/sdr ratio at which point applying the gainmap results in an HDR rendition */ @NonNull public float getDisplayRatioForFullHdr() { @@ -272,8 +299,9 @@ public final class Gainmap implements Parcelable { } /** - * Sets the hdr/sdr ratio below which only the SDR image is displayed. - * @param min The minimum hdr/sdr ratio at which to begin applying the gainmap. Must be >= 1.0f + * Sets the hdr/sdr ratio below which applying the gainmap results in an SDR rendition. + * @param min The minimum hdr/sdr ratio at which point applying the gainmap results in an SDR + * rendition. Must be >= 1.0f */ public void setMinDisplayRatioForHdrTransition(@FloatRange(from = 1.0f) float min) { if (!Float.isFinite(min) || min < 1f) { @@ -284,7 +312,7 @@ public final class Gainmap implements Parcelable { } /** - * Gets the hdr/sdr ratio below which only the SDR image is displayed. + * Gets the hdr/sdr ratio below which applying the gainmap results in an SDR rendition. */ @NonNull public float getMinDisplayRatioForHdrTransition() { @@ -292,6 +320,55 @@ public final class Gainmap implements Parcelable { } /** + * Sets the colorspace that the gainmap math should be applied in. + * Only the primaries are what is relevant for applying the gainmap. The transfer and range + * characteritics are ignored. + * + * If the supplied ColorSpace is null, then applying the gainmap will be done using the color + * gamut of the base image. + */ + @FlaggedApi(Flags.FLAG_ISO_GAINMAP_APIS) + public void setAlternativeImagePrimaries(@Nullable ColorSpace colorSpace) { + long colorSpaceInstance = colorSpace == null ? 0 : colorSpace.getNativeInstance(); + nSetAlternativeColorSpace(mNativePtr, colorSpaceInstance); + } + + /** + * Gets the colorspace that the gainmap math should be applied in. + * Only the primaries are what is relevant for applying the gainmap. The transfer and range + * characteritics are ignored. + * + * If the returned ColorSpace is null, then applying the gainmap will be done using the color + * gamut of the base image. + */ + @FlaggedApi(Flags.FLAG_ISO_GAINMAP_APIS) + @Nullable + public ColorSpace getAlternativeImagePrimaries() { + return nGetAlternativeColorSpace(mNativePtr); + } + + /** + * Sets the direction that the gainmap math should be applied in. + */ + @FlaggedApi(Flags.FLAG_ISO_GAINMAP_APIS) + public void setGainmapDirection(@GainmapDirection int direction) { + if (direction != GAINMAP_DIRECTION_SDR_TO_HDR + && direction != GAINMAP_DIRECTION_HDR_TO_SDR) { + throw new IllegalArgumentException("Invalid gainmap direction: " + direction); + } + nSetDirection(mNativePtr, direction); + } + + /** + * Gets the direction that the gainmap math should be applied in. + */ + @FlaggedApi(Flags.FLAG_ISO_GAINMAP_APIS) + public @GainmapDirection int getGainmapDirection() { + return nGetDirection(mNativePtr); + } + + + /** * No special parcel contents. */ @Override @@ -361,6 +438,10 @@ public final class Gainmap implements Parcelable { private static native void nSetDisplayRatioSdr(long ptr, float min); private static native float nGetDisplayRatioSdr(long ptr); + private static native void nSetAlternativeColorSpace(long ptr, long colorSpacePtr); + private static native ColorSpace nGetAlternativeColorSpace(long ptr); + private static native void nSetDirection(long ptr, int direction); + private static native int nGetDirection(long ptr); private static native void nWriteGainmapToParcel(long ptr, Parcel dest); private static native void nReadGainmapFromParcel(long ptr, Parcel src); } diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig index faea6d42b156..ab052b902e02 100644 --- a/libs/hwui/aconfig/hwui_flags.aconfig +++ b/libs/hwui/aconfig/hwui_flags.aconfig @@ -121,3 +121,11 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + name: "iso_gainmap_apis" + is_exported: true + namespace: "core_graphics" + description: "APIs that expose gainmap metadata corresponding to those defined in ISO 21496-1" + bug: "349357636" +} diff --git a/libs/hwui/jni/Gainmap.cpp b/libs/hwui/jni/Gainmap.cpp index 0fffee744be0..71972d01b94f 100644 --- a/libs/hwui/jni/Gainmap.cpp +++ b/libs/hwui/jni/Gainmap.cpp @@ -16,6 +16,9 @@ #include <Gainmap.h> +#include "SkColorType.h" +#include "SkGainmapInfo.h" + #ifdef __ANDROID__ #include <binder/Parcel.h> #endif @@ -36,6 +39,28 @@ static Gainmap* fromJava(jlong gainmap) { return reinterpret_cast<Gainmap*>(gainmap); } +static SkGainmapInfo::BaseImageType baseImageTypeFromJava(jint direction) { + switch (direction) { + case 0: + return SkGainmapInfo::BaseImageType::kSDR; + case 1: + return SkGainmapInfo::BaseImageType::kHDR; + default: + LOG_ALWAYS_FATAL("Unrecognized Gainmap direction: %d", direction); + } +} + +static jint baseImageTypeToJava(SkGainmapInfo::BaseImageType type) { + switch (type) { + case SkGainmapInfo::BaseImageType::kSDR: + return 0; + case SkGainmapInfo::BaseImageType::kHDR: + return 1; + default: + LOG_ALWAYS_FATAL("Unrecognized base image: %d", type); + } +} + static int getCreateFlags(const sk_sp<Bitmap>& bitmap) { int flags = 0; if (bitmap->info().alphaType() == kPremul_SkAlphaType) { @@ -169,6 +194,36 @@ static jfloat Gainmap_getDisplayRatioSdr(JNIEnv*, jobject, jlong gainmapPtr) { return fromJava(gainmapPtr)->info.fDisplayRatioSdr; } +static void Gainmap_setAlternativeColorSpace(JNIEnv*, jobject, jlong gainmapPtr, + jlong colorSpacePtr) { + auto colorSpace = GraphicsJNI::getNativeColorSpace(colorSpacePtr); + fromJava(gainmapPtr)->info.fGainmapMathColorSpace = colorSpace; +} + +static jobject Gainmap_getAlternativeColorSpace(JNIEnv* env, jobject, jlong gainmapPtr) { + const auto javaGainmap = fromJava(gainmapPtr); + auto colorSpace = javaGainmap->info.fGainmapMathColorSpace.get(); + if (colorSpace == nullptr) { + return nullptr; + } + + auto colorType = javaGainmap->bitmap->colorType(); + // A8 bitmaps don't support colorspaces, but an alternative colorspace is + // still valid for configuring the gainmap math, so use RGBA8888 instead. + if (colorType == kAlpha_8_SkColorType) { + colorType = kRGBA_8888_SkColorType; + } + return GraphicsJNI::getColorSpace(env, colorSpace, colorType); +} + +static void Gainmap_setDirection(JNIEnv*, jobject, jlong gainmapPtr, jint direction) { + fromJava(gainmapPtr)->info.fBaseImageType = baseImageTypeFromJava(direction); +} + +static jint Gainmap_getDirection(JNIEnv* env, jobject, jlong gainmapPtr) { + return baseImageTypeToJava(fromJava(gainmapPtr)->info.fBaseImageType); +} + // ---------------------------------------------------------------------------- // Serialization // ---------------------------------------------------------------------------- @@ -260,6 +315,11 @@ static const JNINativeMethod gGainmapMethods[] = { {"nGetDisplayRatioHdr", "(J)F", (void*)Gainmap_getDisplayRatioHdr}, {"nSetDisplayRatioSdr", "(JF)V", (void*)Gainmap_setDisplayRatioSdr}, {"nGetDisplayRatioSdr", "(J)F", (void*)Gainmap_getDisplayRatioSdr}, + {"nSetAlternativeColorSpace", "(JJ)V", (void*)Gainmap_setAlternativeColorSpace}, + {"nGetAlternativeColorSpace", "(J)Landroid/graphics/ColorSpace;", + (void*)Gainmap_getAlternativeColorSpace}, + {"nSetDirection", "(JI)V", (void*)Gainmap_setDirection}, + {"nGetDirection", "(J)I", (void*)Gainmap_getDirection}, {"nWriteGainmapToParcel", "(JLandroid/os/Parcel;)V", (void*)Gainmap_writeToParcel}, {"nReadGainmapFromParcel", "(JLandroid/os/Parcel;)V", (void*)Gainmap_readFromParcel}, }; |