diff options
| -rw-r--r-- | core/java/android/view/Surface.java | 30 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 13 | ||||
| -rw-r--r-- | core/jni/android_view_Surface.cpp | 7 |
3 files changed, 49 insertions, 1 deletions
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 394660fb538b..ef50fdc5eb4f 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -57,6 +57,7 @@ public class Surface implements Parcelable { private static native int nativeGetHeight(long nativeObject); private static native long nativeGetNextFrameNumber(long nativeObject); + private static native int nativeSetScalingMode(long nativeObject, int scalingMode); public static final Parcelable.Creator<Surface> CREATOR = new Parcelable.Creator<Surface>() { @@ -95,6 +96,21 @@ public class Surface implements Parcelable { private HwuiContext mHwuiContext; /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef({SCALING_MODE_FREEZE, SCALING_MODE_SCALE_TO_WINDOW, + SCALING_MODE_SCALE_CROP, SCALING_MODE_NO_SCALE_CROP}) + public @interface ScalingMode {} + // From system/window.h + /** @hide */ + static final int SCALING_MODE_FREEZE = 0; + /** @hide */ + static final int SCALING_MODE_SCALE_TO_WINDOW = 1; + /** @hide */ + static final int SCALING_MODE_SCALE_CROP = 2; + /** @hide */ + static final int SCALING_MODE_NO_SCALE_CROP = 3; + + /** @hide */ @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) @Retention(RetentionPolicy.SOURCE) public @interface Rotation {} @@ -500,6 +516,20 @@ public class Surface implements Parcelable { } /** + * Set the scaling mode to be used for this surfaces buffers + * @hide + */ + void setScalingMode(@ScalingMode int scalingMode) { + synchronized (mLock) { + checkNotReleasedLocked(); + int err = nativeSetScalingMode(mNativeObject, scalingMode); + if (err != 0) { + throw new IllegalArgumentException("Invalid scaling mode: " + scalingMode); + } + } + } + + /** * 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/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 589c0dc85b68..f4fa98029be7 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -578,8 +578,19 @@ public class SurfaceView extends View { } mSurface.transferFrom(mNewSurface); - if (visible && mSurface.isValid()) { + // We set SCALING_MODE_NO_SCALE_CROP to allow the WindowManager + // to update our Surface crop without requiring a new buffer from + // us. In the default mode of SCALING_MODE_FREEZE, surface geometry + // state (which includes crop) is only applied when a buffer + // with appropriate geometry is available. During drag resize + // it is quite frequent that a matching buffer will not be available + // (because we are constantly being resized and have fallen behind). + // However in such situations the WindowManager still needs to be able + // to update our crop to ensure we stay within the bounds of the containing + // window. + mSurface.setScalingMode(Surface.SCALING_MODE_NO_SCALE_CROP); + if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) { mSurfaceCreated = true; mIsCreating = true; diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index f6e68c48e881..cf68449096a6 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -465,11 +465,17 @@ static jint nativeGetHeight(JNIEnv* env, jclass clazz, jlong nativeObject) { anw->query(anw, NATIVE_WINDOW_HEIGHT, &value); return value; } + static jlong nativeGetNextFrameNumber(JNIEnv *env, jclass clazz, jlong nativeObject) { Surface* surface = reinterpret_cast<Surface*>(nativeObject); return surface->getNextFrameNumber(); } +static jint nativeSetScalingMode(JNIEnv *env, jclass clazz, jlong nativeObject, jint scalingMode) { + Surface* surface = reinterpret_cast<Surface*>(nativeObject); + return surface->setScalingMode(scalingMode); +} + namespace uirenderer { using namespace android::uirenderer::renderthread; @@ -546,6 +552,7 @@ static const JNINativeMethod gSurfaceMethods[] = { {"nativeGetWidth", "(J)I", (void*)nativeGetWidth }, {"nativeGetHeight", "(J)I", (void*)nativeGetHeight }, {"nativeGetNextFrameNumber", "(J)J", (void*)nativeGetNextFrameNumber }, + {"nativeSetScalingMode", "(JI)I", (void*)nativeSetScalingMode }, // HWUI context {"nHwuiCreate", "(JJ)J", (void*) hwui::create }, |