Merge "Add new RGBA_F16 bitmap config"

This commit is contained in:
TreeHugger Robot
2016-12-16 19:02:03 +00:00
committed by Android (Google) Code Review
18 changed files with 412 additions and 134 deletions

View File

@@ -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(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(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);
@@ -11833,6 +11835,7 @@ package android.graphics {
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 HARDWARE;
enum_constant public static final android.graphics.Bitmap.Config RGBA_F16;
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.ColorSpace.Renderer showWhitePoint(boolean);
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 {
@@ -12727,7 +12731,9 @@ package android.graphics {
field public static final deprecated int RGBA_4444 = 7; // 0x7
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_F16 = 22; // 0x16
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 int RGB_565 = 4; // 0x4
field public static final int RGB_888 = 3; // 0x3
@@ -61421,31 +61427,31 @@ package java.util.concurrent {
ctor public CopyOnWriteArrayList();
ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
ctor public CopyOnWriteArrayList(E[]);
method public synchronized boolean add(E);
method public synchronized void add(int, E);
method public synchronized boolean addAll(java.util.Collection<? extends E>);
method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
method public synchronized boolean addIfAbsent(E);
method public synchronized void clear();
method public boolean add(E);
method public void add(int, E);
method public boolean addAll(java.util.Collection<? extends E>);
method public boolean addAll(int, java.util.Collection<? extends E>);
method public int addAllAbsent(java.util.Collection<? extends E>);
method public boolean addIfAbsent(E);
method public void clear();
method public java.lang.Object clone();
method public boolean contains(java.lang.Object);
method public boolean containsAll(java.util.Collection<?>);
method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
method public int indexOf(E, int);
method public int indexOf(java.lang.Object);
method public int indexOf(E, int);
method public boolean isEmpty();
method public java.util.Iterator<E> iterator();
method public int lastIndexOf(E, int);
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 synchronized E remove(int);
method public synchronized boolean remove(java.lang.Object);
method public synchronized boolean removeAll(java.util.Collection<?>);
method public synchronized boolean retainAll(java.util.Collection<?>);
method public synchronized E set(int, E);
method public java.util.ListIterator<E> listIterator(int);
method public E remove(int);
method public boolean remove(java.lang.Object);
method public boolean removeAll(java.util.Collection<?>);
method public boolean retainAll(java.util.Collection<?>);
method public E set(int, E);
method public int size();
method public java.util.List<E> subList(int, int);
method public java.lang.Object[] toArray();

View File

@@ -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(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(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);
@@ -12326,6 +12328,7 @@ package android.graphics {
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 HARDWARE;
enum_constant public static final android.graphics.Bitmap.Config RGBA_F16;
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.ColorSpace.Renderer showWhitePoint(boolean);
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 {
@@ -13220,7 +13224,9 @@ package android.graphics {
field public static final deprecated int RGBA_4444 = 7; // 0x7
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_F16 = 22; // 0x16
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 int RGB_565 = 4; // 0x4
field public static final int RGB_888 = 3; // 0x3
@@ -64944,31 +64950,31 @@ package java.util.concurrent {
ctor public CopyOnWriteArrayList();
ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
ctor public CopyOnWriteArrayList(E[]);
method public synchronized boolean add(E);
method public synchronized void add(int, E);
method public synchronized boolean addAll(java.util.Collection<? extends E>);
method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
method public synchronized boolean addIfAbsent(E);
method public synchronized void clear();
method public boolean add(E);
method public void add(int, E);
method public boolean addAll(java.util.Collection<? extends E>);
method public boolean addAll(int, java.util.Collection<? extends E>);
method public int addAllAbsent(java.util.Collection<? extends E>);
method public boolean addIfAbsent(E);
method public void clear();
method public java.lang.Object clone();
method public boolean contains(java.lang.Object);
method public boolean containsAll(java.util.Collection<?>);
method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
method public int indexOf(E, int);
method public int indexOf(java.lang.Object);
method public int indexOf(E, int);
method public boolean isEmpty();
method public java.util.Iterator<E> iterator();
method public int lastIndexOf(E, int);
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 synchronized E remove(int);
method public synchronized boolean remove(java.lang.Object);
method public synchronized boolean removeAll(java.util.Collection<?>);
method public synchronized boolean retainAll(java.util.Collection<?>);
method public synchronized E set(int, E);
method public java.util.ListIterator<E> listIterator(int);
method public E remove(int);
method public boolean remove(java.lang.Object);
method public boolean removeAll(java.util.Collection<?>);
method public boolean retainAll(java.util.Collection<?>);
method public E set(int, E);
method public int size();
method public java.util.List<E> subList(int, int);
method public java.lang.Object[] toArray();

View File

@@ -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(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(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);
@@ -11864,6 +11866,7 @@ package android.graphics {
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 HARDWARE;
enum_constant public static final android.graphics.Bitmap.Config RGBA_F16;
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.ColorSpace.Renderer showWhitePoint(boolean);
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 {
@@ -12758,7 +12762,9 @@ package android.graphics {
field public static final deprecated int RGBA_4444 = 7; // 0x7
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_F16 = 22; // 0x16
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 int RGB_565 = 4; // 0x4
field public static final int RGB_888 = 3; // 0x3
@@ -61731,31 +61737,31 @@ package java.util.concurrent {
ctor public CopyOnWriteArrayList();
ctor public CopyOnWriteArrayList(java.util.Collection<? extends E>);
ctor public CopyOnWriteArrayList(E[]);
method public synchronized boolean add(E);
method public synchronized void add(int, E);
method public synchronized boolean addAll(java.util.Collection<? extends E>);
method public synchronized boolean addAll(int, java.util.Collection<? extends E>);
method public synchronized int addAllAbsent(java.util.Collection<? extends E>);
method public synchronized boolean addIfAbsent(E);
method public synchronized void clear();
method public boolean add(E);
method public void add(int, E);
method public boolean addAll(java.util.Collection<? extends E>);
method public boolean addAll(int, java.util.Collection<? extends E>);
method public int addAllAbsent(java.util.Collection<? extends E>);
method public boolean addIfAbsent(E);
method public void clear();
method public java.lang.Object clone();
method public boolean contains(java.lang.Object);
method public boolean containsAll(java.util.Collection<?>);
method public void forEach(java.util.function.Consumer<? super E>);
method public E get(int);
method public int indexOf(E, int);
method public int indexOf(java.lang.Object);
method public int indexOf(E, int);
method public boolean isEmpty();
method public java.util.Iterator<E> iterator();
method public int lastIndexOf(E, int);
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 synchronized E remove(int);
method public synchronized boolean remove(java.lang.Object);
method public synchronized boolean removeAll(java.util.Collection<?>);
method public synchronized boolean retainAll(java.util.Collection<?>);
method public synchronized E set(int, E);
method public java.util.ListIterator<E> listIterator(int);
method public E remove(int);
method public boolean remove(java.lang.Object);
method public boolean removeAll(java.util.Collection<?>);
method public boolean retainAll(java.util.Collection<?>);
method public E set(int, E);
method public int size();
method public java.util.List<E> subList(int, int);
method public java.lang.Object[] toArray();

View File

@@ -5,7 +5,11 @@
#include "SkPixelRef.h"
#include "SkImageEncoder.h"
#include "SkImageInfo.h"
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkHalf.h"
#include "SkPM4f.h"
#include "SkPM4fPriv.h"
#include "GraphicsJNI.h"
#include "SkDither.h"
#include "SkUnPreMultiply.h"
@@ -232,6 +236,28 @@ using namespace android::bitmap;
typedef void (*FromColorProc)(void* dst, const SkColor src[], int width,
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,
int, int) {
SkPMColor* d = (SkPMColor*)dst;
@@ -321,6 +347,8 @@ static FromColorProc ChooseFromColorProc(const SkBitmap& bitmap) {
return FromColor_D565;
case kAlpha_8_SkColorType:
return FromColor_DA8;
case kRGBA_F16_SkColorType:
return bitmap.alphaType() == kPremul_SkAlphaType ? FromColor_F16 : FromColor_F16_Raw;
default:
break;
}
@@ -351,8 +379,7 @@ bool GraphicsJNI::SetPixels(JNIEnv* env, jintArray srcColors, int srcOffset, int
dstBitmap.notifyPixelsChanged();
env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array),
JNI_ABORT);
env->ReleaseIntArrayElements(srcColors, const_cast<jint*>(array), JNI_ABORT);
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,
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,
SkColorTable*) {
SkASSERT(width > 0);
@@ -520,6 +565,17 @@ static ToColorProc ChooseToColorProc(const SkBitmap& src) {
}
case kAlpha_8_SkColorType:
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:
break;
}
@@ -554,7 +610,7 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
SkBitmap bitmap;
bitmap.setInfo(SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType,
GraphicsJNI::defaultColorSpace()));
GraphicsJNI::colorSpaceForType(colorType)));
sk_sp<Bitmap> nativeBitmap = Bitmap::allocateHeapBitmap(&bitmap, NULL);
if (!nativeBitmap) {
@@ -562,8 +618,7 @@ static jobject Bitmap_creator(JNIEnv* env, jobject, jintArray jColors,
}
if (jColors != NULL) {
GraphicsJNI::SetPixels(env, jColors, offset, stride,
0, 0, width, height, bitmap);
GraphicsJNI::SetPixels(env, jColors, offset, stride, 0, 0, width, height, bitmap);
}
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();
if (kN32_SkColorType != colorType &&
kRGBA_F16_SkColorType != colorType &&
kRGB_565_SkColorType != colorType &&
kARGB_4444_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);
if (!bitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType,
isSRGB ? SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named) : nullptr), rowBytes)) {
sk_sp<SkColorSpace> colorSpace;
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;
}

View File

@@ -283,8 +283,8 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
// Create the codec.
NinePatchPeeker peeker;
std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(streamDeleter.release(),
&peeker));
std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(
streamDeleter.release(), &peeker));
if (!codec.get()) {
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
// blending is enabled.
SkImageInfo bitmapInfo = decodeInfo.makeColorSpace(GraphicsJNI::defaultColorSpace());
SkImageInfo bitmapInfo = decodeInfo.makeColorSpace(
GraphicsJNI::colorSpaceForType(decodeColorType));
if (decodeColorType == kGray_8_SkColorType) {
// The legacy implementation of BitmapFactory used kAlpha8 for
// grayscale images (before kGray8 existed). While the codec

View File

@@ -297,13 +297,16 @@ enum LegacyBitmapConfig {
kRGB_565_LegacyBitmapConfig = 3,
kARGB_4444_LegacyBitmapConfig = 4,
kARGB_8888_LegacyBitmapConfig = 5,
kHardware_LegacyBitmapConfig = 6,
kRGBA_16F_LegacyBitmapConfig = 6,
kHardware_LegacyBitmapConfig = 7,
kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig
};
jint GraphicsJNI::colorTypeToLegacyBitmapConfig(SkColorType colorType) {
switch (colorType) {
case kRGBA_F16_SkColorType:
return kRGBA_16F_LegacyBitmapConfig;
case kN32_SkColorType:
return kARGB_8888_LegacyBitmapConfig;
case kARGB_4444_SkColorType:
@@ -329,6 +332,7 @@ SkColorType GraphicsJNI::legacyBitmapConfigToColorType(jint legacyConfig) {
kRGB_565_SkColorType,
kARGB_4444_SkColorType,
kN32_SkColorType,
kRGBA_F16_SkColorType,
kN32_SkColorType
};
@@ -458,6 +462,19 @@ sk_sp<SkColorSpace> GraphicsJNI::defaultColorSpace() {
#endif
}
sk_sp<SkColorSpace> GraphicsJNI::linearColorSpace() {
return SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named);
}
sk_sp<SkColorSpace> GraphicsJNI::colorSpaceForType(SkColorType type) {
switch (type) {
case kRGBA_F16_SkColorType:
return linearColorSpace();
default:
return defaultColorSpace();
}
}
///////////////////////////////////////////////////////////////////////////////
bool HeapAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
mStorage = android::Bitmap::allocateHeapBitmap(bitmap, ctable);

View File

@@ -95,6 +95,8 @@ public:
const SkBitmap& dstBitmap);
static sk_sp<SkColorSpace> defaultColorSpace();
static sk_sp<SkColorSpace> linearColorSpace();
static sk_sp<SkColorSpace> colorSpaceForType(SkColorType type);
};
class HeapAllocator : public SkBRDAllocator {

View File

@@ -142,6 +142,10 @@ static inline SkColorType convertPixelFormat(int32_t format) {
return kN32_SkColorType;
case PIXEL_FORMAT_RGBX_8888:
return kN32_SkColorType;
case PIXEL_FORMAT_RGBA_FP16:
return kRGBA_F16_SkColorType;
case PIXEL_FORMAT_RGBX_FP16:
return kRGBA_F16_SkColorType;
case PIXEL_FORMAT_RGB_565:
return kRGB_565_SkColorType;
default:

View File

@@ -168,6 +168,8 @@ PublicFormat android_view_Surface_mapHalFormatDataspaceToPublicFormat(
switch(format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGBA_FP16:
case HAL_PIXEL_FORMAT_RGBX_FP16:
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_Y8:
@@ -283,6 +285,8 @@ static inline SkColorType convertPixelFormat(PixelFormat format) {
switch (format) {
case PIXEL_FORMAT_RGBX_8888: return kN32_SkColorType;
case PIXEL_FORMAT_RGBA_8888: return kN32_SkColorType;
case PIXEL_FORMAT_RGBX_FP16: return kRGBA_F16_SkColorType;
case PIXEL_FORMAT_RGBA_FP16: return kRGBA_F16_SkColorType;
case PIXEL_FORMAT_RGB_565: return kRGB_565_SkColorType;
default: return kUnknown_SkColorType;
}

View File

@@ -164,6 +164,16 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
alphaType = kPremul_SkAlphaType;
break;
}
case PIXEL_FORMAT_RGBX_FP16: {
colorType = kRGBA_F16_SkColorType;
alphaType = kOpaque_SkAlphaType;
break;
}
case PIXEL_FORMAT_RGBA_FP16: {
colorType = kRGBA_F16_SkColorType;
alphaType = kPremul_SkAlphaType;
break;
}
case PIXEL_FORMAT_RGB_565: {
colorType = kRGB_565_SkColorType;
alphaType = kOpaque_SkAlphaType;

View File

@@ -83,6 +83,14 @@ static inline SkImageInfo convertPixelFormat(const ANativeWindow_Buffer& buffer)
colorType = kN32_SkColorType;
alphaType = kOpaque_SkAlphaType;
break;
case WINDOW_FORMAT_RGBA_FP16:
colorType = kRGBA_F16_SkColorType;
alphaType = kPremul_SkAlphaType;
break;
case WINDOW_FORMAT_RGBX_FP16:
colorType = kRGBA_F16_SkColorType;
alphaType = kOpaque_SkAlphaType;
break;
case WINDOW_FORMAT_RGB_565:
colorType = kRGB_565_SkColorType;
alphaType = kOpaque_SkAlphaType;

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

View File

@@ -140,7 +140,7 @@ public final class Bitmap implements Parcelable {
* Native bitmap has been reconfigured, so set premult and cached
* width/height values
*/
// called from JNI
@SuppressWarnings("unused") // called from JNI
void reinit(int width, int height, boolean requestPremultiplied) {
mWidth = width;
mHeight = height;
@@ -465,6 +465,15 @@ public final class Bitmap implements Parcelable {
*/
ARGB_8888 (5),
/**
* Each pixels is stored on 8 bytes. Each channel (RGB and alpha
* for translucency) is stored as a
* {@link android.util.Half half-precision floating point value}.
*
* This configuration is particularly suited for wide-gamut and
* HDR content.
*/
RGBA_F16 (6),
/**
* Special configuration, when bitmap is stored only in graphic memory.
@@ -473,12 +482,12 @@ public final class Bitmap implements Parcelable {
* It is optimal for cases, when the only operation with the bitmap is to draw it on a
* screen.
*/
HARDWARE (6);
HARDWARE (7);
final int nativeInt;
private static Config sConfigs[] = {
null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, HARDWARE
null, ALPHA_8, null, RGB_565, ARGB_4444, ARGB_8888, RGBA_F16, HARDWARE
};
Config(int ni) {
@@ -760,6 +769,9 @@ public final class Bitmap implements Parcelable {
case ALPHA_8:
newConfig = Config.ALPHA_8;
break;
case RGBA_F16:
newConfig = Config.RGBA_F16;
break;
//noinspection deprecation
case ARGB_4444:
case ARGB_8888:
@@ -781,8 +793,13 @@ public final class Bitmap implements Parcelable {
neww = Math.round(deviceR.width());
newh = Math.round(deviceR.height());
bitmap = createBitmap(neww, newh, transformed ? Config.ARGB_8888 : newConfig,
transformed || source.hasAlpha());
Config transformedConfig = newConfig;
if (transformed) {
if (transformedConfig != Config.ARGB_8888 && transformedConfig != Config.RGBA_F16) {
transformedConfig = Config.ARGB_8888;
}
}
bitmap = createBitmap(neww, newh, transformedConfig, transformed || source.hasAlpha());
canvas.translate(-deviceR.left, -deviceR.top);
canvas.concat(m);
@@ -845,14 +862,14 @@ public final class Bitmap implements Parcelable {
* @param width The width of the bitmap
* @param height The height of the bitmap
* @param config The bitmap config to create.
* @param hasAlpha If the bitmap is ARGB_8888 this flag can be used to mark the
* bitmap as opaque. Doing so will clear the bitmap in black
* @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
* mark the bitmap as opaque. Doing so will clear the bitmap in black
* instead of transparent.
*
* @throws IllegalArgumentException if the width or height are <= 0, or if
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
*/
private static Bitmap createBitmap(int width, int height, Config config, boolean hasAlpha) {
public static Bitmap createBitmap(int width, int height, Config config, boolean hasAlpha) {
return createBitmap(null, width, height, config, hasAlpha);
}
@@ -865,14 +882,14 @@ public final class Bitmap implements Parcelable {
* @param width The width of the bitmap
* @param height The height of the bitmap
* @param config The bitmap config to create.
* @param hasAlpha If the bitmap is ARGB_8888 this flag can be used to mark the
* bitmap as opaque. Doing so will clear the bitmap in black
* @param hasAlpha If the bitmap is ARGB_8888 or RGBA_16F this flag can be used to
* mark the bitmap as opaque. Doing so will clear the bitmap in black
* instead of transparent.
*
* @throws IllegalArgumentException if the width or height are <= 0, or if
* Config is Config.HARDWARE, because hardware bitmaps are always immutable
*/
private static Bitmap createBitmap(DisplayMetrics display, int width, int height,
public static Bitmap createBitmap(DisplayMetrics display, int width, int height,
Config config, boolean hasAlpha) {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("width and height must be > 0");
@@ -885,7 +902,7 @@ public final class Bitmap implements Parcelable {
bm.mDensity = display.densityDpi;
}
bm.setHasAlpha(hasAlpha);
if (config == Config.ARGB_8888 && !hasAlpha) {
if ((config == Config.ARGB_8888 || config == Config.RGBA_F16) && !hasAlpha) {
nativeErase(bm.mNativePtr, 0xff000000);
}
// No need to initialize the bitmap to zeroes with other configs;
@@ -1526,7 +1543,7 @@ public final class Bitmap implements Parcelable {
/**
* <p>Replace pixels in the bitmap with the colors in the array. Each element
* in the array is a packed int prepresenting a non-premultiplied ARGB
* in the array is a packed int representing a non-premultiplied ARGB
* {@link Color}.</p>
*
* @param pixels The colors to write to the bitmap

View File

@@ -1670,6 +1670,28 @@ public abstract class ColorSpace {
return new float[] { xyY[0] / xyY[1], 1.0f, (1 - xyY[0] - xyY[1]) / xyY[1] };
}
/**
* Converts values from CIE xyY to CIE L*u*v*. Y is assumed to be 1 so the
* input xyY array only contains the x and y components. After this method
* returns, the xyY array contains the converted u and v components.
*
* @param xyY The xyY value to convert to XYZ, cannot be null,
* length must be a multiple of 2
*/
private static void xyYToUv(@NonNull @Size(multiple = 2) float[] xyY) {
for (int i = 0; i < xyY.length; i += 2) {
float x = xyY[i];
float y = xyY[i + 1];
float d = -2.0f * x + 12.0f * y + 3;
float u = (4.0f * x) / d;
float v = (9.0f * y) / d;
xyY[i] = u;
xyY[i + 1] = v;
}
}
/**
* <p>Computes the chromatic adaptation transform from the specified
* source white point to the specified destination white point.</p>
@@ -3162,10 +3184,10 @@ public abstract class ColorSpace {
/**
* <p>A color space renderer can be used to visualize and compare the gamut and
* white point of one or more color spaces. The output is an sRGB {@link Bitmap}
* showing a CIE 1931 xyY chromaticity diagram.</p>
* showing a CIE 1931 xyY or a CIE 1976 UCS chromaticity diagram.</p>
*
* <p>The following code snippet shows how to compare the {@link Named#SRGB}
* and {@link Named#DCI_P3} color spaces:</p>
* and {@link Named#DCI_P3} color spaces in a CIE 1931 diagram:</p>
*
* <pre class="prettyprint">
* Bitmap bitmap = ColorSpace.createRenderer()
@@ -3188,12 +3210,18 @@ public abstract class ColorSpace {
*/
public static class Renderer {
private static final int NATIVE_SIZE = 1440;
private static final float UCS_SCALE = 9.0f / 6.0f;
// Number of subdivision of the inside of the spectral locus
private static final int CHROMATICITY_RESOLUTION = 32;
private static final double ONE_THIRD = 1.0 / 3.0;
@IntRange(from = 128, to = Integer.MAX_VALUE)
private int mSize = 1024;
private boolean mShowWhitePoint = true;
private boolean mClip = false;
private boolean mUcs = false;
private final List<Pair<ColorSpace, Integer>> mColorSpaces = new ArrayList<>(2);
private final List<Point> mPoints = new ArrayList<>(0);
@@ -3240,6 +3268,35 @@ public abstract class ColorSpace {
return this;
}
/**
* <p>Defines whether the chromaticity diagram should use the uniform
* chromaticity scale (CIE 1976 UCS). When the uniform chromaticity scale
* is used, the distance between two points on the diagram is approximately
* proportional to the perceived color difference.</p>
*
* <p>The following code snippet shows how to enable the uniform chromaticity
* scale. The image below shows the result:</p>
* <pre class="prettyprint">
* Bitmap bitmap = ColorSpace.createRenderer()
* .uniformChromaticityScale(true)
* .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
* .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
* .render();
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_ucs.png" />
* <figcaption style="text-align: center;">CIE 1976 UCS diagram</figcaption>
* </p>
*
* @param ucs True to render the chromaticity diagram as the CIE 1976 UCS diagram
* @return This instance of {@link Renderer}
*/
@NonNull
public Renderer uniformChromaticityScale(boolean ucs) {
mUcs = ucs;
return this;
}
/**
* Sets the dimensions (width and height) in pixels of the output bitmap.
* The size must be at least 128px and defaults to 1024px.
@@ -3302,7 +3359,7 @@ public abstract class ColorSpace {
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison2.png" />
* <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
* <figcaption style="text-align: center;">sRGB, DCI-P3, ACES and scRGB</figcaption>
* </p>
*
* @param colorSpace The color space whose gamut to render on the diagram
@@ -3385,6 +3442,7 @@ public abstract class ColorSpace {
setTransform(canvas, width, height, primaries);
drawBox(canvas, width, height, paint, path);
setUcsTransform(canvas, height);
drawLocus(canvas, width, height, paint, path, primaries);
drawGamuts(canvas, width, height, paint, path, primaries, whitePoint);
drawPoints(canvas, width, height, paint);
@@ -3406,7 +3464,11 @@ public abstract class ColorSpace {
paint.setStyle(Paint.Style.FILL);
float radius = 4.0f / (mUcs ? UCS_SCALE : 1.0f);
float[] v = new float[3];
float[] xy = new float[2];
for (final Point point : mPoints) {
v[0] = point.mRgb[0];
v[1] = point.mRgb[1];
@@ -3415,10 +3477,13 @@ public abstract class ColorSpace {
paint.setColor(point.mColor);
// XYZ to xyY, assuming Y=1.0
// XYZ to xyY, assuming Y=1.0, then to L*u*v* if needed
float sum = v[0] + v[1] + v[2];
canvas.drawCircle(width * v[0] / sum, height - height * v[1] / sum,
4.0f, paint);
xy[0] = v[0] / sum;
xy[1] = v[1] / sum;
if (mUcs) xyYToUv(xy);
canvas.drawCircle(width * xy[0], height - height * xy[1], radius, paint);
}
}
@@ -3440,6 +3505,8 @@ public abstract class ColorSpace {
@NonNull Paint paint, @NonNull Path path,
@NonNull @Size(6) float[] primaries, @NonNull @Size(2) float[] whitePoint) {
float radius = 4.0f / (mUcs ? UCS_SCALE : 1.0f);
for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
ColorSpace colorSpace = item.first;
int color = item.second;
@@ -3447,7 +3514,7 @@ public abstract class ColorSpace {
if (colorSpace.getModel() != Model.RGB) continue;
Rgb rgb = (Rgb) colorSpace;
getPrimaries(rgb, primaries);
getPrimaries(rgb, primaries, mUcs);
path.rewind();
path.moveTo(width * primaries[0], height - height * primaries[1]);
@@ -3462,11 +3529,12 @@ public abstract class ColorSpace {
// Draw the white point
if (mShowWhitePoint) {
rgb.getWhitePoint(whitePoint);
if (mUcs) xyYToUv(whitePoint);
paint.setStyle(Paint.Style.FILL);
paint.setColor(color);
canvas.drawCircle(width * whitePoint[0], height - height * whitePoint[1],
4.0f, paint);
canvas.drawCircle(
width * whitePoint[0], height - height * whitePoint[1], radius, paint);
}
}
}
@@ -3477,10 +3545,12 @@ public abstract class ColorSpace {
*
* @param rgb The color space whose primaries to extract
* @param primaries A pre-allocated array of 6 floats that will hold the result
* @param asUcs True if the primaries should be returned in Luv, false for xyY
*/
@NonNull
@Size(6)
private static float[] getPrimaries(@NonNull Rgb rgb, @NonNull @Size(6) float[] primaries) {
private static float[] getPrimaries(@NonNull Rgb rgb,
@NonNull @Size(6) float[] primaries, boolean asUcs) {
// TODO: We should find a better way to handle these cases
if (rgb.equals(ColorSpace.get(Named.EXTENDED_SRGB)) ||
rgb.equals(ColorSpace.get(Named.LINEAR_EXTENDED_SRGB))) {
@@ -3490,9 +3560,11 @@ public abstract class ColorSpace {
primaries[3] = 1.24f;
primaries[4] = -0.23f;
primaries[5] = -0.57f;
return primaries;
} else {
rgb.getPrimaries(primaries);
}
return rgb.getPrimaries(primaries);
if (asUcs) xyYToUv(primaries);
return primaries;
}
/**
@@ -3513,7 +3585,13 @@ public abstract class ColorSpace {
int vertexCount = SPECTRUM_LOCUS_X.length * CHROMATICITY_RESOLUTION * 6;
float[] vertices = new float[vertexCount * 2];
int[] colors = new int[vertices.length];
computeChromaticityMesh(NATIVE_SIZE, NATIVE_SIZE, vertices, colors);
computeChromaticityMesh(vertices, colors);
if (mUcs) xyYToUv(vertices);
for (int i = 0; i < vertices.length; i += 2) {
vertices[i] *= width;
vertices[i + 1] = height - vertices[i + 1] * height;
}
// Draw the spectral locus
if (mClip && mColorSpaces.size() > 0) {
@@ -3522,7 +3600,8 @@ public abstract class ColorSpace {
if (colorSpace.getModel() != Model.RGB) continue;
Rgb rgb = (Rgb) colorSpace;
getPrimaries(rgb, primaries);
getPrimaries(rgb, primaries, mUcs);
break;
}
@@ -3559,6 +3638,7 @@ public abstract class ColorSpace {
}
path.close();
paint.setStrokeWidth(4.0f / (mUcs ? UCS_SCALE : 1.0f));
paint.setStyle(Paint.Style.STROKE);
paint.setColor(0xff000000);
canvas.drawPath(path, paint);
@@ -3576,25 +3656,38 @@ public abstract class ColorSpace {
*/
private void drawBox(@NonNull Canvas canvas, int width, int height, @NonNull Paint paint,
@NonNull Path path) {
int lineCount = 10;
float scale = 1.0f;
if (mUcs) {
lineCount = 7;
scale = UCS_SCALE;
}
// Draw the unit grid
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2.0f);
paint.setColor(0xffc0c0c0);
for (int i = 1; i <= 9; i++) {
canvas.drawLine(0.0f, height - (height * i / 10.0f),
0.9f * width, height - (height * i / 10.0f), paint);
canvas.drawLine(width * i / 10.0f, height,
width * i / 10.0f, 0.1f * height, paint);
for (int i = 1; i < lineCount - 1; i++) {
float v = i / 10.0f;
float x = (width * v) * scale;
float y = height - (height * v) * scale;
canvas.drawLine(0.0f, y, 0.9f * width, y, paint);
canvas.drawLine(x, height, x, 0.1f * height, paint);
}
// Draw tick marks
paint.setStrokeWidth(4.0f);
paint.setColor(0xff000000);
for (int i = 1; i <= 9; i++) {
canvas.drawLine(0.0f, height - (height * i / 10.0f),
width / 100.0f, height - (height * i / 10.0f), paint);
canvas.drawLine(width * i / 10.0f, height,
width * i / 10.0f, height - (height / 100.0f), paint);
for (int i = 1; i < lineCount - 1; i++) {
float v = i / 10.0f;
float x = (width * v) * scale;
float y = height - (height * v) * scale;
canvas.drawLine(0.0f, y, width / 100.0f, y, paint);
canvas.drawLine(x, height, x, height - (height / 100.0f), paint);
}
// Draw the axis labels
@@ -3603,14 +3696,15 @@ public abstract class ColorSpace {
paint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
Rect bounds = new Rect();
for (int i = 1; i < 9; i++) {
for (int i = 1; i < lineCount - 1; i++) {
String text = "0." + i;
paint.getTextBounds(text, 0, text.length(), bounds);
float y = height - (height * i / 10.0f);
canvas.drawText(text, -0.05f * width + 10, y + bounds.height() / 2.0f, paint);
float v = i / 10.0f;
float x = (width * v) * scale;
float y = height - (height * v) * scale;
float x = width * i / 10.0f;
canvas.drawText(text, -0.05f * width + 10, y + bounds.height() / 2.0f, paint);
canvas.drawText(text, x - bounds.width() / 2.0f,
height + bounds.height() + 16, paint);
}
@@ -3643,7 +3737,7 @@ public abstract class ColorSpace {
if (colorSpace.getModel() != Model.RGB) continue;
Rgb rgb = (Rgb) colorSpace;
getPrimaries(rgb, primaries);
getPrimaries(rgb, primaries, mUcs);
primariesBounds.left = Math.min(primariesBounds.left, primaries[4]);
primariesBounds.top = Math.min(primariesBounds.top, primaries[5]);
@@ -3651,26 +3745,42 @@ public abstract class ColorSpace {
primariesBounds.bottom = Math.max(primariesBounds.bottom, primaries[3]);
}
float max = mUcs ? 0.6f : 0.9f;
primariesBounds.left = Math.min(0.0f, primariesBounds.left);
primariesBounds.top = Math.min(0.0f, primariesBounds.top);
primariesBounds.right = Math.max(0.9f, primariesBounds.right);
primariesBounds.bottom = Math.max(0.9f, primariesBounds.bottom);
primariesBounds.right = Math.max(max, primariesBounds.right);
primariesBounds.bottom = Math.max(max, primariesBounds.bottom);
float scaleX = 0.9f / primariesBounds.width();
float scaleY = 0.9f / primariesBounds.height();
float scaleX = max / primariesBounds.width();
float scaleY = max / primariesBounds.height();
float scale = Math.min(scaleX, scaleY);
canvas.scale(mSize / (float) NATIVE_SIZE, mSize / (float) NATIVE_SIZE);
canvas.scale(scale, scale);
canvas.translate(
(primariesBounds.width() - 0.9f) * width / 2.0f,
(primariesBounds.height() - 0.9f) * height / 2.0f);
(primariesBounds.width() - max) * width / 2.0f,
(primariesBounds.height() - max) * height / 2.0f);
// The spectrum extends ~0.85 vertically and ~0.65 horizontally
// We shift the canvas a little bit to get nicer margins
canvas.translate(0.05f * width, -0.05f * height);
}
/**
* Computes and applies the Canvas transforms required to render the CIE
* 197 UCS chromaticity diagram.
*
* @param canvas The canvas to transform
* @param height Height in pixel of the final image
*/
private void setUcsTransform(@NonNull Canvas canvas, int height) {
if (mUcs) {
canvas.translate(0.0f, (height - height * UCS_SCALE));
canvas.scale(UCS_SCALE, UCS_SCALE);
}
}
// X coordinates of the spectral locus in CIE 1931
private static final float[] SPECTRUM_LOCUS_X = {
0.175596f, 0.172787f, 0.170806f, 0.170085f, 0.160343f,
@@ -3716,21 +3826,15 @@ public abstract class ColorSpace {
0.037799f, 0.029673f, 0.021547f, 0.013421f, 0.005295f
};
// Number of subdivision of the inside of the spectral locus
private static final int CHROMATICITY_RESOLUTION = 32;
private static final double ONE_THIRD = 1.0 / 3.0;
/**
* Computes a 2D mesh representation of the CIE 1931 chromaticity
* diagram.
*
* @param width Width in pixels of the mesh
* @param height Height in pixels of the mesh
* @param vertices Array of floats that will hold the mesh vertices
* @param colors Array of floats that will hold the mesh colors
*/
private static void computeChromaticityMesh(int width, int height,
@NonNull float[] vertices, @NonNull int[] colors) {
private static void computeChromaticityMesh(@NonNull float[] vertices,
@NonNull int[] colors) {
ColorSpace colorSpace = get(Named.SRGB);
@@ -3796,18 +3900,18 @@ public abstract class ColorSpace {
colorIndex += 6;
// Flip the mesh upside down to match Canvas' coordinates system
vertices[vertexIndex++] = v1x * width;
vertices[vertexIndex++] = height - v1y * height;
vertices[vertexIndex++] = v2x * width;
vertices[vertexIndex++] = height - v2y * height;
vertices[vertexIndex++] = v3x * width;
vertices[vertexIndex++] = height - v3y * height;
vertices[vertexIndex++] = v1x * width;
vertices[vertexIndex++] = height - v1y * height;
vertices[vertexIndex++] = v3x * width;
vertices[vertexIndex++] = height - v3y * height;
vertices[vertexIndex++] = v4x * width;
vertices[vertexIndex++] = height - v4y * height;
vertices[vertexIndex++] = v1x;
vertices[vertexIndex++] = v1y;
vertices[vertexIndex++] = v2x;
vertices[vertexIndex++] = v2y;
vertices[vertexIndex++] = v3x;
vertices[vertexIndex++] = v3y;
vertices[vertexIndex++] = v1x;
vertices[vertexIndex++] = v1y;
vertices[vertexIndex++] = v3x;
vertices[vertexIndex++] = v3y;
vertices[vertexIndex++] = v4x;
vertices[vertexIndex++] = v4y;
}
}
}

View File

@@ -22,13 +22,17 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class PixelFormat {
/** @hide */
@IntDef({UNKNOWN, TRANSLUCENT, TRANSPARENT, OPAQUE})
@Retention(RetentionPolicy.SOURCE)
public @interface Opacity {}
/* these constants need to match those in hardware/hardware.h */
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({RGBA_8888, RGBX_8888, RGBA_F16, RGBX_F16, RGB_888, RGB_565})
public @interface Format { };
// NOTE: these constants must match the values from graphics/common/x.x/types.hal
public static final int UNKNOWN = 0;
@@ -62,7 +66,6 @@ public class PixelFormat {
@Deprecated
public static final int RGB_332 = 0xB;
/**
* @deprecated use {@link android.graphics.ImageFormat#NV16
* ImageFormat.NV16} instead.
@@ -84,6 +87,9 @@ public class PixelFormat {
@Deprecated
public static final int YCbCr_422_I = 0x14;
public static final int RGBA_F16 = 0x16;
public static final int RGBX_F16 = 0x17;
/**
* @deprecated use {@link android.graphics.ImageFormat#JPEG
* ImageFormat.JPEG} instead.
@@ -91,7 +97,10 @@ public class PixelFormat {
@Deprecated
public static final int JPEG = 0x100;
public static void getPixelFormatInfo(int format, PixelFormat info) {
public int bytesPerPixel;
public int bitsPerPixel;
public static void getPixelFormatInfo(@Format int format, PixelFormat info) {
switch (format) {
case RGBA_8888:
case RGBX_8888:
@@ -124,18 +133,24 @@ public class PixelFormat {
info.bitsPerPixel = 12;
info.bytesPerPixel = 1;
break;
case RGBA_F16:
case RGBX_F16:
info.bitsPerPixel = 64;
info.bytesPerPixel = 8;
break;
default:
throw new IllegalArgumentException("unknown pixel format " + format);
}
}
public static boolean formatHasAlpha(int format) {
public static boolean formatHasAlpha(@Format int format) {
switch (format) {
case PixelFormat.A_8:
case PixelFormat.LA_88:
case PixelFormat.RGBA_4444:
case PixelFormat.RGBA_5551:
case PixelFormat.RGBA_8888:
case PixelFormat.RGBA_F16:
case PixelFormat.TRANSLUCENT:
case PixelFormat.TRANSPARENT:
return true;
@@ -143,9 +158,6 @@ public class PixelFormat {
return false;
}
public int bytesPerPixel;
public int bitsPerPixel;
/**
* Determine whether or not this is a public-visible and non-deprecated {@code format}.
*
@@ -159,12 +171,14 @@ public class PixelFormat {
*
* @hide
*/
public static boolean isPublicFormat(int format) {
public static boolean isPublicFormat(@Format int format) {
switch (format) {
case RGBA_8888:
case RGBX_8888:
case RGB_888:
case RGB_565:
case RGBA_F16:
case RGBX_F16:
return true;
}

View File

@@ -131,6 +131,13 @@ inline CopyResult copyTextureInto(Caches& caches, RenderState& renderState,
destWidth, destHeight, caches.maxTextureSize);
return CopyResult::DestinationInvalid;
}
// TODO: Add support for RGBA_F16 destinations
if (bitmap->colorType() == kRGBA_F16_SkColorType) {
ALOGW("Can't copy surface into bitmap, RGBA_F16 config is not supported");
return CopyResult::DestinationInvalid;
}
GLuint fbo = renderState.createFramebuffer();
if (!fbo) {
ALOGW("Could not obtain an FBO");

View File

@@ -225,6 +225,12 @@ void Texture::colorTypeToGlFormatAndType(const Caches& caches, SkColorType color
*outInternalFormat = GL_LUMINANCE;
*outType = GL_UNSIGNED_BYTE;
break;
case kRGBA_F16_SkColorType:
// This format is always linear
*outFormat = GL_RGBA;
*outInternalFormat = GL_RGBA16F;
*outType = GL_HALF_FLOAT;
break;
default:
LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", colorType);
break;

View File

@@ -108,6 +108,8 @@ static PixelFormat internalFormatToPixelFormat(GLint internalFormat) {
return PIXEL_FORMAT_RGBA_8888;
case GL_RGB:
return PIXEL_FORMAT_RGB_565;
case GL_RGBA16F:
return PIXEL_FORMAT_RGBA_FP16;
default:
LOG_ALWAYS_FATAL("Unsupported bitmap colorType: %d", internalFormat);
return PIXEL_FORMAT_UNKNOWN;
@@ -306,7 +308,8 @@ sk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, SkPixelRef& pixelRef)
sk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer) {
PixelFormat format = graphicBuffer->getPixelFormat();
if (!graphicBuffer.get() || format != PIXEL_FORMAT_RGBA_8888) {
if (!graphicBuffer.get() ||
(format != PIXEL_FORMAT_RGBA_8888 && format != PIXEL_FORMAT_RGBA_FP16)) {
return nullptr;
}
SkImageInfo info = SkImageInfo::Make(graphicBuffer->getWidth(), graphicBuffer->getHeight(),