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];
47 return [
self populateTextureFromRGBAPixelBuffer:pixelBuffer textureOut:textureOut];
51 - (BOOL)populateTextureFromYUVAPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer
52 textureOut:(nonnull FlutterMetalExternalTexture*)textureOut {
53 CVMetalTextureRef yCVMetalTexture =
nullptr;
54 CVMetalTextureRef uvCVMetalTextureRef =
nullptr;
56 SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
58 CVReturn yCVReturn = CVMetalTextureCacheCreateTextureFromImage(
60 _darwinMetalContext.textureCache,
63 MTLPixelFormatR8Unorm,
64 CVPixelBufferGetWidthOfPlane(pixelBuffer, 0u),
65 CVPixelBufferGetHeightOfPlane(pixelBuffer, 0u),
69 if (yCVReturn != kCVReturnSuccess) {
70 NSLog(
@"Could not create Metal texture from pixel buffer: CVReturn %d", yCVReturn);
74 CVReturn uvCVReturn = CVMetalTextureCacheCreateTextureFromImage(
76 _darwinMetalContext.textureCache,
79 MTLPixelFormatRG8Unorm,
80 CVPixelBufferGetWidthOfPlane(pixelBuffer, 1u),
81 CVPixelBufferGetHeightOfPlane(pixelBuffer, 1u),
83 &uvCVMetalTextureRef);
85 if (uvCVReturn != kCVReturnSuccess) {
86 CVBufferRelease(yCVMetalTexture);
87 NSLog(
@"Could not create Metal texture from pixel buffer: CVReturn %d", uvCVReturn);
91 _textures = {(__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(yCVMetalTexture),
92 (__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(uvCVMetalTextureRef)};
93 CVBufferRelease(yCVMetalTexture);
94 CVBufferRelease(uvCVMetalTextureRef);
96 textureOut->num_textures = 2;
97 textureOut->height = textureSize.height();
98 textureOut->width = textureSize.width();
99 textureOut->pixel_format = FlutterMetalExternalTexturePixelFormat::kYUVA;
101 OSType pixel_format = CVPixelBufferGetPixelFormatType(pixelBuffer);
102 textureOut->yuv_color_space = pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
103 ? FlutterMetalExternalTextureYUVColorSpace::kBT601LimitedRange
104 : FlutterMetalExternalTextureYUVColorSpace::kBT601FullRange;
109 - (BOOL)populateTextureFromRGBAPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer
110 textureOut:(nonnull FlutterMetalExternalTexture*)textureOut {
111 SkISize textureSize =
112 SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
114 CVMetalTextureRef cvMetalTexture =
nullptr;
116 CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
117 _darwinMetalContext.textureCache,
120 MTLPixelFormatBGRA8Unorm,
122 textureSize.height(),
126 if (cvReturn != kCVReturnSuccess) {
127 NSLog(
@"Could not create Metal texture from pixel buffer: CVReturn %d", cvReturn);
131 _textures = {(__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(cvMetalTexture)};
132 CVBufferRelease(cvMetalTexture);
134 textureOut->num_textures = 1;
135 textureOut->height = textureSize.height();
136 textureOut->width = textureSize.width();
137 textureOut->pixel_format = FlutterMetalExternalTexturePixelFormat::kRGBA;