Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp
32288 views
1
/*
2
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include "D3DBadHardware.h"
27
#include "D3DPipelineManager.h"
28
#include "D3DRenderQueue.h"
29
#include "WindowsFlags.h"
30
#include "awt_Win32GraphicsDevice.h"
31
32
// state of the adapter prior to initialization
33
#define CONTEXT_NOT_INITED 0
34
// this state is set if adapter initialization had failed
35
#define CONTEXT_INIT_FAILED (-1)
36
// this state is set if adapter was successfully created
37
#define CONTEXT_CREATED 1
38
39
static BOOL bNoHwCheck = (getenv("J2D_D3D_NO_HWCHECK") != NULL);
40
41
D3DPipelineManager *D3DPipelineManager::pMgr = NULL;
42
43
44
D3DPipelineManager * D3DPipelineManager::CreateInstance(void)
45
{
46
if (!IsD3DEnabled() ||
47
FAILED((D3DPipelineManager::CheckOSVersion())) ||
48
FAILED((D3DPipelineManager::GDICheckForBadHardware())))
49
{
50
return NULL;
51
}
52
53
if (pMgr == NULL) {
54
pMgr = new D3DPipelineManager();
55
if (FAILED(pMgr->InitD3D())) {
56
SAFE_DELETE(pMgr);
57
}
58
} else {
59
// this should never happen so to be on the safe side do not
60
// use this unexpected pointer, do not try to release it, just null
61
// it out and fail safely
62
J2dRlsTraceLn1(J2D_TRACE_ERROR,
63
"D3DPPLM::CreateInstance: unexpected instance: 0x%x,"\
64
" abort.", pMgr);
65
pMgr = NULL;
66
}
67
return pMgr;
68
}
69
70
void D3DPipelineManager::DeleteInstance()
71
{
72
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::DeleteInstance()");
73
SAFE_DELETE(pMgr);
74
}
75
76
D3DPipelineManager * D3DPipelineManager::GetInstance(void)
77
{
78
return pMgr;
79
}
80
81
D3DPipelineManager::D3DPipelineManager(void)
82
{
83
pd3d9 = NULL;
84
hLibD3D9 = NULL;
85
pAdapters = NULL;
86
adapterCount = 0;
87
currentFSFocusAdapter = -1;
88
defaultFocusWindow = 0;
89
devType = SelectDeviceType();
90
}
91
92
D3DPipelineManager::~D3DPipelineManager(void)
93
{
94
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::~D3DPipelineManager()");
95
ReleaseD3D();
96
}
97
98
HRESULT D3DPipelineManager::ReleaseD3D(void)
99
{
100
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::ReleaseD3D()");
101
102
ReleaseAdapters();
103
104
SAFE_RELEASE(pd3d9);
105
106
if (hLibD3D9 != NULL) {
107
::FreeLibrary(hLibD3D9);
108
hLibD3D9 = NULL;
109
}
110
111
return S_OK;
112
}
113
114
// Creates a Direct3D9 object and initializes adapters.
115
// If succeeded, returns S_OK, otherwise returns the error code.
116
HRESULT D3DPipelineManager::InitD3D(void)
117
{
118
typedef IDirect3D9 * WINAPI FnDirect3DCreate9(UINT SDKVersion);
119
120
hLibD3D9 = JDK_LoadSystemLibrary("d3d9.dll");
121
if (hLibD3D9 == NULL) {
122
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: no d3d9.dll");
123
return E_FAIL;
124
}
125
126
FnDirect3DCreate9 *d3dcreate9 = NULL;
127
d3dcreate9 = (FnDirect3DCreate9*)
128
::GetProcAddress(hLibD3D9, "Direct3DCreate9");
129
if (d3dcreate9 == NULL) {
130
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: no Direct3DCreate9");
131
::FreeLibrary(hLibD3D9);
132
return E_FAIL;
133
}
134
135
pd3d9 = d3dcreate9(D3D_SDK_VERSION);
136
if (pd3d9 == NULL) {
137
J2dRlsTraceLn(J2D_TRACE_ERROR,
138
"InitD3D: unable to create IDirect3D9 object");
139
::FreeLibrary(hLibD3D9);
140
return E_FAIL;
141
}
142
143
HRESULT res;
144
if (FAILED(res = InitAdapters())) {
145
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitD3D: failed to init adapters");
146
ReleaseD3D();
147
return res;
148
}
149
150
return S_OK;
151
}
152
153
HRESULT D3DPipelineManager::ReleaseAdapters()
154
{
155
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::ReleaseAdapters()");
156
157
D3DRQ_ResetCurrentContextAndDestination();
158
if (pAdapters != NULL) {
159
for (UINT i = 0; i < adapterCount; i++) {
160
if (pAdapters[i].pd3dContext != NULL) {
161
delete pAdapters[i].pd3dContext;
162
}
163
}
164
delete[] pAdapters;
165
pAdapters = NULL;
166
}
167
if (defaultFocusWindow != 0) {
168
DestroyWindow(defaultFocusWindow);
169
UnregisterClass(L"D3DFocusWindow", GetModuleHandle(NULL));
170
defaultFocusWindow = 0;
171
}
172
currentFSFocusAdapter = -1;
173
return S_OK;
174
}
175
176
// static
177
void D3DPipelineManager::NotifyAdapterEventListeners(UINT adapter,
178
jint eventType)
179
{
180
HMONITOR hMon;
181
int gdiScreen;
182
D3DPipelineManager *pMgr;
183
184
// fix for 6946559: if d3d preloading fails jmv may be NULL
185
if (jvm == NULL) {
186
return;
187
}
188
189
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
190
RETURN_IF_NULL(env);
191
192
pMgr = D3DPipelineManager::GetInstance();
193
RETURN_IF_NULL(pMgr);
194
hMon = pMgr->pd3d9->GetAdapterMonitor(adapter);
195
196
/*
197
* If we don't have devices initialized yet, no sense to clear them.
198
*/
199
if (!Devices::GetInstance()){
200
return;
201
}
202
203
gdiScreen = AwtWin32GraphicsDevice::GetScreenFromHMONITOR(hMon);
204
205
JNU_CallStaticMethodByName(env, NULL,
206
"sun/java2d/pipe/hw/AccelDeviceEventNotifier",
207
"eventOccured", "(II)V",
208
gdiScreen, eventType);
209
}
210
211
UINT D3DPipelineManager::GetAdapterOrdinalForScreen(jint gdiScreen)
212
{
213
HMONITOR mHnd = AwtWin32GraphicsDevice::GetMonitor(gdiScreen);
214
if (mHnd == (HMONITOR)0) {
215
return D3DADAPTER_DEFAULT;
216
}
217
return GetAdapterOrdinalByHmon((HMONITOR)mHnd);
218
}
219
220
// static
221
HRESULT D3DPipelineManager::HandleAdaptersChange(HMONITOR *pHMONITORs, UINT monNum)
222
{
223
HRESULT res = S_OK;
224
BOOL bResetD3D = FALSE, bFound;
225
226
D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
227
RETURN_STATUS_IF_NULL(pHMONITORs, E_FAIL);
228
if (pMgr == NULL) {
229
// NULL pMgr is valid when the pipeline is not enabled or if it hasn't
230
// been created yet
231
return S_OK;
232
}
233
RETURN_STATUS_IF_NULL(pMgr->pAdapters, E_FAIL);
234
RETURN_STATUS_IF_NULL(pMgr->pd3d9, E_FAIL);
235
236
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::HandleAdaptersChange");
237
238
if (monNum != pMgr->adapterCount) {
239
J2dTraceLn2(J2D_TRACE_VERBOSE,
240
" number of adapters changed (old=%d, new=%d)",
241
pMgr->adapterCount, monNum);
242
bResetD3D = TRUE;
243
} else {
244
for (UINT i = 0; i < pMgr->adapterCount; i++) {
245
HMONITOR hMon = pMgr->pd3d9->GetAdapterMonitor(i);
246
if (hMon == (HMONITOR)0x0) {
247
J2dTraceLn1(J2D_TRACE_VERBOSE, " adapter %d: removed", i);
248
bResetD3D = TRUE;
249
break;
250
}
251
bFound = FALSE;
252
for (UINT mon = 0; mon < monNum; mon++) {
253
if (pHMONITORs[mon] == hMon) {
254
J2dTraceLn3(J2D_TRACE_VERBOSE,
255
" adapter %d: found hmnd[%d]=0x%x", i, mon, hMon);
256
bFound = TRUE;
257
break;
258
}
259
}
260
if (!bFound) {
261
J2dTraceLn2(J2D_TRACE_VERBOSE,
262
" adapter %d: could not find hmnd=0x%x "\
263
"in the list of new hmnds", i, hMon);
264
bResetD3D = TRUE;
265
break;
266
}
267
}
268
}
269
270
if (bResetD3D) {
271
J2dTraceLn(J2D_TRACE_VERBOSE, " adapters changed: resetting d3d");
272
pMgr->ReleaseD3D();
273
res = pMgr->InitD3D();
274
}
275
return res;
276
}
277
278
HRESULT D3DPipelineManager::HandleLostDevices()
279
{
280
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::HandleLostDevices()");
281
BOOL bAllClear = TRUE;
282
283
HWND hwnd = GetCurrentFocusWindow();
284
if (hwnd != defaultFocusWindow) {
285
// we're in full-screen mode
286
WINDOWPLACEMENT wp;
287
::ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
288
wp.length = sizeof(WINDOWPLACEMENT);
289
::GetWindowPlacement(hwnd, &wp);
290
291
// Only attempt to restore the devices if we're in full-screen mode
292
// and the fs window is active; sleep otherwise.
293
// Restoring a window while minimized causes problems on Vista:
294
// sometimes we restore the window too quickly and it pops up back from
295
// minimized state when the device is restored.
296
//
297
// WARNING: this is a sleep on the Toolkit thread! We may reconsider
298
// this if we find any issues later.
299
if ((wp.showCmd & SW_SHOWMINNOACTIVE) && !(wp.showCmd & SW_SHOWNORMAL)){
300
static DWORD prevCallTime = 0;
301
J2dTraceLn(J2D_TRACE_VERBOSE, " fs focus window is minimized");
302
DWORD currentTime = ::GetTickCount();
303
if ((currentTime - prevCallTime) < 100) {
304
J2dTraceLn(J2D_TRACE_VERBOSE, " tight loop detected, sleep");
305
::Sleep(100);
306
}
307
prevCallTime = currentTime;
308
return D3DERR_DEVICELOST;
309
}
310
}
311
if (pAdapters != NULL) {
312
for (UINT i = 0; i < adapterCount; i++) {
313
if (pAdapters[i].pd3dContext != NULL) {
314
J2dTraceLn1(J2D_TRACE_VERBOSE,
315
" HandleLostDevices: checking adapter %d", i);
316
D3DContext *d3dc = pAdapters[i].pd3dContext;
317
if (FAILED(d3dc->CheckAndResetDevice())) {
318
bAllClear = FALSE;
319
}
320
}
321
}
322
}
323
return bAllClear ? S_OK : D3DERR_DEVICELOST;
324
}
325
326
HRESULT D3DPipelineManager::InitAdapters()
327
{
328
HRESULT res = E_FAIL;
329
330
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::InitAdapters()");
331
if (pAdapters != NULL) {
332
ReleaseAdapters();
333
}
334
335
adapterCount = pd3d9->GetAdapterCount();
336
pAdapters = new D3DAdapter[adapterCount];
337
if (pAdapters == NULL) {
338
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitAdapters: out of memory");
339
adapterCount = 0;
340
return E_FAIL;
341
}
342
ZeroMemory(pAdapters, adapterCount * sizeof(D3DAdapter));
343
344
res = CheckAdaptersInfo();
345
RETURN_STATUS_IF_FAILED(res);
346
347
currentFSFocusAdapter = -1;
348
if (CreateDefaultFocusWindow() == 0) {
349
return E_FAIL;
350
}
351
352
return S_OK;
353
}
354
355
// static
356
HRESULT
357
D3DPipelineManager::CheckOSVersion()
358
{
359
// require Windows XP or newer client-class OS
360
if (IS_WINVER_ATLEAST(5, 1) &&
361
!D3DPPLM_OsVersionMatches(OS_WINSERV_2008R2|OS_WINSERV_2008|
362
OS_WINSERV_2003))
363
{
364
J2dTraceLn(J2D_TRACE_INFO,
365
"D3DPPLM::CheckOSVersion: Windows XP or newer client-classs"\
366
" OS detected, passed");
367
return S_OK;
368
}
369
J2dRlsTraceLn(J2D_TRACE_ERROR,
370
"D3DPPLM::CheckOSVersion: Windows 2000 or earlier (or a "\
371
"server) OS detected, failed");
372
if (bNoHwCheck) {
373
J2dRlsTraceLn(J2D_TRACE_WARNING,
374
" OS check overridden via J2D_D3D_NO_HWCHECK");
375
return S_OK;
376
}
377
return E_FAIL;
378
}
379
380
// static
381
HRESULT
382
D3DPipelineManager::GDICheckForBadHardware()
383
{
384
DISPLAY_DEVICE dd;
385
dd.cb = sizeof(DISPLAY_DEVICE);
386
387
int failedDevices = 0;
388
int attachedDevices = 0;
389
int i = 0;
390
WCHAR *id;
391
WCHAR vendorId[5];
392
WCHAR deviceId[5];
393
DWORD dwDId, dwVId;
394
395
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GDICheckForBadHardware");
396
397
// i<20 is to guard against buggy drivers
398
while (EnumDisplayDevices(NULL, i, &dd, 0) && i < 20) {
399
if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) {
400
attachedDevices++;
401
id = dd.DeviceID;
402
if (wcslen(id) > 21) {
403
// get vendor ID
404
wcsncpy(vendorId, id+8, 4);
405
int args1 = swscanf(vendorId, L"%X", &dwVId);
406
407
// get device ID
408
wcsncpy(deviceId, id+17, 4);
409
int args2 = swscanf(deviceId, L"%X", &dwDId);
410
411
if (args1 == 1 && args2 == 1) {
412
J2dTraceLn2(J2D_TRACE_VERBOSE,
413
" device: vendorID=0x%04x, deviceId=0x%04x",
414
dwVId, dwDId);
415
// since we don't have a driver version here we will
416
// just ask to ignore the version for now; bad hw
417
// entries with specific drivers information will be
418
// processed later when d3d is initialized and we can
419
// obtain a driver version
420
if (FAILED(CheckForBadHardware(dwVId, dwDId, MAX_VERSION))){
421
failedDevices++;
422
}
423
}
424
}
425
}
426
427
i++;
428
}
429
430
if (failedDevices == attachedDevices) {
431
J2dRlsTraceLn(J2D_TRACE_ERROR,
432
"D3DPPLM::GDICheckForBadHardware: no suitable devices found");
433
return E_FAIL;
434
}
435
436
return S_OK;
437
}
438
439
BOOL D3DPPLM_OsVersionMatches(USHORT osInfo) {
440
static USHORT currentOS = OS_UNDEFINED;
441
442
if (currentOS == OS_UNDEFINED) {
443
BOOL bVersOk;
444
OSVERSIONINFOEX osvi;
445
446
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
447
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
448
449
bVersOk = GetVersionEx((OSVERSIONINFO *) &osvi);
450
451
J2dRlsTrace(J2D_TRACE_INFO, "[I] OS Version = ");
452
if (bVersOk && osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
453
osvi.dwMajorVersion > 4)
454
{
455
if (osvi.dwMajorVersion >= 6 && osvi.dwMinorVersion == 0) {
456
if (osvi.wProductType == VER_NT_WORKSTATION) {
457
J2dRlsTrace(J2D_TRACE_INFO, "OS_VISTA\n");
458
currentOS = OS_VISTA;
459
} else {
460
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2008\n");
461
currentOS = OS_WINSERV_2008;
462
}
463
} else if (osvi.dwMajorVersion >= 6 && osvi.dwMinorVersion >= 1) {
464
if (osvi.wProductType == VER_NT_WORKSTATION) {
465
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINDOWS7 or newer\n");
466
currentOS = OS_WINDOWS7;
467
} else {
468
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2008R2 or newer\n");
469
currentOS = OS_WINSERV_2008R2;
470
}
471
} else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {
472
if (osvi.wProductType == VER_NT_WORKSTATION) {
473
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINXP_64\n");
474
currentOS = OS_WINXP_64;
475
} else {
476
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2003\n");
477
currentOS = OS_WINSERV_2003;
478
}
479
} else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {
480
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINXP ");
481
currentOS = OS_WINXP;
482
if (osvi.wSuiteMask & VER_SUITE_PERSONAL) {
483
J2dRlsTrace(J2D_TRACE_INFO, "Home\n");
484
} else {
485
J2dRlsTrace(J2D_TRACE_INFO, "Pro\n");
486
}
487
} else {
488
J2dRlsTrace2(J2D_TRACE_INFO,
489
"OS_UNKNOWN: dwMajorVersion=%d dwMinorVersion=%d\n",
490
osvi.dwMajorVersion, osvi.dwMinorVersion);
491
currentOS = OS_UNKNOWN;
492
}
493
} else {
494
if (bVersOk) {
495
J2dRlsTrace2(J2D_TRACE_INFO,
496
"OS_UNKNOWN: dwPlatformId=%d dwMajorVersion=%d\n",
497
osvi.dwPlatformId, osvi.dwMajorVersion);
498
} else {
499
J2dRlsTrace(J2D_TRACE_INFO,"OS_UNKNOWN: GetVersionEx failed\n");
500
}
501
currentOS = OS_UNKNOWN;
502
}
503
}
504
return (currentOS & osInfo);
505
}
506
507
// static
508
HRESULT
509
D3DPipelineManager::CheckForBadHardware(DWORD vId, DWORD dId, LONGLONG version)
510
{
511
DWORD vendorId, deviceId;
512
UINT adapterInfo = 0;
513
514
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::CheckForBadHardware");
515
516
while ((vendorId = badHardware[adapterInfo].VendorId) != 0x0000 &&
517
(deviceId = badHardware[adapterInfo].DeviceId) != 0x0000)
518
{
519
if (vendorId == vId && (deviceId == dId || deviceId == ALL_DEVICEIDS)) {
520
LONGLONG goodVersion = badHardware[adapterInfo].DriverVersion;
521
USHORT osInfo = badHardware[adapterInfo].OsInfo;
522
// the hardware check fails if:
523
// - we have an entry for this OS and
524
// - hardware is bad for all driver versions (NO_VERSION), or
525
// we have a driver version which is older than the
526
// minimum required for this OS
527
if (D3DPPLM_OsVersionMatches(osInfo) &&
528
(goodVersion == NO_VERSION || version < goodVersion))
529
{
530
J2dRlsTraceLn2(J2D_TRACE_ERROR,
531
"D3DPPLM::CheckForBadHardware: found matching "\
532
"hardware: VendorId=0x%04x DeviceId=0x%04x",
533
vendorId, deviceId);
534
if (goodVersion != NO_VERSION) {
535
// this was a match by the driver version
536
LARGE_INTEGER li;
537
li.QuadPart = goodVersion;
538
J2dRlsTraceLn(J2D_TRACE_ERROR,
539
" bad driver found, device disabled");
540
J2dRlsTraceLn4(J2D_TRACE_ERROR,
541
" update your driver to at "\
542
"least version %d.%d.%d.%d",
543
HIWORD(li.HighPart), LOWORD(li.HighPart),
544
HIWORD(li.LowPart), LOWORD(li.LowPart));
545
} else {
546
// this was a match by the device (no good driver for this
547
// device)
548
J2dRlsTraceLn(J2D_TRACE_ERROR,
549
"D3DPPLM::CheckForBadHardware: bad hardware "\
550
"found, device disabled");
551
}
552
if (!bNoHwCheck) {
553
return D3DERR_INVALIDDEVICE;
554
}
555
J2dRlsTraceLn(J2D_TRACE_WARNING, " Warning: hw/driver match "\
556
"overridden (via J2D_D3D_NO_HWCHECK)");
557
}
558
}
559
adapterInfo++;
560
}
561
562
return S_OK;
563
}
564
565
HRESULT D3DPipelineManager::CheckAdaptersInfo()
566
{
567
D3DADAPTER_IDENTIFIER9 aid;
568
UINT failedAdaptersCount = 0;
569
570
J2dRlsTraceLn(J2D_TRACE_INFO, "CheckAdaptersInfo");
571
J2dRlsTraceLn(J2D_TRACE_INFO, "------------------");
572
for (UINT Adapter = 0; Adapter < adapterCount; Adapter++) {
573
574
if (FAILED(pd3d9->GetAdapterIdentifier(Adapter, 0, &aid))) {
575
pAdapters[Adapter].state = CONTEXT_INIT_FAILED;
576
failedAdaptersCount++;
577
continue;
578
}
579
580
J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Ordinal : %d", Adapter);
581
J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Handle : 0x%x",
582
pd3d9->GetAdapterMonitor(Adapter));
583
J2dRlsTraceLn1(J2D_TRACE_INFO, "Description : %s",
584
aid.Description);
585
J2dRlsTraceLn2(J2D_TRACE_INFO, "GDI Name, Driver : %s, %s",
586
aid.DeviceName, aid.Driver);
587
J2dRlsTraceLn1(J2D_TRACE_INFO, "Vendor Id : 0x%04x",
588
aid.VendorId);
589
J2dRlsTraceLn1(J2D_TRACE_INFO, "Device Id : 0x%04x",
590
aid.DeviceId);
591
J2dRlsTraceLn1(J2D_TRACE_INFO, "SubSys Id : 0x%x",
592
aid.SubSysId);
593
J2dRlsTraceLn4(J2D_TRACE_INFO, "Driver Version : %d.%d.%d.%d",
594
HIWORD(aid.DriverVersion.HighPart),
595
LOWORD(aid.DriverVersion.HighPart),
596
HIWORD(aid.DriverVersion.LowPart),
597
LOWORD(aid.DriverVersion.LowPart));
598
J2dRlsTrace3(J2D_TRACE_INFO,
599
"[I] GUID : {%08X-%04X-%04X-",
600
aid.DeviceIdentifier.Data1,
601
aid.DeviceIdentifier.Data2,
602
aid.DeviceIdentifier.Data3);
603
J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X-%02X%02X",
604
aid.DeviceIdentifier.Data4[0],
605
aid.DeviceIdentifier.Data4[1],
606
aid.DeviceIdentifier.Data4[2],
607
aid.DeviceIdentifier.Data4[3]);
608
J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X%02X%02X}\n",
609
aid.DeviceIdentifier.Data4[4],
610
aid.DeviceIdentifier.Data4[5],
611
aid.DeviceIdentifier.Data4[6],
612
aid.DeviceIdentifier.Data4[7]);
613
614
if (FAILED(CheckForBadHardware(aid.VendorId, aid.DeviceId,
615
aid.DriverVersion.QuadPart)) ||
616
FAILED(CheckDeviceCaps(Adapter)) ||
617
FAILED(D3DEnabledOnAdapter(Adapter)))
618
{
619
pAdapters[Adapter].state = CONTEXT_INIT_FAILED;
620
failedAdaptersCount++;
621
}
622
J2dRlsTraceLn(J2D_TRACE_INFO, "------------------");
623
}
624
625
if (failedAdaptersCount == adapterCount) {
626
J2dRlsTraceLn(J2D_TRACE_ERROR,
627
"D3DPPLM::CheckAdaptersInfo: no suitable adapters found");
628
return E_FAIL;
629
}
630
631
return S_OK;
632
}
633
634
D3DDEVTYPE D3DPipelineManager::SelectDeviceType()
635
{
636
char *pRas = getenv("J2D_D3D_RASTERIZER");
637
D3DDEVTYPE dtype = D3DDEVTYPE_HAL;
638
if (pRas != NULL) {
639
J2dRlsTrace(J2D_TRACE_WARNING, "[W] D3DPPLM::SelectDeviceType: ");
640
if (strncmp(pRas, "ref", 3) == 0 || strncmp(pRas, "rgb", 3) == 0) {
641
J2dRlsTrace(J2D_TRACE_WARNING, "ref rasterizer selected");
642
dtype = D3DDEVTYPE_REF;
643
} else if (strncmp(pRas, "hal",3) == 0 || strncmp(pRas, "tnl",3) == 0) {
644
J2dRlsTrace(J2D_TRACE_WARNING, "hal rasterizer selected");
645
dtype = D3DDEVTYPE_HAL;
646
} else if (strncmp(pRas, "nul", 3) == 0) {
647
J2dRlsTrace(J2D_TRACE_WARNING, "nullref rasterizer selected");
648
dtype = D3DDEVTYPE_NULLREF;
649
} else {
650
J2dRlsTrace1(J2D_TRACE_WARNING,
651
"unknown rasterizer: %s, only (ref|hal|nul) "\
652
"supported, hal selected instead", pRas);
653
}
654
J2dRlsTrace(J2D_TRACE_WARNING, "\n");
655
}
656
return dtype;
657
}
658
659
#define CHECK_CAP(FLAG, CAP) \
660
do { \
661
if (!((FLAG)&CAP)) { \
662
J2dRlsTraceLn2(J2D_TRACE_ERROR, \
663
"D3DPPLM::CheckDeviceCaps: adapter %d: Failed "\
664
"(cap %s not supported)", \
665
adapter, #CAP); \
666
return E_FAIL; \
667
} \
668
} while (0)
669
670
HRESULT D3DPipelineManager::CheckDeviceCaps(UINT adapter)
671
{
672
HRESULT res;
673
D3DCAPS9 d3dCaps;
674
675
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::CheckDeviceCaps");
676
677
res = pd3d9->GetDeviceCaps(adapter, devType, &d3dCaps);
678
RETURN_STATUS_IF_FAILED(res);
679
680
CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_DRAWPRIMTLVERTEX);
681
682
// by requiring hardware tnl we are hoping for better drivers quality
683
if (!IsD3DForced()) {
684
// fail if not hw tnl unless d3d was forced
685
CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWTRANSFORMANDLIGHT);
686
}
687
if (d3dCaps.DeviceType == D3DDEVTYPE_HAL) {
688
CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWRASTERIZATION);
689
}
690
691
CHECK_CAP(d3dCaps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST);
692
693
CHECK_CAP(d3dCaps.Caps3, D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD);
694
695
CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE);
696
CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_BLENDOP);
697
CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_MASKZ);
698
699
CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_ALWAYS);
700
CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_LESS);
701
702
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ZERO);
703
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ONE);
704
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_SRCALPHA);
705
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_DESTALPHA);
706
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVSRCALPHA);
707
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVDESTALPHA);
708
709
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ZERO);
710
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ONE);
711
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_SRCALPHA);
712
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_DESTALPHA);
713
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA);
714
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVDESTALPHA);
715
716
CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP);
717
CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_WRAP);
718
719
CHECK_CAP(d3dCaps.TextureOpCaps, D3DTEXOPCAPS_MODULATE);
720
721
if (d3dCaps.PixelShaderVersion < D3DPS_VERSION(2,0) && !IsD3DForced()) {
722
J2dRlsTraceLn1(J2D_TRACE_ERROR,
723
"D3DPPLM::CheckDeviceCaps: adapter %d: Failed "\
724
"(pixel shaders 2.0 required)", adapter);
725
return E_FAIL;
726
}
727
728
J2dRlsTraceLn1(J2D_TRACE_INFO,
729
"D3DPPLM::CheckDeviceCaps: adapter %d: Passed", adapter);
730
return S_OK;
731
}
732
733
734
HRESULT D3DPipelineManager::D3DEnabledOnAdapter(UINT adapter)
735
{
736
HRESULT res;
737
D3DDISPLAYMODE dm;
738
739
res = pd3d9->GetAdapterDisplayMode(adapter, &dm);
740
RETURN_STATUS_IF_FAILED(res);
741
742
res = pd3d9->CheckDeviceType(adapter, devType, dm.Format, dm.Format, TRUE);
743
if (FAILED(res)) {
744
J2dRlsTraceLn1(J2D_TRACE_ERROR,
745
"D3DPPLM::D3DEnabledOnAdapter: no " \
746
"suitable d3d device on adapter %d", adapter);
747
}
748
749
return res;
750
}
751
752
UINT D3DPipelineManager::GetAdapterOrdinalByHmon(HMONITOR hMon)
753
{
754
UINT ret = D3DADAPTER_DEFAULT;
755
756
if (pd3d9 != NULL) {
757
UINT adapterCount = pd3d9->GetAdapterCount();
758
for (UINT adapter = 0; adapter < adapterCount; adapter++) {
759
HMONITOR hm = pd3d9->GetAdapterMonitor(adapter);
760
if (hm == hMon) {
761
ret = adapter;
762
break;
763
}
764
}
765
}
766
return ret;
767
}
768
769
D3DFORMAT
770
D3DPipelineManager::GetMatchingDepthStencilFormat(UINT adapterOrdinal,
771
D3DFORMAT adapterFormat,
772
D3DFORMAT renderTargetFormat)
773
{
774
static D3DFORMAT formats[] =
775
{ D3DFMT_D16, D3DFMT_D32, D3DFMT_D24S8, D3DFMT_D24X8 };
776
D3DFORMAT newFormat = D3DFMT_UNKNOWN;
777
HRESULT res;
778
for (int i = 0; i < 4; i++) {
779
res = pd3d9->CheckDeviceFormat(adapterOrdinal,
780
devType, adapterFormat, D3DUSAGE_DEPTHSTENCIL,
781
D3DRTYPE_SURFACE, formats[i]);
782
if (FAILED(res)) continue;
783
784
res = pd3d9->CheckDepthStencilMatch(adapterOrdinal,
785
devType, adapterFormat, renderTargetFormat, formats[i]);
786
if (FAILED(res)) continue;
787
newFormat = formats[i];
788
break;
789
}
790
return newFormat;
791
}
792
793
HWND D3DPipelineManager::CreateDefaultFocusWindow()
794
{
795
UINT adapterOrdinal = D3DADAPTER_DEFAULT;
796
797
J2dTraceLn1(J2D_TRACE_INFO,
798
"D3DPPLM::CreateDefaultFocusWindow: adapter=%d",
799
adapterOrdinal);
800
801
if (defaultFocusWindow != 0) {
802
J2dRlsTraceLn(J2D_TRACE_WARNING,
803
"D3DPPLM::CreateDefaultFocusWindow: "\
804
"existing default focus window!");
805
return defaultFocusWindow;
806
}
807
808
WNDCLASS wc;
809
ZeroMemory(&wc, sizeof(WNDCLASS));
810
wc.hInstance = GetModuleHandle(NULL);
811
wc.lpfnWndProc = DefWindowProc;
812
wc.lpszClassName = L"D3DFocusWindow";
813
if (RegisterClass(&wc) == 0) {
814
J2dRlsTraceLn(J2D_TRACE_ERROR,
815
"D3DPPLM::CreateDefaultFocusWindow: "\
816
"error registering window class");
817
return 0;
818
}
819
820
MONITORINFO mi;
821
ZeroMemory(&mi, sizeof(MONITORINFO));
822
mi.cbSize = sizeof(MONITORINFO);
823
HMONITOR hMon = pd3d9->GetAdapterMonitor(adapterOrdinal);
824
if (hMon == 0 || !GetMonitorInfo(hMon, (LPMONITORINFO)&mi)) {
825
J2dRlsTraceLn1(J2D_TRACE_ERROR,
826
"D3DPPLM::CreateDefaultFocusWindow: "\
827
"error getting monitor info for adapter=%d", adapterOrdinal);
828
return 0;
829
}
830
831
HWND hWnd = CreateWindow(L"D3DFocusWindow", L"D3DFocusWindow", WS_POPUP,
832
mi.rcMonitor.left, mi.rcMonitor.top, 1, 1,
833
NULL, NULL, GetModuleHandle(NULL), NULL);
834
if (hWnd == 0) {
835
J2dRlsTraceLn(J2D_TRACE_ERROR,
836
"D3DPPLM::CreateDefaultFocusWindow: CreateWindow failed");
837
} else {
838
J2dTraceLn2(J2D_TRACE_INFO,
839
" Created default focus window %x for adapter %d",
840
hWnd, adapterOrdinal);
841
defaultFocusWindow = hWnd;
842
}
843
return hWnd;
844
}
845
846
HWND D3DPipelineManager::GetCurrentFocusWindow()
847
{
848
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GetCurrentFocusWindow");
849
if (currentFSFocusAdapter < 0) {
850
J2dTraceLn1(J2D_TRACE_VERBOSE,
851
" no fs windows, using default focus window=0x%x",
852
defaultFocusWindow);
853
return defaultFocusWindow;
854
}
855
J2dTraceLn1(J2D_TRACE_VERBOSE, " using fs window=0x%x",
856
pAdapters[currentFSFocusAdapter].fsFocusWindow);
857
return pAdapters[currentFSFocusAdapter].fsFocusWindow;
858
}
859
860
HWND D3DPipelineManager::SetFSFocusWindow(UINT adapterOrdinal, HWND hWnd)
861
{
862
J2dTraceLn2(J2D_TRACE_INFO,"D3DPPLM::SetFSFocusWindow hwnd=0x%x adapter=%d",
863
hWnd, adapterOrdinal);
864
865
HWND prev = pAdapters[adapterOrdinal].fsFocusWindow;
866
pAdapters[adapterOrdinal].fsFocusWindow = hWnd;
867
if (currentFSFocusAdapter < 0) {
868
J2dTraceLn(J2D_TRACE_VERBOSE, " first full-screen window");
869
// first fs window
870
currentFSFocusAdapter = adapterOrdinal;
871
// REMIND: we might want to reset the rest of the context here as well
872
// like we do when the an adapter exits fs mode; currently they will
873
// be reset sometime later
874
} else {
875
// there's already a fs window
876
if (currentFSFocusAdapter == adapterOrdinal) {
877
// it's current fs window => we're exiting fs mode on this adapter;
878
// look for a new fs focus window
879
if (hWnd == 0) {
880
UINT i;
881
currentFSFocusAdapter = -1;
882
for (i = 0; i < adapterCount; i++) {
883
if (pAdapters[i].fsFocusWindow != 0) {
884
J2dTraceLn1(J2D_TRACE_VERBOSE,
885
" adapter %d is still in fs mode", i);
886
currentFSFocusAdapter = i;
887
break;
888
}
889
}
890
// we have to reset all devices any time current focus device
891
// exits fs mode, and also to prevent some of them being left in
892
// a lost state when the last device exits fs - when non-last
893
// adapters exit fs mode they would not be able to create the
894
// device and will be put in a lost state forever
895
HRESULT res;
896
J2dTraceLn(J2D_TRACE_VERBOSE,
897
" adapter exited full-screen, reset all adapters");
898
for (i = 0; i < adapterCount; i++) {
899
if (pAdapters[i].pd3dContext != NULL) {
900
res = pAdapters[i].pd3dContext->ResetContext();
901
D3DRQ_MarkLostIfNeeded(res,
902
D3DRQ_GetCurrentDestination());
903
}
904
}
905
} else {
906
J2dTraceLn1(J2D_TRACE_WARNING,
907
"D3DPM::SetFSFocusWindow: setting the fs "\
908
"window again for adapter %d", adapterOrdinal);
909
}
910
}
911
}
912
return prev;
913
}
914
915
HRESULT D3DPipelineManager::GetD3DContext(UINT adapterOrdinal,
916
D3DContext **ppd3dContext)
917
{
918
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GetD3DContext");
919
920
HRESULT res = S_OK;
921
if (adapterOrdinal < 0 || adapterOrdinal >= adapterCount ||
922
pAdapters == NULL ||
923
pAdapters[adapterOrdinal].state == CONTEXT_INIT_FAILED)
924
{
925
J2dRlsTraceLn1(J2D_TRACE_ERROR,
926
"D3DPPLM::GetD3DContext: invalid parameters or "\
927
"failed init for adapter %d", adapterOrdinal);
928
*ppd3dContext = NULL;
929
return E_FAIL;
930
}
931
932
if (pAdapters[adapterOrdinal].state == CONTEXT_NOT_INITED) {
933
D3DContext *pCtx = NULL;
934
935
if (pAdapters[adapterOrdinal].pd3dContext != NULL) {
936
J2dTraceLn1(J2D_TRACE_ERROR, " non-null context in "\
937
"uninitialized adapter %d", adapterOrdinal);
938
res = E_FAIL;
939
} else {
940
J2dTraceLn1(J2D_TRACE_VERBOSE,
941
" initializing context for adapter %d",adapterOrdinal);
942
943
if (SUCCEEDED(res = D3DEnabledOnAdapter(adapterOrdinal))) {
944
res = D3DContext::CreateInstance(pd3d9, adapterOrdinal, &pCtx);
945
if (FAILED(res)) {
946
J2dRlsTraceLn1(J2D_TRACE_ERROR,
947
"D3DPPLM::GetD3DContext: failed to create context "\
948
"for adapter=%d", adapterOrdinal);
949
}
950
} else {
951
J2dRlsTraceLn1(J2D_TRACE_ERROR,
952
"D3DPPLM::GetContext: no d3d on adapter %d",adapterOrdinal);
953
}
954
}
955
pAdapters[adapterOrdinal].state =
956
SUCCEEDED(res) ? CONTEXT_CREATED : CONTEXT_INIT_FAILED;
957
pAdapters[adapterOrdinal].pd3dContext = pCtx;
958
}
959
*ppd3dContext = pAdapters[adapterOrdinal].pd3dContext;
960
return res;
961
}
962
963
964
//==============================================================
965
// D3DInitializer
966
//==============================================================
967
968
D3DInitializer D3DInitializer::theInstance;
969
970
D3DInitializer::D3DInitializer()
971
: bComInitialized(false), pAdapterIniters(NULL)
972
{
973
}
974
975
D3DInitializer::~D3DInitializer()
976
{
977
if (pAdapterIniters) {
978
delete[] pAdapterIniters;
979
}
980
}
981
982
void D3DInitializer::InitImpl()
983
{
984
J2dRlsTraceLn(J2D_TRACE_INFO, "D3DInitializer::InitImpl");
985
if (SUCCEEDED(::CoInitialize(NULL))) {
986
bComInitialized = true;
987
}
988
D3DPipelineManager *pMgr = D3DPipelineManager::CreateInstance();
989
if (pMgr != NULL) {
990
// init adapters if we are preloading
991
if (AwtToolkit::GetInstance().GetPreloadThread().OnPreloadThread()) {
992
UINT adapterCount = pMgr->adapterCount;
993
994
pAdapterIniters = new D3DAdapterInitializer[adapterCount];
995
for (UINT i=0; i<adapterCount; i++) {
996
pAdapterIniters[i].setAdapter(i);
997
AwtToolkit::GetInstance().GetPreloadThread().AddAction(&pAdapterIniters[i]);
998
}
999
}
1000
}
1001
}
1002
1003
void D3DInitializer::CleanImpl(bool reInit)
1004
{
1005
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DInitializer::CleanImpl (%s)",
1006
reInit ? "RELAUNCH" : "normal");
1007
D3DPipelineManager::DeleteInstance();
1008
if (bComInitialized) {
1009
CoUninitialize();
1010
}
1011
}
1012
1013
1014
void D3DInitializer::D3DAdapterInitializer::InitImpl()
1015
{
1016
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) started", adapter);
1017
1018
D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
1019
if (pMgr == NULL) {
1020
return;
1021
}
1022
1023
D3DContext *pd3dContext;
1024
pMgr->GetD3DContext(adapter, &pd3dContext);
1025
1026
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) finished", adapter);
1027
}
1028
1029
void D3DInitializer::D3DAdapterInitializer::CleanImpl(bool reInit)
1030
{
1031
// nothing to do - D3DPipelineManager cleans adapters
1032
}
1033
1034
1035
extern "C" {
1036
/*
1037
* Export function to start D3D preloading
1038
* (called from java/javaw - see src/windows/bin/java-md.c)
1039
*/
1040
__declspec(dllexport) int preloadD3D()
1041
{
1042
J2dRlsTraceLn(J2D_TRACE_INFO, "AWT warmup: preloadD3D");
1043
AwtToolkit::GetInstance().GetPreloadThread().AddAction(&D3DInitializer::GetInstance());
1044
return 1;
1045
}
1046
1047
}
1048
1049
1050