Skip to content

Commit

Permalink
Transparency support for D3D swap chain
Browse files Browse the repository at this point in the history
  • Loading branch information
MatkovIvan committed Dec 5, 2023
1 parent cacfcb2 commit bdf8985
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 27 deletions.
45 changes: 31 additions & 14 deletions skiko/src/awtMain/cpp/windows/directXRedrawer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include <dxgi1_4.h>
#include <dxgi1_6.h>

#include <dcomp.h>
#pragma comment(lib, "dcomp.lib")

const int BuffersCount = 2;

class DirectXDevice
Expand Down Expand Up @@ -53,24 +56,39 @@ class DirectXDevice
}

void initSwapChain() {
RECT windowRect;
GetClientRect(window, &windowRect);
UINT width = windowRect.right - windowRect.left;
UINT height = windowRect.bottom - windowRect.top;

gr_cp<IDXGIFactory4> swapChainFactory4;
gr_cp<IDXGISwapChain1> swapChain1;
CreateDXGIFactory2(0, IID_PPV_ARGS(&swapChainFactory4));
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
swapChainDesc.BufferCount = BuffersCount;
swapChainDesc.Width = width;
swapChainDesc.Height = height;
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = BuffersCount;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.Scaling = DXGI_SCALING_NONE;
swapChainFactory4->CreateSwapChainForHwnd(queue.get(), window, &swapChainDesc, nullptr, nullptr, &swapChain1);
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
swapChainFactory4->CreateSwapChainForComposition(queue.get(), &swapChainDesc, nullptr, &swapChain1);

IDCompositionDevice* g_pdcDevice = nullptr;
IDCompositionTarget* g_pdcTarget = nullptr;
IDCompositionVisual* g_pdcVisual = nullptr;
DCompositionCreateDevice(0, IID_PPV_ARGS(&g_pdcDevice));
g_pdcDevice->CreateTargetForHwnd(window, true, &g_pdcTarget);
g_pdcDevice->CreateVisual(&g_pdcVisual);
g_pdcVisual->SetContent(swapChain1.get());
g_pdcTarget->SetRoot(g_pdcVisual);
g_pdcDevice->Commit();

swapChainFactory4->MakeWindowAssociation(window, DXGI_MWA_NO_ALT_ENTER);
swapChain1->QueryInterface(IID_PPV_ARGS(&swapChain));
RECT windowRect;
GetWindowRect(window, &windowRect);
unsigned int w = windowRect.right - windowRect.left;
unsigned int h = windowRect.bottom - windowRect.top;
swapChain->ResizeBuffers(BuffersCount, w, h, DXGI_FORMAT_R8G8B8A8_UNORM, 0);
swapChainFactory4.reset(nullptr);
}
};
Expand Down Expand Up @@ -292,6 +310,7 @@ extern "C"
return 0;
}

HWND hWnd = fromJavaPointer<HWND>(contentHandle);
DirectXDevice *d3dDevice = new DirectXDevice();
d3dDevice->backendContext.fAdapter = adapter;
d3dDevice->backendContext.fDevice = device;
Expand All @@ -300,13 +319,11 @@ extern "C"

d3dDevice->device = device;
d3dDevice->queue = queue;
d3dDevice->window = (HWND)contentHandle;
d3dDevice->window = hWnd;

if (transparency) {
//TODO: current swapChain does not support transparency
return 0;
// HWND wnd = GetAncestor(d3dDevice->window, GA_PARENT);
// enableTransparentWindow(wnd);
const LONG style = GetWindowLong(hWnd, GWL_EXSTYLE);
SetWindowLong(hWnd, GWL_EXSTYLE, style | WS_EX_TRANSPARENT);
}

return toJavaPointer(d3dDevice);
Expand Down
21 changes: 10 additions & 11 deletions skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ actual open class SkiaLayer internal constructor(
ContentScale,
}

private var _transparency: Boolean = false
actual var transparency: Boolean
get() = _transparency
actual var transparency: Boolean = false
set(value) {
_transparency = value
if (!value) {
background = UIManager.getColor("Panel.background")
field = value
background = if (!value) {
// TODO: Is it better to set `null` to reuse color of parent component?
UIManager.getColor("Panel.background")
} else {
background = Color(0, 0, 0, 0)
// Transparent background is required for software rendering
Color(0, 0, 0, 0)
}
}

Expand Down Expand Up @@ -301,9 +301,9 @@ actual open class SkiaLayer internal constructor(

private val redrawerManager = RedrawerManager<Redrawer>(properties.renderApi) { renderApi, oldRedrawer ->
oldRedrawer?.dispose()
val newRedrawer = renderFactory.createRedrawer(this, renderApi, analytics, properties)
newRedrawer.syncSize()
newRedrawer
renderFactory.createRedrawer(this, renderApi, analytics, properties).also {
it.syncSize()
}
}

internal val redrawer: Redrawer?
Expand Down Expand Up @@ -371,7 +371,6 @@ actual open class SkiaLayer internal constructor(
redrawer?.syncSize()
}


override fun paint(g: java.awt.Graphics) {
Logger.debug { "Paint called on: $this" }
checkContentScale()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package org.jetbrains.skiko.redrawer

import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.withContext
import org.jetbrains.skia.DirectContext
import org.jetbrains.skia.Surface
import org.jetbrains.skia.SurfaceProps
import org.jetbrains.skia.impl.interopScope
import org.jetbrains.skia.impl.InteropPointer
import org.jetbrains.skia.impl.interopScope
import org.jetbrains.skiko.*
import org.jetbrains.skiko.context.Direct3DContextHandler

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ expect open class SkiaLayer {
* If rendering is full screen.
*/
var fullscreen: Boolean

/**
* If transparency is enabled.
*/
Expand Down
5 changes: 5 additions & 0 deletions skiko/src/jvmMain/cpp/common/stubs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ JNIEXPORT void JNICALL Java_org_jetbrains_skiko_context_Direct3DContextHandler_f
skikoUnimplemented("Java_org_jetbrains_skiko_context_Direct3DContextHandler_flush");
}

JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_chooseAdapter(JNIEnv *env, jobject redrawer, jint adapterPriority) {
skikoUnimplemented("Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_chooseAdapter");
return 0;
}

JNIEXPORT jlong JNICALL Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_createDirectXDevice(
JNIEnv *env, jobject redrawer, jint adapterPriority, jlong contentHandle, jboolean transparency) {
skikoUnimplemented("Java_org_jetbrains_skiko_redrawer_Direct3DRedrawer_createDirectXDevice");
Expand Down

0 comments on commit bdf8985

Please sign in to comment.