Skip to content

Commit

Permalink
8185862: AWT Assertion Failure in ::GetDIBits(hBMDC, hBM, 0, 1, 0, gp…
Browse files Browse the repository at this point in the history
…BitmapInfo, 0) 'awt_Win32GraphicsDevice.cpp', at line 185

Reviewed-by: aivanov, prr
  • Loading branch information
RealCLanger committed Mar 13, 2024
1 parent 7f6b7eb commit 1ad3ebc
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,7 +23,6 @@
* questions.
*/


package java.awt;

import java.awt.image.BufferedImage;
Expand All @@ -36,7 +35,6 @@
import sun.font.FontManagerFactory;
import sun.java2d.HeadlessGraphicsEnvironment;
import sun.java2d.SunGraphicsEnvironment;
import sun.security.action.GetPropertyAction;

/**
*
Expand Down
32 changes: 26 additions & 6 deletions src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -28,20 +28,41 @@
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;

import sun.awt.windows.WToolkit;

public class PlatformGraphicsInfo {

private static final boolean hasDisplays;

static {
loadAWTLibrary();
hasDisplays = hasDisplays0();
}

@SuppressWarnings("removal")
private static void loadAWTLibrary() {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("awt");
return null;
}
});
}

private static native boolean hasDisplays0();

public static GraphicsEnvironment createGE() {
return new Win32GraphicsEnvironment();
}

public static Toolkit createToolkit() {
return new sun.awt.windows.WToolkit();
return new WToolkit();
}

public static boolean getDefaultHeadlessProperty() {
// On Windows, we assume we can always create headful apps.
// Here is where we can add code that would actually check.
return false;
// If we don't find usable displays, we run headless.
return !hasDisplays;
}

/*
Expand All @@ -54,5 +75,4 @@ public static String getDefaultHeadlessMessage() {
"\nThe application does not have desktop access,\n" +
"but this program performed an operation which requires it.";
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -60,7 +60,8 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
WToolkit.loadLibraries();
// setup flags before initializing native layer
WindowsFlags.initFlags();
initDisplayWrapper();

initDisplay();

// Install correct surface manager factory.
SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
Expand All @@ -82,20 +83,12 @@ public final class Win32GraphicsEnvironment extends SunGraphicsEnvironment {
}

/**
* Initializes native components of the graphics environment. This
* Initializes native components of the graphics environment. This
* includes everything from the native GraphicsDevice elements to
* the DirectX rendering layer.
*/
private static native void initDisplay();

private static boolean displayInitialized; // = false;
public static void initDisplayWrapper() {
if (!displayInitialized) {
displayInitialized = true;
initDisplay();
}
}

public Win32GraphicsEnvironment() {
}

Expand Down
81 changes: 48 additions & 33 deletions src/java.desktop/windows/native/libawt/windows/Devices.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -85,60 +85,75 @@
#include "Trace.h"
#include "D3DPipelineManager.h"

typedef struct {
int monitorCounter;
int monitorLimit;
HMONITOR* hmpMonitors;
} MonitorData;

/* Some helper functions (from awt_MMStub.h/cpp) */

int g_nMonitorCounter;
int g_nMonitorLimit;
HMONITOR* g_hmpMonitors;
// Only monitors where CreateDC does not fail are valid
static BOOL IsValidMonitor(HMONITOR hMon)
{
MONITORINFOEX mieInfo;
memset((void*)(&mieInfo), 0, sizeof(MONITORINFOEX));
mieInfo.cbSize = sizeof(MONITORINFOEX);
if (!::GetMonitorInfo(hMon, (LPMONITORINFOEX)(&mieInfo))) {
J2dTraceLn1(J2D_TRACE_INFO, "Devices::IsValidMonitor: GetMonitorInfo failed for monitor with handle %p", hMon);
return FALSE;
}

HDC hDC = CreateDC(mieInfo.szDevice, NULL, NULL, NULL);
if (NULL == hDC) {
J2dTraceLn2(J2D_TRACE_INFO, "Devices::IsValidMonitor: CreateDC failed for monitor with handle %p, device: %S", hMon, mieInfo.szDevice);
return FALSE;
}

::DeleteDC(hDC);
return TRUE;
}

// Callback for CountMonitors below
BOOL WINAPI clb_fCountMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lP)
static BOOL WINAPI clb_fCountMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lpMonitorCounter)
{
g_nMonitorCounter ++;
if (IsValidMonitor(hMon)) {
(*((int *)lpMonitorCounter))++;
}

return TRUE;
}

int WINAPI CountMonitors(void)
{
g_nMonitorCounter = 0;
::EnumDisplayMonitors(NULL, NULL, clb_fCountMonitors, 0L);
return g_nMonitorCounter;

int monitorCounter = 0;
::EnumDisplayMonitors(NULL, NULL, clb_fCountMonitors, (LPARAM)&monitorCounter);
return monitorCounter;
}

// Callback for CollectMonitors below
BOOL WINAPI clb_fCollectMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lP)
static BOOL WINAPI clb_fCollectMonitors(HMONITOR hMon, HDC hDC, LPRECT rRect, LPARAM lpMonitorData)
{

if ((g_nMonitorCounter < g_nMonitorLimit) && (NULL != g_hmpMonitors)) {
g_hmpMonitors[g_nMonitorCounter] = hMon;
g_nMonitorCounter ++;
MonitorData* pMonitorData = (MonitorData *)lpMonitorData;
if ((pMonitorData->monitorCounter < pMonitorData->monitorLimit) && (IsValidMonitor(hMon))) {
pMonitorData->hmpMonitors[pMonitorData->monitorCounter] = hMon;
pMonitorData->monitorCounter++;
}

return TRUE;
}

int WINAPI CollectMonitors(HMONITOR* hmpMonitors, int nNum)
static int WINAPI CollectMonitors(HMONITOR* hmpMonitors, int nNum)
{
int retCode = 0;

if (NULL != hmpMonitors) {

g_nMonitorCounter = 0;
g_nMonitorLimit = nNum;
g_hmpMonitors = hmpMonitors;

::EnumDisplayMonitors(NULL, NULL, clb_fCollectMonitors, 0L);

retCode = g_nMonitorCounter;

g_nMonitorCounter = 0;
g_nMonitorLimit = 0;
g_hmpMonitors = NULL;

MonitorData monitorData;
monitorData.monitorCounter = 0;
monitorData.monitorLimit = nNum;
monitorData.hmpMonitors = hmpMonitors;
::EnumDisplayMonitors(NULL, NULL, clb_fCollectMonitors, (LPARAM)&monitorData);
return monitorData.monitorCounter;
} else {
return 0;
}
return retCode;
}

BOOL WINAPI MonitorBounds(HMONITOR hmMonitor, RECT* rpBounds)
Expand Down
4 changes: 3 additions & 1 deletion src/java.desktop/windows/native/libawt/windows/Devices.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -74,4 +74,6 @@ static CriticalSection arrayLock;

BOOL WINAPI MonitorBounds (HMONITOR, RECT*);

int WINAPI CountMonitors (void);

#endif // _DEVICES_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2024 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

#include <sun_awt_PlatformGraphicsInfo.h>
#include "Devices.h"

/*
* Class: sun_awt_PlatformGraphicsInfo
* Method: hasDisplays0
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL
Java_sun_awt_PlatformGraphicsInfo_hasDisplays0(JNIEnv *env, jclass thisClass) {
return CountMonitors() > 0 ? JNI_TRUE : JNI_FALSE;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -179,7 +179,9 @@ void AwtWin32GraphicsDevice::Initialize()
}
gpBitmapInfo->bmiHeader.biBitCount = 0;
HDC hBMDC = this->GetDC();
VERIFY(hBMDC != NULL);
HBITMAP hBM = ::CreateCompatibleBitmap(hBMDC, 1, 1);
VERIFY(hBM != NULL);
VERIFY(::GetDIBits(hBMDC, hBM, 0, 1, NULL, gpBitmapInfo, DIB_RGB_COLORS));

if (colorData->bitsperpixel > 8) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -36,10 +36,8 @@
BOOL DWMIsCompositionEnabled();

void initScreens(JNIEnv *env) {

if (!Devices::UpdateInstance(env)) {
JNU_ThrowInternalError(env, "Could not update the devices array.");
return;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -33,7 +33,6 @@
/**
* @test
* @bug 8189604 8208702
* @requires !vm.debug | os.family != "windows"
* @run main/othervm -Djava.awt.headless=false HangDuringStaticInitialization
* @run main/othervm -Djava.awt.headless=true HangDuringStaticInitialization
*/
Expand Down

3 comments on commit 1ad3ebc

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RealCLanger
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/backport jdk22u

@openjdk
Copy link

@openjdk openjdk bot commented on 1ad3ebc Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RealCLanger the backport was successfully created on the branch backport-RealCLanger-1ad3ebcf in my personal fork of openjdk/jdk22u. To create a pull request with this backport targeting openjdk/jdk22u:master, just click the following link:

➡️ Create pull request

The title of the pull request is automatically filled in correctly and below you find a suggestion for the pull request body:

Hi all,

This pull request contains a backport of commit 1ad3ebcf from the openjdk/jdk repository.

The commit being backported was authored by Christoph Langer on 13 Mar 2024 and was reviewed by Alexey Ivanov and Phil Race.

Thanks!

If you need to update the source branch of the pull then run the following commands in a local clone of your personal fork of openjdk/jdk22u:

$ git fetch https://github.com/openjdk-bots/jdk22u.git backport-RealCLanger-1ad3ebcf:backport-RealCLanger-1ad3ebcf
$ git checkout backport-RealCLanger-1ad3ebcf
# make changes
$ git add paths/to/changed/files
$ git commit --message 'Describe additional changes made'
$ git push https://github.com/openjdk-bots/jdk22u.git backport-RealCLanger-1ad3ebcf

Please sign in to comment.