// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.6
part of engine;

// TODO(yjbanov): this is currently very naive. We probably want to cache
//                fewer large canvases than small canvases. We could also
//                improve cache hit count if we did not require exact canvas
//                size match, but instead could choose a canvas that's big
//                enough. The optimal heuristic will need to be figured out.
//                For example, we probably don't want to pick a full-screen
//                canvas to draw a 10x10 picture. Let's revisit this after
//                Harry's layer merging refactor.
/// The maximum number canvases cached.
const int _kCanvasCacheSize = 30;

/// Canvases available for reuse, capped at [_kCanvasCacheSize].
final List<BitmapCanvas> _recycledCanvases = <BitmapCanvas>[];

/// Reduces recycled canvas list by 50% to reduce bitmap canvas memory use.
void _reduceCanvasMemoryUsage() {
  final int canvasCount = _recycledCanvases.length;
  for (int i = 0; i < canvasCount; i++) {
    _recycledCanvases[i].dispose();
  }
  _recycledCanvases.clear();
}

/// A request to repaint a canvas.
///
/// Paint requests are prioritized such that the larger pictures go first. This
/// makes canvas allocation more efficient by letting large pictures claim
/// larger recycled canvases. Otherwise, small pictures would claim the large
/// canvases forcing us to allocate new large canvases.
class _PaintRequest {
  _PaintRequest({
    this.canvasSize,
    this.paintCallback,
  })  : assert(canvasSize != null),
        assert(paintCallback != null);

  final ui.Size canvasSize;
  final ui.VoidCallback paintCallback;
}

/// Repaint requests produced by [PersistedPicture]s that actually paint on the
/// canvas. Painting is delayed until the layer tree is updated to maximize
/// the number of reusable canvases.
List<_PaintRequest> _paintQueue = <_PaintRequest>[];

void _recycleCanvas(EngineCanvas canvas) {
  if (canvas is BitmapCanvas) {
    if (canvas.isReusable()) {
      _recycledCanvases.add(canvas);
      if (_recycledCanvases.length > _kCanvasCacheSize) {
        final BitmapCanvas removedCanvas = _recycledCanvases.removeAt(0);
        removedCanvas.dispose();
        if (_debugShowCanvasReuseStats) {
          DebugCanvasReuseOverlay.instance.disposedCount++;
        }
      }
      if (_debugShowCanvasReuseStats) {
        DebugCanvasReuseOverlay.instance.inRecycleCount =
            _recycledCanvases.length;
      }
    } else {
      canvas.dispose();
    }
  }
}


/// Signature of a function that instantiates a [PersistedPicture].
typedef PersistedPictureFactory = PersistedPicture Function(
  double dx,
  double dy,
  ui.Picture picture,
  int hints,
);

/// Function used by the [SceneBuilder] to instantiate a picture layer.
PersistedPictureFactory persistedPictureFactory = standardPictureFactory;

/// Instantiates an implementation of a picture layer that uses DOM, CSS, and
/// 2D canvas for painting.
PersistedStandardPicture standardPictureFactory(
    double dx, double dy, ui.Picture picture, int hints) {
  return PersistedStandardPicture(dx, dy, picture, hints);
}

/// Instantiates an implementation of a picture layer that uses CSS Paint API
/// (part of Houdini) for painting.
PersistedHoudiniPicture houdiniPictureFactory(
    double dx, double dy, ui.Picture picture, int hints) {
  return PersistedHoudiniPicture(dx, dy, picture, hints);
}

class PersistedHoudiniPicture extends PersistedPicture {
  PersistedHoudiniPicture(double dx, double dy, ui.Picture picture, int hints)
      : super(dx, dy, picture, hints) {
    if (!_cssPainterRegistered) {
      _registerCssPainter();
    }
  }

  static bool _cssPainterRegistered = false;

  @override
  double matchForUpdate(PersistedPicture existingSurface) {
    // Houdini is display list-based so all pictures are cheap to repaint.
    // However, if the picture hasn't changed at all then it's completely
    // free.
    return existingSurface.picture == picture ? 0.0 : 1.0;
  }

  static void _registerCssPainter() {
    _cssPainterRegistered = true;
    final dynamic css = js_util.getProperty(html.window, 'CSS');
    final dynamic paintWorklet = js_util.getProperty(css, 'paintWorklet');
    if (paintWorklet == null) {
      html.window.console.warn(
          'WARNING: CSS.paintWorklet not available. Paint worklets are only '
          'supported on sites served from https:// or http://localhost.');
      return;
    }
    js_util.callMethod(
      paintWorklet,
      'addModule',
      <dynamic>[
        '/packages/flutter_web_ui/assets/houdini_painter.js',
      ],
    );
  }

  /// Houdini does not paint to bitmap.
  @override
  int get bitmapPixelCount => 0;

  @override
  void applyPaint(EngineCanvas oldCanvas) {
    _recycleCanvas(oldCanvas);
    final HoudiniCanvas canvas = HoudiniCanvas(_optimalLocalCullRect);
    _canvas = canvas;
    domRenderer.clearDom(rootElement);
    rootElement.append(_canvas.rootElement);
    picture.recordingCanvas.apply(_canvas, _optimalLocalCullRect);
    canvas.commit();
  }
}

class PersistedStandardPicture extends PersistedPicture {
  PersistedStandardPicture(double dx, double dy, ui.Picture picture, int hints)
      : super(dx, dy, picture, hints);

  @override
  double matchForUpdate(PersistedStandardPicture existingSurface) {
    if (existingSurface.picture == picture) {
      // Picture is the same, return perfect score.
      return 0.0;
    }

    if (!existingSurface.picture.recordingCanvas.didDraw) {
      // The previous surface didn't draw anything and therefore has no
      // resources to reuse.
      return 1.0;
    }

    final bool didRequireBitmap =
        existingSurface.picture.recordingCanvas.hasArbitraryPaint;
    final bool requiresBitmap = picture.recordingCanvas.hasArbitraryPaint;
    if (didRequireBitmap != requiresBitmap) {
      // Switching canvas types is always expensive.
      return 1.0;
    } else if (!requiresBitmap) {
      // Currently DomCanvas is always expensive to repaint, as we always throw
      // out all the DOM we rendered before. This may change in the future, at
      // which point we may return other values here.
      return 1.0;
    } else {
      final BitmapCanvas oldCanvas = existingSurface._canvas;
      if (oldCanvas == null) {
        // We did not allocate a canvas last time. This can happen when the
        // picture is completely clipped out of the view.
        return 1.0;
      } else if (!oldCanvas.doesFitBounds(_exactLocalCullRect)) {
        // The canvas needs to be resized before painting.
        return 1.0;
      } else {
        final int newPixelCount = BitmapCanvas._widthToPhysical(_exactLocalCullRect.width)
             * BitmapCanvas._heightToPhysical(_exactLocalCullRect.height);
        final int oldPixelCount =
            oldCanvas._widthInBitmapPixels * oldCanvas._heightInBitmapPixels;

        if (oldPixelCount == 0) {
          return 1.0;
        }

        final double pixelCountRatio = newPixelCount / oldPixelCount;
        assert(0 <= pixelCountRatio && pixelCountRatio <= 1.0,
            'Invalid pixel count ratio $pixelCountRatio');
        return 1.0 - pixelCountRatio;
      }
    }
  }

  @override
  Matrix4 get localTransformInverse => null;

  @override
  int get bitmapPixelCount {
    if (_canvas is! BitmapCanvas) {
      return 0;
    }

    final BitmapCanvas bitmapCanvas = _canvas;
    return bitmapCanvas.bitmapPixelCount;
  }

  @override
  void applyPaint(EngineCanvas oldCanvas) {
    if (picture.recordingCanvas.hasArbitraryPaint) {
      _applyBitmapPaint(oldCanvas);
    } else {
      _applyDomPaint(oldCanvas);
    }
  }

  void _applyDomPaint(EngineCanvas oldCanvas) {
    _recycleCanvas(oldCanvas);
    _canvas = DomCanvas();
    domRenderer.clearDom(rootElement);
    rootElement.append(_canvas.rootElement);
    picture.recordingCanvas.apply(_canvas, _optimalLocalCullRect);
  }

  void _applyBitmapPaint(EngineCanvas oldCanvas) {
    if (oldCanvas is BitmapCanvas &&
        oldCanvas.doesFitBounds(_optimalLocalCullRect) &&
        oldCanvas.isReusable()) {
      if (_debugShowCanvasReuseStats) {
        DebugCanvasReuseOverlay.instance.keptCount++;
      }
      oldCanvas.bounds = _optimalLocalCullRect;
      _canvas = oldCanvas;
      _canvas.clear();
      picture.recordingCanvas.apply(_canvas, _optimalLocalCullRect);
    } else {
      // We can't use the old canvas because the size has changed, so we put
      // it in a cache for later reuse.
      _recycleCanvas(oldCanvas);
      // We cannot paint immediately because not all canvases that we may be
      // able to reuse have been released yet. So instead we enqueue this
      // picture to be painted after the update cycle is done syncing the layer
      // tree then reuse canvases that were freed up.
      _paintQueue.add(_PaintRequest(
        canvasSize: _optimalLocalCullRect.size,
        paintCallback: () {
          _canvas = _findOrCreateCanvas(_optimalLocalCullRect);
          if (_debugExplainSurfaceStats) {
            final BitmapCanvas bitmapCanvas = _canvas;
            _surfaceStatsFor(this).paintPixelCount +=
                bitmapCanvas.bitmapPixelCount;
          }
          domRenderer.clearDom(rootElement);
          rootElement.append(_canvas.rootElement);
          _canvas.clear();
          picture.recordingCanvas.apply(_canvas, _optimalLocalCullRect);
        },
      ));
    }
  }

  /// Attempts to reuse a canvas from the [_recycledCanvases]. Allocates a new
  /// one if unable to reuse.
  ///
  /// The best recycled canvas is one that:
  ///
  /// - Fits the requested [canvasSize]. This is a hard requirement. Otherwise
  ///   we risk clipping the picture.
  /// - Is the smallest among all possible reusable canvases. This makes canvas
  ///   reuse more efficient.
  /// - Contains no more than twice the number of requested pixels. This makes
  ///   sure we do not use too much memory for small canvases.
  BitmapCanvas _findOrCreateCanvas(ui.Rect bounds) {
    final ui.Size canvasSize = bounds.size;
    BitmapCanvas bestRecycledCanvas;
    double lastPixelCount = double.infinity;
    for (int i = 0; i < _recycledCanvases.length; i++) {
      final BitmapCanvas candidate = _recycledCanvases[i];
      if (!candidate.isReusable()) {
        continue;
      }

      final ui.Size candidateSize = candidate.size;
      final double candidatePixelCount =
          candidateSize.width * candidateSize.height;

      final bool fits = candidate.doesFitBounds(bounds);
      final bool isSmaller = candidatePixelCount < lastPixelCount;
      if (fits && isSmaller) {
        // [isTooSmall] is used to make sure that a small picture doesn't
        // reuse and hold onto memory of a large canvas.
        final double requestedPixelCount = bounds.width * bounds.height;
        final bool isTooSmall = isSmaller &&
            requestedPixelCount > 1 &&
            (candidatePixelCount / requestedPixelCount) > 4;
        if (!isTooSmall) {
          bestRecycledCanvas = candidate;
          lastPixelCount = candidatePixelCount;
          final bool fitsExactly = candidateSize.width == canvasSize.width &&
              candidateSize.height == canvasSize.height;
          if (fitsExactly) {
            // No need to keep looking any more.
            break;
          }
        }
      }
    }

    if (bestRecycledCanvas != null) {
      if (_debugExplainSurfaceStats) {
        _surfaceStatsFor(this).reuseCanvasCount++;
      }
      _recycledCanvases.remove(bestRecycledCanvas);
      if (_debugShowCanvasReuseStats) {
        DebugCanvasReuseOverlay.instance.inRecycleCount =
            _recycledCanvases.length;
      }
      if (_debugShowCanvasReuseStats) {
        DebugCanvasReuseOverlay.instance.reusedCount++;
      }
      bestRecycledCanvas.bounds = bounds;
      bestRecycledCanvas.elementCache = _elementCache;
      return bestRecycledCanvas;
    }

    if (_debugShowCanvasReuseStats) {
      DebugCanvasReuseOverlay.instance.createdCount++;
    }
    final BitmapCanvas canvas = BitmapCanvas(bounds);
    canvas.elementCache = _elementCache;
    if (_debugExplainSurfaceStats) {
      _surfaceStatsFor(this)
        ..allocateBitmapCanvasCount += 1
        ..allocatedBitmapSizeInPixels =
            canvas._widthInBitmapPixels * canvas._heightInBitmapPixels;
    }
    return canvas;
  }
}

/// A surface that uses a combination of `<canvas>`, `<div>` and `<p>` elements
/// to draw shapes and text.
abstract class PersistedPicture extends PersistedLeafSurface {
  PersistedPicture(this.dx, this.dy, this.picture, this.hints)
      : localPaintBounds = picture.recordingCanvas.pictureBounds;

  EngineCanvas _canvas;

  /// Returns the canvas used by this picture layer.
  ///
  /// Useful for tests.
  EngineCanvas get debugCanvas => _canvas;

  final double dx;
  final double dy;
  final EnginePicture picture;
  final ui.Rect localPaintBounds;
  final int hints;

  /// Cache for reusing elements such as images across picture updates.
  CrossFrameCache<html.HtmlElement> _elementCache =
      CrossFrameCache<html.HtmlElement>();

  @override
  html.Element createElement() {
    return defaultCreateElement('flt-picture');
  }

  @override
  void recomputeTransformAndClip() {
    _transform = parent._transform;
    if (dx != 0.0 || dy != 0.0) {
      _transform = _transform.clone();
      _transform.translate(dx, dy);
    }
    _computeExactCullRects();
  }

  /// The rectangle that contains all visible pixels drawn by [picture] inside
  /// the current layer hierarchy in local coordinates.
  ///
  /// This value is a conservative estimate, i.e. it must be big enough to
  /// contain everything that's visible, but it may be bigger than necessary.
  /// Therefore it should not be used for clipping. It is meant to be used for
  /// optimizing canvas allocation.
  ui.Rect get optimalLocalCullRect => _optimalLocalCullRect;
  ui.Rect _optimalLocalCullRect;

  /// Same as [optimalLocalCullRect] but in screen coordinate system.
  ui.Rect get debugExactGlobalCullRect => _exactGlobalCullRect;
  ui.Rect _exactGlobalCullRect;

  ui.Rect _exactLocalCullRect;

  /// Computes the canvas paint bounds based on the estimated paint bounds and
  /// the scaling produced by transformations.
  ///
  /// Return `true` if the local cull rect changed, indicating that a repaint
  /// may be required. Returns `false` otherwise. Global cull rect changes do
  /// not necessarily incur repaints. For example, if the layer sub-tree was
  /// translated from one frame to another we may not need to repaint, just
  /// translate the canvas.
  void _computeExactCullRects() {
    assert(transform != null);
    assert(localPaintBounds != null);

    if (parent._projectedClip == null) {
      // Compute and cache chain of clipping bounds on parent of picture since
      // parent may include multiple pictures so it can be reused by all
      // child pictures.
      ui.Rect bounds;
      PersistedSurface parentSurface = parent;
      final Matrix4 clipTransform = Matrix4.identity();
      while (parentSurface != null) {
        final ui.Rect localClipBounds = parentSurface._localClipBounds;
        if (localClipBounds != null) {
          if (bounds == null) {
            bounds = transformRect(clipTransform, localClipBounds);
          } else {
            bounds =
                bounds.intersect(transformRect(clipTransform, localClipBounds));
          }
        }
        final Matrix4 localInverse = parentSurface.localTransformInverse;
        if (localInverse != null && !localInverse.isIdentity()) {
          clipTransform.multiply(localInverse);
        }
        parentSurface = parentSurface.parent;
      }
      if (bounds != null && (bounds.width <= 0 || bounds.height <= 0)) {
        bounds = ui.Rect.zero;
      }
      // Cache projected clip on parent.
      parent._projectedClip = bounds;
    }
    // Intersect localPaintBounds with parent projected clip to calculate
    // and cache [_exactLocalCullRect].
    if (parent._projectedClip == null) {
      _exactLocalCullRect = localPaintBounds;
    } else {
      _exactLocalCullRect = localPaintBounds.intersect(parent._projectedClip);
    }
    if (_exactLocalCullRect.width <= 0 || _exactLocalCullRect.height <= 0) {
      _exactLocalCullRect = ui.Rect.zero;
      _exactGlobalCullRect = ui.Rect.zero;
    } else {
      assert(() {
        _exactGlobalCullRect = transformRect(transform, _exactLocalCullRect);
        return true;
      }());
    }
  }

  bool _computeOptimalCullRect(PersistedPicture oldSurface) {
    assert(_exactLocalCullRect != null);

    if (oldSurface == null || !oldSurface.picture.recordingCanvas.didDraw) {
      // First useful paint.
      _optimalLocalCullRect = _exactLocalCullRect;
      return true;
    }

    assert(oldSurface._optimalLocalCullRect != null);

    final bool surfaceBeingRetained = identical(oldSurface, this);
    final ui.Rect oldOptimalLocalCullRect = surfaceBeingRetained
        ? _optimalLocalCullRect
        : oldSurface._optimalLocalCullRect;

    if (_exactLocalCullRect == ui.Rect.zero) {
      // The clip collapsed into a zero-sized rectangle. If it was already zero,
      // no need to signal cull rect change.
      _optimalLocalCullRect = ui.Rect.zero;
      return oldOptimalLocalCullRect != ui.Rect.zero;
    }

    if (rectContainsOther(oldOptimalLocalCullRect, _exactLocalCullRect)) {
      // The cull rect we computed in the past contains the newly computed cull
      // rect. This can happen, for example, when the picture is being shrunk by
      // a clip when it is scrolled out of the screen. In this case we do not
      // repaint the picture. We just let it be shrunk by the outer clip.
      _optimalLocalCullRect = oldOptimalLocalCullRect;
      return false;
    }

    // The new cull rect contains area not covered by a previous rect. Perhaps
    // the clip is growing, moving around the picture, or both. In this case
    // a part of the picture may not have been painted. We will need to
    // request a new canvas and paint the picture on it. However, this is also
    // a strong signal that the clip will continue growing as typically
    // Flutter uses animated transitions. So instead of allocating the canvas
    // the size of the currently visible area, we try to allocate a canvas of
    // a bigger size. This will prevent any further repaints as future frames
    // will hit the above case where the new cull rect is fully contained
    // within the cull rect we compute now.

    // Compute the delta, by which each of the side of the clip rect has "moved"
    // since the last time we updated the cull rect.
    final double leftwardDelta = oldOptimalLocalCullRect.left - _exactLocalCullRect.left;
    final double upwardDelta = oldOptimalLocalCullRect.top - _exactLocalCullRect.top;
    final double rightwardDelta = _exactLocalCullRect.right - oldOptimalLocalCullRect.right;
    final double bottomwardDelta = _exactLocalCullRect.bottom - oldOptimalLocalCullRect.bottom;

    // Compute the new optimal rect to paint into.
    final ui.Rect newLocalCullRect = ui.Rect.fromLTRB(
      _exactLocalCullRect.left - _predictTrend(leftwardDelta, _exactLocalCullRect.width),
      _exactLocalCullRect.top - _predictTrend(upwardDelta, _exactLocalCullRect.height),
      _exactLocalCullRect.right + _predictTrend(rightwardDelta, _exactLocalCullRect.width),
      _exactLocalCullRect.bottom + _predictTrend(bottomwardDelta, _exactLocalCullRect.height),
    ).intersect(localPaintBounds);

    final bool localCullRectChanged = _optimalLocalCullRect != newLocalCullRect;
    _optimalLocalCullRect = newLocalCullRect;
    return localCullRectChanged;
  }

  /// Predicts the delta a particular side of a clip rect will move given the
  /// [delta] it moved by last, and the respective [extent] (width or height)
  /// of the clip.
  static double _predictTrend(double delta, double extent) {
    if (delta <= 0.0) {
      // Shrinking. Give it 10% of the extent in case the trend is reversed.
      return extent * 0.1;
    } else {
      // Growing. Predict 10 more frames of similar deltas. Give it at least
      // 50% of the extent (protect from extremely slow growth trend such as
      // slow scrolling). Give no more than the full extent (protects from
      // fast scrolling that could lead to overallocation).
      return math.min(
        math.max(extent * 0.5, delta * 10.0),
        extent,
      );
    }
  }

  /// Number of bitmap pixel painted by this picture.
  ///
  /// If the implementation does not paint onto a bitmap canvas, it should
  /// return zero.
  int get bitmapPixelCount;

  void _applyPaint(PersistedPicture oldSurface) {
    final EngineCanvas oldCanvas = oldSurface?._canvas;
    if (!picture.recordingCanvas.didDraw || _optimalLocalCullRect.isEmpty) {
      // The picture is empty, or it has been completely clipped out. Skip
      // painting. This removes all the setup work and scaffolding objects
      // that won't be useful for anything anyway.
      _recycleCanvas(oldCanvas);
      domRenderer.clearDom(rootElement);
      _canvas = null;
      return;
    }

    if (_debugExplainSurfaceStats) {
      _surfaceStatsFor(this).paintCount++;
    }

    assert(_optimalLocalCullRect != null);
    applyPaint(oldCanvas);
  }

  /// Concrete implementations implement this method to do actual painting.
  void applyPaint(EngineCanvas oldCanvas);

  void _applyTranslate() {
    rootElement.style.transform = 'translate(${dx}px, ${dy}px)';
  }

  @override
  void apply() {
    _applyTranslate();
    _applyPaint(null);
  }

  @override
  void build() {
    _computeOptimalCullRect(null);
    super.build();
  }

  @override
  void update(PersistedPicture oldSurface) {
    super.update(oldSurface);
    // Transfer element cache over.
    _elementCache = oldSurface._elementCache;

    if (dx != oldSurface.dx || dy != oldSurface.dy) {
      _applyTranslate();
    }

    final bool cullRectChangeRequiresRepaint =
        _computeOptimalCullRect(oldSurface);
    if (identical(picture, oldSurface.picture)) {
      // The picture is the same. Attempt to avoid repaint.
      if (cullRectChangeRequiresRepaint) {
        // Cull rect changed such that a repaint is still necessary.
        _applyPaint(oldSurface);
      } else {
        // Cull rect did not change, or changed such in a way that does not
        // require a repaint (e.g. it shrunk).
        _canvas = oldSurface._canvas;
      }
    } else {
      // We have a new picture. Repaint.
      _applyPaint(oldSurface);
    }
  }

  @override
  void retain() {
    super.retain();
    final bool cullRectChangeRequiresRepaint = _computeOptimalCullRect(this);
    if (cullRectChangeRequiresRepaint) {
      _applyPaint(this);
    }
  }

  @override
  void discard() {
    _recycleCanvas(_canvas);
    super.discard();
  }

  @override
  void debugPrintChildren(StringBuffer buffer, int indent) {
    super.debugPrintChildren(buffer, indent);
    if (rootElement != null && rootElement.firstChild != null) {
      final html.Element firstChild = rootElement.firstChild;
      final String canvasTag = firstChild.tagName.toLowerCase();
      final int canvasHash = rootElement.firstChild.hashCode;
      buffer.writeln('${'  ' * (indent + 1)}<$canvasTag @$canvasHash />');
    } else if (rootElement != null) {
      buffer.writeln(
          '${'  ' * (indent + 1)}<${rootElement.tagName.toLowerCase()} @$hashCode />');
    } else {
      buffer.writeln('${'  ' * (indent + 1)}<recycled-canvas />');
    }
  }

  @override
  void debugValidate(List<String> validationErrors) {
    super.debugValidate(validationErrors);

    if (picture.recordingCanvas.didDraw) {
      if (!_optimalLocalCullRect.isEmpty && debugCanvas == null) {
        validationErrors
            .add('$runtimeType has non-trivial picture but it has null canvas');
      }
      if (_optimalLocalCullRect == null) {
        validationErrors.add('$runtimeType has null _optimalLocalCullRect');
      }
      if (_exactGlobalCullRect == null) {
        validationErrors.add('$runtimeType has null _exactGlobalCullRect');
      }
      if (_exactLocalCullRect == null) {
        validationErrors.add('$runtimeType has null _exactLocalCullRect');
      }
    }
  }
}
