Skip to content

Commit

Permalink
Windows. Fix a crash on CI without dcomp.dll (#909)
Browse files Browse the repository at this point in the history
## Issues fixed

Some CI don't have this library and when we run an application we have a
crash:
```
...\skiko-windows-x64.dll: Can't find dependent libraries
java.lang.UnsatisfiedLinkError: ...\skiko-windows-x64.dll: Can't find dependent libraries
	at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
	at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:388)
	at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:232)
	at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:174)
	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2394)
	at java.base/java.lang.Runtime.load0(Runtime.java:755)
	at java.base/java.lang.System.load(System.java:1957)
	at org.jetbrains.skiko.Library.loadLibraryOrCopy(Library.kt:17)
	at org.jetbrains.skiko.Library.findAndLoad(Library.kt:111)
	at org.jetbrains.skiko.Library.load(Library.kt:56)
	at org.jetbrains.skia.impl.Library$Companion.staticLoad(Library.jvm.kt:12)
	at org.jetbrains.skia.Surface.<clinit>(Surface.kt:539)
	at androidx.compose.ui.test.SkikoComposeUiTest.<init>(ComposeUiTest.skikoMain.kt:172)
	at androidx.compose.ui.test.SkikoComposeUiTest.<init>(ComposeUiTest.skikoMain.kt:118)
	at androidx.compose.ui.test.SkikoComposeUiTest.<init>(ComposeUiTest.skikoMain.kt:139)
	at androidx.compose.ui.test.SkikoComposeUiTest.<init>(ComposeUiTest.skikoMain.kt:134)
	at androidx.compose.ui.test.junit4.DesktopComposeTestRule.<init>(DesktopComposeTestRule.desktop.kt:54)
	at androidx.compose.ui.test.junit4.DesktopComposeTestRule_desktopKt.createComposeRule(DesktopComposeTestRule.desktop.kt:41)
```

Reported in
https://jetbrains.slack.com/archives/C5VQN94SH/p1712564847131459?thread_ts=1712091431.760099&cid=C5VQN94SH

## Proposed changes
Load this library in runtime, and fallback to
`CreateSwapChainForComposition`

## Testing
1. Run Compose with transparent window:
```
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Surface
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.material.Text
import androidx.compose.runtime.*

fun main() = application {
    var isOpen by remember { mutableStateOf(true) }
    if (isOpen) {
        Window(
            onCloseRequest = { isOpen = false },
            title = "Transparent Window Example",
            transparent = true,
            undecorated = true, //transparent window must be undecorated
        ) {
            Surface(
                modifier = Modifier.fillMaxSize().padding(5.dp).shadow(3.dp, RoundedCornerShape(20.dp)),
                color = Color(55, 55, 55),
                shape = RoundedCornerShape(20.dp) //window has round corners now
            ) {
                Text("Hello World!", color = Color.White)
            }
        }
    }
}
```
Transparency should work, there shouldn't be errors in the log.

2. change `transparent = false`

Transparency shouldn't work, there shouldn't be errors in the log.

This should be tested by QA.

---------

Co-authored-by: Ivan Matkov <[email protected]>
  • Loading branch information
igordmn and MatkovIvan authored Apr 16, 2024
1 parent 1647328 commit 7a6f62b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
24 changes: 24 additions & 0 deletions skiko/src/awtMain/cpp/windows/DCompLibrary.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "DCompLibrary.h"

namespace DCompLibrary {
static HINSTANCE getLibrary() {
static HINSTANCE library = LoadLibrary("dcomp.dll");
return library;
}

HRESULT DCompositionCreateDevice(
IDXGIDevice *dxgiDevice,
REFIID iid,
void **dcompositionDevice
) {
HINSTANCE library = getLibrary();

if (library != nullptr) {
typedef HRESULT(WINAPI * PROC_DCompositionCreateDevice)(IDXGIDevice * dxgiDevice, REFIID iid, void **dcompositionDevice);
static auto compositionCreateDevice = (PROC_DCompositionCreateDevice) GetProcAddress(library, "DCompositionCreateDevice");
return compositionCreateDevice(dxgiDevice, iid, dcompositionDevice);
} else {
return E_FAIL;
}
}
}
11 changes: 11 additions & 0 deletions skiko/src/awtMain/cpp/windows/DCompLibrary.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include <dcomp.h>

namespace DCompLibrary {
HRESULT DCompositionCreateDevice(
IDXGIDevice *dxgiDevice,
REFIID iid,
void **dcompositionDevice
);
}
6 changes: 2 additions & 4 deletions skiko/src/awtMain/cpp/windows/directXRedrawer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "SkSurface.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "../common/interop.hh"
#include "DCompLibrary.h"

#include "d3d/GrD3DTypes.h"
#include <d3d12sdklayers.h>
Expand All @@ -20,9 +21,6 @@
#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 @@ -95,7 +93,7 @@ class DirectXDevice
HRESULT result = swapChainFactory4->CreateSwapChainForComposition(queue.get(), &swapChainDesc, nullptr, swapChain1);
if (FAILED(result)) { return result; }

result = DCompositionCreateDevice(0, IID_PPV_ARGS(&dcDevice));
result = DCompLibrary::DCompositionCreateDevice(0, IID_PPV_ARGS(&dcDevice));
if (FAILED(result)) { return result; }
result = dcDevice->CreateTargetForHwnd(hWnd, true, &dcTarget);
if (FAILED(result)) { return result; }
Expand Down

0 comments on commit 7a6f62b

Please sign in to comment.