diff --git a/browser-app.cpp b/browser-app.cpp index f0aba74f0..509dbb0a7 100644 --- a/browser-app.cpp +++ b/browser-app.cpp @@ -117,7 +117,8 @@ void BrowserApp::OnContextCreated(CefRefPtr browser, { CefRefPtr globalObj = context->GetGlobal(); - CefRefPtr obsStudioObj = CefV8Value::CreateObject(0, 0); + CefRefPtr obsStudioObj = + CefV8Value::CreateObject(nullptr, nullptr); globalObj->SetValue("obsstudio", obsStudioObj, V8_PROPERTY_ATTRIBUTE_NONE); @@ -154,7 +155,7 @@ void BrowserApp::ExecuteJSFunction(CefRefPtr browser, CefRefPtr jsFunction = obsStudioObj->GetValue(functionName); if (jsFunction && jsFunction->IsFunction()) - jsFunction->ExecuteFunction(NULL, arguments); + jsFunction->ExecuteFunction(nullptr, arguments); context->Exit(); } @@ -310,7 +311,7 @@ bool BrowserApp::OnProcessMessageReceived(CefRefPtr browser, CefRefPtr dispatchEvent = globalObj->GetValue("dispatchEvent"); - dispatchEvent->ExecuteFunction(NULL, arguments); + dispatchEvent->ExecuteFunction(nullptr, arguments); context->Exit(); @@ -340,7 +341,7 @@ bool BrowserApp::OnProcessMessageReceived(CefRefPtr browser, args.push_back(retval); if (callback) - callback->ExecuteFunction(NULL, args); + callback->ExecuteFunction(nullptr, args); context->Exit(); diff --git a/browser-client.cpp b/browser-client.cpp index e0966bcc7..4304f357b 100644 --- a/browser-client.cpp +++ b/browser-client.cpp @@ -26,6 +26,9 @@ #include #include #include +#if defined(__APPLE__) && CHROME_VERSION_BUILD > 4430 +#include +#endif using namespace json11; @@ -61,9 +64,34 @@ CefRefPtr BrowserClient::GetAudioHandler() } #endif +#if CHROME_VERSION_BUILD >= 4638 +CefRefPtr BrowserClient::GetRequestHandler() +{ + return this; +} + +CefRefPtr BrowserClient::GetResourceRequestHandler( + CefRefPtr, CefRefPtr, + CefRefPtr request, bool, bool, const CefString &, bool &) +{ + if (request->GetHeaderByName("origin") == "null") { + return this; + } + + return nullptr; +} + +CefResourceRequestHandler::ReturnValue BrowserClient::OnBeforeResourceLoad( + CefRefPtr, CefRefPtr, CefRefPtr, + CefRefPtr) +{ + return RV_CONTINUE; +} +#endif + bool BrowserClient::OnBeforePopup(CefRefPtr, CefRefPtr, const CefString &, const CefString &, - WindowOpenDisposition, bool, + cef_window_open_disposition_t, bool, const CefPopupFeatures &, CefWindowInfo &, CefRefPtr &, CefBrowserSettings &, #if CHROME_VERSION_BUILD >= 3770 @@ -269,37 +297,59 @@ void BrowserClient::OnAcceleratedPaint(CefRefPtr, return; } - if (shared_handle != last_handle) { - obs_enter_graphics(); +#ifndef _WIN32 + if (shared_handle == last_handle) + return; +#endif - if (bs->texture) { - if (bs->extra_texture) { - gs_texture_destroy(bs->extra_texture); - bs->extra_texture = nullptr; - } - gs_texture_destroy(bs->texture); - bs->texture = nullptr; - } + obs_enter_graphics(); - bs->texture = gs_texture_open_shared( - (uint32_t)(uintptr_t)shared_handle); - if (bs->texture) { - const uint32_t cx = gs_texture_get_width(bs->texture); - const uint32_t cy = gs_texture_get_height(bs->texture); - const gs_color_format format = - gs_texture_get_color_format(bs->texture); - const gs_color_format linear_format = - gs_generalize_format(format); - if (linear_format != format) { - bs->extra_texture = gs_texture_create( - cx, cy, linear_format, 1, nullptr, 0); - } + if (bs->texture) { + if (bs->extra_texture) { + gs_texture_destroy(bs->extra_texture); + bs->extra_texture = nullptr; } +#ifdef _WIN32 + gs_texture_release_sync(bs->texture, 0); +#endif + gs_texture_destroy(bs->texture); +#ifdef _WIN32 + CloseHandle(extra_handle); +#endif + bs->texture = nullptr; + } - obs_leave_graphics(); +#if defined(__APPLE__) && CHROME_VERSION_BUILD > 4183 + bs->texture = gs_texture_create_from_iosurface( + (IOSurfaceRef)(uintptr_t)shared_handle); +#elif defined(_WIN32) && CHROME_VERSION_BUILD > 4183 + DuplicateHandle(GetCurrentProcess(), (HANDLE)(uintptr_t)shared_handle, + GetCurrentProcess(), &extra_handle, 0, false, + DUPLICATE_SAME_ACCESS); + + bs->texture = + gs_texture_open_nt_shared((uint32_t)(uintptr_t)shared_handle); + gs_texture_acquire_sync(bs->texture, 1, INFINITE); +#else + bs->texture = + gs_texture_open_shared((uint32_t)(uintptr_t)shared_handle); +#endif - last_handle = shared_handle; + if (bs->texture) { + const uint32_t cx = gs_texture_get_width(bs->texture); + const uint32_t cy = gs_texture_get_height(bs->texture); + const gs_color_format format = + gs_texture_get_color_format(bs->texture); + const gs_color_format linear_format = + gs_generalize_format(format); + if (linear_format != format) { + bs->extra_texture = gs_texture_create( + cx, cy, linear_format, 1, nullptr, 0); + } } + obs_leave_graphics(); + + last_handle = shared_handle; } #endif diff --git a/browser-client.hpp b/browser-client.hpp index fb23c83fa..89e06968c 100644 --- a/browser-client.hpp +++ b/browser-client.hpp @@ -19,6 +19,7 @@ #pragma once #include +#include #include "cef-headers.hpp" #include "browser-config.h" #include "obs-browser-source.hpp" @@ -28,6 +29,10 @@ struct BrowserSource; class BrowserClient : public CefClient, public CefDisplayHandler, public CefLifeSpanHandler, + public CefRequestHandler, +#if CHROME_VERSION_BUILD >= 4638 + public CefResourceRequestHandler, +#endif public CefContextMenuHandler, public CefRenderHandler, #if CHROME_VERSION_BUILD >= 3683 @@ -38,6 +43,7 @@ class BrowserClient : public CefClient, #ifdef SHARED_TEXTURE_SUPPORT_ENABLED #ifdef _WIN32 void *last_handle = INVALID_HANDLE_VALUE; + void *extra_handle = INVALID_HANDLE_VALUE; #elif defined(__APPLE__) void *last_handle = nullptr; #endif @@ -72,6 +78,9 @@ class BrowserClient : public CefClient, virtual CefRefPtr GetRenderHandler() override; virtual CefRefPtr GetDisplayHandler() override; virtual CefRefPtr GetLifeSpanHandler() override; +#if CHROME_VERSION_BUILD >= 4638 + virtual CefRefPtr GetRequestHandler() override; +#endif virtual CefRefPtr GetContextMenuHandler() override; #if CHROME_VERSION_BUILD >= 3683 @@ -102,7 +111,7 @@ class BrowserClient : public CefClient, OnBeforePopup(CefRefPtr browser, CefRefPtr frame, const CefString &target_url, const CefString &target_frame_name, - WindowOpenDisposition target_disposition, + cef_window_open_disposition_t target_disposition, bool user_gesture, const CefPopupFeatures &popupFeatures, CefWindowInfo &windowInfo, CefRefPtr &client, CefBrowserSettings &settings, @@ -110,6 +119,21 @@ class BrowserClient : public CefClient, CefRefPtr &extra_info, #endif bool *no_javascript_access) override; +#if CHROME_VERSION_BUILD >= 4638 + /* CefRequestHandler */ + virtual CefRefPtr GetResourceRequestHandler( + CefRefPtr browser, CefRefPtr frame, + CefRefPtr request, bool is_navigation, + bool is_download, const CefString &request_initiator, + bool &disable_default_handling) override; + + /* CefResourceRequestHandler */ + virtual CefResourceRequestHandler::ReturnValue + OnBeforeResourceLoad(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr request, + CefRefPtr callback) override; +#endif /* CefContextMenuHandler */ virtual void diff --git a/browser-scheme.cpp b/browser-scheme.cpp index 7991cfe9f..3a2862c27 100644 --- a/browser-scheme.cpp +++ b/browser-scheme.cpp @@ -55,7 +55,11 @@ BrowserSchemeHandlerFactory::Create(CefRefPtr browser, CefStreamReader::CreateForFile(path); #endif - return new CefStreamResourceHandler(CefGetMimeType(fileExtension), - stream); + if (stream) { + return new CefStreamResourceHandler( + CefGetMimeType(fileExtension), stream); + } else { + return nullptr; + } } #endif diff --git a/browser-scheme.hpp b/browser-scheme.hpp index 62b4d75e0..dd28614f6 100644 --- a/browser-scheme.hpp +++ b/browser-scheme.hpp @@ -22,7 +22,7 @@ #include #include -#if CHROME_VERSION_BUILD >= 3440 +#if CHROME_VERSION_BUILD >= 3440 && CHROME_VERSION_BUILD < 4638 #define ENABLE_LOCAL_FILE_URL_SCHEME 1 #else #define ENABLE_LOCAL_FILE_URL_SCHEME 0 diff --git a/cef-headers.hpp b/cef-headers.hpp index fdd97ddff..7a3121472 100644 --- a/cef-headers.hpp +++ b/cef-headers.hpp @@ -47,8 +47,11 @@ #endif #if CHROME_VERSION_BUILD >= 3770 -#define SendBrowserProcessMessage(browser, pid, msg) \ - browser->GetMainFrame()->SendProcessMessage(pid, msg); +#define SendBrowserProcessMessage(browser, pid, msg) \ + CefRefPtr mainFrame = browser->GetMainFrame(); \ + if (mainFrame) { \ + mainFrame->SendProcessMessage(pid, msg); \ + } #else #define SendBrowserProcessMessage(browser, pid, msg) \ browser->SendProcessMessage(pid, msg); diff --git a/obs-browser-source.cpp b/obs-browser-source.cpp index 07d0b5807..72349cca8 100644 --- a/obs-browser-source.cpp +++ b/obs-browser-source.cpp @@ -148,8 +148,13 @@ bool BrowserSource::CreateBrowser() #if CHROME_VERSION_BUILD < 3071 windowInfo.transparent_painting_enabled = true; #endif +#if CHROME_VERSION_BUILD < 4430 windowInfo.width = width; windowInfo.height = height; +#else + windowInfo.bounds.width = width; + windowInfo.bounds.height = height; +#endif windowInfo.windowless_rendering_enabled = true; #ifdef SHARED_TEXTURE_SUPPORT_ENABLED @@ -159,7 +164,7 @@ bool BrowserSource::CreateBrowser() CefBrowserSettings cefBrowserSettings; #ifdef SHARED_TEXTURE_SUPPORT_ENABLED -#ifdef _WIN32 +#ifdef BROWSER_EXTERNAL_BEGIN_FRAME_ENABLED if (!fps_custom) { windowInfo.external_begin_frame_enabled = true; cefBrowserSettings.windowless_frame_rate = 0; @@ -167,9 +172,11 @@ bool BrowserSource::CreateBrowser() cefBrowserSettings.windowless_frame_rate = fps; } #else - double video_fps = obs_get_active_fps(); + struct obs_video_info ovi; + obs_get_video_info(&ovi); + canvas_fps = (double)ovi.fps_num / (double)ovi.fps_den; cefBrowserSettings.windowless_frame_rate = - (fps_custom) ? fps : video_fps; + (fps_custom) ? fps : canvas_fps; #endif #else cefBrowserSettings.windowless_frame_rate = fps; @@ -178,14 +185,13 @@ bool BrowserSource::CreateBrowser() cefBrowserSettings.default_font_size = 16; cefBrowserSettings.default_fixed_font_size = 16; -#if ENABLE_LOCAL_FILE_URL_SCHEME +#if ENABLE_LOCAL_FILE_URL_SCHEME && CHROME_VERSION_BUILD < 4430 if (is_local) { /* Disable web security for file:// URLs to allow * local content access to remote APIs */ cefBrowserSettings.web_security = STATE_DISABLED; } #endif - cefBrowser = CefBrowserHost::CreateBrowserSync( windowInfo, browserClient, url, cefBrowserSettings, #if CHROME_VERSION_BUILD >= 3770 @@ -299,7 +305,11 @@ void BrowserSource::SendFocus(bool focus) { ExecuteOnBrowser( [=](CefRefPtr cefBrowser) { +#if CHROME_VERSION_BUILD < 4430 cefBrowser->GetHost()->SendFocusEvent(focus); +#else + cefBrowser->GetHost()->SetFocus(focus); +#endif }, true); } @@ -379,7 +389,8 @@ void BrowserSource::SetShowing(bool showing) true); Json json = Json::object{{"visible", showing}}; DispatchJSEvent("obsSourceVisibleChanged", json.dump(), this); -#if defined(_WIN32) && defined(SHARED_TEXTURE_SUPPORT_ENABLED) +#if defined(BROWSER_EXTERNAL_BEGIN_FRAME_ENABLED) && \ + defined(SHARED_TEXTURE_SUPPORT_ENABLED) if (showing && !fps_custom) { reset_frame = false; } @@ -414,7 +425,7 @@ void BrowserSource::Refresh() true); } #ifdef SHARED_TEXTURE_SUPPORT_ENABLED -#ifdef _WIN32 +#ifdef BROWSER_EXTERNAL_BEGIN_FRAME_ENABLED inline void BrowserSource::SignalBeginFrame() { if (reset_frame) { @@ -539,9 +550,21 @@ void BrowserSource::Tick() { if (create_browser && CreateBrowser()) create_browser = false; -#if defined(_WIN32) && defined(SHARED_TEXTURE_SUPPORT_ENABLED) +#if defined(SHARED_TEXTURE_SUPPORT_ENABLED) +#if defined(BROWSER_EXTERNAL_BEGIN_FRAME_ENABLED) if (!fps_custom) reset_frame = true; +#else + struct obs_video_info ovi; + obs_get_video_info(&ovi); + double video_fps = (double)ovi.fps_num / (double)ovi.fps_den; + + if (!fps_custom) { + if (!!cefBrowser && canvas_fps != video_fps) { + Update(); + } + } +#endif #endif } @@ -600,7 +623,8 @@ void BrowserSource::Render() gs_enable_framebuffer_srgb(previous); } -#if defined(_WIN32) && defined(SHARED_TEXTURE_SUPPORT_ENABLED) +#if defined(BROWSER_EXTERNAL_BEGIN_FRAME_ENABLED) && \ + defined(SHARED_TEXTURE_SUPPORT_ENABLED) SignalBeginFrame(); #elif USE_QT_LOOP ProcessCef(); diff --git a/obs-browser-source.hpp b/obs-browser-source.hpp index 3ab2a76c9..ec79e2344 100644 --- a/obs-browser-source.hpp +++ b/obs-browser-source.hpp @@ -69,13 +69,15 @@ struct BrowserSource { int height = 0; bool fps_custom = false; int fps = 0; + double canvas_fps = 0; bool restart = false; bool shutdown_on_invisible = false; bool is_local = false; bool first_update = true; bool reroute_audio = true; ControlLevel webpage_control_level = DEFAULT_CONTROL_LEVEL; -#if defined(_WIN32) && defined(SHARED_TEXTURE_SUPPORT_ENABLED) +#if defined(BROWSER_EXTERNAL_BEGIN_FRAME_ENABLED) && \ + defined(SHARED_TEXTURE_SUPPORT_ENABLED) bool reset_frame = false; #endif bool is_showing = false; @@ -129,7 +131,8 @@ struct BrowserSource { void SetActive(bool active); void Refresh(); -#if defined(_WIN32) && defined(SHARED_TEXTURE_SUPPORT_ENABLED) +#if defined(BROWSER_EXTERNAL_BEGIN_FRAME_ENABLED) && \ + defined(SHARED_TEXTURE_SUPPORT_ENABLED) inline void SignalBeginFrame(); #endif }; diff --git a/panel/browser-panel.cpp b/panel/browser-panel.cpp index ee5a7c90d..2fb829bed 100644 --- a/panel/browser-panel.cpp +++ b/panel/browser-panel.cpp @@ -195,10 +195,12 @@ void QCefWidgetInternal::closeBrowser() reinterpret_cast( client.get()); + if (bc) { + bc->widget = nullptr; + } + cefBrowser->GetHost()->WasHidden(true); cefBrowser->GetHost()->CloseBrowser(true); - - bc->widget = nullptr; }; /* So you're probably wondering what's going on here. If you @@ -231,6 +233,7 @@ void QCefWidgetInternal::closeBrowser() #endif destroyBrowser(browser); + browser = nullptr; cefBrowser = nullptr; } } @@ -332,7 +335,10 @@ void QCefWidgetInternal::Init() #ifdef __APPLE__ QSize size = this->size(); +#endif +#if CHROME_VERSION_BUILD < 4430 +#ifdef __APPLE__ windowInfo.SetAsChild((CefWindowHandle)handle, 0, 0, size.width(), size.height()); #else @@ -343,6 +349,11 @@ void QCefWidgetInternal::Init() #endif windowInfo.SetAsChild((CefWindowHandle)handle, rc); #endif +#else + windowInfo.SetAsChild((CefWindowHandle)handle, + CefRect(0, 0, size.width(), + size.height())); +#endif CefRefPtr browserClient = new QCefBrowserClient(this, script, @@ -416,6 +427,9 @@ void QCefWidgetInternal::Resize() changes.height = size.height(); XConfigureWindow(xDisplay, (Window)handle, CWX | CWY | CWHeight | CWWidth, &changes); +#if CHROME_VERSION_BUILD >= 4638 + XSync(xDisplay, false); +#endif #endif });