Merge "Expand gainmap screencapture:" into main
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 12de82a..d563ad3 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -416,7 +416,6 @@
format = ANDROID_BITMAP_COMPRESS_FORMAT_PNG;
} else if (jpeg) {
format = ANDROID_BITMAP_COMPRESS_FORMAT_JPEG;
- captureArgs.attachGainmap = true;
}
// setThreadPoolMaxThreadCount(0) actually tells the kernel it's
diff --git a/core/java/android/window/ScreenCapture.java b/core/java/android/window/ScreenCapture.java
index 5446428..fc41307 100644
--- a/core/java/android/window/ScreenCapture.java
+++ b/core/java/android/window/ScreenCapture.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.graphics.ColorSpace;
+import android.graphics.Gainmap;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
@@ -184,17 +185,29 @@
* @hide
*/
public static class ScreenshotHardwareBuffer {
+ private static final float EPSILON = 1.0f / 64.0f;
+
private final HardwareBuffer mHardwareBuffer;
private final ColorSpace mColorSpace;
private final boolean mContainsSecureLayers;
private final boolean mContainsHdrLayers;
+ private final HardwareBuffer mGainmap;
+ private final float mHdrSdrRatio;
public ScreenshotHardwareBuffer(HardwareBuffer hardwareBuffer, ColorSpace colorSpace,
boolean containsSecureLayers, boolean containsHdrLayers) {
+ this(hardwareBuffer, colorSpace, containsSecureLayers, containsHdrLayers, null, 1.0f);
+ }
+
+ public ScreenshotHardwareBuffer(HardwareBuffer hardwareBuffer, ColorSpace colorSpace,
+ boolean containsSecureLayers, boolean containsHdrLayers, HardwareBuffer gainmap,
+ float hdrSdrRatio) {
mHardwareBuffer = hardwareBuffer;
mColorSpace = colorSpace;
mContainsSecureLayers = containsSecureLayers;
mContainsHdrLayers = containsHdrLayers;
+ mGainmap = gainmap;
+ mHdrSdrRatio = hdrSdrRatio;
}
/**
@@ -209,13 +222,12 @@
* @param containsHdrLayers Indicates whether this graphic buffer contains HDR content.
*/
private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
- int dataspace, boolean containsSecureLayers, boolean containsHdrLayers) {
+ int dataspace, boolean containsSecureLayers, boolean containsHdrLayers,
+ HardwareBuffer gainmap, float hdrSdrRatio) {
ColorSpace colorSpace = ColorSpace.getFromDataSpace(dataspace);
- return new ScreenshotHardwareBuffer(
- hardwareBuffer,
+ return new ScreenshotHardwareBuffer(hardwareBuffer,
colorSpace != null ? colorSpace : ColorSpace.get(ColorSpace.Named.SRGB),
- containsSecureLayers,
- containsHdrLayers);
+ containsSecureLayers, containsHdrLayers, gainmap, hdrSdrRatio);
}
public ColorSpace getColorSpace() {
@@ -259,7 +271,22 @@
Log.w(TAG, "Failed to take screenshot. Null screenshot object");
return null;
}
- return Bitmap.wrapHardwareBuffer(mHardwareBuffer, mColorSpace);
+
+ Bitmap bitmap = Bitmap.wrapHardwareBuffer(mHardwareBuffer, mColorSpace);
+ if (mGainmap != null) {
+ Bitmap gainmapBitmap = Bitmap.wrapHardwareBuffer(mGainmap, null);
+ Gainmap gainmap = new Gainmap(gainmapBitmap);
+ gainmap.setRatioMin(1.0f, 1.0f, 1.0f);
+ gainmap.setRatioMax(mHdrSdrRatio, mHdrSdrRatio, mHdrSdrRatio);
+ gainmap.setGamma(1.0f, 1.0f, 1.0f);
+ gainmap.setEpsilonSdr(EPSILON, EPSILON, EPSILON);
+ gainmap.setEpsilonHdr(EPSILON, EPSILON, EPSILON);
+ gainmap.setMinDisplayRatioForHdrTransition(1.0f);
+ gainmap.setDisplayRatioForFullHdr(mHdrSdrRatio);
+ bitmap.setGainmap(gainmap);
+ }
+
+ return bitmap;
}
}
diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp
index 1a52fb7..5657fa1 100644
--- a/core/jni/android_window_ScreenCapture.cpp
+++ b/core/jni/android_window_ScreenCapture.cpp
@@ -110,13 +110,19 @@
captureResults.fenceResult.value()->waitForever(LOG_TAG);
jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
env, captureResults.buffer->toAHardwareBuffer());
+ jobject jGainmap = nullptr;
+ if (captureResults.optionalGainMap) {
+ jGainmap = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
+ env, captureResults.optionalGainMap->toAHardwareBuffer());
+ }
jobject screenshotHardwareBuffer =
env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
gScreenshotHardwareBufferClassInfo.builder,
jhardwareBuffer,
static_cast<jint>(captureResults.capturedDataspace),
captureResults.capturedSecureLayers,
- captureResults.capturedHdrLayers);
+ captureResults.capturedHdrLayers, jGainmap,
+ captureResults.hdrSdrRatio);
checkAndClearException(env, "builder");
env->CallVoidMethod(consumer.get(), gConsumerClassInfo.accept, screenshotHardwareBuffer,
fenceStatus(captureResults.fenceResult));
@@ -340,7 +346,8 @@
MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
gScreenshotHardwareBufferClassInfo.builder =
GetStaticMethodIDOrDie(env, screenshotGraphicsBufferClazz, "createFromNative",
- "(Landroid/hardware/HardwareBuffer;IZZ)Landroid/window/"
+ "(Landroid/hardware/HardwareBuffer;IZZLandroid/hardware/"
+ "HardwareBuffer;F)Landroid/window/"
"ScreenCapture$ScreenshotHardwareBuffer;");
return err;
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index e2db2c9..677fd86 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -154,7 +154,10 @@
"libstatssocket_lazy",
"libtonemap",
],
- whole_static_libs: ["hwui_flags_cc_lib"],
+ whole_static_libs: [
+ "hwui_flags_cc_lib",
+ "libsurfaceflingerflags",
+ ],
},
host: {
static_libs: [
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index cc292d9..b1550b0 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -19,6 +19,7 @@
#include "HardwareBitmapUploader.h"
#include "Properties.h"
#ifdef __ANDROID__ // Layoutlib does not support render thread
+#include <com_android_graphics_surfaceflinger_flags.h>
#include <private/android/AHardwareBufferHelpers.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferMapper.h>
@@ -562,7 +563,7 @@
bool Bitmap::compress(JavaCompressFormat format, int32_t quality, SkWStream* stream) {
#ifdef __ANDROID__ // TODO: This isn't built for host for some reason?
- if (hasGainmap() && format == JavaCompressFormat::Jpeg) {
+ if (hasGainmap()) {
SkBitmap baseBitmap = getSkBitmap();
SkBitmap gainmapBitmap = gainmap()->bitmap->getSkBitmap();
if (gainmapBitmap.colorType() == SkColorType::kAlpha_8_SkColorType) {
@@ -572,12 +573,27 @@
greyGainmap.setPixelRef(sk_ref_sp(gainmapBitmap.pixelRef()), 0, 0);
gainmapBitmap = std::move(greyGainmap);
}
- SkJpegEncoder::Options options{.fQuality = quality};
- return SkJpegGainmapEncoder::EncodeHDRGM(stream, baseBitmap.pixmap(), options,
- gainmapBitmap.pixmap(), options, gainmap()->info);
+ switch (format) {
+ case JavaCompressFormat::Jpeg: {
+ SkJpegEncoder::Options options{.fQuality = quality};
+ return SkJpegGainmapEncoder::EncodeHDRGM(stream, baseBitmap.pixmap(), options,
+ gainmapBitmap.pixmap(), options,
+ gainmap()->info);
+ }
+ case JavaCompressFormat::Png: {
+ if (com::android::graphics::surfaceflinger::flags::true_hdr_screenshots()) {
+ SkGainmapInfo info = gainmap()->info;
+ SkPngEncoder::Options options{.fGainmap = &gainmapBitmap.pixmap(),
+ .fGainmapInfo = &info};
+ return SkPngEncoder::Encode(stream, baseBitmap.pixmap(), options);
+ }
+ // fallthrough if we're not supporting HDR screenshots
+ }
+ default:
+ ALOGI("Format: %d doesn't support gainmap compression!", format);
+ }
}
#endif
-
SkBitmap skbitmap;
getSkBitmap(&skbitmap);
return compress(skbitmap, format, quality, stream);