diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 286e0979d12b7..dc19d32815078 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -96,6 +96,8 @@ public class Surface implements Parcelable { private HwuiContext mHwuiContext; + private boolean mIsSingleBuffered; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({SCALING_MODE_FREEZE, SCALING_MODE_SCALE_TO_WINDOW, @@ -158,7 +160,7 @@ public class Surface implements Parcelable { if (surfaceTexture == null) { throw new IllegalArgumentException("surfaceTexture must not be null"); } - + mIsSingleBuffered = surfaceTexture.isSingleBuffered(); synchronized (mLock) { mName = surfaceTexture.toString(); setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture)); @@ -458,6 +460,7 @@ public class Surface implements Parcelable { // the reference count on mNativeObject. Either way, it is // not necessary to call nativeRelease() here. mName = source.readString(); + mIsSingleBuffered = source.readInt() != 0; setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source)); } } @@ -469,6 +472,7 @@ public class Surface implements Parcelable { } synchronized (mLock) { dest.writeString(mName); + dest.writeInt(mIsSingleBuffered ? 1 : 0); nativeWriteToParcel(mNativeObject, dest); } if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { @@ -530,6 +534,14 @@ public class Surface implements Parcelable { } } + /** + * Returns whether or not this Surface is backed by a single-buffered SurfaceTexture + * @hide + */ + public boolean isSingleBuffered() { + return mIsSingleBuffered; + } + /** * Exception thrown when a Canvas couldn't be locked with {@link Surface#lockCanvas}, or * when a SurfaceTexture could not successfully be allocated. diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 0d8a95c9bcd33..73b3f52f078b9 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -371,7 +371,12 @@ static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz, if (sur != NULL) { bufferProducer = sur->getIGraphicBufferProducer(); } - SurfaceComposerClient::setDisplaySurface(token, bufferProducer); + status_t err = SurfaceComposerClient::setDisplaySurface(token, + bufferProducer); + if (err != NO_ERROR) { + doThrowIAE(env, "Illegal Surface, could not enable async mode. Was this" + " Surface created with singleBufferMode?"); + } } static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz, diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index 5c54324d81070..c3861083e2fda 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -77,6 +77,8 @@ public class SurfaceTexture { private long mProducer; private long mFrameAvailableListener; + private boolean mIsSingleBuffered; + /** * Callback interface for being notified that a new stream frame is available. */ @@ -130,6 +132,7 @@ public class SurfaceTexture { */ public SurfaceTexture(int texName, boolean singleBufferMode) { mCreatorLooper = Looper.myLooper(); + mIsSingleBuffered = singleBufferMode; nativeInit(false, texName, singleBufferMode, new WeakReference(this)); } @@ -157,6 +160,7 @@ public class SurfaceTexture { */ public SurfaceTexture(boolean singleBufferMode) { mCreatorLooper = Looper.myLooper(); + mIsSingleBuffered = singleBufferMode; nativeInit(true, 0, singleBufferMode, new WeakReference(this)); } @@ -378,6 +382,14 @@ public class SurfaceTexture { } } + /** + * Returns true if the SurfaceTexture is single-buffered + * @hide + */ + public boolean isSingleBuffered() { + return mIsSingleBuffered; + } + private native void nativeInit(boolean isDetached, int texName, boolean singleBufferMode, WeakReference weakSelf) throws Surface.OutOfResourcesException; diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 0abd2e79b45f9..45a96441e57e2 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -1402,6 +1402,9 @@ public final class DisplayManagerService extends SystemService { throw new IllegalArgumentException("width, height, and densityDpi must be " + "greater than 0"); } + if (surface.isSingleBuffered()) { + throw new IllegalArgumentException("Surface can't be single-buffered"); + } if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;