7 #include "flutter/fml/platform/darwin/cf_utils.h"
10 FlutterDarwinContextMetalSkia* _darwinMetalContext;
20 darwinMetalContext:(FlutterDarwinContextMetalSkia*)context {
25 _darwinMetalContext = context;
30 - (int64_t)textureID {
34 - (BOOL)populateTexture:(FlutterMetalExternalTexture*)textureOut {
36 fml::CFRef<CVPixelBufferRef> pixelBuffer([
_texture copyPixelBuffer]);
42 OSType pixel_format = CVPixelBufferGetPixelFormatType(pixelBuffer);
43 if (pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
44 pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
45 return [
self populateTextureFromYUVAPixelBuffer:pixelBuffer textureOut:textureOut];
46 }
else if (pixel_format == kCVPixelFormatType_32BGRA) {
47 return [
self populateTextureFromRGBAPixelBuffer:pixelBuffer textureOut:textureOut];
49 NSLog(
@"Unsupported pixel format: %d", pixel_format);
54 - (BOOL)populateTextureFromYUVAPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer
55 textureOut:(nonnull FlutterMetalExternalTexture*)textureOut {
56 CVMetalTextureRef yCVMetalTexture =
nullptr;
57 CVMetalTextureRef uvCVMetalTextureRef =
nullptr;
59 SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
61 CVReturn yCVReturn = CVMetalTextureCacheCreateTextureFromImage(
63 _darwinMetalContext.textureCache,
66 MTLPixelFormatR8Unorm,
67 CVPixelBufferGetWidthOfPlane(pixelBuffer, 0u),
68 CVPixelBufferGetHeightOfPlane(pixelBuffer, 0u),
72 if (yCVReturn != kCVReturnSuccess) {
73 NSLog(
@"Could not create Metal texture from pixel buffer: CVReturn %d", yCVReturn);
77 CVReturn uvCVReturn = CVMetalTextureCacheCreateTextureFromImage(
79 _darwinMetalContext.textureCache,
82 MTLPixelFormatRG8Unorm,
83 CVPixelBufferGetWidthOfPlane(pixelBuffer, 1u),
84 CVPixelBufferGetHeightOfPlane(pixelBuffer, 1u),
86 &uvCVMetalTextureRef);
88 if (uvCVReturn != kCVReturnSuccess) {
89 CVBufferRelease(yCVMetalTexture);
90 NSLog(
@"Could not create Metal texture from pixel buffer: CVReturn %d", uvCVReturn);
94 _textures = {(__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(yCVMetalTexture),
95 (__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(uvCVMetalTextureRef)};
96 CVBufferRelease(yCVMetalTexture);
97 CVBufferRelease(uvCVMetalTextureRef);
99 textureOut->num_textures = 2;
100 textureOut->height = textureSize.height();
101 textureOut->width = textureSize.width();
102 textureOut->pixel_format = FlutterMetalExternalTexturePixelFormat::kYUVA;
104 OSType pixel_format = CVPixelBufferGetPixelFormatType(pixelBuffer);
105 textureOut->yuv_color_space = pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
106 ? FlutterMetalExternalTextureYUVColorSpace::kBT601LimitedRange
107 : FlutterMetalExternalTextureYUVColorSpace::kBT601FullRange;
112 - (BOOL)populateTextureFromRGBAPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer
113 textureOut:(nonnull FlutterMetalExternalTexture*)textureOut {
114 SkISize textureSize =
115 SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
117 CVMetalTextureRef cvMetalTexture =
nullptr;
119 CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
120 _darwinMetalContext.textureCache,
123 MTLPixelFormatBGRA8Unorm,
125 textureSize.height(),
129 if (cvReturn != kCVReturnSuccess) {
130 NSLog(
@"Could not create Metal texture from pixel buffer: CVReturn %d", cvReturn);
134 _textures = {(__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(cvMetalTexture)};
135 CVBufferRelease(cvMetalTexture);
137 textureOut->num_textures = 1;
138 textureOut->height = textureSize.height();
139 textureOut->width = textureSize.width();
140 textureOut->pixel_format = FlutterMetalExternalTexturePixelFormat::kRGBA;