Merge "ViewRootImpl: Add USE_BLAST flag."

This commit is contained in:
Rob Carr
2019-10-10 19:43:49 +00:00
committed by Android (Google) Code Review
8 changed files with 238 additions and 8 deletions

View File

@@ -199,7 +199,10 @@ public final class SurfaceControl implements Parcelable {
private final CloseGuard mCloseGuard = CloseGuard.get();
private String mName;
long mNativeObject; // package visibility only for Surface.java access
/**
* @hide
*/
public long mNativeObject;
// TODO: Move this to native.
private final Object mSizeLock = new Object();
@@ -317,6 +320,11 @@ public final class SurfaceControl implements Parcelable {
*/
public static final int FX_SURFACE_CONTAINER = 0x00080000;
/**
* @hide
*/
public static final int FX_SURFACE_BLAST = 0x00040000;
/**
* Mask used for FX values above.
*
@@ -692,6 +700,14 @@ public final class SurfaceControl implements Parcelable {
return (mFlags & FX_SURFACE_DIM) == FX_SURFACE_DIM;
}
/**
* @hide
*/
public Builder setBLASTLayer() {
unsetBufferSize();
return setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK);
}
/**
* Indicates whether a 'ContainerLayer' is to be constructed.
*
@@ -1951,7 +1967,10 @@ public final class SurfaceControl implements Parcelable {
public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
Transaction.class.getClassLoader(),
nativeGetNativeTransactionFinalizer(), 512);
private long mNativeObject;
/**
* @hide
*/
public long mNativeObject;
private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>();
Runnable mFreeNativeResources;

View File

@@ -45,6 +45,7 @@ import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.BLASTBufferQueue;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.FrameInfo;
@@ -170,6 +171,8 @@ public final class ViewRootImpl implements ViewParent,
*/
private static final boolean MT_RENDERER_AVAILABLE = true;
private static final boolean USE_BLAST_BUFFERQUEUE = false;
/**
* If set to 2, the view system will switch from using rectangles retrieved from window to
* dispatch to the view hierarchy to using {@link InsetsController}, that derives the insets
@@ -475,6 +478,9 @@ public final class ViewRootImpl implements ViewParent,
@UnsupportedAppUsage
public final Surface mSurface = new Surface();
private final SurfaceControl mSurfaceControl = new SurfaceControl();
private SurfaceControl mBlastSurfaceControl;
private BLASTBufferQueue mBlastBufferQueue;
/**
* Transaction object that can be used to synchronize child SurfaceControl changes with
@@ -1282,6 +1288,11 @@ public final class ViewRootImpl implements ViewParent,
}
mWindowAttributes.privateFlags |= compatibleWindowFlag;
if (USE_BLAST_BUFFERQUEUE) {
mWindowAttributes.privateFlags =
WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST;
}
if (mWindowAttributes.preservePreviousSurfaceInsets) {
// Restore old surface insets.
mWindowAttributes.surfaceInsets.set(
@@ -1629,6 +1640,29 @@ public final class ViewRootImpl implements ViewParent,
return mBoundsLayer;
}
Surface getOrCreateBLASTSurface(int width, int height) {
if (mSurfaceControl == null || !mSurfaceControl.isValid()) {
return null;
}
if (mBlastSurfaceControl == null) {
mBlastSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
.setParent(mSurfaceControl)
.setName("BLAST")
.setBLASTLayer()
.build();
mBlastBufferQueue = new BLASTBufferQueue(
mBlastSurfaceControl, width, height);
}
mBlastBufferQueue.update(mSurfaceControl, width, height);
mTransaction.show(mBlastSurfaceControl)
.reparent(mBlastSurfaceControl, mSurfaceControl)
.apply();
return mBlastBufferQueue.getSurface();
}
private void setBoundsLayerCrop() {
// mWinFrame is already adjusted for surface insets. So offset it and use it as
// the cropping bounds.
@@ -1658,6 +1692,13 @@ public final class ViewRootImpl implements ViewParent,
}
mSurface.release();
mSurfaceControl.release();
if (mBlastBufferQueue != null) {
mTransaction.remove(mBlastSurfaceControl).apply();
mBlastSurfaceControl = null;
// We should probably add an explicit dispose.
mBlastBufferQueue = null;
}
}
/**
@@ -2413,10 +2454,9 @@ public final class ViewRootImpl implements ViewParent,
// will be transparent
if (mAttachInfo.mThreadedRenderer != null) {
try {
hwInitialized = mAttachInfo.mThreadedRenderer.initialize(
mSurface);
hwInitialized = mAttachInfo.mThreadedRenderer.initialize(mSurface);
if (hwInitialized && (host.mPrivateFlags
& View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
& View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
// Don't pre-allocate if transparent regions
// are requested as they may not be needed
mAttachInfo.mThreadedRenderer.allocateBuffers();
@@ -7139,7 +7179,13 @@ public final class ViewRootImpl implements ViewParent,
mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,
mPendingMergedConfiguration, mSurfaceControl, mTempInsets);
if (mSurfaceControl.isValid()) {
mSurface.copyFrom(mSurfaceControl);
if (USE_BLAST_BUFFERQUEUE == false) {
mSurface.copyFrom(mSurfaceControl);
} else {
mSurface.transferFrom(getOrCreateBLASTSurface(
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f)));
}
} else {
destroySurface();
}

View File

@@ -1833,6 +1833,13 @@ public interface WindowManager extends ViewManager {
*/
public static final int PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC = 0x01000000;
/**
* Flag to request creation of a BLAST (Buffer as LayerState) Layer.
* If not specified the client will receive a BufferQueue layer.
* @hide
*/
public static final int PRIVATE_FLAG_USE_BLAST = 0x02000000;
/**
* An internal annotation for flags that can be specified to {@link #softInputMode}.
*

View File

@@ -117,6 +117,7 @@ cc_library_shared {
"android_view_RenderNodeAnimator.cpp",
"android_view_Surface.cpp",
"android_view_SurfaceControl.cpp",
"android_graphics_BLASTBufferQueue.cpp",
"android_view_SurfaceSession.cpp",
"android_view_TextureView.cpp",
"android_view_VelocityTracker.cpp",

View File

@@ -115,6 +115,7 @@ extern int register_android_util_MemoryIntArray(JNIEnv* env);
extern int register_android_content_StringBlock(JNIEnv* env);
extern int register_android_content_XmlBlock(JNIEnv* env);
extern int register_android_content_res_ApkAssets(JNIEnv* env);
extern int register_android_graphics_BLASTBufferQueue(JNIEnv* env);
extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
extern int register_android_view_InputApplicationHandle(JNIEnv* env);
extern int register_android_view_InputWindowHandle(JNIEnv* env);
@@ -1458,10 +1459,9 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_opengl_jni_GLES31),
REG_JNI(register_android_opengl_jni_GLES31Ext),
REG_JNI(register_android_opengl_jni_GLES32),
REG_JNI(register_android_graphics_classes),
REG_JNI(register_android_graphics_BLASTBufferQueue),
REG_JNI(register_android_graphics_GraphicBuffer),
REG_JNI(register_android_database_CursorWindow),
REG_JNI(register_android_database_SQLiteConnection),
REG_JNI(register_android_database_SQLiteGlobal),

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "BLASTBufferQueue"
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_view_Surface.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
#include <gui/BLASTBufferQueue.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
namespace android {
static jlong nativeCreate(JNIEnv* env, jclass clazz, jlong surfaceControl, jlong width, jlong height) {
sp<BLASTBufferQueue> queue = new BLASTBufferQueue(
reinterpret_cast<SurfaceControl*>(surfaceControl), width, height);
queue->incStrong((void*)nativeCreate);
return reinterpret_cast<jlong>(queue.get());
}
static void nativeDestroy(JNIEnv* env, jclass clazz, jlong ptr) {
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
queue->decStrong((void*)nativeCreate);
}
static jobject nativeGetSurface(JNIEnv* env, jclass clazz, jlong ptr) {
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
return android_view_Surface_createFromIGraphicBufferProducer(env, queue->getIGraphicBufferProducer());
}
static void nativeSetNextTransaction(JNIEnv* env, jclass clazz, jlong ptr, jlong transactionPtr) {
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionPtr);
queue->setNextTransaction(transaction);
}
static void nativeUpdate(JNIEnv*env, jclass clazz, jlong ptr, jlong surfaceControl, jlong width, jlong height) {
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
queue->update(reinterpret_cast<SurfaceControl*>(surfaceControl), width, height);
}
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "nativeCreate", "(JJJ)J",
(void*)nativeCreate },
{ "nativeGetSurface", "(J)Landroid/view/Surface;",
(void*)nativeGetSurface },
{ "nativeDestroy", "(J)V",
(void*)nativeDestroy },
{ "nativeSetNextTransaction", "(JJ)V",
(void*)nativeSetNextTransaction },
{ "nativeUpdate", "(JJJJ)V",
(void*)nativeUpdate }
};
int register_android_graphics_BLASTBufferQueue(JNIEnv* env) {
int res = jniRegisterNativeMethods(env, "android/graphics/BLASTBufferQueue",
gMethods, NELEM(gMethods));
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
return 0;
}
} // namespace android

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.graphics;
import android.view.Surface;
import android.view.SurfaceControl;
/**
* @hide
*/
public final class BLASTBufferQueue {
// Note: This field is accessed by native code.
private long mNativeObject; // BLASTBufferQueue*
private static native long nativeCreate(long surfaceControl, long width, long height);
private static native void nativeDestroy(long ptr);
private static native Surface nativeGetSurface(long ptr);
private static native void nativeSetNextTransaction(long ptr, long transactionPtr);
private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height);
/** Create a new connection with the surface flinger. */
public BLASTBufferQueue(SurfaceControl sc, int width, int height) {
mNativeObject = nativeCreate(sc.mNativeObject, width, height);
}
public void destroy() {
nativeDestroy(mNativeObject);
}
public Surface getSurface() {
return nativeGetSurface(mNativeObject);
}
public void setNextTransaction(SurfaceControl.Transaction t) {
nativeSetNextTransaction(mNativeObject, t.mNativeObject);
}
public void update(SurfaceControl sc, int width, int height) {
nativeUpdate(mNativeObject, sc.mNativeObject, width, height);
}
@Override
protected void finalize() throws Throwable {
try {
if (mNativeObject != 0) {
nativeDestroy(mNativeObject);
}
} finally {
super.finalize();
}
}
}

View File

@@ -38,6 +38,7 @@ import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.SurfaceControl;
import android.view.WindowContentFrameStats;
import android.view.WindowManager;
import com.android.server.protolog.common.ProtoLog;
@@ -108,6 +109,13 @@ class WindowSurfaceController {
.setFlags(flags)
.setMetadata(METADATA_WINDOW_TYPE, windowType)
.setMetadata(METADATA_OWNER_UID, ownerUid);
if ((win.getAttrs().privateFlags &
WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0) {
b.setContainerLayer();
}
mSurfaceControl = b.build();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}