Merge "SurfaceView: Fix overlocking of mSurfaceLock" into tm-dev am: ec6577d13e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17808703

Change-Id: I6a5e4b0e613d3bfa418453defa5cd9bcc4b35aad
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Rob Carr
2022-05-05 15:26:54 +00:00
committed by Automerger Merge Worker

View File

@@ -719,9 +719,14 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
private void releaseSurfaces(boolean releaseSurfacePackage) { private void releaseSurfaces(boolean releaseSurfacePackage) {
mSurfaceAlpha = 1f; mSurfaceAlpha = 1f;
synchronized (mSurfaceControlLock) { mSurfaceLock.lock();
try {
mSurface.destroy(); mSurface.destroy();
} finally {
mSurfaceLock.unlock();
}
synchronized (mSurfaceControlLock) {
if (mBlastBufferQueue != null) { if (mBlastBufferQueue != null) {
mBlastBufferQueue.destroy(); mBlastBufferQueue.destroy();
mBlastBufferQueue = null; mBlastBufferQueue = null;
@@ -770,105 +775,99 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
Transaction surfaceUpdateTransaction) { Transaction surfaceUpdateTransaction) {
boolean realSizeChanged = false; boolean realSizeChanged = false;
mSurfaceLock.lock(); mDrawingStopped = !mVisible;
try {
mDrawingStopped = !mVisible;
if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ "Cur surface: " + mSurface); + "Cur surface: " + mSurface);
// If we are creating the surface control or the parent surface has not // If we are creating the surface control or the parent surface has not
// changed, then set relative z. Otherwise allow the parent // changed, then set relative z. Otherwise allow the parent
// SurfaceChangedCallback to update the relative z. This is needed so that // SurfaceChangedCallback to update the relative z. This is needed so that
// we do not change the relative z before the server is ready to swap the // we do not change the relative z before the server is ready to swap the
// parent surface. // parent surface.
if (creating) { if (creating) {
updateRelativeZ(surfaceUpdateTransaction); updateRelativeZ(surfaceUpdateTransaction);
if (mSurfacePackage != null) { if (mSurfacePackage != null) {
reparentSurfacePackage(surfaceUpdateTransaction, mSurfacePackage); reparentSurfacePackage(surfaceUpdateTransaction, mSurfacePackage);
}
} }
mParentSurfaceSequenceId = viewRoot.getSurfaceSequenceId();
if (mViewVisibility) {
surfaceUpdateTransaction.show(mSurfaceControl);
} else {
surfaceUpdateTransaction.hide(mSurfaceControl);
}
updateBackgroundVisibility(surfaceUpdateTransaction);
updateBackgroundColor(surfaceUpdateTransaction);
if (mUseAlpha) {
float alpha = getFixedAlpha();
surfaceUpdateTransaction.setAlpha(mSurfaceControl, alpha);
mSurfaceAlpha = alpha;
}
surfaceUpdateTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
if ((sizeChanged || hintChanged) && !creating) {
setBufferSize(surfaceUpdateTransaction);
}
if (sizeChanged || creating || !isHardwareAccelerated()) {
// Set a window crop when creating the surface or changing its size to
// crop the buffer to the surface size since the buffer producer may
// use SCALING_MODE_SCALE and submit a larger size than the surface
// size.
if (mClipSurfaceToBounds && mClipBounds != null) {
surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
} else {
surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
mSurfaceHeight);
}
surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth,
mSurfaceHeight);
if (isHardwareAccelerated()) {
// This will consume the passed in transaction and the transaction will be
// applied on a render worker thread.
replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight);
} else {
onSetSurfacePositionAndScale(surfaceUpdateTransaction, mSurfaceControl,
mScreenRect.left /*positionLeft*/,
mScreenRect.top /*positionTop*/,
mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
}
if (DEBUG_POSITION) {
Log.d(TAG, String.format(
"%d performSurfaceTransaction %s "
+ "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
System.identityHashCode(this),
isHardwareAccelerated() ? "RenderWorker" : "UI Thread",
mScreenRect.left, mScreenRect.top, mScreenRect.right,
mScreenRect.bottom, mSurfaceWidth, mSurfaceHeight));
}
}
applyTransactionOnVriDraw(surfaceUpdateTransaction);
updateEmbeddedAccessibilityMatrix(false);
mSurfaceFrame.left = 0;
mSurfaceFrame.top = 0;
if (translator == null) {
mSurfaceFrame.right = mSurfaceWidth;
mSurfaceFrame.bottom = mSurfaceHeight;
} else {
float appInvertedScale = translator.applicationInvertedScale;
mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
}
final int surfaceWidth = mSurfaceFrame.right;
final int surfaceHeight = mSurfaceFrame.bottom;
realSizeChanged = mLastSurfaceWidth != surfaceWidth
|| mLastSurfaceHeight != surfaceHeight;
mLastSurfaceWidth = surfaceWidth;
mLastSurfaceHeight = surfaceHeight;
} finally {
mSurfaceLock.unlock();
} }
mParentSurfaceSequenceId = viewRoot.getSurfaceSequenceId();
if (mViewVisibility) {
surfaceUpdateTransaction.show(mSurfaceControl);
} else {
surfaceUpdateTransaction.hide(mSurfaceControl);
}
updateBackgroundVisibility(surfaceUpdateTransaction);
updateBackgroundColor(surfaceUpdateTransaction);
if (mUseAlpha) {
float alpha = getFixedAlpha();
surfaceUpdateTransaction.setAlpha(mSurfaceControl, alpha);
mSurfaceAlpha = alpha;
}
surfaceUpdateTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
if ((sizeChanged || hintChanged) && !creating) {
setBufferSize(surfaceUpdateTransaction);
}
if (sizeChanged || creating || !isHardwareAccelerated()) {
// Set a window crop when creating the surface or changing its size to
// crop the buffer to the surface size since the buffer producer may
// use SCALING_MODE_SCALE and submit a larger size than the surface
// size.
if (mClipSurfaceToBounds && mClipBounds != null) {
surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
} else {
surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
mSurfaceHeight);
}
surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth,
mSurfaceHeight);
if (isHardwareAccelerated()) {
// This will consume the passed in transaction and the transaction will be
// applied on a render worker thread.
replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight);
} else {
onSetSurfacePositionAndScale(surfaceUpdateTransaction, mSurfaceControl,
mScreenRect.left /*positionLeft*/,
mScreenRect.top /*positionTop*/,
mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
}
if (DEBUG_POSITION) {
Log.d(TAG, String.format(
"%d performSurfaceTransaction %s "
+ "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
System.identityHashCode(this),
isHardwareAccelerated() ? "RenderWorker" : "UI Thread",
mScreenRect.left, mScreenRect.top, mScreenRect.right,
mScreenRect.bottom, mSurfaceWidth, mSurfaceHeight));
}
}
applyTransactionOnVriDraw(surfaceUpdateTransaction);
updateEmbeddedAccessibilityMatrix(false);
mSurfaceFrame.left = 0;
mSurfaceFrame.top = 0;
if (translator == null) {
mSurfaceFrame.right = mSurfaceWidth;
mSurfaceFrame.bottom = mSurfaceHeight;
} else {
float appInvertedScale = translator.applicationInvertedScale;
mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
}
final int surfaceWidth = mSurfaceFrame.right;
final int surfaceHeight = mSurfaceFrame.bottom;
realSizeChanged = mLastSurfaceWidth != surfaceWidth
|| mLastSurfaceHeight != surfaceHeight;
mLastSurfaceWidth = surfaceWidth;
mLastSurfaceHeight = surfaceHeight;
return realSizeChanged; return realSizeChanged;
} }
@@ -1103,21 +1102,30 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
* Surface for compatibility reasons. * Surface for compatibility reasons.
*/ */
private void copySurface(boolean surfaceControlCreated, boolean bufferSizeChanged) { private void copySurface(boolean surfaceControlCreated, boolean bufferSizeChanged) {
if (surfaceControlCreated) { // Some legacy applications use the underlying native {@link Surface} object
mSurface.copyFrom(mBlastBufferQueue); // as a key to whether anything has changed. In these cases, updates to the
} // existing {@link Surface} will be ignored when the size changes.
// Therefore, we must explicitly recreate the {@link Surface} in these
// cases.
boolean needsWorkaround = bufferSizeChanged &&
getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O;
if (!surfaceControlCreated && !needsWorkaround) {
return;
}
mSurfaceLock.lock();
try {
if (surfaceControlCreated) {
mSurface.copyFrom(mBlastBufferQueue);
}
if (bufferSizeChanged && getContext().getApplicationInfo().targetSdkVersion if (needsWorkaround) {
< Build.VERSION_CODES.O) { if (mBlastBufferQueue != null) {
// Some legacy applications use the underlying native {@link Surface} object mSurface.transferFrom(mBlastBufferQueue.createSurfaceWithHandle());
// as a key to whether anything has changed. In these cases, updates to the }
// existing {@link Surface} will be ignored when the size changes. }
// Therefore, we must explicitly recreate the {@link Surface} in these } finally {
// cases. mSurfaceLock.unlock();
if (mBlastBufferQueue != null) { }
mSurface.transferFrom(mBlastBufferQueue.createSurfaceWithHandle());
}
}
} }
private void setBufferSize(Transaction transaction) { private void setBufferSize(Transaction transaction) {