Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/sun/java2d/d3d/D3DGraphicsDevice.cpp
32288 views
/*1* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "sun_java2d_d3d_D3DGraphicsDevice.h"26#include "D3DGraphicsDevice.h"27#include "D3DPipelineManager.h"28#include "D3DRenderQueue.h"29#include "Trace.h"30#include "awt_Toolkit.h"31#include "awt_Window.h"3233extern jobject CreateDisplayMode(JNIEnv* env, jint width, jint height,34jint bitDepth, jint refreshRate);35extern void addDisplayMode(JNIEnv* env, jobject arrayList, jint width,36jint height, jint bitDepth, jint refreshRate);3738extern "C" {39/*40* Class: sun_java2d_d3d_D3DGraphicsDevice41* Method: initD3D42* Signature: ()Z43*/44JNIEXPORT jboolean JNICALL Java_sun_java2d_d3d_D3DGraphicsDevice_initD3D45(JNIEnv *env, jclass)46{47J2dTraceLn(J2D_TRACE_INFO, "D3DGD_initD3D");4849jboolean result = D3DInitializer::GetInstance().EnsureInited()50? JNI_TRUE : JNI_FALSE;51J2dTraceLn1(J2D_TRACE_INFO, "D3DGD_initD3D: result=%x", result);52return result;53}5455/*56* Class: sun_java2d_d3d_D3DGraphicsDevice57* Method: getDeviceIdNative58* Signature: (I)Ljava/lang/String;59*/60JNIEXPORT jstring JNICALL Java_sun_java2d_d3d_D3DGraphicsDevice_getDeviceIdNative61(JNIEnv *env, jclass d3dsdc, jint gdiScreen)62{63D3DPipelineManager *pMgr;64UINT adapter;65D3DADAPTER_IDENTIFIER9 aid;66IDirect3D9 *pd3d9;6768J2dTraceLn(J2D_TRACE_INFO, "D3DGD_getDeviceIdNative");6970pMgr = D3DPipelineManager::GetInstance();71RETURN_STATUS_IF_NULL(pMgr, NULL);72pd3d9 = pMgr->GetD3DObject();73RETURN_STATUS_IF_NULL(pd3d9, NULL);7475adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);76if (FAILED(pd3d9->GetAdapterIdentifier(adapter, 0, &aid))) {77return NULL;78}7980// ('%d.' will take no more than 6+1 chars since we are printing a WORD)81// AAAA&BBBB MAX_DEVICE_IDENTIFIER_STRING (%d.%d.%d.%d)082size_t len = (4+1+4 +1+MAX_DEVICE_IDENTIFIER_STRING+1 +1+(6+1)*4+1 +1);83WCHAR *pAdapterId = new WCHAR[len];84RETURN_STATUS_IF_NULL(pAdapterId, NULL);8586_snwprintf(pAdapterId, len, L"%x&%x %S (%d.%d.%d.%d)",870xffff & aid.VendorId, 0xffff & aid.DeviceId, aid.Description,88HIWORD(aid.DriverVersion.HighPart),89LOWORD(aid.DriverVersion.HighPart),90HIWORD(aid.DriverVersion.LowPart),91LOWORD(aid.DriverVersion.LowPart));92// _snwprintf doesn't add 0 at the end if the formatted string didn't fit93// in the buffer so we have to make sure it is null terminated94pAdapterId[len-1] = (WCHAR)0;9596J2dTraceLn1(J2D_TRACE_VERBOSE, " id=%S", pAdapterId);9798jstring ret = JNU_NewStringPlatform(env, pAdapterId);99100delete[] pAdapterId;101102return ret;103}104105/*106* Class: sun_java2d_d3d_D3DGraphicsDevice107* Method: getDeviceCapsNative108* Signature: (I)I109*/110JNIEXPORT jint JNICALL111Java_sun_java2d_d3d_D3DGraphicsDevice_getDeviceCapsNative112(JNIEnv *env, jclass d3dsdc, jint gdiScreen)113{114D3DPipelineManager *pMgr;115D3DContext *pCtx;116UINT adapter;117118J2dRlsTraceLn(J2D_TRACE_INFO, "D3DGD_getDeviceCapsNative");119120pMgr = D3DPipelineManager::GetInstance();121RETURN_STATUS_IF_NULL(pMgr, CAPS_EMPTY);122adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);123124if (FAILED(pMgr->GetD3DContext(adapter, &pCtx))) {125J2dRlsTraceLn1(J2D_TRACE_ERROR,126"D3DGD_getDeviceCapsNative: device %d disabled", adapter);127return CAPS_EMPTY;128}129return pCtx->GetContextCaps();130}131132/*133* Class: sun_java2d_d3d_D3DGraphicsDevice134* Method: enterFullScreenExclusiveNative135* Signature: (IJ)V136*/137JNIEXPORT jboolean JNICALL138Java_sun_java2d_d3d_D3DGraphicsDevice_enterFullScreenExclusiveNative139(JNIEnv *env, jclass gdc, jint gdiScreen, jlong window)140{141HRESULT res;142D3DPipelineManager *pMgr;143D3DContext *pCtx;144HWND hWnd;145AwtWindow *w;146D3DPRESENT_PARAMETERS newParams, *pCurParams;147D3DDISPLAYMODE dm;148UINT adapter;149150J2dTraceLn(J2D_TRACE_INFO, "D3DGD_enterFullScreenExclusiveNative");151152RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);153adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);154155if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {156D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());157return JNI_FALSE;158}159160w = (AwtWindow *)AwtComponent::GetComponent((HWND)window);161if (w == NULL || !::IsWindow(hWnd = w->GetTopLevelHWnd())) {162J2dTraceLn(J2D_TRACE_WARNING,163"D3DGD_enterFullScreenExclusiveNative: disposed window");164return JNI_FALSE;165}166167// REMIND: should we also move the non-topleve window from168// being on top here (it's moved to front in GraphicsDevice.setFSW())?169170pCtx->Get3DObject()->GetAdapterDisplayMode(adapter, &dm);171pCurParams = pCtx->GetPresentationParams();172173// let the mananger know that we're entering the fs mode, it will174// set the proper current focus window for us, which ConfigureContext will175// use when creating the device176pMgr->SetFSFocusWindow(adapter, hWnd);177178newParams = *pCurParams;179newParams.hDeviceWindow = hWnd;180newParams.Windowed = FALSE;181newParams.BackBufferCount = 1;182newParams.BackBufferFormat = dm.Format;183newParams.FullScreen_RefreshRateInHz = dm.RefreshRate;184newParams.BackBufferWidth = dm.Width;185newParams.BackBufferHeight = dm.Height;186newParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;187newParams.SwapEffect = D3DSWAPEFFECT_DISCARD;188189res = pCtx->ConfigureContext(&newParams);190D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());191return SUCCEEDED(res);192}193194/*195* Class: sun_java2d_d3d_D3DGraphicsDevice196* Method: exitFullScreenExclusiveNative197* Signature: (I)V198*/199JNIEXPORT jboolean JNICALL200Java_sun_java2d_d3d_D3DGraphicsDevice_exitFullScreenExclusiveNative201(JNIEnv *env, jclass gdc, jint gdiScreen)202{203HRESULT res;204D3DPipelineManager *pMgr;205D3DContext *pCtx;206D3DPRESENT_PARAMETERS newParams, *pCurParams;207UINT adapter;208209J2dTraceLn(J2D_TRACE_INFO, "D3DGD_exitFullScreenExclusiveNative");210211RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);212adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);213214if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {215D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());216return JNI_FALSE;217}218219pCurParams = pCtx->GetPresentationParams();220221newParams = *pCurParams;222// we're exiting fs, the device window can be 0223newParams.hDeviceWindow = 0;224newParams.Windowed = TRUE;225newParams.BackBufferFormat = D3DFMT_UNKNOWN;226newParams.BackBufferCount = 1;227newParams.FullScreen_RefreshRateInHz = 0;228newParams.BackBufferWidth = 0;229newParams.BackBufferHeight = 0;230newParams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;231newParams.SwapEffect = D3DSWAPEFFECT_COPY;232233res = pCtx->ConfigureContext(&newParams);234D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());235236// exited fs, update current focus window237// note that we call this after this adapter exited fs mode so that238// the rest of the adapters can be reset239pMgr->SetFSFocusWindow(adapter, 0);240241return SUCCEEDED(res);242}243244/*245* Class: sun_java2d_d3d_D3DGraphicsDevice246* Method: configDisplayModeNative247* Signature: (IJIIII)V248*/249JNIEXPORT void JNICALL250Java_sun_java2d_d3d_D3DGraphicsDevice_configDisplayModeNative251(JNIEnv *env, jclass gdc, jint gdiScreen, jlong window,252jint width, jint height, jint bitDepth, jint refreshRate)253{254HRESULT res;255D3DPipelineManager *pMgr;256D3DContext *pCtx;257D3DPRESENT_PARAMETERS newParams, *pCurParams;258UINT adapter;259260J2dTraceLn(J2D_TRACE_INFO, "D3DGD_configDisplayModeNative");261262RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance());263adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);264265if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {266D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());267return;268}269270pCurParams = pCtx->GetPresentationParams();271272newParams = *pCurParams;273newParams.BackBufferWidth = width;274newParams.BackBufferHeight = height;275newParams.FullScreen_RefreshRateInHz = refreshRate;276newParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;277// we leave the swap effect so that it's more likely278// to be the one user selected initially279// newParams.SwapEffect = D3DSWAPEFFECT_DISCARD;280281if (bitDepth == 32) {282newParams.BackBufferFormat = D3DFMT_X8R8G8B8;283} else if (bitDepth == 16) {284UINT modeNum;285D3DDISPLAYMODE mode;286IDirect3D9 *pd3d9;287UINT modesCount;288289RETURN_IF_NULL(pd3d9 = pMgr->GetD3DObject());290291modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_R5G6B5);292if (modesCount == 0) {293modesCount = pd3d9->GetAdapterModeCount(adapter, D3DFMT_X1R5G5B5);294}295296newParams.BackBufferFormat = D3DFMT_UNKNOWN;297for (modeNum = 0; modeNum < modesCount; modeNum++) {298if (SUCCEEDED(pd3d9->EnumAdapterModes(adapter, D3DFMT_R5G6B5,299modeNum, &mode)))300{301if (mode.Width == width && mode.Height == height &&302mode.RefreshRate == refreshRate)303{304// prefer 565 over 555305if (mode.Format == D3DFMT_R5G6B5) {306newParams.BackBufferFormat = D3DFMT_R5G6B5;307break;308} else if (mode.Format == D3DFMT_X1R5G5B5) {309newParams.BackBufferFormat = D3DFMT_X1R5G5B5;310}311}312}313}314if (newParams.BackBufferFormat == D3DFMT_UNKNOWN) {315J2dRlsTraceLn(J2D_TRACE_ERROR,316"D3DGD_configDisplayModeNative: no 16-bit formats");317return;318}319} else {320J2dRlsTraceLn1(J2D_TRACE_ERROR,321"D3DGD_configDisplayModeNative: unsupported depth: %d",322bitDepth);323return;324}325326J2dTraceLn4(J2D_TRACE_VERBOSE, " changing to dm: %dx%dx%d@%d",327newParams.BackBufferWidth, newParams.BackBufferHeight,328bitDepth, refreshRate);329J2dTraceLn1(J2D_TRACE_VERBOSE, " selected backbuffer format: %d",330newParams.BackBufferFormat);331332res = pCtx->ConfigureContext(&newParams);333if (SUCCEEDED(res)) {334// the full screen window doesn't receive WM_SIZE event when335// the display mode changes (it does get resized though) so we need to336// generate the event ourselves337::SendMessage(newParams.hDeviceWindow, WM_SIZE, width, height);338}339D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());340}341342343/*344* Class: sun_java2d_d3d_D3DGraphicsDevice345* Method: getCurrentDisplayModeNative346* Signature: (I)Ljava/awt/DisplayMode;347*/348JNIEXPORT jobject JNICALL349Java_sun_java2d_d3d_D3DGraphicsDevice_getCurrentDisplayModeNative350(JNIEnv *env, jclass gdc, jint gdiScreen)351{352D3DPipelineManager *pMgr;353IDirect3D9 *pd3d9;354jobject ret = NULL;355D3DDISPLAYMODE mode;356UINT adapter;357358J2dTraceLn(J2D_TRACE_INFO, "D3DGD_getCurrentDisplayModeNative");359360RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), NULL);361RETURN_STATUS_IF_NULL(pd3d9 = pMgr->GetD3DObject(), NULL);362adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);363364if (SUCCEEDED(pd3d9->GetAdapterDisplayMode(adapter, &mode))) {365int bitDepth = -1;366// these are the only three valid screen formats367switch (mode.Format) {368case D3DFMT_X8R8G8B8: bitDepth = 32; break;369case D3DFMT_R5G6B5:370case D3DFMT_X1R5G5B5: bitDepth = 16; break;371}372J2dTraceLn4(J2D_TRACE_VERBOSE,373" current dm: %dx%dx%d@%d",374mode.Width, mode.Height, bitDepth, mode.RefreshRate);375ret = CreateDisplayMode(env, mode.Width, mode.Height, bitDepth,376mode.RefreshRate);377}378return ret;379}380381/*382* Class: sun_java2d_d3d_D3DGraphicsDevice383* Method: enumDisplayModesNative384* Signature: (ILjava/util/ArrayList;)V385*/386JNIEXPORT void JNICALL387Java_sun_java2d_d3d_D3DGraphicsDevice_enumDisplayModesNative388(JNIEnv *env, jclass gdc, jint gdiScreen, jobject arrayList)389{390D3DPipelineManager *pMgr;391IDirect3D9 *pd3d9;392jobject ret = NULL;393D3DDISPLAYMODE mode;394UINT formatNum, modeNum, modesCount;395UINT adapter;396// EnumAdapterModes treats 555 and 565 formats as equivalents397static D3DFORMAT formats[] =398{ D3DFMT_X8R8G8B8, D3DFMT_R5G6B5 };399400J2dTraceLn(J2D_TRACE_INFO, "D3DGD_enumDisplayModesNative");401402RETURN_IF_NULL(pMgr = D3DPipelineManager::GetInstance());403RETURN_IF_NULL(pd3d9 = pMgr->GetD3DObject());404adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);405406for (formatNum = 0; formatNum < (sizeof formats)/(sizeof *formats); formatNum++) {407modesCount = pd3d9->GetAdapterModeCount(adapter, formats[formatNum]);408for (modeNum = 0; modeNum < modesCount; modeNum++) {409if (SUCCEEDED(pd3d9->EnumAdapterModes(adapter, formats[formatNum],410modeNum, &mode)))411{412int bitDepth = -1;413// these are the only three valid screen formats,414// 30-bit is returned as X8R8G8B8415switch (mode.Format) {416case D3DFMT_X8R8G8B8: bitDepth = 32; break;417case D3DFMT_R5G6B5:418case D3DFMT_X1R5G5B5: bitDepth = 16; break;419}420J2dTraceLn4(J2D_TRACE_VERBOSE, " found dm: %dx%dx%d@%d",421mode.Width, mode.Height, bitDepth,mode.RefreshRate);422addDisplayMode(env, arrayList, mode.Width, mode.Height,423bitDepth, mode.RefreshRate);424}425}426}427}428429/*430* Class: sun_java2d_d3d_D3DGraphicsDevice431* Method: getAvailableAcceleratedMemoryNative432* Signature: (I)J433*/434JNIEXPORT jlong JNICALL435Java_sun_java2d_d3d_D3DGraphicsDevice_getAvailableAcceleratedMemoryNative436(JNIEnv *env, jclass gdc, jint gdiScreen)437{438// REMIND: looks like Direct3D provides information about texture memory439// only via IDirect3DDevice9::GetAvailableTextureMem, however, it440// seems to report the same amount as direct draw used to.441HRESULT res;442D3DPipelineManager *pMgr;443D3DContext *pCtx;444IDirect3DDevice9 *pd3dDevice;445UINT adapter;446447J2dTraceLn(J2D_TRACE_INFO, "D3DGD_getAvailableAcceleratedMemoryNative");448449RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), 0L);450adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);451452if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {453D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());454return 0L;455}456RETURN_STATUS_IF_NULL(pd3dDevice = pCtx->Get3DDevice(), 0L);457458UINT mem = pd3dDevice->GetAvailableTextureMem();459J2dTraceLn1(J2D_TRACE_VERBOSE, " available memory=%d", mem);460return mem;461}462463/*464* Class: sun_java2d_d3d_D3DGraphicsDevice465* Method: isD3DAvailableOnDeviceNative466* Signature: (I)Z467*/468JNIEXPORT jboolean JNICALL469Java_sun_java2d_d3d_D3DGraphicsDevice_isD3DAvailableOnDeviceNative470(JNIEnv *env, jclass gdc, jint gdiScreen)471{472HRESULT res;473D3DPipelineManager *pMgr;474D3DContext *pCtx;475UINT adapter;476477J2dTraceLn(J2D_TRACE_INFO, "D3DGD_isD3DAvailableOnDeviceNative");478479RETURN_STATUS_IF_NULL(pMgr = D3DPipelineManager::GetInstance(), JNI_FALSE);480adapter = pMgr->GetAdapterOrdinalForScreen(gdiScreen);481482if (FAILED(res = pMgr->GetD3DContext(adapter, &pCtx))) {483D3DRQ_MarkLostIfNeeded(res, D3DRQ_GetCurrentDestination());484return JNI_FALSE;485}486487return JNI_TRUE;488}489490} // extern "C"491492493