Skip to content

Commit

Permalink
Add texture support for macOS shell. (#8507)
Browse files Browse the repository at this point in the history
  • Loading branch information
cloudwebrtc authored and chinmaygarde committed Oct 10, 2019
1 parent 179fab9 commit 0f9d88c
Show file tree
Hide file tree
Showing 16 changed files with 215 additions and 10 deletions.
4 changes: 3 additions & 1 deletion ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterBin
FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h
FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h
FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h
FILE: ../../../flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h
FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterChannels.mm
FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterChannelsTest.m
FILE: ../../../flutter/shell/platform/darwin/common/framework/Source/FlutterCodecs.mm
Expand All @@ -740,7 +741,6 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterHeadle
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlatformViews.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPlugin.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterPluginAppLifeCycleDelegate.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Info.plist
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterAppDelegate.mm
Expand Down Expand Up @@ -818,6 +818,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterDartP
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputModel.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputModel.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h
Expand Down
1 change: 1 addition & 0 deletions shell/platform/darwin/common/framework_shared.gni
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ framework_shared_headers =
"framework/Headers/FlutterBinaryMessenger.h",
"framework/Headers/FlutterChannels.h",
"framework/Headers/FlutterCodecs.h",
"framework/Headers/FlutterTexture.h",
],
"abspath")
1 change: 0 additions & 1 deletion shell/platform/darwin/ios/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ _flutter_framework_headers = [
"framework/Headers/FlutterPlatformViews.h",
"framework/Headers/FlutterPlugin.h",
"framework/Headers/FlutterPluginAppLifeCycleDelegate.h",
"framework/Headers/FlutterTexture.h",
"framework/Headers/FlutterViewController.h",
]

Expand Down
2 changes: 1 addition & 1 deletion shell/platform/darwin/ios/ios_external_texture_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "flutter/flow/texture.h"
#include "flutter/fml/platform/darwin/cf_utils.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h"
#include "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"

namespace flutter {

Expand Down
2 changes: 1 addition & 1 deletion shell/platform/darwin/ios/platform_view_ios.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterTexture.h"
#include "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"
#include "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterView.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/accessibility_bridge.h"
Expand Down
7 changes: 6 additions & 1 deletion shell/platform/darwin/macos/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ shared_library("create_flutter_framework_dylib") {
"framework/Source/FlutterDartProject_Internal.h",
"framework/Source/FlutterEngine.mm",
"framework/Source/FlutterEngine_Internal.h",
"framework/Source/FlutterExternalTextureGL.h",
"framework/Source/FlutterExternalTextureGL.mm",
"framework/Source/FlutterTextInputModel.h",
"framework/Source/FlutterTextInputModel.mm",
"framework/Source/FlutterTextInputPlugin.h",
Expand All @@ -75,7 +77,10 @@ shared_library("create_flutter_framework_dylib") {

cflags_objcc = [ "-fobjc-arc" ]

libs = [ "Cocoa.framework" ]
libs = [
"Cocoa.framework",
"CoreVideo.framework",
]
}

action("copy_dylib_and_update_framework_install_name") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "FlutterDartProject.h"
#include "FlutterMacros.h"
#include "FlutterPluginRegistrarMacOS.h"
#include "FlutterTexture.h"

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

Expand All @@ -20,7 +21,7 @@
* Coordinates a single instance of execution of a Flutter engine.
*/
FLUTTER_EXPORT
@interface FlutterEngine : NSObject <FlutterPluginRegistry>
@interface FlutterEngine : NSObject <FlutterTextureRegistry, FlutterPluginRegistry>

/**
* Initializes an engine with the given viewController.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
#import "FlutterMacros.h"
#import "FlutterPluginMacOS.h"
#import "FlutterPluginRegistrarMacOS.h"
#import "FlutterTexture.h"
#import "FlutterViewController.h"
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import "FlutterBinaryMessenger.h"
#import "FlutterChannels.h"
#import "FlutterMacros.h"
#import "FlutterTexture.h"

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

/**
* Returns a `FlutterTextureRegistry` for registering textures
* provided by the plugin.
*/
@property(nonnull, readonly) id<FlutterTextureRegistry> textures;

/**
* The view displaying Flutter content. May return |nil|, for instance in a headless environment.
*
Expand Down
49 changes: 49 additions & 0 deletions shell/platform/darwin/macos/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <vector>

#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
#import "flutter/shell/platform/embedder/embedder.h"

Expand Down Expand Up @@ -46,6 +47,12 @@ - (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message;
*/
- (void)shutDownEngine;

/**
* Forwards texture copy request to the corresponding texture via |textureID|.
*/
- (BOOL)populateTextureWithIdentifier:(int64_t)textureID
openGLTexture:(FlutterOpenGLTexture*)openGLTexture;

@end

#pragma mark -
Expand Down Expand Up @@ -78,6 +85,10 @@ - (instancetype)initWithPlugin:(NSString*)pluginKey flutterEngine:(FlutterEngine
return _flutterEngine.binaryMessenger;
}

- (id<FlutterTextureRegistry>)textures {
return _flutterEngine;
}

- (NSView*)view {
return _flutterEngine.viewController.view;
}
Expand Down Expand Up @@ -119,6 +130,14 @@ static void OnPlatformMessage(const FlutterPlatformMessage* message, FlutterEngi
[engine engineCallbackOnPlatformMessage:message];
}

static bool OnAcquireExternalTexture(FlutterEngine* engine,
int64_t texture_identifier,
size_t width,
size_t height,
FlutterOpenGLTexture* open_gl_texture) {
return [engine populateTextureWithIdentifier:texture_identifier openGLTexture:open_gl_texture];
}

#pragma mark -

@implementation FlutterEngine {
Expand All @@ -136,6 +155,9 @@ @implementation FlutterEngine {

// Whether the engine can continue running after the view controller is removed.
BOOL _allowHeadlessExecution;

// A mapping of textureID to internal FlutterExternalTextureGL adapter.
NSMutableDictionary<NSNumber*, FlutterExternalTextureGL*>* _textures;
}

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

_project = project ?: [[FlutterDartProject alloc] init];
_messageHandlers = [[NSMutableDictionary alloc] init];
_textures = [[NSMutableDictionary alloc] init];
_allowHeadlessExecution = allowHeadlessExecution;

return self;
Expand Down Expand Up @@ -177,6 +200,7 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint {
.open_gl.present = (BoolCallback)OnPresent,
.open_gl.fbo_callback = (UIntCallback)OnFBO,
.open_gl.make_resource_current = (BoolCallback)OnMakeResourceCurrent,
.open_gl.gl_external_texture_frame_callback = (TextureFrameCallback)OnAcquireExternalTexture,
};

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

#pragma mark - FlutterTextureRegistrar

- (BOOL)populateTextureWithIdentifier:(int64_t)textureID
openGLTexture:(FlutterOpenGLTexture*)openGLTexture {
return [_textures[@(textureID)] populateTexture:openGLTexture];
}

- (int64_t)registerTexture:(id<FlutterTexture>)texture {
FlutterExternalTextureGL* FlutterTexture =
[[FlutterExternalTextureGL alloc] initWithFlutterTexture:texture];
int64_t textureID = [FlutterTexture textureID];
FlutterEngineRegisterExternalTexture(_engine, textureID);
_textures[@(textureID)] = FlutterTexture;
return textureID;
}

- (void)textureFrameAvailable:(int64_t)textureID {
FlutterEngineMarkExternalTextureFrameAvailable(_engine, textureID);
}

- (void)unregisterTexture:(int64_t)textureID {
FlutterEngineUnregisterExternalTexture(_engine, textureID);
[_textures removeObjectForKey:@(textureID)];
}

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <Foundation/Foundation.h>

#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterTexture.h"
#import "flutter/shell/platform/embedder/embedder.h"

/**
* Used to bridge FlutterTexture object and handle the texture copy request the
* Flutter engine.
*/
@interface FlutterExternalTextureGL : NSObject

/**
* Initializes a texture adapter with |texture| return a instance.
*/
- (nonnull instancetype)initWithFlutterTexture:(nonnull id<FlutterTexture>)texture;

/**
* Accepts texture buffer copy request from the Flutter engine.
* When the user side marks the textureID as available, the Flutter engine will
* callback to this method and ask for populate the |openGLTexture| object,
* such as the texture type and the format of the pixel buffer and the texture object.
*/
- (BOOL)populateTexture:(nonnull FlutterOpenGLTexture*)openGLTexture;

/**
* Returns the ID for the FlutterTexture instance.
*/
- (int64_t)textureID;

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h"

#import <AppKit/AppKit.h>
#import <CoreVideo/CoreVideo.h>
#import <OpenGL/gl.h>

static void OnCVOpenGLTextureRelease(CVOpenGLTextureRef cvOpenGLTexture) {
CVOpenGLTextureRelease(cvOpenGLTexture);
}

@implementation FlutterExternalTextureGL {
/**
* OpenGL texture cache.
*/
CVOpenGLTextureCacheRef _openGLTextureCache;
/**
* User side texture object, used to copy pixel buffer.
*/
id<FlutterTexture> _texture;
}

- (instancetype)initWithFlutterTexture:(id<FlutterTexture>)texture {
self = [super init];
if (self) {
_texture = texture;
}
return self;
}

- (int64_t)textureID {
return reinterpret_cast<int64_t>(self);
}

- (BOOL)populateTexture:(FlutterOpenGLTexture*)openGLTexture {
// Copy the pixel buffer from the FlutterTexture instance implemented on the user side.
CVPixelBufferRef pixelBuffer = [_texture copyPixelBuffer];

if (!pixelBuffer) {
return NO;
}

// Create the opengl texture cache if necessary.
if (!_openGLTextureCache) {
CGLContextObj context = [NSOpenGLContext currentContext].CGLContextObj;
CGLPixelFormatObj format = CGLGetPixelFormat(context);
if (CVOpenGLTextureCacheCreate(kCFAllocatorDefault, NULL, context, format, NULL,
&_openGLTextureCache) != kCVReturnSuccess) {
NSLog(@"Could not create texture cache.");
CVPixelBufferRelease(pixelBuffer);
return NO;
}
}

// Try to clear the cache of OpenGL textures to save memory.
CVOpenGLTextureCacheFlush(_openGLTextureCache, 0);

CVOpenGLTextureRef cvOpenGLTexture = NULL;
if (CVOpenGLTextureCacheCreateTextureFromImage(kCFAllocatorDefault, _openGLTextureCache,
pixelBuffer, NULL,
&cvOpenGLTexture) != kCVReturnSuccess) {
CVPixelBufferRelease(pixelBuffer);
return NO;
}

openGLTexture->target = static_cast<uint32_t>(CVOpenGLTextureGetTarget(cvOpenGLTexture));
openGLTexture->name = static_cast<uint32_t>(CVOpenGLTextureGetName(cvOpenGLTexture));
openGLTexture->format = static_cast<uint32_t>(GL_RGBA8);
openGLTexture->destruction_callback = (VoidCallback)OnCVOpenGLTextureRelease;
openGLTexture->user_data = cvOpenGLTexture;
openGLTexture->width = CVPixelBufferGetWidth(pixelBuffer);
openGLTexture->height = CVPixelBufferGetHeight(pixelBuffer);

CVPixelBufferRelease(pixelBuffer);
return YES;
}

- (void)dealloc {
CVOpenGLTextureCacheRelease(_openGLTextureCache);
}

@end
12 changes: 10 additions & 2 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -807,8 +807,16 @@ FlutterEngineResult FlutterEngineRun(size_t version,
GrGLTextureInfo gr_texture_info = {texture.target, texture.name,
texture.format};

GrBackendTexture gr_backend_texture(size.width(), size.height(),
GrMipMapped::kNo, gr_texture_info);
size_t width = size.width();
size_t height = size.height();

if (texture.width != 0 && texture.height != 0) {
width = texture.width;
height = texture.height;
}

GrBackendTexture gr_backend_texture(width, height, GrMipMapped::kNo,
gr_texture_info);
SkImage::TextureReleaseProc release_proc = texture.destruction_callback;
auto image = SkImage::MakeFromTexture(
context, // context
Expand Down
11 changes: 10 additions & 1 deletion shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ typedef enum {
} FlutterOpenGLTargetType;

typedef struct {
/// Target texture of the active texture unit (example GL_TEXTURE_2D).
/// Target texture of the active texture unit (example GL_TEXTURE_2D or
/// GL_TEXTURE_RECTANGLE).
uint32_t target;
/// The name of the texture.
uint32_t name;
Expand All @@ -230,6 +231,14 @@ typedef struct {
/// Callback invoked (on an engine managed thread) that asks the embedder to
/// collect the texture.
VoidCallback destruction_callback;
/// Optional parameters for texture height/width, default is 0, non-zero means
/// the texture has the specified width/height. Usually, when the texture type
/// is GL_TEXTURE_RECTANGLE, we need to specify the texture width/height to
/// tell the embedder to scale when rendering.
/// Width of the texture.
size_t width;
/// Height of the texture.
size_t height;
} FlutterOpenGLTexture;

typedef struct {
Expand Down

0 comments on commit 0f9d88c

Please sign in to comment.