Merge "Use BLAST layer for screen rotation, surface freezer, and organizer" into sc-dev

This commit is contained in:
Chavi Weingarten
2021-04-16 00:30:11 +00:00
committed by Android (Google) Code Review
6 changed files with 103 additions and 32 deletions

View File

@@ -35,6 +35,7 @@ import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.Bitmap;
import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
@@ -188,6 +189,10 @@ public final class SurfaceControl implements Parcelable {
IBinder displayToken, int mode);
private static native void nativeReparent(long transactionObj, long nativeObject,
long newParentNativeObject);
private static native void nativeSetBuffer(long transactionObj, long nativeObject,
GraphicBuffer buffer);
private static native void nativeSetColorSpace(long transactionObj, long nativeObject,
int colorSpace);
private static native void nativeOverrideHdrTypes(IBinder displayToken, int[] modes);
@@ -3362,6 +3367,31 @@ public final class SurfaceControl implements Parcelable {
return this;
}
/**
* Set a buffer for a SurfaceControl. This can only be used for SurfaceControls that were
* created as type {@link #FX_SURFACE_BLAST}
*
* @hide
*/
public Transaction setBuffer(SurfaceControl sc, GraphicBuffer buffer) {
checkPreconditions(sc);
nativeSetBuffer(mNativeObject, sc.mNativeObject, buffer);
return this;
}
/**
* Set the color space for the SurfaceControl. The supported color spaces are SRGB
* and Display P3, other color spaces will be treated as SRGB. This can only be used for
* SurfaceControls that were created as type {@link #FX_SURFACE_BLAST}
*
* @hide
*/
public Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) {
checkPreconditions(sc);
nativeSetColorSpace(mNativeObject, sc.mNativeObject, colorSpace.getId());
return this;
}
/**
* Merge the other transaction into this transaction, clearing the
* other transaction as if it had been applied.

View File

@@ -30,6 +30,7 @@
#include <android/hardware/display/IDeviceProductInfoConstants.h>
#include <android/os/IInputConstants.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_graphics_GraphicBuffer.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
#include <android_runtime/android_view_Surface.h>
#include <android_runtime/android_view_SurfaceSession.h>
@@ -253,6 +254,15 @@ constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace
}
}
constexpr ui::Dataspace fromNamedColorSpaceValueToDataspace(const jint colorSpace) {
switch (colorSpace) {
case JNamedColorSpace::DISPLAY_P3:
return ui::Dataspace::DISPLAY_P3;
default:
return ui::Dataspace::V0_SRGB;
}
}
constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
switch (colorMode) {
case ui::ColorMode::DISPLAY_P3:
@@ -553,6 +563,23 @@ static void nativeSetGeometry(JNIEnv* env, jclass clazz, jlong transactionObj, j
transaction->setGeometry(ctrl, source, dst, orientation);
}
static void nativeSetBuffer(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
jobject bufferObject) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
sp<GraphicBuffer> buffer(
android_graphics_GraphicBuffer_getNativeGraphicsBuffer(env, bufferObject));
transaction->setBuffer(ctrl, buffer);
}
static void nativeSetColorSpace(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
jint colorSpace) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
ui::Dataspace dataspace = fromNamedColorSpaceValueToDataspace(colorSpace);
transaction->setDataspace(ctrl, dataspace);
}
static void nativeSetBlurRegions(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject, jobjectArray regions, jint regionsLength) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -1877,6 +1904,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeGetDisplayedContentSample },
{"nativeSetGeometry", "(JJLandroid/graphics/Rect;Landroid/graphics/Rect;J)V",
(void*)nativeSetGeometry },
{"nativeSetBuffer", "(JJLandroid/graphics/GraphicBuffer;)V",
(void*)nativeSetBuffer },
{"nativeSetColorSpace", "(JJI)V",
(void*)nativeSetColorSpace },
{"nativeSyncInputWindows", "(J)V",
(void*)nativeSyncInputWindows },
{"nativeGetDisplayBrightnessSupport", "(Landroid/os/IBinder;)Z",

View File

@@ -36,9 +36,11 @@ import static com.android.server.wm.WindowStateAnimator.WINDOW_FREEZE_LAYER;
import android.animation.ArgbEvaluator;
import android.content.Context;
import android.graphics.Color;
import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.Trace;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -210,9 +212,9 @@ class ScreenRotationAnimation {
String name = "RotationLayer";
mScreenshotLayer = displayContent.makeOverlay()
.setName(name)
.setBufferSize(mWidth, mHeight)
.setSecure(isSecure)
.setCallsite("ScreenRotationAnimation")
.setBLASTLayer()
.build();
// This is the way to tell the input system to exclude this surface from occlusion
// detection since we don't have a window for it. We do this because this window is
@@ -225,32 +227,29 @@ class ScreenRotationAnimation {
.setCallsite("ScreenRotationAnimation")
.build();
final Surface surface = mService.mSurfaceFactory.get();
// In case display bounds change, screenshot buffer and surface may mismatch so
// set a scaling mode.
surface.copyFrom(mScreenshotLayer);
surface.setScalingMode(Surface.SCALING_MODE_SCALE_TO_WINDOW);
HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer();
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"ScreenRotationAnimation#getMedianBorderLuma");
mStartLuma = RotationAnimationUtils.getMedianBorderLuma(
screenshotBuffer.getHardwareBuffer(), screenshotBuffer.getColorSpace());
mStartLuma = RotationAnimationUtils.getMedianBorderLuma(hardwareBuffer,
screenshotBuffer.getColorSpace());
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
try {
surface.attachAndQueueBufferWithColorSpace(screenshotBuffer.getHardwareBuffer(),
screenshotBuffer.getColorSpace());
} catch (RuntimeException e) {
Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
}
GraphicBuffer buffer = GraphicBuffer.createFromHardwareBuffer(
screenshotBuffer.getHardwareBuffer());
// Scale the layer to the display size.
float dsdx = (float) mWidth / hardwareBuffer.getWidth();
float dsdy = (float) mHeight / hardwareBuffer.getHeight();
t.setLayer(mScreenshotLayer, SCREEN_FREEZE_LAYER_BASE);
t.reparent(mBackColorSurface, displayContent.getSurfaceControl());
t.setLayer(mBackColorSurface, -1);
t.setColor(mBackColorSurface, new float[]{mStartLuma, mStartLuma, mStartLuma});
t.setAlpha(mBackColorSurface, 1);
t.setBuffer(mScreenshotLayer, buffer);
t.setColorSpace(mScreenshotLayer, screenshotBuffer.getColorSpace());
t.setMatrix(mScreenshotLayer, dsdx, 0, 0, dsdy);
t.show(mScreenshotLayer);
t.show(mBackColorSurface);
surface.destroy();
} catch (OutOfResourcesException e) {
Slog.w(TAG, "Unable to allocate freeze surface", e);

View File

@@ -22,6 +22,7 @@ import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_SCREEN_ROTATI
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
@@ -153,29 +154,24 @@ class SurfaceFreezer {
*/
Snapshot(Supplier<Surface> surfaceFactory, SurfaceControl.Transaction t,
SurfaceControl.ScreenshotHardwareBuffer screenshotBuffer, SurfaceControl parent) {
Surface drawSurface = surfaceFactory.get();
// We can't use a delegating constructor since we need to
// reference this::onAnimationFinished
HardwareBuffer hardwareBuffer = screenshotBuffer.getHardwareBuffer();
final int width = hardwareBuffer.getWidth();
final int height = hardwareBuffer.getHeight();
GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(
screenshotBuffer.getHardwareBuffer());
mSurfaceControl = mAnimatable.makeAnimationLeash()
.setName("snapshot anim: " + mAnimatable.toString())
.setBufferSize(width, height)
.setFormat(PixelFormat.TRANSLUCENT)
.setParent(parent)
.setSecure(screenshotBuffer.containsSecureLayers())
.setCallsite("SurfaceFreezer.Snapshot")
.setBLASTLayer()
.build();
ProtoLog.i(WM_SHOW_TRANSACTIONS, " THUMBNAIL %s: CREATE", mSurfaceControl);
// Transfer the thumbnail to the surface
drawSurface.copyFrom(mSurfaceControl);
drawSurface.attachAndQueueBufferWithColorSpace(hardwareBuffer,
screenshotBuffer.getColorSpace());
drawSurface.release();
t.setBuffer(mSurfaceControl, graphicBuffer);
t.setColorSpace(mSurfaceControl, screenshotBuffer.getColorSpace());
t.show(mSurfaceControl);
// We parent the thumbnail to the container, and just place it on top of anything else

View File

@@ -36,6 +36,7 @@ import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Binder;
@@ -45,7 +46,6 @@ import android.os.Parcel;
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Slog;
import android.view.Surface;
import android.view.SurfaceControl;
import android.window.IDisplayAreaOrganizerController;
import android.window.ITaskOrganizerController;
@@ -766,18 +766,21 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
return false;
}
GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer(
buffer.getHardwareBuffer());
SurfaceControl screenshot = mService.mWindowManager.mSurfaceControlFactory.apply(null)
.setName(wc.getName() + " - Organizer Screenshot")
.setBufferSize(bounds.width(), bounds.height())
.setFormat(PixelFormat.TRANSLUCENT)
.setParent(wc.getParentSurfaceControl())
.setSecure(buffer.containsSecureLayers())
.setCallsite("WindowOrganizerController.takeScreenshot")
.setBLASTLayer()
.build();
Surface surface = new Surface();
surface.copyFrom(screenshot);
surface.attachAndQueueBufferWithColorSpace(buffer.getHardwareBuffer(), null);
surface.release();
SurfaceControl.Transaction transaction = mService.mWindowManager.mTransactionFactory.get();
transaction.setBuffer(screenshot, graphicBuffer);
transaction.setColorSpace(screenshot, buffer.getColorSpace());
transaction.apply();
outSurfaceControl.copyFrom(screenshot, "WindowOrganizerController.takeScreenshot");
return true;

View File

@@ -17,6 +17,8 @@
package com.android.server.wm;
import android.annotation.NonNull;
import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.Region;
@@ -253,4 +255,14 @@ public class StubTransaction extends SurfaceControl.Transaction {
public SurfaceControl.Transaction unsetFixedTransformHint(@NonNull SurfaceControl sc) {
return this;
}
@Override
public SurfaceControl.Transaction setBuffer(SurfaceControl sc, GraphicBuffer buffer) {
return this;
}
@Override
public SurfaceControl.Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) {
return this;
}
}