/**
  * This function is invoked by Gecko (compositor thread) via JNI; be careful when modifying
  * signature.
  */
 public static GLController registerCxxCompositor() {
   try {
     LayerView layerView = GeckoAppShell.getLayerView();
     GLController controller = layerView.getGLController();
     controller.compositorCreated();
     return controller;
   } catch (Exception e) {
     Log.e(LOGTAG, "Error registering compositor!", e);
     return null;
   }
 }
  private void surfaceChanged(int width, int height) {
    mGLController.surfaceChanged(width, height);

    if (mListener != null) {
      mListener.surfaceChanged(width, height);
    }
  }
  public LayerView(Context context, AttributeSet attrs) {
    super(context, attrs);

    mGLController = GLController.getInstance(this);
    mPaintState = PAINT_START;
    mBackgroundColor = Color.WHITE;

    mTouchInterceptors = new ArrayList<TouchEventInterceptor>();
  }
  /* When using a SurfaceView (mSurfaceView != null), resizing happens in two
   * phases. First, the LayerView changes size, then, often some frames later,
   * the SurfaceView changes size. Because of this, we need to split the
   * resize into two phases to avoid jittering.
   *
   * The first phase is the LayerView size change. mListener is notified so
   * that a synchronous draw can be performed (otherwise a blank frame will
   * appear).
   *
   * The second phase is the SurfaceView size change. At this point, the
   * backing GL surface is resized and another synchronous draw is performed.
   * Gecko is also sent the new window size, and this will likely cause an
   * extra draw a few frames later, after it's re-rendered and caught up.
   *
   * In the case that there is no valid GL surface (for example, when
   * resuming, or when coming back from the awesomescreen), or we're using a
   * TextureView instead of a SurfaceView, the first phase is skipped.
   */
  private void onSizeChanged(int width, int height) {
    if (!mGLController.hasValidSurface() || mSurfaceView == null) {
      surfaceChanged(width, height);
      return;
    }

    if (mListener != null) {
      mListener.sizeChanged(width, height);
    }
  }
 private void onDestroyed() {
   mGLController.surfaceDestroyed();
 }