diff --git a/Examples/AdvancedEffects/android/app/app.iml b/Examples/AdvancedEffects/android/app/app.iml
index 2cd6263fb978920319d5d99a6c685a4ebdea558d..04987cfac2432bef82215719fb37ed437bebb771 100644
--- a/Examples/AdvancedEffects/android/app/app.iml
+++ b/Examples/AdvancedEffects/android/app/app.iml
@@ -97,8 +97,8 @@
-
+
diff --git a/Examples/AdvancedEffects/ios/AdvancedEffects.xcodeproj/xcshareddata/xcschemes/AdvancedEffects.xcscheme b/Examples/AdvancedEffects/ios/AdvancedEffects.xcodeproj/xcshareddata/xcschemes/AdvancedEffects.xcscheme
index fc0591be51e890b1f2f5a10663f9074f1ca5ee16..0888e641f24af7f6c7e3395348ccfdc64059d77d 100644
--- a/Examples/AdvancedEffects/ios/AdvancedEffects.xcodeproj/xcshareddata/xcschemes/AdvancedEffects.xcscheme
+++ b/Examples/AdvancedEffects/ios/AdvancedEffects.xcodeproj/xcshareddata/xcschemes/AdvancedEffects.xcscheme
@@ -37,10 +37,10 @@
+ shouldUseLaunchSchemeArgsEnv = "YES">
@@ -62,15 +62,18 @@
ReferencedContainer = "container:AdvancedEffects.xcodeproj">
+
+
@@ -82,14 +85,21 @@
ReferencedContainer = "container:AdvancedEffects.xcodeproj">
+
+
+
+
diff --git a/Examples/AdvancedEffects/src/Banner.js b/Examples/AdvancedEffects/src/Banner.js
index c9f5285f985750ea02c4e0c3a08e52ab28788567..8f412882cd54f98a6ec7f238ed80dfd43428eff0 100644
--- a/Examples/AdvancedEffects/src/Banner.js
+++ b/Examples/AdvancedEffects/src/Banner.js
@@ -27,7 +27,9 @@ void main( void ) {
class Banner extends React.Component {
render () {
const { width, height, time } = this.props;
- return console.log("Banner onLoad")}>
+ return console.log("Banner onLoad")}
+ onProgress={e => console.log("Banner onProgress", e.nativeEvent)}>
;
}
diff --git a/Examples/AdvancedEffects/src/Intro.js b/Examples/AdvancedEffects/src/Intro.js
index 662829851bf5a0c7421249dcb69c6aef568bf9c7..94af9f9426b365ec27f90eb672185c6c6971a4fd 100644
--- a/Examples/AdvancedEffects/src/Intro.js
+++ b/Examples/AdvancedEffects/src/Intro.js
@@ -40,7 +40,9 @@ void main() {
class Intro extends React.Component {
render () {
const { time, fps, width, height } = this.props;
- return
+ return console.log("Intro onLoad")}
+ onProgress={e => console.log("Intro onProgress", e.nativeEvent)}>
true}
onMoveShouldSetResponder={() => true}
onLoad={() => console.log("Vignette onLoad")}
+ onProgress={e => console.log("Vignette onProgress", e.nativeEvent)}
onResponderMove={this.onResponderMove}>
+
+
+
+
@@ -77,10 +81,13 @@
+
+
+
diff --git a/Examples/android/RNGL.iml b/Examples/android/RNGL.iml
index e3cb714fc579494723124b675e53b2f5c97483d9..d90b763d79676e58f0ed979346315239bc64de94 100644
--- a/Examples/android/RNGL.iml
+++ b/Examples/android/RNGL.iml
@@ -85,8 +85,8 @@
-
+
diff --git a/android/RNGL.iml b/android/RNGL.iml
index 0ee7994615f51180446a865a16fb4c90840aa6ef..da94af0025670f3a0730de90d6eeb16c76e1ab26 100644
--- a/android/RNGL.iml
+++ b/android/RNGL.iml
@@ -1,5 +1,5 @@
-
+
diff --git a/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java b/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java
index d7a8919c9317bc34f2faa886f988dc1533ea4189..40cf63cb32ddf32e13148ddd5fcd0e72cad07890 100644
--- a/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java
+++ b/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java
@@ -33,10 +33,12 @@ import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
+import java.util.Set;
import java.util.concurrent.Executor;
import javax.microedition.khronos.egl.EGLConfig;
@@ -47,7 +49,8 @@ public class GLCanvas extends GLSurfaceView
private ReactContext reactContext;
private RNGLContext rnglContext;
- private boolean preloadingDone = false;
+ private boolean dirtyOnLoad = true;
+ private boolean neverRendered = true;
private boolean deferredRendering = false;
private GLRenderData renderData;
private int defaultFBO;
@@ -127,11 +130,15 @@ public class GLCanvas extends GLSurfaceView
if (contentTextures.size() != this.nbContentTextures)
resizeUniformContentTextures(nbContentTextures);
- if (!preloadingDone) {
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
+ if (haveRemainingToPreload()) {
+ if (neverRendered) {
+ neverRendered = false;
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
return;
}
+ neverRendered = false;
final boolean shouldRenderNow = deferredRendering || autoRedraw || nbContentTextures == 0;
if (nbContentTextures > 0) {
@@ -161,6 +168,15 @@ public class GLCanvas extends GLSurfaceView
}
}
+ private boolean haveRemainingToPreload() {
+ for (Uri uri: imagesToPreload) {
+ if (!preloaded.contains(uri)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public void setNbContentTextures(int n) {
this.nbContentTextures = n;
requestRender();
@@ -168,7 +184,7 @@ public class GLCanvas extends GLSurfaceView
public void setRenderId(int renderId) {
if (nbContentTextures > 0) {
- if (preloadingDone) syncContentBitmaps();
+ if (!haveRemainingToPreload()) syncContentBitmaps();
requestRender();
}
}
@@ -190,25 +206,18 @@ public class GLCanvas extends GLSurfaceView
public void setData (GLData data) {
this.data = data;
- if (preloadingDone) syncContentBitmaps();
+ if (!haveRemainingToPreload()) syncContentBitmaps();
requestSyncData();
}
public void setImagesToPreload (ReadableArray imagesToPreloadRA) {
- if (preloadingDone) return;
List imagesToPreload = new ArrayList<>();
for (int i=0; i images = new HashMap<>();
GLRenderData node = recSyncData(data, images);
if (node == null) return false;
+ Set imagesGone = diff(this.images.keySet(), images.keySet());
renderData = node;
this.images = images;
+ this.preloaded.removeAll(imagesGone);
return true;
}
@@ -652,6 +657,11 @@ public class GLCanvas extends GLSurfaceView
recRender(renderData);
glDisable(GL_BLEND);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
+
+ if (dirtyOnLoad && !haveRemainingToPreload()) {
+ dirtyOnLoad = false;
+ dispatchOnLoad();
+ }
}
private void dispatchOnCaptureFrame (String frame) {
@@ -666,7 +676,7 @@ public class GLCanvas extends GLSurfaceView
private void dispatchOnProgress (double progress, int loaded, int total) {
WritableMap event = Arguments.createMap();
- event.putDouble("progress", progress);
+ event.putDouble("progress", Double.isNaN(progress) ? 0.0 : progress);
event.putInt("loaded", loaded);
event.putInt("total", total);
ReactContext reactContext = (ReactContext)getContext();
@@ -732,4 +742,10 @@ public class GLCanvas extends GLSurfaceView
mPointerEvents = pointerEvents;
}
+ static Set diff(Set a, Set b) {
+ Set d = new HashSet<>();
+ d.addAll(a);
+ d.removeAll(b);
+ return d;
+ }
}
diff --git a/ios/GLCanvas.m b/ios/GLCanvas.m
index 2af658374e0cf3b3dce6aa56f9103ba81f2e21d3..9250e7d07092086033f292e987bb5eb31c348382 100644
--- a/ios/GLCanvas.m
+++ b/ios/GLCanvas.m
@@ -26,6 +26,16 @@ NSString* srcResource (id res)
return src;
}
+NSArray* diff (NSArray* a, NSArray* b) {
+ NSMutableArray *arr = [[NSMutableArray alloc] init];
+ for (NSString* k in a) {
+ if (![b containsObject:k]) {
+ [arr addObject:k];
+ }
+ }
+ return arr;
+}
+
// For reference, see implementation of gl-shader's GLCanvas
@implementation GLCanvas
@@ -47,7 +57,8 @@ NSString* srcResource (id res)
GLint defaultFBO;
NSMutableArray *_preloaded;
- BOOL _preloadingDone;
+ BOOL _dirtyOnLoad;
+ BOOL _neverRendered;
NSTimer *animationTimer;
@@ -61,7 +72,8 @@ NSString* srcResource (id res)
_images = @{};
_preloaded = [[NSMutableArray alloc] init];
_captureFrameRequested = false;
- _preloadingDone = false;
+ _dirtyOnLoad = true;
+ _neverRendered = true;
self.context = [bridge.rnglContext getContext];
self.contentScaleFactor = RCTScreenScale();
}
@@ -80,15 +92,8 @@ RCT_NOT_IMPLEMENTED(-init)
-(void)setImagesToPreload:(NSArray *)imagesToPreload
{
- if (_preloadingDone) return;
- if ([imagesToPreload count] == 0) {
- [self dispatchOnLoad];
- _preloadingDone = true;
- }
- else {
- _preloadingDone = false;
- }
_imagesToPreload = imagesToPreload;
+ [self requestSyncData];
}
- (void)setOpaque:(BOOL)opaque
@@ -151,7 +156,6 @@ RCT_NOT_IMPLEMENTED(-init)
- (void)syncData
{
- [EAGLContext setCurrentContext:self.context];
@autoreleasepool {
NSDictionary *prevImages = _images;
@@ -270,6 +274,9 @@ RCT_NOT_IMPLEMENTED(-init)
if (res != nil) {
_renderData = traverseTree(_data);
_images = images;
+ for (NSString *src in diff([prevImages allKeys], [images allKeys])) {
+ [_preloaded removeObject:src];
+ }
}
}
}
@@ -303,6 +310,16 @@ RCT_NOT_IMPLEMENTED(-init)
}
}
+- (BOOL)haveRemainingToPreload
+{
+ for (id res in _imagesToPreload) {
+ if (![_preloaded containsObject:srcResource(res)]) {
+ return true;
+ }
+ }
+ return false;
+}
+
//// Draw
@@ -316,11 +333,16 @@ RCT_NOT_IMPLEMENTED(-init)
self.layer.opaque = _opaque;
- if (!_preloadingDone) {
- glClearColor(0.0, 0.0, 0.0, 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
+ if ([self haveRemainingToPreload]) {
+ if (_neverRendered) {
+ _neverRendered = false;
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
return;
}
+ _neverRendered = false;
+
BOOL needsDeferredRendering = _nbContentTextures > 0 && !_autoRedraw;
if (needsDeferredRendering && !_deferredRendering) {
dispatch_async(dispatch_get_main_queue(), ^{
@@ -407,6 +429,11 @@ RCT_NOT_IMPLEMENTED(-init)
recDraw(_renderData);
glDisable(GL_BLEND);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
+
+ if (_dirtyOnLoad && ![self haveRemainingToPreload]) {
+ _dirtyOnLoad = false;
+ [self dispatchOnLoad];
+ }
}
}
@@ -414,22 +441,13 @@ RCT_NOT_IMPLEMENTED(-init)
- (void)onImageLoad:(NSString *)loaded
{
- if (!_preloadingDone) {
- [_preloaded addObject:loaded];
- int count = [self countPreloaded];
- int total = (int) [_imagesToPreload count];
- double progress = ((double) count) / ((double) total);
- [self dispatchOnProgress:progress withLoaded:count withTotal:total];
- if (count == total) {
- [self dispatchOnLoad];
- _preloadingDone = true;
- [self requestSyncData];
- }
- }
- else {
- // Any texture image load will trigger a future re-sync of data (if no preloaded)
- [self requestSyncData];
- }
+ [_preloaded addObject:loaded];
+ int count = [self countPreloaded];
+ int total = (int) [_imagesToPreload count];
+ double progress = ((double) count) / ((double) total);
+ [self dispatchOnProgress:progress withLoaded:count withTotal:total];
+ _dirtyOnLoad = true;
+ [self requestSyncData];
}
- (int)countPreloaded