Merge "ImageWriter: remove mCloseLock guard from queue and dequeue operations" into tm-qpr-dev am: 8809b27560

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

Change-Id: Ifa8be1fc14bb67968d041d770b06258f597da44a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Avichal Rakesh
2023-01-05 00:03:54 +00:00
committed by Automerger Merge Worker

View File

@@ -431,17 +431,15 @@ public class ImageWriter implements AutoCloseable {
* @see Image#close * @see Image#close
*/ */
public Image dequeueInputImage() { public Image dequeueInputImage() {
synchronized (mCloseLock) { if (mDequeuedImages.size() >= mMaxImages) {
if (mDequeuedImages.size() >= mMaxImages) { throw new IllegalStateException(
throw new IllegalStateException( "Already dequeued max number of Images " + mMaxImages);
"Already dequeued max number of Images " + mMaxImages);
}
WriterSurfaceImage newImage = new WriterSurfaceImage(this);
nativeDequeueInputImage(mNativeContext, newImage);
mDequeuedImages.add(newImage);
newImage.mIsImageValid = true;
return newImage;
} }
WriterSurfaceImage newImage = new WriterSurfaceImage(this);
nativeDequeueInputImage(mNativeContext, newImage);
mDequeuedImages.add(newImage);
newImage.mIsImageValid = true;
return newImage;
} }
/** /**
@@ -500,52 +498,50 @@ public class ImageWriter implements AutoCloseable {
throw new IllegalArgumentException("image shouldn't be null"); throw new IllegalArgumentException("image shouldn't be null");
} }
synchronized (mCloseLock) { boolean ownedByMe = isImageOwnedByMe(image);
boolean ownedByMe = isImageOwnedByMe(image); if (ownedByMe && !(((WriterSurfaceImage) image).mIsImageValid)) {
if (ownedByMe && !(((WriterSurfaceImage) image).mIsImageValid)) { throw new IllegalStateException("Image from ImageWriter is invalid");
throw new IllegalStateException("Image from ImageWriter is invalid"); }
// For images from other components that have non-null owner, need to detach first,
// then attach. Images without owners must already be attachable.
if (!ownedByMe) {
if ((image.getOwner() instanceof ImageReader)) {
ImageReader prevOwner = (ImageReader) image.getOwner();
prevOwner.detachImage(image);
} else if (image.getOwner() != null) {
throw new IllegalArgumentException(
"Only images from ImageReader can be queued to"
+ " ImageWriter, other image source is not supported yet!");
} }
// For images from other components that have non-null owner, need to detach first, attachAndQueueInputImage(image);
// then attach. Images without owners must already be attachable. // This clears the native reference held by the original owner.
if (!ownedByMe) { // When this Image is detached later by this ImageWriter, the
if ((image.getOwner() instanceof ImageReader)) { // native memory won't be leaked.
ImageReader prevOwner = (ImageReader) image.getOwner(); image.close();
return;
}
prevOwner.detachImage(image); Rect crop = image.getCropRect();
} else if (image.getOwner() != null) { nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), image.getDataSpace(),
throw new IllegalArgumentException( crop.left, crop.top, crop.right, crop.bottom, image.getTransform(),
"Only images from ImageReader can be queued to" image.getScalingMode());
+ " ImageWriter, other image source is not supported yet!");
}
attachAndQueueInputImage(image); /**
// This clears the native reference held by the original owner. * Only remove and cleanup the Images that are owned by this
// When this Image is detached later by this ImageWriter, the * ImageWriter. Images detached from other owners are only temporarily
// native memory won't be leaked. * owned by this ImageWriter and will be detached immediately after they
image.close(); * are released by downstream consumers, so there is no need to keep
return; * track of them in mDequeuedImages.
} */
if (ownedByMe) {
Rect crop = image.getCropRect(); mDequeuedImages.remove(image);
nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), image.getDataSpace(), // Do not call close here, as close is essentially cancel image.
crop.left, crop.top, crop.right, crop.bottom, image.getTransform(), WriterSurfaceImage wi = (WriterSurfaceImage) image;
image.getScalingMode()); wi.clearSurfacePlanes();
wi.mIsImageValid = false;
/**
* Only remove and cleanup the Images that are owned by this
* ImageWriter. Images detached from other owners are only temporarily
* owned by this ImageWriter and will be detached immediately after they
* are released by downstream consumers, so there is no need to keep
* track of them in mDequeuedImages.
*/
if (ownedByMe) {
mDequeuedImages.remove(image);
// Do not call close here, as close is essentially cancel image.
WriterSurfaceImage wi = (WriterSurfaceImage) image;
wi.clearSurfacePlanes();
wi.mIsImageValid = false;
}
} }
} }
@@ -681,11 +677,11 @@ public class ImageWriter implements AutoCloseable {
*/ */
@Override @Override
public void close() { public void close() {
setOnImageReleasedListener(null, null);
synchronized (mCloseLock) { synchronized (mCloseLock) {
if (!mIsWriterValid) { if (!mIsWriterValid) {
return; return;
} }
setOnImageReleasedListener(null, null);
for (Image image : mDequeuedImages) { for (Image image : mDequeuedImages) {
image.close(); image.close();
} }
@@ -817,14 +813,12 @@ public class ImageWriter implements AutoCloseable {
} }
final Handler handler; final Handler handler;
final boolean isWriterValid;
synchronized (iw.mListenerLock) { synchronized (iw.mListenerLock) {
handler = iw.mListenerHandler; handler = iw.mListenerHandler;
} }
synchronized (iw.mCloseLock) {
isWriterValid = iw.mIsWriterValid; if (handler != null) {
} // The ListenerHandler will take care of ensuring that the parent ImageWriter is valid
if (handler != null && isWriterValid) {
handler.sendEmptyMessage(0); handler.sendEmptyMessage(0);
} }
} }