Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@ FLUTTER_DARWIN_EXPORT
* See also: https://github.com/flutter/plugins/tree/master/packages/camera
*/
@protocol FlutterTexture <NSObject>
/** Copy the contents of the texture into a `CVPixelBuffer`. */
/**
* Copy the contents of the texture into a `CVPixelBuffer`.
*
* The type of the pixel buffer is one of the following:
* - `kCVPixelFormatType_32BGRA`
* - `kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange`
* - `kCVPixelFormatType_420YpCbCr8BiPlanarFullRange`
*/
- (CVPixelBufferRef _Nullable)copyPixelBuffer;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,11 @@ - (void)onTextureUnregistered {
if (_pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
_pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
image = [self wrapNV12ExternalPixelBuffer:pixelBuffer context:context];
} else if (_pixelFormat == kCVPixelFormatType_32BGRA) {
image = [self wrapBGRAExternalPixelBuffer:pixelBuffer context:context];
} else {
image = [self wrapRGBAExternalPixelBuffer:pixelBuffer context:context];
FML_LOG(ERROR) << "Unsupported pixel format: " << _pixelFormat;
return nullptr;
}

if (!image) {
Expand Down Expand Up @@ -235,7 +238,7 @@ - (void)onTextureUnregistered {
return flutter::DlImage::Make(skImage);
}

- (sk_sp<flutter::DlImage>)wrapRGBAExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
- (sk_sp<flutter::DlImage>)wrapBGRAExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
context:(flutter::Texture::PaintContext&)context {
SkISize textureSize =
SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,4 +288,50 @@ - (CVPixelBufferRef)pixelBuffer {
gpuSurface->makeImageSnapshot();
}

TEST_F(FlutterEmbedderExternalTextureTest, TestPopulateUnsupportedExternalTexture) {
// Constants.
const size_t width = 100;
const size_t height = 100;
const int64_t texture_id = 1;

// Set up the surface.
FlutterDarwinContextMetalSkia* darwinContextMetal =
[[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
GrDirectContext* grContext = darwinContextMetal.mainContext.get();
sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));

// Create a texture.
TestExternalTexture* testExternalTexture =
[[TestExternalTexture alloc] initWidth:width
height:height
pixelFormatType:kCVPixelFormatType_420YpCbCr8PlanarFullRange];
FlutterExternalTexture* textureHolder =
[[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
darwinMetalContext:darwinContextMetal];

// Callback to resolve the texture.
EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
size_t h) {
EXPECT_TRUE(w == width);
EXPECT_TRUE(h == height);

auto texture = std::make_unique<FlutterMetalExternalTexture>();
EXPECT_FALSE([textureHolder populateTexture:texture.get()]);
return nullptr;
};

// Render the texture.
std::unique_ptr<flutter::Texture> texture =
std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
SkRect bounds = SkRect::MakeWH(info.width(), info.height());
DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
flutter::Texture::PaintContext context{
.canvas = &canvas,
.gr_context = grContext,
};
texture->Paint(context, bounds, /*freeze=*/false, sampling);
}

} // namespace flutter::testing
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ - (BOOL)populateTexture:(FlutterMetalExternalTexture*)textureOut {
if (pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
pixel_format == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
return [self populateTextureFromYUVAPixelBuffer:pixelBuffer textureOut:textureOut];
} else {
} else if (pixel_format == kCVPixelFormatType_32BGRA) {
return [self populateTextureFromRGBAPixelBuffer:pixelBuffer textureOut:textureOut];
} else {
NSLog(@"Unsupported pixel format: %d", pixel_format);
return NO;
}
}

Expand Down