Merge "SurfaceView: Synchronize initial destframe change from BBQ" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
852000568a
@@ -942,9 +942,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
// When the listener is updated, we will get at least a single position update call so we can
|
// When the listener is updated, we will get at least a single position update call so we can
|
||||||
// guarantee any changes we post will be applied.
|
// guarantee any changes we post will be applied.
|
||||||
private void replacePositionUpdateListener(int surfaceWidth, int surfaceHeight,
|
private void replacePositionUpdateListener(int surfaceWidth, int surfaceHeight,
|
||||||
@Nullable Transaction geometryTransaction) {
|
Transaction geometryTransaction) {
|
||||||
if (mPositionListener != null) {
|
if (mPositionListener != null) {
|
||||||
mRenderNode.removePositionUpdateListener(mPositionListener);
|
mRenderNode.removePositionUpdateListener(mPositionListener);
|
||||||
|
geometryTransaction = mPositionListener.getTransaction().merge(geometryTransaction);
|
||||||
}
|
}
|
||||||
mPositionListener = new SurfaceViewPositionUpdateListener(surfaceWidth, surfaceHeight,
|
mPositionListener = new SurfaceViewPositionUpdateListener(surfaceWidth, surfaceHeight,
|
||||||
geometryTransaction);
|
geometryTransaction);
|
||||||
@@ -952,7 +953,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator,
|
private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator,
|
||||||
boolean creating, boolean sizeChanged, boolean hintChanged) {
|
boolean creating, boolean sizeChanged, boolean hintChanged,
|
||||||
|
Transaction geometryTransaction) {
|
||||||
boolean realSizeChanged = false;
|
boolean realSizeChanged = false;
|
||||||
|
|
||||||
mSurfaceLock.lock();
|
mSurfaceLock.lock();
|
||||||
@@ -990,10 +992,6 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
mSurfaceAlpha = alpha;
|
mSurfaceAlpha = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
// While creating the surface, we will set it's initial
|
|
||||||
// geometry. Outside of that though, we should generally
|
|
||||||
// leave it to the RenderThread.
|
|
||||||
Transaction geometryTransaction = new Transaction();
|
|
||||||
geometryTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
|
geometryTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
|
||||||
if ((sizeChanged || hintChanged) && !creating) {
|
if ((sizeChanged || hintChanged) && !creating) {
|
||||||
setBufferSize(geometryTransaction);
|
setBufferSize(geometryTransaction);
|
||||||
@@ -1016,20 +1014,18 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
mSurfaceHeight);
|
mSurfaceHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean applyChangesOnRenderThread =
|
|
||||||
sizeChanged && !creating && isHardwareAccelerated();
|
|
||||||
if (isHardwareAccelerated()) {
|
if (isHardwareAccelerated()) {
|
||||||
// This will consume the passed in transaction and the transaction will be
|
// This will consume the passed in transaction and the transaction will be
|
||||||
// applied on a render worker thread.
|
// applied on a render worker thread.
|
||||||
replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight,
|
replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight,
|
||||||
applyChangesOnRenderThread ? geometryTransaction : null);
|
geometryTransaction);
|
||||||
}
|
}
|
||||||
if (DEBUG_POSITION) {
|
if (DEBUG_POSITION) {
|
||||||
Log.d(TAG, String.format(
|
Log.d(TAG, String.format(
|
||||||
"%d updateSurfacePosition %s"
|
"%d performSurfaceTransaction %s "
|
||||||
+ "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
|
+ "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
|
||||||
System.identityHashCode(this),
|
System.identityHashCode(this),
|
||||||
applyChangesOnRenderThread ? "RenderWorker" : "UiThread",
|
isHardwareAccelerated() ? "RenderWorker" : "UI Thread",
|
||||||
mScreenRect.left, mScreenRect.top, mScreenRect.right,
|
mScreenRect.left, mScreenRect.top, mScreenRect.right,
|
||||||
mScreenRect.bottom, mSurfaceWidth, mSurfaceHeight));
|
mScreenRect.bottom, mSurfaceWidth, mSurfaceHeight));
|
||||||
}
|
}
|
||||||
@@ -1141,12 +1137,14 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
|
|
||||||
final Rect surfaceInsets = viewRoot.mWindowAttributes.surfaceInsets;
|
final Rect surfaceInsets = viewRoot.mWindowAttributes.surfaceInsets;
|
||||||
mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
|
mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
|
||||||
|
// Collect all geometry changes and apply these changes on the RenderThread worker
|
||||||
|
// via the RenderNode.PositionUpdateListener.
|
||||||
|
final Transaction geometryTransaction = new Transaction();
|
||||||
if (creating) {
|
if (creating) {
|
||||||
updateOpaqueFlag();
|
updateOpaqueFlag();
|
||||||
final String name = "SurfaceView[" + viewRoot.getTitle().toString() + "]";
|
final String name = "SurfaceView[" + viewRoot.getTitle().toString() + "]";
|
||||||
if (mUseBlastAdapter) {
|
if (mUseBlastAdapter) {
|
||||||
createBlastSurfaceControls(viewRoot, name);
|
createBlastSurfaceControls(viewRoot, name, geometryTransaction);
|
||||||
} else {
|
} else {
|
||||||
mDeferredDestroySurfaceControl = createSurfaceControls(viewRoot, name);
|
mDeferredDestroySurfaceControl = createSurfaceControls(viewRoot, name);
|
||||||
}
|
}
|
||||||
@@ -1155,7 +1153,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
}
|
}
|
||||||
|
|
||||||
final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
|
final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
|
||||||
translator, creating, sizeChanged, hintChanged);
|
translator, creating, sizeChanged, hintChanged, geometryTransaction);
|
||||||
final boolean redrawNeeded = sizeChanged || creating || hintChanged
|
final boolean redrawNeeded = sizeChanged || creating || hintChanged
|
||||||
|| (mVisible && !mDrawFinished);
|
|| (mVisible && !mDrawFinished);
|
||||||
|
|
||||||
@@ -1322,7 +1320,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
// is still alive, the old buffers will continue to be presented until replaced by buffers from
|
// is still alive, the old buffers will continue to be presented until replaced by buffers from
|
||||||
// the new adapter. This means we do not need to track the old surface control and destroy it
|
// the new adapter. This means we do not need to track the old surface control and destroy it
|
||||||
// after the client has drawn to avoid any flickers.
|
// after the client has drawn to avoid any flickers.
|
||||||
private void createBlastSurfaceControls(ViewRootImpl viewRoot, String name) {
|
private void createBlastSurfaceControls(ViewRootImpl viewRoot, String name,
|
||||||
|
Transaction geometryTransaction) {
|
||||||
if (mSurfaceControl == null) {
|
if (mSurfaceControl == null) {
|
||||||
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
|
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
|
||||||
.setName(name)
|
.setName(name)
|
||||||
@@ -1363,8 +1362,9 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
}
|
}
|
||||||
mTransformHint = viewRoot.getBufferTransformHint();
|
mTransformHint = viewRoot.getBufferTransformHint();
|
||||||
mBlastSurfaceControl.setTransformHint(mTransformHint);
|
mBlastSurfaceControl.setTransformHint(mTransformHint);
|
||||||
mBlastBufferQueue = new BLASTBufferQueue(name, mBlastSurfaceControl, mSurfaceWidth,
|
mBlastBufferQueue = new BLASTBufferQueue(name);
|
||||||
mSurfaceHeight, mFormat);
|
mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat,
|
||||||
|
geometryTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDrawFinished() {
|
private void onDrawFinished() {
|
||||||
@@ -1545,6 +1545,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
applyOrMergeTransaction(mRtTransaction, frameNumber);
|
applyOrMergeTransaction(mRtTransaction, frameNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Transaction getTransaction() {
|
||||||
|
return mPositionChangedTransaction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SurfaceViewPositionUpdateListener mPositionListener = null;
|
private SurfaceViewPositionUpdateListener mPositionListener = null;
|
||||||
@@ -1638,6 +1642,11 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
@Override
|
@Override
|
||||||
public void setFixedSize(int width, int height) {
|
public void setFixedSize(int width, int height) {
|
||||||
if (mRequestedWidth != width || mRequestedHeight != height) {
|
if (mRequestedWidth != width || mRequestedHeight != height) {
|
||||||
|
if (DEBUG_POSITION) {
|
||||||
|
Log.d(TAG, String.format("%d setFixedSize %dx%d -> %dx%d",
|
||||||
|
System.identityHashCode(this), mRequestedWidth, mRequestedHeight, width,
|
||||||
|
height));
|
||||||
|
}
|
||||||
mRequestedWidth = width;
|
mRequestedWidth = width;
|
||||||
mRequestedHeight = height;
|
mRequestedHeight = height;
|
||||||
requestLayout();
|
requestLayout();
|
||||||
@@ -1647,6 +1656,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
|
|||||||
@Override
|
@Override
|
||||||
public void setSizeFromLayout() {
|
public void setSizeFromLayout() {
|
||||||
if (mRequestedWidth != -1 || mRequestedHeight != -1) {
|
if (mRequestedWidth != -1 || mRequestedHeight != -1) {
|
||||||
|
if (DEBUG_POSITION) {
|
||||||
|
Log.d(TAG, String.format("%d setSizeFromLayout was %dx%d",
|
||||||
|
System.identityHashCode(this), mRequestedWidth, mRequestedHeight));
|
||||||
|
}
|
||||||
mRequestedWidth = mRequestedHeight = -1;
|
mRequestedWidth = mRequestedHeight = -1;
|
||||||
requestLayout();
|
requestLayout();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,21 +67,19 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName, jlong surfaceControl,
|
static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName) {
|
||||||
jlong width, jlong height, jint format) {
|
ScopedUtfChars name(env, jName);
|
||||||
String8 str8;
|
sp<BLASTBufferQueue> queue = new BLASTBufferQueue(name.c_str());
|
||||||
if (jName) {
|
queue->incStrong((void*)nativeCreate);
|
||||||
const jchar* str16 = env->GetStringCritical(jName, nullptr);
|
return reinterpret_cast<jlong>(queue.get());
|
||||||
if (str16) {
|
}
|
||||||
str8 = String8(reinterpret_cast<const char16_t*>(str16), env->GetStringLength(jName));
|
|
||||||
env->ReleaseStringCritical(jName, str16);
|
static jlong nativeCreateAndUpdate(JNIEnv* env, jclass clazz, jstring jName, jlong surfaceControl,
|
||||||
str16 = nullptr;
|
jlong width, jlong height, jint format) {
|
||||||
}
|
ScopedUtfChars name(env, jName);
|
||||||
}
|
|
||||||
std::string name = str8.string();
|
|
||||||
sp<BLASTBufferQueue> queue =
|
sp<BLASTBufferQueue> queue =
|
||||||
new BLASTBufferQueue(name, reinterpret_cast<SurfaceControl*>(surfaceControl), width,
|
new BLASTBufferQueue(name.c_str(), reinterpret_cast<SurfaceControl*>(surfaceControl),
|
||||||
height, format);
|
width, height, format);
|
||||||
queue->incStrong((void*)nativeCreate);
|
queue->incStrong((void*)nativeCreate);
|
||||||
return reinterpret_cast<jlong>(queue.get());
|
return reinterpret_cast<jlong>(queue.get());
|
||||||
}
|
}
|
||||||
@@ -142,7 +140,8 @@ static jlong nativeGetLastAcquiredFrameNum(JNIEnv* env, jclass clazz, jlong ptr)
|
|||||||
static const JNINativeMethod gMethods[] = {
|
static const JNINativeMethod gMethods[] = {
|
||||||
/* name, signature, funcPtr */
|
/* name, signature, funcPtr */
|
||||||
// clang-format off
|
// clang-format off
|
||||||
{"nativeCreate", "(Ljava/lang/String;JJJI)J", (void*)nativeCreate},
|
{"nativeCreate", "(Ljava/lang/String;)J", (void*)nativeCreate},
|
||||||
|
{"nativeCreateAndUpdate", "(Ljava/lang/String;JJJI)J", (void*)nativeCreateAndUpdate},
|
||||||
{"nativeGetSurface", "(JZ)Landroid/view/Surface;", (void*)nativeGetSurface},
|
{"nativeGetSurface", "(JZ)Landroid/view/Surface;", (void*)nativeGetSurface},
|
||||||
{"nativeDestroy", "(J)V", (void*)nativeDestroy},
|
{"nativeDestroy", "(J)V", (void*)nativeDestroy},
|
||||||
{"nativeSetNextTransaction", "(JJ)V", (void*)nativeSetNextTransaction},
|
{"nativeSetNextTransaction", "(JJ)V", (void*)nativeSetNextTransaction},
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ public final class BLASTBufferQueue {
|
|||||||
// Note: This field is accessed by native code.
|
// Note: This field is accessed by native code.
|
||||||
public long mNativeObject; // BLASTBufferQueue*
|
public long mNativeObject; // BLASTBufferQueue*
|
||||||
|
|
||||||
private static native long nativeCreate(String name, long surfaceControl, long width,
|
private static native long nativeCreateAndUpdate(String name, long surfaceControl, long width,
|
||||||
long height, int format);
|
long height, int format);
|
||||||
|
private static native long nativeCreate(String name);
|
||||||
private static native void nativeDestroy(long ptr);
|
private static native void nativeDestroy(long ptr);
|
||||||
private static native Surface nativeGetSurface(long ptr, boolean includeSurfaceControlHandle);
|
private static native Surface nativeGetSurface(long ptr, boolean includeSurfaceControlHandle);
|
||||||
private static native void nativeSetNextTransaction(long ptr, long transactionPtr);
|
private static native void nativeSetNextTransaction(long ptr, long transactionPtr);
|
||||||
@@ -54,7 +55,11 @@ public final class BLASTBufferQueue {
|
|||||||
/** Create a new connection with the surface flinger. */
|
/** Create a new connection with the surface flinger. */
|
||||||
public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
|
public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
|
||||||
@PixelFormat.Format int format) {
|
@PixelFormat.Format int format) {
|
||||||
mNativeObject = nativeCreate(name, sc.mNativeObject, width, height, format);
|
mNativeObject = nativeCreateAndUpdate(name, sc.mNativeObject, width, height, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BLASTBufferQueue(String name) {
|
||||||
|
mNativeObject = nativeCreate(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
|
|||||||
Reference in New Issue
Block a user