// 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 (uint32_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
