5#import "flutter/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.h"
6#include "flutter/display_list/image/dl_image.h"
25 CVMetalTextureCacheRef _textureCache;
34- (instancetype)initWithTextureCache:(nonnull CVMetalTextureCacheRef)textureCache
35 textureID:(int64_t)textureID
37 enableImpeller:(
BOOL)enableImpeller {
39 _textureCache = textureCache;
40 CFRetain(_textureCache);
52 CVMetalTextureCacheFlush(_textureCache,
55 CFRelease(_textureCache);
59- (void)paintContext:(
flutter::Texture::PaintContext&)context
60 bounds:(const
SkRect&)bounds
65 if (needsUpdatedTexture) {
66 [
self onNeedsUpdatedTexture:context];
80- (void)onNeedsUpdatedTexture:(
flutter::Texture::PaintContext&)context {
81 CVPixelBufferRef pixelBuffer = [_externalTexture copyPixelBuffer];
97- (void)onGrContextCreated {
103- (void)onGrContextDestroyed {
109 CVMetalTextureCacheFlush(_textureCache,
114- (void)markNewFrameAvailable {
118- (void)onTextureUnregistered {
119 if ([
_externalTexture respondsToSelector:
@selector(onTextureUnregistered:)]) {
120 [_externalTexture onTextureUnregistered:_externalTexture];
124#pragma mark - External texture skia wrapper methods.
126- (
sk_sp<
flutter::DlImage>)wrapExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
127 context:(
flutter::Texture::PaintContext&)context {
133 if (
_pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
134 _pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
135 image = [
self wrapNV12ExternalPixelBuffer:pixelBuffer context:context];
137 image = [
self wrapBGRAExternalPixelBuffer:pixelBuffer context:context];
144 FML_DLOG(
ERROR) <<
"Could not wrap Metal texture as a display list image.";
150- (
sk_sp<
flutter::DlImage>)wrapNV12ExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
151 context:(
flutter::Texture::PaintContext&)context {
153 SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
154 CVMetalTextureRef yMetalTexture =
nullptr;
157 CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
161 MTLPixelFormatR8Unorm,
167 if (cvReturn != kCVReturnSuccess) {
168 FML_DLOG(
ERROR) <<
"Could not create Metal texture from pixel buffer: CVReturn " << cvReturn;
173 CVMetalTextureRef uvMetalTexture =
nullptr;
176 CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
180 MTLPixelFormatRG8Unorm,
181 textureSize.
width() / 2,
186 if (cvReturn != kCVReturnSuccess) {
187 FML_DLOG(
ERROR) <<
"Could not create Metal texture from pixel buffer: CVReturn " << cvReturn;
192 id<MTLTexture> yTex = CVMetalTextureGetTexture(yMetalTexture);
193 CVBufferRelease(yMetalTexture);
195 id<MTLTexture> uvTex = CVMetalTextureGetTexture(uvMetalTexture);
196 CVBufferRelease(uvMetalTexture);
216 _pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
231 width:textureSize.width()
232 height:textureSize.height()];
241- (
sk_sp<
flutter::DlImage>)wrapBGRAExternalPixelBuffer:(CVPixelBufferRef)pixelBuffer
242 context:(
flutter::Texture::PaintContext&)context {
244 SkISize::Make(CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer));
245 CVMetalTextureRef metalTexture =
nullptr;
247 CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
251 MTLPixelFormatBGRA8Unorm,
257 if (cvReturn != kCVReturnSuccess) {
258 FML_DLOG(
ERROR) <<
"Could not create Metal texture from pixel buffer: CVReturn " << cvReturn;
262 id<MTLTexture> rgbaTex = CVMetalTextureGetTexture(metalTexture);
263 CVBufferRelease(metalTexture);
278 width:textureSize.width()
279 height:textureSize.height()];
293 UVTex:(
id<MTLTexture>)uvTex
297 height:(
size_t)height {
301 GrMtlTextureInfo ySkiaTextureInfo;
302 ySkiaTextureInfo.fTexture = sk_cfp<const void*>{(__bridge_retained
const void*)yTex};
305 skiaBackendTextures[0] =
308 GrMtlTextureInfo uvSkiaTextureInfo;
309 uvSkiaTextureInfo.fTexture = sk_cfp<const void*>{(__bridge_retained
const void*)uvTex};
311 skiaBackendTextures[1] =
324+ (
sk_sp<
SkImage>)wrapRGBATexture:(
id<MTLTexture>)rgbaTex
327 height:(
size_t)height {
332 GrMtlTextureInfo skiaTextureInfo;
333 skiaTextureInfo.fTexture = sk_cfp<const void*>{(__bridge_retained
const void*)rgbaTex};
sk_sp< flutter::DlImage > _externalImage
NSObject< FlutterTexture > * _externalTexture
CVPixelBufferRef _lastPixelBuffer
BOOL _textureFrameAvailable
@ kTopLeft_GrSurfaceOrigin
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
@ kRec601_Limited_SkYUVColorSpace
describes SDTV range
@ kJPEG_Full_SkYUVColorSpace
describes full range
@ kY_UV
Plane 0: Y, Plane 1: UV.
@ k444
No subsampling. UV values for each Y.
static sk_sp< DlImage > Make(const SkImage *image)
static sk_sp< DlImageImpeller > MakeFromYUVTextures(AiksContext *aiks_context, std::shared_ptr< Texture > y_texture, std::shared_ptr< Texture > uv_texture, YUVColorSpace yuv_color_space)
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
static std::shared_ptr< TextureMTL > Wrapper(TextureDescriptor desc, id< MTLTexture > texture, std::function< void()> deletion_proc=nullptr)
void reset(T *ptr=nullptr)
#define FML_DLOG(severity)
#define FML_LOG(severity)
sk_sp< SkImage > wrapRGBATexture:grContext:width:height:(nonnull id< MTLTexture > rgbaTex,[grContext] nonnull GrDirectContext *grContext,[width] size_t width,[height] size_t height)
sk_sp< SkImage > wrapYUVATexture:UVTex:YUVColorSpace:grContext:width:height:(nonnull id< MTLTexture > yTex,[UVTex] nonnull id< MTLTexture > uvTex,[YUVColorSpace] SkYUVColorSpace colorSpace,[grContext] nonnull GrDirectContext *grContext,[width] size_t width,[height] size_t height)
SK_API GrBackendTexture MakeMtl(int width, int height, skgpu::Mipmapped, const GrMtlTextureInfo &mtlInfo, std::string_view label={})
SK_API sk_sp< SkImage > TextureFromYUVATextures(GrRecordingContext *context, const GrYUVABackendTextures &yuvaTextures, sk_sp< SkColorSpace > imageColorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
SK_API sk_sp< SkImage > BorrowTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
Optional< SkRect > bounds
sk_sp< const SkImage > image
SkSamplingOptions sampling
static constexpr SkISize Make(int32_t w, int32_t h)
constexpr int32_t width() const
constexpr int32_t height() const
static SkRect Make(const SkISize &size)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...