Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/windows/native/libawt/java2d/d3d/D3DPipelineManager.cpp
41159 views
1
/*
2
* Copyright (c) 2007, 2016, 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
UINT D3DPipelineManager::GetAdapterOrdinalForScreen(jint gdiScreen)
177
{
178
HMONITOR mHnd = AwtWin32GraphicsDevice::GetMonitor(gdiScreen);
179
if (mHnd == (HMONITOR)0) {
180
return D3DADAPTER_DEFAULT;
181
}
182
return GetAdapterOrdinalByHmon((HMONITOR)mHnd);
183
}
184
185
// static
186
HRESULT D3DPipelineManager::HandleAdaptersChange(HMONITOR *pHMONITORs, UINT monNum)
187
{
188
HRESULT res = S_OK;
189
BOOL bResetD3D = FALSE, bFound;
190
191
D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
192
RETURN_STATUS_IF_NULL(pHMONITORs, E_FAIL);
193
if (pMgr == NULL) {
194
// NULL pMgr is valid when the pipeline is not enabled or if it hasn't
195
// been created yet
196
return S_OK;
197
}
198
RETURN_STATUS_IF_NULL(pMgr->pAdapters, E_FAIL);
199
RETURN_STATUS_IF_NULL(pMgr->pd3d9, E_FAIL);
200
201
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::HandleAdaptersChange");
202
203
if (monNum != pMgr->adapterCount) {
204
J2dTraceLn2(J2D_TRACE_VERBOSE,
205
" number of adapters changed (old=%d, new=%d)",
206
pMgr->adapterCount, monNum);
207
bResetD3D = TRUE;
208
} else {
209
for (UINT i = 0; i < pMgr->adapterCount; i++) {
210
HMONITOR hMon = pMgr->pd3d9->GetAdapterMonitor(i);
211
if (hMon == (HMONITOR)0x0) {
212
J2dTraceLn1(J2D_TRACE_VERBOSE, " adapter %d: removed", i);
213
bResetD3D = TRUE;
214
break;
215
}
216
bFound = FALSE;
217
for (UINT mon = 0; mon < monNum; mon++) {
218
if (pHMONITORs[mon] == hMon) {
219
J2dTraceLn3(J2D_TRACE_VERBOSE,
220
" adapter %d: found hmnd[%d]=0x%x", i, mon, hMon);
221
bFound = TRUE;
222
break;
223
}
224
}
225
if (!bFound) {
226
J2dTraceLn2(J2D_TRACE_VERBOSE,
227
" adapter %d: could not find hmnd=0x%x "\
228
"in the list of new hmnds", i, hMon);
229
bResetD3D = TRUE;
230
break;
231
}
232
}
233
}
234
235
if (bResetD3D) {
236
J2dTraceLn(J2D_TRACE_VERBOSE, " adapters changed: resetting d3d");
237
pMgr->ReleaseD3D();
238
res = pMgr->InitD3D();
239
}
240
return res;
241
}
242
243
HRESULT D3DPipelineManager::HandleLostDevices()
244
{
245
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::HandleLostDevices()");
246
BOOL bAllClear = TRUE;
247
248
HWND hwnd = GetCurrentFocusWindow();
249
if (hwnd != defaultFocusWindow) {
250
// we're in full-screen mode
251
WINDOWPLACEMENT wp;
252
::ZeroMemory(&wp, sizeof(WINDOWPLACEMENT));
253
wp.length = sizeof(WINDOWPLACEMENT);
254
::GetWindowPlacement(hwnd, &wp);
255
256
// Only attempt to restore the devices if we're in full-screen mode
257
// and the fs window is active; sleep otherwise.
258
// Restoring a window while minimized causes problems on Vista:
259
// sometimes we restore the window too quickly and it pops up back from
260
// minimized state when the device is restored.
261
//
262
// WARNING: this is a sleep on the Toolkit thread! We may reconsider
263
// this if we find any issues later.
264
if ((wp.showCmd & SW_SHOWMINNOACTIVE) && !(wp.showCmd & SW_SHOWNORMAL)){
265
static DWORD prevCallTime = 0;
266
J2dTraceLn(J2D_TRACE_VERBOSE, " fs focus window is minimized");
267
DWORD currentTime = ::GetTickCount();
268
if ((currentTime - prevCallTime) < 100) {
269
J2dTraceLn(J2D_TRACE_VERBOSE, " tight loop detected, sleep");
270
::Sleep(100);
271
}
272
prevCallTime = currentTime;
273
return D3DERR_DEVICELOST;
274
}
275
}
276
if (pAdapters != NULL) {
277
for (UINT i = 0; i < adapterCount; i++) {
278
if (pAdapters[i].pd3dContext != NULL) {
279
J2dTraceLn1(J2D_TRACE_VERBOSE,
280
" HandleLostDevices: checking adapter %d", i);
281
D3DContext *d3dc = pAdapters[i].pd3dContext;
282
if (FAILED(d3dc->CheckAndResetDevice())) {
283
bAllClear = FALSE;
284
}
285
}
286
}
287
}
288
return bAllClear ? S_OK : D3DERR_DEVICELOST;
289
}
290
291
HRESULT D3DPipelineManager::InitAdapters()
292
{
293
HRESULT res = E_FAIL;
294
295
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::InitAdapters()");
296
if (pAdapters != NULL) {
297
ReleaseAdapters();
298
}
299
300
adapterCount = pd3d9->GetAdapterCount();
301
pAdapters = new D3DAdapter[adapterCount];
302
if (pAdapters == NULL) {
303
J2dRlsTraceLn(J2D_TRACE_ERROR, "InitAdapters: out of memory");
304
adapterCount = 0;
305
return E_FAIL;
306
}
307
ZeroMemory(pAdapters, adapterCount * sizeof(D3DAdapter));
308
309
res = CheckAdaptersInfo();
310
RETURN_STATUS_IF_FAILED(res);
311
312
currentFSFocusAdapter = -1;
313
if (CreateDefaultFocusWindow() == 0) {
314
return E_FAIL;
315
}
316
317
return S_OK;
318
}
319
320
// static
321
HRESULT
322
D3DPipelineManager::CheckOSVersion()
323
{
324
// require Windows XP or newer client-class OS
325
if (IS_WINVER_ATLEAST(5, 1) &&
326
!D3DPPLM_OsVersionMatches(OS_WINSERV_2008R2|OS_WINSERV_2008|
327
OS_WINSERV_2003))
328
{
329
J2dTraceLn(J2D_TRACE_INFO,
330
"D3DPPLM::CheckOSVersion: Windows XP or newer client-classs"\
331
" OS detected, passed");
332
return S_OK;
333
}
334
J2dRlsTraceLn(J2D_TRACE_ERROR,
335
"D3DPPLM::CheckOSVersion: Windows 2000 or earlier (or a "\
336
"server) OS detected, failed");
337
if (bNoHwCheck) {
338
J2dRlsTraceLn(J2D_TRACE_WARNING,
339
" OS check overridden via J2D_D3D_NO_HWCHECK");
340
return S_OK;
341
}
342
return E_FAIL;
343
}
344
345
// static
346
HRESULT
347
D3DPipelineManager::GDICheckForBadHardware()
348
{
349
DISPLAY_DEVICE dd;
350
dd.cb = sizeof(DISPLAY_DEVICE);
351
352
int failedDevices = 0;
353
int attachedDevices = 0;
354
int i = 0;
355
WCHAR *id;
356
WCHAR vendorId[5];
357
WCHAR deviceId[5];
358
DWORD dwDId, dwVId;
359
360
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GDICheckForBadHardware");
361
362
// i<20 is to guard against buggy drivers
363
while (EnumDisplayDevices(NULL, i, &dd, 0) && i < 20) {
364
if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) {
365
attachedDevices++;
366
id = dd.DeviceID;
367
if (wcslen(id) > 21) {
368
// get vendor ID
369
wcsncpy(vendorId, id+8, 4);
370
int args1 = swscanf(vendorId, L"%X", &dwVId);
371
372
// get device ID
373
wcsncpy(deviceId, id+17, 4);
374
int args2 = swscanf(deviceId, L"%X", &dwDId);
375
376
if (args1 == 1 && args2 == 1) {
377
J2dTraceLn2(J2D_TRACE_VERBOSE,
378
" device: vendorID=0x%04x, deviceId=0x%04x",
379
dwVId, dwDId);
380
// since we don't have a driver version here we will
381
// just ask to ignore the version for now; bad hw
382
// entries with specific drivers information will be
383
// processed later when d3d is initialized and we can
384
// obtain a driver version
385
if (FAILED(CheckForBadHardware(dwVId, dwDId, MAX_VERSION))){
386
failedDevices++;
387
}
388
}
389
}
390
}
391
392
i++;
393
}
394
395
if (failedDevices == attachedDevices) {
396
J2dRlsTraceLn(J2D_TRACE_ERROR,
397
"D3DPPLM::GDICheckForBadHardware: no suitable devices found");
398
return E_FAIL;
399
}
400
401
return S_OK;
402
}
403
404
BOOL D3DPPLM_OsVersionMatches(USHORT osInfo) {
405
static USHORT currentOS = OS_UNDEFINED;
406
407
if (currentOS == OS_UNDEFINED) {
408
BOOL bVersOk;
409
OSVERSIONINFOEX osvi;
410
411
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
412
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
413
414
bVersOk = GetVersionEx((OSVERSIONINFO *) &osvi);
415
416
J2dRlsTrace(J2D_TRACE_INFO, "[I] OS Version = ");
417
if (bVersOk && osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
418
osvi.dwMajorVersion > 4)
419
{
420
if (osvi.dwMajorVersion >= 6 && osvi.dwMinorVersion == 0) {
421
if (osvi.wProductType == VER_NT_WORKSTATION) {
422
J2dRlsTrace(J2D_TRACE_INFO, "OS_VISTA\n");
423
currentOS = OS_VISTA;
424
} else {
425
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2008\n");
426
currentOS = OS_WINSERV_2008;
427
}
428
} else if (osvi.dwMajorVersion >= 6 && osvi.dwMinorVersion >= 1) {
429
if (osvi.wProductType == VER_NT_WORKSTATION) {
430
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINDOWS7 or newer\n");
431
currentOS = OS_WINDOWS7;
432
} else {
433
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2008R2 or newer\n");
434
currentOS = OS_WINSERV_2008R2;
435
}
436
} else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {
437
if (osvi.wProductType == VER_NT_WORKSTATION) {
438
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINXP_64\n");
439
currentOS = OS_WINXP_64;
440
} else {
441
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINSERV_2003\n");
442
currentOS = OS_WINSERV_2003;
443
}
444
} else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {
445
J2dRlsTrace(J2D_TRACE_INFO, "OS_WINXP ");
446
currentOS = OS_WINXP;
447
if (osvi.wSuiteMask & VER_SUITE_PERSONAL) {
448
J2dRlsTrace(J2D_TRACE_INFO, "Home\n");
449
} else {
450
J2dRlsTrace(J2D_TRACE_INFO, "Pro\n");
451
}
452
} else {
453
J2dRlsTrace2(J2D_TRACE_INFO,
454
"OS_UNKNOWN: dwMajorVersion=%d dwMinorVersion=%d\n",
455
osvi.dwMajorVersion, osvi.dwMinorVersion);
456
currentOS = OS_UNKNOWN;
457
}
458
} else {
459
if (bVersOk) {
460
J2dRlsTrace2(J2D_TRACE_INFO,
461
"OS_UNKNOWN: dwPlatformId=%d dwMajorVersion=%d\n",
462
osvi.dwPlatformId, osvi.dwMajorVersion);
463
} else {
464
J2dRlsTrace(J2D_TRACE_INFO,"OS_UNKNOWN: GetVersionEx failed\n");
465
}
466
currentOS = OS_UNKNOWN;
467
}
468
}
469
return (currentOS & osInfo);
470
}
471
472
// static
473
HRESULT
474
D3DPipelineManager::CheckForBadHardware(DWORD vId, DWORD dId, LONGLONG version)
475
{
476
DWORD vendorId, deviceId;
477
UINT adapterInfo = 0;
478
479
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::CheckForBadHardware");
480
481
while ((vendorId = badHardware[adapterInfo].VendorId) != 0x0000 &&
482
(deviceId = badHardware[adapterInfo].DeviceId) != 0x0000)
483
{
484
if (vendorId == vId && (deviceId == dId || deviceId == ALL_DEVICEIDS)) {
485
LONGLONG goodVersion = badHardware[adapterInfo].DriverVersion;
486
USHORT osInfo = badHardware[adapterInfo].OsInfo;
487
// the hardware check fails if:
488
// - we have an entry for this OS and
489
// - hardware is bad for all driver versions (NO_VERSION), or
490
// we have a driver version which is older than the
491
// minimum required for this OS
492
if (D3DPPLM_OsVersionMatches(osInfo) &&
493
(goodVersion == NO_VERSION || version < goodVersion))
494
{
495
J2dRlsTraceLn2(J2D_TRACE_ERROR,
496
"D3DPPLM::CheckForBadHardware: found matching "\
497
"hardware: VendorId=0x%04x DeviceId=0x%04x",
498
vendorId, deviceId);
499
if (goodVersion != NO_VERSION) {
500
// this was a match by the driver version
501
LARGE_INTEGER li;
502
li.QuadPart = goodVersion;
503
J2dRlsTraceLn(J2D_TRACE_ERROR,
504
" bad driver found, device disabled");
505
J2dRlsTraceLn4(J2D_TRACE_ERROR,
506
" update your driver to at "\
507
"least version %d.%d.%d.%d",
508
HIWORD(li.HighPart), LOWORD(li.HighPart),
509
HIWORD(li.LowPart), LOWORD(li.LowPart));
510
} else {
511
// this was a match by the device (no good driver for this
512
// device)
513
J2dRlsTraceLn(J2D_TRACE_ERROR,
514
"D3DPPLM::CheckForBadHardware: bad hardware "\
515
"found, device disabled");
516
}
517
if (!bNoHwCheck) {
518
return D3DERR_INVALIDDEVICE;
519
}
520
J2dRlsTraceLn(J2D_TRACE_WARNING, " Warning: hw/driver match "\
521
"overridden (via J2D_D3D_NO_HWCHECK)");
522
}
523
}
524
adapterInfo++;
525
}
526
527
return S_OK;
528
}
529
530
HRESULT D3DPipelineManager::CheckAdaptersInfo()
531
{
532
D3DADAPTER_IDENTIFIER9 aid;
533
UINT failedAdaptersCount = 0;
534
535
J2dRlsTraceLn(J2D_TRACE_INFO, "CheckAdaptersInfo");
536
J2dRlsTraceLn(J2D_TRACE_INFO, "------------------");
537
for (UINT Adapter = 0; Adapter < adapterCount; Adapter++) {
538
539
if (FAILED(pd3d9->GetAdapterIdentifier(Adapter, 0, &aid))) {
540
pAdapters[Adapter].state = CONTEXT_INIT_FAILED;
541
failedAdaptersCount++;
542
continue;
543
}
544
545
J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Ordinal : %d", Adapter);
546
J2dRlsTraceLn1(J2D_TRACE_INFO, "Adapter Handle : 0x%x",
547
pd3d9->GetAdapterMonitor(Adapter));
548
J2dRlsTraceLn1(J2D_TRACE_INFO, "Description : %s",
549
aid.Description);
550
J2dRlsTraceLn2(J2D_TRACE_INFO, "GDI Name, Driver : %s, %s",
551
aid.DeviceName, aid.Driver);
552
J2dRlsTraceLn1(J2D_TRACE_INFO, "Vendor Id : 0x%04x",
553
aid.VendorId);
554
J2dRlsTraceLn1(J2D_TRACE_INFO, "Device Id : 0x%04x",
555
aid.DeviceId);
556
J2dRlsTraceLn1(J2D_TRACE_INFO, "SubSys Id : 0x%x",
557
aid.SubSysId);
558
J2dRlsTraceLn4(J2D_TRACE_INFO, "Driver Version : %d.%d.%d.%d",
559
HIWORD(aid.DriverVersion.HighPart),
560
LOWORD(aid.DriverVersion.HighPart),
561
HIWORD(aid.DriverVersion.LowPart),
562
LOWORD(aid.DriverVersion.LowPart));
563
J2dRlsTrace3(J2D_TRACE_INFO,
564
"[I] GUID : {%08X-%04X-%04X-",
565
aid.DeviceIdentifier.Data1,
566
aid.DeviceIdentifier.Data2,
567
aid.DeviceIdentifier.Data3);
568
J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X-%02X%02X",
569
aid.DeviceIdentifier.Data4[0],
570
aid.DeviceIdentifier.Data4[1],
571
aid.DeviceIdentifier.Data4[2],
572
aid.DeviceIdentifier.Data4[3]);
573
J2dRlsTrace4(J2D_TRACE_INFO, "%02X%02X%02X%02X}\n",
574
aid.DeviceIdentifier.Data4[4],
575
aid.DeviceIdentifier.Data4[5],
576
aid.DeviceIdentifier.Data4[6],
577
aid.DeviceIdentifier.Data4[7]);
578
579
if (FAILED(CheckForBadHardware(aid.VendorId, aid.DeviceId,
580
aid.DriverVersion.QuadPart)) ||
581
FAILED(CheckDeviceCaps(Adapter)) ||
582
FAILED(D3DEnabledOnAdapter(Adapter)))
583
{
584
pAdapters[Adapter].state = CONTEXT_INIT_FAILED;
585
failedAdaptersCount++;
586
}
587
J2dRlsTraceLn(J2D_TRACE_INFO, "------------------");
588
}
589
590
if (failedAdaptersCount == adapterCount) {
591
J2dRlsTraceLn(J2D_TRACE_ERROR,
592
"D3DPPLM::CheckAdaptersInfo: no suitable adapters found");
593
return E_FAIL;
594
}
595
596
return S_OK;
597
}
598
599
D3DDEVTYPE D3DPipelineManager::SelectDeviceType()
600
{
601
char *pRas = getenv("J2D_D3D_RASTERIZER");
602
D3DDEVTYPE dtype = D3DDEVTYPE_HAL;
603
if (pRas != NULL) {
604
J2dRlsTrace(J2D_TRACE_WARNING, "[W] D3DPPLM::SelectDeviceType: ");
605
if (strncmp(pRas, "ref", 3) == 0 || strncmp(pRas, "rgb", 3) == 0) {
606
J2dRlsTrace(J2D_TRACE_WARNING, "ref rasterizer selected");
607
dtype = D3DDEVTYPE_REF;
608
} else if (strncmp(pRas, "hal",3) == 0 || strncmp(pRas, "tnl",3) == 0) {
609
J2dRlsTrace(J2D_TRACE_WARNING, "hal rasterizer selected");
610
dtype = D3DDEVTYPE_HAL;
611
} else if (strncmp(pRas, "nul", 3) == 0) {
612
J2dRlsTrace(J2D_TRACE_WARNING, "nullref rasterizer selected");
613
dtype = D3DDEVTYPE_NULLREF;
614
} else {
615
J2dRlsTrace1(J2D_TRACE_WARNING,
616
"unknown rasterizer: %s, only (ref|hal|nul) "\
617
"supported, hal selected instead", pRas);
618
}
619
J2dRlsTrace(J2D_TRACE_WARNING, "\n");
620
}
621
return dtype;
622
}
623
624
#define CHECK_CAP(FLAG, CAP) \
625
do { \
626
if (!((FLAG)&CAP)) { \
627
J2dRlsTraceLn2(J2D_TRACE_ERROR, \
628
"D3DPPLM::CheckDeviceCaps: adapter %d: Failed "\
629
"(cap %s not supported)", \
630
adapter, #CAP); \
631
return E_FAIL; \
632
} \
633
} while (0)
634
635
HRESULT D3DPipelineManager::CheckDeviceCaps(UINT adapter)
636
{
637
HRESULT res;
638
D3DCAPS9 d3dCaps;
639
640
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::CheckDeviceCaps");
641
642
res = pd3d9->GetDeviceCaps(adapter, devType, &d3dCaps);
643
RETURN_STATUS_IF_FAILED(res);
644
645
CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_DRAWPRIMTLVERTEX);
646
647
// by requiring hardware tnl we are hoping for better drivers quality
648
if (!IsD3DForced()) {
649
// fail if not hw tnl unless d3d was forced
650
CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWTRANSFORMANDLIGHT);
651
}
652
if (d3dCaps.DeviceType == D3DDEVTYPE_HAL) {
653
CHECK_CAP(d3dCaps.DevCaps, D3DDEVCAPS_HWRASTERIZATION);
654
}
655
656
CHECK_CAP(d3dCaps.RasterCaps, D3DPRASTERCAPS_SCISSORTEST);
657
658
CHECK_CAP(d3dCaps.Caps3, D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD);
659
660
CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_CULLNONE);
661
CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_BLENDOP);
662
CHECK_CAP(d3dCaps.PrimitiveMiscCaps, D3DPMISCCAPS_MASKZ);
663
664
CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_ALWAYS);
665
CHECK_CAP(d3dCaps.ZCmpCaps, D3DPCMPCAPS_LESS);
666
667
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ZERO);
668
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_ONE);
669
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_SRCALPHA);
670
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_DESTALPHA);
671
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVSRCALPHA);
672
CHECK_CAP(d3dCaps.SrcBlendCaps, D3DPBLENDCAPS_INVDESTALPHA);
673
674
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ZERO);
675
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_ONE);
676
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_SRCALPHA);
677
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_DESTALPHA);
678
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVSRCALPHA);
679
CHECK_CAP(d3dCaps.DestBlendCaps, D3DPBLENDCAPS_INVDESTALPHA);
680
681
CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_CLAMP);
682
CHECK_CAP(d3dCaps.TextureAddressCaps, D3DPTADDRESSCAPS_WRAP);
683
684
CHECK_CAP(d3dCaps.TextureOpCaps, D3DTEXOPCAPS_MODULATE);
685
686
if (d3dCaps.PixelShaderVersion < D3DPS_VERSION(2,0) && !IsD3DForced()) {
687
J2dRlsTraceLn1(J2D_TRACE_ERROR,
688
"D3DPPLM::CheckDeviceCaps: adapter %d: Failed "\
689
"(pixel shaders 2.0 required)", adapter);
690
return E_FAIL;
691
}
692
693
J2dRlsTraceLn1(J2D_TRACE_INFO,
694
"D3DPPLM::CheckDeviceCaps: adapter %d: Passed", adapter);
695
return S_OK;
696
}
697
698
699
HRESULT D3DPipelineManager::D3DEnabledOnAdapter(UINT adapter)
700
{
701
HRESULT res;
702
D3DDISPLAYMODE dm;
703
704
res = pd3d9->GetAdapterDisplayMode(adapter, &dm);
705
RETURN_STATUS_IF_FAILED(res);
706
707
res = pd3d9->CheckDeviceType(adapter, devType, dm.Format, dm.Format, TRUE);
708
if (FAILED(res)) {
709
J2dRlsTraceLn1(J2D_TRACE_ERROR,
710
"D3DPPLM::D3DEnabledOnAdapter: no " \
711
"suitable d3d device on adapter %d", adapter);
712
}
713
714
return res;
715
}
716
717
UINT D3DPipelineManager::GetAdapterOrdinalByHmon(HMONITOR hMon)
718
{
719
UINT ret = D3DADAPTER_DEFAULT;
720
721
if (pd3d9 != NULL) {
722
UINT adapterCount = pd3d9->GetAdapterCount();
723
for (UINT adapter = 0; adapter < adapterCount; adapter++) {
724
HMONITOR hm = pd3d9->GetAdapterMonitor(adapter);
725
if (hm == hMon) {
726
ret = adapter;
727
break;
728
}
729
}
730
}
731
return ret;
732
}
733
734
D3DFORMAT
735
D3DPipelineManager::GetMatchingDepthStencilFormat(UINT adapterOrdinal,
736
D3DFORMAT adapterFormat,
737
D3DFORMAT renderTargetFormat)
738
{
739
static D3DFORMAT formats[] =
740
{ D3DFMT_D16, D3DFMT_D32, D3DFMT_D24S8, D3DFMT_D24X8 };
741
D3DFORMAT newFormat = D3DFMT_UNKNOWN;
742
HRESULT res;
743
for (int i = 0; i < 4; i++) {
744
res = pd3d9->CheckDeviceFormat(adapterOrdinal,
745
devType, adapterFormat, D3DUSAGE_DEPTHSTENCIL,
746
D3DRTYPE_SURFACE, formats[i]);
747
if (FAILED(res)) continue;
748
749
res = pd3d9->CheckDepthStencilMatch(adapterOrdinal,
750
devType, adapterFormat, renderTargetFormat, formats[i]);
751
if (FAILED(res)) continue;
752
newFormat = formats[i];
753
break;
754
}
755
return newFormat;
756
}
757
758
HWND D3DPipelineManager::CreateDefaultFocusWindow()
759
{
760
UINT adapterOrdinal = D3DADAPTER_DEFAULT;
761
762
J2dTraceLn1(J2D_TRACE_INFO,
763
"D3DPPLM::CreateDefaultFocusWindow: adapter=%d",
764
adapterOrdinal);
765
766
if (defaultFocusWindow != 0) {
767
J2dRlsTraceLn(J2D_TRACE_WARNING,
768
"D3DPPLM::CreateDefaultFocusWindow: "\
769
"existing default focus window!");
770
return defaultFocusWindow;
771
}
772
773
WNDCLASS wc;
774
ZeroMemory(&wc, sizeof(WNDCLASS));
775
wc.hInstance = GetModuleHandle(NULL);
776
wc.lpfnWndProc = DefWindowProc;
777
wc.lpszClassName = L"D3DFocusWindow";
778
if (RegisterClass(&wc) == 0) {
779
J2dRlsTraceLn(J2D_TRACE_ERROR,
780
"D3DPPLM::CreateDefaultFocusWindow: "\
781
"error registering window class");
782
return 0;
783
}
784
785
MONITORINFO mi;
786
ZeroMemory(&mi, sizeof(MONITORINFO));
787
mi.cbSize = sizeof(MONITORINFO);
788
HMONITOR hMon = pd3d9->GetAdapterMonitor(adapterOrdinal);
789
if (hMon == 0 || !GetMonitorInfo(hMon, (LPMONITORINFO)&mi)) {
790
J2dRlsTraceLn1(J2D_TRACE_ERROR,
791
"D3DPPLM::CreateDefaultFocusWindow: "\
792
"error getting monitor info for adapter=%d", adapterOrdinal);
793
return 0;
794
}
795
796
HWND hWnd = CreateWindow(L"D3DFocusWindow", L"D3DFocusWindow", WS_POPUP,
797
mi.rcMonitor.left, mi.rcMonitor.top, 1, 1,
798
NULL, NULL, GetModuleHandle(NULL), NULL);
799
if (hWnd == 0) {
800
J2dRlsTraceLn(J2D_TRACE_ERROR,
801
"D3DPPLM::CreateDefaultFocusWindow: CreateWindow failed");
802
} else {
803
J2dTraceLn2(J2D_TRACE_INFO,
804
" Created default focus window %x for adapter %d",
805
hWnd, adapterOrdinal);
806
defaultFocusWindow = hWnd;
807
}
808
return hWnd;
809
}
810
811
HWND D3DPipelineManager::GetCurrentFocusWindow()
812
{
813
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GetCurrentFocusWindow");
814
if (currentFSFocusAdapter < 0) {
815
J2dTraceLn1(J2D_TRACE_VERBOSE,
816
" no fs windows, using default focus window=0x%x",
817
defaultFocusWindow);
818
return defaultFocusWindow;
819
}
820
J2dTraceLn1(J2D_TRACE_VERBOSE, " using fs window=0x%x",
821
pAdapters[currentFSFocusAdapter].fsFocusWindow);
822
return pAdapters[currentFSFocusAdapter].fsFocusWindow;
823
}
824
825
HWND D3DPipelineManager::SetFSFocusWindow(UINT adapterOrdinal, HWND hWnd)
826
{
827
J2dTraceLn2(J2D_TRACE_INFO,"D3DPPLM::SetFSFocusWindow hwnd=0x%x adapter=%d",
828
hWnd, adapterOrdinal);
829
830
HWND prev = pAdapters[adapterOrdinal].fsFocusWindow;
831
pAdapters[adapterOrdinal].fsFocusWindow = hWnd;
832
if (currentFSFocusAdapter < 0) {
833
J2dTraceLn(J2D_TRACE_VERBOSE, " first full-screen window");
834
// first fs window
835
currentFSFocusAdapter = adapterOrdinal;
836
// REMIND: we might want to reset the rest of the context here as well
837
// like we do when the an adapter exits fs mode; currently they will
838
// be reset sometime later
839
} else {
840
// there's already a fs window
841
if (currentFSFocusAdapter == adapterOrdinal) {
842
// it's current fs window => we're exiting fs mode on this adapter;
843
// look for a new fs focus window
844
if (hWnd == 0) {
845
UINT i;
846
currentFSFocusAdapter = -1;
847
for (i = 0; i < adapterCount; i++) {
848
if (pAdapters[i].fsFocusWindow != 0) {
849
J2dTraceLn1(J2D_TRACE_VERBOSE,
850
" adapter %d is still in fs mode", i);
851
currentFSFocusAdapter = i;
852
break;
853
}
854
}
855
// we have to reset all devices any time current focus device
856
// exits fs mode, and also to prevent some of them being left in
857
// a lost state when the last device exits fs - when non-last
858
// adapters exit fs mode they would not be able to create the
859
// device and will be put in a lost state forever
860
HRESULT res;
861
J2dTraceLn(J2D_TRACE_VERBOSE,
862
" adapter exited full-screen, reset all adapters");
863
for (i = 0; i < adapterCount; i++) {
864
if (pAdapters[i].pd3dContext != NULL) {
865
res = pAdapters[i].pd3dContext->ResetContext();
866
D3DRQ_MarkLostIfNeeded(res,
867
D3DRQ_GetCurrentDestination());
868
}
869
}
870
} else {
871
J2dTraceLn1(J2D_TRACE_WARNING,
872
"D3DPM::SetFSFocusWindow: setting the fs "\
873
"window again for adapter %d", adapterOrdinal);
874
}
875
}
876
}
877
return prev;
878
}
879
880
HRESULT D3DPipelineManager::GetD3DContext(UINT adapterOrdinal,
881
D3DContext **ppd3dContext)
882
{
883
J2dTraceLn(J2D_TRACE_INFO, "D3DPPLM::GetD3DContext");
884
885
HRESULT res = S_OK;
886
if (adapterOrdinal < 0 || adapterOrdinal >= adapterCount ||
887
pAdapters == NULL ||
888
pAdapters[adapterOrdinal].state == CONTEXT_INIT_FAILED)
889
{
890
J2dRlsTraceLn1(J2D_TRACE_ERROR,
891
"D3DPPLM::GetD3DContext: invalid parameters or "\
892
"failed init for adapter %d", adapterOrdinal);
893
*ppd3dContext = NULL;
894
return E_FAIL;
895
}
896
897
if (pAdapters[adapterOrdinal].state == CONTEXT_NOT_INITED) {
898
D3DContext *pCtx = NULL;
899
900
if (pAdapters[adapterOrdinal].pd3dContext != NULL) {
901
J2dTraceLn1(J2D_TRACE_ERROR, " non-null context in "\
902
"uninitialized adapter %d", adapterOrdinal);
903
res = E_FAIL;
904
} else {
905
J2dTraceLn1(J2D_TRACE_VERBOSE,
906
" initializing context for adapter %d",adapterOrdinal);
907
908
if (SUCCEEDED(res = D3DEnabledOnAdapter(adapterOrdinal))) {
909
res = D3DContext::CreateInstance(pd3d9, adapterOrdinal, &pCtx);
910
if (FAILED(res)) {
911
J2dRlsTraceLn1(J2D_TRACE_ERROR,
912
"D3DPPLM::GetD3DContext: failed to create context "\
913
"for adapter=%d", adapterOrdinal);
914
}
915
} else {
916
J2dRlsTraceLn1(J2D_TRACE_ERROR,
917
"D3DPPLM::GetContext: no d3d on adapter %d",adapterOrdinal);
918
}
919
}
920
pAdapters[adapterOrdinal].state =
921
SUCCEEDED(res) ? CONTEXT_CREATED : CONTEXT_INIT_FAILED;
922
pAdapters[adapterOrdinal].pd3dContext = pCtx;
923
}
924
*ppd3dContext = pAdapters[adapterOrdinal].pd3dContext;
925
return res;
926
}
927
928
929
//==============================================================
930
// D3DInitializer
931
//==============================================================
932
933
D3DInitializer D3DInitializer::theInstance;
934
935
D3DInitializer::D3DInitializer()
936
: bComInitialized(false), pAdapterIniters(NULL)
937
{
938
}
939
940
D3DInitializer::~D3DInitializer()
941
{
942
if (pAdapterIniters) {
943
delete[] pAdapterIniters;
944
}
945
}
946
947
void D3DInitializer::InitImpl()
948
{
949
J2dRlsTraceLn(J2D_TRACE_INFO, "D3DInitializer::InitImpl");
950
if (SUCCEEDED(::CoInitialize(NULL))) {
951
bComInitialized = true;
952
}
953
D3DPipelineManager *pMgr = D3DPipelineManager::CreateInstance();
954
if (pMgr != NULL) {
955
// init adapters if we are preloading
956
if (AwtToolkit::GetInstance().GetPreloadThread().OnPreloadThread()) {
957
UINT adapterCount = pMgr->adapterCount;
958
959
pAdapterIniters = new D3DAdapterInitializer[adapterCount];
960
for (UINT i=0; i<adapterCount; i++) {
961
pAdapterIniters[i].setAdapter(i);
962
AwtToolkit::GetInstance().GetPreloadThread().AddAction(&pAdapterIniters[i]);
963
}
964
}
965
}
966
}
967
968
void D3DInitializer::CleanImpl(bool reInit)
969
{
970
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DInitializer::CleanImpl (%s)",
971
reInit ? "RELAUNCH" : "normal");
972
D3DPipelineManager::DeleteInstance();
973
if (bComInitialized) {
974
CoUninitialize();
975
}
976
}
977
978
979
void D3DInitializer::D3DAdapterInitializer::InitImpl()
980
{
981
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) started", adapter);
982
983
D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
984
if (pMgr == NULL) {
985
return;
986
}
987
988
D3DContext *pd3dContext;
989
pMgr->GetD3DContext(adapter, &pd3dContext);
990
991
J2dRlsTraceLn1(J2D_TRACE_INFO, "D3DAdapterInitializer::InitImpl(%d) finished", adapter);
992
}
993
994
void D3DInitializer::D3DAdapterInitializer::CleanImpl(bool reInit)
995
{
996
// nothing to do - D3DPipelineManager cleans adapters
997
}
998
999
1000
extern "C" {
1001
/*
1002
* Export function to start D3D preloading
1003
* (called from java/javaw - see src/windows/bin/java-md.c)
1004
*/
1005
__declspec(dllexport) int preloadD3D()
1006
{
1007
J2dRlsTraceLn(J2D_TRACE_INFO, "AWT warmup: preloadD3D");
1008
AwtToolkit::GetInstance().GetPreloadThread().AddAction(&D3DInitializer::GetInstance());
1009
return 1;
1010
}
1011
1012
}
1013
1014
1015