diff --git a/android/rngl.iml b/android/rngl.iml index 686ef627749ca7cfc9b593d3a04d650c0440292d..1654eb94a35c0f7617b5c58afceef26911900fee 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 d39b9d430dfa0ccb22181dda35f30579051a2633..a7e8d6c405698d451084cf678db72e59fe02ab39 100644 --- a/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java +++ b/android/src/main/java/com/projectseptember/RNGL/GLCanvas.java @@ -3,10 +3,13 @@ package com.projectseptember.RNGL; import static android.opengl.GLES20.*; import android.graphics.Bitmap; +import android.graphics.Matrix; import android.graphics.PixelFormat; import android.net.Uri; import android.opengl.GLSurfaceView; import android.util.DisplayMetrics; +import android.util.Log; +import android.view.View; import android.view.ViewGroup; import com.facebook.imagepipeline.core.ExecutorSupplier; @@ -47,7 +50,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, E private boolean autoRedraw; private GLData data; private List imagesToPreload; - private List preloaded = new ArrayList<>(); // FIXME double check that this works + private List preloaded = new ArrayList<>(); private Map images = new HashMap<>(); private List contentTextures = new ArrayList<>(); @@ -82,7 +85,7 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, E public GLFBO getFBO (Integer id) { if (!fbos.containsKey(id)) { - fbos.put(id, new GLFBO()); + fbos.put(id, new GLFBO(this)); } return fbos.get(id); } @@ -100,7 +103,11 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, E public void onSurfaceCreated(GL10 gl, EGLConfig config) { fbos = new HashMap<>(); shaders = new HashMap<>(); - // TODO : need to reset GLImage and GLTexture. in a smart way (images if already loaded just need to re-set the bitmap) + images = new HashMap<>(); + contentTextures = new ArrayList<>(); + contentBitmaps = new ArrayList<>(); + renderData = null; + requestSyncData(); } @Override @@ -248,6 +255,25 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, E }); } + public static Bitmap captureView (View view) { + int w = view.getWidth(); + int h = view.getHeight(); + if (w <= 0 || h <= 0) + return Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888); + Bitmap bitmap = view.getDrawingCache(); + if (bitmap == null) + view.setDrawingCacheEnabled(true); + bitmap = view.getDrawingCache(); + if (bitmap == null) { + Log.e("GLCanvas", "view.getDrawingCache() is null. view="+view); + return Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888); + } + Matrix matrix = new Matrix(); + matrix.postScale(1, -1); + Bitmap reversed = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); + return reversed; + } + /** * Snapshot the content views and save to contentBitmaps (must run in UI Thread) */ @@ -256,11 +282,19 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, E ViewGroup parent = (ViewGroup) this.getParent(); int count = parent == null ? 0 : parent.getChildCount() - 1; for (int i = 0; i < count; i++) { - bitmaps.add(GLTexture.captureView(parent.getChildAt(i))); + View view = parent.getChildAt(i); + if (view instanceof ViewGroup) { + ViewGroup group = (ViewGroup) view; + if (group.getChildCount() == 1) { + // If the content container only contain one other container, + // we will use it for rasterization. That way we screenshot without cropping. + view = group.getChildAt(0); + } + } + bitmaps.add(captureView(view)); } contentBitmaps = bitmaps; - //Log.i("GLCanvas", "syncContentBitmaps "+count+" "+parent); return count; } @@ -271,12 +305,10 @@ public class GLCanvas extends GLSurfaceView implements GLSurfaceView.Renderer, E int size = Math.min(contentTextures.size(), contentBitmaps.size()); for (int i=0; i { @@ -77,4 +80,14 @@ public class GLCanvasManager extends SimpleViewManager { } return new GLCanvas(context, executorSupplier); } + + @Override + public @Nullable Map getExportedCustomDirectEventTypeConstants() { + return MapBuilder.of( + "load", + MapBuilder.of("registrationName", "onLoad"), + "progress", + MapBuilder.of("registrationName", "onProgress") + ); + } } diff --git a/android/src/main/java/com/projectseptember/RNGL/GLFBO.java b/android/src/main/java/com/projectseptember/RNGL/GLFBO.java index 006fdb51bd4f9af538f2cbb40f24f73ef6ab87c6..db48d03cff7ef98bd883b7151a62e4cfcdef41d9 100644 --- a/android/src/main/java/com/projectseptember/RNGL/GLFBO.java +++ b/android/src/main/java/com/projectseptember/RNGL/GLFBO.java @@ -2,6 +2,7 @@ package com.projectseptember.RNGL; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Executor; import static android.opengl.GLES20.*; @@ -10,9 +11,32 @@ public class GLFBO { private int handle; private int width = 0; private int height = 0; + private Executor glExecutor; + + /** + * GLFBO constructor as well as all methods must be called in GL Thread + * @param glExecutor is only required for finalize() + */ + public GLFBO (Executor glExecutor) { + this.glExecutor = glExecutor; + FBOState state = new FBOState(); + + int[] handleArr = new int[1]; + glGenFramebuffers(1, handleArr, 0); + handle = handleArr[0]; + + int numColors = 1; + + glBindFramebuffer(GL_FRAMEBUFFER, handle); + + for(int i=0; i