diff --git a/dist/unity-webview-nofragment.unitypackage b/dist/unity-webview-nofragment.unitypackage index 20b26952..8362607c 100644 Binary files a/dist/unity-webview-nofragment.unitypackage and b/dist/unity-webview-nofragment.unitypackage differ diff --git a/dist/unity-webview-nofragment.zip b/dist/unity-webview-nofragment.zip index 73bed6c5..0542b81f 100644 Binary files a/dist/unity-webview-nofragment.zip and b/dist/unity-webview-nofragment.zip differ diff --git a/dist/unity-webview.unitypackage b/dist/unity-webview.unitypackage index 84d02649..102e1817 100644 Binary files a/dist/unity-webview.unitypackage and b/dist/unity-webview.unitypackage differ diff --git a/dist/unity-webview.zip b/dist/unity-webview.zip index c8b0762d..1585209c 100644 Binary files a/dist/unity-webview.zip and b/dist/unity-webview.zip differ diff --git a/plugins/Android/src/net/gree/unitywebview/CWebViewPlugin.java b/plugins/Android/src/net/gree/unitywebview/CWebViewPlugin.java index 404b82a7..72512723 100644 --- a/plugins/Android/src/net/gree/unitywebview/CWebViewPlugin.java +++ b/plugins/Android/src/net/gree/unitywebview/CWebViewPlugin.java @@ -35,6 +35,7 @@ import android.os.Environment; import android.provider.MediaStore; import android.util.Log; +import android.util.Pair; import android.view.Gravity; import android.view.View; import android.view.ViewGroup.LayoutParams; @@ -63,6 +64,7 @@ import java.net.URL; import java.net.URLEncoder; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Hashtable; @@ -120,6 +122,8 @@ public class CWebViewPlugin extends Fragment { private static long instanceCount; private long mInstanceId; + private boolean mPaused; + private List> mTransactions; private String mBasicAuthUserName; private String mBasicAuthPassword; @@ -206,19 +210,26 @@ public boolean IsInitialized() { public void Init(final String gameObject, final boolean transparent, final String ua) { final CWebViewPlugin self = this; final Activity a = UnityPlayer.currentActivity; + instanceCount++; + mInstanceId = instanceCount; a.runOnUiThread(new Runnable() {public void run() { if (mWebView != null) { return; } setRetainInstance(true); - instanceCount++; - mInstanceId = instanceCount; - a - .getFragmentManager() - .beginTransaction() - .add(0, self, "CWebViewPlugin" + mInstanceId) - .commit(); + if (mPaused) { + if (mTransactions == null) { + mTransactions = new ArrayList>(); + } + mTransactions.add(Pair.create("add", self)); + } else { + a + .getFragmentManager() + .beginTransaction() + .add(0, self, "CWebViewPlugin" + mInstanceId) + .commit(); + } mAlertDialogEnabled = true; mCustomHeaders = new Hashtable(); @@ -618,11 +629,19 @@ public void Destroy() { mWebView.destroy(); mWebView = null; - a - .getFragmentManager() - .beginTransaction() - .remove(self) - .commit(); + if (mPaused) { + if (mTransactions == null) { + mTransactions = new ArrayList>(); + } + mTransactions.add(Pair.create("remove", self)); + } else { + a + .getFragmentManager() + .beginTransaction() + .remove(self) + .commit(); + } + }}); } @@ -743,13 +762,38 @@ public void SetAlertDialogEnabled(final boolean enabled) { } // cf. https://stackoverflow.com/questions/31788748/webview-youtube-videos-playing-in-background-on-rotation-and-minimise/31789193#31789193 - public void OnApplicationPause(final boolean paused) { + public void OnApplicationPause(boolean paused) { + mPaused = paused; final Activity a = UnityPlayer.currentActivity; a.runOnUiThread(new Runnable() {public void run() { + if (!mPaused) { + if (mTransactions != null) { + for (Pair pair : mTransactions) { + CWebViewPlugin self = pair.second; + switch (pair.first) { + case "add": + a + .getFragmentManager() + .beginTransaction() + .add(0, self, "CWebViewPlugin" + mInstanceId) + .commit(); + break; + case "remove": + a + .getFragmentManager() + .beginTransaction() + .remove(self) + .commit(); + break; + } + } + mTransactions.clear(); + } + } if (mWebView == null) { return; } - if (paused) { + if (mPaused) { mWebView.onPause(); if (mWebView.getVisibility() == View.VISIBLE) { // cf. https://qiita.com/nbhd/items/d31711faa8852143f3a4 diff --git a/plugins/Mac/Sources/WebView.m b/plugins/Mac/Sources/WebView.m index 66d24aac..937345f1 100644 --- a/plugins/Mac/Sources/WebView.m +++ b/plugins/Mac/Sources/WebView.m @@ -23,17 +23,16 @@ #import #import #import -#import #import static BOOL inEditor; +static BOOL useMetal; @interface CWebViewPlugin : NSObject { WebView *webView; NSString *gameObject; NSBitmapImageRep *bitmap; - int textureId; BOOL needsDisplay; NSMutableDictionary *customRequestHeader; NSMutableArray *messages; @@ -364,10 +363,9 @@ - (void)update:(int)x y:(int)y deltaY:(float)deltaY buttonDown:(BOOL)buttonDown if (bitmap == nil) { bitmap = [webView bitmapImageRepForCachingDisplayInRect:webView.frame]; } - memset([bitmap bitmapData], 0, [bitmap bytesPerRow] * [bitmap pixelsHigh]); [webView cacheDisplayInRect:webView.frame toBitmapImageRep:bitmap]; + needsDisplay = true; } - needsDisplay = refreshBitmap; } } @@ -385,41 +383,46 @@ - (int)bitmapHigh } } -- (void)setTextureId:(int)tId +- (void)render:(void *)textureBuffer { @synchronized(self) { - textureId = tId; - } -} - -- (void)render -{ - @synchronized(self) { - if (webView == nil || !needsDisplay || bitmap == nil) { + if (webView == nil) return; + if (!needsDisplay) + return; + if (bitmap == nil) + return; + int w = (int)[bitmap pixelsWide]; + int h = (int)[bitmap pixelsHigh]; + int p = (int)[bitmap samplesPerPixel]; + int r = (int)[bitmap bytesPerRow]; + uint8_t *s0 = (uint8_t *)[bitmap bitmapData]; + uint32_t *d0 = (uint32_t *)textureBuffer; + if (p == 3) { + for (int y = 0; y < h; y++) { + uint8_t *s = s0 + y * r; + uint32_t *d = d0 + y * w; + for (int x = 0; x < w; x++) { + uint32_t r = *s++; + uint32_t g = *s++; + uint32_t b = *s++; + *d++ = (0xff << 24) | (b << 16) | (g << 8) | r; + } + } + } else if (p == 4) { + for (int y = 0; y < h; y++) { + uint8_t *s = s0 + y * r; + uint32_t *d = d0 + y * w; + for (int x = 0; x < w; x++) { + uint32_t r = *s++; + uint32_t g = *s++; + uint32_t b = *s++; + uint32_t a = *s++; + *d++ = (a << 24) | (b << 16) | (g << 8) | r; + } + } } - int samplesPerPixel = (int)[bitmap samplesPerPixel]; - int rowLength = 0; - int unpackAlign = 0; - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowLength); - glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackAlign); - glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)[bitmap bytesPerRow] / samplesPerPixel); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glBindTexture(GL_TEXTURE_2D, textureId); - if (![bitmap isPlanar] && (samplesPerPixel == 3 || samplesPerPixel == 4)) { - glTexSubImage2D( - GL_TEXTURE_2D, - 0, - 0, - 0, - (GLsizei)[bitmap pixelsWide], - (GLsizei)[bitmap pixelsHigh], - samplesPerPixel == 4 ? GL_RGBA : GL_RGB, - GL_UNSIGNED_BYTE, - [bitmap bitmapData]); - } - glPixelStorei(GL_UNPACK_ROW_LENGTH, rowLength); - glPixelStorei(GL_UNPACK_ALIGNMENT, unpackAlign); + needsDisplay = false; } } @@ -461,13 +464,12 @@ - (const char *)getCustomRequestHeaderValue:(const char *)headerKey @end -typedef void (*UnityRenderEventFunc)(int eventId); #ifdef __cplusplus extern "C" { #endif const char *_CWebViewPlugin_GetAppPath(void); void *_CWebViewPlugin_Init( - const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor); + const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor, BOOL usemetal); void _CWebViewPlugin_Destroy(void *instance); void _CWebViewPlugin_SetRect(void *instance, int width, int height); void _CWebViewPlugin_SetVisibility(void *instance, BOOL visibility); @@ -485,10 +487,7 @@ void _CWebViewPlugin_Update(void *instance, int x, int y, float deltaY, BOOL keyPress, unsigned char keyCode, const char *keyChars, BOOL refreshBitmap); int _CWebViewPlugin_BitmapWidth(void *instance); int _CWebViewPlugin_BitmapHeight(void *instance); - void _CWebViewPlugin_SetTextureId(void *instance, int textureId); - void _CWebViewPlugin_SetCurrentInstance(void *instance); - void UnityRenderEvent(int eventId); - UnityRenderEventFunc GetRenderEventFunc(void); + void _CWebViewPlugin_Render(void *instance, void *textureBuffer); void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue); void _CWebViewPlugin_RemoveCustomHeader(void *instance, const char *headerKey); void _CWebViewPlugin_ClearCustomHeader(void *instance); @@ -509,12 +508,13 @@ void _CWebViewPlugin_Update(void *instance, int x, int y, float deltaY, static NSMutableSet *pool; void *_CWebViewPlugin_Init( - const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor) + const char *gameObject, BOOL transparent, int width, int height, const char *ua, BOOL ineditor, BOOL usemetal) { if (pool == 0) { pool = [[NSMutableSet alloc] init]; } inEditor = ineditor; + useMetal = usemetal; CWebViewPlugin *webViewPlugin = [[CWebViewPlugin alloc] initWithGameObject:gameObject transparent:transparent width:width height:height ua:ua]; [pool addObject:webViewPlugin]; return (__bridge_retained void *)webViewPlugin; @@ -522,7 +522,6 @@ void _CWebViewPlugin_Update(void *instance, int x, int y, float deltaY, void _CWebViewPlugin_Destroy(void *instance) { - _CWebViewPlugin_SetCurrentInstance(NULL); CWebViewPlugin *webViewPlugin = (__bridge_transfer CWebViewPlugin *)instance; [pool removeObject:webViewPlugin]; [webViewPlugin dispose]; @@ -617,34 +616,10 @@ int _CWebViewPlugin_BitmapHeight(void *instance) return [webViewPlugin bitmapHigh]; } -void _CWebViewPlugin_SetTextureId(void *instance, int textureId) +void _CWebViewPlugin_Render(void *instance, void *textureBuffer) { CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance; - [webViewPlugin setTextureId:textureId]; -} - -static void *_instance; - -void _CWebViewPlugin_SetCurrentInstance(void *instance) -{ - _instance = instance; -} - -void UnityRenderEvent(int eventId) -{ - if (_instance == nil) { - return; - } - CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)_instance; - _instance = nil; - if ([pool containsObject:webViewPlugin]) { - [webViewPlugin render]; - } -} - -UnityRenderEventFunc GetRenderEventFunc(void) -{ - return UnityRenderEvent; + [webViewPlugin render:textureBuffer]; } void _CWebViewPlugin_AddCustomHeader(void *instance, const char *headerKey, const char *headerValue) diff --git a/plugins/Mac/Sources/WebViewSeparated.m b/plugins/Mac/Sources/WebViewSeparated.m index 94abc035..92c37653 100644 --- a/plugins/Mac/Sources/WebViewSeparated.m +++ b/plugins/Mac/Sources/WebViewSeparated.m @@ -23,10 +23,10 @@ #import #import #import -#import #import static BOOL inEditor; +static BOOL useMetal; @interface CWebViewPlugin : NSObject { @@ -35,7 +35,6 @@ @interface CWebViewPlugin : NSObject; @@ -65,6 +66,7 @@ public class WebViewObject : MonoBehaviour IntPtr webView; Rect rect; Texture2D texture; + byte[] textureDataBuffer; string inputString; bool hasFocus; #elif UNITY_IPHONE @@ -158,7 +160,7 @@ public bool IsKeyboardVisible private static extern string _CWebViewPlugin_GetAppPath(); [DllImport("WebViewSeparated")] private static extern IntPtr _CWebViewPlugin_Init( - string gameObject, bool transparent, int width, int height, string ua, bool ineditor); + string gameObject, bool transparent, int width, int height, string ua, bool ineditor, bool usemetal); [DllImport("WebViewSeparated")] private static extern int _CWebViewPlugin_Destroy(IntPtr instance); [DllImport("WebViewSeparated")] @@ -204,11 +206,7 @@ private static extern void _CWebViewPlugin_Update(IntPtr instance, [DllImport("WebViewSeparated")] private static extern int _CWebViewPlugin_BitmapHeight(IntPtr instance); [DllImport("WebViewSeparated")] - private static extern void _CWebViewPlugin_SetTextureId(IntPtr instance, int textureId); - [DllImport("WebViewSeparated")] - private static extern void _CWebViewPlugin_SetCurrentInstance(IntPtr instance); - [DllImport("WebViewSeparated")] - private static extern IntPtr GetRenderEventFunc(); + private static extern void _CWebViewPlugin_Render(IntPtr instance, IntPtr textureBuffer); [DllImport("WebViewSeparated")] private static extern void _CWebViewPlugin_AddCustomHeader(IntPtr instance, string headerKey, string headerValue); [DllImport("WebViewSeparated")] @@ -224,7 +222,7 @@ private static extern void _CWebViewPlugin_Update(IntPtr instance, private static extern string _CWebViewPlugin_GetAppPath(); [DllImport("WebView")] private static extern IntPtr _CWebViewPlugin_Init( - string gameObject, bool transparent, int width, int height, string ua, bool ineditor); + string gameObject, bool transparent, int width, int height, string ua, bool ineditor, bool usemetal); [DllImport("WebView")] private static extern int _CWebViewPlugin_Destroy(IntPtr instance); [DllImport("WebView")] @@ -270,11 +268,7 @@ private static extern void _CWebViewPlugin_Update(IntPtr instance, [DllImport("WebView")] private static extern int _CWebViewPlugin_BitmapHeight(IntPtr instance); [DllImport("WebView")] - private static extern void _CWebViewPlugin_SetTextureId(IntPtr instance, int textureId); - [DllImport("WebView")] - private static extern void _CWebViewPlugin_SetCurrentInstance(IntPtr instance); - [DllImport("WebView")] - private static extern IntPtr GetRenderEventFunc(); + private static extern void _CWebViewPlugin_Render(IntPtr instance, IntPtr textureBuffer); [DllImport("WebView")] private static extern void _CWebViewPlugin_AddCustomHeader(IntPtr instance, string headerKey, string headerValue); [DllImport("WebView")] @@ -416,7 +410,8 @@ public void Init( Screen.width, Screen.height, ua, - Application.platform == RuntimePlatform.OSXEditor); + Application.platform == RuntimePlatform.OSXEditor, + SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal); // define pseudo requestAnimationFrame. EvaluateJS(@"(function() { var vsync = 1000 / 60; @@ -1071,15 +1066,14 @@ void OnGUI() texture = new Texture2D(w, h, TextureFormat.RGBA32, false, true); texture.filterMode = FilterMode.Bilinear; texture.wrapMode = TextureWrapMode.Clamp; + textureDataBuffer = new byte[w * h * 4]; } } - _CWebViewPlugin_SetTextureId(webView, (int)texture.GetNativeTexturePtr()); - _CWebViewPlugin_SetCurrentInstance(webView); -#if UNITY_4_6 || UNITY_5_0 || UNITY_5_1 - GL.IssuePluginEvent(-1); -#else - GL.IssuePluginEvent(GetRenderEventFunc(), -1); -#endif + var gch = GCHandle.Alloc(textureDataBuffer, GCHandleType.Pinned); + _CWebViewPlugin_Render(webView, gch.AddrOfPinnedObject()); + gch.Free(); + texture.LoadRawTextureData(textureDataBuffer); + texture.Apply(); } if (texture != null) { Matrix4x4 m = GUI.matrix;