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/D3DGraphicsDevice.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 "sun_java2d_d3d_D3DGraphicsDevice.h"
27
#include "D3DGraphicsDevice.h"
28
#include "D3DPipelineManager.h"
29
#include "D3DRenderQueue.h"
30
#include "Trace.h"
31
#include "awt_Toolkit.h"
32
#include "awt_Window.h"
33
34
extern jobject CreateDisplayMode(JNIEnv* env, jint width, jint height,
35
jint bitDepth, jint refreshRate);
36
extern void addDisplayMode(JNIEnv* env, jobject arrayList, jint width,
37
jint height, jint bitDepth, jint refreshRate);
38
39
extern "C" {
40
/*
41
* Class: sun_java2d_d3d_D3DGraphicsDevice
42
* Method: initD3D
43
* Signature: ()Z
44
*/
45
JNIEXPORT jboolean JNICALL Java_sun_java2d_d3d_D3DGraphicsDevice_initD3D
46
(JNIEnv *env, jclass)
47
{
48
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_initD3D");
49
50
jboolean result = D3DInitializer::GetInstance().EnsureInited()
51
? JNI_TRUE : JNI_FALSE;
52
J2dTraceLn1(J2D_TRACE_INFO, "D3DGD_initD3D: result=%x", result);
53
return result;
54
}
55
56
/*
57
* Class: sun_java2d_d3d_D3DGraphicsDevice
58
* Method: getDeviceIdNative
59
* Signature: (I)Ljava/lang/String;
60
*/
61
JNIEXPORT jstring JNICALL Java_sun_java2d_d3d_D3DGraphicsDevice_getDeviceIdNative
62
(JNIEnv *env, jclass d3dsdc, jint gdiScreen)
63
{
64
D3DPipelineManager *pMgr;
65
UINT adapter;
66
D3DADAPTER_IDENTIFIER9 aid;
67
IDirect3D9 *pd3d9;
68
69
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_getDeviceIdNative");
70
71
pMgr = D3DPipelineManager::GetInstance();
72
RETURN_STATUS_IF_NULL(pMgr, NULL);
73
pd3d9 = pMgr->GetD3DObject();
74
RETURN_STATUS_IF_NULL(pd3d9, NULL);
75
76
adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);
77
if (FAILED(pd3d9->GetAdapterIdentifier(adapter, 0, &aid))) {
78
return NULL;
79
}
80
81
// ('%d.' will take no more than 6+1 chars since we are printing a WORD)
82
// AAAA&BBBB MAX_DEVICE_IDENTIFIER_STRING (%d.%d.%d.%d)0
83
size_t len = (4+1+4 +1+MAX_DEVICE_IDENTIFIER_STRING+1 +1+(6+1)*4+1 +1);
84
WCHAR *pAdapterId = new WCHAR[len];
85
RETURN_STATUS_IF_NULL(pAdapterId, NULL);
86
87
_snwprintf(pAdapterId, len, L"%x&%x %S (%d.%d.%d.%d)",
88
0xffff & aid.VendorId, 0xffff & aid.DeviceId, aid.Description,
89
HIWORD(aid.DriverVersion.HighPart),
90
LOWORD(aid.DriverVersion.HighPart),
91
HIWORD(aid.DriverVersion.LowPart),
92
LOWORD(aid.DriverVersion.LowPart));
93
// _snwprintf doesn't add 0 at the end if the formatted string didn't fit
94
// in the buffer so we have to make sure it is null terminated
95
pAdapterId[len-1] = (WCHAR)0;
96
97
J2dTraceLn1(J2D_TRACE_VERBOSE, " id=%S", pAdapterId);
98
99
jstring ret = JNU_NewStringPlatform(env, pAdapterId);
100
101
delete[] pAdapterId;
102
103
return ret;
104
}
105
106
/*
107
* Class: sun_java2d_d3d_D3DGraphicsDevice
108
* Method: getDeviceCapsNative
109
* Signature: (I)I
110
*/
111
JNIEXPORT jint JNICALL
112
Java_sun_java2d_d3d_D3DGraphicsDevice_getDeviceCapsNative
113
(JNIEnv *env, jclass d3dsdc, jint gdiScreen)
114
{
115
D3DPipelineManager *pMgr;
116
D3DContext *pCtx;
117
UINT adapter;
118
119
J2dRlsTraceLn(J2D_TRACE_INFO, "D3DGD_getDeviceCapsNative");
120
121
pMgr = D3DPipelineManager::GetInstance();
122
RETURN_STATUS_IF_NULL(pMgr, CAPS_EMPTY);
123
adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);
124
125
if (FAILED(pMgr->GetD3DContext(adapter, &pCtx))) {
126
J2dRlsTraceLn1(J2D_TRACE_ERROR,
127
"D3DGD_getDeviceCapsNative: device %d disabled", adapter);
128
return CAPS_EMPTY;
129
}
130
return pCtx->GetContextCaps();
131
}
132
133
/*
134
* Class: sun_java2d_d3d_D3DGraphicsDevice
135
* Method: enterFullScreenExclusiveNative
136
* Signature: (IJ)V
137
*/
138
JNIEXPORT jboolean JNICALL
139
Java_sun_java2d_d3d_D3DGraphicsDevice_enterFullScreenExclusiveNative
140
(JNIEnv *env, jclass gdc, jint gdiScreen, jlong window)
141
{
142
HRESULT res;
143
D3DPipelineManager *pMgr;
144
D3DContext *pCtx;
145
HWND hWnd;
146
AwtWindow *w;
147
D3DPRESENT_PARAMETERS newParams, *pCurParams;
148
D3DDISPLAYMODE dm;
149
UINT adapter;
150
151
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_enterFullScreenExclusiveNative");
152
153
RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);
154
adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);
155
156
if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {
157
D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
158
return JNI_FALSE;
159
}
160
161
w = (AwtWindow *)AwtComponent::GetComponent((HWND)window);
162
if (w == NULL || !::IsWindow(hWnd = w->GetTopLevelHWnd())) {
163
J2dTraceLn(J2D_TRACE_WARNING,
164
"D3DGD_enterFullScreenExclusiveNative: disposed window");
165
return JNI_FALSE;
166
}
167
168
// REMIND: should we also move the non-topleve window from
169
// being on top here (it's moved to front in GraphicsDevice.setFSW())?
170
171
pCtx->Get3DObject()->GetAdapterDisplayMode(adapter, &dm);
172
pCurParams = pCtx->GetPresentationParams();
173
174
// let the mananger know that we're entering the fs mode, it will
175
// set the proper current focus window for us, which ConfigureContext will
176
// use when creating the device
177
pMgr->SetFSFocusWindow(adapter, hWnd);
178
179
newParams = *pCurParams;
180
newParams.hDeviceWindow = hWnd;
181
newParams.Windowed = FALSE;
182
newParams.BackBufferCount = 1;
183
newParams.BackBufferFormat = dm.Format;
184
newParams.FullScreen_RefreshRateInHz = dm.RefreshRate;
185
newParams.BackBufferWidth = dm.Width;
186
newParams.BackBufferHeight = dm.Height;
187
newParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
188
newParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
189
190
res = pCtx->ConfigureContext(&newParams);
191
D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
192
return SUCCEEDED(res);
193
}
194
195
/*
196
* Class: sun_java2d_d3d_D3DGraphicsDevice
197
* Method: exitFullScreenExclusiveNative
198
* Signature: (I)V
199
*/
200
JNIEXPORT jboolean JNICALL
201
Java_sun_java2d_d3d_D3DGraphicsDevice_exitFullScreenExclusiveNative
202
(JNIEnv *env, jclass gdc, jint gdiScreen)
203
{
204
HRESULT res;
205
D3DPipelineManager *pMgr;
206
D3DContext *pCtx;
207
D3DPRESENT_PARAMETERS newParams, *pCurParams;
208
UINT adapter;
209
210
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_exitFullScreenExclusiveNative");
211
212
RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);
213
adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);
214
215
if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {
216
D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
217
return JNI_FALSE;
218
}
219
220
pCurParams = pCtx->GetPresentationParams();
221
222
newParams = *pCurParams;
223
// we're exiting fs, the device window can be 0
224
newParams.hDeviceWindow = 0;
225
newParams.Windowed = TRUE;
226
newParams.BackBufferFormat = D3DFMT_UNKNOWN;
227
newParams.BackBufferCount = 1;
228
newParams.FullScreen_RefreshRateInHz = 0;
229
newParams.BackBufferWidth = 0;
230
newParams.BackBufferHeight = 0;
231
newParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
232
newParams.SwapEffect = D3DSWAPEFFECT_COPY;
233
234
res = pCtx->ConfigureContext(&newParams);
235
D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
236
237
// exited fs, update current focus window
238
// note that we call this after this adapter exited fs mode so that
239
// the rest of the adapters can be reset
240
pMgr->SetFSFocusWindow(adapter, 0);
241
242
return SUCCEEDED(res);
243
}
244
245
/*
246
* Class: sun_java2d_d3d_D3DGraphicsDevice
247
* Method: configDisplayModeNative
248
* Signature: (IJIIII)V
249
*/
250
JNIEXPORT void JNICALL
251
Java_sun_java2d_d3d_D3DGraphicsDevice_configDisplayModeNative
252
(JNIEnv *env, jclass gdc, jint gdiScreen, jlong window,
253
jint width, jint height, jint bitDepth, jint refreshRate)
254
{
255
HRESULT res;
256
D3DPipelineManager *pMgr;
257
D3DContext *pCtx;
258
D3DPRESENT_PARAMETERS newParams, *pCurParams;
259
UINT adapter;
260
261
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_configDisplayModeNative");
262
263
RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance());
264
adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);
265
266
if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {
267
D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
268
return;
269
}
270
271
pCurParams = pCtx->GetPresentationParams();
272
273
newParams = *pCurParams;
274
newParams.BackBufferWidth = width;
275
newParams.BackBufferHeight = height;
276
newParams.FullScreen_RefreshRateInHz = refreshRate;
277
newParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
278
// we leave the swap effect so that it's more likely
279
// to be the one user selected initially
280
// newParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
281
282
if (bitDepth == 32) {
283
newParams.BackBufferFormat = D3DFMT_X8R8G8B8;
284
} else if (bitDepth == 16) {
285
UINT modeNum;
286
D3DDISPLAYMODE mode;
287
IDirect3D9 *pd3d9;
288
UINT modesCount;
289
290
RETURN_IF_NULL(pd3d9 = pMgr->GetD3DObject());
291
292
modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_R5G6B5);
293
if (modesCount == 0) {
294
modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_X1R5G5B5);
295
}
296
297
newParams.BackBufferFormat = D3DFMT_UNKNOWN;
298
for (modeNum = 0; modeNum < modesCount; modeNum++) {
299
if (SUCCEEDED(pd3d9->EnumAdapterModes(adapter, D3DFMT_R5G6B5,
300
modeNum, &mode)))
301
{
302
if (mode.Width == width && mode.Height == height &&
303
mode.RefreshRate == refreshRate)
304
{
305
// prefer 565 over 555
306
if (mode.Format == D3DFMT_R5G6B5) {
307
newParams.BackBufferFormat = D3DFMT_R5G6B5;
308
break;
309
} else if (mode.Format == D3DFMT_X1R5G5B5) {
310
newParams.BackBufferFormat = D3DFMT_X1R5G5B5;
311
}
312
}
313
}
314
}
315
if (newParams.BackBufferFormat == D3DFMT_UNKNOWN) {
316
J2dRlsTraceLn(J2D_TRACE_ERROR,
317
"D3DGD_configDisplayModeNative: no 16-bit formats");
318
return;
319
}
320
} else {
321
J2dRlsTraceLn1(J2D_TRACE_ERROR,
322
"D3DGD_configDisplayModeNative: unsupported depth: %d",
323
bitDepth);
324
return;
325
}
326
327
J2dTraceLn4(J2D_TRACE_VERBOSE, " changing to dm: %dx%dx%d@%d",
328
newParams.BackBufferWidth, newParams.BackBufferHeight,
329
bitDepth, refreshRate);
330
J2dTraceLn1(J2D_TRACE_VERBOSE, " selected backbuffer format: %d",
331
newParams.BackBufferFormat);
332
333
res = pCtx->ConfigureContext(&newParams);
334
if (SUCCEEDED(res)) {
335
// the full screen window doesn't receive WM_SIZE event when
336
// the display mode changes (it does get resized though) so we need to
337
// generate the event ourselves
338
::SendMessage(newParams.hDeviceWindow, WM_SIZE, width, height);
339
}
340
D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
341
}
342
343
344
/*
345
* Class: sun_java2d_d3d_D3DGraphicsDevice
346
* Method: getCurrentDisplayModeNative
347
* Signature: (I)Ljava/awt/DisplayMode;
348
*/
349
JNIEXPORT jobject JNICALL
350
Java_sun_java2d_d3d_D3DGraphicsDevice_getCurrentDisplayModeNative
351
(JNIEnv *env, jclass gdc, jint gdiScreen)
352
{
353
D3DPipelineManager *pMgr;
354
IDirect3D9 *pd3d9;
355
jobject ret = NULL;
356
D3DDISPLAYMODE mode;
357
UINT adapter;
358
359
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_getCurrentDisplayModeNative");
360
361
RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), NULL);
362
RETURN_STATUS_IF_NULL(pd3d9 = pMgr->GetD3DObject(), NULL);
363
adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);
364
365
if (SUCCEEDED(pd3d9->GetAdapterDisplayMode(adapter, &mode))) {
366
int bitDepth = -1;
367
// these are the only three valid screen formats
368
switch (mode.Format) {
369
case D3DFMT_X8R8G8B8: bitDepth = 32; break;
370
case D3DFMT_R5G6B5:
371
case D3DFMT_X1R5G5B5: bitDepth = 16; break;
372
}
373
J2dTraceLn4(J2D_TRACE_VERBOSE,
374
" current dm: %dx%dx%d@%d",
375
mode.Width, mode.Height, bitDepth, mode.RefreshRate);
376
ret = CreateDisplayMode(env, mode.Width, mode.Height, bitDepth,
377
mode.RefreshRate);
378
}
379
return ret;
380
}
381
382
/*
383
* Class: sun_java2d_d3d_D3DGraphicsDevice
384
* Method: enumDisplayModesNative
385
* Signature: (ILjava/util/ArrayList;)V
386
*/
387
JNIEXPORT void JNICALL
388
Java_sun_java2d_d3d_D3DGraphicsDevice_enumDisplayModesNative
389
(JNIEnv *env, jclass gdc, jint gdiScreen, jobject arrayList)
390
{
391
D3DPipelineManager *pMgr;
392
IDirect3D9 *pd3d9;
393
jobject ret = NULL;
394
D3DDISPLAYMODE mode;
395
UINT formatNum, modeNum, modesCount;
396
UINT adapter;
397
// EnumAdapterModes treats 555 and 565 formats as equivalents
398
static D3DFORMAT formats[] =
399
{ D3DFMT_X8R8G8B8, D3DFMT_R5G6B5 };
400
401
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_enumDisplayModesNative");
402
403
RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance());
404
RETURN_IF_NULL(pd3d9 = pMgr->GetD3DObject());
405
adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);
406
407
for (formatNum = 0; formatNum < (sizeof formats)/(sizeof *formats); formatNum++) {
408
modesCount = pd3d9->GetAdapterModeCount(adapter, formats[formatNum]);
409
for (modeNum = 0; modeNum < modesCount; modeNum++) {
410
if (SUCCEEDED(pd3d9->EnumAdapterModes(adapter, formats[formatNum],
411
modeNum, &mode)))
412
{
413
int bitDepth = -1;
414
// these are the only three valid screen formats,
415
// 30-bit is returned as X8R8G8B8
416
switch (mode.Format) {
417
case D3DFMT_X8R8G8B8: bitDepth = 32; break;
418
case D3DFMT_R5G6B5:
419
case D3DFMT_X1R5G5B5: bitDepth = 16; break;
420
}
421
J2dTraceLn4(J2D_TRACE_VERBOSE, " found dm: %dx%dx%d@%d",
422
mode.Width, mode.Height, bitDepth,mode.RefreshRate);
423
addDisplayMode(env, arrayList, mode.Width, mode.Height,
424
bitDepth, mode.RefreshRate);
425
}
426
}
427
}
428
}
429
430
/*
431
* Class: sun_java2d_d3d_D3DGraphicsDevice
432
* Method: getAvailableAcceleratedMemoryNative
433
* Signature: (I)J
434
*/
435
JNIEXPORT jlong JNICALL
436
Java_sun_java2d_d3d_D3DGraphicsDevice_getAvailableAcceleratedMemoryNative
437
(JNIEnv *env, jclass gdc, jint gdiScreen)
438
{
439
// REMIND: looks like Direct3D provides information about texture memory
440
// only via IDirect3DDevice9::GetAvailableTextureMem, however, it
441
// seems to report the same amount as direct draw used to.
442
HRESULT res;
443
D3DPipelineManager *pMgr;
444
D3DContext *pCtx;
445
IDirect3DDevice9 *pd3dDevice;
446
UINT adapter;
447
448
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_getAvailableAcceleratedMemoryNative");
449
450
RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), 0L);
451
adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);
452
453
if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {
454
D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
455
return 0L;
456
}
457
RETURN_STATUS_IF_NULL(pd3dDevice = pCtx->Get3DDevice(), 0L);
458
459
UINT mem = pd3dDevice->GetAvailableTextureMem();
460
J2dTraceLn1(J2D_TRACE_VERBOSE, " available memory=%d", mem);
461
return mem;
462
}
463
464
/*
465
* Class: sun_java2d_d3d_D3DGraphicsDevice
466
* Method: isD3DAvailableOnDeviceNative
467
* Signature: (I)Z
468
*/
469
JNIEXPORT jboolean JNICALL
470
Java_sun_java2d_d3d_D3DGraphicsDevice_isD3DAvailableOnDeviceNative
471
(JNIEnv *env, jclass gdc, jint gdiScreen)
472
{
473
HRESULT res;
474
D3DPipelineManager *pMgr;
475
D3DContext *pCtx;
476
UINT adapter;
477
478
J2dTraceLn(J2D_TRACE_INFO, "D3DGD_isD3DAvailableOnDeviceNative");
479
480
RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);
481
adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);
482
483
if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {
484
D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());
485
return JNI_FALSE;
486
}
487
488
return JNI_TRUE;
489
}
490
491
} // extern "C"
492
493