Loading core/java/android/view/RenderNode.java +5 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,9 @@ public class RenderNode { private RenderNode(String name, View owningView) { mNativeRenderNode = nCreate(name); mOwningView = owningView; if (mOwningView instanceof SurfaceView) { nRequestPositionUpdates(mNativeRenderNode, (SurfaceView) mOwningView); } } /** Loading Loading @@ -863,6 +866,8 @@ public class RenderNode { private static native void nOutput(long renderNode); private static native int nGetDebugSize(long renderNode); private static native void nRequestPositionUpdates(long renderNode, SurfaceView callback); /////////////////////////////////////////////////////////////////////////// // Animations /////////////////////////////////////////////////////////////////////////// Loading core/java/android/view/SurfaceView.java +73 −28 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ public class SurfaceView extends View { } }; final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { Loading @@ -143,6 +143,17 @@ public class SurfaceView extends View { } }; private final ViewTreeObserver.OnPreDrawListener mDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { // reposition ourselves where the surface is mHaveFrame = getWidth() > 0 && getHeight() > 0; updateWindow(false, false); return true; } }; boolean mRequestedVisible = false; boolean mWindowVisibility = false; boolean mViewVisibility = false; Loading @@ -168,17 +179,9 @@ public class SurfaceView extends View { boolean mUpdateWindowNeeded; boolean mReportDrawNeeded; private Translator mTranslator; private int mWindowInsetLeft; private int mWindowInsetTop; private final ViewTreeObserver.OnPreDrawListener mDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { // reposition ourselves where the surface is mHaveFrame = getWidth() > 0 && getHeight() > 0; updateWindow(false, false); return true; } }; private boolean mGlobalListenersAdded; public SurfaceView(Context context) { Loading Loading @@ -443,17 +446,17 @@ public class SurfaceView extends View { int myHeight = mRequestedHeight; if (myHeight <= 0) myHeight = getHeight(); getLocationInWindow(mLocation); final boolean creating = mWindow == null; final boolean formatChanged = mFormat != mRequestedFormat; final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight; final boolean visibleChanged = mVisible != mRequestedVisible; final boolean layoutSizeChanged = getWidth() != mLayout.width || getHeight() != mLayout.height; final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; if (force || creating || formatChanged || sizeChanged || visibleChanged || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) { getLocationInWindow(mLocation); if (DEBUG) Log.i(TAG, "Changes: creating=" + creating + " format=" + formatChanged + " size=" + sizeChanged + " visible=" + visibleChanged Loading Loading @@ -643,7 +646,11 @@ public class SurfaceView extends View { TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + " w=" + mLayout.width + " h=" + mLayout.height + ", frame=" + mSurfaceFrame); } else if (positionChanged || layoutSizeChanged) { // Only the position has changed } else if (!isHardwareAccelerated()) { getLocationInWindow(mLocation); final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; if (positionChanged || layoutSizeChanged) { // Only the position has changed mWindowSpaceLeft = mLocation[0]; mWindowSpaceTop = mLocation[1]; // For our size changed check, we keep mLayout.width and mLayout.height Loading @@ -654,15 +661,53 @@ public class SurfaceView extends View { transformFromViewToWindowSpace(mLocation); try { Log.d(TAG, String.format("updateWindowPosition UI, " + "postion = [%d, %d, %d, %d]", mWindowSpaceLeft, mWindowSpaceTop, mLocation[0], mLocation[1])); mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop, mLocation[0], mLocation[1], viewRoot != null ? viewRoot.getNextFrameNumber() : -1, mWinFrame); mLocation[0], mLocation[1], -1, mWinFrame); } catch (RemoteException ex) { Log.e(TAG, "Exception from relayout", ex); } } } } private Rect mRTLastReportedPosition = new Rect(); /** * Called by native on RenderThread to update the window position * @hide */ public final void updateWindowPositionRT(long frameNumber, int left, int top, int right, int bottom) { IWindowSession session = mSession; MyWindow window = mWindow; if (session == null || window == null) { // Guess we got detached, that sucks return; } if (mRTLastReportedPosition.left == left && mRTLastReportedPosition.top == top && mRTLastReportedPosition.right == right && mRTLastReportedPosition.bottom == bottom) { return; } try { if (DEBUG) { Log.d(TAG, String.format("updateWindowPosition RT, frameNr = %d, " + "postion = [%d, %d, %d, %d]", frameNumber, left, top, right, bottom)); } // Just using mRTLastReportedPosition as a dummy rect here session.repositionChild(window, left, top, right, bottom, frameNumber, mRTLastReportedPosition); // Now overwrite mRTLastReportedPosition with our values mRTLastReportedPosition.set(left, top, right, bottom); } catch (RemoteException ex) { Log.e(TAG, "Exception from repositionChild", ex); } } private SurfaceHolder.Callback[] getSurfaceCallbacks() { SurfaceHolder.Callback callbacks[]; Loading core/java/android/view/ViewRootImpl.java +0 −14 Original line number Diff line number Diff line Loading @@ -6815,20 +6815,6 @@ public final class ViewRootImpl implements ViewParent, } } long getNextFrameNumber() { long frameNumber = -1; if (mSurfaceHolder != null) { mSurfaceHolder.mSurfaceLock.lock(); } if (mSurface.isValid()) { frameNumber = mSurface.getNextFrameNumber(); } if (mSurfaceHolder != null) { mSurfaceHolder.mSurfaceLock.unlock(); } return frameNumber; } class TakenSurfaceHolder extends BaseSurfaceHolder { @Override public boolean onAllowLockCanvas() { Loading core/jni/android_view_RenderNode.cpp +72 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ #define LOG_TAG "OpenGLRenderer" #define ATRACE_TAG ATRACE_TAG_VIEW #include <EGL/egl.h> Loading @@ -24,7 +25,10 @@ #include <android_runtime/AndroidRuntime.h> #include <Animator.h> #include <DamageAccumulator.h> #include <Matrix.h> #include <RenderNode.h> #include <TreeInfo.h> #include <Paint.h> #include "core_jni_helpers.h" Loading Loading @@ -461,6 +465,69 @@ static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz, renderNode->animators().endAllStagingAnimators(); } // ---------------------------------------------------------------------------- // SurfaceView position callback // ---------------------------------------------------------------------------- jmethodID gSurfaceViewPositionUpdateMethod; static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, jlong renderNodePtr, jobject surfaceview) { class SurfaceViewPositionUpdater : public RenderNode::PositionListener { public: SurfaceViewPositionUpdater(JNIEnv* env, jobject surfaceview) { env->GetJavaVM(&mVm); mWeakRef = env->NewWeakGlobalRef(surfaceview); } virtual ~SurfaceViewPositionUpdater() { jnienv()->DeleteWeakGlobalRef(mWeakRef); mWeakRef = nullptr; } virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) override { if (CC_UNLIKELY(!mWeakRef || !info.updateWindowPositions)) return; ATRACE_NAME("Update SurfaceView position"); JNIEnv* env = jnienv(); jobject localref = env->NewLocalRef(mWeakRef); if (CC_UNLIKELY(!localref)) { jnienv()->DeleteWeakGlobalRef(mWeakRef); mWeakRef = nullptr; return; } Matrix4 transform; info.damageAccumulator->computeCurrentTransform(&transform); const RenderProperties& props = node.properties(); uirenderer::Rect bounds(props.getWidth(), props.getHeight()); transform.mapRect(bounds); bounds.left -= info.windowInsetLeft; bounds.right -= info.windowInsetLeft; bounds.top -= info.windowInsetTop; bounds.bottom -= info.windowInsetTop; env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod, (jlong) info.frameNumber, (jint) bounds.left, (jint) bounds.top, (jint) bounds.right, (jint) bounds.bottom); env->DeleteLocalRef(localref); } private: JNIEnv* jnienv() { JNIEnv* env; if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", mVm); } return env; } JavaVM* mVm; jobject mWeakRef; }; RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); renderNode->setPositionListener(new SurfaceViewPositionUpdater(env, surfaceview)); } // ---------------------------------------------------------------------------- // JNI Glue // ---------------------------------------------------------------------------- Loading Loading @@ -539,9 +606,14 @@ static const JNINativeMethod gMethods[] = { { "nAddAnimator", "(JJ)V", (void*) android_view_RenderNode_addAnimator }, { "nEndAllAnimators", "(J)V", (void*) android_view_RenderNode_endAllAnimators }, { "nRequestPositionUpdates", "(JLandroid/view/SurfaceView;)V", (void*) android_view_RenderNode_requestPositionUpdates }, }; int register_android_view_RenderNode(JNIEnv* env) { jclass clazz = FindClassOrDie(env, "android/view/SurfaceView"); gSurfaceViewPositionUpdateMethod = GetMethodIDOrDie(env, clazz, "updateWindowPositionRT", "(JIIII)V"); return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } Loading core/jni/android_view_ThreadedRenderer.cpp +15 −8 Original line number Diff line number Diff line Loading @@ -134,7 +134,14 @@ public: virtual void prepareTree(TreeInfo& info) { info.errorHandler = this; // TODO: This is hacky info.windowInsetLeft = -stagingProperties().getLeft(); info.windowInsetTop = -stagingProperties().getTop(); info.updateWindowPositions = true; RenderNode::prepareTree(info); info.updateWindowPositions = false; info.windowInsetLeft = 0; info.windowInsetTop = 0; info.errorHandler = NULL; } Loading Loading @@ -369,28 +376,28 @@ static void android_view_ThreadedRenderer_setName(JNIEnv* env, jobject clazz, static void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface); proxy->initialize(window); sp<Surface> surface = android_view_Surface_getSurface(env, jsurface); proxy->initialize(surface); } static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); sp<ANativeWindow> window; sp<Surface> surface; if (jsurface) { window = android_view_Surface_getNativeWindow(env, jsurface); surface = android_view_Surface_getSurface(env, jsurface); } proxy->updateSurface(window); proxy->updateSurface(surface); } static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); sp<ANativeWindow> window; sp<Surface> surface; if (jsurface) { window = android_view_Surface_getNativeWindow(env, jsurface); surface = android_view_Surface_getSurface(env, jsurface); } return proxy->pauseSurface(window); return proxy->pauseSurface(surface); } static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr, Loading Loading
core/java/android/view/RenderNode.java +5 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,9 @@ public class RenderNode { private RenderNode(String name, View owningView) { mNativeRenderNode = nCreate(name); mOwningView = owningView; if (mOwningView instanceof SurfaceView) { nRequestPositionUpdates(mNativeRenderNode, (SurfaceView) mOwningView); } } /** Loading Loading @@ -863,6 +866,8 @@ public class RenderNode { private static native void nOutput(long renderNode); private static native int nGetDebugSize(long renderNode); private static native void nRequestPositionUpdates(long renderNode, SurfaceView callback); /////////////////////////////////////////////////////////////////////////// // Animations /////////////////////////////////////////////////////////////////////////// Loading
core/java/android/view/SurfaceView.java +73 −28 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ public class SurfaceView extends View { } }; final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { Loading @@ -143,6 +143,17 @@ public class SurfaceView extends View { } }; private final ViewTreeObserver.OnPreDrawListener mDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { // reposition ourselves where the surface is mHaveFrame = getWidth() > 0 && getHeight() > 0; updateWindow(false, false); return true; } }; boolean mRequestedVisible = false; boolean mWindowVisibility = false; boolean mViewVisibility = false; Loading @@ -168,17 +179,9 @@ public class SurfaceView extends View { boolean mUpdateWindowNeeded; boolean mReportDrawNeeded; private Translator mTranslator; private int mWindowInsetLeft; private int mWindowInsetTop; private final ViewTreeObserver.OnPreDrawListener mDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { // reposition ourselves where the surface is mHaveFrame = getWidth() > 0 && getHeight() > 0; updateWindow(false, false); return true; } }; private boolean mGlobalListenersAdded; public SurfaceView(Context context) { Loading Loading @@ -443,17 +446,17 @@ public class SurfaceView extends View { int myHeight = mRequestedHeight; if (myHeight <= 0) myHeight = getHeight(); getLocationInWindow(mLocation); final boolean creating = mWindow == null; final boolean formatChanged = mFormat != mRequestedFormat; final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight; final boolean visibleChanged = mVisible != mRequestedVisible; final boolean layoutSizeChanged = getWidth() != mLayout.width || getHeight() != mLayout.height; final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; if (force || creating || formatChanged || sizeChanged || visibleChanged || mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) { getLocationInWindow(mLocation); if (DEBUG) Log.i(TAG, "Changes: creating=" + creating + " format=" + formatChanged + " size=" + sizeChanged + " visible=" + visibleChanged Loading Loading @@ -643,7 +646,11 @@ public class SurfaceView extends View { TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y + " w=" + mLayout.width + " h=" + mLayout.height + ", frame=" + mSurfaceFrame); } else if (positionChanged || layoutSizeChanged) { // Only the position has changed } else if (!isHardwareAccelerated()) { getLocationInWindow(mLocation); final boolean positionChanged = mWindowSpaceLeft != mLocation[0] || mWindowSpaceTop != mLocation[1]; if (positionChanged || layoutSizeChanged) { // Only the position has changed mWindowSpaceLeft = mLocation[0]; mWindowSpaceTop = mLocation[1]; // For our size changed check, we keep mLayout.width and mLayout.height Loading @@ -654,15 +661,53 @@ public class SurfaceView extends View { transformFromViewToWindowSpace(mLocation); try { Log.d(TAG, String.format("updateWindowPosition UI, " + "postion = [%d, %d, %d, %d]", mWindowSpaceLeft, mWindowSpaceTop, mLocation[0], mLocation[1])); mSession.repositionChild(mWindow, mWindowSpaceLeft, mWindowSpaceTop, mLocation[0], mLocation[1], viewRoot != null ? viewRoot.getNextFrameNumber() : -1, mWinFrame); mLocation[0], mLocation[1], -1, mWinFrame); } catch (RemoteException ex) { Log.e(TAG, "Exception from relayout", ex); } } } } private Rect mRTLastReportedPosition = new Rect(); /** * Called by native on RenderThread to update the window position * @hide */ public final void updateWindowPositionRT(long frameNumber, int left, int top, int right, int bottom) { IWindowSession session = mSession; MyWindow window = mWindow; if (session == null || window == null) { // Guess we got detached, that sucks return; } if (mRTLastReportedPosition.left == left && mRTLastReportedPosition.top == top && mRTLastReportedPosition.right == right && mRTLastReportedPosition.bottom == bottom) { return; } try { if (DEBUG) { Log.d(TAG, String.format("updateWindowPosition RT, frameNr = %d, " + "postion = [%d, %d, %d, %d]", frameNumber, left, top, right, bottom)); } // Just using mRTLastReportedPosition as a dummy rect here session.repositionChild(window, left, top, right, bottom, frameNumber, mRTLastReportedPosition); // Now overwrite mRTLastReportedPosition with our values mRTLastReportedPosition.set(left, top, right, bottom); } catch (RemoteException ex) { Log.e(TAG, "Exception from repositionChild", ex); } } private SurfaceHolder.Callback[] getSurfaceCallbacks() { SurfaceHolder.Callback callbacks[]; Loading
core/java/android/view/ViewRootImpl.java +0 −14 Original line number Diff line number Diff line Loading @@ -6815,20 +6815,6 @@ public final class ViewRootImpl implements ViewParent, } } long getNextFrameNumber() { long frameNumber = -1; if (mSurfaceHolder != null) { mSurfaceHolder.mSurfaceLock.lock(); } if (mSurface.isValid()) { frameNumber = mSurface.getNextFrameNumber(); } if (mSurfaceHolder != null) { mSurfaceHolder.mSurfaceLock.unlock(); } return frameNumber; } class TakenSurfaceHolder extends BaseSurfaceHolder { @Override public boolean onAllowLockCanvas() { Loading
core/jni/android_view_RenderNode.cpp +72 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ */ #define LOG_TAG "OpenGLRenderer" #define ATRACE_TAG ATRACE_TAG_VIEW #include <EGL/egl.h> Loading @@ -24,7 +25,10 @@ #include <android_runtime/AndroidRuntime.h> #include <Animator.h> #include <DamageAccumulator.h> #include <Matrix.h> #include <RenderNode.h> #include <TreeInfo.h> #include <Paint.h> #include "core_jni_helpers.h" Loading Loading @@ -461,6 +465,69 @@ static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz, renderNode->animators().endAllStagingAnimators(); } // ---------------------------------------------------------------------------- // SurfaceView position callback // ---------------------------------------------------------------------------- jmethodID gSurfaceViewPositionUpdateMethod; static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, jlong renderNodePtr, jobject surfaceview) { class SurfaceViewPositionUpdater : public RenderNode::PositionListener { public: SurfaceViewPositionUpdater(JNIEnv* env, jobject surfaceview) { env->GetJavaVM(&mVm); mWeakRef = env->NewWeakGlobalRef(surfaceview); } virtual ~SurfaceViewPositionUpdater() { jnienv()->DeleteWeakGlobalRef(mWeakRef); mWeakRef = nullptr; } virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) override { if (CC_UNLIKELY(!mWeakRef || !info.updateWindowPositions)) return; ATRACE_NAME("Update SurfaceView position"); JNIEnv* env = jnienv(); jobject localref = env->NewLocalRef(mWeakRef); if (CC_UNLIKELY(!localref)) { jnienv()->DeleteWeakGlobalRef(mWeakRef); mWeakRef = nullptr; return; } Matrix4 transform; info.damageAccumulator->computeCurrentTransform(&transform); const RenderProperties& props = node.properties(); uirenderer::Rect bounds(props.getWidth(), props.getHeight()); transform.mapRect(bounds); bounds.left -= info.windowInsetLeft; bounds.right -= info.windowInsetLeft; bounds.top -= info.windowInsetTop; bounds.bottom -= info.windowInsetTop; env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod, (jlong) info.frameNumber, (jint) bounds.left, (jint) bounds.top, (jint) bounds.right, (jint) bounds.bottom); env->DeleteLocalRef(localref); } private: JNIEnv* jnienv() { JNIEnv* env; if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", mVm); } return env; } JavaVM* mVm; jobject mWeakRef; }; RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); renderNode->setPositionListener(new SurfaceViewPositionUpdater(env, surfaceview)); } // ---------------------------------------------------------------------------- // JNI Glue // ---------------------------------------------------------------------------- Loading Loading @@ -539,9 +606,14 @@ static const JNINativeMethod gMethods[] = { { "nAddAnimator", "(JJ)V", (void*) android_view_RenderNode_addAnimator }, { "nEndAllAnimators", "(J)V", (void*) android_view_RenderNode_endAllAnimators }, { "nRequestPositionUpdates", "(JLandroid/view/SurfaceView;)V", (void*) android_view_RenderNode_requestPositionUpdates }, }; int register_android_view_RenderNode(JNIEnv* env) { jclass clazz = FindClassOrDie(env, "android/view/SurfaceView"); gSurfaceViewPositionUpdateMethod = GetMethodIDOrDie(env, clazz, "updateWindowPositionRT", "(JIIII)V"); return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } Loading
core/jni/android_view_ThreadedRenderer.cpp +15 −8 Original line number Diff line number Diff line Loading @@ -134,7 +134,14 @@ public: virtual void prepareTree(TreeInfo& info) { info.errorHandler = this; // TODO: This is hacky info.windowInsetLeft = -stagingProperties().getLeft(); info.windowInsetTop = -stagingProperties().getTop(); info.updateWindowPositions = true; RenderNode::prepareTree(info); info.updateWindowPositions = false; info.windowInsetLeft = 0; info.windowInsetTop = 0; info.errorHandler = NULL; } Loading Loading @@ -369,28 +376,28 @@ static void android_view_ThreadedRenderer_setName(JNIEnv* env, jobject clazz, static void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface); proxy->initialize(window); sp<Surface> surface = android_view_Surface_getSurface(env, jsurface); proxy->initialize(surface); } static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); sp<ANativeWindow> window; sp<Surface> surface; if (jsurface) { window = android_view_Surface_getNativeWindow(env, jsurface); surface = android_view_Surface_getSurface(env, jsurface); } proxy->updateSurface(window); proxy->updateSurface(surface); } static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); sp<ANativeWindow> window; sp<Surface> surface; if (jsurface) { window = android_view_Surface_getNativeWindow(env, jsurface); surface = android_view_Surface_getSurface(env, jsurface); } return proxy->pauseSurface(window); return proxy->pauseSurface(surface); } static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr, Loading