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

#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.h"

#include "flutter/fml/platform/darwin/cf_utils.h"

@implementation FlutterExternalTextureMetal {
  FlutterDarwinContextMetal* _darwinMetalContext;

  int64_t _textureID;

  id<FlutterTexture> _texture;

  std::vector<FlutterMetalTextureHandle> _textures;
}

- (instancetype)initWithFlutterTexture:(id<FlutterTexture>)texture
                    darwinMetalContext:(FlutterDarwinContextMetal*)context {
  self = [super init];
  if (self) {
    _texture = texture;
    _textureID = reinterpret_cast<int64_t>(_texture);
    _darwinMetalContext = context;
  }
  return self;
}

- (int64_t)textureID {
  return _textureID;
}

- (BOOL)populateTexture:(FlutterMetalExternalTexture*)textureOut {
  // Copy the pixel buffer from the FlutterTexture instance implemented on the user side.
  fml::CFRef<CVPixelBufferRef> pixelBuffer([_texture copyPixelBuffer]);

  if (!pixelBuffer) {
    return NO;
  }

  OSType pixel_format = CVPixelBufferGetPixelFormatType(pixelBuffer);
  if (pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
      pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
    return [self populateTextureFromYUVAPixelBuffer:pixelBuffer textureOut:textureOut];
  } else {
    return [self populateTextureFromRGBAPixelBuffer:pixelBuffer textureOut:textureOut];
  }
}

- (BOOL)populateTextureFromYUVAPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer
                                textureOut:(nonnull FlutterMetalExternalTexture*)textureOut {
  CVMetalTextureRef yCVMetalTexture = nullptr;
  CVMetalTextureRef uvCVMetalTextureRef = nullptr;
  SkISize textureSize =
      SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));

  CVReturn yCVReturn = CVMetalTextureCacheCreateTextureFromImage(
      /*allocator=*/kCFAllocatorDefault,
      /*textureCache=*/_darwinMetalContext.textureCache,
      /*sourceImage=*/pixelBuffer,
      /*textureAttributes=*/nullptr,
      /*pixelFormat=*/MTLPixelFormatR8Unorm,
      /*width=*/CVPixelBufferGetWidthOfPlane(pixelBuffer, 0u),
      /*height=*/CVPixelBufferGetHeightOfPlane(pixelBuffer, 0u),
      /*planeIndex=*/0u,
      /*texture=*/&yCVMetalTexture);

  if (yCVReturn != kCVReturnSuccess) {
    NSLog(@"Could not create Metal texture from pixel buffer: CVReturn %d", yCVReturn);
    return NO;
  }

  CVReturn uvCVReturn = CVMetalTextureCacheCreateTextureFromImage(
      /*allocator=*/kCFAllocatorDefault,
      /*textureCache=*/_darwinMetalContext.textureCache,
      /*sourceImage=*/pixelBuffer,
      /*textureAttributes=*/nullptr,
      /*pixelFormat=*/MTLPixelFormatRG8Unorm,
      /*width=*/CVPixelBufferGetWidthOfPlane(pixelBuffer, 1u),
      /*height=*/CVPixelBufferGetHeightOfPlane(pixelBuffer, 1u),
      /*planeIndex=*/1u,
      /*texture=*/&uvCVMetalTextureRef);

  if (uvCVReturn != kCVReturnSuccess) {
    CVBufferRelease(yCVMetalTexture);
    NSLog(@"Could not create Metal texture from pixel buffer: CVReturn %d", uvCVReturn);
    return NO;
  }

  _textures = {(__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(yCVMetalTexture),
               (__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(uvCVMetalTextureRef)};
  CVBufferRelease(yCVMetalTexture);
  CVBufferRelease(uvCVMetalTextureRef);

  textureOut->num_textures = 2;
  textureOut->height = textureSize.height();
  textureOut->width = textureSize.width();
  textureOut->pixel_format = FlutterMetalExternalTexturePixelFormat::kYUVA;
  textureOut->textures = _textures.data();

  return YES;
}

- (BOOL)populateTextureFromRGBAPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer
                                textureOut:(nonnull FlutterMetalExternalTexture*)textureOut {
  SkISize textureSize =
      SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));

  CVMetalTextureRef cvMetalTexture = nullptr;
  CVReturn cvReturn =
      CVMetalTextureCacheCreateTextureFromImage(/*allocator=*/kCFAllocatorDefault,
                                                /*textureCache=*/_darwinMetalContext.textureCache,
                                                /*sourceImage=*/pixelBuffer,
                                                /*textureAttributes=*/nullptr,
                                                /*pixelFormat=*/MTLPixelFormatBGRA8Unorm,
                                                /*width=*/textureSize.width(),
                                                /*height=*/textureSize.height(),
                                                /*planeIndex=*/0u,
                                                /*texture=*/&cvMetalTexture);

  if (cvReturn != kCVReturnSuccess) {
    NSLog(@"Could not create Metal texture from pixel buffer: CVReturn %d", cvReturn);
    return NO;
  }

  _textures = {(__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(cvMetalTexture)};
  CVBufferRelease(cvMetalTexture);

  textureOut->num_textures = 1;
  textureOut->height = textureSize.height();
  textureOut->width = textureSize.width();
  textureOut->pixel_format = FlutterMetalExternalTexturePixelFormat::kRGBA;
  textureOut->textures = _textures.data();

  return YES;
}

@end
