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

Commit 9505a655 authored by Romain Guy's avatar Romain Guy
Browse files

Add new RGBA_F16 bitmap config

This configuration uses 64 bits per pixel. Heach component is stored as a
half precision float value (16 bits). Half floats can be decoded/encoded
using android.util.Half.

RGBA_F16 bitmaps are used to decode wide-gamut images stored in 16 bit
formats (PNG 16 bit for instance). aapt is currently not aware of PNG
16 bits so such files must be placed in raw/ resource directories.

This first pass provides only partial drawing support with hardware
acceleration. RGBA_F16 bitmaps are stored in linear space and need
to be encoded to gamma space with the appropriate OETF to be rendered
properly on Android's current surfaces. They are however suitable for
linear blending. Full rendering support will be provided in a future
CL (BitmapShaders might be a bit tricky to handle properly during
shader generation).

Bug: 32984164
Test: bit CtsGraphicsTestCases:android.graphics.cts.BitmapRGBAF16Test

Change-Id: I328e6b567441a1b9d152a3e7be944a2cf63193bd
parent de315b99
Loading
Loading
Loading
Loading
+21 −15
Original line number Original line Diff line number Diff line
@@ -11769,6 +11769,8 @@ package android.graphics {
    method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int, android.graphics.Matrix, boolean);
    method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int, android.graphics.Matrix, boolean);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config, boolean);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config, boolean);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
@@ -11833,6 +11835,7 @@ package android.graphics {
    enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444;
    enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444;
    enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
    enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
    enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
    enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
    enum_constant public static final android.graphics.Bitmap.Config RGBA_F16;
    enum_constant public static final android.graphics.Bitmap.Config RGB_565;
    enum_constant public static final android.graphics.Bitmap.Config RGB_565;
  }
  }
@@ -12192,6 +12195,7 @@ package android.graphics {
    method public android.graphics.Bitmap render();
    method public android.graphics.Bitmap render();
    method public android.graphics.ColorSpace.Renderer showWhitePoint(boolean);
    method public android.graphics.ColorSpace.Renderer showWhitePoint(boolean);
    method public android.graphics.ColorSpace.Renderer size(int);
    method public android.graphics.ColorSpace.Renderer size(int);
    method public android.graphics.ColorSpace.Renderer uniformChromaticityScale(boolean);
  }
  }
  public static class ColorSpace.Rgb extends android.graphics.ColorSpace {
  public static class ColorSpace.Rgb extends android.graphics.ColorSpace {
@@ -12727,7 +12731,9 @@ package android.graphics {
    field public static final deprecated int RGBA_4444 = 7; // 0x7
    field public static final deprecated int RGBA_4444 = 7; // 0x7
    field public static final deprecated int RGBA_5551 = 6; // 0x6
    field public static final deprecated int RGBA_5551 = 6; // 0x6
    field public static final int RGBA_8888 = 1; // 0x1
    field public static final int RGBA_8888 = 1; // 0x1
    field public static final int RGBA_F16 = 22; // 0x16
    field public static final int RGBX_8888 = 2; // 0x2
    field public static final int RGBX_8888 = 2; // 0x2
    field public static final int RGBX_F16 = 23; // 0x17
    field public static final deprecated int RGB_332 = 11; // 0xb
    field public static final deprecated int RGB_332 = 11; // 0xb
    field public static final int RGB_565 = 4; // 0x4
    field public static final int RGB_565 = 4; // 0x4
    field public static final int RGB_888 = 3; // 0x3
    field public static final int RGB_888 = 3; // 0x3
@@ -61421,31 +61427,31 @@ package java.util.concurrent {
    ctor public CopyOnWriteArrayList();
    ctor public CopyOnWriteArrayList();
    ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
    ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
    ctor public CopyOnWriteArrayList(E[]);
    ctor public CopyOnWriteArrayList(E[]);
    method public synchronized boolean add(E);
    method public boolean add(E);
    method public synchronized void add(int, E);
    method public void add(int, E);
    method public synchronized boolean addAll(java.util.Collection<? extends E>);
    method public boolean addAll(java.util.Collection<? extends E>);
    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
    method public boolean addAll(int, java.util.Collection<? extends E>);
    method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
    method public int addAllAbsent(java.util.Collection<? extends E>);
    method public synchronized boolean addIfAbsent(E);
    method public boolean addIfAbsent(E);
    method public synchronized void clear();
    method public void clear();
    method public java.lang.Object clone();
    method public java.lang.Object clone();
    method public boolean contains(java.lang.Object);
    method public boolean contains(java.lang.Object);
    method public boolean containsAll(java.util.Collection<?>);
    method public boolean containsAll(java.util.Collection<?>);
    method public void forEach(java.util.function.Consumer<? super E>);
    method public void forEach(java.util.function.Consumer<? super E>);
    method public E get(int);
    method public E get(int);
    method public int indexOf(E, int);
    method public int indexOf(java.lang.Object);
    method public int indexOf(java.lang.Object);
    method public int indexOf(E, int);
    method public boolean isEmpty();
    method public boolean isEmpty();
    method public java.util.Iterator<E> iterator();
    method public java.util.Iterator<E> iterator();
    method public int lastIndexOf(E, int);
    method public int lastIndexOf(java.lang.Object);
    method public int lastIndexOf(java.lang.Object);
    method public java.util.ListIterator<E> listIterator(int);
    method public int lastIndexOf(E, int);
    method public java.util.ListIterator<E> listIterator();
    method public java.util.ListIterator<E> listIterator();
    method public synchronized E remove(int);
    method public java.util.ListIterator<E> listIterator(int);
    method public synchronized boolean remove(java.lang.Object);
    method public E remove(int);
    method public synchronized boolean removeAll(java.util.Collection<?>);
    method public boolean remove(java.lang.Object);
    method public synchronized boolean retainAll(java.util.Collection<?>);
    method public boolean removeAll(java.util.Collection<?>);
    method public synchronized E set(int, E);
    method public boolean retainAll(java.util.Collection<?>);
    method public E set(int, E);
    method public int size();
    method public int size();
    method public java.util.List<E> subList(int, int);
    method public java.util.List<E> subList(int, int);
    method public java.lang.Object[] toArray();
    method public java.lang.Object[] toArray();
+21 −15
Original line number Original line Diff line number Diff line
@@ -12262,6 +12262,8 @@ package android.graphics {
    method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int, android.graphics.Matrix, boolean);
    method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int, android.graphics.Matrix, boolean);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config, boolean);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config, boolean);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
@@ -12326,6 +12328,7 @@ package android.graphics {
    enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444;
    enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444;
    enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
    enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
    enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
    enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
    enum_constant public static final android.graphics.Bitmap.Config RGBA_F16;
    enum_constant public static final android.graphics.Bitmap.Config RGB_565;
    enum_constant public static final android.graphics.Bitmap.Config RGB_565;
  }
  }
@@ -12685,6 +12688,7 @@ package android.graphics {
    method public android.graphics.Bitmap render();
    method public android.graphics.Bitmap render();
    method public android.graphics.ColorSpace.Renderer showWhitePoint(boolean);
    method public android.graphics.ColorSpace.Renderer showWhitePoint(boolean);
    method public android.graphics.ColorSpace.Renderer size(int);
    method public android.graphics.ColorSpace.Renderer size(int);
    method public android.graphics.ColorSpace.Renderer uniformChromaticityScale(boolean);
  }
  }
  public static class ColorSpace.Rgb extends android.graphics.ColorSpace {
  public static class ColorSpace.Rgb extends android.graphics.ColorSpace {
@@ -13220,7 +13224,9 @@ package android.graphics {
    field public static final deprecated int RGBA_4444 = 7; // 0x7
    field public static final deprecated int RGBA_4444 = 7; // 0x7
    field public static final deprecated int RGBA_5551 = 6; // 0x6
    field public static final deprecated int RGBA_5551 = 6; // 0x6
    field public static final int RGBA_8888 = 1; // 0x1
    field public static final int RGBA_8888 = 1; // 0x1
    field public static final int RGBA_F16 = 22; // 0x16
    field public static final int RGBX_8888 = 2; // 0x2
    field public static final int RGBX_8888 = 2; // 0x2
    field public static final int RGBX_F16 = 23; // 0x17
    field public static final deprecated int RGB_332 = 11; // 0xb
    field public static final deprecated int RGB_332 = 11; // 0xb
    field public static final int RGB_565 = 4; // 0x4
    field public static final int RGB_565 = 4; // 0x4
    field public static final int RGB_888 = 3; // 0x3
    field public static final int RGB_888 = 3; // 0x3
@@ -64923,31 +64929,31 @@ package java.util.concurrent {
    ctor public CopyOnWriteArrayList();
    ctor public CopyOnWriteArrayList();
    ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
    ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
    ctor public CopyOnWriteArrayList(E[]);
    ctor public CopyOnWriteArrayList(E[]);
    method public synchronized boolean add(E);
    method public boolean add(E);
    method public synchronized void add(int, E);
    method public void add(int, E);
    method public synchronized boolean addAll(java.util.Collection<? extends E>);
    method public boolean addAll(java.util.Collection<? extends E>);
    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
    method public boolean addAll(int, java.util.Collection<? extends E>);
    method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
    method public int addAllAbsent(java.util.Collection<? extends E>);
    method public synchronized boolean addIfAbsent(E);
    method public boolean addIfAbsent(E);
    method public synchronized void clear();
    method public void clear();
    method public java.lang.Object clone();
    method public java.lang.Object clone();
    method public boolean contains(java.lang.Object);
    method public boolean contains(java.lang.Object);
    method public boolean containsAll(java.util.Collection<?>);
    method public boolean containsAll(java.util.Collection<?>);
    method public void forEach(java.util.function.Consumer<? super E>);
    method public void forEach(java.util.function.Consumer<? super E>);
    method public E get(int);
    method public E get(int);
    method public int indexOf(E, int);
    method public int indexOf(java.lang.Object);
    method public int indexOf(java.lang.Object);
    method public int indexOf(E, int);
    method public boolean isEmpty();
    method public boolean isEmpty();
    method public java.util.Iterator<E> iterator();
    method public java.util.Iterator<E> iterator();
    method public int lastIndexOf(E, int);
    method public int lastIndexOf(java.lang.Object);
    method public int lastIndexOf(java.lang.Object);
    method public java.util.ListIterator<E> listIterator(int);
    method public int lastIndexOf(E, int);
    method public java.util.ListIterator<E> listIterator();
    method public java.util.ListIterator<E> listIterator();
    method public synchronized E remove(int);
    method public java.util.ListIterator<E> listIterator(int);
    method public synchronized boolean remove(java.lang.Object);
    method public E remove(int);
    method public synchronized boolean removeAll(java.util.Collection<?>);
    method public boolean remove(java.lang.Object);
    method public synchronized boolean retainAll(java.util.Collection<?>);
    method public boolean removeAll(java.util.Collection<?>);
    method public synchronized E set(int, E);
    method public boolean retainAll(java.util.Collection<?>);
    method public E set(int, E);
    method public int size();
    method public int size();
    method public java.util.List<E> subList(int, int);
    method public java.util.List<E> subList(int, int);
    method public java.lang.Object[] toArray();
    method public java.lang.Object[] toArray();
+21 −15
Original line number Original line Diff line number Diff line
@@ -11800,6 +11800,8 @@ package android.graphics {
    method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int, android.graphics.Matrix, boolean);
    method public static android.graphics.Bitmap createBitmap(android.graphics.Bitmap, int, int, int, int, android.graphics.Matrix, boolean);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int, int, android.graphics.Bitmap.Config, boolean);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int, int, android.graphics.Bitmap.Config, boolean);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(android.util.DisplayMetrics, int[], int, int, int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
    method public static android.graphics.Bitmap createBitmap(int[], int, int, android.graphics.Bitmap.Config);
@@ -11864,6 +11866,7 @@ package android.graphics {
    enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444;
    enum_constant public static final deprecated android.graphics.Bitmap.Config ARGB_4444;
    enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
    enum_constant public static final android.graphics.Bitmap.Config ARGB_8888;
    enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
    enum_constant public static final android.graphics.Bitmap.Config HARDWARE;
    enum_constant public static final android.graphics.Bitmap.Config RGBA_F16;
    enum_constant public static final android.graphics.Bitmap.Config RGB_565;
    enum_constant public static final android.graphics.Bitmap.Config RGB_565;
  }
  }
@@ -12223,6 +12226,7 @@ package android.graphics {
    method public android.graphics.Bitmap render();
    method public android.graphics.Bitmap render();
    method public android.graphics.ColorSpace.Renderer showWhitePoint(boolean);
    method public android.graphics.ColorSpace.Renderer showWhitePoint(boolean);
    method public android.graphics.ColorSpace.Renderer size(int);
    method public android.graphics.ColorSpace.Renderer size(int);
    method public android.graphics.ColorSpace.Renderer uniformChromaticityScale(boolean);
  }
  }
  public static class ColorSpace.Rgb extends android.graphics.ColorSpace {
  public static class ColorSpace.Rgb extends android.graphics.ColorSpace {
@@ -12758,7 +12762,9 @@ package android.graphics {
    field public static final deprecated int RGBA_4444 = 7; // 0x7
    field public static final deprecated int RGBA_4444 = 7; // 0x7
    field public static final deprecated int RGBA_5551 = 6; // 0x6
    field public static final deprecated int RGBA_5551 = 6; // 0x6
    field public static final int RGBA_8888 = 1; // 0x1
    field public static final int RGBA_8888 = 1; // 0x1
    field public static final int RGBA_F16 = 22; // 0x16
    field public static final int RGBX_8888 = 2; // 0x2
    field public static final int RGBX_8888 = 2; // 0x2
    field public static final int RGBX_F16 = 23; // 0x17
    field public static final deprecated int RGB_332 = 11; // 0xb
    field public static final deprecated int RGB_332 = 11; // 0xb
    field public static final int RGB_565 = 4; // 0x4
    field public static final int RGB_565 = 4; // 0x4
    field public static final int RGB_888 = 3; // 0x3
    field public static final int RGB_888 = 3; // 0x3
@@ -61710,31 +61716,31 @@ package java.util.concurrent {
    ctor public CopyOnWriteArrayList();
    ctor public CopyOnWriteArrayList();
    ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
    ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
    ctor public CopyOnWriteArrayList(E[]);
    ctor public CopyOnWriteArrayList(E[]);
    method public synchronized boolean add(E);
    method public boolean add(E);
    method public synchronized void add(int, E);
    method public void add(int, E);
    method public synchronized boolean addAll(java.util.Collection<? extends E>);
    method public boolean addAll(java.util.Collection<? extends E>);
    method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
    method public boolean addAll(int, java.util.Collection<? extends E>);
    method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
    method public int addAllAbsent(java.util.Collection<? extends E>);
    method public synchronized boolean addIfAbsent(E);
    method public boolean addIfAbsent(E);
    method public synchronized void clear();
    method public void clear();
    method public java.lang.Object clone();
    method public java.lang.Object clone();
    method public boolean contains(java.lang.Object);
    method public boolean contains(java.lang.Object);
    method public boolean containsAll(java.util.Collection<?>);
    method public boolean containsAll(java.util.Collection<?>);
    method public void forEach(java.util.function.Consumer<? super E>);
    method public void forEach(java.util.function.Consumer<? super E>);
    method public E get(int);
    method public E get(int);
    method public int indexOf(E, int);
    method public int indexOf(java.lang.Object);
    method public int indexOf(java.lang.Object);
    method public int indexOf(E, int);
    method public boolean isEmpty();
    method public boolean isEmpty();
    method public java.util.Iterator<E> iterator();
    method public java.util.Iterator<E> iterator();
    method public int lastIndexOf(E, int);
    method public int lastIndexOf(java.lang.Object);
    method public int lastIndexOf(java.lang.Object);
    method public java.util.ListIterator<E> listIterator(int);
    method public int lastIndexOf(E, int);
    method public java.util.ListIterator<E> listIterator();
    method public java.util.ListIterator<E> listIterator();
    method public synchronized E remove(int);
    method public java.util.ListIterator<E> listIterator(int);
    method public synchronized boolean remove(java.lang.Object);
    method public E remove(int);
    method public synchronized boolean removeAll(java.util.Collection<?>);
    method public boolean remove(java.lang.Object);
    method public synchronized boolean retainAll(java.util.Collection<?>);
    method public boolean removeAll(java.util.Collection<?>);
    method public synchronized E set(int, E);
    method public boolean retainAll(java.util.Collection<?>);
    method public E set(int, E);
    method public int size();
    method public int size();
    method public java.util.List<E> subList(int, int);
    method public java.util.List<E> subList(int, int);
    method public java.lang.Object[] toArray();
    method public java.lang.Object[] toArray();
+70 −7
Original line number Original line Diff line number Diff line
@@ -5,7 +5,11 @@
#include "SkPixelRef.h"
#include "SkPixelRef.h"
#include "SkImageEncoder.h"
#include "SkImageEncoder.h"
#include "SkImageInfo.h"
#include "SkImageInfo.h"
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkColorPriv.h"
#include "SkHalf.h"
#include "SkPM4f.h"
#include "SkPM4fPriv.h"
#include "GraphicsJNI.h"
#include "GraphicsJNI.h"
#include "SkDither.h"
#include "SkDither.h"
#include "SkUnPreMultiply.h"
#include "SkUnPreMultiply.h"
@@ -232,6 +236,28 @@ using namespace android::bitmap;
typedef void (*FromColorProc)(void* dst, const SkColor src[], int width,
typedef void (*FromColorProc)(void* dst, const SkColor src[], int width,
                              int x, int y);
                              int x, int y);


static void FromColor_F16(void* dst, const SkColor src[], int width,
                          int, int) {
    uint64_t* d = (uint64_t*)dst;

    for (int i = 0; i < width; i++) {
        *d++ = SkColor4f::FromColor(*src++).premul().toF16();
    }
}

static void FromColor_F16_Raw(void* dst, const SkColor src[], int width,
                          int, int) {
    uint64_t* d = (uint64_t*)dst;

    for (int i = 0; i < width; i++) {
        const float* color = SkColor4f::FromColor(*src++).vec();
        uint16_t* scratch = reinterpret_cast<uint16_t*>(d++);
        for (int i = 0; i < 4; ++i) {
            scratch[i] = SkFloatToHalf(color[i]);
        }
    }
}

static void FromColor_D32(void* dst, const SkColor src[], int width,
static void FromColor_D32(void* dst, const SkColor src[], int width,
                          int, int) {
                          int, int) {
    SkPMColor* d = (SkPMColor*)dst;
    SkPMColor* d = (SkPMColor*)dst;
@@ -321,6 +347,8 @@ static FromColorProc ChooseFromColorProc(const SkBitmap& bitmap) {
            return FromColor_D565;
            return FromColor_D565;
        case kAlpha_8_SkColorType:
        case kAlpha_8_SkColorType:
            return FromColor_DA8;
            return FromColor_DA8;
        case kRGBA_F16_SkColorType:
            return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_F16 : FromColor_F16_Raw;
        default:
        default:
            break;
            break;
    }
    }
@@ -351,8 +379,7 @@ bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int


    dstBitmap.notifyPixelsChanged();
    dstBitmap.notifyPixelsChanged();


    env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array),
    env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), JNI_ABORT);
                                 JNI_ABORT);
    return true;
    return true;
}
}


@@ -361,6 +388,24 @@ bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int
typedef void (*ToColorProc)(SkColor dst[], const void* src, int width,
typedef void (*ToColorProc)(SkColor dst[], const void* src, int width,
                            SkColorTable*);
                            SkColorTable*);


static void ToColor_F16_Alpha(SkColor dst[], const void* src, int width,
                              SkColorTable*) {
    SkASSERT(width > 0);
    uint64_t* s = (uint64_t*)src;
    do {
        *dst++ = SkPM4f::FromF16((const uint16_t*) s++).unpremul().toSkColor();
    } while (--width != 0);
}

static void ToColor_F16_Raw(SkColor dst[], const void* src, int width,
                            SkColorTable*) {
    SkASSERT(width > 0);
    uint64_t* s = (uint64_t*)src;
    do {
        *dst++ = Sk4f_toS32(swizzle_rb(SkHalfToFloat_finite_ftz(*s++)));
    } while (--width != 0);
}

static void ToColor_S32_Alpha(SkColor dst[], const void* src, int width,
static void ToColor_S32_Alpha(SkColor dst[], const void* src, int width,
                              SkColorTable*) {
                              SkColorTable*) {
    SkASSERT(width > 0);
    SkASSERT(width > 0);
@@ -520,6 +565,17 @@ static ToColorProc ChooseToColorProc(const SkBitmap& src) {
            }
            }
        case kAlpha_8_SkColorType:
        case kAlpha_8_SkColorType:
            return ToColor_SA8;
            return ToColor_SA8;
        case kRGBA_F16_SkColorType:
            switch (src.alphaType()) {
                case kOpaque_SkAlphaType:
                    return ToColor_F16_Raw;
                case kPremul_SkAlphaType:
                    return ToColor_F16_Alpha;
                case kUnpremul_SkAlphaType:
                    return ToColor_F16_Raw;
                default:
                    return NULL;
            }
        default:
        default:
            break;
            break;
    }
    }
@@ -554,7 +610,7 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,


    SkBitmap bitmap;
    SkBitmap bitmap;
    bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType,
    bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType,
            GraphicsJNI::defaultColorSpace()));
            GraphicsJNI::colorSpaceForType(colorType)));


    sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL);
    sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL);
    if (!nativeBitmap) {
    if (!nativeBitmap) {
@@ -562,8 +618,7 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
    }
    }


    if (jColors != NULL) {
    if (jColors != NULL) {
        GraphicsJNI::SetPixels(env, jColors, offset, stride,
        GraphicsJNI::SetPixels(env, jColors, offset, stride, 0, 0, width, height, bitmap);
                0, 0, width, height, bitmap);
    }
    }


    return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable));
    return createBitmap(env, nativeBitmap.release(), getPremulBitmapCreateFlags(isMutable));
@@ -790,6 +845,7 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
    const int         density = p->readInt32();
    const int         density = p->readInt32();


    if (kN32_SkColorType != colorType &&
    if (kN32_SkColorType != colorType &&
            kRGBA_F16_SkColorType != colorType &&
            kRGB_565_SkColorType != colorType &&
            kRGB_565_SkColorType != colorType &&
            kARGB_4444_SkColorType != colorType &&
            kARGB_4444_SkColorType != colorType &&
            kIndex_8_SkColorType != colorType &&
            kIndex_8_SkColorType != colorType &&
@@ -800,8 +856,15 @@ static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {


    std::unique_ptr<SkBitmap> bitmap(new SkBitmap);
    std::unique_ptr<SkBitmap> bitmap(new SkBitmap);


    if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType,
    sk_sp<SkColorSpace> colorSpace;
            isSRGB ? SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named) : nullptr), rowBytes)) {
    if (kRGBA_F16_SkColorType == colorType) {
        colorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named);
    } else {
        colorSpace = isSRGB ? SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named) : nullptr;
    }

    if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType, colorSpace),
            rowBytes)) {
        return NULL;
        return NULL;
    }
    }


+4 −3
Original line number Original line Diff line number Diff line
@@ -283,8 +283,8 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding


    // Create the codec.
    // Create the codec.
    NinePatchPeeker peeker;
    NinePatchPeeker peeker;
    std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(streamDeleter.release(),
    std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(
            &peeker));
            streamDeleter.release(), &peeker));
    if (!codec.get()) {
    if (!codec.get()) {
        return nullObjectReturn("SkAndroidCodec::NewFromStream returned null");
        return nullObjectReturn("SkAndroidCodec::NewFromStream returned null");
    }
    }
@@ -399,7 +399,8 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding


    // We always decode to sRGB, but only mark the bitmap with a color space if linear
    // We always decode to sRGB, but only mark the bitmap with a color space if linear
    // blending is enabled.
    // blending is enabled.
    SkImageInfo bitmapInfo = decodeInfo.makeColorSpace(GraphicsJNI::defaultColorSpace());
    SkImageInfo bitmapInfo = decodeInfo.makeColorSpace(
            GraphicsJNI::colorSpaceForType(decodeColorType));
    if (decodeColorType == kGray_8_SkColorType) {
    if (decodeColorType == kGray_8_SkColorType) {
        // The legacy implementation of BitmapFactory used kAlpha8 for
        // The legacy implementation of BitmapFactory used kAlpha8 for
        // grayscale images (before kGray8 existed).  While the codec
        // grayscale images (before kGray8 existed).  While the codec
Loading