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

Commit 48340af0 authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

Merge "Don't assume all FP16 bitmaps are linearly encoded."

parents f1a4991d 6e35e637
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <hwui/Paint.h>
#include <hwui/Bitmap.h>
#include <renderthread/RenderProxy.h>
#include <utils/Color.h>

#include <android_runtime/android_hardware_HardwareBuffer.h>

@@ -602,6 +603,14 @@ static jint Bitmap_getGenerationId(JNIEnv* env, jobject, jlong bitmapHandle) {
    return static_cast<jint>(bitmap->getGenerationID());
}

static jboolean Bitmap_isConfigF16(JNIEnv* env, jobject, jlong bitmapHandle) {
    LocalScopedBitmap bitmap(bitmapHandle);
    if (bitmap->info().colorType() == kRGBA_F16_SkColorType) {
        return JNI_TRUE;
    }
    return JNI_FALSE;
}

static jboolean Bitmap_isPremultiplied(JNIEnv* env, jobject, jlong bitmapHandle) {
    LocalScopedBitmap bitmap(bitmapHandle);
    if (bitmap->info().alphaType() == kPremul_SkAlphaType) {
@@ -1120,7 +1129,8 @@ static jobject Bitmap_createHardwareBitmap(JNIEnv* env, jobject, jobject graphic
    sp<GraphicBuffer> buffer(graphicBufferForJavaObject(env, graphicBuffer));
    // To support any color space, we need to pass an additional ColorSpace argument to
    // java Bitmap.createHardwareBitmap.
    sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer, SkColorSpace::MakeSRGB());
    SkColorType ct = uirenderer::PixelFormatToColorType(buffer->getPixelFormat());
    sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer, ct, SkColorSpace::MakeSRGB());
    if (!bitmap.get()) {
        ALOGW("failed to create hardware bitmap from graphic buffer");
        return NULL;
@@ -1133,7 +1143,8 @@ static jobject Bitmap_wrapHardwareBufferBitmap(JNIEnv* env, jobject, jobject har
    AHardwareBuffer* hwBuf = android_hardware_HardwareBuffer_getNativeHardwareBuffer(env,
        hardwareBuffer);
    sp<GraphicBuffer> buffer(AHardwareBuffer_to_GraphicBuffer(hwBuf));
    sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer,
    SkColorType ct = uirenderer::PixelFormatToColorType(buffer->getPixelFormat());
    sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer, ct,
            GraphicsJNI::getNativeColorSpace(colorSpacePtr));
    if (!bitmap.get()) {
        ALOGW("failed to create hardware bitmap from hardware buffer");
@@ -1193,6 +1204,7 @@ static const JNINativeMethod gBitmapMethods[] = {
    {   "nativeErase",              "(JJJ)V", (void*)Bitmap_eraseLong },
    {   "nativeRowBytes",           "(J)I", (void*)Bitmap_rowBytes },
    {   "nativeConfig",             "(J)I", (void*)Bitmap_config },
    {   "nativeIsConfigF16",        "(J)Z", (void*)Bitmap_isConfigF16 },
    {   "nativeHasAlpha",           "(J)Z", (void*)Bitmap_hasAlpha },
    {   "nativeIsPremultiplied",    "(J)Z", (void*)Bitmap_isPremultiplied},
    {   "nativeSetHasAlpha",        "(JZZ)V", (void*)Bitmap_setHasAlpha},
+2 −1
Original line number Diff line number Diff line
@@ -1038,8 +1038,9 @@ static jobject android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode(
        // Continue I guess?
    }

    SkColorType ct = uirenderer::PixelFormatToColorType(buffer->getPixelFormat());
    sk_sp<SkColorSpace> cs = uirenderer::DataSpaceToColorSpace(bufferItem.mDataSpace);
    sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer, cs);
    sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer, ct, cs);
    return bitmap::createBitmap(env, bitmap.release(),
            android::bitmap::kBitmapCreateFlag_Premultiplied);
}
+14 −11
Original line number Diff line number Diff line
@@ -1711,20 +1711,22 @@ public final class Bitmap implements Parcelable {
     */
    @Nullable
    public final ColorSpace getColorSpace() {
        // A reconfigure can change the configuration and rgba16f is
        // always linear scRGB at this time
        if (getConfig() == Config.RGBA_F16) {
            // Reset the color space for potential future reconfigurations
            mColorSpace = null;
            return ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB);
        }

        checkRecycled("getColorSpace called on a recycled bitmap");
        // Cache the color space retrieval since it can be fairly expensive
        if (mColorSpace == null) {
            if (nativeIsConfigF16(mNativePtr)) {
                // an F16 bitmaps is intended to always be linear extended, but due to
                // inconsistencies in Bitmap.create() functions it is possible to have
                // rendered into a bitmap in non-linear sRGB.
                if (nativeIsSRGB(mNativePtr)) {
                mColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
            } else if (getConfig() == Config.HARDWARE && nativeIsSRGBLinear(mNativePtr)) {
                    mColorSpace = ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB);
                } else {
                    mColorSpace = ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB);
                }
            } else if (nativeIsSRGB(mNativePtr)) {
                mColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
            } else if (nativeIsSRGBLinear(mNativePtr)) {
                mColorSpace = ColorSpace.get(ColorSpace.Named.LINEAR_SRGB);
            } else {
                float[] xyz = new float[9];
                float[] params = new float[7];
@@ -2127,6 +2129,7 @@ public final class Bitmap implements Parcelable {
    private static native void nativeErase(long nativeBitmap, long colorSpacePtr, long color);
    private static native int nativeRowBytes(long nativeBitmap);
    private static native int nativeConfig(long nativeBitmap);
    private static native boolean nativeIsConfigF16(long nativeBitmap);

    private static native int nativeGetPixel(long nativeBitmap, int x, int y);
    private static native void nativeGetPixels(long nativeBitmap, int[] pixels,
+7 −11
Original line number Diff line number Diff line
@@ -164,15 +164,11 @@ static SkBitmap makeHwCompatible(const FormatInfo& format, const SkBitmap& sourc
        const SkImageInfo& info = source.info();
        bitmap.allocPixels(
                SkImageInfo::MakeN32(info.width(), info.height(), info.alphaType(), nullptr));
        bitmap.eraseColor(0);
        if (info.colorType() == kRGBA_F16_SkColorType) {
            // Drawing RGBA_F16 onto ARGB_8888 is not supported
            source.readPixels(bitmap.info().makeColorSpace(SkColorSpace::MakeSRGB()),
                              bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
        } else {

        SkCanvas canvas(bitmap);
        canvas.drawColor(0);
        canvas.drawBitmap(source, 0.0f, 0.0f, nullptr);
        }

        return bitmap;
    }
}
@@ -253,8 +249,8 @@ sk_sp<Bitmap> HardwareBitmapUploader::allocateHardwareBitmap(const SkBitmap& sou
        eglDestroySyncKHR(display, fence);
    }

    return Bitmap::createFrom(buffer.get(), bitmap.refColorSpace(), bitmap.alphaType(),
                              Bitmap::computePalette(bitmap));
    return Bitmap::createFrom(buffer.get(), bitmap.colorType(), bitmap.refColorSpace(),
                              bitmap.alphaType(), Bitmap::computePalette(bitmap));
}

void HardwareBitmapUploader::terminate() {
+4 −5
Original line number Diff line number Diff line
@@ -133,12 +133,11 @@ sk_sp<Bitmap> Bitmap::createFrom(const SkImageInfo& info, SkPixelRef& pixelRef)
}


sk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer, sk_sp<SkColorSpace> colorSpace,
                                 SkAlphaType alphaType, BitmapPalette palette) {
    // As we will be effectively texture-sampling the buffer (using either EGL or Vulkan), we can
    // view the format as RGBA8888.
sk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer, SkColorType colorType,
                                 sk_sp<SkColorSpace> colorSpace, SkAlphaType alphaType,
                                 BitmapPalette palette) {
    SkImageInfo info = SkImageInfo::Make(graphicBuffer->getWidth(), graphicBuffer->getHeight(),
                                         kRGBA_8888_SkColorType, alphaType, colorSpace);
                                         colorType, alphaType, colorSpace);
    return sk_sp<Bitmap>(new Bitmap(graphicBuffer.get(), info, palette));
}

Loading