Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d2d9340 authored by Sally Qi's avatar Sally Qi
Browse files

Make gainmap parcelable.

Bug: 267215989
Test: android.graphics.cts.GainmapTest

Change-Id: I189f652f26f2f92e37afdc3f69ae7b7653d69bf0
parent 31d0a293
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -15497,8 +15497,9 @@ package android.graphics {
    ctor @Deprecated public EmbossMaskFilter(float[], float, float, float);
  }
  public final class Gainmap {
  public final class Gainmap implements android.os.Parcelable {
    ctor public Gainmap(@NonNull android.graphics.Bitmap);
    method public int describeContents();
    method @NonNull public float getDisplayRatioForFullHdr();
    method @NonNull public float[] getEpsilonHdr();
    method @NonNull public float[] getEpsilonSdr();
@@ -15515,6 +15516,8 @@ package android.graphics {
    method @NonNull public void setMinDisplayRatioForHdrTransition(@FloatRange(from=1.0f) float);
    method @NonNull public void setRatioMax(float, float, float);
    method @NonNull 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;
  }
  public class HardwareBufferRenderer implements java.lang.AutoCloseable {
+26 −17
Original line number Diff line number Diff line
@@ -2186,6 +2186,9 @@ public final class Bitmap implements Parcelable {
                    if (bm == null) {
                        throw new RuntimeException("Failed to unparcel Bitmap");
                    }
                    if (p.readBoolean()) {
                        bm.setGainmap(p.readTypedObject(Gainmap.CREATOR));
                    }
                    return bm;
                }
                public Bitmap[] newArray(int size) {
@@ -2215,6 +2218,12 @@ public final class Bitmap implements Parcelable {
        if (!nativeWriteToParcel(mNativePtr, mDensity, p)) {
            throw new RuntimeException("native writeToParcel failed");
        }
        if (hasGainmap()) {
            p.writeBoolean(true);
            p.writeTypedObject(mGainmap, flags);
        } else {
            p.writeBoolean(false);
        }
    }

    /**
+49 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package android.graphics;

import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;

import libcore.util.NativeAllocationRegistry;

@@ -76,7 +78,7 @@ import libcore.util.NativeAllocationRegistry;
 *
 * In the above math, log() is a natural logarithm and exp() is natural exponentiation.
 */
public final class Gainmap {
public final class Gainmap implements Parcelable {

    // Use a Holder to allow static initialization of Gainmap in the boot image.
    private static class NoImagePreloadHolder {
@@ -284,6 +286,50 @@ public final class Gainmap {
        return nGetDisplayRatioSdr(mNativePtr);
    }

    /**
     * No special parcel contents.
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * Write the gainmap to the parcel.
     *
     * @param dest Parcel object to write the gainmap data into
     * @param flags Additional flags about how the object should be written.
     */
    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        if (mNativePtr == 0) {
            throw new IllegalStateException("Cannot be written to a parcel");
        }
        dest.writeTypedObject(mGainmapContents, flags);
        // write gainmapinfo into parcel
        nWriteGainmapToParcel(mNativePtr, dest);
    }

    public static final @NonNull Parcelable.Creator<Gainmap> CREATOR =
            new Parcelable.Creator<Gainmap>() {
            /**
             * Rebuilds a gainmap previously stored with writeToParcel().
             *
             * @param in Parcel object to read the gainmap from
             * @return a new gainmap created from the data in the parcel
             */
            public Gainmap createFromParcel(Parcel in) {
                Gainmap gm = new Gainmap(in.readTypedObject(Bitmap.CREATOR));
                // read gainmapinfo from parcel
                nReadGainmapFromParcel(gm.mNativePtr, in);
                return gm;
            }

            public Gainmap[] newArray(int size) {
                return new Gainmap[size];
            }
        };

    private static native long nGetFinalizer();
    private static native long nCreateEmpty();

@@ -309,4 +355,6 @@ public final class Gainmap {

    private static native void nSetDisplayRatioSdr(long ptr, float min);
    private static native float nGetDisplayRatioSdr(long ptr);
    private static native void nWriteGainmapToParcel(long ptr, Parcel dest);
    private static native void nReadGainmapFromParcel(long ptr, Parcel src);
}
+1 −0
Original line number Diff line number Diff line
@@ -364,6 +364,7 @@ cc_defaults {
        "jni/PathMeasure.cpp",
        "jni/Picture.cpp",
        "jni/Region.cpp",
        "jni/ScopedParcel.cpp",
        "jni/Shader.cpp",
        "jni/RenderEffect.cpp",
        "jni/Typeface.cpp",
+2 −90
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#include "Gainmap.h"
#include "GraphicsJNI.h"
#include "HardwareBufferHelpers.h"
#include "ScopedParcel.h"
#include "SkBitmap.h"
#include "SkBlendMode.h"
#include "SkCanvas.h"
@@ -27,12 +28,7 @@

#ifdef __ANDROID__ // Layoutlib does not support graphic buffer, parcel or render thread
#include <android-base/unique_fd.h>
#include <android/binder_parcel.h>
#include <android/binder_parcel_jni.h>
#include <android/binder_parcel_platform.h>
#include <cutils/ashmem.h>
#include <renderthread/RenderProxy.h>
#include <sys/mman.h>
#endif

#include <inttypes.h>
@@ -617,90 +613,6 @@ static void Bitmap_setHasMipMap(JNIEnv* env, jobject, jlong bitmapHandle,

// TODO: Move somewhere else
#ifdef __ANDROID__  // Layoutlib does not support parcel

class ScopedParcel {
public:
    explicit ScopedParcel(JNIEnv* env, jobject parcel) {
        mParcel = AParcel_fromJavaParcel(env, parcel);
    }

    ~ScopedParcel() { AParcel_delete(mParcel); }

    int32_t readInt32() {
        int32_t temp = 0;
        // TODO: This behavior-matches what android::Parcel does
        // but this should probably be better
        if (AParcel_readInt32(mParcel, &temp) != STATUS_OK) {
            temp = 0;
        }
        return temp;
    }

    uint32_t readUint32() {
        uint32_t temp = 0;
        // TODO: This behavior-matches what android::Parcel does
        // but this should probably be better
        if (AParcel_readUint32(mParcel, &temp) != STATUS_OK) {
            temp = 0;
        }
        return temp;
    }

    void writeInt32(int32_t value) { AParcel_writeInt32(mParcel, value); }

    void writeUint32(uint32_t value) { AParcel_writeUint32(mParcel, value); }

    bool allowFds() const { return AParcel_getAllowFds(mParcel); }

    std::optional<sk_sp<SkData>> readData() {
        struct Data {
            void* ptr = nullptr;
            size_t size = 0;
        } data;
        auto error = AParcel_readByteArray(mParcel, &data,
                                           [](void* arrayData, int32_t length,
                                              int8_t** outBuffer) -> bool {
                                               Data* data = reinterpret_cast<Data*>(arrayData);
                                               if (length > 0) {
                                                   data->ptr = sk_malloc_canfail(length);
                                                   if (!data->ptr) {
                                                       return false;
                                                   }
                                                   *outBuffer =
                                                           reinterpret_cast<int8_t*>(data->ptr);
                                                   data->size = length;
                                               }
                                               return true;
                                           });
        if (error != STATUS_OK || data.size <= 0) {
            sk_free(data.ptr);
            return std::nullopt;
        } else {
            return SkData::MakeFromMalloc(data.ptr, data.size);
        }
    }

    void writeData(const std::optional<sk_sp<SkData>>& optData) {
        if (optData) {
            const auto& data = *optData;
            AParcel_writeByteArray(mParcel, reinterpret_cast<const int8_t*>(data->data()),
                                   data->size());
        } else {
            AParcel_writeByteArray(mParcel, nullptr, -1);
        }
    }

    AParcel* get() { return mParcel; }

private:
    AParcel* mParcel;
};

enum class BlobType : int32_t {
    IN_PLACE,
    ASHMEM,
};

#define ON_ERROR_RETURN(X) \
    if ((error = (X)) != STATUS_OK) return error

Loading