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

Commit e84cc9ea authored by Alec Mouri's avatar Alec Mouri
Browse files

Correctly render ISO gainmapped images

* Apply the gainmap in reverse when using an HDR base image
* Support alternative primaries
* Nudge the guards that optimize away applying the gainmap shader

Bug: 349357636
Flag: com.android.graphics.hwui.flags.iso_gainmap_apis
Test: GainmapTests
Change-Id: I230a765feddb306330e643e6ead8e62719f49ee5
parent 06af5c8f
Loading
Loading
Loading
Loading
+7 −12
Original line number Diff line number Diff line
@@ -622,18 +622,13 @@ bool SkiaCanvas::useGainmapShader(Bitmap& bitmap) {
    auto colorSpace = info.colorSpace();
    // If we don't have a colorspace, we can't apply a gainmap
    if (!colorSpace) return false;
    skcms_TransferFunction tfn;
    colorSpace->transferFn(&tfn);

    auto transferType = skcms_TransferFunction_getType(&tfn);
    switch (transferType) {
        case skcms_TFType_HLGish:
        case skcms_TFType_HLGinvish:
        case skcms_TFType_PQish:
            return true;
        case skcms_TFType_Invalid:
        case skcms_TFType_sRGBish:
            return false;

    const float targetRatio = uirenderer::getTargetHdrSdrRatio(colorSpace);

    if (bitmap.gainmap()->info.fBaseImageType == SkGainmapInfo::BaseImageType::kHDR) {
        return targetRatio < bitmap.gainmap()->info.fDisplayRatioHdr;
    } else {
        return targetRatio > bitmap.gainmap()->info.fDisplayRatioSdr;
    }
}

+12 −3
Original line number Diff line number Diff line
@@ -73,7 +73,9 @@ void DrawGainmapBitmap(SkCanvas* c, const sk_sp<const SkImage>& image, const SkR
#ifdef __ANDROID__
    auto destColorspace = c->imageInfo().refColorSpace();
    float targetSdrHdrRatio = getTargetHdrSdrRatio(destColorspace.get());
    if (targetSdrHdrRatio > 1.f && gainmapImage) {
    const bool baseImageHdr = gainmapInfo.fBaseImageType == SkGainmapInfo::BaseImageType::kHDR;
    if (gainmapImage && ((baseImageHdr && targetSdrHdrRatio < gainmapInfo.fDisplayRatioHdr) ||
                         (!baseImageHdr && targetSdrHdrRatio > gainmapInfo.fDisplayRatioSdr))) {
        SkPaint gainmapPaint = *paint;
        float sX = gainmapImage->width() / (float)image->width();
        float sY = gainmapImage->height() / (float)image->height();
@@ -183,7 +185,10 @@ private:
                baseImage->colorSpace() ? baseImage->refColorSpace() : SkColorSpace::MakeSRGB();

        // Determine the color space in which the gainmap math is to be applied.
        sk_sp<SkColorSpace> gainmapMathColorSpace = baseColorSpace->makeLinearGamma();
        sk_sp<SkColorSpace> gainmapMathColorSpace =
                mGainmapInfo.fGainmapMathColorSpace
                        ? mGainmapInfo.fGainmapMathColorSpace->makeLinearGamma()
                        : baseColorSpace->makeLinearGamma();

        // Create a color filter to transform from the base image's color space to the color space
        // in which the gainmap is to be applied.
@@ -266,6 +271,10 @@ private:
                    W = 1.f;
                }
            }

            if (mGainmapInfo.fBaseImageType == SkGainmapInfo::BaseImageType::kHDR) {
                W -= 1.f;
            }
            mBuilder.uniform("W") = W;
            uniforms = mBuilder.uniforms();
        }