From 6d773a80e73f65c6607abdf2811b183647bde661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Sun, 19 Jun 2016 16:33:05 +0200 Subject: [PATCH] Fix GLImage.m, inject warnings on Image usage, expose resolveAssetSource --- .eslintrc | 51 ------------------- .eslintrc.json | 49 ++++++++++++++++++ android/RNGL.iml | 1 + .../com/projectseptember/RNGL/GLCanvas.java | 12 ++++- example/android/app/app.iml | 24 ++++----- example/package.json | 6 +-- example/src/AdvancedEffects/index.js | 3 +- ios/GLCanvas.m | 3 ++ ios/GLImage.m | 34 +++++++++---- package.json | 4 +- src/index.js | 23 ++++++++- 11 files changed, 127 insertions(+), 83 deletions(-) delete mode 100644 .eslintrc create mode 100644 .eslintrc.json diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index aa5082c..0000000 --- a/.eslintrc +++ /dev/null @@ -1,51 +0,0 @@ -{ - "parser": "babel-eslint", - "globals": { - "requestAnimationFrame": true - }, - "rules": { - "indent": [ - 2, - 2 - ], - "quotes": [ - 2, - "double" - ], - "linebreak-style": [ - 2, - "unix" - ], - "semi": [ - 2, - "always" - ], - "comma-dangle": 0, - "no-var": 1, - - "react/jsx-boolean-value": 1, - "react/jsx-no-undef": 1, - "react/jsx-quotes": 1, - "react/jsx-uses-react": 1, - "react/jsx-uses-vars": 1, - "react/no-danger": 1, - "react/no-did-mount-set-state": 1, - "react/no-did-update-set-state": 1, - "react/no-unknown-property": 1, - "react/react-in-jsx-scope": 1, - "react/require-extension": 1, - "react/sort-comp": 1 - }, - "env": { - "es6": true, - "node": true - }, - "extends": "eslint:recommended", - "ecmaFeatures": { - "jsx": true, - "experimentalObjectRestSpread": true - }, - "plugins": [ - "react" - ] -} diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..6af15b2 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,49 @@ +{ + "parser": "babel-eslint", + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "node": true + }, + "globals": { + "__DEV__": true + }, + "extends": "eslint:recommended", + "installedESLint": true, + "parserOptions": { + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + }, + "sourceType": "module" + }, + "plugins": [ + "react" + ], + "rules": { + "indent": [ + "error", + 2 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "double" + ], + "semi": [ + "error", + "always" + ], + "no-console": [ + "error", + { "allow": ["warn", "error" ] } + ], + "comma-dangle": 0, + "react/jsx-uses-react": "error", + "react/jsx-uses-vars": "error" + } +} diff --git a/android/RNGL.iml b/android/RNGL.iml index ae08619..27e83b1 100644 --- a/android/RNGL.iml +++ b/android/RNGL.iml @@ -100,6 +100,7 @@ + diff --git a/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java b/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java index 4b12b77..c88c495 100644 --- a/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java +++ b/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java @@ -490,7 +490,17 @@ public class GLCanvas extends GLSurfaceView textures.put(uniformName, emptyTexture); } else { - ReadableMap value = dataUniforms.getMap(uniformName); + ReadableMap value = null; + try { + value = dataUniforms.getMap(uniformName); + } + catch (Exception e) { + shader.runtimeException( + "texture uniform '"+uniformName+"': you cannot directly give require('./img.png') "+ + "to gl-react, use resolveAssetSource(require('./img.png')) instead." + ); + return null; + } String t = value.getString("type"); if (t.equals("content")) { int id = value.getInt("id"); diff --git a/example/android/app/app.iml b/example/android/app/app.iml index 4b00cde..9fc5b90 100644 --- a/example/android/app/app.iml +++ b/example/android/app/app.iml @@ -64,14 +64,6 @@ - - - - - - - - @@ -80,14 +72,20 @@ + + + + + + + + - - @@ -97,7 +95,7 @@ - + @@ -107,20 +105,19 @@ - - + @@ -132,7 +129,6 @@ - diff --git a/example/package.json b/example/package.json index 954cac4..2115dcc 100644 --- a/example/package.json +++ b/example/package.json @@ -7,12 +7,12 @@ }, "dependencies": { "crypto": "0.0.3", - "gl-react": "^2.2.0", - "gl-react-blur": "^1.2.2", + "gl-react": "2.2.4", + "gl-react-blur": "^1.3.0", "gl-react-native": "file:..", "glsl-transitions": "^2016.2.15", "react": "^15.1.0", - "react-native": "^0.27.2", + "react-native": "^0.28.0-rc.0", "react-native-fs": "^1.4.0", "react-native-material-kit": "PyYoshi/react-native-material-kit#rn-0.25.1", "react-transform-hmr": "^1.0.2", diff --git a/example/src/AdvancedEffects/index.js b/example/src/AdvancedEffects/index.js index ab037b6..3d1d4e0 100644 --- a/example/src/AdvancedEffects/index.js +++ b/example/src/AdvancedEffects/index.js @@ -1,13 +1,14 @@ import React from "react"; import {StyleSheet, View} from "react-native"; +import {resolveAssetSource} from "gl-react-native"; const { width: viewportW, height: viewportH } = require("Dimensions").get("window"); -import resolveAssetSource from "react-native/Libraries/Image/resolveAssetSource"; import Banner from "./Banner"; import Intro from "./Intro"; import Vignette from "./Vignette"; import Slideshow from "./Slideshow"; + class AdvancedEffects extends React.Component { constructor (props) { diff --git a/ios/GLCanvas.m b/ios/GLCanvas.m index 3578b98..1a19eec 100644 --- a/ios/GLCanvas.m +++ b/ios/GLCanvas.m @@ -227,6 +227,9 @@ RCT_NOT_IMPLEMENTED(-init) [emptyTexture setPixels:nil]; textures[uniformName] = emptyTexture; } + else if ([value isKindOfClass:[NSNumber class]]) { + RCTLogError(@"texture uniform '%@': you cannot directly give require('./img.png') to gl-react, use resolveAssetSource(require('./img.png')) instead.", uniformName); + } else { NSString *type = [RCTConvert NSString:value[@"type"]]; if ([type isEqualToString:@"content"]) { diff --git a/ios/GLImage.m b/ios/GLImage.m index 0e83272..16d0770 100644 --- a/ios/GLImage.m +++ b/ios/GLImage.m @@ -5,6 +5,7 @@ #import "RCTImageLoader.h" #import "RCTLog.h" #import "GLTexture.h" +#import "RCTUtils.h" @implementation GLImage { @@ -70,31 +71,46 @@ RCT_NOT_IMPLEMENTED(-init) - (void)reloadImage { + RCTImageSource *source = _source; if (_loading) _loading(); _loading = nil; - if (!_source) { + if (!source) { [self clearImage]; } else { // Load the image (without resizing it) - _loading = [_bridge.imageLoader loadImageWithURLRequest:_source.imageURL.absoluteString + __weak GLImage *weakSelf = self; + _loading = [_bridge.imageLoader loadImageWithURLRequest:source.request size:CGSizeZero scale:0 clipped:YES resizeMode:RCTResizeModeStretch progressBlock:nil - completionBlock:^(NSError *error, UIImage *image) { + completionBlock:^(NSError *error, UIImage *loadedImage) { + GLImage *strongSelf = weakSelf; + void (^setImageBlock)(UIImage *) = ^(UIImage *image) { + if (![source isEqual:strongSelf.source]) { + // Bail out if source has changed since we started loading + return; + } + strongSelf.image = [UIImage imageWithCGImage:image.CGImage]; + dispatch_async(dispatch_get_main_queue(), ^{ + if (_onload) _onload(); + }); + }; + _loading = nil; [self clearImage]; if (error) { NSLog(@"Image failed to load: %@", error); } else { - // we need to copy the image because it seems the image will be altered. - // ^^^ FIXME: check if it's still the case - self.image = [UIImage imageWithCGImage:image.CGImage]; - dispatch_async(dispatch_get_main_queue(), ^{ - if (_onload) _onload(); - }); + if ([NSThread isMainThread]) { + setImageBlock(loadedImage); + } else { + RCTExecuteOnMainThread(^{ + setImageBlock(loadedImage); + }, NO); + } } }]; } diff --git a/package.json b/package.json index aaecf6b..51b466d 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "author": "Project September ", "license": "MIT", "peerDependencies": { - "react-native": "*", - "gl-react": "^2.2.3" + "react-native": "* || 0.28.0-rc.0", + "gl-react": "^2.2.4" }, "dependencies": { "invariant": "2.2.0", diff --git a/src/index.js b/src/index.js index 61e73d5..463bf1a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,11 @@ import invariant from "invariant"; -import { Shaders } from "gl-react"; +import { Shaders, runtime } from "gl-react"; import isAnimated from "gl-react/src/isAnimated"; import makeSurface from "./makeSurface"; import GLCanvas from "./GLCanvas"; -import {NativeModules, View, Animated} from "react-native"; +import {NativeModules, View, Animated, Image} from "react-native"; +import resolveAssetSource from "react-native/Libraries/Image/resolveAssetSource"; + const {RNGLContext} = NativeModules; invariant(RNGLContext, `gl-react-native: the native module is not available. @@ -23,7 +25,24 @@ Shaders.setImplementation({ remove: id => RNGLContext.removeShader(id) }); +if (__DEV__) { + runtime.decorateVDOMContent = vdom => { + if (vdom && vdom.type === Image && !vdom.props.glReactUseImage) { + console.warn( +`gl-react: Found a ReactNative.Image element. This is not performant. Try one of these: +- pass-in directly the image URL in your uniforms. +- use gl-react-image which implements the same Image API directly in OpenGL. https://github.com/gre/gl-react-image +- If you need more features like padding, explicitly setting image size, you can implement your own shader. + +If you still want to do this, add a glReactUseImage prop to the Image to disable this warning. +`); + } + return vdom; + }; +} + module.exports = { + resolveAssetSource, Surface: makeSurface({ View, GLCanvas, -- 2.26.2