Loading core/java/android/hardware/DisplayLuts.java 0 → 100644 +131 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.hardware; import android.annotation.NonNull; import android.util.IntArray; import java.util.ArrayList; import java.util.List; /** * @hide */ public final class DisplayLuts { private IntArray mOffsets; private int mTotalLength; private List<float[]> mLutBuffers; private IntArray mLutDimensions; private IntArray mLutSizes; private IntArray mLutSamplingKeys; private static final int LUT_LENGTH_LIMIT = 100000; public DisplayLuts() { mOffsets = new IntArray(); mTotalLength = 0; mLutBuffers = new ArrayList<>(); mLutDimensions = new IntArray(); mLutSizes = new IntArray(); mLutSamplingKeys = new IntArray(); } /** * Add the lut to be applied. * * @param buffer * @param dimension either 1D or 3D * @param size * @param samplingKey */ public void addLut(@NonNull float[] buffer, @LutProperties.Dimension int dimension, int size, @LutProperties.SamplingKey int samplingKey) { int lutLength = 0; if (dimension == LutProperties.ONE_DIMENSION) { lutLength = size; } else if (dimension == LutProperties.THREE_DIMENSION) { lutLength = size * size * size; } else { clear(); throw new IllegalArgumentException("The dimension is either 1D or 3D!"); } if (lutLength >= LUT_LENGTH_LIMIT) { clear(); throw new IllegalArgumentException("The lut length is too big to handle!"); } mOffsets.add(mTotalLength); mTotalLength += lutLength; mLutBuffers.add(buffer); mLutDimensions.add(dimension); mLutSizes.add(size); mLutSamplingKeys.add(samplingKey); } private void clear() { mTotalLength = 0; mOffsets.clear(); mLutBuffers.clear(); mLutDimensions.clear(); mLutSamplingKeys.clear(); } /** * @return the array of Lut buffers */ public float[] getLutBuffers() { float[] buffer = new float[mTotalLength]; for (int i = 0; i < mLutBuffers.size(); i++) { float[] lutBuffer = mLutBuffers.get(i); System.arraycopy(lutBuffer, 0, buffer, mOffsets.get(i), lutBuffer.length); } return buffer; } /** * @return the starting point of each lut memory region of the lut buffer */ public int[] getOffsets() { return mOffsets.toArray(); } /** * @return the array of Lut size */ public int[] getLutSizes() { return mLutSizes.toArray(); } /** * @return the array of Lut dimension */ public int[] getLutDimensions() { return mLutDimensions.toArray(); } /** * @return the array of sampling key */ public int[] getLutSamplingKeys() { return mLutSamplingKeys.toArray(); } } core/java/android/hardware/LutProperties.java 0 → 100644 +94 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.hardware; import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Lut properties class. * * A Lut (Look-Up Table) is a pre-calculated table for color transformation. * * @hide */ public final class LutProperties { private final @Dimension int mDimension; private final long mSize; private final @SamplingKey int[] mSamplingKeys; @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SAMPLING_KEY_"}, value = { SAMPLING_KEY_RGB, SAMPLING_KEY_MAX_RGB }) public @interface SamplingKey { } /** use r,g,b channel as the gain value of a Lut */ public static final int SAMPLING_KEY_RGB = 0; /** use max of r,g,b channel as the gain value of a Lut */ public static final int SAMPLING_KEY_MAX_RGB = 1; @Retention(RetentionPolicy.SOURCE) @IntDef(value = { ONE_DIMENSION, THREE_DIMENSION }) public @interface Dimension { } /** The Lut is one dimensional */ public static final int ONE_DIMENSION = 1; /** The Lut is three dimensional */ public static final int THREE_DIMENSION = 3; public @Dimension int getDimension() { return mDimension; } /** * @return the size of the Lut. */ public long getSize() { return mSize; } /** * @return the list of sampling keys */ public @SamplingKey int[] getSamplingKeys() { if (mSamplingKeys.length == 0) { throw new IllegalStateException("no sampling key!"); } return mSamplingKeys; } /* use in the native code */ private LutProperties(@Dimension int dimension, long size, @SamplingKey int[] samplingKeys) { if (dimension != ONE_DIMENSION || dimension != THREE_DIMENSION) { throw new IllegalArgumentException("The dimension is either 1 or 3!"); } mDimension = dimension; mSize = size; mSamplingKeys = samplingKeys; } } core/java/android/hardware/OverlayProperties.java +18 −1 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ public final class OverlayProperties implements Parcelable { // Invoked on destruction private Runnable mCloser; private LutProperties[] mLutProperties; private OverlayProperties(long nativeObject) { if (nativeObject != 0) { mCloser = sRegistry.registerNativeAllocation(this, nativeObject); Loading @@ -69,6 +71,20 @@ public final class OverlayProperties implements Parcelable { return sDefaultOverlayProperties; } /** * Gets the lut properties of the display. * @hide */ public LutProperties[] getLutProperties() { if (mNativeObject == 0) { return null; } if (mLutProperties == null) { mLutProperties = nGetLutProperties(mNativeObject); } return mLutProperties; } /** * Indicates that hardware composition of a buffer encoded with the provided {@link DataSpace} * and {@link HardwareBuffer.Format} is supported on the device. Loading Loading @@ -140,4 +156,5 @@ public final class OverlayProperties implements Parcelable { long nativeObject, int dataspace, int format); private static native void nWriteOverlayPropertiesToParcel(long nativeObject, Parcel dest); private static native long nReadOverlayPropertiesFromParcel(Parcel in); private static native LutProperties[] nGetLutProperties(long nativeObject); } No newline at end of file core/java/android/view/SurfaceControl.java +14 −2 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.gui.DropInputMode; import android.gui.StalledTransactionInfo; import android.gui.TrustedOverlay; import android.hardware.DataSpace; import android.hardware.DisplayLuts; import android.hardware.HardwareBuffer; import android.hardware.OverlayProperties; import android.hardware.SyncFence; Loading Loading @@ -307,9 +308,9 @@ public final class SurfaceControl implements Parcelable { private static native StalledTransactionInfo nativeGetStalledTransactionInfo(int pid); private static native void nativeSetDesiredPresentTimeNanos(long transactionObj, long desiredPresentTimeNanos); private static native void nativeSetFrameTimeline(long transactionObj, long vsyncId); private static native void nativeNotifyShutdown(); private static native void nativeSetLuts(long transactionObj, long nativeObject, float[] buffers, int[] slots, int[] dimensions, int[] sizes, int[] samplingKeys); /** * Transforms that can be applied to buffers as they are displayed to a window. Loading Loading @@ -4399,6 +4400,17 @@ public final class SurfaceControl implements Parcelable { return this; } /** @hide */ public @NonNull Transaction setLuts(@NonNull SurfaceControl sc, @NonNull DisplayLuts displayLuts) { checkPreconditions(sc); nativeSetLuts(mNativeObject, sc.mNativeObject, displayLuts.getLutBuffers(), displayLuts.getOffsets(), displayLuts.getLutDimensions(), displayLuts.getLutSizes(), displayLuts.getLutSamplingKeys()); return this; } /** * Sets the caching hint for the layer. By default, the caching hint is * {@link CACHING_ENABLED}. Loading core/jni/android_hardware_OverlayProperties.cpp +43 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "OverlayProperties" // #define LOG_NDEBUG 0 #include <android/gui/LutProperties.h> #include <android/gui/OverlayProperties.h> #include <binder/Parcel.h> #include <gui/SurfaceComposerClient.h> Loading @@ -35,6 +36,12 @@ static struct { jclass clazz; jmethodID ctor; } gOverlayPropertiesClassInfo; static struct { jclass clazz; jmethodID ctor; } gLutPropertiesClassInfo; // ---------------------------------------------------------------------------- // OverlayProperties lifecycle // ---------------------------------------------------------------------------- Loading Loading @@ -95,6 +102,36 @@ static jlong android_hardware_OverlayProperties_createDefault(JNIEnv* env, jobje return reinterpret_cast<jlong>(overlayProperties); } static jobjectArray android_hardware_OverlayProperties_getLutProperties(JNIEnv* env, jobject thiz, jlong nativeObject) { gui::OverlayProperties* overlayProperties = reinterpret_cast<gui::OverlayProperties*>(nativeObject); if (overlayProperties->lutProperties.has_value()) { return NULL; } auto& lutProperties = overlayProperties->lutProperties.value(); if (lutProperties.empty()) { return NULL; } int32_t size = static_cast<int32_t>(lutProperties.size()); jobjectArray nativeLutProperties = env->NewObjectArray(size, gLutPropertiesClassInfo.clazz, NULL); if (nativeLutProperties == NULL) { return NULL; } for (int32_t i = 0; i < size; i++) { if (lutProperties[i].has_value()) { auto& item = lutProperties[i].value(); jobject properties = env->NewObject(gLutPropertiesClassInfo.clazz, gLutPropertiesClassInfo.ctor, static_cast<int32_t>(item.dimension), item.size, item.samplingKeys.data()); env->SetObjectArrayElement(nativeLutProperties, i, properties); } } return nativeLutProperties; } // ---------------------------------------------------------------------------- // Serialization // ---------------------------------------------------------------------------- Loading Loading @@ -161,6 +198,8 @@ static const JNINativeMethod gMethods[] = { { "nReadOverlayPropertiesFromParcel", "(Landroid/os/Parcel;)J", (void*) android_hardware_OverlayProperties_read }, {"nCreateDefault", "()J", (void*) android_hardware_OverlayProperties_createDefault }, {"nGetLutProperties", "(J)[Landroid/hardware/LutProperties;", (void*) android_hardware_OverlayProperties_getLutProperties }, }; // clang-format on Loading @@ -171,5 +210,9 @@ int register_android_hardware_OverlayProperties(JNIEnv* env) { gOverlayPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gOverlayPropertiesClassInfo.ctor = GetMethodIDOrDie(env, gOverlayPropertiesClassInfo.clazz, "<init>", "(J)V"); clazz = FindClassOrDie(env, "android/hardware/LutProperties"); gLutPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gLutPropertiesClassInfo.ctor = GetMethodIDOrDie(env, gLutPropertiesClassInfo.clazz, "<init>", "(IJ[I)V"); return err; } Loading
core/java/android/hardware/DisplayLuts.java 0 → 100644 +131 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.hardware; import android.annotation.NonNull; import android.util.IntArray; import java.util.ArrayList; import java.util.List; /** * @hide */ public final class DisplayLuts { private IntArray mOffsets; private int mTotalLength; private List<float[]> mLutBuffers; private IntArray mLutDimensions; private IntArray mLutSizes; private IntArray mLutSamplingKeys; private static final int LUT_LENGTH_LIMIT = 100000; public DisplayLuts() { mOffsets = new IntArray(); mTotalLength = 0; mLutBuffers = new ArrayList<>(); mLutDimensions = new IntArray(); mLutSizes = new IntArray(); mLutSamplingKeys = new IntArray(); } /** * Add the lut to be applied. * * @param buffer * @param dimension either 1D or 3D * @param size * @param samplingKey */ public void addLut(@NonNull float[] buffer, @LutProperties.Dimension int dimension, int size, @LutProperties.SamplingKey int samplingKey) { int lutLength = 0; if (dimension == LutProperties.ONE_DIMENSION) { lutLength = size; } else if (dimension == LutProperties.THREE_DIMENSION) { lutLength = size * size * size; } else { clear(); throw new IllegalArgumentException("The dimension is either 1D or 3D!"); } if (lutLength >= LUT_LENGTH_LIMIT) { clear(); throw new IllegalArgumentException("The lut length is too big to handle!"); } mOffsets.add(mTotalLength); mTotalLength += lutLength; mLutBuffers.add(buffer); mLutDimensions.add(dimension); mLutSizes.add(size); mLutSamplingKeys.add(samplingKey); } private void clear() { mTotalLength = 0; mOffsets.clear(); mLutBuffers.clear(); mLutDimensions.clear(); mLutSamplingKeys.clear(); } /** * @return the array of Lut buffers */ public float[] getLutBuffers() { float[] buffer = new float[mTotalLength]; for (int i = 0; i < mLutBuffers.size(); i++) { float[] lutBuffer = mLutBuffers.get(i); System.arraycopy(lutBuffer, 0, buffer, mOffsets.get(i), lutBuffer.length); } return buffer; } /** * @return the starting point of each lut memory region of the lut buffer */ public int[] getOffsets() { return mOffsets.toArray(); } /** * @return the array of Lut size */ public int[] getLutSizes() { return mLutSizes.toArray(); } /** * @return the array of Lut dimension */ public int[] getLutDimensions() { return mLutDimensions.toArray(); } /** * @return the array of sampling key */ public int[] getLutSamplingKeys() { return mLutSamplingKeys.toArray(); } }
core/java/android/hardware/LutProperties.java 0 → 100644 +94 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.hardware; import android.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Lut properties class. * * A Lut (Look-Up Table) is a pre-calculated table for color transformation. * * @hide */ public final class LutProperties { private final @Dimension int mDimension; private final long mSize; private final @SamplingKey int[] mSamplingKeys; @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SAMPLING_KEY_"}, value = { SAMPLING_KEY_RGB, SAMPLING_KEY_MAX_RGB }) public @interface SamplingKey { } /** use r,g,b channel as the gain value of a Lut */ public static final int SAMPLING_KEY_RGB = 0; /** use max of r,g,b channel as the gain value of a Lut */ public static final int SAMPLING_KEY_MAX_RGB = 1; @Retention(RetentionPolicy.SOURCE) @IntDef(value = { ONE_DIMENSION, THREE_DIMENSION }) public @interface Dimension { } /** The Lut is one dimensional */ public static final int ONE_DIMENSION = 1; /** The Lut is three dimensional */ public static final int THREE_DIMENSION = 3; public @Dimension int getDimension() { return mDimension; } /** * @return the size of the Lut. */ public long getSize() { return mSize; } /** * @return the list of sampling keys */ public @SamplingKey int[] getSamplingKeys() { if (mSamplingKeys.length == 0) { throw new IllegalStateException("no sampling key!"); } return mSamplingKeys; } /* use in the native code */ private LutProperties(@Dimension int dimension, long size, @SamplingKey int[] samplingKeys) { if (dimension != ONE_DIMENSION || dimension != THREE_DIMENSION) { throw new IllegalArgumentException("The dimension is either 1 or 3!"); } mDimension = dimension; mSize = size; mSamplingKeys = samplingKeys; } }
core/java/android/hardware/OverlayProperties.java +18 −1 Original line number Diff line number Diff line Loading @@ -50,6 +50,8 @@ public final class OverlayProperties implements Parcelable { // Invoked on destruction private Runnable mCloser; private LutProperties[] mLutProperties; private OverlayProperties(long nativeObject) { if (nativeObject != 0) { mCloser = sRegistry.registerNativeAllocation(this, nativeObject); Loading @@ -69,6 +71,20 @@ public final class OverlayProperties implements Parcelable { return sDefaultOverlayProperties; } /** * Gets the lut properties of the display. * @hide */ public LutProperties[] getLutProperties() { if (mNativeObject == 0) { return null; } if (mLutProperties == null) { mLutProperties = nGetLutProperties(mNativeObject); } return mLutProperties; } /** * Indicates that hardware composition of a buffer encoded with the provided {@link DataSpace} * and {@link HardwareBuffer.Format} is supported on the device. Loading Loading @@ -140,4 +156,5 @@ public final class OverlayProperties implements Parcelable { long nativeObject, int dataspace, int format); private static native void nWriteOverlayPropertiesToParcel(long nativeObject, Parcel dest); private static native long nReadOverlayPropertiesFromParcel(Parcel in); private static native LutProperties[] nGetLutProperties(long nativeObject); } No newline at end of file
core/java/android/view/SurfaceControl.java +14 −2 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import android.gui.DropInputMode; import android.gui.StalledTransactionInfo; import android.gui.TrustedOverlay; import android.hardware.DataSpace; import android.hardware.DisplayLuts; import android.hardware.HardwareBuffer; import android.hardware.OverlayProperties; import android.hardware.SyncFence; Loading Loading @@ -307,9 +308,9 @@ public final class SurfaceControl implements Parcelable { private static native StalledTransactionInfo nativeGetStalledTransactionInfo(int pid); private static native void nativeSetDesiredPresentTimeNanos(long transactionObj, long desiredPresentTimeNanos); private static native void nativeSetFrameTimeline(long transactionObj, long vsyncId); private static native void nativeNotifyShutdown(); private static native void nativeSetLuts(long transactionObj, long nativeObject, float[] buffers, int[] slots, int[] dimensions, int[] sizes, int[] samplingKeys); /** * Transforms that can be applied to buffers as they are displayed to a window. Loading Loading @@ -4399,6 +4400,17 @@ public final class SurfaceControl implements Parcelable { return this; } /** @hide */ public @NonNull Transaction setLuts(@NonNull SurfaceControl sc, @NonNull DisplayLuts displayLuts) { checkPreconditions(sc); nativeSetLuts(mNativeObject, sc.mNativeObject, displayLuts.getLutBuffers(), displayLuts.getOffsets(), displayLuts.getLutDimensions(), displayLuts.getLutSizes(), displayLuts.getLutSamplingKeys()); return this; } /** * Sets the caching hint for the layer. By default, the caching hint is * {@link CACHING_ENABLED}. Loading
core/jni/android_hardware_OverlayProperties.cpp +43 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "OverlayProperties" // #define LOG_NDEBUG 0 #include <android/gui/LutProperties.h> #include <android/gui/OverlayProperties.h> #include <binder/Parcel.h> #include <gui/SurfaceComposerClient.h> Loading @@ -35,6 +36,12 @@ static struct { jclass clazz; jmethodID ctor; } gOverlayPropertiesClassInfo; static struct { jclass clazz; jmethodID ctor; } gLutPropertiesClassInfo; // ---------------------------------------------------------------------------- // OverlayProperties lifecycle // ---------------------------------------------------------------------------- Loading Loading @@ -95,6 +102,36 @@ static jlong android_hardware_OverlayProperties_createDefault(JNIEnv* env, jobje return reinterpret_cast<jlong>(overlayProperties); } static jobjectArray android_hardware_OverlayProperties_getLutProperties(JNIEnv* env, jobject thiz, jlong nativeObject) { gui::OverlayProperties* overlayProperties = reinterpret_cast<gui::OverlayProperties*>(nativeObject); if (overlayProperties->lutProperties.has_value()) { return NULL; } auto& lutProperties = overlayProperties->lutProperties.value(); if (lutProperties.empty()) { return NULL; } int32_t size = static_cast<int32_t>(lutProperties.size()); jobjectArray nativeLutProperties = env->NewObjectArray(size, gLutPropertiesClassInfo.clazz, NULL); if (nativeLutProperties == NULL) { return NULL; } for (int32_t i = 0; i < size; i++) { if (lutProperties[i].has_value()) { auto& item = lutProperties[i].value(); jobject properties = env->NewObject(gLutPropertiesClassInfo.clazz, gLutPropertiesClassInfo.ctor, static_cast<int32_t>(item.dimension), item.size, item.samplingKeys.data()); env->SetObjectArrayElement(nativeLutProperties, i, properties); } } return nativeLutProperties; } // ---------------------------------------------------------------------------- // Serialization // ---------------------------------------------------------------------------- Loading Loading @@ -161,6 +198,8 @@ static const JNINativeMethod gMethods[] = { { "nReadOverlayPropertiesFromParcel", "(Landroid/os/Parcel;)J", (void*) android_hardware_OverlayProperties_read }, {"nCreateDefault", "()J", (void*) android_hardware_OverlayProperties_createDefault }, {"nGetLutProperties", "(J)[Landroid/hardware/LutProperties;", (void*) android_hardware_OverlayProperties_getLutProperties }, }; // clang-format on Loading @@ -171,5 +210,9 @@ int register_android_hardware_OverlayProperties(JNIEnv* env) { gOverlayPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gOverlayPropertiesClassInfo.ctor = GetMethodIDOrDie(env, gOverlayPropertiesClassInfo.clazz, "<init>", "(J)V"); clazz = FindClassOrDie(env, "android/hardware/LutProperties"); gLutPropertiesClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gLutPropertiesClassInfo.ctor = GetMethodIDOrDie(env, gLutPropertiesClassInfo.clazz, "<init>", "(IJ[I)V"); return err; }