浏览代码

Merge pull request #38629 from Technohacker/windows-dwm-ppt-3.2

Use DwmEnableBlurBehindWindow for Windows Per Pixel Transparency
Rémi Verschelde 5 年之前
父节点
当前提交
5d26836c78

+ 0 - 4
core/os/os.h

@@ -247,10 +247,6 @@ public:
 	virtual bool get_window_per_pixel_transparency_enabled() const { return false; }
 	virtual void set_window_per_pixel_transparency_enabled(bool p_enabled) {}
 
-	virtual uint8_t *get_layered_buffer_data() { return NULL; }
-	virtual Size2 get_layered_buffer_size() { return Size2(0, 0); }
-	virtual void swap_layered_buffer() {}
-
 	virtual void set_ime_active(const bool p_active) {}
 	virtual void set_ime_position(const Point2 &p_pos) {}
 	virtual Point2 get_ime_selection() const { return Point2(); }

+ 1 - 12
drivers/gles2/rasterizer_gles2.cpp

@@ -448,18 +448,7 @@ void RasterizerGLES2::output_lens_distorted_to_screen(RID p_render_target, const
 void RasterizerGLES2::end_frame(bool p_swap_buffers) {
 
 	if (OS::get_singleton()->is_layered_allowed()) {
-		if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
-#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED)
-			Size2 wndsize = OS::get_singleton()->get_layered_buffer_size();
-			uint8_t *data = OS::get_singleton()->get_layered_buffer_data();
-			if (data) {
-				glReadPixels(0, 0, wndsize.x, wndsize.y, GL_BGRA, GL_UNSIGNED_BYTE, data);
-				OS::get_singleton()->swap_layered_buffer();
-
-				return;
-			}
-#endif
-		} else {
+		if (!OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
 			//clear alpha
 			glColorMask(false, false, false, true);
 			glClearColor(0, 0, 0, 1);

+ 1 - 12
drivers/gles3/rasterizer_gles3.cpp

@@ -372,18 +372,7 @@ void RasterizerGLES3::output_lens_distorted_to_screen(RID p_render_target, const
 void RasterizerGLES3::end_frame(bool p_swap_buffers) {
 
 	if (OS::get_singleton()->is_layered_allowed()) {
-		if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
-#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED)
-			Size2 wndsize = OS::get_singleton()->get_layered_buffer_size();
-			uint8_t *data = OS::get_singleton()->get_layered_buffer_data();
-			if (data) {
-				glReadPixels(0, 0, wndsize.x, wndsize.y, GL_BGRA, GL_UNSIGNED_BYTE, data);
-				OS::get_singleton()->swap_layered_buffer();
-
-				return;
-			}
-#endif
-		} else {
+		if (!OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
 			//clear alpha
 			glColorMask(false, false, false, true);
 			glClearColor(0, 0, 0, 1);

+ 0 - 4
platform/osx/os_osx.mm

@@ -2661,7 +2661,6 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) {
 	if (!is_layered_allowed()) return;
 	if (layered_window != p_enabled) {
 		if (p_enabled) {
-			set_borderless_window(true);
 			GLint opacity = 0;
 			[window_object setBackgroundColor:[NSColor clearColor]];
 			[window_object setOpaque:NO];
@@ -2691,9 +2690,6 @@ void OS_OSX::set_borderless_window(bool p_borderless) {
 	if (p_borderless) {
 		[window_object setStyleMask:NSWindowStyleMaskBorderless];
 	} else {
-		if (layered_window)
-			set_window_per_pixel_transparency_enabled(false);
-
 		[window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (resizable ? NSWindowStyleMaskResizable : 0)];
 
 		// Force update of the window styles

+ 12 - 91
platform/windows/os_windows.cpp

@@ -974,27 +974,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 				maximized = false;
 				minimized = false;
 			}
-			if (is_layered_allowed() && layered_window) {
-				DeleteObject(hBitmap);
-
-				RECT r;
-				GetWindowRect(hWnd, &r);
-				dib_size = Size2i(r.right - r.left, r.bottom - r.top);
-
-				BITMAPINFO bmi;
-				ZeroMemory(&bmi, sizeof(BITMAPINFO));
-				bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-				bmi.bmiHeader.biWidth = dib_size.x;
-				bmi.bmiHeader.biHeight = dib_size.y;
-				bmi.bmiHeader.biPlanes = 1;
-				bmi.bmiHeader.biBitCount = 32;
-				bmi.bmiHeader.biCompression = BI_RGB;
-				bmi.bmiHeader.biSizeImage = dib_size.x * dib_size.y * 4;
-				hBitmap = CreateDIBSection(hDC_dib, &bmi, DIB_RGB_COLORS, (void **)&dib_data, NULL, 0x0);
-				SelectObject(hDC_dib, hBitmap);
-
-				ZeroMemory(dib_data, dib_size.x * dib_size.y * 4);
-			}
 			//return 0;								// Jump Back
 		} break;
 
@@ -2231,76 +2210,27 @@ void OS_Windows::set_window_per_pixel_transparency_enabled(bool p_enabled) {
 	if (!is_layered_allowed()) return;
 	if (layered_window != p_enabled) {
 		if (p_enabled) {
-			set_borderless_window(true);
 			//enable per-pixel alpha
-			hDC_dib = CreateCompatibleDC(GetDC(hWnd));
-
-			SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
-
-			RECT r;
-			GetWindowRect(hWnd, &r);
-			dib_size = Size2(r.right - r.left, r.bottom - r.top);
 
-			BITMAPINFO bmi;
-			ZeroMemory(&bmi, sizeof(BITMAPINFO));
-			bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
-			bmi.bmiHeader.biWidth = dib_size.x;
-			bmi.bmiHeader.biHeight = dib_size.y;
-			bmi.bmiHeader.biPlanes = 1;
-			bmi.bmiHeader.biBitCount = 32;
-			bmi.bmiHeader.biCompression = BI_RGB;
-			bmi.bmiHeader.biSizeImage = dib_size.x * dib_size.y * 4;
-			hBitmap = CreateDIBSection(hDC_dib, &bmi, DIB_RGB_COLORS, (void **)&dib_data, NULL, 0x0);
-			SelectObject(hDC_dib, hBitmap);
-
-			ZeroMemory(dib_data, dib_size.x * dib_size.y * 4);
+			DWM_BLURBEHIND bb = { 0 };
+			HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
+			bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
+			bb.hRgnBlur = hRgn;
+			bb.fEnable = TRUE;
+			DwmEnableBlurBehindWindow(hWnd, &bb);
 
 			layered_window = true;
 		} else {
 			//disable per-pixel alpha
 			layered_window = false;
 
-			SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
-
-			//cleanup
-			DeleteObject(hBitmap);
-			DeleteDC(hDC_dib);
-		}
-	}
-}
-
-uint8_t *OS_Windows::get_layered_buffer_data() {
-
-	return (is_layered_allowed() && layered_window) ? dib_data : NULL;
-}
-
-Size2 OS_Windows::get_layered_buffer_size() {
-
-	return (is_layered_allowed() && layered_window) ? dib_size : Size2();
-}
-
-void OS_Windows::swap_layered_buffer() {
-
-	if (is_layered_allowed() && layered_window) {
-
-		//premultiply alpha
-		for (int y = 0; y < dib_size.y; y++) {
-			for (int x = 0; x < dib_size.x; x++) {
-				float alpha = (float)dib_data[y * (int)dib_size.x * 4 + x * 4 + 3] / (float)0xFF;
-				dib_data[y * (int)dib_size.x * 4 + x * 4 + 0] *= alpha;
-				dib_data[y * (int)dib_size.x * 4 + x * 4 + 1] *= alpha;
-				dib_data[y * (int)dib_size.x * 4 + x * 4 + 2] *= alpha;
-			}
+			DWM_BLURBEHIND bb = { 0 };
+			HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
+			bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
+			bb.hRgnBlur = hRgn;
+			bb.fEnable = FALSE;
+			DwmEnableBlurBehindWindow(hWnd, &bb);
 		}
-		//swap layered window buffer
-		POINT ptSrc = { 0, 0 };
-		SIZE sizeWnd = { (long)dib_size.x, (long)dib_size.y };
-		BLENDFUNCTION bf;
-		bf.BlendOp = AC_SRC_OVER;
-		bf.BlendFlags = 0;
-		bf.AlphaFormat = AC_SRC_ALPHA;
-		bf.SourceConstantAlpha = 0xFF;
-		UpdateLayeredWindow(hWnd, NULL, NULL, &sizeWnd, hDC_dib, &ptSrc, 0, &bf, ULW_ALPHA);
 	}
 }
 
@@ -2308,9 +2238,6 @@ void OS_Windows::set_borderless_window(bool p_borderless) {
 	if (video_mode.borderless_window == p_borderless)
 		return;
 
-	if (!p_borderless && layered_window)
-		set_window_per_pixel_transparency_enabled(false);
-
 	video_mode.borderless_window = p_borderless;
 
 	preserve_window_size = true;
@@ -3477,7 +3404,6 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
 	drop_events = false;
 	key_event_pos = 0;
 	layered_window = false;
-	hBitmap = NULL;
 	force_quit = false;
 	alt_mem = false;
 	gr_mem = false;
@@ -3534,11 +3460,6 @@ OS_Windows::~OS_Windows() {
 		wintab_WTClose(wtctx);
 		wtctx = 0;
 	}
-
-	if (is_layered_allowed() && layered_window) {
-		DeleteObject(hBitmap);
-		DeleteDC(hDC_dib);
-	}
 #ifdef STDOUT_FILE
 	fclose(stdo);
 #endif

+ 1 - 8
platform/windows/os_windows.h

@@ -49,6 +49,7 @@
 #include "drivers/xaudio2/audio_driver_xaudio2.h"
 #endif
 
+#include <dwmapi.h>
 #include <fcntl.h>
 #include <io.h>
 #include <stdio.h>
@@ -297,10 +298,6 @@ class OS_Windows : public OS {
 	HWND hWnd;
 	Point2 last_pos;
 
-	HBITMAP hBitmap; //DIB section for layered window
-	uint8_t *dib_data;
-	Size2 dib_size;
-	HDC hDC_dib;
 	bool layered_window;
 
 	uint32_t move_timer_id;
@@ -452,10 +449,6 @@ public:
 	virtual bool get_window_per_pixel_transparency_enabled() const;
 	virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
 
-	virtual uint8_t *get_layered_buffer_data();
-	virtual Size2 get_layered_buffer_size();
-	virtual void swap_layered_buffer();
-
 	virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
 	virtual Error close_dynamic_library(void *p_library_handle);
 	virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);

+ 0 - 4
platform/x11/os_x11.cpp

@@ -964,7 +964,6 @@ void OS_X11::set_window_per_pixel_transparency_enabled(bool p_enabled) {
 	if (!is_layered_allowed()) return;
 	if (layered_window != p_enabled) {
 		if (p_enabled) {
-			set_borderless_window(true);
 			layered_window = true;
 		} else {
 			layered_window = false;
@@ -1683,9 +1682,6 @@ void OS_X11::set_borderless_window(bool p_borderless) {
 	if (get_borderless_window() == p_borderless)
 		return;
 
-	if (!p_borderless && layered_window)
-		set_window_per_pixel_transparency_enabled(false);
-
 	current_videomode.borderless_window = p_borderless;
 
 	Hints hints;