summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt6
-rw-r--r--graphics/java/android/graphics/Gainmap.java93
-rw-r--r--libs/hwui/aconfig/hwui_flags.aconfig8
-rw-r--r--libs/hwui/jni/Gainmap.cpp60
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},
};