Skip to content

Commit 0f9d88c

Browse files
cloudwebrtcchinmaygarde
authored andcommitted
Add texture support for macOS shell. (flutter#8507)
1 parent 179fab9 commit 0f9d88c

16 files changed

+215
-10
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterBin
723723
FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h
724724
FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h
725725
FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h
726+
FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h
726727
FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterChannels.mm
727728
FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m
728729
FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm
@@ -740,7 +741,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterHeadle
740741
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h
741742
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h
742743
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h
743-
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h
744744
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h
745745
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Info.plist
746746
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm
@@ -818,6 +818,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterDartP
818818
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h
819819
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm
820820
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h
821+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h
822+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.mm
821823
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputModel.h
822824
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputModel.mm
823825
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h

shell/platform/darwin/common/framework_shared.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ framework_shared_headers =
88
"framework/Headers/FlutterBinaryMessenger.h",
99
"framework/Headers/FlutterChannels.h",
1010
"framework/Headers/FlutterCodecs.h",
11+
"framework/Headers/FlutterTexture.h",
1112
],
1213
"abspath")

shell/platform/darwin/ios/BUILD.gn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ _flutter_framework_headers = [
3030
"framework/Headers/FlutterPlatformViews.h",
3131
"framework/Headers/FlutterPlugin.h",
3232
"framework/Headers/FlutterPluginAppLifeCycleDelegate.h",
33-
"framework/Headers/FlutterTexture.h",
3433
"framework/Headers/FlutterViewController.h",
3534
]
3635

shell/platform/darwin/ios/ios_external_texture_gl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "flutter/flow/texture.h"
99
#include "flutter/fml/platform/darwin/cf_utils.h"
1010
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
11-
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h"
11+
#include "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"
1212

1313
namespace flutter {
1414

shell/platform/darwin/ios/platform_view_ios.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "flutter/fml/memory/weak_ptr.h"
1313
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
1414
#include "flutter/shell/common/platform_view.h"
15-
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h"
15+
#include "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"
1616
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
1717
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h"
1818
#include "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h"

shell/platform/darwin/macos/BUILD.gn

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ shared_library("create_flutter_framework_dylib") {
5252
"framework/Source/FlutterDartProject_Internal.h",
5353
"framework/Source/FlutterEngine.mm",
5454
"framework/Source/FlutterEngine_Internal.h",
55+
"framework/Source/FlutterExternalTextureGL.h",
56+
"framework/Source/FlutterExternalTextureGL.mm",
5557
"framework/Source/FlutterTextInputModel.h",
5658
"framework/Source/FlutterTextInputModel.mm",
5759
"framework/Source/FlutterTextInputPlugin.h",
@@ -75,7 +77,10 @@ shared_library("create_flutter_framework_dylib") {
7577

7678
cflags_objcc = [ "-fobjc-arc" ]
7779

78-
libs = [ "Cocoa.framework" ]
80+
libs = [
81+
"Cocoa.framework",
82+
"CoreVideo.framework",
83+
]
7984
}
8085

8186
action("copy_dylib_and_update_framework_install_name") {

shell/platform/darwin/macos/framework/Headers/FlutterEngine.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "FlutterDartProject.h"
1212
#include "FlutterMacros.h"
1313
#include "FlutterPluginRegistrarMacOS.h"
14+
#include "FlutterTexture.h"
1415

1516
// TODO: Merge this file with the iOS FlutterEngine.h.
1617

@@ -20,7 +21,7 @@
2021
* Coordinates a single instance of execution of a Flutter engine.
2122
*/
2223
FLUTTER_EXPORT
23-
@interface FlutterEngine : NSObject <FlutterPluginRegistry>
24+
@interface FlutterEngine : NSObject <FlutterTextureRegistry, FlutterPluginRegistry>
2425

2526
/**
2627
* Initializes an engine with the given viewController.

shell/platform/darwin/macos/framework/Headers/FlutterMacOS.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
#import "FlutterMacros.h"
1212
#import "FlutterPluginMacOS.h"
1313
#import "FlutterPluginRegistrarMacOS.h"
14+
#import "FlutterTexture.h"
1415
#import "FlutterViewController.h"

shell/platform/darwin/macos/framework/Headers/FlutterPluginRegistrarMacOS.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#import "FlutterBinaryMessenger.h"
1010
#import "FlutterChannels.h"
1111
#import "FlutterMacros.h"
12+
#import "FlutterTexture.h"
1213

1314
// TODO: Merge this file and FlutterPluginMacOS.h with the iOS FlutterPlugin.h, sharing all but
1415
// the platform-specific methods.
@@ -28,6 +29,12 @@ FLUTTER_EXPORT
2829
*/
2930
@property(nonnull, readonly) id<FlutterBinaryMessenger> messenger;
3031

32+
/**
33+
* Returns a `FlutterTextureRegistry` for registering textures
34+
* provided by the plugin.
35+
*/
36+
@property(nonnull, readonly) id<FlutterTextureRegistry> textures;
37+
3138
/**
3239
* The view displaying Flutter content. May return |nil|, for instance in a headless environment.
3340
*

shell/platform/darwin/macos/framework/Source/FlutterEngine.mm

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <vector>
99

1010
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h"
11+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h"
1112
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
1213
#import "flutter/shell/platform/embedder/embedder.h"
1314

@@ -46,6 +47,12 @@ - (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message;
4647
*/
4748
- (void)shutDownEngine;
4849

50+
/**
51+
* Forwards texture copy request to the corresponding texture via |textureID|.
52+
*/
53+
- (BOOL)populateTextureWithIdentifier:(int64_t)textureID
54+
openGLTexture:(FlutterOpenGLTexture*)openGLTexture;
55+
4956
@end
5057

5158
#pragma mark -
@@ -78,6 +85,10 @@ - (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine
7885
return _flutterEngine.binaryMessenger;
7986
}
8087

88+
- (id<FlutterTextureRegistry>)textures {
89+
return _flutterEngine;
90+
}
91+
8192
- (NSView*)view {
8293
return _flutterEngine.viewController.view;
8394
}
@@ -119,6 +130,14 @@ static void OnPlatformMessage(const FlutterPlatformMessage* message, FlutterEngi
119130
[engine engineCallbackOnPlatformMessage:message];
120131
}
121132

133+
static bool OnAcquireExternalTexture(FlutterEngine* engine,
134+
int64_t texture_identifier,
135+
size_t width,
136+
size_t height,
137+
FlutterOpenGLTexture* open_gl_texture) {
138+
return [engine populateTextureWithIdentifier:texture_identifier openGLTexture:open_gl_texture];
139+
}
140+
122141
#pragma mark -
123142

124143
@implementation FlutterEngine {
@@ -136,6 +155,9 @@ @implementation FlutterEngine {
136155

137156
// Whether the engine can continue running after the view controller is removed.
138157
BOOL _allowHeadlessExecution;
158+
159+
// A mapping of textureID to internal FlutterExternalTextureGL adapter.
160+
NSMutableDictionary<NSNumber*, FlutterExternalTextureGL*>* _textures;
139161
}
140162

141163
- (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)project {
@@ -150,6 +172,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix
150172

151173
_project = project ?: [[FlutterDartProject alloc] init];
152174
_messageHandlers = [[NSMutableDictionary alloc] init];
175+
_textures = [[NSMutableDictionary alloc] init];
153176
_allowHeadlessExecution = allowHeadlessExecution;
154177

155178
return self;
@@ -177,6 +200,7 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint {
177200
.open_gl.present = (BoolCallback)OnPresent,
178201
.open_gl.fbo_callback = (UIntCallback)OnFBO,
179202
.open_gl.make_resource_current = (BoolCallback)OnMakeResourceCurrent,
203+
.open_gl.gl_external_texture_frame_callback = (TextureFrameCallback)OnAcquireExternalTexture,
180204
};
181205

182206
// TODO(stuartmorgan): Move internal channel registration from FlutterViewController to here.
@@ -398,4 +422,29 @@ - (void)setMessageHandlerOnChannel:(nonnull NSString*)channel
398422
return [[FlutterEngineRegistrar alloc] initWithPlugin:pluginName flutterEngine:self];
399423
}
400424

425+
#pragma mark - FlutterTextureRegistrar
426+
427+
- (BOOL)populateTextureWithIdentifier:(int64_t)textureID
428+
openGLTexture:(FlutterOpenGLTexture*)openGLTexture {
429+
return [_textures[@(textureID)] populateTexture:openGLTexture];
430+
}
431+
432+
- (int64_t)registerTexture:(id<FlutterTexture>)texture {
433+
FlutterExternalTextureGL* FlutterTexture =
434+
[[FlutterExternalTextureGL alloc] initWithFlutterTexture:texture];
435+
int64_t textureID = [FlutterTexture textureID];
436+
FlutterEngineRegisterExternalTexture(_engine, textureID);
437+
_textures[@(textureID)] = FlutterTexture;
438+
return textureID;
439+
}
440+
441+
- (void)textureFrameAvailable:(int64_t)textureID {
442+
FlutterEngineMarkExternalTextureFrameAvailable(_engine, textureID);
443+
}
444+
445+
- (void)unregisterTexture:(int64_t)textureID {
446+
FlutterEngineUnregisterExternalTexture(_engine, textureID);
447+
[_textures removeObjectForKey:@(textureID)];
448+
}
449+
401450
@end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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 <Foundation/Foundation.h>
6+
7+
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"
8+
#import "flutter/shell/platform/embedder/embedder.h"
9+
10+
/**
11+
* Used to bridge FlutterTexture object and handle the texture copy request the
12+
* Flutter engine.
13+
*/
14+
@interface FlutterExternalTextureGL : NSObject
15+
16+
/**
17+
* Initializes a texture adapter with |texture| return a instance.
18+
*/
19+
- (nonnull instancetype)initWithFlutterTexture:(nonnull id<FlutterTexture>)texture;
20+
21+
/**
22+
* Accepts texture buffer copy request from the Flutter engine.
23+
* When the user side marks the textureID as available, the Flutter engine will
24+
* callback to this method and ask for populate the |openGLTexture| object,
25+
* such as the texture type and the format of the pixel buffer and the texture object.
26+
*/
27+
- (BOOL)populateTexture:(nonnull FlutterOpenGLTexture*)openGLTexture;
28+
29+
/**
30+
* Returns the ID for the FlutterTexture instance.
31+
*/
32+
- (int64_t)textureID;
33+
34+
@end
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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/FlutterExternalTextureGL.h"
6+
7+
#import <AppKit/AppKit.h>
8+
#import <CoreVideo/CoreVideo.h>
9+
#import <OpenGL/gl.h>
10+
11+
static void OnCVOpenGLTextureRelease(CVOpenGLTextureRef cvOpenGLTexture) {
12+
CVOpenGLTextureRelease(cvOpenGLTexture);
13+
}
14+
15+
@implementation FlutterExternalTextureGL {
16+
/**
17+
* OpenGL texture cache.
18+
*/
19+
CVOpenGLTextureCacheRef _openGLTextureCache;
20+
/**
21+
* User side texture object, used to copy pixel buffer.
22+
*/
23+
id<FlutterTexture> _texture;
24+
}
25+
26+
- (instancetype)initWithFlutterTexture:(id<FlutterTexture>)texture {
27+
self = [super init];
28+
if (self) {
29+
_texture = texture;
30+
}
31+
return self;
32+
}
33+
34+
- (int64_t)textureID {
35+
return reinterpret_cast<int64_t>(self);
36+
}
37+
38+
- (BOOL)populateTexture:(FlutterOpenGLTexture*)openGLTexture {
39+
// Copy the pixel buffer from the FlutterTexture instance implemented on the user side.
40+
CVPixelBufferRef pixelBuffer = [_texture copyPixelBuffer];
41+
42+
if (!pixelBuffer) {
43+
return NO;
44+
}
45+
46+
// Create the opengl texture cache if necessary.
47+
if (!_openGLTextureCache) {
48+
CGLContextObj context = [NSOpenGLContext currentContext].CGLContextObj;
49+
CGLPixelFormatObj format = CGLGetPixelFormat(context);
50+
if (CVOpenGLTextureCacheCreate(kCFAllocatorDefault, NULL, context, format, NULL,
51+
&_openGLTextureCache) != kCVReturnSuccess) {
52+
NSLog(@"Could not create texture cache.");
53+
CVPixelBufferRelease(pixelBuffer);
54+
return NO;
55+
}
56+
}
57+
58+
// Try to clear the cache of OpenGL textures to save memory.
59+
CVOpenGLTextureCacheFlush(_openGLTextureCache, 0);
60+
61+
CVOpenGLTextureRef cvOpenGLTexture = NULL;
62+
if (CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _openGLTextureCache,
63+
pixelBuffer, NULL,
64+
&cvOpenGLTexture) != kCVReturnSuccess) {
65+
CVPixelBufferRelease(pixelBuffer);
66+
return NO;
67+
}
68+
69+
openGLTexture->target = static_cast<uint32_t>(CVOpenGLTextureGetTarget(cvOpenGLTexture));
70+
openGLTexture->name = static_cast<uint32_t>(CVOpenGLTextureGetName(cvOpenGLTexture));
71+
openGLTexture->format = static_cast<uint32_t>(GL_RGBA8);
72+
openGLTexture->destruction_callback = (VoidCallback)OnCVOpenGLTextureRelease;
73+
openGLTexture->user_data = cvOpenGLTexture;
74+
openGLTexture->width = CVPixelBufferGetWidth(pixelBuffer);
75+
openGLTexture->height = CVPixelBufferGetHeight(pixelBuffer);
76+
77+
CVPixelBufferRelease(pixelBuffer);
78+
return YES;
79+
}
80+
81+
- (void)dealloc {
82+
CVOpenGLTextureCacheRelease(_openGLTextureCache);
83+
}
84+
85+
@end

shell/platform/embedder/embedder.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,8 +807,16 @@ FlutterEngineResult FlutterEngineRun(size_t version,
807807
GrGLTextureInfo gr_texture_info = {texture.target, texture.name,
808808
texture.format};
809809

810-
GrBackendTexture gr_backend_texture(size.width(), size.height(),
811-
GrMipMapped::kNo, gr_texture_info);
810+
size_t width = size.width();
811+
size_t height = size.height();
812+
813+
if (texture.width != 0 && texture.height != 0) {
814+
width = texture.width;
815+
height = texture.height;
816+
}
817+
818+
GrBackendTexture gr_backend_texture(width, height, GrMipMapped::kNo,
819+
gr_texture_info);
812820
SkImage::TextureReleaseProc release_proc = texture.destruction_callback;
813821
auto image = SkImage::MakeFromTexture(
814822
context, // context

shell/platform/embedder/embedder.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ typedef enum {
219219
} FlutterOpenGLTargetType;
220220

221221
typedef struct {
222-
/// Target texture of the active texture unit (example GL_TEXTURE_2D).
222+
/// Target texture of the active texture unit (example GL_TEXTURE_2D or
223+
/// GL_TEXTURE_RECTANGLE).
223224
uint32_t target;
224225
/// The name of the texture.
225226
uint32_t name;
@@ -230,6 +231,14 @@ typedef struct {
230231
/// Callback invoked (on an engine managed thread) that asks the embedder to
231232
/// collect the texture.
232233
VoidCallback destruction_callback;
234+
/// Optional parameters for texture height/width, default is 0, non-zero means
235+
/// the texture has the specified width/height. Usually, when the texture type
236+
/// is GL_TEXTURE_RECTANGLE, we need to specify the texture width/height to
237+
/// tell the embedder to scale when rendering.
238+
/// Width of the texture.
239+
size_t width;
240+
/// Height of the texture.
241+
size_t height;
233242
} FlutterOpenGLTexture;
234243

235244
typedef struct {

0 commit comments

Comments
 (0)