public void finish() {
    if (parentCanvas == null || op == null || preExistingTransform == null || targetRect == null) {
      throw new IllegalStateException("OffscreenBitmap: finish() call without matching start()");
    }

    switch (currentStrategy) {
      case DIRECT:
        parentCanvas.restore();
        break;

      case SAVE_LAYER:
        parentCanvas.restore();
        break;

      case BITMAP:
        if (bitmap == null) {
          throw new IllegalStateException("Bitmap is not ready; should've been initialized at start() time");
        }

        if (op.hasShadow()) {
          // Composing the shadow first and then the content like this will be incorrect in the
          // presence of op.blendMode. However, that is not used at the moment, so this
          // optimization is safe. (Otherwise, we'd have to have another bitmap here for the
          // intermediate result.)
          renderBitmapShadow(parentCanvas, op.shadow);
        }

        if (bitmapSrcRect == null) bitmapSrcRect = new Rect();
        bitmapSrcRect.set(0, 0, (int)(targetRect.width() * preExistingTransform[Matrix.MSCALE_X]), (int)(targetRect.height() * preExistingTransform[Matrix.MSCALE_Y]));
        parentCanvas.drawBitmap(bitmap, bitmapSrcRect, targetRect, composePaint);
        break;

      case RENDER_NODE:
        if (renderNode == null) {
          throw new IllegalStateException("RenderNode is not ready; should've been initialized at start() time");
        }

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
          throw new IllegalStateException("RenderNode not supported but we chose it as render strategy");
        }

        parentCanvas.save();
        parentCanvas.scale(1.0f / preExistingTransform[Matrix.MSCALE_X], 1.0f / preExistingTransform[Matrix.MSCALE_Y]);
        renderNode.endRecording();
        if (op.hasShadow()) {
          // Composing the shadow first and then the content like this will be incorrect in the
          // presence of op.blendMode. However, that is not used at the moment, so this
          // optimization is safe. (Otherwise, we'd have to have another render node here for the
          // intermediate result.)
          renderHardwareShadow(parentCanvas, op.shadow);
        }
        parentCanvas.drawRenderNode(renderNode);
        parentCanvas.restore();
        break;
    }

    parentCanvas = null;
  }
parentCanvas' pre-existing matrix when start() was called
lottie/src/main/java/com/airbnb/lottie/utils/OffscreenLayer.java