@CalledByNative
  private void requestRender() {
    ContentViewCore contentViewCore =
        mCurrentContentView != null ? mCurrentContentView.getContentViewCore() : null;

    boolean rendererHasFrame =
        contentViewCore != null && contentViewCore.consumePendingRendererFrame();

    if (rendererHasFrame && mPendingSwapBuffers + mPendingRenders < MAX_SWAP_BUFFER_COUNT) {
      TraceEvent.instant("requestRender:now");
      mNeedToRender = false;
      mPendingRenders++;

      // The handler can be null if we are detached from the window.  Calling
      // {@link View#post(Runnable)} properly handles this case, but we lose the front of
      // queue behavior.  That is okay for this edge case.
      Handler handler = getHandler();
      if (handler != null) {
        handler.postAtFrontOfQueue(mRenderRunnable);
      } else {
        post(mRenderRunnable);
      }
      mVSyncAdapter.requestUpdate();
    } else if (mPendingRenders <= 0) {
      assert mPendingRenders == 0;
      TraceEvent.instant("requestRender:later");
      mNeedToRender = true;
      mVSyncAdapter.requestUpdate();
    }
  }