Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 07af6a9

Browse files
authored
Create a wrapper for IOSurface to handle creation and (#22663)
binding IOSurfaces to textures / framebuffers.
1 parent 2eea247 commit 07af6a9

File tree

5 files changed

+113
-44
lines changed

5 files changed

+113
-44
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExter
10561056
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.mm
10571057
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterFrameBufferProvider.h
10581058
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterFrameBufferProvider.mm
1059+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h
1060+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.mm
10591061
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.h
10601062
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.mm
10611063
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.h

shell/platform/darwin/macos/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ source_set("flutter_framework_source") {
5454
"framework/Source/FlutterExternalTextureGL.mm",
5555
"framework/Source/FlutterFrameBufferProvider.h",
5656
"framework/Source/FlutterFrameBufferProvider.mm",
57+
"framework/Source/FlutterIOSurfaceHolder.h",
58+
"framework/Source/FlutterIOSurfaceHolder.mm",
5759
"framework/Source/FlutterMouseCursorPlugin.h",
5860
"framework/Source/FlutterMouseCursorPlugin.mm",
5961
"framework/Source/FlutterResizeSynchronizer.h",
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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 <Cocoa/Cocoa.h>
6+
7+
/**
8+
* FlutterIOSurfaceHolder maintains an IOSurface
9+
* and provides an interface to bind the IOSurface to a texture.
10+
*/
11+
@interface FlutterIOSurfaceHolder : NSObject
12+
13+
/**
14+
* Bind the IOSurface to the provided texture and fbo.
15+
*/
16+
- (void)bindSurfaceToTexture:(GLuint)texture fbo:(GLuint)fbo size:(CGSize)size;
17+
18+
/**
19+
* Releases the current IOSurface if one exists
20+
* and creates a new IOSurface with the specified size.
21+
*/
22+
- (void)recreateIOSurfaceWithSize:(CGSize)size;
23+
24+
/**
25+
* Returns a reference to the underlying IOSurface.
26+
*/
27+
- (const IOSurfaceRef&)ioSurface;
28+
29+
@end
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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/FlutterIOSurfaceHolder.h"
6+
7+
#include <OpenGL/gl.h>
8+
9+
@interface FlutterIOSurfaceHolder () {
10+
IOSurfaceRef _ioSurface;
11+
}
12+
@end
13+
14+
@implementation FlutterIOSurfaceHolder
15+
16+
- (void)bindSurfaceToTexture:(GLuint)texture fbo:(GLuint)fbo size:(CGSize)size {
17+
[self recreateIOSurfaceWithSize:size];
18+
19+
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
20+
21+
CGLTexImageIOSurface2D(CGLGetCurrentContext(), GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, int(size.width),
22+
int(size.height), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, _ioSurface,
23+
0 /* plane */);
24+
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
25+
26+
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
27+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, texture,
28+
0);
29+
30+
NSAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
31+
@"Framebuffer status check failed");
32+
}
33+
34+
- (void)recreateIOSurfaceWithSize:(CGSize)size {
35+
if (_ioSurface) {
36+
CFRelease(_ioSurface);
37+
}
38+
39+
unsigned pixelFormat = 'BGRA';
40+
unsigned bytesPerElement = 4;
41+
42+
size_t bytesPerRow = IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, size.width * bytesPerElement);
43+
size_t totalBytes = IOSurfaceAlignProperty(kIOSurfaceAllocSize, size.height * bytesPerRow);
44+
NSDictionary* options = @{
45+
(id)kIOSurfaceWidth : @(size.width),
46+
(id)kIOSurfaceHeight : @(size.height),
47+
(id)kIOSurfacePixelFormat : @(pixelFormat),
48+
(id)kIOSurfaceBytesPerElement : @(bytesPerElement),
49+
(id)kIOSurfaceBytesPerRow : @(bytesPerRow),
50+
(id)kIOSurfaceAllocSize : @(totalBytes),
51+
};
52+
53+
_ioSurface = IOSurfaceCreate((CFDictionaryRef)options);
54+
}
55+
56+
- (const IOSurfaceRef&)ioSurface {
57+
return _ioSurface;
58+
}
59+
60+
- (void)dealloc {
61+
if (_ioSurface) {
62+
CFRelease(_ioSurface);
63+
}
64+
}
65+
66+
@end

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

Lines changed: 14 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h"
66
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterFrameBufferProvider.h"
7+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h"
78

89
#include <OpenGL/gl.h>
910

@@ -22,7 +23,7 @@ @interface FlutterSurfaceManager () {
2223

2324
NSOpenGLContext* _openGLContext;
2425

25-
IOSurfaceRef _ioSurface[kFlutterSurfaceManagerBufferCount];
26+
FlutterIOSurfaceHolder* _ioSurfaces[kFlutterSurfaceManagerBufferCount];
2627
FlutterFrameBufferProvider* _frameBuffers[kFlutterSurfaceManagerBufferCount];
2728
}
2829
@end
@@ -42,6 +43,9 @@ - (instancetype)initWithLayer:(CALayer*)containingLayer
4243

4344
_frameBuffers[0] = [[FlutterFrameBufferProvider alloc] initWithOpenGLContext:_openGLContext];
4445
_frameBuffers[1] = [[FlutterFrameBufferProvider alloc] initWithOpenGLContext:_openGLContext];
46+
47+
_ioSurfaces[0] = [FlutterIOSurfaceHolder alloc];
48+
_ioSurfaces[1] = [FlutterIOSurfaceHolder alloc];
4549
}
4650
return self;
4751
}
@@ -55,38 +59,11 @@ - (void)ensureSurfaceSize:(CGSize)size {
5559
MacOSGLContextSwitch context_switch(_openGLContext);
5660

5761
for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) {
58-
if (_ioSurface[i]) {
59-
CFRelease(_ioSurface[i]);
60-
}
61-
unsigned pixelFormat = 'BGRA';
62-
unsigned bytesPerElement = 4;
63-
64-
size_t bytesPerRow =
65-
IOSurfaceAlignProperty(kIOSurfaceBytesPerRow, size.width * bytesPerElement);
66-
size_t totalBytes = IOSurfaceAlignProperty(kIOSurfaceAllocSize, size.height * bytesPerRow);
67-
NSDictionary* options = @{
68-
(id)kIOSurfaceWidth : @(size.width),
69-
(id)kIOSurfaceHeight : @(size.height),
70-
(id)kIOSurfacePixelFormat : @(pixelFormat),
71-
(id)kIOSurfaceBytesPerElement : @(bytesPerElement),
72-
(id)kIOSurfaceBytesPerRow : @(bytesPerRow),
73-
(id)kIOSurfaceAllocSize : @(totalBytes),
74-
};
75-
_ioSurface[i] = IOSurfaceCreate((CFDictionaryRef)options);
76-
77-
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, [_frameBuffers[i] glTextureId]);
78-
79-
CGLTexImageIOSurface2D(CGLGetCurrentContext(), GL_TEXTURE_RECTANGLE_ARB, GL_RGBA,
80-
int(size.width), int(size.height), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
81-
_ioSurface[i], 0 /* plane */);
82-
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
83-
84-
glBindFramebuffer(GL_FRAMEBUFFER, [_frameBuffers[i] glFrameBufferId]);
85-
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB,
86-
[_frameBuffers[i] glTextureId], 0);
87-
88-
NSAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
89-
@"Framebuffer status check failed");
62+
[_ioSurfaces[i] recreateIOSurfaceWithSize:size];
63+
64+
GLuint fbo = [_frameBuffers[i] glFrameBufferId];
65+
GLuint texture = [_frameBuffers[i] glTextureId];
66+
[_ioSurfaces[i] bindSurfaceToTexture:texture fbo:fbo size:size];
9067
}
9168
}
9269

@@ -96,10 +73,11 @@ - (void)swapBuffers {
9673
// The surface is an OpenGL texture, which means it has origin in bottom left corner
9774
// and needs to be flipped vertically
9875
_contentLayer.transform = CATransform3DMakeScale(1, -1, 1);
99-
[_contentLayer setContents:(__bridge id)_ioSurface[kFlutterSurfaceManagerBackBuffer]];
76+
IOSurfaceRef contentIOSurface = [_ioSurfaces[kFlutterSurfaceManagerBackBuffer] ioSurface];
77+
[_contentLayer setContents:(__bridge id)contentIOSurface];
10078

101-
std::swap(_ioSurface[kFlutterSurfaceManagerBackBuffer],
102-
_ioSurface[kFlutterSurfaceManagerFrontBuffer]);
79+
std::swap(_ioSurfaces[kFlutterSurfaceManagerBackBuffer],
80+
_ioSurfaces[kFlutterSurfaceManagerFrontBuffer]);
10381
std::swap(_frameBuffers[kFlutterSurfaceManagerBackBuffer],
10482
_frameBuffers[kFlutterSurfaceManagerFrontBuffer]);
10583
}
@@ -108,12 +86,4 @@ - (uint32_t)glFrameBufferId {
10886
return [_frameBuffers[kFlutterSurfaceManagerBackBuffer] glFrameBufferId];
10987
}
11088

111-
- (void)dealloc {
112-
for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) {
113-
if (_ioSurface[i]) {
114-
CFRelease(_ioSurface[i]);
115-
}
116-
}
117-
}
118-
11989
@end

0 commit comments

Comments
 (0)