未验证 提交 acc24667 编写于 作者: M Matej Knopp 提交者: GitHub

Fix code style issues in MacOS embedder (#22270)

上级 122f2425
......@@ -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
......
......@@ -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",
......
......@@ -52,6 +52,11 @@ static FlutterLocale FlutterLocaleFromNSLocale(NSLocale* locale) {
*/
- (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.
*/
......@@ -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) {
......@@ -469,6 +473,11 @@ static bool OnAcquireExternalTexture(FlutterEngine* engine,
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;
......
// 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
// 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; });
}
}
......
// 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;
......
// 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/FlutterSurfaceManager.h"
#import "flutter/fml/logging.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/MacOSSwitchableGLContext.h"
#include <OpenGL/gl.h>
#import "flutter/shell/platform/darwin/macos/framework/Source/MacOSGLContextSwitch.h"
enum {
kFront = 0,
kBack = 1,
kBufferCount,
kFlutterSurfaceManagerFrontBuffer = 0,
kFlutterSurfaceManagerBackBuffer = 1,
kFlutterSurfaceManagerBufferCount,
};
@interface FlutterSurfaceManager () {
CGSize surfaceSize;
CALayer* layer; // provided (parent layer)
CALayer* contentLayer;
NSOpenGLContext* openGLContext;
uint32_t _frameBufferId[kBufferCount];
uint32_t _backingTexture[kBufferCount];
IOSurfaceRef _ioSurface[kBufferCount];
CGSize _surfaceSize;
CALayer* _containingLayer; // provided (parent layer)
CALayer* _contentLayer;
NSOpenGLContext* _openGLContext;
uint32_t _frameBufferId[kFlutterSurfaceManagerBufferCount];
uint32_t _backingTexture[kFlutterSurfaceManagerBufferCount];
IOSurfaceRef _ioSurface[kFlutterSurfaceManagerBufferCount];
}
@end
@implementation FlutterSurfaceManager
- (instancetype)initWithLayer:(CALayer*)layer_ openGLContext:(NSOpenGLContext*)opengLContext_ {
- (instancetype)initWithLayer:(CALayer*)containingLayer
openGLContext:(NSOpenGLContext*)openGLContext {
if (self = [super init]) {
layer = layer_;
openGLContext = opengLContext_;
_containingLayer = containingLayer;
_openGLContext = openGLContext;
// Layer for content. This is separate from provided layer, because it needs to be flipped
// vertically if we render to OpenGL texture
contentLayer = [[CALayer alloc] init];
[layer_ addSublayer:contentLayer];
_contentLayer = [[CALayer alloc] init];
[_containingLayer addSublayer:_contentLayer];
flutter::GLContextSwitch context_switch(
std::make_unique<MacOSSwitchableGLContext>(opengLContext_));
MacOSGLContextSwitch context_switch(openGLContext);
glGenFramebuffers(2, _frameBufferId);
glGenTextures(2, _backingTexture);
......@@ -57,15 +61,14 @@ enum {
}
- (void)ensureSurfaceSize:(CGSize)size {
if (CGSizeEqualToSize(size, surfaceSize)) {
if (CGSizeEqualToSize(size, _surfaceSize)) {
return;
}
surfaceSize = size;
_surfaceSize = size;
flutter::GLContextSwitch context_switch(
std::make_unique<MacOSSwitchableGLContext>(openGLContext));
MacOSGLContextSwitch context_switch(_openGLContext);
for (int i = 0; i < kBufferCount; ++i) {
for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) {
if (_ioSurface[i]) {
CFRelease(_ioSurface[i]);
}
......@@ -96,29 +99,33 @@ enum {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB,
_backingTexture[i], 0);
FML_DCHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
NSAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
@"Framebuffer status check failed");
}
}
- (void)swapBuffers {
contentLayer.frame = layer.bounds;
_contentLayer.frame = _containingLayer.bounds;
// The surface is an OpenGL texture, which means it has origin in bottom left corner
// and needs to be flipped vertically
contentLayer.transform = CATransform3DMakeScale(1, -1, 1);
[contentLayer setContents:(__bridge id)_ioSurface[kBack]];
std::swap(_ioSurface[kBack], _ioSurface[kFront]);
std::swap(_frameBufferId[kBack], _frameBufferId[kFront]);
std::swap(_backingTexture[kBack], _backingTexture[kFront]);
_contentLayer.transform = CATransform3DMakeScale(1, -1, 1);
[_contentLayer setContents:(__bridge id)_ioSurface[kFlutterSurfaceManagerBackBuffer]];
std::swap(_ioSurface[kFlutterSurfaceManagerBackBuffer],
_ioSurface[kFlutterSurfaceManagerFrontBuffer]);
std::swap(_frameBufferId[kFlutterSurfaceManagerBackBuffer],
_frameBufferId[kFlutterSurfaceManagerFrontBuffer]);
std::swap(_backingTexture[kFlutterSurfaceManagerBackBuffer],
_backingTexture[kFlutterSurfaceManagerFrontBuffer]);
}
- (uint32_t)glFrameBufferId {
return _frameBufferId[kBack];
return _frameBufferId[kFlutterSurfaceManagerBackBuffer];
}
- (void)dealloc {
for (int i = 0; i < kBufferCount; ++i) {
for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) {
if (_ioSurface[i]) {
CFRelease(_ioSurface[i]);
}
......
......@@ -20,7 +20,16 @@
*/
@interface FlutterView : NSView
/**
* The OpenGL context of backing surface.
*/
@property(readwrite, nonatomic, nonnull) NSOpenGLContext* openGLContext;
/**
* Controls whether view resizing synchronously updates contents. This can only be enabled
* after the engine is running and producing frames, because during synchronous view resizing the
* platform thread is blocked until engine produces frame with requested size.
*/
@property(readwrite, nonatomic) BOOL synchronousResizing;
- (nullable instancetype)initWithFrame:(NSRect)frame
......@@ -38,7 +47,15 @@
- (nullable instancetype)initWithCoder:(nonnull NSCoder*)coder NS_UNAVAILABLE;
- (nonnull instancetype)init NS_UNAVAILABLE;
/**
* Flushes the OpenGL context and flips the surfaces. Expected to be called on raster thread.
*/
- (void)present;
- (int)getFrameBufferIdForSize:(CGSize)size;
/**
* Ensures that framebuffer with requested size exists and returns the ID. Expected to be called on
* raster thread.
*/
- (int)frameBufferIDForSize:(CGSize)size;
@end
......@@ -3,17 +3,18 @@
// found in the LICENSE file.
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/MacOSSwitchableGLContext.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/MacOSGLContextSwitch.h"
#import <OpenGL/gl.h>
#import <QuartzCore/QuartzCore.h>
@interface FlutterView () <FlutterResizeSynchronizerDelegate> {
__weak id<FlutterViewReshapeListener> _reshapeListener;
FlutterResizeSynchronizer* resizeSynchronizer;
FlutterSurfaceManager* surfaceManager;
FlutterResizeSynchronizer* _resizeSynchronizer;
FlutterSurfaceManager* _surfaceManager;
}
@end
......@@ -35,9 +36,9 @@
[self setWantsLayer:YES];
resizeSynchronizer = [[FlutterResizeSynchronizer alloc] initWithDelegate:self];
surfaceManager = [[FlutterSurfaceManager alloc] initWithLayer:self.layer
openGLContext:self.openGLContext];
_resizeSynchronizer = [[FlutterResizeSynchronizer alloc] initWithDelegate:self];
_surfaceManager = [[FlutterSurfaceManager alloc] initWithLayer:self.layer
openGLContext:self.openGLContext];
_reshapeListener = reshapeListener;
}
......@@ -45,8 +46,7 @@
}
- (void)resizeSynchronizerFlush:(FlutterResizeSynchronizer*)synchronizer {
flutter::GLContextSwitch context_switch(
std::make_unique<MacOSSwitchableGLContext>(self.openGLContext));
MacOSGLContextSwitch context_switch(self.openGLContext);
glFlush();
}
......@@ -54,29 +54,29 @@
[CATransaction begin];
[CATransaction setDisableActions:YES];
[surfaceManager swapBuffers];
[_surfaceManager swapBuffers];
[CATransaction commit];
}
- (int)getFrameBufferIdForSize:(CGSize)size {
if ([resizeSynchronizer shouldEnsureSurfaceForSize:size]) {
[surfaceManager ensureSurfaceSize:size];
- (int)frameBufferIDForSize:(CGSize)size {
if ([_resizeSynchronizer shouldEnsureSurfaceForSize:size]) {
[_surfaceManager ensureSurfaceSize:size];
}
return [surfaceManager glFrameBufferId];
return [_surfaceManager glFrameBufferId];
}
- (void)present {
[resizeSynchronizer requestCommit];
[_resizeSynchronizer requestCommit];
}
- (void)reshaped {
if (self.synchronousResizing) {
CGSize scaledSize = [self convertSizeToBacking:self.bounds.size];
[resizeSynchronizer beginResize:scaledSize
notify:^{
[_reshapeListener viewDidReshape:self];
}];
[_resizeSynchronizer beginResize:scaledSize
notify:^{
[_reshapeListener viewDidReshape:self];
}];
} else {
[_reshapeListener viewDidReshape:self];
}
......
// 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>
/**
* RAII wrapper that sets provided NSOpenGLContext as current and restores
* original context on scope exit.
*/
class MacOSGLContextSwitch {
public:
explicit MacOSGLContextSwitch(NSOpenGLContext* context);
~MacOSGLContextSwitch();
MacOSGLContextSwitch(const MacOSGLContextSwitch&) = delete;
MacOSGLContextSwitch(MacOSGLContextSwitch&&) = delete;
private:
NSOpenGLContext* previous_;
};
// 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/MacOSGLContextSwitch.h"
MacOSGLContextSwitch::MacOSGLContextSwitch(NSOpenGLContext* context) {
previous_ = [NSOpenGLContext currentContext];
[context makeCurrentContext];
}
MacOSGLContextSwitch::~MacOSGLContextSwitch() {
if (previous_) {
[previous_ makeCurrentContext];
} else {
[NSOpenGLContext clearCurrentContext];
}
}
#include "flutter/flow/gl_context_switch.h"
#include "flutter/fml/memory/thread_checker.h"
#import <Cocoa/Cocoa.h>
class MacOSSwitchableGLContext final : public flutter::SwitchableGLContext {
public:
explicit MacOSSwitchableGLContext(NSOpenGLContext* context);
bool SetCurrent() override;
bool RemoveCurrent() override;
private:
NSOpenGLContext* context_;
NSOpenGLContext* previous_context_;
FML_DECLARE_THREAD_CHECKER(checker);
FML_DISALLOW_COPY_AND_ASSIGN(MacOSSwitchableGLContext);
};
#import "flutter/shell/platform/darwin/macos/framework/Source/MacOSSwitchableGLContext.h"
MacOSSwitchableGLContext::MacOSSwitchableGLContext(NSOpenGLContext* context) : context_(context) {}
bool MacOSSwitchableGLContext::SetCurrent() {
FML_DCHECK_CREATION_THREAD_IS_CURRENT(checker);
previous_context_ = [NSOpenGLContext currentContext];
[context_ makeCurrentContext];
return true;
}
bool MacOSSwitchableGLContext::RemoveCurrent() {
if (previous_context_) {
[previous_context_ makeCurrentContext];
} else {
[NSOpenGLContext clearCurrentContext];
}
return true;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册