Skip to content

Commit 0bc22f6

Browse files
committed
- Fix for iOS
1 parent 6cec3bb commit 0bc22f6

File tree

7 files changed

+107
-74
lines changed

7 files changed

+107
-74
lines changed

cpp/RNWebGL.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#ifdef __APPLE__
99
#include <OpenGLES/ES3/gl.h>
1010
#include <OpenGLES/ES3/glext.h>
11-
#include <OpenGLES/EAGL.h>
1211
#endif
1312

1413
#include <exception>
@@ -25,7 +24,7 @@
2524
#include "JSUtils.h"
2625
#include "JSConvertTypedArray.h"
2726
#define STB_IMAGE_IMPLEMENTATION
28-
#include "stb_image.h"
27+
#include"stb_image.h"
2928

3029
#ifdef __APPLE__
3130
#include "iOSUtils.h"
@@ -2107,7 +2106,7 @@ return nullptr; \
21072106
// Exponent extensions
21082107
// -------------------
21092108

2110-
_WRAP_METHOD(endFrame, 0) {
2109+
_WRAP_METHOD(endFrameEXP, 0) {
21112110
addToNextBatch([=] {
21122111
setNeedsRedraw(true);
21132112
});
@@ -2116,7 +2115,7 @@ return nullptr; \
21162115
return nullptr;
21172116
}
21182117

2119-
_WRAP_METHOD(flush, 0) {
2118+
_WRAP_METHOD(flushEXP, 0) {
21202119
addBlockingToNextBatch([&] {
21212120
// nothing, it's just a helper so that we can measure how much time some operations take
21222121
});
@@ -2410,8 +2409,8 @@ JSObjectSetFunctionWithUTF8CStringName(jsCtx, jsGl, #name, \
24102409
_INSTALL_METHOD(getExtension);
24112410

24122411
// Exponent extensions
2413-
_INSTALL_METHOD(endFrame);
2414-
_INSTALL_METHOD(flush);
2412+
_INSTALL_METHOD(endFrameEXP);
2413+
_INSTALL_METHOD(flushEXP);
24152414

24162415
#undef _INSTALL_METHOD
24172416
}

cpp/iOSUtils.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <stdarg.h>
33

44
#import <Foundation/Foundation.h>
5+
#import <OpenGLES/EAGL.h>
56

67
void iOSLog(const char *msg, ...) {
78
va_list args;

ios/RNWebGLContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
- (void)takeSnapshotWithOptions:(nonnull NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject;
3434
- (void)destroy;
3535

36+
+ (CGFloat)screenScale;
37+
3638
// "protected"
3739
@property (nonatomic, assign) RNWebGLContextId contextId;
3840
@property (nonatomic, strong, nonnull) EAGLContext *eaglCtx;

ios/RNWebGLContext.m

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ @interface RNWebGLContext ()
1212

1313
@end
1414

15+
@interface RCTBridge ()
16+
17+
- (JSGlobalContextRef)jsContextRef;
18+
- (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue;
19+
20+
@end
21+
1522
@implementation RNWebGLContext
1623

1724
- (instancetype)initWithDelegate:(id<RNWebGLContextDelegate>)delegate andObjectMananger:(nonnull RNWebGLObjectManager *)objectManager {
@@ -77,7 +84,7 @@ - (void)initialize:(void(^)(BOOL))callback {
7784
[self.delegate glContextInitialized:self];
7885
}
7986
BLOCK_SAFE_RUN(callback, YES);
80-
}];
87+
} queue:RCTJSThread];
8188
return;
8289
}
8390
BLOCK_SAFE_RUN(callback, NO);
@@ -175,7 +182,7 @@ - (void)takeSnapshotWithOptions:(nonnull NSDictionary *)options resolve:(RCTProm
175182
providerRef, NULL, true, kCGRenderingIntentDefault);
176183

177184
// Begin image context
178-
CGFloat scale = [EXUtilities screenScale];
185+
CGFloat scale = [RNWebGLContext screenScale];
179186
NSInteger widthInPoints = width / scale;
180187
NSInteger heightInPoints = height / scale;
181188
UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale);
@@ -255,8 +262,45 @@ - (NSString *)generateSnapshotPathWithExtension:(NSString *)extension {
255262
NSString *directory = [[self getPathForDirectory: NSCachesDirectory] stringByAppendingPathComponent:@"GLView"];
256263
NSString *fileName = [[[NSUUID UUID] UUIDString] stringByAppendingString:extension];
257264

258-
[[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:@[] error:nil];
265+
[[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:@{} error:nil];
259266

260267
return [directory stringByAppendingPathComponent:fileName];
261268
}
269+
270+
#pragma mark - Copy from RN
271+
272+
+ (BOOL)isMainQueue {
273+
static void *mainQueueKey = &mainQueueKey;
274+
static dispatch_once_t onceToken;
275+
dispatch_once(&onceToken, ^{
276+
dispatch_queue_set_specific(dispatch_get_main_queue(),
277+
mainQueueKey, mainQueueKey, NULL);
278+
});
279+
return dispatch_get_specific(mainQueueKey) == mainQueueKey;
280+
}
281+
282+
+ (void)unsafeExecuteOnMainQueueOnceSync:(dispatch_once_t *)onceToken block:(dispatch_block_t)block {
283+
// The solution was borrowed from a post by Ben Alpert:
284+
// https://benalpert.com/2014/04/02/dispatch-once-initialization-on-the-main-thread.html
285+
// See also: https://www.mikeash.com/pyblog/friday-qa-2014-06-06-secrets-of-dispatch_once.html
286+
if ([self isMainQueue]) {
287+
dispatch_once(onceToken, block);
288+
} else {
289+
if (DISPATCH_EXPECT(*onceToken == 0L, NO)) {
290+
dispatch_sync(dispatch_get_main_queue(), ^{
291+
dispatch_once(onceToken, block);
292+
});
293+
}
294+
}
295+
}
296+
297+
+ (CGFloat)screenScale {
298+
static dispatch_once_t onceToken;
299+
static CGFloat scale;
300+
[self unsafeExecuteOnMainQueueOnceSync:&onceToken block:^{
301+
scale = [UIScreen mainScreen].scale;
302+
}];
303+
return scale;
304+
}
305+
262306
@end

ios/RNWebGLObjectManager.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
#import "RCTBridgeModule.h"
77
#endif
88

9+
#if __has_include(<React/RCTBridge.h>)
10+
#import <React/RCTBridge.h>
11+
#elif __has_include("React/RCTBridge.h")
12+
#import "React/RCTBridge.h"
13+
#else
14+
#import "RCTBridge.h"
15+
#endif
16+
917
#import "RNWebGLObject.h"
1018

1119
typedef void (^RNWebGLObjectCompletionBlock)(NSError *error, RNWebGLObject *obj);

ios/RNWebGLObjectManager.m

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
#import "RNWebGLObjectManager.h"
22
#import "RNWebGLContext.h"
33

4+
#import "RNWebGLTextureUIImage.h"
5+
46
@interface RNWebGLObjectManager()
57

68
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, RNWebGLContext *> *glContexts;
79
@property (nonatomic, strong) NSMutableDictionary<NSNumber *, RNWebGLObject *> *objects;
10+
@property (nonatomic, strong) NSArray<id<RNWebGLObjectConfigLoader>> *loaders;
811

912
@end
1013

@@ -18,6 +21,7 @@ - (instancetype)init {
1821
if ((self = [super init])) {
1922
_glContexts = [NSMutableDictionary dictionary];
2023
_objects = [NSMutableDictionary dictionary];
24+
_loaders = NULL;
2125
}
2226
return self;
2327
}
@@ -48,11 +52,11 @@ - (void)dealloc {
4852

4953
# pragma mark - Snapshots
5054

51-
RCT_EXPORT_METHOD(takeSnapshotAsync,
52-
takeSnapshotWithContextId:(nonnull NSNumber *)ctxId
53-
andOptions:(nonnull NSDictionary *)options
54-
resolver:(RCTPromiseResolveBlock)resolve
55-
rejecter:(RCTPromiseRejectBlock)reject)
55+
RCT_REMAP_METHOD(takeSnapshotAsync,
56+
takeSnapshotWithContextId:(nonnull NSNumber *)ctxId
57+
andOptions:(nonnull NSDictionary *)options
58+
resolver:(RCTPromiseResolveBlock)resolve
59+
rejecter:(RCTPromiseRejectBlock)reject)
5660
{
5761
RNWebGLContext *glContext = [self getContextWithId:ctxId];
5862
if (glContext == nil) {
@@ -64,11 +68,12 @@ - (void)dealloc {
6468

6569
# pragma mark - Headless Context
6670

67-
RCT_EXPORT_METHOD(createContextAsync,
68-
createContext:(RCTPromiseResolveBlock)resolve
69-
reject:(RCTPromiseRejectBlock)reject)
70-
{
71-
RNWebGLContext *glContext = [[RNWebGLContext alloc] initWithDelegate:nil andModuleRegistry:_moduleRegistry];
71+
RCT_REMAP_METHOD(createContextAsync,
72+
createContext:(RCTPromiseResolveBlock)resolve
73+
reject:(RCTPromiseRejectBlock)reject)
74+
{
75+
RNWebGLContext *glContext = [[RNWebGLContext alloc] initWithDelegate:nil andObjectMananger:self];
76+
7277
[glContext initialize:^(BOOL success) {
7378
if (success) {
7479
resolve(@{ @"ctxId": @(glContext.contextId) });
@@ -82,10 +87,10 @@ - (void)dealloc {
8287
}];
8388
}
8489

85-
RCT_EXPORT_METHOD(destroyContextAsync,
86-
destroyContextWithId:(nonnull NSNumber *)ctxId
87-
resolve:(RCTPromiseResolveBlock)resolve
88-
reject:(RCTPromiseRejectBlock)reject) {
90+
RCT_REMAP_METHOD(destroyContextAsync,
91+
destroyContextWithId:(nonnull NSNumber *)ctxId
92+
resolve:(RCTPromiseResolveBlock)resolve
93+
reject:(RCTPromiseRejectBlock)reject) {
8994
RNWebGLContext *glContext = [self getContextWithId:ctxId];
9095
if (glContext != nil) {
9196
[glContext destroy];
@@ -95,16 +100,14 @@ - (void)dealloc {
95100
}
96101
}
97102

98-
RCT_EXPORT_METHOD(destroyObjectAsync,
99-
destroyObjectAsync:(nonnull NSNumber *)objId
100-
resolve:(RCTPromiseResolveBlock)resolve
101-
reject:(RCTPromiseRejectBlock)reject) {
103+
RCT_REMAP_METHOD(destroyObjectAsync,
104+
destroyObjectAsync:(nonnull NSNumber *)objId
105+
resolve:(RCTPromiseResolveBlock)resolve
106+
reject:(RCTPromiseRejectBlock)reject) {
102107
_objects[objId] = nil;
103108
resolve(@(YES));
104109
}
105110

106-
@end
107-
108111

109112
# pragma mark - Object Loading
110113

@@ -121,7 +124,7 @@ - (void)dealloc {
121124
}
122125

123126
-(void)loadWithConfig:(NSDictionary *)config withCompletionBlock:(RNWebGLObjectCompletionBlock)callback {
124-
id<RNWebGLTextureConfigLoader> loader = [self objectLoaderForConfig:config];
127+
id<RNWebGLObjectConfigLoader> loader = [self objectLoaderForConfig:config];
125128
if (!loader) {
126129
if (RCT_DEBUG) RCTLogError(@"No suitable RNWebGLTextureLoader found for %@", config);
127130
callback([NSError errorWithDomain:@"RNWebGL" code:1 userInfo:@{ NSLocalizedDescriptionKey: @"No suitable RNWebGLTextureLoader found" }], nil);
@@ -140,13 +143,17 @@ -(void)loadWithConfig:(NSDictionary *)config withCompletionBlock:(RNWebGLObjectC
140143
-(void)loadWithConfigAndWaitAttached:(NSDictionary *)config withCompletionBlock:(RNWebGLObjectCompletionBlock)callback {
141144
[self loadWithConfig:config withCompletionBlock:^(NSError *error, RNWebGLObject *obj) {
142145
if(obj != nil) {
143-
if ([obj isAttached]) {
144-
callback(error, obj);
146+
if([obj isKindOfClass:[RNWebGLTexture class]]) {
147+
if ([((RNWebGLTexture*)obj) isAttached]) {
148+
callback(error, obj);
149+
return;
150+
}
151+
[((RNWebGLTexture*)obj) listenAttached:^{
152+
callback(error, obj);
153+
}];
145154
return;
146155
}
147-
[obj listenAttached:^{
148-
callback(error, obj);
149-
}];
156+
callback(error, obj);
150157
return;
151158
}
152159
callback(error, nil);
@@ -157,7 +164,10 @@ -(void)unloadWithObjId:(RNWebGLObjectId)objId {
157164
NSNumber *key = @(objId);
158165
RNWebGLObject *t = _objects[key];
159166
if (t) {
160-
[t unload];
167+
if([t isKindOfClass:[RNWebGLTexture class]]) {
168+
[((RNWebGLTexture*)t) unload];
169+
170+
}
161171
[_objects removeObjectForKey:key];
162172
}
163173
}
@@ -167,13 +177,18 @@ -(void)unloadWithCtxId:(RNWebGLContextId)ctxId {
167177
for (NSNumber *key in [_objects keyEnumerator]) {
168178
RNWebGLObject *t = _objects[key];
169179
if (t.ctxId == ctxId) {
170-
[t unload];
180+
if([t isKindOfClass:[RNWebGLTexture class]]) {
181+
[((RNWebGLTexture*)t) unload];
182+
183+
}
171184
[unloadedKeys addObject:key];
172185
}
173186
}
174187
[_objects removeObjectsForKeys:unloadedKeys];
175188
}
176189

190+
@end
191+
177192
# pragma mark - Bridge
178193

179194
@implementation RCTBridge (RNWebGLObjectManager)

ios/RNWebGLView.m

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ - (instancetype)initWithManager:(RNWebGLViewManager *)viewManager
4343
_viewBuffersSize = CGSizeZero;
4444

4545

46-
self.contentScaleFactor = [RNWebGLView screenScale];
46+
self.contentScaleFactor = [RNWebGLContext screenScale];
4747

4848
// Initialize properties of our backing CAEAGLLayer
4949
CAEAGLLayer *eaglLayer = (CAEAGLLayer *) self.layer;
@@ -293,40 +293,4 @@ - (RNWebGLObjectId)glContextGetDefaultFramebuffer {
293293
return _viewFramebuffer;
294294
}
295295

296-
#pragma mark - Copy from RN
297-
298-
+ (BOOL)isMainQueue {
299-
static void *mainQueueKey = &mainQueueKey;
300-
static dispatch_once_t onceToken;
301-
dispatch_once(&onceToken, ^{
302-
dispatch_queue_set_specific(dispatch_get_main_queue(),
303-
mainQueueKey, mainQueueKey, NULL);
304-
});
305-
return dispatch_get_specific(mainQueueKey) == mainQueueKey;
306-
}
307-
308-
+ (void)unsafeExecuteOnMainQueueOnceSync:(dispatch_once_t *)onceToken block:(dispatch_block_t)block {
309-
// The solution was borrowed from a post by Ben Alpert:
310-
// https://benalpert.com/2014/04/02/dispatch-once-initialization-on-the-main-thread.html
311-
// See also: https://www.mikeash.com/pyblog/friday-qa-2014-06-06-secrets-of-dispatch_once.html
312-
if ([self isMainQueue]) {
313-
dispatch_once(onceToken, block);
314-
} else {
315-
if (DISPATCH_EXPECT(*onceToken == 0L, NO)) {
316-
dispatch_sync(dispatch_get_main_queue(), ^{
317-
dispatch_once(onceToken, block);
318-
});
319-
}
320-
}
321-
}
322-
323-
+ (CGFloat)screenScale {
324-
static dispatch_once_t onceToken;
325-
static CGFloat scale;
326-
[self unsafeExecuteOnMainQueueOnceSync:&onceToken block:^{
327-
scale = [UIScreen mainScreen].scale;
328-
}];
329-
return scale;
330-
}
331-
332296
@end

0 commit comments

Comments
 (0)