Flutter Engine
The Flutter Engine
FlutterExternalTexture.mm
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.h"
6
7#include "flutter/fml/platform/darwin/cf_utils.h"
8
9@implementation FlutterExternalTexture {
10 FlutterDarwinContextMetalSkia* _darwinMetalContext;
11
12 int64_t _textureID;
13
14 id<FlutterTexture> _texture;
15
16 std::vector<FlutterMetalTextureHandle> _textures;
17}
18
19- (instancetype)initWithFlutterTexture:(id<FlutterTexture>)texture
20 darwinMetalContext:(FlutterDarwinContextMetalSkia*)context {
21 self = [super init];
22 if (self) {
24 _textureID = reinterpret_cast<int64_t>(_texture);
25 _darwinMetalContext = context;
26 }
27 return self;
28}
29
30- (int64_t)textureID {
31 return _textureID;
32}
33
34- (BOOL)populateTexture:(FlutterMetalExternalTexture*)textureOut {
35 // Copy the pixel buffer from the FlutterTexture instance implemented on the user side.
36 fml::CFRef<CVPixelBufferRef> pixelBuffer([_texture copyPixelBuffer]);
37
38 if (!pixelBuffer) {
39 return NO;
40 }
41
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];
48 } else {
49 NSLog(@"Unsupported pixel format: %d", pixel_format);
50 return NO;
51 }
52}
53
54- (BOOL)populateTextureFromYUVAPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer
55 textureOut:(nonnull FlutterMetalExternalTexture*)textureOut {
56 CVMetalTextureRef yCVMetalTexture = nullptr;
57 CVMetalTextureRef uvCVMetalTextureRef = nullptr;
58 SkISize textureSize =
59 SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
60
61 CVReturn yCVReturn = CVMetalTextureCacheCreateTextureFromImage(
62 /*allocator=*/kCFAllocatorDefault,
63 /*textureCache=*/_darwinMetalContext.textureCache,
64 /*sourceImage=*/pixelBuffer,
65 /*textureAttributes=*/nullptr,
66 /*pixelFormat=*/MTLPixelFormatR8Unorm,
67 /*width=*/CVPixelBufferGetWidthOfPlane(pixelBuffer, 0u),
68 /*height=*/CVPixelBufferGetHeightOfPlane(pixelBuffer, 0u),
69 /*planeIndex=*/0u,
70 /*texture=*/&yCVMetalTexture);
71
72 if (yCVReturn != kCVReturnSuccess) {
73 NSLog(@"Could not create Metal texture from pixel buffer: CVReturn %d", yCVReturn);
74 return NO;
75 }
76
77 CVReturn uvCVReturn = CVMetalTextureCacheCreateTextureFromImage(
78 /*allocator=*/kCFAllocatorDefault,
79 /*textureCache=*/_darwinMetalContext.textureCache,
80 /*sourceImage=*/pixelBuffer,
81 /*textureAttributes=*/nullptr,
82 /*pixelFormat=*/MTLPixelFormatRG8Unorm,
83 /*width=*/CVPixelBufferGetWidthOfPlane(pixelBuffer, 1u),
84 /*height=*/CVPixelBufferGetHeightOfPlane(pixelBuffer, 1u),
85 /*planeIndex=*/1u,
86 /*texture=*/&uvCVMetalTextureRef);
87
88 if (uvCVReturn != kCVReturnSuccess) {
89 CVBufferRelease(yCVMetalTexture);
90 NSLog(@"Could not create Metal texture from pixel buffer: CVReturn %d", uvCVReturn);
91 return NO;
92 }
93
94 _textures = {(__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(yCVMetalTexture),
95 (__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(uvCVMetalTextureRef)};
96 CVBufferRelease(yCVMetalTexture);
97 CVBufferRelease(uvCVMetalTextureRef);
98
99 textureOut->num_textures = 2;
100 textureOut->height = textureSize.height();
101 textureOut->width = textureSize.width();
103 textureOut->textures = _textures.data();
104 OSType pixel_format = CVPixelBufferGetPixelFormatType(pixelBuffer);
105 textureOut->yuv_color_space = pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
108
109 return YES;
110}
111
112- (BOOL)populateTextureFromRGBAPixelBuffer:(nonnull CVPixelBufferRef)pixelBuffer
113 textureOut:(nonnull FlutterMetalExternalTexture*)textureOut {
114 SkISize textureSize =
115 SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
116
117 CVMetalTextureRef cvMetalTexture = nullptr;
118 CVReturn cvReturn =
119 CVMetalTextureCacheCreateTextureFromImage(/*allocator=*/kCFAllocatorDefault,
120 /*textureCache=*/_darwinMetalContext.textureCache,
121 /*sourceImage=*/pixelBuffer,
122 /*textureAttributes=*/nullptr,
123 /*pixelFormat=*/MTLPixelFormatBGRA8Unorm,
124 /*width=*/textureSize.width(),
125 /*height=*/textureSize.height(),
126 /*planeIndex=*/0u,
127 /*texture=*/&cvMetalTexture);
128
129 if (cvReturn != kCVReturnSuccess) {
130 NSLog(@"Could not create Metal texture from pixel buffer: CVReturn %d", cvReturn);
131 return NO;
132 }
133
134 _textures = {(__bridge FlutterMetalTextureHandle)CVMetalTextureGetTexture(cvMetalTexture)};
135 CVBufferRelease(cvMetalTexture);
136
137 textureOut->num_textures = 1;
138 textureOut->height = textureSize.height();
139 textureOut->width = textureSize.width();
141 textureOut->textures = _textures.data();
142
143 return YES;
144}
145
146@end
std::vector< FlutterMetalTextureHandle > _textures
id< FlutterTexture > _texture
int64_t _textureID
@ kBT601LimitedRange
Definition: embedder.h:613
@ kBT601FullRange
Definition: embedder.h:612
@ kRGBA
Definition: embedder.h:607
@ kYUVA
Definition: embedder.h:606
const void * FlutterMetalTextureHandle
Alias for id<MTLTexture>.
Definition: embedder.h:602
FlTexture * texture
FlutterMetalTextureHandle * textures
Definition: embedder.h:635
size_t num_textures
Represents the size of the textures array.
Definition: embedder.h:626
FlutterMetalExternalTexturePixelFormat pixel_format
The pixel format type of the external.
Definition: embedder.h:624
FlutterMetalExternalTextureYUVColorSpace yuv_color_space
The YUV color space of the YUV external texture.
Definition: embedder.h:637
size_t height
Height of the texture.
Definition: embedder.h:622
size_t width
Height of the texture.
Definition: embedder.h:620
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
int BOOL
Definition: windows_types.h:37