Skip to content

Commit

Permalink
Fix code style issues in MacOS embedder (flutter#22270)
Browse files Browse the repository at this point in the history
  • Loading branch information
knopp authored and chaselatta committed Nov 30, 2020
1 parent 2429a68 commit e57ab05
Show file tree
Hide file tree
Showing 13 changed files with 262 additions and 194 deletions.
4 changes: 2 additions & 2 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1068,8 +1068,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/MacOSSwitchableGLContext.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/MacOSSwitchableGLContext.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/MacOSGLContextSwitch.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/MacOSGLContextSwitch.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/fixtures/flutter_desktop_test.dart
FILE: ../../../flutter/shell/platform/darwin/macos/framework/module.modulemap
FILE: ../../../flutter/shell/platform/embedder/assets/EmbedderInfo.plist
Expand Down
6 changes: 2 additions & 4 deletions shell/platform/darwin/macos/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,13 @@ source_set("flutter_framework_source") {
"framework/Source/FlutterView.mm",
"framework/Source/FlutterViewController.mm",
"framework/Source/FlutterViewController_Internal.h",
"framework/Source/MacOSSwitchableGLContext.h",
"framework/Source/MacOSSwitchableGLContext.mm",
"framework/Source/MacOSGLContextSwitch.h",
"framework/Source/MacOSGLContextSwitch.mm",
]

sources += _flutter_framework_headers

deps = [
"//flutter/flow:flow",
"//flutter/fml:fml",
"//flutter/shell/platform/common/cpp:common_cpp_switches",
"//flutter/shell/platform/darwin/common:framework_shared",
"//flutter/shell/platform/embedder:embedder_as_internal_library",
Expand Down
13 changes: 11 additions & 2 deletions shell/platform/darwin/macos/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ - (bool)engineCallbackOnClearCurrent;
*/
- (bool)engineCallbackOnPresent;

/**
* Called by the engine when framebuffer object ID is requested.
*/
- (uint32_t)engineCallbackOnFBO:(const FlutterFrameInfo*)info;

/**
* Makes the resource context the current context.
*/
Expand Down Expand Up @@ -146,8 +151,7 @@ static bool OnPresent(FlutterEngine* engine) {
}

static uint32_t OnFBO(FlutterEngine* engine, const FlutterFrameInfo* info) {
CGSize size = CGSizeMake(info->size.width, info->size.height);
return [engine.viewController.flutterView getFrameBufferIdForSize:size];
return [engine engineCallbackOnFBO:info];
}

static bool OnMakeResourceCurrent(FlutterEngine* engine) {
Expand Down Expand Up @@ -469,6 +473,11 @@ - (bool)engineCallbackOnMakeCurrent {
return true;
}

- (uint32_t)engineCallbackOnFBO:(const FlutterFrameInfo*)info {
CGSize size = CGSizeMake(info->size.width, info->size.height);
return [_viewController.flutterView frameBufferIDForSize:size];
}

- (bool)engineCallbackOnClearCurrent {
[NSOpenGLContext clearCurrentContext];
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,59 +1,78 @@
// 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 <Cocoa/Cocoa.h>

@class FlutterResizeSynchronizer;

/**
* Implemented by FlutterView.
*/
@protocol FlutterResizeSynchronizerDelegate

// Invoked on raster thread; Delegate should flush the OpenGL context
- (void)resizeSynchronizerFlush:(FlutterResizeSynchronizer*)synchronizer;
/**
* Invoked on raster thread; Delegate should flush the OpenGL context.
*/
- (void)resizeSynchronizerFlush:(nonnull FlutterResizeSynchronizer*)synchronizer;

// Invoked on platform thread; Delegate should flip the surfaces
- (void)resizeSynchronizerCommit:(FlutterResizeSynchronizer*)synchronizer;
/**
* Invoked on platform thread; Delegate should flip the surfaces.
*/
- (void)resizeSynchronizerCommit:(nonnull FlutterResizeSynchronizer*)synchronizer;

@end

// Encapsulates the logic for blocking platform thread during window resize as
// well as synchronizing the raster and platform thread during commit (presenting frame)
//
// Flow during window resize
//
// 1. Platform thread calls [synchronizer beginResize:notify:]
// This will hold the platform thread until we're ready to display contents.
// 2. Raster thread calls [synchronizer shouldEnsureSurfaceForSize:] with target size
// This will return false for any size other than target size
// 3. Raster thread calls [synchronizer requestCommit]
// Any commit calls before shouldEnsureSurfaceForSize: is called with the right
// size are simply ignored; There's no point rasterizing and displaying frames
// with wrong size.
// Both delegate methods (flush/commit) will be invoked before beginResize returns
//
// Flow during regular operation (no resizing)
//
// 1. Raster thread calls [synchronizer requestCommit]
// This will invoke [delegate flush:] on raster thread and
// [delegate commit:] on platform thread. The requestCommit call will be blocked
// until this is done. This is necessary to ensure that rasterizer won't start
// rasterizing next frame before we flipped the surface, which must be performed
// on platform thread
/**
* Encapsulates the logic for blocking platform thread during window resize as
* well as synchronizing the raster and platform thread during commit (presenting frame).
*
* Flow during window resize
*
* 1. Platform thread calls [synchronizer beginResize:notify:]
* This will hold the platform thread until we're ready to display contents.
* 2. Raster thread calls [synchronizer shouldEnsureSurfaceForSize:] with target size
* This will return false for any size other than target size
* 3. Raster thread calls [synchronizer requestCommit]
* Any commit calls before shouldEnsureSurfaceForSize: is called with the right
* size are simply ignored; There's no point rasterizing and displaying frames
* with wrong size.
* Both delegate methods (flush/commit) will be invoked before beginResize returns
*
* Flow during regular operation (no resizing)
*
* 1. Raster thread calls [synchronizer requestCommit]
* This will invoke [delegate flush:] on raster thread and
* [delegate commit:] on platform thread. The requestCommit call will be blocked
* until this is done. This is necessary to ensure that rasterizer won't start
* rasterizing next frame before we flipped the surface, which must be performed
* on platform thread
*/
@interface FlutterResizeSynchronizer : NSObject

- (instancetype)initWithDelegate:(id<FlutterResizeSynchronizerDelegate>)delegate;
- (nullable instancetype)initWithDelegate:(nonnull id<FlutterResizeSynchronizerDelegate>)delegate;

// Blocks the platform thread until
// - shouldEnsureSurfaceForSize is called with proper size and
// - requestCommit is called
// All requestCommit calls before `shouldEnsureSurfaceForSize` is called with
// expected size are ignored;
// The notify block is invoked immediately after synchronizer mutex is acquired
- (void)beginResize:(CGSize)size notify:(dispatch_block_t)notify;
/**
* Blocks the platform thread until
* - shouldEnsureSurfaceForSize is called with proper size and
* - requestCommit is called
* All requestCommit calls before `shouldEnsureSurfaceForSize` is called with
* expected size are ignored;
* The notify block is invoked immediately after synchronizer mutex is acquired.
*/
- (void)beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify;

// Returns whether the view should ensure surfaces with given size;
// This will be false during resizing for any size other than size specified
// during beginResize
- (bool)shouldEnsureSurfaceForSize:(CGSize)size;
/**
* Returns whether the view should ensure surfaces with given size;
* This will be false during resizing for any size other than size specified
* during beginResize.
*/
- (BOOL)shouldEnsureSurfaceForSize:(CGSize)size;

// Called from rasterizer thread, will block until delegate resizeSynchronizerCommit:
// method is called (on platform thread)
/**
* Called from rasterizer thread, will block until delegate resizeSynchronizerCommit:
* method is called (on platform thread).
*/
- (void)requestCommit;

@end
Original file line number Diff line number Diff line change
@@ -1,103 +1,117 @@
// 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/FlutterResizeSynchronizer.h"

#import <mutex>
#include <mutex>

@interface FlutterResizeSynchronizer () {
uint32_t cookie; // counter to detect stale callbacks
// Counter to detect stale callbacks.
uint32_t _cookie;

std::mutex _mutex;

// Used to block [beginResize:].
std::condition_variable _condBlockBeginResize;
// Used to block [requestCommit].
std::condition_variable _condBlockRequestCommit;

// If NO, requestCommit calls are ignored until shouldEnsureSurfaceForSize is called with
// proper size.
BOOL _acceptingCommit;

// Waiting for resize to finish.
BOOL _waiting;

std::mutex mutex;
std::condition_variable condBlockBeginResize; // used to block [beginResize:]
std::condition_variable condBlockRequestCommit; // used to block [requestCommit]
// RequestCommit was called and [delegate commit:] must be performed on platform thread.
BOOL _pendingCommit;

bool acceptingCommit; // if false, requestCommit calls are ignored until
// shouldEnsureSurfaceForSize is called with proper size
bool waiting; // waiting for resize to finish
bool pendingCommit; // requestCommit was called and [delegate commit:] must be performed on
// platform thread
CGSize newSize; // target size for resizing
// Target size for resizing.
CGSize _newSize;

__weak id<FlutterResizeSynchronizerDelegate> delegate;
__weak id<FlutterResizeSynchronizerDelegate> _delegate;
}
@end

@implementation FlutterResizeSynchronizer

- (instancetype)initWithDelegate:(id<FlutterResizeSynchronizerDelegate>)delegate_ {
- (instancetype)initWithDelegate:(id<FlutterResizeSynchronizerDelegate>)delegate {
if (self = [super init]) {
acceptingCommit = true;
delegate = delegate_;
_acceptingCommit = YES;
_delegate = delegate;
}
return self;
}

- (void)beginResize:(CGSize)size notify:(dispatch_block_t)notify {
std::unique_lock<std::mutex> lock(mutex);
if (!delegate) {
std::unique_lock<std::mutex> lock(_mutex);
if (!_delegate) {
return;
}

++cookie;
++_cookie;

// from now on, ignore all incoming commits until the block below gets
// scheduled on raster thread
acceptingCommit = false;
_acceptingCommit = NO;

// let pending commits finish to unblock the raster thread
pendingCommit = false;
condBlockBeginResize.notify_all();
_pendingCommit = NO;
_condBlockBeginResize.notify_all();

// let the engine send resize notification
notify();

newSize = size;
_newSize = size;

waiting = true;
_waiting = YES;

condBlockRequestCommit.wait(lock, [&] { return pendingCommit; });
_condBlockRequestCommit.wait(lock, [&] { return _pendingCommit; });

[delegate resizeSynchronizerFlush:self];
[delegate resizeSynchronizerCommit:self];
pendingCommit = false;
condBlockBeginResize.notify_all();
[_delegate resizeSynchronizerFlush:self];
[_delegate resizeSynchronizerCommit:self];
_pendingCommit = NO;
_condBlockBeginResize.notify_all();

waiting = false;
_waiting = NO;
}

- (bool)shouldEnsureSurfaceForSize:(CGSize)size {
std::unique_lock<std::mutex> lock(mutex);
if (!acceptingCommit) {
if (CGSizeEqualToSize(newSize, size)) {
acceptingCommit = true;
- (BOOL)shouldEnsureSurfaceForSize:(CGSize)size {
std::unique_lock<std::mutex> lock(_mutex);
if (!_acceptingCommit) {
if (CGSizeEqualToSize(_newSize, size)) {
_acceptingCommit = YES;
}
}
return acceptingCommit;
return _acceptingCommit;
}

- (void)requestCommit {
std::unique_lock<std::mutex> lock(mutex);
if (!acceptingCommit) {
std::unique_lock<std::mutex> lock(_mutex);
if (!_acceptingCommit) {
return;
}

pendingCommit = true;
if (waiting) { // BeginResize is in progress, interrupt it and schedule commit call
condBlockRequestCommit.notify_all();
condBlockBeginResize.wait(lock, [&]() { return !pendingCommit; });
_pendingCommit = YES;
if (_waiting) { // BeginResize is in progress, interrupt it and schedule commit call
_condBlockRequestCommit.notify_all();
_condBlockBeginResize.wait(lock, [&]() { return !_pendingCommit; });
} else {
// No resize, schedule commit on platform thread and wait until either done
// or interrupted by incoming BeginResize
[delegate resizeSynchronizerFlush:self];
dispatch_async(dispatch_get_main_queue(), [self, cookie_ = cookie] {
std::unique_lock<std::mutex> lock(mutex);
if (cookie_ == cookie) {
if (delegate) {
[delegate resizeSynchronizerCommit:self];
[_delegate resizeSynchronizerFlush:self];
dispatch_async(dispatch_get_main_queue(), [self, cookie = _cookie] {
std::unique_lock<std::mutex> lock(_mutex);
if (cookie == _cookie) {
if (_delegate) {
[_delegate resizeSynchronizerCommit:self];
}
pendingCommit = false;
condBlockBeginResize.notify_all();
_pendingCommit = NO;
_condBlockBeginResize.notify_all();
}
});
condBlockBeginResize.wait(lock, [&]() { return !pendingCommit; });
_condBlockBeginResize.wait(lock, [&]() { return !_pendingCommit; });
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// 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 <Cocoa/Cocoa.h>

// Manages the IOSurfaces for FlutterView
@interface FlutterSurfaceManager : NSObject

- (instancetype)initWithLayer:(CALayer*)layer openGLContext:(NSOpenGLContext*)opengLContext;
- (nullable instancetype)initWithLayer:(nonnull CALayer*)containingLayer
openGLContext:(nonnull NSOpenGLContext*)opengLContext;

- (void)ensureSurfaceSize:(CGSize)size;
- (void)swapBuffers;
Expand Down
Loading

0 comments on commit e57ab05

Please sign in to comment.