// Copyright 2020 The Fuchsia 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 "software_view.h"

#include <lib/trace/event.h>
#include <lib/ui/scenic/cpp/commands.h>

#include <algorithm>

#include <fbl/algorithm.h>

namespace frame_compression {
namespace {

// sRGB color space.
constexpr uint32_t kColor0 = 0xff6448fe;
constexpr uint32_t kColor1 = 0xffb3d5eb;

// Inspect values.
constexpr char kView[] = "view";
constexpr char kModifier[] = "modifier";
constexpr char kImage[] = "image";
constexpr char kImageBytes[] = "image_bytes";
constexpr char kImageBytesUsed[] = "image_bytes_used";
constexpr char kImageBytesDeduped[] = "image_bytes_deduped";
constexpr char kWidthInTiles[] = "width_in_tiles";
constexpr char kHeightInTiles[] = "height_in_tiles";

}  // namespace

SoftwareView::SoftwareView(scenic::ViewContext context, uint64_t modifier, uint32_t width,
                           uint32_t height, uint32_t paint_count, FILE* png_fp,
                           inspect::Node inspect_node)
    : BaseView(std::move(context), "Software View Example", width, height, std::move(inspect_node)),
      modifier_(modifier),
      paint_count_(paint_count),
      png_fp_(png_fp),
      inspect_node_(top_inspect_node_.CreateLazyValues(kView, [this] { return PopulateStats(); })) {
  zx_status_t status = component_context()->svc()->Connect(sysmem_allocator_.NewRequest());
  FX_CHECK(status == ZX_OK);

  fuchsia::sysmem::BufferCollectionTokenSyncPtr local_token;
  status = sysmem_allocator_->AllocateSharedCollection(local_token.NewRequest());
  FX_CHECK(status == ZX_OK);
  fuchsia::sysmem::BufferCollectionTokenSyncPtr scenic_token;
  status = local_token->Duplicate(std::numeric_limits<uint32_t>::max(), scenic_token.NewRequest());
  FX_CHECK(status == ZX_OK);
  status = local_token->Sync();
  FX_CHECK(status == ZX_OK);

  const uint32_t kBufferId = 1;
  session()->RegisterBufferCollection(kBufferId, std::move(scenic_token));

  fuchsia::sysmem::BufferCollectionSyncPtr buffer_collection;
  status = sysmem_allocator_->BindSharedCollection(std::move(local_token),
                                                   buffer_collection.NewRequest());
  FX_CHECK(status == ZX_OK);

  //
  // Set buffer collection constraints for CPU usage.
  //

  fuchsia::sysmem::BufferCollectionConstraints constraints;
  constraints.min_buffer_count = kNumImages;
  constraints.usage.cpu = fuchsia::sysmem::cpuUsageWrite | fuchsia::sysmem::cpuUsageWriteOften;
  constraints.has_buffer_memory_constraints = true;
  constraints.buffer_memory_constraints.min_size_bytes = 0;
  constraints.buffer_memory_constraints.max_size_bytes = 0xffffffff;
  constraints.buffer_memory_constraints.physically_contiguous_required = false;
  constraints.buffer_memory_constraints.secure_required = false;
  constraints.buffer_memory_constraints.ram_domain_supported = true;
  constraints.buffer_memory_constraints.cpu_domain_supported = true;
  constraints.buffer_memory_constraints.inaccessible_domain_supported = false;
  constraints.buffer_memory_constraints.heap_permitted_count = 0;
  constraints.image_format_constraints_count = 1;
  fuchsia::sysmem::ImageFormatConstraints& image_constraints =
      constraints.image_format_constraints[0];
  image_constraints = fuchsia::sysmem::ImageFormatConstraints();
  image_constraints.min_coded_width = width_;
  image_constraints.min_coded_height = height_;
  image_constraints.max_coded_width = width_;
  image_constraints.max_coded_height = height_;
  image_constraints.min_bytes_per_row = 0;
  image_constraints.max_bytes_per_row = std::numeric_limits<uint32_t>::max();
  image_constraints.max_coded_width_times_coded_height = std::numeric_limits<uint32_t>::max();
  image_constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::R8G8B8A8;
  image_constraints.color_spaces_count = 1;
  image_constraints.color_space[0].type = fuchsia::sysmem::ColorSpaceType::SRGB;
  image_constraints.pixel_format.has_format_modifier = true;
  image_constraints.pixel_format.format_modifier.value = modifier_;

  // Force bytes per row to 4 * |width_| when using linear buffer.
  if (modifier_ == fuchsia::sysmem::FORMAT_MODIFIER_LINEAR) {
    image_constraints.min_bytes_per_row = width_ * 4;
    image_constraints.max_bytes_per_row = width_ * 4;
  }

  status = buffer_collection->SetConstraints(true, constraints);
  FX_CHECK(status == ZX_OK);

  zx_status_t allocation_status = ZX_OK;
  fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info = {};
  status = buffer_collection->WaitForBuffersAllocated(&allocation_status, &buffer_collection_info);
  FX_CHECK(status == ZX_OK);
  FX_CHECK(allocation_status == ZX_OK);
  FX_CHECK(buffer_collection_info.settings.image_format_constraints.pixel_format.type ==
           image_constraints.pixel_format.type);
  bool needs_flush = buffer_collection_info.settings.buffer_settings.coherency_domain ==
                     fuchsia::sysmem::CoherencyDomain::RAM;
  uint32_t stride = buffer_collection_info.settings.image_format_constraints.min_bytes_per_row;

  //
  // Initialize images from allocated buffer collection.
  //

  for (size_t i = 0; i < kNumImages; ++i) {
    auto& image = images_[i];

    image.image_id = session()->AllocResourceId();
    fuchsia::sysmem::ImageFormat_2 image_format = {};
    image_format.coded_width = width_;
    image_format.coded_height = height_;
    session()->Enqueue(scenic::NewCreateImage2Cmd(image.image_id, width_, height_, kBufferId, i));

    uint8_t* vmo_base;
    FX_CHECK(buffer_collection_info.buffers[i].vmo != ZX_HANDLE_INVALID);
    const zx::vmo& image_vmo = buffer_collection_info.buffers[i].vmo;
    auto image_vmo_bytes = buffer_collection_info.settings.buffer_settings.size_bytes;
    FX_CHECK(image_vmo_bytes > 0);
    status = zx::vmar::root_self()->map(ZX_VM_PERM_WRITE | ZX_VM_PERM_READ, 0, image_vmo, 0,
                                        image_vmo_bytes, reinterpret_cast<uintptr_t*>(&vmo_base));
    vmo_base += buffer_collection_info.buffers[i].vmo_usable_start;

    image.vmo_ptr = vmo_base;
    image.image_bytes = image_vmo_bytes;
    switch (modifier) {
      case fuchsia::sysmem::FORMAT_MODIFIER_ARM_AFBC_16X16_YUV_TILED_HEADER: {
        uint32_t width_in_tiles =
            fbl::round_up(width_, kTiledAfbcWidthAlignment) / kAfbcTilePixelWidth;
        uint32_t height_in_tiles =
            fbl::round_up(height_, kTiledAfbcHeightAlignment) / kAfbcTilePixelHeight;
        image.width_in_tiles = width_in_tiles;
        image.height_in_tiles = height_in_tiles;
      } break;
      case fuchsia::sysmem::FORMAT_MODIFIER_LINEAR:
        image.stride = stride;
        break;
      default:
        FX_NOTREACHED() << "Modifier not supported.";
    }
    image.needs_flush = needs_flush;
    image.inspect_node = top_inspect_node_.CreateLazyNode(kImage + std::to_string(i), [this, i] {
      auto& image = images_[i];
      return PopulateImageStats(image);
    });
  }

  buffer_collection->Close();
}

void SoftwareView::OnSceneInvalidated(fuchsia::images::PresentationInfo presentation_info) {
  if (!has_logical_size()) {
    return;
  }

  uint32_t frame_number = GetNextFrameNumber();
  if (frame_number < paint_count_) {
    auto& image = images_[GetNextImageIndex()];
    if (png_fp_) {
      png_infop info_ptr;
      auto png = CreatePngReadStruct(png_fp_, &info_ptr);
      SetPixelsFromPng(image, png);
      DestroyPngReadStruct(png, info_ptr);
    } else {
      SetPixelsFromColorOffset(image, GetNextColorOffset());
    }
    material_.SetTexture(image.image_id);
  }

  Animate(presentation_info);

  // The rectangle is constantly animating; invoke InvalidateScene() to guarantee
  // that OnSceneInvalidated() will be called again.
  InvalidateScene();
}

void SoftwareView::SetPixelsFromColorOffset(Image& image, uint32_t color_offset) {
  switch (modifier_) {
    case fuchsia::sysmem::FORMAT_MODIFIER_ARM_AFBC_16X16_YUV_TILED_HEADER:
      SetAfbcPixelsFromColorOffset(image, color_offset);
      break;
    case fuchsia::sysmem::FORMAT_MODIFIER_LINEAR:
      SetLinearPixelsFromColorOffset(image, color_offset);
      break;
    default:
      FX_NOTREACHED() << "Modifier not supported.";
  }
  image.image_bytes_used = image.image_bytes;
}

void SoftwareView::SetAfbcPixelsFromColorOffset(Image& image, uint32_t color_offset) {
  TRACE_DURATION("gfx", "SoftwareView::SetAfbcPixelsFromColorOffset");

  uint32_t width_in_tiles = image.width_in_tiles;
  uint32_t height_in_tiles = image.height_in_tiles;
  uint32_t tile_count = width_in_tiles * height_in_tiles;
  uint32_t body_offset =
      fbl::round_up(tile_count * kAfbcBytesPerBlockHeader, kTiledAfbcBodyAlignment);
  uint32_t subtile_num_bytes = kTileNumBytes / (kAfbcSubtileSize * kAfbcSubtileSize);
  uint32_t subtile_stride = subtile_num_bytes / kAfbcSubtileSize;
  uint32_t width_in_superblocks = width_in_tiles / kAfbcHeaderTileWidth;
  uint32_t height_in_superblocks = height_in_tiles / kAfbcHeaderTileHeight;

  uint8_t* header_base = image.vmo_ptr;
  uint8_t* body_base = header_base + body_offset;

  uint32_t next_tile_index = 0;
  for (unsigned k = 0; k < height_in_superblocks; k++) {
    for (unsigned j = 0; j < width_in_superblocks; j++) {
      for (unsigned i = 0; i < kAfbcHeaderTileBlocks; i++) {
        // 8x8 superblock layout:
        //
        // +--+--+--+--+--+--+--+--
        // |01|02|05|06|17|18|21|..
        // +--+--+--+--+--+--+--+
        // |03|04|07|08|19|20|..
        // +--+--+--+--+--+--+
        // |09|10|13|14|25|..
        // +--+--+--+--+--+
        // |11|12|15|16|..
        // +--+--+--+--+
        // |32|33|36|..
        // +--+--+--+
        // |34|35|..
        // +--+--+
        // |40|..
        // +--+
        // +..
        //

        // 4x4 offset and index:
        unsigned block_4x4 = i / 16;
        unsigned block_4x4_index = i % 16;

        // 2x2 offset and index:
        unsigned block_2x2 = block_4x4_index / 4;
        unsigned block_2x2_index = block_4x4_index % 4;

        // y offsets:
        unsigned block_4x4_y = block_4x4 / 2;
        unsigned block_2x2_y = block_2x2 / 2;
        unsigned block_y = block_2x2_index / 2;

        unsigned tile_y =
            ((k * kAfbcHeaderTileHeight) + block_4x4_y * 4 + block_2x2_y * 2 + block_y) *
            kAfbcTilePixelHeight;
        unsigned tile_y_end = tile_y + kAfbcTilePixelHeight;

        unsigned header_offset = (((k * width_in_superblocks + j) * kAfbcHeaderTileBlocks) + i) *
                                 kAfbcBytesPerBlockHeader;
        uint8_t* header_ptr = header_base + header_offset;
        // Use solid color tile if possible.
        if (tile_y >= color_offset || tile_y_end < color_offset) {
          uint32_t color = tile_y >= color_offset ? kColor0 : kColor1;
          // Reset header.
          header_ptr[0] = header_ptr[1] = header_ptr[2] = header_ptr[3] = header_ptr[4] =
              header_ptr[5] = header_ptr[6] = header_ptr[7] = header_ptr[12] = header_ptr[13] =
                  header_ptr[14] = header_ptr[15] = 0;
          // Solid colors are stored at offset 8 in block header.
          *(reinterpret_cast<uint32_t*>(header_ptr + 8)) = color;
        } else {
          uint32_t tile_index = next_tile_index++;
          uint32_t tile_offset = kTileNumBytes * tile_index;
          // 16 sub-tiles.
          constexpr struct {
            unsigned x;
            unsigned y;
          } kSubtileOffset[kAfbcSubtileSize * kAfbcSubtileSize] = {
              {4, 4}, {0, 4},  {0, 0},   {4, 0},  {8, 0},  {12, 0}, {12, 4}, {8, 4},
              {8, 8}, {12, 8}, {12, 12}, {8, 12}, {4, 12}, {0, 12}, {0, 8},  {4, 8},
          };

          for (unsigned l = 0; l < countof(kSubtileOffset); ++l) {
            unsigned offset = tile_offset + subtile_num_bytes * l;

            for (unsigned yy = 0; yy < kAfbcSubtileSize; ++yy) {
              unsigned y = tile_y + kSubtileOffset[l].y + yy;
              uint32_t color = y >= color_offset ? kColor0 : kColor1;
              uint32_t* target =
                  reinterpret_cast<uint32_t*>(body_base + offset + yy * subtile_stride);

              for (unsigned xx = 0; xx < kAfbcSubtileSize; ++xx) {
                target[xx] = color;
              }
            }
          }

          if (image.needs_flush) {
            zx_cache_flush(body_base + tile_offset, kTileNumBytes, ZX_CACHE_FLUSH_DATA);
          }

          // Store offset of uncompressed tile memory in byte 0-3.
          *(reinterpret_cast<uint32_t*>(header_ptr)) = body_offset + tile_offset;

          // Set byte 4-15 to disable compression for tile memory.
          header_ptr[4] = header_ptr[7] = header_ptr[10] = header_ptr[13] = 0x41;
          header_ptr[5] = header_ptr[8] = header_ptr[11] = header_ptr[14] = 0x10;
          header_ptr[6] = header_ptr[9] = header_ptr[12] = header_ptr[15] = 0x04;
        }
      }
    }
  }

  if (image.needs_flush) {
    zx_cache_flush(header_base, body_offset, ZX_CACHE_FLUSH_DATA);
  }

  image.image_bytes_used = body_offset + next_tile_index * kTileNumBytes;
  image.image_bytes_deduped = 0;
}

void SoftwareView::SetLinearPixelsFromColorOffset(Image& image, uint32_t color_offset) {
  TRACE_DURATION("gfx", "SoftwareView::SetLinearPixelsFromColorOffset");

  uint8_t* vmo_base = image.vmo_ptr;
  for (uint32_t y = 0; y < height_; ++y) {
    uint32_t color = y >= color_offset ? kColor0 : kColor1;
    uint32_t* target = reinterpret_cast<uint32_t*>(&vmo_base[y * image.stride]);
    for (uint32_t x = 0; x < width_; ++x) {
      target[x] = color;
    }
  }

  if (image.needs_flush) {
    zx_cache_flush(image.vmo_ptr, image.image_bytes, ZX_CACHE_FLUSH_DATA);
  }
}

void SoftwareView::SetPixelsFromPng(Image& image, png_structp png) {
  switch (modifier_) {
    case fuchsia::sysmem::FORMAT_MODIFIER_ARM_AFBC_16X16_YUV_TILED_HEADER:
      SetAfbcPixelsFromPng(image, png);
      break;
    case fuchsia::sysmem::FORMAT_MODIFIER_LINEAR:
      SetLinearPixelsFromPng(image, png);
      break;
    default:
      FX_NOTREACHED() << "Modifier not supported.";
  }
}

void SoftwareView::SetAfbcPixelsFromPng(Image& image, png_structp png) {
  TRACE_DURATION("gfx", "SoftwareView::SetAfbcPixelsFromPng");

  uint32_t width_in_tiles = image.width_in_tiles;
  uint32_t height_in_tiles = image.height_in_tiles;
  uint32_t tile_count = width_in_tiles * height_in_tiles;
  uint32_t body_offset =
      fbl::round_up(tile_count * kAfbcBytesPerBlockHeader, kTiledAfbcBodyAlignment);
  uint32_t subtile_num_bytes = kTileNumBytes / (kAfbcSubtileSize * kAfbcSubtileSize);
  uint32_t subtile_stride = subtile_num_bytes / kAfbcSubtileSize;
  uint32_t width_in_superblocks = width_in_tiles / kAfbcHeaderTileWidth;
  uint32_t stride = width_in_tiles * kAfbcTilePixelWidth;

  uint8_t* header_base = image.vmo_ptr;
  uint8_t* body_base = header_base + body_offset;

  uint32_t next_tile_index = 0;
  uint32_t solid_tile_count = 0;

  // Resize scratch buffer to fit one row of tiles.
  scratch_.resize(stride * kAfbcTilePixelHeight);
  // Reset tile map.
  image.tiles.clear();

  uint32_t rows_left = height_;
  for (unsigned j = 0; j < height_in_tiles; ++j) {
    row_pointers_.clear();
    for (uint32_t y = 0; y < kAfbcTilePixelHeight; ++y) {
      row_pointers_.push_back(reinterpret_cast<png_bytep>(scratch_.data()) + y * stride * 4);
    }
    memset(scratch_.data(), 0, scratch_.size() * 4);

    if (rows_left) {
      TRACE_DURATION("gfx", "SoftwareView::SetAfbcPixelsFromPng::ReadRows");
      uint32_t rows = std::min(rows_left, static_cast<uint32_t>(row_pointers_.size()));
      png_read_rows(png, row_pointers_.data(), nullptr, rows);
      rows_left -= rows;
    }

    for (unsigned i = 0; i < width_in_tiles; i++) {
      unsigned tile_x = i * kAfbcTilePixelWidth;

      constexpr uint32_t kAfbcSubtileNumPixels = kAfbcSubtileSize * kAfbcSubtileSize;

#define S(offset) ((offset)*kAfbcSubtileNumPixels)
      constexpr uint32_t kAfbcSubtileOffset[4][4] = {
          {S(2), S(1), S(14), S(13)},
          {S(3), S(0), S(15), S(12)},
          {S(4), S(7), S(8), S(11)},
          {S(5), S(6), S(9), S(10)},
      };
#undef S

      uint32_t tile_pixels[kTileNumPixels];
      uint32_t last_pixel = scratch_[tile_x];
      bool is_solid_color = true;

      {
        TRACE_DURATION("gfx", "SoftwareView::SetAfbcPixelsFromPng::LinearToTile");

        // Convert to uncompressed tile memory and detect solid colors in the process.
        for (unsigned y = 0; y < kAfbcTilePixelHeight; ++y) {
          uint32_t* row = scratch_.data() + y * stride + tile_x;
          uint32_t subtile_j = y / kAfbcSubtileSize;
          uint32_t subtile_y = y % kAfbcSubtileSize;
          uint32_t subtile_row_offset = subtile_y * kAfbcSubtileSize;
          for (unsigned x = 0; x < kAfbcTilePixelWidth; ++x) {
            uint32_t pixel = row[x];
            uint32_t subtile_i = x / kAfbcSubtileSize;
            uint32_t subtile_x = x % kAfbcSubtileSize;
            uint32_t tile_offset =
                kAfbcSubtileOffset[subtile_i][subtile_j] + subtile_row_offset + subtile_x;
            tile_pixels[tile_offset] = pixel;
            is_solid_color = is_solid_color && (pixel == last_pixel);
            last_pixel = pixel;
          }
        }
      }

      unsigned superblock_i = i / kAfbcHeaderTileWidth;
      unsigned superblock_x = i % kAfbcHeaderTileWidth;
      unsigned block_4x4_i = superblock_x / 4;
      unsigned block_4x4_x = superblock_x % 4;
      unsigned block_2x2_i = block_4x4_x / 2;
      unsigned block_2x2_x = block_4x4_x % 2;

      unsigned superblock_j = j / kAfbcHeaderTileHeight;
      unsigned superblock_y = j % kAfbcHeaderTileHeight;
      unsigned block_4x4_j = superblock_y / 4;
      unsigned block_4x4_y = superblock_y % 4;
      unsigned block_2x2_j = block_4x4_y / 2;
      unsigned block_2x2_y = block_4x4_y % 2;

      unsigned superblock_idx = superblock_j * width_in_superblocks + superblock_i;

      unsigned tile_idx = superblock_idx * kAfbcHeaderTileBlocks;
      tile_idx += (block_4x4_j * 2 + block_4x4_i) * 16;
      tile_idx += (block_2x2_j * 2 + block_2x2_i) * 4;
      tile_idx += block_2x2_y * 2 + block_2x2_x;

      unsigned header_offset = tile_idx * kAfbcBytesPerBlockHeader;
      uint8_t* header_ptr = header_base + header_offset;
      if (is_solid_color) {
        TRACE_DURATION("gfx", "SoftwareView::SetAfbcPixelsFromPng::SetSolid");

        // Reset header.
        header_ptr[0] = header_ptr[1] = header_ptr[2] = header_ptr[3] = header_ptr[4] =
            header_ptr[5] = header_ptr[6] = header_ptr[7] = header_ptr[12] = header_ptr[13] =
                header_ptr[14] = header_ptr[15] = 0;

        // Solid colors are stored at offset 8 in block header.
        *(reinterpret_cast<uint32_t*>(header_ptr + 8)) = last_pixel;
        ++solid_tile_count;
      } else {
        TRACE_DURATION("gfx", "SoftwareView::SetAfbcPixelsFromPng::Uncompressed");

        uint32_t tile_offset;

        auto it = image.tiles.find((Tile){tile_pixels});
        if (it == image.tiles.end()) {
          uint32_t tile_index = next_tile_index++;
          tile_offset = tile_index * kTileNumBytes;

          // Copy uncompressed tile memory and add new unique tile.
          memcpy(body_base + tile_offset, tile_pixels, kTileNumBytes);
          if (image.needs_flush) {
            zx_cache_flush(body_base + tile_offset, kTileNumBytes, ZX_CACHE_FLUSH_DATA);
          }
          image.tiles.insert(
              {(Tile){reinterpret_cast<uint32_t*>(body_base + tile_offset)}, tile_offset});
        } else {
          tile_offset = it->second;
        }

        // Store offset of uncompressed tile memory in byte 0-3.
        *(reinterpret_cast<uint32_t*>(header_ptr)) = body_offset + tile_offset;

        // Set byte 4-15 to disable compression for tile memory.
        header_ptr[4] = header_ptr[7] = header_ptr[10] = header_ptr[13] = 0x41;
        header_ptr[5] = header_ptr[8] = header_ptr[11] = header_ptr[14] = 0x10;
        header_ptr[6] = header_ptr[9] = header_ptr[12] = header_ptr[15] = 0x04;
      }
    }
  }

  if (image.needs_flush) {
    TRACE_DURATION("gfx", "SoftwareView::SetAfbcPixelsFromPng::Flush");
    zx_cache_flush(header_base, body_offset, ZX_CACHE_FLUSH_DATA);
  }

  image.image_bytes_used = body_offset + next_tile_index * kTileNumBytes;
  image.image_bytes_deduped = ((tile_count - solid_tile_count) - next_tile_index) * kTileNumBytes;
}

void SoftwareView::SetLinearPixelsFromPng(Image& image, png_structp png) {
  TRACE_DURATION("gfx", "SoftwareView::SetLinearPixelsFromPng");

  row_pointers_.clear();
  uint8_t* vmo_base = image.vmo_ptr;
  for (uint32_t y = 0; y < height_; ++y) {
    row_pointers_.push_back(reinterpret_cast<png_bytep>(&vmo_base[y * image.stride]));
  }

  {
    TRACE_DURATION("gfx", "SoftwareView::SetLinearPixelsFromPng::ReadImage");
    png_read_image(png, row_pointers_.data());
  }

  if (image.needs_flush) {
    TRACE_DURATION("gfx", "SoftwareView::SetLinearPixelsFromPng::Flush");
    zx_cache_flush(image.vmo_ptr, image.image_bytes, ZX_CACHE_FLUSH_DATA);
  }

  image.image_bytes_used = height_ * image.stride;
  image.image_bytes_deduped = 0;
}

fit::promise<inspect::Inspector> SoftwareView::PopulateStats() const {
  inspect::Inspector inspector;

  inspector.GetRoot().CreateUint(kModifier, modifier_, &inspector);

  return fit::make_ok_promise(std::move(inspector));
}

fit::promise<inspect::Inspector> SoftwareView::PopulateImageStats(const Image& image) const {
  inspect::Inspector inspector;

  inspector.GetRoot().CreateUint(kImageBytes, image.image_bytes, &inspector);
  inspector.GetRoot().CreateUint(kImageBytesUsed, image.image_bytes_used, &inspector);
  inspector.GetRoot().CreateUint(kImageBytesDeduped, image.image_bytes_deduped, &inspector);
  if (modifier_ == fuchsia::sysmem::FORMAT_MODIFIER_ARM_AFBC_16X16_YUV_TILED_HEADER) {
    inspector.GetRoot().CreateUint(kWidthInTiles, image.width_in_tiles, &inspector);
    inspector.GetRoot().CreateUint(kHeightInTiles, image.height_in_tiles, &inspector);
  }

  return fit::make_ok_promise(std::move(inspector));
}

}  // namespace frame_compression
