Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add texture support for macOS shell. #8507

Merged
merged 40 commits into from
Oct 10, 2019
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5302cf8
Merge pull request #1 from flutter/master
cloudwebrtc Mar 28, 2019
2953e13
Merge remote-tracking branch 'upstream/master'
cloudwebrtc Apr 9, 2019
4b422b3
Add texture support for macOS shell.
cloudwebrtc Apr 9, 2019
fa3f8b0
code format.
cloudwebrtc Apr 9, 2019
a222a4a
Add missing file.
cloudwebrtc Apr 9, 2019
668e656
Update FLETexture.h
cloudwebrtc Apr 9, 2019
97f1e91
Update FLEPluginRegistrar.h
cloudwebrtc Apr 10, 2019
cd636b4
Restore header file order.
cloudwebrtc Apr 10, 2019
799e9c1
Update code styles and comments.
cloudwebrtc Apr 10, 2019
52b1417
Rename textureId to textureID.
cloudwebrtc Apr 10, 2019
e49c549
Update comment for FLEExternalTextureGL.h.
cloudwebrtc Apr 10, 2019
7589f46
Update comments and partial code.
cloudwebrtc Apr 17, 2019
2c60631
Rename the texture in some methods to disambiguate.
cloudwebrtc Apr 17, 2019
42b7502
Merge remote-tracking branch 'upstream/master'
cloudwebrtc Apr 18, 2019
dbcdf16
Merge branch 'master' into macos_texture
cloudwebrtc Apr 18, 2019
9b15427
Fix errors caused by merge master conflicts.
cloudwebrtc Apr 18, 2019
e4ff652
Merge remote-tracking branch 'upstream/master' into macos_texture
cloudwebrtc May 19, 2019
ba2efa3
Merge remote-tracking branch 'upstream/master' into macos_texture
cloudwebrtc Jul 11, 2019
9c19bac
clang format.
cloudwebrtc Jul 16, 2019
6ff0a76
gn format.
cloudwebrtc Jul 16, 2019
ec8083a
Add files to licenses_flutter.
cloudwebrtc Jul 16, 2019
ff49e14
Merge remote-tracking branch 'upstream/master' into macos_texture
cloudwebrtc Sep 24, 2019
ee09e69
clang-format.
cloudwebrtc Sep 24, 2019
0f06004
Update.
cloudwebrtc Sep 24, 2019
09156bf
Use shared FlutterTexture.h.
cloudwebrtc Sep 25, 2019
235314a
clang-format.
cloudwebrtc Sep 25, 2019
650c00a
Fixed FlutterTexture.h import path for ios.
cloudwebrtc Sep 25, 2019
d4c0be8
Update.
cloudwebrtc Sep 26, 2019
cda947c
clang-format.
cloudwebrtc Sep 26, 2019
e78d2e1
Change _pixelBuffer to a local variable.
cloudwebrtc Sep 27, 2019
eb3bf39
Add missing static on a local constant
stuartmorgan Sep 27, 2019
d622f01
Fix variable naming inconsistency
stuartmorgan Sep 27, 2019
ec70d4a
Merge branch 'master' into macos_texture
cloudwebrtc Oct 5, 2019
2871956
Use drawImageRect to draw textures of undesired size.
cloudwebrtc Oct 5, 2019
9b63c65
Merge branch 'macos_texture' of https://github.com/cloudwebrtc/flutte…
cloudwebrtc Oct 5, 2019
4962f91
clang-format.
cloudwebrtc Oct 5, 2019
b20be2c
Fixed CI errors.
cloudwebrtc Oct 5, 2019
067e8a1
update.
cloudwebrtc Oct 7, 2019
27c6f94
clang-format.
cloudwebrtc Oct 7, 2019
5f6833f
Merge remote-tracking branch 'upstream/master' into macos_texture
cloudwebrtc Oct 10, 2019
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
4 changes: 3 additions & 1 deletion ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,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 @@ -735,7 +736,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 @@ -813,6 +813,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
58 changes: 58 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,14 @@ - (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message;
*/
- (void)shutDownEngine;

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

@end

#pragma mark -
Expand Down Expand Up @@ -78,6 +87,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 +132,17 @@ 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
width:width
height:height
openGLTexture:open_gl_texture];
}

#pragma mark -

@implementation FlutterEngine {
Expand All @@ -136,6 +160,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 +177,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 +205,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 +427,33 @@ - (void)setMessageHandlerOnChannel:(nonnull NSString*)channel
return [[FlutterEngineRegistrar alloc] initWithPlugin:pluginName flutterEngine:self];
}

#pragma mark - FlutterTextureRegistrar

- (BOOL)populateTextureWithIdentifier:(int64_t)textureID
width:(size_t)width
height:(size_t)height
openGLTexture:(FlutterOpenGLTexture*)openGLTexture {
return [_textures[@(textureID)] populateTextureWithWidth:width
height:height
openGLTexture: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,36 @@
// 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)populateTextureWithWidth:(size_t)width
height:(size_t)height
openGLTexture:(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,87 @@
// 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)populateTextureWithWidth:(size_t)width
Copy link
Member

Choose a reason for hiding this comment

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

You are not using the width and the height argument in this method at all!

The way this API works it that the engine tells the embedder what size it needs the texture to be. If the texture is not of that exact size, the engine will attempt to clamp or resize the texture to get something usable. The clamping behavior is what you seem to be running into.

There is information being thrown away in this method. That is, when you ask the texture to copyPixelBuffer, you are not giving it any indication about what the size of the pixel buffer should be. This method acts as if size does not matter. When, in fact, the engine care about the size and it is asking you for a texture of that size. This method is just not using it.

So now you have a texture of some unspecified size that you need to give to the engine because you didn't use the dimensions the engine asked of the embedder. To solve this issue, we now need to resort to the expensive device to host transfer so we can resize on the CPU before transferring that information back to the device.

If we don't throw away the information the engine gives us, we can be a whole lot faster. This can be done in one of the following ways:

  • Augment copyPixelBuffer to take the width and the height. This way, plugins will know what texture the engine expects and can create texture of the right size to begin with.
  • If it is unreasonable for plugins to expect to create textures of the correct size, we can still make the FlutterOpenGLTexture take a width and height parameter (subject to ABI restrictions I mentioned below). That way, we give the plugins the best chance to match texture sizes. If however, the size the engine expects is not the same as the size the plugin gives back to us, instead of implementing the resize via a software render pass, we can achieve the same by applying a transformation to the draw on the GPU. This can be modified by pushing a CTM on the canvas here.

Whatever you choose, let do as many operations on the GPU as possible by utilizing all information the engine give to the embedder.

height:(size_t)height
openGLTexture:(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
14 changes: 12 additions & 2 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,8 @@ FlutterEngineResult FlutterEngineRun(size_t version,
int64_t texture_identifier, GrContext* context,
const SkISize& size) -> sk_sp<SkImage> {
FlutterOpenGLTexture texture = {};
texture.width = 0;
cloudwebrtc marked this conversation as resolved.
Show resolved Hide resolved
texture.height = 0;

if (!ptr(user_data, texture_identifier, size.width(), size.height(),
&texture)) {
Expand All @@ -807,8 +809,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
Loading