@@ -502,7 +502,9 @@ static abstract class GlRenderer extends HardwareRenderer {
502502 static final int SURFACE_STATE_ERROR = 0 ;
503503 static final int SURFACE_STATE_SUCCESS = 1 ;
504504 static final int SURFACE_STATE_UPDATED = 2 ;
505-
505+
506+ static final int FUNCTOR_PROCESS_DELAY = 2 ;
507+
506508 static EGL10 sEgl ;
507509 static EGLDisplay sEglDisplay ;
508510 static EGLConfig sEglConfig ;
@@ -549,7 +551,9 @@ static abstract class GlRenderer extends HardwareRenderer {
549551 private boolean mDestroyed ;
550552
551553 private final Rect mRedrawClip = new Rect ();
554+
552555 private final int [] mSurfaceSize = new int [2 ];
556+ private final FunctorsRunnable mFunctorsRunnable = new FunctorsRunnable ();
553557
554558 GlRenderer (int glVersion , boolean translucent ) {
555559 mGlVersion = glVersion ;
@@ -957,6 +961,24 @@ void onPreDraw(Rect dirty) {
957961 void onPostDraw () {
958962 }
959963
964+ class FunctorsRunnable implements Runnable {
965+ View .AttachInfo attachInfo ;
966+
967+ @ Override
968+ public void run () {
969+ final HardwareRenderer renderer = attachInfo .mHardwareRenderer ;
970+ if (renderer == null || !renderer .isEnabled () || renderer != GlRenderer .this ) {
971+ return ;
972+ }
973+
974+ final int surfaceState = checkCurrent ();
975+ if (surfaceState != SURFACE_STATE_ERROR ) {
976+ int status = mCanvas .invokeFunctors (mRedrawClip );
977+ handleFunctorStatus (attachInfo , status );
978+ }
979+ }
980+ }
981+
960982 @ Override
961983 boolean draw (View view , View .AttachInfo attachInfo , HardwareDrawCallbacks callbacks ,
962984 Rect dirty ) {
@@ -1051,15 +1073,7 @@ boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callba
10511073 }
10521074 }
10531075
1054- if (status != DisplayList .STATUS_DONE ) {
1055- if (mRedrawClip .isEmpty ()) {
1056- attachInfo .mViewRootImpl .invalidate ();
1057- } else {
1058- attachInfo .mViewRootImpl .invalidateChildInParent (
1059- null , mRedrawClip );
1060- mRedrawClip .setEmpty ();
1061- }
1062- }
1076+ handleFunctorStatus (attachInfo , status );
10631077 } else {
10641078 // Shouldn't reach here
10651079 view .draw (canvas );
@@ -1111,6 +1125,26 @@ boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callba
11111125 return false ;
11121126 }
11131127
1128+ private void handleFunctorStatus (View .AttachInfo attachInfo , int status ) {
1129+ // If the draw flag is set, functors will be invoked while executing
1130+ // the tree of display lists
1131+ if ((status & DisplayList .STATUS_DRAW ) != 0 ) {
1132+ if (mRedrawClip .isEmpty ()) {
1133+ attachInfo .mViewRootImpl .invalidate ();
1134+ } else {
1135+ attachInfo .mViewRootImpl .invalidateChildInParent (null , mRedrawClip );
1136+ mRedrawClip .setEmpty ();
1137+ }
1138+ }
1139+
1140+ if ((status & DisplayList .STATUS_INVOKE ) != 0 ) {
1141+ attachInfo .mHandler .removeCallbacks (mFunctorsRunnable );
1142+ mFunctorsRunnable .attachInfo = attachInfo ;
1143+ // delay the functor callback by a few ms so it isn't polled constantly
1144+ attachInfo .mHandler .postDelayed (mFunctorsRunnable , FUNCTOR_PROCESS_DELAY );
1145+ }
1146+ }
1147+
11141148 /**
11151149 * Ensures the current EGL context is the one we expect.
11161150 *
0 commit comments