private void applyMasks(Canvas canvas, Matrix matrix) {
    if (L.isTraceEnabled()) {
      L.beginSection("Layer#saveLayer");
    }
    Utils.saveLayerCompat(canvas, rect, dstInPaint, SAVE_FLAGS);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
      // Pre-Pie, offscreen buffers were opaque which meant that outer border of a mask
      // might get drawn depending on the result of float rounding.
      clearCanvas(canvas);
    }
    if (L.isTraceEnabled()) {
      L.endSection("Layer#saveLayer");
    }
    for (int i = 0; i < mask.getMasks().size(); i++) {
      Mask mask = this.mask.getMasks().get(i);
      BaseKeyframeAnimation<ShapeData, Path> maskAnimation = this.mask.getMaskAnimations().get(i);
      BaseKeyframeAnimation<Integer, Integer> opacityAnimation = this.mask.getOpacityAnimations().get(i);
      switch (mask.getMaskMode()) {
        case MASK_MODE_NONE:
          // None mask should have no effect. If all masks are NONE, fill the
          // mask canvas with a rectangle so it fully covers the original layer content.
          // However, if there are other masks, they should be the only ones that have an effect so
          // this should noop.
          if (areAllMasksNone()) {
            contentPaint.setAlpha(255);
            canvas.drawRect(rect, contentPaint);
          }
          break;
        case MASK_MODE_ADD:
          if (mask.isInverted()) {
            applyInvertedAddMask(canvas, matrix, maskAnimation, opacityAnimation);
          } else {
            applyAddMask(canvas, matrix, maskAnimation, opacityAnimation);
          }
          break;
        case MASK_MODE_SUBTRACT:
          if (i == 0) {
            contentPaint.setColor(Color.BLACK);
            contentPaint.setAlpha(255);
            canvas.drawRect(rect, contentPaint);
          }
          if (mask.isInverted()) {
            applyInvertedSubtractMask(canvas, matrix, maskAnimation, opacityAnimation);
          } else {
            applySubtractMask(canvas, matrix, maskAnimation);
          }
          break;
        case MASK_MODE_INTERSECT:
          if (mask.isInverted()) {
            applyInvertedIntersectMask(canvas, matrix, maskAnimation, opacityAnimation);
          } else {
            applyIntersectMask(canvas, matrix, maskAnimation, opacityAnimation);
          }
          break;
      }
    }
    if (L.isTraceEnabled()) {
      L.beginSection("Layer#restoreLayer");
    }
    canvas.restore();
    if (L.isTraceEnabled()) {
      L.endSection("Layer#restoreLayer");
    }
  }
Enable this to debug slow animations by outlining masks and mattes. The performance overhead of the masks and mattes will
be proportional to the surface area of all of the masks/mattes combined.
<p>
DO NOT leave this enabled in production.
lottie/src/main/java/com/airbnb/lottie/model/layer/BaseLayer.java