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 1 commit
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 {
} else if (_pixelFormat == kCVPixelFormatType_32BGRA) {
image = [self wrapRGBAExternalPixelBuffer:pixelBuffer context:context];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is incorrectly named. Perhaps rename to wrapBGRAExternalPixelBuffer:context: too? Internally, it does assume BGRA as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Note that [FlutterDarwinExternalTextureSkImageWrapper: wrapRGBATexture:grContext:width:height:] also has RGBA in its name. I'm not sure renaming all of them to use BGRA is a good idea, but I'm open to suggestions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If its not already a public method and the name is more fitting, go for it!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was considering renaming the wrapRGBATexture method, but I think it is better to keep the method name as it is.

Link1 Link2

We have kYUVA and kRGBA as the two possible values for FlutterMetalExternalTexturePixelFormat, and the function I mentioned above is used along with the enum, FlutterMetalExternalTexturePixelFormat. So it sounds like renaming would be more confusing.

} else {
FML_LOG(ERROR) << "Unsupported pixel format: " << _pixelFormat;
return nullptr;
}

if (!image) {
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