summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/SurfaceControl.java23
-rw-r--r--core/java/android/view/ViewRootImpl.java54
-rw-r--r--core/java/android/view/WindowManager.java7
-rw-r--r--core/jni/Android.bp1
-rw-r--r--core/jni/AndroidRuntime.cpp4
-rw-r--r--core/jni/android_graphics_BLASTBufferQueue.cpp82
-rw-r--r--graphics/java/android/graphics/BLASTBufferQueue.java67
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java8
8 files changed, 238 insertions, 8 deletions
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 6637c5b06a1b..8dd475e0c306 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -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();
@@ -318,6 +321,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.
*
* @hide
@@ -693,6 +701,14 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * @hide
+ */
+ public Builder setBLASTLayer() {
+ unsetBufferSize();
+ return setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK);
+ }
+
+ /**
* Indicates whether a 'ContainerLayer' is to be constructed.
*
* Container layers will not be rendered in any fashion and instead are used
@@ -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;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cf0698575851..9ddd84f1943c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -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();
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 001ab6650551..4a6ef987a642 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1834,6 +1834,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}.
*
* @hide
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 0feab7f61918..ce405feb5985 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -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",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index d476d2d2c35c..3497f920e6a4 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -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),
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
new file mode 100644
index 000000000000..185e58160adf
--- /dev/null
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -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
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
new file mode 100644
index 000000000000..8c6a9371d53b
--- /dev/null
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -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();
+ }
+ }
+}
+
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 7f68c48e473f..0b4ea9927139 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -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);
}