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

#include "components/viz/service/frame_sinks/video_capture/video_capture_overlay.h"

#include <algorithm>
#include <cmath>
#include <utility>

#include "base/bind.h"
#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
#include "media/base/limits.h"
#include "media/base/video_frame.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkFilterQuality.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect_conversions.h"

using media::VideoFrame;
using media::VideoPixelFormat;

namespace viz {

VideoCaptureOverlay::FrameSource::~FrameSource() = default;

VideoCaptureOverlay::VideoCaptureOverlay(
    FrameSource* frame_source,
    mojom::FrameSinkVideoCaptureOverlayRequest request)
    : frame_source_(frame_source), binding_(this, std::move(request)) {
  DCHECK(frame_source_);
  binding_.set_connection_error_handler(
      base::BindOnce(&FrameSource::OnOverlayConnectionLost,
                     base::Unretained(frame_source_), this));
}

VideoCaptureOverlay::~VideoCaptureOverlay() = default;

void VideoCaptureOverlay::SetImageAndBounds(const SkBitmap& image,
                                            const gfx::RectF& bounds) {
  const gfx::Rect old_rect = ComputeSourceMutationRect();

  image_ = image;
  bounds_ = bounds;

  // Reset the cached sprite since the source image has been changed.
  sprite_ = nullptr;

  const gfx::Rect new_rect = ComputeSourceMutationRect();
  if (!new_rect.IsEmpty() || !old_rect.IsEmpty()) {
    frame_source_->InvalidateRect(old_rect);
    frame_source_->InvalidateRect(new_rect);
    frame_source_->RequestRefreshFrame();
  }
}

void VideoCaptureOverlay::SetBounds(const gfx::RectF& bounds) {
  if (bounds_ != bounds) {
    const gfx::Rect old_rect = ComputeSourceMutationRect();
    bounds_ = bounds;
    const gfx::Rect new_rect = ComputeSourceMutationRect();
    if (!new_rect.IsEmpty() || !old_rect.IsEmpty()) {
      frame_source_->InvalidateRect(old_rect);
      frame_source_->InvalidateRect(new_rect);
      frame_source_->RequestRefreshFrame();
    }
  }
}

namespace {

// Scales a |relative| rect having coordinates in the range [0.0,1.0) by the
// given |span|, snapping all coordinates to even numbers.
gfx::Rect ToAbsoluteBoundsForI420(const gfx::RectF& relative,
                                  const gfx::Rect& span) {
  const float absolute_left = std::fma(relative.x(), span.width(), span.x());
  const float absolute_top = std::fma(relative.y(), span.height(), span.y());
  const float absolute_right =
      std::fma(relative.right(), span.width(), span.x());
  const float absolute_bottom =
      std::fma(relative.bottom(), span.height(), span.y());

  // Compute the largest I420-friendly Rect that is fully-enclosed by the
  // absolute rect. Use saturated_cast<> to restrict all extreme results [and
  // Inf and NaN] to a safe range of integers.
  const int snapped_left =
      base::saturated_cast<int16_t>(std::ceil(absolute_left / 2.0f)) * 2;
  const int snapped_top =
      base::saturated_cast<int16_t>(std::ceil(absolute_top / 2.0f)) * 2;
  const int snapped_right =
      base::saturated_cast<int16_t>(std::floor(absolute_right / 2.0f)) * 2;
  const int snapped_bottom =
      base::saturated_cast<int16_t>(std::floor(absolute_bottom / 2.0f)) * 2;
  return gfx::Rect(snapped_left, snapped_top,
                   std::max(0, snapped_right - snapped_left),
                   std::max(0, snapped_bottom - snapped_top));
}

// Shrinks the given |rect| by the minimum amount necessary to align its corners
// to even-numbered coordinates. |rect| is assumed to have non-negative values
// for its coordinates.
gfx::Rect MinimallyShrinkRectForI420(const gfx::Rect& rect) {
  DCHECK(gfx::Rect(0, 0, media::limits::kMaxDimension,
                   media::limits::kMaxDimension)
             .Contains(rect));
  const int left = rect.x() + (rect.x() % 2);
  const int top = rect.y() + (rect.y() % 2);
  const int right = rect.right() - (rect.right() % 2);
  const int bottom = rect.bottom() - (rect.bottom() % 2);
  return gfx::Rect(left, top, std::max(0, right - left),
                   std::max(0, bottom - top));
}

}  // namespace

VideoCaptureOverlay::OnceRenderer VideoCaptureOverlay::MakeRenderer(
    const gfx::Rect& region_in_frame,
    const VideoPixelFormat frame_format) {
  // If there's no image set yet, punt.
  if (image_.drawsNothing()) {
    return VideoCaptureOverlay::OnceRenderer();
  }

  // Determine the bounds of the sprite to be blitted onto the video frame. The
  // calculations here align to the 2x2 pixel-quads, since dealing with
  // fractions or partial I420 chroma plane alpha-blending would greatly
  // complexify the blitting algorithm later on. This introduces a little
  // inaccuracy in the size and position of the overlay in the final result, but
  // should be an acceptable trade-off for all use cases.
  const gfx::Rect bounds_in_frame =
      ToAbsoluteBoundsForI420(bounds_, region_in_frame);
  // If the sprite's size will be unreasonably large, punt.
  if (bounds_in_frame.width() > media::limits::kMaxDimension ||
      bounds_in_frame.height() > media::limits::kMaxDimension) {
    return VideoCaptureOverlay::OnceRenderer();
  }

  // Compute the blit rect: the region of the frame to be modified by future
  // Sprite::Blit() calls. First, |region_in_frame| must be shrunk to have
  // even-valued coordinates to ensure the final blit rect is I420-friendly.
  // Then, the shrunk |region_in_frame| is used to clip |bounds_in_frame|.
  gfx::Rect blit_rect = MinimallyShrinkRectForI420(region_in_frame);
  blit_rect.Intersect(bounds_in_frame);
  // If the two rects didn't intersect at all (i.e., everything has been
  // clipped), punt.
  if (blit_rect.IsEmpty()) {
    return VideoCaptureOverlay::OnceRenderer();
  }

  // If the cached sprite does not match the computed scaled size and/or pixel
  // format, create a new instance for this (and future) renderers.
  if (!sprite_ || sprite_->size() != bounds_in_frame.size() ||
      sprite_->format() != frame_format) {
    sprite_ = base::MakeRefCounted<Sprite>(image_, bounds_in_frame.size(),
                                           frame_format);
  }

  return base::BindOnce(&Sprite::Blit, sprite_, bounds_in_frame.origin(),
                        blit_rect);
}

// static
VideoCaptureOverlay::OnceRenderer VideoCaptureOverlay::MakeCombinedRenderer(
    const std::vector<VideoCaptureOverlay*>& overlays,
    const gfx::Rect& region_in_frame,
    const VideoPixelFormat frame_format) {
  if (overlays.empty()) {
    return VideoCaptureOverlay::OnceRenderer();
  }

  std::vector<OnceRenderer> renderers;
  for (VideoCaptureOverlay* overlay : overlays) {
    renderers.emplace_back(
        overlay->MakeRenderer(region_in_frame, frame_format));
    if (renderers.back().is_null()) {
      renderers.pop_back();
    }
  }

  if (renderers.empty()) {
    return VideoCaptureOverlay::OnceRenderer();
  }

  return base::BindOnce(
      [](std::vector<OnceRenderer> renderers, VideoFrame* frame) {
        for (OnceRenderer& renderer : renderers) {
          std::move(renderer).Run(frame);
        }
      },
      std::move(renderers));
}

gfx::Rect VideoCaptureOverlay::ComputeSourceMutationRect() const {
  if (!image_.drawsNothing() && !bounds_.IsEmpty()) {
    const gfx::Size& source_size = frame_source_->GetSourceSize();
    gfx::Rect result = gfx::ToEnclosingRect(
        gfx::ScaleRect(bounds_, source_size.width(), source_size.height()));
    result.Intersect(gfx::Rect(source_size));
    return result;
  }
  return gfx::Rect();
}

VideoCaptureOverlay::Sprite::Sprite(const SkBitmap& image,
                                    const gfx::Size& size,
                                    const VideoPixelFormat format)
    : image_(image), size_(size), format_(format) {
  DCHECK(!image_.isNull());
}

VideoCaptureOverlay::Sprite::~Sprite() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

namespace {

// Returns the pointer to the element at the |offset| position, given a pointer
// to the element for (0,0) in a row-major image plane.
template <typename Pointer>
Pointer PositionPointerInPlane(Pointer plane_begin,
                               int stride,
                               const gfx::Point& offset) {
  return plane_begin + (offset.y() * stride) + offset.x();
}

// Returns the pointer to the element at the |offset| position, given a pointer
// to the element for (0,0) in a row-major bitmap with 4 elements per pixel.
template <typename Pointer>
Pointer PositionPointerARGB(Pointer pixels_begin,
                            int stride,
                            const gfx::Point& offset) {
  return pixels_begin + (offset.y() * stride) + (4 * offset.x());
}

// Transforms the lower 8 bits of |value| from the [0,255] range to the
// normalized floating-point [0.0,1.0] range.
float From255(uint8_t value) {
  return value / 255.0f;
}

// Transforms the value from the normalized floating-point [0.0,1.0] range to an
// unsigned int in the [0,255] range, capping any out-of-range values.
uint32_t ToClamped255(float value) {
  value = std::fma(value, 255.0f, 0.5f /* rounding */);
  return base::saturated_cast<uint8_t>(value);
}

}  // namespace

void VideoCaptureOverlay::Sprite::Blit(const gfx::Point& position,
                                       const gfx::Rect& blit_rect,
                                       VideoFrame* frame) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(frame);
  DCHECK_EQ(format_, frame->format());
  DCHECK(frame->visible_rect().Contains(blit_rect));
  DCHECK(frame->ColorSpace().IsValid());

  TRACE_EVENT2("gpu.capture", "VideoCaptureOverlay::Sprite::Blit", "x",
               position.x(), "y", position.y());

  if (!transformed_image_ || color_space_ != frame->ColorSpace()) {
    color_space_ = frame->ColorSpace();
    TransformImage();
  }

  // Compute the left-most and top-most pixel to source from the transformed
  // image. This is usually (0,0) unless only part of the sprite is being
  // blitted (i.e., cropped at the edge(s) of the video frame).
  gfx::Point src_origin = blit_rect.origin() - position.OffsetFromOrigin();
  DCHECK(gfx::Rect(size_).Contains(gfx::Rect(src_origin, blit_rect.size())));

  // Blit the sprite (src) onto the video frame (dest). One of two algorithms is
  // used, depending on the video frame's format, as the blending calculations
  // and data layout/format are different.
  switch (frame->format()) {
    case media::PIXEL_FORMAT_I420: {
      // Core assumption: All coordinates are aligned to even-numbered
      // coordinates.
      DCHECK_EQ(src_origin.x() % 2, 0);
      DCHECK_EQ(src_origin.y() % 2, 0);
      DCHECK_EQ(blit_rect.x() % 2, 0);
      DCHECK_EQ(blit_rect.y() % 2, 0);
      DCHECK_EQ(blit_rect.width() % 2, 0);
      DCHECK_EQ(blit_rect.height() % 2, 0);

      // Helper function to execute a "SrcOver" blit from |src| to |dst|, and
      // store the results back in |dst|.
      const auto BlitOntoPlane = [](const gfx::Size& blit_size, int src_stride,
                                    const float* src, const float* under_weight,
                                    int dst_stride, uint8_t* dst) {
        for (int row = 0; row < blit_size.height(); ++row, src += src_stride,
                 under_weight += src_stride, dst += dst_stride) {
          for (int col = 0; col < blit_size.width(); ++col) {
            dst[col] = ToClamped255(
                std::fma(From255(dst[col]), under_weight[col], src[col]));
          }
        }
      };

      // Blit the Y plane: |src| points to the pre-multiplied luma values, while
      // |under_weight| points to the "one minus src alpha" values. Both have
      // the same stride, |src_stride|.
      int src_stride = size_.width();
      const float* under_weight = PositionPointerInPlane(
          transformed_image_.get(), src_stride, src_origin);
      const int num_pixels = size_.GetArea();
      const float* src = under_weight + num_pixels;
      // Likewise, start |dst| at the upper-left-most pixel within the video
      // frame's Y plane that will be SrcOver'ed.
      int dst_stride = frame->stride(VideoFrame::kYPlane);
      uint8_t* dst =
          PositionPointerInPlane(frame->visible_data(VideoFrame::kYPlane),
                                 dst_stride, blit_rect.origin());
      BlitOntoPlane(blit_rect.size(), src_stride, src, under_weight, dst_stride,
                    dst);

      // Blit the U and V planes similarly to the Y plane, but reduce all
      // coordinates by 2x2.
      src_stride = size_.width() / 2;
      src_origin = gfx::Point(src_origin.x() / 2, src_origin.y() / 2);
      under_weight = PositionPointerInPlane(
          transformed_image_.get() + 2 * num_pixels, src_stride, src_origin);
      const int num_chroma_pixels = size_.GetArea() / 4;
      src = under_weight + num_chroma_pixels;
      dst_stride = frame->stride(VideoFrame::kUPlane);
      const gfx::Rect chroma_blit_rect(blit_rect.x() / 2, blit_rect.y() / 2,
                                       blit_rect.width() / 2,
                                       blit_rect.height() / 2);
      dst = PositionPointerInPlane(frame->visible_data(VideoFrame::kUPlane),
                                   dst_stride, chroma_blit_rect.origin());
      BlitOntoPlane(chroma_blit_rect.size(), src_stride, src, under_weight,
                    dst_stride, dst);
      src += num_chroma_pixels;
      dst_stride = frame->stride(VideoFrame::kVPlane);
      dst = PositionPointerInPlane(frame->visible_data(VideoFrame::kVPlane),
                                   dst_stride, chroma_blit_rect.origin());
      BlitOntoPlane(chroma_blit_rect.size(), src_stride, src, under_weight,
                    dst_stride, dst);

      break;
    }

    case media::PIXEL_FORMAT_ARGB: {
      // Start |src| at the upper-left-most pixel within |transformed_image_|
      // that will be blitted.
      const int src_stride = size_.width() * 4;
      const float* src =
          PositionPointerARGB(transformed_image_.get(), src_stride, src_origin);

      // Likewise, start |dst| at the upper-left-most pixel within the video
      // frame that will be SrcOver'ed.
      const int dst_stride = frame->stride(VideoFrame::kARGBPlane);
      DCHECK_EQ(dst_stride % sizeof(uint32_t), 0u);
      uint8_t* dst =
          PositionPointerARGB(frame->visible_data(VideoFrame::kARGBPlane),
                              dst_stride, blit_rect.origin());
      DCHECK_EQ((dst - frame->visible_data(VideoFrame::kARGBPlane)) %
                    sizeof(uint32_t),
                0u);

      // Blend each sprite pixel over the corresponding pixel in the video
      // frame, and store the result back in the video frame. Note that the
      // video frame format does NOT have color values pre-multiplied by the
      // alpha.
      for (int row = 0; row < blit_rect.height();
           ++row, src += src_stride, dst += dst_stride) {
        uint32_t* dst_pixel = reinterpret_cast<uint32_t*>(dst);
        for (int col = 0; col < blit_rect.width(); ++col) {
          const int src_idx = 4 * col;
          const float src_alpha = src[src_idx];
          const float dst_weight =
              From255(dst_pixel[col] >> 24) * (1.0f - src_alpha);
          const float out_alpha = src_alpha + dst_weight;
          float out_red = std::fma(From255(dst_pixel[col] >> 16), dst_weight,
                                   src[src_idx + 1]);
          float out_green = std::fma(From255(dst_pixel[col] >> 8), dst_weight,
                                     src[src_idx + 2]);
          float out_blue = std::fma(From255(dst_pixel[col] >> 0), dst_weight,
                                    src[src_idx + 3]);
          if (out_alpha != 0.0f) {
            out_red /= out_alpha;
            out_green /= out_alpha;
            out_blue /= out_alpha;
          }
          dst_pixel[col] =
              ((ToClamped255(out_alpha) << 24) | (ToClamped255(out_red) << 16) |
               (ToClamped255(out_green) << 8) | (ToClamped255(out_blue) << 0));
        }
      }

      break;
    }

    default:
      NOTREACHED();
      break;
  }
}

void VideoCaptureOverlay::Sprite::TransformImage() {
  TRACE_EVENT2("gpu.capture", "VideoCaptureOverlay::Sprite::TransformImage",
               "width", size_.width(), "height", size_.height());

  // Scale the source |image_| to match the format and size required. For the
  // purposes of color space conversion, the alpha must not be pre-multiplied.
  const SkImageInfo scaled_image_format =
      SkImageInfo::Make(size_.width(), size_.height(), kN32_SkColorType,
                        kUnpremul_SkAlphaType, image_.refColorSpace());
  SkBitmap scaled_image;
  if (image_.info() == scaled_image_format) {
    scaled_image = image_;
  } else {
    if (scaled_image.tryAllocPixels(scaled_image_format) &&
        image_.pixmap().scalePixels(scaled_image.pixmap(),
                                    kMedium_SkFilterQuality)) {
      // Cache the scaled image, to avoid needing to re-scale in future calls to
      // this method.
      image_ = scaled_image;
    } else {
      // If the allocation, format conversion and/or scaling failed, just reset
      // the |scaled_image|. This will be checked below.
      scaled_image.reset();
    }
  }

  // Populate |colors| and |alphas| from the |scaled_image|. If the image
  // scaling operation failed, this sprite should draw nothing, and so fully
  // transparent pixels will be generated instead.
  const int num_pixels = size_.GetArea();
  std::unique_ptr<float[]> alphas(new float[num_pixels]);
  std::unique_ptr<gfx::ColorTransform::TriStim[]> colors(
      new gfx::ColorTransform::TriStim[num_pixels]);
  if (scaled_image.drawsNothing()) {
    std::fill(alphas.get(), alphas.get() + num_pixels, 0.0f);
    std::fill(colors.get(), colors.get() + num_pixels,
              gfx::ColorTransform::TriStim());
  } else {
    int pos = 0;
    for (int y = 0; y < size_.height(); ++y) {
      const uint32_t* src = scaled_image.getAddr32(0, y);
      for (int x = 0; x < size_.width(); ++x) {
        const uint32_t pixel = src[x];
        alphas[pos] = ((pixel >> SK_A32_SHIFT) & 0xff) / 255.0f;
        colors[pos].SetPoint(((pixel >> SK_R32_SHIFT) & 0xff) / 255.0f,
                             ((pixel >> SK_G32_SHIFT) & 0xff) / 255.0f,
                             ((pixel >> SK_B32_SHIFT) & 0xff) / 255.0f);
        ++pos;
      }
    }
  }

  // Transform the colors, if needed. This may perform RGB→YUV conversion.
  gfx::ColorSpace image_color_space;
  if (scaled_image.colorSpace()) {
    image_color_space = gfx::ColorSpace(*scaled_image.colorSpace());
  }
  if (!image_color_space.IsValid()) {
    // Assume a default linear color space, if no color space was provided.
    image_color_space = gfx::ColorSpace(
        gfx::ColorSpace::PrimaryID::BT709, gfx::ColorSpace::TransferID::LINEAR,
        gfx::ColorSpace::MatrixID::RGB, gfx::ColorSpace::RangeID::FULL);
  }
  if (image_color_space != color_space_) {
    const auto color_transform = gfx::ColorTransform::NewColorTransform(
        image_color_space, color_space_,
        gfx::ColorTransform::Intent::INTENT_ABSOLUTE);
    color_transform->Transform(colors.get(), num_pixels);
  }

  switch (format_) {
    case media::PIXEL_FORMAT_I420: {
      // Produce 5 planes of data: The "one minus alpha" plane, the Y plane, the
      // subsampled "one minus alpha" plane, the U plane, and the V plane.
      // Pre-multiply the colors by the alpha to prevent extra work in multiple
      // later Blit() calls.
      DCHECK_EQ(size_.width() % 2, 0);
      DCHECK_EQ(size_.height() % 2, 0);
      const int num_chroma_pixels = size_.GetArea() / 4;
      transformed_image_.reset(
          new float[num_pixels * 2 + num_chroma_pixels * 3]);

      // Copy the alpha values, and pre-multiply the luma values by the alpha.
      float* out_1_minus_alpha = transformed_image_.get();
      float* out_luma = out_1_minus_alpha + num_pixels;
      for (int i = 0; i < num_pixels; ++i) {
        const float alpha = alphas[i];
        out_1_minus_alpha[i] = 1.0f - alpha;
        out_luma[i] = colors[i].x() * alpha;
      }

      // Downscale the alpha, U, and V planes by 2x2, and pre-multiply the
      // chroma values by the alpha.
      float* out_uv_1_minus_alpha = out_luma + num_pixels;
      float* out_u = out_uv_1_minus_alpha + num_chroma_pixels;
      float* out_v = out_u + num_chroma_pixels;
      const float* alpha_row0 = alphas.get();
      const float* const alpha_row_end = alpha_row0 + num_pixels;
      const gfx::ColorTransform::TriStim* color_row0 = colors.get();
      while (alpha_row0 < alpha_row_end) {
        const float* alpha_row1 = alpha_row0 + size_.width();
        const gfx::ColorTransform::TriStim* color_row1 =
            color_row0 + size_.width();
        for (int col = 0; col < size_.width(); col += 2) {
          // First, the downscaled alpha is the average of the four original
          // alpha values:
          //
          //     sum_of_alphas = a[r,c] + a[r,c+1] + a[r+1,c] + a[r+1,c+1];
          //     average_alpha = sum_of_alphas / 4
          *(out_uv_1_minus_alpha++) =
              std::fma(alpha_row0[col] + alpha_row0[col + 1] + alpha_row1[col] +
                           alpha_row1[col + 1],
                       -1.0f / 4.0f, 1.0f);
          // Then, the downscaled chroma values are the weighted average of the
          // four original chroma values (weighed by alpha):
          //
          //   weighted_sum_of_chromas =
          //       c[r,c]*a[r,c] + c[r,c+1]*a[r,c+1] +
          //           c[r+1,c]*a[r+1,c] + c[r+1,c+1]*a[r+1,c+1]
          //   sum_of_weights = sum_of_alphas;
          //   average_chroma = weighted_sum_of_chromas / sum_of_weights
          //
          // But then, because the chroma is to be pre-multiplied by the alpha,
          // the calculations simplify, as follows:
          //
          //   premul_chroma = average_chroma * average_alpha
          //                 = (weighted_sum_of_chromas / sum_of_alphas) *
          //                       (sum_of_alphas / 4)
          //                 = weighted_sum_of_chromas / 4
          //
          // This also automatically solves a special case, when sum_of_alphas
          // is zero: With the simplified calculations, there is no longer a
          // "divide-by-zero guard" needed; and the result in this case will be
          // a zero chroma, which is perfectly acceptable behavior.
          *(out_u++) = ((color_row0[col].y() * alpha_row0[col]) +
                        (color_row0[col + 1].y() * alpha_row0[col + 1]) +
                        (color_row1[col].y() * alpha_row1[col]) +
                        (color_row1[col + 1].y() * alpha_row1[col + 1])) /
                       4.0f;
          *(out_v++) = ((color_row0[col].z() * alpha_row0[col]) +
                        (color_row0[col + 1].z() * alpha_row0[col + 1]) +
                        (color_row1[col].z() * alpha_row1[col]) +
                        (color_row1[col + 1].z() * alpha_row1[col + 1])) /
                       4.0f;
        }
        alpha_row0 = alpha_row1 + size_.width();
        color_row0 = color_row1 + size_.width();
      }

      break;
    }

    case media::PIXEL_FORMAT_ARGB: {
      // Produce ARGB pixels from |colors| and |alphas|. Pre-multiply the colors
      // by the alpha to prevent extra work in multiple later Blit() calls.
      transformed_image_.reset(new float[num_pixels * 4]);
      float* out = transformed_image_.get();
      for (int i = 0; i < num_pixels; ++i) {
        const float alpha = alphas[i];
        *(out++) = alpha;
        *(out++) = colors[i].x() * alpha;
        *(out++) = colors[i].y() * alpha;
        *(out++) = colors[i].z() * alpha;
      }
      break;
    }

    default:
      NOTREACHED();
      break;
  }
}

}  // namespace viz
