// 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.

#include "impeller/renderer/backend/metal/device_buffer_mtl.h"

#include "flutter/fml/logging.h"
#include "impeller/base/validation.h"
#include "impeller/renderer/backend/metal/formats_mtl.h"
#include "impeller/renderer/backend/metal/texture_mtl.h"

namespace impeller {

DeviceBufferMTL::DeviceBufferMTL(DeviceBufferDescriptor desc,
                                 id<MTLBuffer> buffer,
                                 MTLStorageMode storage_mode)
    : DeviceBuffer(desc), buffer_(buffer), storage_mode_(storage_mode) {}

DeviceBufferMTL::~DeviceBufferMTL() = default;

id<MTLBuffer> DeviceBufferMTL::GetMTLBuffer() const {
  return buffer_;
}

uint8_t* DeviceBufferMTL::OnGetContents() const {
  if (storage_mode_ != MTLStorageModeShared) {
    return nullptr;
  }
  return reinterpret_cast<uint8_t*>(buffer_.contents);
}

std::shared_ptr<Texture> DeviceBufferMTL::AsTexture(
    Allocator& allocator,
    const TextureDescriptor& descriptor,
    uint16_t row_bytes) const {
  auto mtl_texture_desc = ToMTLTextureDescriptor(descriptor);

  if (!mtl_texture_desc) {
    VALIDATION_LOG << "Texture descriptor was invalid.";
    return nullptr;
  }

  if (@available(iOS 13.0, macos 10.15, *)) {
    mtl_texture_desc.resourceOptions = buffer_.resourceOptions;
  }

  auto texture = [buffer_ newTextureWithDescriptor:mtl_texture_desc
                                            offset:0
                                       bytesPerRow:row_bytes];
  if (!texture) {
    return nullptr;
  }
  return TextureMTL::Create(descriptor, texture);
}

[[nodiscard]] bool DeviceBufferMTL::OnCopyHostBuffer(const uint8_t* source,
                                                     Range source_range,
                                                     size_t offset) {
  auto dest = static_cast<uint8_t*>(buffer_.contents);

  if (!dest) {
    return false;
  }

  if (source) {
    ::memmove(dest + offset, source + source_range.offset, source_range.length);
  }

// MTLStorageModeManaged is never present on always returns false on iOS. But
// the compiler is mad that `didModifyRange:` appears in a TU meant for iOS. So,
// just compile it away.
#if !FML_OS_IOS
  if (storage_mode_ == MTLStorageModeManaged) {
    [buffer_ didModifyRange:NSMakeRange(offset, source_range.length)];
  }
#endif

  return true;
}

void DeviceBufferMTL::Flush(std::optional<Range> range) const {
#if !FML_OS_IOS
  auto flush_range = range.value_or(Range{0, GetDeviceBufferDescriptor().size});
  if (storage_mode_ == MTLStorageModeManaged) {
    [buffer_
        didModifyRange:NSMakeRange(flush_range.offset, flush_range.length)];
  }
#endif
}

bool DeviceBufferMTL::SetLabel(const std::string& label) {
  if (label.empty()) {
    return false;
  }
  [buffer_ setLabel:@(label.c_str())];
  return true;
}

bool DeviceBufferMTL::SetLabel(const std::string& label, Range range) {
  if (label.empty()) {
    return false;
  }
  [buffer_ addDebugMarker:@(label.c_str())
                    range:NSMakeRange(range.offset, range.length)];
  return true;
}

}  // namespace impeller
