fix undefined behavior when skipping drawFrames

Bug: skia:10467
Change-Id: I2831938cde36c77129b013173c8a19120077f507
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/299919
Commit-Queue: Jorge Betancourt <jmbetancourt@google.com>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Reviewed-by: Stan Iliev <stani@google.com>
This commit is contained in:
Jorge Betancourt 2020-07-01 16:27:41 -04:00 committed by Skia Commit-Bot
parent 6d344c3069
commit 4522f6e82d
2 changed files with 26 additions and 22 deletions

View File

@ -173,7 +173,7 @@ Java_org_skia_skottie_SkottieRunner_00024SkottieAnimationImpl_nDeleteProxy(JNIEn
delete skottieAnimation;
}
extern "C" JNIEXPORT void
extern "C" JNIEXPORT bool
JNICALL
Java_org_skia_skottie_SkottieRunner_00024SkottieAnimationImpl_nDrawFrame(JNIEnv *env, jclass clazz,
jlong nativeProxy, jint width,
@ -182,14 +182,14 @@ Java_org_skia_skottie_SkottieRunner_00024SkottieAnimationImpl_nDrawFrame(JNIEnv
jfloat progress) {
ATRACE_NAME("SkottieDrawFrame");
if (!nativeProxy) {
return;
return false;
}
SkottieAnimation* skottieAnimation = reinterpret_cast<SkottieAnimation*>(nativeProxy);
auto grContext = skottieAnimation->mRunner->mGrContext;
if (!grContext) {
return;
return false;
}
sksg::InvalidationController ic;
@ -197,7 +197,7 @@ Java_org_skia_skottie_SkottieRunner_00024SkottieAnimationImpl_nDrawFrame(JNIEnv
if (skottieAnimation->mAnimation) {
skottieAnimation->mAnimation->seek(progress, &ic);
if (ic.bounds().isEmpty()) {
return;
return false;
}
}
@ -228,6 +228,7 @@ Java_org_skia_skottie_SkottieRunner_00024SkottieAnimationImpl_nDrawFrame(JNIEnv
skottieAnimation->mAnimation->render(canvas, &bounds);
canvas->flush();
return true;
}
extern "C" JNIEXPORT jlong

View File

@ -456,28 +456,31 @@ class SkottieRunner {
mNewSurface = true;
return;
}
nDrawFrame(mNativeProxy, mSurfaceWidth, mSurfaceHeight, false,
mProgress);
if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
int error = mEgl.eglGetError();
if (error == EGL10.EGL_BAD_SURFACE
// only if nDrawFrames() returns true do we need to swap buffers
if(nDrawFrame(mNativeProxy, mSurfaceWidth, mSurfaceHeight, false,
mProgress)) {
if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
int error = mEgl.eglGetError();
if (error == EGL10.EGL_BAD_SURFACE
|| error == EGL10.EGL_BAD_NATIVE_WINDOW) {
// For some reason our surface was destroyed. Recreate EGL surface
// on next frame.
mNewSurface = true;
// This really shouldn't happen, but if it does we can recover easily
// by just not trying to use the surface anymore
Log.w(LOG_TAG, "swapBuffers failed "
// For some reason our surface was destroyed. Recreate EGL surface
// on next frame.
mNewSurface = true;
// This really shouldn't happen, but if it does we can recover
// easily by just not trying to use the surface anymore
Log.w(LOG_TAG, "swapBuffers failed "
+ GLUtils.getEGLErrorString(error));
return;
}
return;
}
// Some other fatal EGL error happened, log an error and stop the animation.
throw new RuntimeException("Cannot swap buffers "
// Some other fatal EGL error happened, log an error and stop the
// animation.
throw new RuntimeException("Cannot swap buffers "
+ GLUtils.getEGLErrorString(error));
}
}
// If animation stopped, release EGL surface.
if (!mIsRunning) {
// Ensure we always have a valid surface & context.
@ -538,8 +541,8 @@ class SkottieRunner {
private native long nCreateProxy(long runner, ByteBuffer data);
private native void nDeleteProxy(long nativeProxy);
private native void nDrawFrame(long nativeProxy, int width, int height,
boolean wideColorGamut, float progress);
private native boolean nDrawFrame(long nativeProxy, int width, int height,
boolean wideColorGamut, float progress);
private native long nGetDuration(long nativeProxy);
}