Merge "Ensure SKP serialization occurs on RenderThread" into qt-qpr1-dev
This commit is contained in:
@@ -868,6 +868,94 @@ public class ViewDebug {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class StreamingPictureCallbackHandler implements AutoCloseable,
|
||||||
|
HardwareRenderer.PictureCapturedCallback, Runnable {
|
||||||
|
private final HardwareRenderer mRenderer;
|
||||||
|
private final Callable<OutputStream> mCallback;
|
||||||
|
private final Executor mExecutor;
|
||||||
|
private final ReentrantLock mLock = new ReentrantLock(false);
|
||||||
|
private final ArrayDeque<byte[]> mQueue = new ArrayDeque<>(3);
|
||||||
|
private final ByteArrayOutputStream mByteStream = new ByteArrayOutputStream();
|
||||||
|
private boolean mStopListening;
|
||||||
|
private Thread mRenderThread;
|
||||||
|
|
||||||
|
private StreamingPictureCallbackHandler(HardwareRenderer renderer,
|
||||||
|
Callable<OutputStream> callback, Executor executor) {
|
||||||
|
mRenderer = renderer;
|
||||||
|
mCallback = callback;
|
||||||
|
mExecutor = executor;
|
||||||
|
mRenderer.setPictureCaptureCallback(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
mLock.lock();
|
||||||
|
mStopListening = true;
|
||||||
|
mLock.unlock();
|
||||||
|
mRenderer.setPictureCaptureCallback(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPictureCaptured(Picture picture) {
|
||||||
|
mLock.lock();
|
||||||
|
if (mStopListening) {
|
||||||
|
mLock.unlock();
|
||||||
|
mRenderer.setPictureCaptureCallback(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mRenderThread == null) {
|
||||||
|
mRenderThread = Thread.currentThread();
|
||||||
|
}
|
||||||
|
boolean needsInvoke = true;
|
||||||
|
if (mQueue.size() == 3) {
|
||||||
|
mQueue.removeLast();
|
||||||
|
needsInvoke = false;
|
||||||
|
}
|
||||||
|
picture.writeToStream(mByteStream);
|
||||||
|
mQueue.add(mByteStream.toByteArray());
|
||||||
|
mByteStream.reset();
|
||||||
|
mLock.unlock();
|
||||||
|
|
||||||
|
if (needsInvoke) {
|
||||||
|
mExecutor.execute(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mLock.lock();
|
||||||
|
final byte[] picture = mQueue.poll();
|
||||||
|
final boolean isStopped = mStopListening;
|
||||||
|
mLock.unlock();
|
||||||
|
if (Thread.currentThread() == mRenderThread) {
|
||||||
|
close();
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"ViewDebug#startRenderingCommandsCapture must be given an executor that "
|
||||||
|
+ "invokes asynchronously");
|
||||||
|
}
|
||||||
|
if (isStopped) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OutputStream stream = null;
|
||||||
|
try {
|
||||||
|
stream = mCallback.call();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.w("ViewDebug", "Aborting rendering commands capture "
|
||||||
|
+ "because callback threw exception", ex);
|
||||||
|
}
|
||||||
|
if (stream != null) {
|
||||||
|
try {
|
||||||
|
stream.write(picture);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Log.w("ViewDebug", "Aborting rendering commands capture "
|
||||||
|
+ "due to IOException writing to output stream", ex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Begins capturing the entire rendering commands for the view tree referenced by the given
|
* Begins capturing the entire rendering commands for the view tree referenced by the given
|
||||||
* view. The view passed may be any View in the tree as long as it is attached. That is,
|
* view. The view passed may be any View in the tree as long as it is attached. That is,
|
||||||
@@ -913,18 +1001,7 @@ public class ViewDebug {
|
|||||||
}
|
}
|
||||||
final HardwareRenderer renderer = attachInfo.mThreadedRenderer;
|
final HardwareRenderer renderer = attachInfo.mThreadedRenderer;
|
||||||
if (renderer != null) {
|
if (renderer != null) {
|
||||||
return new PictureCallbackHandler(renderer, (picture -> {
|
return new StreamingPictureCallbackHandler(renderer, callback, executor);
|
||||||
try {
|
|
||||||
OutputStream stream = callback.call();
|
|
||||||
if (stream != null) {
|
|
||||||
picture.writeToStream(stream);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
// fall through
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}), executor);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user