6867515: Reduce impact of D3D initializion on startup time
6891435: Improve D3D preloading 6946559: AWTToolKit thread crashes in JNU_GetEnv 6987967: D3D preloading thread should initialize COM Reviewed-by: igor, art, uta
This commit is contained in:
parent
fbe778aead
commit
631d924ad6
@ -51,6 +51,92 @@ static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
|
|||||||
static jboolean GetJREPath(char *path, jint pathsize);
|
static jboolean GetJREPath(char *path, jint pathsize);
|
||||||
static void EnsureJreInstallation(const char *jrepath);
|
static void EnsureJreInstallation(const char *jrepath);
|
||||||
|
|
||||||
|
/* We supports warmup for UI stack that is performed in parallel
|
||||||
|
* to VM initialization.
|
||||||
|
* This helps to improve startup of UI application as warmup phase
|
||||||
|
* might be long due to initialization of OS or hardware resources.
|
||||||
|
* It is not CPU bound and therefore it does not interfere with VM init.
|
||||||
|
* Obviously such warmup only has sense for UI apps and therefore it needs
|
||||||
|
* to be explicitly requested by passing -Dsun.awt.warmup=true property
|
||||||
|
* (this is always the case for plugin/javaws).
|
||||||
|
*
|
||||||
|
* Implementation launches new thread after VM starts and use it to perform
|
||||||
|
* warmup code (platform dependent).
|
||||||
|
* This thread is later reused as AWT toolkit thread as graphics toolkit
|
||||||
|
* often assume that they are used from the same thread they were launched on.
|
||||||
|
*
|
||||||
|
* At the moment we only support warmup for D3D. It only possible on windows
|
||||||
|
* and only if other flags do not prohibit this (e.g. OpenGL support requested).
|
||||||
|
*/
|
||||||
|
#undef ENABLE_AWT_PRELOAD
|
||||||
|
#ifndef JAVA_ARGS /* turn off AWT preloading for javac, jar, etc */
|
||||||
|
#define ENABLE_AWT_PRELOAD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_AWT_PRELOAD
|
||||||
|
/* "AWT was preloaded" flag;
|
||||||
|
* turned on by AWTPreload().
|
||||||
|
*/
|
||||||
|
int awtPreloaded = 0;
|
||||||
|
|
||||||
|
/* Calls a function with the name specified
|
||||||
|
* the function must be int(*fn)(void).
|
||||||
|
*/
|
||||||
|
int AWTPreload(const char *funcName);
|
||||||
|
/* stops AWT preloading */
|
||||||
|
void AWTPreloadStop();
|
||||||
|
|
||||||
|
/* D3D preloading */
|
||||||
|
/* -1: not initialized; 0: OFF, 1: ON */
|
||||||
|
int awtPreloadD3D = -1;
|
||||||
|
/* command line parameter to swith D3D preloading on */
|
||||||
|
#define PARAM_PRELOAD_D3D "-Dsun.awt.warmup"
|
||||||
|
/* D3D/OpenGL management parameters */
|
||||||
|
#define PARAM_NODDRAW "-Dsun.java2d.noddraw"
|
||||||
|
#define PARAM_D3D "-Dsun.java2d.d3d"
|
||||||
|
#define PARAM_OPENGL "-Dsun.java2d.opengl"
|
||||||
|
/* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */
|
||||||
|
#define D3D_PRELOAD_FUNC "preloadD3D"
|
||||||
|
|
||||||
|
|
||||||
|
/* Extracts value of a parameter with the specified name
|
||||||
|
* from command line argument (returns pointer in the argument).
|
||||||
|
* Returns NULL if the argument does not contains the parameter.
|
||||||
|
* e.g.:
|
||||||
|
* GetParamValue("theParam", "theParam=value") returns pointer to "value".
|
||||||
|
*/
|
||||||
|
const char * GetParamValue(const char *paramName, const char *arg) {
|
||||||
|
int nameLen = JLI_StrLen(paramName);
|
||||||
|
if (JLI_StrNCmp(paramName, arg, nameLen) == 0) {
|
||||||
|
/* arg[nameLen] is valid (may contain final NULL) */
|
||||||
|
if (arg[nameLen] == '=') {
|
||||||
|
return arg + nameLen + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checks if commandline argument contains property specified
|
||||||
|
* and analyze it as boolean property (true/false).
|
||||||
|
* Returns -1 if the argument does not contain the parameter;
|
||||||
|
* Returns 1 if the argument contains the parameter and its value is "true";
|
||||||
|
* Returns 0 if the argument contains the parameter and its value is "false".
|
||||||
|
*/
|
||||||
|
int GetBoolParamValue(const char *paramName, const char *arg) {
|
||||||
|
const char * paramValue = GetParamValue(paramName, arg);
|
||||||
|
if (paramValue != NULL) {
|
||||||
|
if (JLI_StrCaseCmp(paramValue, "true") == 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (JLI_StrCaseCmp(paramValue, "false") == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_AWT_PRELOAD */
|
||||||
|
|
||||||
|
|
||||||
static jboolean _isjavaw = JNI_FALSE;
|
static jboolean _isjavaw = JNI_FALSE;
|
||||||
|
|
||||||
|
|
||||||
@ -132,6 +218,30 @@ CreateExecutionEnvironment(int *pargc, char ***pargv,
|
|||||||
exit(4);
|
exit(4);
|
||||||
}
|
}
|
||||||
/* If we got here, jvmpath has been correctly initialized. */
|
/* If we got here, jvmpath has been correctly initialized. */
|
||||||
|
|
||||||
|
/* Check if we need preload AWT */
|
||||||
|
#ifdef ENABLE_AWT_PRELOAD
|
||||||
|
argv = *pargv;
|
||||||
|
for (i = 0; i < *pargc ; i++) {
|
||||||
|
/* Tests the "turn on" parameter only if not set yet. */
|
||||||
|
if (awtPreloadD3D < 0) {
|
||||||
|
if (GetBoolParamValue(PARAM_PRELOAD_D3D, argv[i]) == 1) {
|
||||||
|
awtPreloadD3D = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Test parameters which can disable preloading if not already disabled. */
|
||||||
|
if (awtPreloadD3D != 0) {
|
||||||
|
if (GetBoolParamValue(PARAM_NODDRAW, argv[i]) == 1
|
||||||
|
|| GetBoolParamValue(PARAM_D3D, argv[i]) == 0
|
||||||
|
|| GetBoolParamValue(PARAM_OPENGL, argv[i]) == 1)
|
||||||
|
{
|
||||||
|
awtPreloadD3D = 0;
|
||||||
|
/* no need to test the rest of the parameters */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_AWT_PRELOAD */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1087,6 +1197,40 @@ ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void
|
|||||||
0,
|
0,
|
||||||
&thread_id);
|
&thread_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* AWT preloading (AFTER main thread start) */
|
||||||
|
#ifdef ENABLE_AWT_PRELOAD
|
||||||
|
/* D3D preloading */
|
||||||
|
if (awtPreloadD3D != 0) {
|
||||||
|
char *envValue;
|
||||||
|
/* D3D routines checks env.var J2D_D3D if no appropriate
|
||||||
|
* command line params was specified
|
||||||
|
*/
|
||||||
|
envValue = getenv("J2D_D3D");
|
||||||
|
if (envValue != NULL && JLI_StrCaseCmp(envValue, "false") == 0) {
|
||||||
|
awtPreloadD3D = 0;
|
||||||
|
}
|
||||||
|
/* Test that AWT preloading isn't disabled by J2D_D3D_PRELOAD env.var */
|
||||||
|
envValue = getenv("J2D_D3D_PRELOAD");
|
||||||
|
if (envValue != NULL && JLI_StrCaseCmp(envValue, "false") == 0) {
|
||||||
|
awtPreloadD3D = 0;
|
||||||
|
}
|
||||||
|
if (awtPreloadD3D < 0) {
|
||||||
|
/* If awtPreloadD3D is still undefined (-1), test
|
||||||
|
* if it is turned on by J2D_D3D_PRELOAD env.var.
|
||||||
|
* By default it's turned OFF.
|
||||||
|
*/
|
||||||
|
awtPreloadD3D = 0;
|
||||||
|
if (envValue != NULL && JLI_StrCaseCmp(envValue, "true") == 0) {
|
||||||
|
awtPreloadD3D = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (awtPreloadD3D) {
|
||||||
|
AWTPreload(D3D_PRELOAD_FUNC);
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_AWT_PRELOAD */
|
||||||
|
|
||||||
if (thread_handle) {
|
if (thread_handle) {
|
||||||
WaitForSingleObject(thread_handle, INFINITE);
|
WaitForSingleObject(thread_handle, INFINITE);
|
||||||
GetExitCodeThread(thread_handle, &rslt);
|
GetExitCodeThread(thread_handle, &rslt);
|
||||||
@ -1094,6 +1238,13 @@ ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void
|
|||||||
} else {
|
} else {
|
||||||
rslt = continuation(args);
|
rslt = continuation(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_AWT_PRELOAD
|
||||||
|
if (awtPreloaded) {
|
||||||
|
AWTPreloadStop();
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_AWT_PRELOAD */
|
||||||
|
|
||||||
return rslt;
|
return rslt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1140,3 +1291,98 @@ InitLauncher(boolean javaw)
|
|||||||
_isjavaw = javaw;
|
_isjavaw = javaw;
|
||||||
JLI_SetTraceLauncher();
|
JLI_SetTraceLauncher();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ============================== */
|
||||||
|
/* AWT preloading */
|
||||||
|
#ifdef ENABLE_AWT_PRELOAD
|
||||||
|
|
||||||
|
typedef int FnPreloadStart(void);
|
||||||
|
typedef void FnPreloadStop(void);
|
||||||
|
static FnPreloadStop *fnPreloadStop = NULL;
|
||||||
|
static HMODULE hPreloadAwt = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Starts AWT preloading
|
||||||
|
*/
|
||||||
|
int AWTPreload(const char *funcName)
|
||||||
|
{
|
||||||
|
int result = -1;
|
||||||
|
/* load AWT library once (if several preload function should be called) */
|
||||||
|
if (hPreloadAwt == NULL) {
|
||||||
|
/* awt.dll is not loaded yet */
|
||||||
|
char libraryPath[MAXPATHLEN];
|
||||||
|
int jrePathLen = 0;
|
||||||
|
HMODULE hJava = NULL;
|
||||||
|
HMODULE hVerify = NULL;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
/* awt.dll depends on jvm.dll & java.dll;
|
||||||
|
* jvm.dll is already loaded, so we need only java.dll;
|
||||||
|
* java.dll depends on MSVCRT lib & verify.dll.
|
||||||
|
*/
|
||||||
|
if (!GetJREPath(libraryPath, MAXPATHLEN)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save path length */
|
||||||
|
jrePathLen = JLI_StrLen(libraryPath);
|
||||||
|
|
||||||
|
/* load msvcrt 1st */
|
||||||
|
LoadMSVCRT();
|
||||||
|
|
||||||
|
/* load verify.dll */
|
||||||
|
JLI_StrCat(libraryPath, "\\bin\\verify.dll");
|
||||||
|
hVerify = LoadLibrary(libraryPath);
|
||||||
|
if (hVerify == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore jrePath */
|
||||||
|
libraryPath[jrePathLen] = 0;
|
||||||
|
/* load java.dll */
|
||||||
|
JLI_StrCat(libraryPath, "\\bin\\" JAVA_DLL);
|
||||||
|
hJava = LoadLibrary(libraryPath);
|
||||||
|
if (hJava == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* restore jrePath */
|
||||||
|
libraryPath[jrePathLen] = 0;
|
||||||
|
/* load awt.dll */
|
||||||
|
JLI_StrCat(libraryPath, "\\bin\\awt.dll");
|
||||||
|
hPreloadAwt = LoadLibrary(libraryPath);
|
||||||
|
if (hPreloadAwt == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get "preloadStop" func ptr */
|
||||||
|
fnPreloadStop = (FnPreloadStop *)GetProcAddress(hPreloadAwt, "preloadStop");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hPreloadAwt != NULL) {
|
||||||
|
FnPreloadStart *fnInit = (FnPreloadStart *)GetProcAddress(hPreloadAwt, funcName);
|
||||||
|
if (fnInit != NULL) {
|
||||||
|
/* don't forget to stop preloading */
|
||||||
|
awtPreloaded = 1;
|
||||||
|
|
||||||
|
result = fnInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Terminates AWT preloading
|
||||||
|
*/
|
||||||
|
void AWTPreloadStop() {
|
||||||
|
if (fnPreloadStop != NULL) {
|
||||||
|
fnPreloadStop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ENABLE_AWT_PRELOAD */
|
||||||
|
@ -218,6 +218,8 @@ public class WToolkit extends SunToolkit implements Runnable {
|
|||||||
|
|
||||||
private static native void postDispose();
|
private static native void postDispose();
|
||||||
|
|
||||||
|
private static native boolean startToolkitThread(Runnable thread);
|
||||||
|
|
||||||
public WToolkit() {
|
public WToolkit() {
|
||||||
// Startup toolkit threads
|
// Startup toolkit threads
|
||||||
if (PerformanceLogger.loggingEnabled()) {
|
if (PerformanceLogger.loggingEnabled()) {
|
||||||
@ -231,9 +233,6 @@ public class WToolkit extends SunToolkit implements Runnable {
|
|||||||
// where notifyAll can be called before
|
// where notifyAll can be called before
|
||||||
// the "AWT-Windows" thread's parent thread is
|
// the "AWT-Windows" thread's parent thread is
|
||||||
// waiting, resulting in a deadlock on startup.
|
// waiting, resulting in a deadlock on startup.
|
||||||
Thread toolkitThread = new Thread(this, "AWT-Windows");
|
|
||||||
toolkitThread.setDaemon(true);
|
|
||||||
toolkitThread.setPriority(Thread.NORM_PRIORITY+1);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fix for 4701990.
|
* Fix for 4701990.
|
||||||
@ -242,7 +241,11 @@ public class WToolkit extends SunToolkit implements Runnable {
|
|||||||
*/
|
*/
|
||||||
AWTAutoShutdown.notifyToolkitThreadBusy();
|
AWTAutoShutdown.notifyToolkitThreadBusy();
|
||||||
|
|
||||||
toolkitThread.start();
|
if (!startToolkitThread(this)) {
|
||||||
|
Thread toolkitThread = new Thread(this, "AWT-Windows");
|
||||||
|
toolkitThread.setDaemon(true);
|
||||||
|
toolkitThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
wait();
|
wait();
|
||||||
@ -263,6 +266,7 @@ public class WToolkit extends SunToolkit implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
Thread.currentThread().setPriority(Thread.NORM_PRIORITY+1);
|
||||||
boolean startPump = init();
|
boolean startPump = init();
|
||||||
|
|
||||||
if (startPump) {
|
if (startPump) {
|
||||||
|
@ -36,22 +36,6 @@ extern jobject CreateDisplayMode(JNIEnv* env, jint width, jint height,
|
|||||||
extern void addDisplayMode(JNIEnv* env, jobject arrayList, jint width,
|
extern void addDisplayMode(JNIEnv* env, jobject arrayList, jint width,
|
||||||
jint height, jint bitDepth, jint refreshRate);
|
jint height, jint bitDepth, jint refreshRate);
|
||||||
|
|
||||||
void InitD3D(void *pReturn)
|
|
||||||
{
|
|
||||||
J2dTraceLn(J2D_TRACE_INFO, "InitD3D");
|
|
||||||
|
|
||||||
jboolean *pRet = (jboolean *)pReturn;
|
|
||||||
|
|
||||||
D3DPipelineManager *pMgr = D3DPipelineManager::CreateInstance();
|
|
||||||
if (pMgr == NULL) {
|
|
||||||
J2dTraceLn(J2D_TRACE_ERROR, "InitD3D: could not create or init d3d");
|
|
||||||
*pRet = JNI_FALSE;
|
|
||||||
} else {
|
|
||||||
J2dTraceLn(J2D_TRACE_INFO, "InitD3D: successfully initialized d3d");
|
|
||||||
*pRet = JNI_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
/*
|
/*
|
||||||
* Class: sun_java2d_d3d_D3DGraphicsDevice
|
* Class: sun_java2d_d3d_D3DGraphicsDevice
|
||||||
@ -63,8 +47,8 @@ JNIEXPORT jboolean JNICALL Java_sun_java2d_d3d_D3DGraphicsDevice_initD3D
|
|||||||
{
|
{
|
||||||
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_initD3D");
|
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_initD3D");
|
||||||
|
|
||||||
jboolean result = JNI_FALSE;
|
jboolean result = D3DInitializer::GetInstance().EnsureInited()
|
||||||
AwtToolkit::GetInstance().InvokeFunction(InitD3D, &result);
|
? JNI_TRUE : JNI_FALSE;
|
||||||
J2dTraceLn1(J2D_TRACE_INFO, "D3DGD_initD3D: result=%x", result);
|
J2dTraceLn1(J2D_TRACE_INFO, "D3DGD_initD3D: result=%x", result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ static BOOL bNoHwCheck = (getenv("J2D_D3D_NO_HWCHECK") != NULL);
|
|||||||
|
|
||||||
D3DPipelineManager *D3DPipelineManager::pMgr = NULL;
|
D3DPipelineManager *D3DPipelineManager::pMgr = NULL;
|
||||||
|
|
||||||
|
|
||||||
D3DPipelineManager * D3DPipelineManager::CreateInstance(void)
|
D3DPipelineManager * D3DPipelineManager::CreateInstance(void)
|
||||||
{
|
{
|
||||||
if (!IsD3DEnabled() ||
|
if (!IsD3DEnabled() ||
|
||||||
@ -179,6 +180,12 @@ void D3DPipelineManager::NotifyAdapterEventListeners(UINT adapter,
|
|||||||
HMONITOR hMon;
|
HMONITOR hMon;
|
||||||
int gdiScreen;
|
int gdiScreen;
|
||||||
D3DPipelineManager *pMgr;
|
D3DPipelineManager *pMgr;
|
||||||
|
|
||||||
|
// fix for 6946559: if d3d preloading fails jmv may be NULL
|
||||||
|
if (jvm == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
|
||||||
|
|
||||||
pMgr = D3DPipelineManager::GetInstance();
|
pMgr = D3DPipelineManager::GetInstance();
|
||||||
@ -934,3 +941,87 @@ HRESULT D3DPipelineManager::GetD3DContext(UINT adapterOrdinal,
|
|||||||
*ppd3dContext = pAdapters[adapterOrdinal].pd3dContext;
|
*ppd3dContext = pAdapters[adapterOrdinal].pd3dContext;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//==============================================================
|
||||||
|
// D3DInitializer
|
||||||
|
//==============================================================
|
||||||
|
|
||||||
|
D3DInitializer D3DInitializer::theInstance;
|
||||||
|
|
||||||
|
D3DInitializer::D3DInitializer()
|
||||||
|
: bComInitialized(false), pAdapterIniters(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DInitializer::~D3DInitializer()
|
||||||
|
{
|
||||||
|
if (pAdapterIniters) {
|
||||||
|
delete[] pAdapterIniters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3DInitializer::InitImpl()
|
||||||
|
{
|
||||||
|
J2dRlsTraceLn(J2D_TRACE_INFO, "D3DInitializer::InitImpl");
|
||||||
|
if (SUCCEEDED(::CoInitialize(NULL))) {
|
||||||
|
bComInitialized = true;
|
||||||
|
}
|
||||||
|
D3DPipelineManager *pMgr = D3DPipelineManager::CreateInstance();
|
||||||
|
if (pMgr != NULL) {
|
||||||
|
UINT adapterCount = pMgr->adapterCount;
|
||||||
|
|
||||||
|
pAdapterIniters = new D3DAdapterInitializer[adapterCount];
|
||||||
|
for (UINT i=0; i<adapterCount; i++) {
|
||||||
|
pAdapterIniters[i].setAdapter(i);
|
||||||
|
AwtToolkit::GetInstance().GetPreloadThread().AddAction(&pAdapterIniters[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3DInitializer::CleanImpl(bool reInit)
|
||||||
|
{
|
||||||
|
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DInitializer::CleanImpl (%s)",
|
||||||
|
reInit ? "RELAUNCH" : "normal");
|
||||||
|
D3DPipelineManager::DeleteInstance();
|
||||||
|
if (bComInitialized) {
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void D3DInitializer::D3DAdapterInitializer::InitImpl()
|
||||||
|
{
|
||||||
|
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) started", adapter);
|
||||||
|
|
||||||
|
D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
|
||||||
|
if (pMgr == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3DContext *pd3dContext;
|
||||||
|
pMgr->GetD3DContext(adapter, &pd3dContext);
|
||||||
|
|
||||||
|
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) finished", adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3DInitializer::D3DAdapterInitializer::CleanImpl(bool reInit)
|
||||||
|
{
|
||||||
|
// nothing to do - D3DPipelineManager cleans adapters
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
/*
|
||||||
|
* Export function to start D3D preloading
|
||||||
|
* (called from java/javaw - see src/windows/bin/java-md.c)
|
||||||
|
*/
|
||||||
|
__declspec(dllexport) int preloadD3D()
|
||||||
|
{
|
||||||
|
J2dRlsTraceLn(J2D_TRACE_INFO, "AWT warmup: preloadD3D");
|
||||||
|
AwtToolkit::GetInstance().GetPreloadThread().AddAction(&D3DInitializer::GetInstance());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "D3DPipeline.h"
|
#include "D3DPipeline.h"
|
||||||
#include "D3DContext.h"
|
#include "D3DContext.h"
|
||||||
|
#include "awt_Toolkit.h"
|
||||||
|
|
||||||
typedef class D3DPipelineManager *LPD3DPIPELINEMANAGER;
|
typedef class D3DPipelineManager *LPD3DPIPELINEMANAGER;
|
||||||
|
|
||||||
@ -38,11 +39,15 @@ typedef struct D3DAdapter
|
|||||||
|
|
||||||
class D3DPIPELINE_API D3DPipelineManager
|
class D3DPIPELINE_API D3DPipelineManager
|
||||||
{
|
{
|
||||||
public:
|
friend class D3DInitializer;
|
||||||
|
private:
|
||||||
// creates and initializes instance of D3DPipelineManager, may return NULL
|
// creates and initializes instance of D3DPipelineManager, may return NULL
|
||||||
static D3DPipelineManager* CreateInstance(void);
|
static D3DPipelineManager* CreateInstance(void);
|
||||||
|
|
||||||
// deletes the single instance of the manager
|
// deletes the single instance of the manager
|
||||||
static void DeleteInstance();
|
static void DeleteInstance();
|
||||||
|
|
||||||
|
public:
|
||||||
// returns the single instance of the manager, may return NULL
|
// returns the single instance of the manager, may return NULL
|
||||||
static D3DPipelineManager* GetInstance(void);
|
static D3DPipelineManager* GetInstance(void);
|
||||||
|
|
||||||
@ -143,3 +148,40 @@ private:
|
|||||||
#define OS_ALL (OS_VISTA|OS_WINSERV_2008|OS_WINXP|OS_WINXP_64|OS_WINSERV_2003)
|
#define OS_ALL (OS_VISTA|OS_WINSERV_2008|OS_WINXP|OS_WINXP_64|OS_WINSERV_2003)
|
||||||
#define OS_UNKNOWN (~OS_ALL)
|
#define OS_UNKNOWN (~OS_ALL)
|
||||||
BOOL D3DPPLM_OsVersionMatches(USHORT osInfo);
|
BOOL D3DPPLM_OsVersionMatches(USHORT osInfo);
|
||||||
|
|
||||||
|
|
||||||
|
class D3DInitializer : public AwtToolkit::PreloadAction {
|
||||||
|
private:
|
||||||
|
D3DInitializer();
|
||||||
|
~D3DInitializer();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// PreloadAction overrides
|
||||||
|
virtual void InitImpl();
|
||||||
|
virtual void CleanImpl(bool reInit);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static D3DInitializer& GetInstance() { return theInstance; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// single instance
|
||||||
|
static D3DInitializer theInstance;
|
||||||
|
|
||||||
|
// adapter initializer class
|
||||||
|
class D3DAdapterInitializer : public AwtToolkit::PreloadAction {
|
||||||
|
public:
|
||||||
|
void setAdapter(UINT adapter) { this->adapter = adapter; }
|
||||||
|
protected:
|
||||||
|
// PreloadAction overrides
|
||||||
|
virtual void InitImpl();
|
||||||
|
virtual void CleanImpl(bool reInit);
|
||||||
|
private:
|
||||||
|
UINT adapter;
|
||||||
|
};
|
||||||
|
|
||||||
|
// the flag indicates success of COM initialization
|
||||||
|
bool bComInitialized;
|
||||||
|
D3DAdapterInitializer *pAdapterIniters;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
@ -28,7 +28,8 @@
|
|||||||
#include "WindowsFlags.h"
|
#include "WindowsFlags.h"
|
||||||
|
|
||||||
BOOL accelReset; // reset registry 2d acceleration settings
|
BOOL accelReset; // reset registry 2d acceleration settings
|
||||||
BOOL useD3D; // d3d enabled flag
|
BOOL useD3D = TRUE; // d3d enabled flag
|
||||||
|
// initially is TRUE to allow D3D preloading
|
||||||
BOOL forceD3DUsage; // force d3d on or off
|
BOOL forceD3DUsage; // force d3d on or off
|
||||||
jboolean g_offscreenSharing; // JAWT accelerated surface sharing
|
jboolean g_offscreenSharing; // JAWT accelerated surface sharing
|
||||||
BOOL checkRegistry; // Diagnostic tool: outputs 2d registry settings
|
BOOL checkRegistry; // Diagnostic tool: outputs 2d registry settings
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "awt.h"
|
#include "awt.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
|
#include <process.h>
|
||||||
|
|
||||||
//#if defined(_DEBUG) && defined(_MSC_VER) && _MSC_VER >= 1000
|
//#if defined(_DEBUG) && defined(_MSC_VER) && _MSC_VER >= 1000
|
||||||
//#include <crtdbg.h>
|
//#include <crtdbg.h>
|
||||||
@ -92,7 +93,7 @@ extern void DWMResetCompositionEnabled();
|
|||||||
|
|
||||||
/* Initialize the Java VM instance variable when the library is
|
/* Initialize the Java VM instance variable when the library is
|
||||||
first loaded */
|
first loaded */
|
||||||
JavaVM *jvm;
|
JavaVM *jvm = NULL;
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL
|
JNIEXPORT jint JNICALL
|
||||||
JNI_OnLoad(JavaVM *vm, void *reserved)
|
JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||||
@ -362,6 +363,95 @@ HWND AwtToolkit::CreateToolkitWnd(LPCTSTR name)
|
|||||||
return hwnd;
|
return hwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ToolkitThreadProc_Data {
|
||||||
|
bool result;
|
||||||
|
HANDLE hCompleted;
|
||||||
|
|
||||||
|
jobject thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ToolkitThreadProc(void *param)
|
||||||
|
{
|
||||||
|
ToolkitThreadProc_Data *data = (ToolkitThreadProc_Data *)param;
|
||||||
|
|
||||||
|
bool bNotified = false;
|
||||||
|
|
||||||
|
JNIEnv *env;
|
||||||
|
JavaVMAttachArgs attachArgs;
|
||||||
|
attachArgs.version = JNI_VERSION_1_2;
|
||||||
|
attachArgs.name = "AWT-Windows";
|
||||||
|
attachArgs.group = NULL;
|
||||||
|
|
||||||
|
jint res = jvm->AttachCurrentThreadAsDaemon((void **)&env, &attachArgs);
|
||||||
|
if (res < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobject thread = env->NewGlobalRef(data->thread);
|
||||||
|
if (thread != NULL) {
|
||||||
|
jclass cls = env->GetObjectClass(thread);
|
||||||
|
if (cls != NULL) {
|
||||||
|
jmethodID runId = env->GetMethodID(cls, "run", "()V");
|
||||||
|
if (runId != NULL) {
|
||||||
|
data->result = true;
|
||||||
|
::SetEvent(data->hCompleted);
|
||||||
|
bNotified = true;
|
||||||
|
|
||||||
|
env->CallVoidMethod(thread, runId);
|
||||||
|
|
||||||
|
if (env->ExceptionCheck()) {
|
||||||
|
env->ExceptionDescribe();
|
||||||
|
env->ExceptionClear();
|
||||||
|
// TODO: handle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
env->DeleteLocalRef(cls);
|
||||||
|
}
|
||||||
|
env->DeleteGlobalRef(thread);
|
||||||
|
}
|
||||||
|
if (!bNotified) {
|
||||||
|
::SetEvent(data->hCompleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
jvm->DetachCurrentThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: sun_awt_windows_WToolkit
|
||||||
|
* Method: startToolkitThread
|
||||||
|
* Signature: (Ljava/lang/Runnable;)Z
|
||||||
|
*/
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_sun_awt_windows_WToolkit_startToolkitThread(JNIEnv *env, jclass cls, jobject thread)
|
||||||
|
{
|
||||||
|
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||||
|
|
||||||
|
ToolkitThreadProc_Data data;
|
||||||
|
data.result = false;
|
||||||
|
data.thread = env->NewGlobalRef(thread);
|
||||||
|
if (data.thread == NULL) {
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
data.hCompleted = ::CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
|
bool result = tk.GetPreloadThread()
|
||||||
|
.InvokeAndTerminate(ToolkitThreadProc, &data);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
::WaitForSingleObject(data.hCompleted, INFINITE);
|
||||||
|
result = data.result;
|
||||||
|
} else {
|
||||||
|
// no awt preloading
|
||||||
|
// return back to the usual toolkit way
|
||||||
|
}
|
||||||
|
::CloseHandle(data.hCompleted);
|
||||||
|
|
||||||
|
env->DeleteGlobalRef(data.thread);
|
||||||
|
|
||||||
|
return result ? JNI_TRUE : JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL AwtToolkit::Initialize(BOOL localPump) {
|
BOOL AwtToolkit::Initialize(BOOL localPump) {
|
||||||
AwtToolkit& tk = AwtToolkit::GetInstance();
|
AwtToolkit& tk = AwtToolkit::GetInstance();
|
||||||
|
|
||||||
@ -375,6 +465,11 @@ BOOL AwtToolkit::Initialize(BOOL localPump) {
|
|||||||
// ComCtl32Util was constructed but not disposed
|
// ComCtl32Util was constructed but not disposed
|
||||||
ComCtl32Util::GetInstance().InitLibraries();
|
ComCtl32Util::GetInstance().InitLibraries();
|
||||||
|
|
||||||
|
if (!localPump) {
|
||||||
|
// if preload thread was run, terminate it
|
||||||
|
preloadThread.Terminate(true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Register this toolkit's helper window */
|
/* Register this toolkit's helper window */
|
||||||
VERIFY(tk.RegisterClass() != NULL);
|
VERIFY(tk.RegisterClass() != NULL);
|
||||||
|
|
||||||
@ -443,7 +538,7 @@ BOOL AwtToolkit::Dispose() {
|
|||||||
// dispose Direct3D-related resources. This should be done
|
// dispose Direct3D-related resources. This should be done
|
||||||
// before AwtObjectList::Cleanup() as the d3d will attempt to
|
// before AwtObjectList::Cleanup() as the d3d will attempt to
|
||||||
// shutdown when the last of its windows is disposed of
|
// shutdown when the last of its windows is disposed of
|
||||||
D3DPipelineManager::DeleteInstance();
|
D3DInitializer::GetInstance().Clean();
|
||||||
|
|
||||||
AwtObjectList::Cleanup();
|
AwtObjectList::Cleanup();
|
||||||
AwtFont::Cleanup();
|
AwtFont::Cleanup();
|
||||||
@ -1639,6 +1734,270 @@ void AwtToolkit::GetWindowRect(HWND hWnd, LPRECT lpRect)
|
|||||||
::GetWindowRect(hWnd, lpRect);
|
::GetWindowRect(hWnd, lpRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* AWT preloading support
|
||||||
|
*/
|
||||||
|
bool AwtToolkit::PreloadAction::EnsureInited()
|
||||||
|
{
|
||||||
|
DWORD _initThreadId = GetInitThreadID();
|
||||||
|
if (_initThreadId != 0) {
|
||||||
|
// already inited
|
||||||
|
// ensure the action is inited on correct thread
|
||||||
|
PreloadThread &preloadThread
|
||||||
|
= AwtToolkit::GetInstance().GetPreloadThread();
|
||||||
|
if (_initThreadId == preloadThread.GetThreadId()) {
|
||||||
|
if (!preloadThread.IsWrongThread()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// inited on preloadThread (wrongThread), not cleaned yet
|
||||||
|
// have to wait cleanup completion
|
||||||
|
preloadThread.Wait4Finish();
|
||||||
|
} else {
|
||||||
|
// inited on other thread (Toolkit thread?)
|
||||||
|
// consider as correctly inited
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// init on Toolkit thread
|
||||||
|
AwtToolkit::GetInstance().InvokeFunction(InitWrapper, this);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD AwtToolkit::PreloadAction::GetInitThreadID()
|
||||||
|
{
|
||||||
|
CriticalSection::Lock lock(initLock);
|
||||||
|
return initThreadId;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AwtToolkit::PreloadAction::Clean()
|
||||||
|
{
|
||||||
|
DWORD _initThreadId = GetInitThreadID();
|
||||||
|
if (_initThreadId == ::GetCurrentThreadId()) {
|
||||||
|
// inited on this thread
|
||||||
|
Clean(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/
|
||||||
|
void AwtToolkit::PreloadAction::InitWrapper(void *param)
|
||||||
|
{
|
||||||
|
PreloadAction *pThis = (PreloadAction *)param;
|
||||||
|
pThis->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AwtToolkit::PreloadAction::Init()
|
||||||
|
{
|
||||||
|
CriticalSection::Lock lock(initLock);
|
||||||
|
if (initThreadId == 0) {
|
||||||
|
initThreadId = ::GetCurrentThreadId();
|
||||||
|
InitImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AwtToolkit::PreloadAction::Clean(bool reInit) {
|
||||||
|
CriticalSection::Lock lock(initLock);
|
||||||
|
if (initThreadId != 0) {
|
||||||
|
//ASSERT(initThreadId == ::GetCurrentThreadId());
|
||||||
|
CleanImpl(reInit);
|
||||||
|
initThreadId = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PreloadThread implementation
|
||||||
|
AwtToolkit::PreloadThread::PreloadThread()
|
||||||
|
: status(None), wrongThread(false), threadId(0),
|
||||||
|
pActionChain(NULL), pLastProcessedAction(NULL),
|
||||||
|
execFunc(NULL), execParam(NULL)
|
||||||
|
{
|
||||||
|
hFinished = ::CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
hAwake = ::CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
AwtToolkit::PreloadThread::~PreloadThread()
|
||||||
|
{
|
||||||
|
//Terminate(false);
|
||||||
|
::CloseHandle(hFinished);
|
||||||
|
::CloseHandle(hAwake);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AwtToolkit::PreloadThread::AddAction(AwtToolkit::PreloadAction *pAction)
|
||||||
|
{
|
||||||
|
CriticalSection::Lock lock(threadLock);
|
||||||
|
|
||||||
|
if (status > Preloading) {
|
||||||
|
// too late - the thread already terminated or run as toolkit thread
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pActionChain == NULL) {
|
||||||
|
// 1st action
|
||||||
|
pActionChain = pAction;
|
||||||
|
} else {
|
||||||
|
// add the action to the chain
|
||||||
|
PreloadAction *pChain = pActionChain;
|
||||||
|
while (true) {
|
||||||
|
PreloadAction *pNext = pChain->GetNext();
|
||||||
|
if (pNext == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pChain = pNext;
|
||||||
|
}
|
||||||
|
pChain->SetNext(pAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status > None) {
|
||||||
|
// the thread is already running (status == Preloading)
|
||||||
|
AwakeThread();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to start thread
|
||||||
|
::ResetEvent(hAwake);
|
||||||
|
::ResetEvent(hFinished);
|
||||||
|
|
||||||
|
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0x100000, StaticThreadProc,
|
||||||
|
this, 0, &threadId);
|
||||||
|
|
||||||
|
if (hThread == 0) {
|
||||||
|
threadId = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = Preloading;
|
||||||
|
|
||||||
|
::CloseHandle(hThread);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AwtToolkit::PreloadThread::Terminate(bool wrongThread)
|
||||||
|
{
|
||||||
|
CriticalSection::Lock lock(threadLock);
|
||||||
|
|
||||||
|
if (status != Preloading) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
execFunc = NULL;
|
||||||
|
execParam = NULL;
|
||||||
|
this->wrongThread = wrongThread;
|
||||||
|
status = Cleaning;
|
||||||
|
AwakeThread();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AwtToolkit::PreloadThread::InvokeAndTerminate(void(_cdecl *fn)(void *), void *param)
|
||||||
|
{
|
||||||
|
CriticalSection::Lock lock(threadLock);
|
||||||
|
|
||||||
|
if (status != Preloading) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
execFunc = fn;
|
||||||
|
execParam = param;
|
||||||
|
status = fn == NULL ? Cleaning : RunningToolkit;
|
||||||
|
AwakeThread();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/
|
||||||
|
unsigned WINAPI AwtToolkit::PreloadThread::StaticThreadProc(void *param)
|
||||||
|
{
|
||||||
|
AwtToolkit::PreloadThread *pThis = (AwtToolkit::PreloadThread *)param;
|
||||||
|
return pThis->ThreadProc();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned AwtToolkit::PreloadThread::ThreadProc()
|
||||||
|
{
|
||||||
|
void(_cdecl *_execFunc)(void *) = NULL;
|
||||||
|
void *_execParam = NULL;
|
||||||
|
bool _wrongThread = false;
|
||||||
|
|
||||||
|
// initialization
|
||||||
|
while (true) {
|
||||||
|
PreloadAction *pAction;
|
||||||
|
{
|
||||||
|
CriticalSection::Lock lock(threadLock);
|
||||||
|
if (status != Preloading) {
|
||||||
|
// get invoke parameters
|
||||||
|
_execFunc = execFunc;
|
||||||
|
_execParam = execParam;
|
||||||
|
_wrongThread = wrongThread;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pAction = GetNextAction();
|
||||||
|
}
|
||||||
|
if (pAction != NULL) {
|
||||||
|
pAction->Init();
|
||||||
|
} else {
|
||||||
|
::WaitForSingleObject(hAwake, INFINITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// call a function from InvokeAndTerminate
|
||||||
|
if (_execFunc != NULL) {
|
||||||
|
_execFunc(_execParam);
|
||||||
|
} else {
|
||||||
|
// time to terminate..
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanup
|
||||||
|
{
|
||||||
|
CriticalSection::Lock lock(threadLock);
|
||||||
|
pLastProcessedAction = NULL; // goto 1st action in the chain
|
||||||
|
status = Cleaning;
|
||||||
|
}
|
||||||
|
for (PreloadAction *pAction = GetNextAction(); pAction != NULL;
|
||||||
|
pAction = GetNextAction()) {
|
||||||
|
pAction->Clean(_wrongThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't clear threadId! it is used by PreloadAction::EnsureInited
|
||||||
|
|
||||||
|
{
|
||||||
|
CriticalSection::Lock lock(threadLock);
|
||||||
|
status = Finished;
|
||||||
|
}
|
||||||
|
::SetEvent(hFinished);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AwtToolkit::PreloadAction* AwtToolkit::PreloadThread::GetNextAction()
|
||||||
|
{
|
||||||
|
CriticalSection::Lock lock(threadLock);
|
||||||
|
PreloadAction *pAction = (pLastProcessedAction == NULL)
|
||||||
|
? pActionChain
|
||||||
|
: pLastProcessedAction->GetNext();
|
||||||
|
if (pAction != NULL) {
|
||||||
|
pLastProcessedAction = pAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
/* Terminates preload thread (if it's still alive
|
||||||
|
* - it may occur if the application doesn't use AWT).
|
||||||
|
* The function is called from launcher after completion main java thread.
|
||||||
|
*/
|
||||||
|
__declspec(dllexport) void preloadStop()
|
||||||
|
{
|
||||||
|
AwtToolkit::GetInstance().GetPreloadThread().Terminate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Toolkit native methods
|
* Toolkit native methods
|
||||||
*/
|
*/
|
||||||
|
@ -465,6 +465,151 @@ public:
|
|||||||
|
|
||||||
void InstallMouseLowLevelHook();
|
void InstallMouseLowLevelHook();
|
||||||
void UninstallMouseLowLevelHook();
|
void UninstallMouseLowLevelHook();
|
||||||
|
|
||||||
|
|
||||||
|
/* AWT preloading (early Toolkit thread start)
|
||||||
|
*/
|
||||||
|
public:
|
||||||
|
/* Toolkit preload action class.
|
||||||
|
* Preload actions should be registered with
|
||||||
|
* AwtToolkit::getInstance().GetPreloadThread().AddAction().
|
||||||
|
* AwtToolkit thread calls InitImpl method at the beghining
|
||||||
|
* and CleanImpl(false) before exiting for all registered actions.
|
||||||
|
* If an application provides own Toolkit thread
|
||||||
|
* (sun.awt.windows.WToolkit.embeddedInit), the thread calls Clean(true)
|
||||||
|
* for each action.
|
||||||
|
*/
|
||||||
|
class PreloadThread; // forward declaration
|
||||||
|
class PreloadAction {
|
||||||
|
friend class PreloadThread;
|
||||||
|
public:
|
||||||
|
PreloadAction() : initThreadId(0), pNext(NULL) {}
|
||||||
|
virtual ~PreloadAction() {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// called by PreloadThread or as result
|
||||||
|
// of EnsureInited() call (on Toolkit thread!).
|
||||||
|
virtual void InitImpl() = 0;
|
||||||
|
|
||||||
|
// called by PreloadThread (before exiting).
|
||||||
|
// reInit == false: normal shutdown;
|
||||||
|
// reInit == true: PreloadThread is shutting down due external
|
||||||
|
// Toolkit thread was provided.
|
||||||
|
virtual void CleanImpl(bool reInit) = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Initialized the action on the Toolkit thread if not yet initialized.
|
||||||
|
bool EnsureInited();
|
||||||
|
|
||||||
|
// returns thread ID which the action was inited on (0 if not inited)
|
||||||
|
DWORD GetInitThreadID();
|
||||||
|
|
||||||
|
// Allows to deinitialize action earlier.
|
||||||
|
// The method must be called on the Toolkit thread only.
|
||||||
|
// returns true on success,
|
||||||
|
// false if the action was inited on other thread.
|
||||||
|
bool Clean();
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned initThreadId;
|
||||||
|
// lock for Init/Clean
|
||||||
|
CriticalSection initLock;
|
||||||
|
|
||||||
|
// Chain support (for PreloadThread)
|
||||||
|
PreloadAction *pNext; // for action chain used by PreloadThread
|
||||||
|
void SetNext(PreloadAction *pNext) { this->pNext = pNext; }
|
||||||
|
PreloadAction *GetNext() { return pNext; }
|
||||||
|
|
||||||
|
// wrapper for AwtToolkit::InvokeFunction
|
||||||
|
static void InitWrapper(void *param);
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Clean(bool reInit);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Toolkit preload thread class.
|
||||||
|
*/
|
||||||
|
class PreloadThread {
|
||||||
|
public:
|
||||||
|
PreloadThread();
|
||||||
|
~PreloadThread();
|
||||||
|
|
||||||
|
// adds action & start the thread if not yet started
|
||||||
|
bool AddAction(PreloadAction *pAction);
|
||||||
|
|
||||||
|
// sets termination flag; returns true if the thread is running.
|
||||||
|
// wrongThread specifies cause of the termination:
|
||||||
|
// false means termination on the application shutdown;
|
||||||
|
// wrongThread is used as reInit parameter for action cleanup.
|
||||||
|
bool Terminate(bool wrongThread);
|
||||||
|
bool InvokeAndTerminate(void(_cdecl *fn)(void *), void *param);
|
||||||
|
|
||||||
|
// waits for the the thread completion;
|
||||||
|
// use the method after Terminate() only if Terminate() returned true
|
||||||
|
INLINE void Wait4Finish() {
|
||||||
|
::WaitForSingleObject(hFinished, INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE unsigned GetThreadId() {
|
||||||
|
CriticalSection::Lock lock(threadLock);
|
||||||
|
return threadId;
|
||||||
|
}
|
||||||
|
INLINE bool IsWrongThread() {
|
||||||
|
CriticalSection::Lock lock(threadLock);
|
||||||
|
return wrongThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// data access lock
|
||||||
|
CriticalSection threadLock;
|
||||||
|
|
||||||
|
// the thread status
|
||||||
|
enum Status {
|
||||||
|
None = -1, // initial
|
||||||
|
Preloading = 0, // preloading in progress
|
||||||
|
RunningToolkit, // Running as Toolkit thread
|
||||||
|
Cleaning, // exited from Toolkit thread proc, cleaning
|
||||||
|
Finished //
|
||||||
|
} status;
|
||||||
|
|
||||||
|
// "wrong thread" flag
|
||||||
|
bool wrongThread;
|
||||||
|
|
||||||
|
// thread proc (calls (this)param->ThreadProc())
|
||||||
|
static unsigned WINAPI StaticThreadProc(void *param);
|
||||||
|
unsigned ThreadProc();
|
||||||
|
|
||||||
|
INLINE void AwakeThread() {
|
||||||
|
::SetEvent(hAwake);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if threadId != 0 -> we are running
|
||||||
|
unsigned threadId;
|
||||||
|
// ThreadProc sets the event on exit
|
||||||
|
HANDLE hFinished;
|
||||||
|
// ThreadProc waits on the event for NewAction/Terminate/InvokeAndTerminate
|
||||||
|
HANDLE hAwake;
|
||||||
|
|
||||||
|
// function/param to invoke (InvokeAndTerminate)
|
||||||
|
// if execFunc == NULL => just terminate
|
||||||
|
void(_cdecl *execFunc)(void *);
|
||||||
|
void *execParam;
|
||||||
|
|
||||||
|
// action chain
|
||||||
|
PreloadAction *pActionChain;
|
||||||
|
PreloadAction *pLastProcessedAction;
|
||||||
|
|
||||||
|
// returns next action in the list (NULL if no more actions)
|
||||||
|
PreloadAction* GetNextAction();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
INLINE PreloadThread& GetPreloadThread() { return preloadThread; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
PreloadThread preloadThread;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user