![JAR search and dependency download from the Maven repository](/logo.png)
native-prism-d3d.D3DResourceFactory.cc Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openjfx-78-backport-native Show documentation
Show all versions of openjfx-78-backport-native Show documentation
This contains the native files for the backport of OpenJFX 8 to run on Java 7.
The newest version!
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "com_sun_prism_d3d_D3DResourceFactory.h"
#include "D3DPipelineManager.h"
#include "D3DResourceManager.h"
#include "D3DContext.h"
#include "TextureUploader.h"
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nGetContext
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nGetContext
(JNIEnv *jEnv, jclass, jint adapterOrdinal)
{
D3DPipelineManager *pMgr = D3DPipelineManager::GetInstance();
D3DContext *pCtx = NULL;
HRESULT res;
RETURN_STATUS_IF_NULL(pMgr, 0L);
res = pMgr->GetD3DContext(adapterOrdinal, &pCtx);
if (SUCCEEDED(res)) {
pCtx->ResetClip();
pCtx->ResetTransform();
return ptr_to_jlong(pCtx);
}
return 0L;
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nCreateTexture
*/
JNIEXPORT jlong JNICALL
Java_com_sun_prism_d3d_D3DResourceFactory_nCreateTexture
(JNIEnv *env, jclass klass,
jlong ctx, jint formatHint, jint usageHint, jboolean isRTT, jint width, jint height)
{
HRESULT res;
TraceLn5(NWT_TRACE_INFO,
"nCreateTexture formatHint=%d usageHint=%d isRTT=%d w=%d h=%d",
formatHint, usageHint, isRTT, width, height);
D3DContext *pCtx = (D3DContext *)jlong_to_ptr(ctx);
D3DResourceManager *pMgr = pCtx->GetResourceManager();
D3DResource *pTexResource;
D3DFORMAT format = D3DFMT_UNKNOWN;
// only considered when the format isn't explicitly requested
BOOL isOpaque = FALSE;
if (usageHint == 1) {
OutputDebugStringA("Texture.Usage.DYNAMIC");
}
DWORD dwUsage = usageHint == 1/*Texture.Usage.DYNAMIC*/ ? D3DUSAGE_DYNAMIC : 0;
// formatHint is the hint about the content of the texture, not a hard
// requirement
switch (formatHint) {
case PFORMAT_BYTE_RGBA_PRE:
case PFORMAT_INT_ARGB_PRE:
format = D3DFMT_A8R8G8B8;
break;
case PFORMAT_BYTE_RGB: // Note: this is actually 3-byte RGB
format = D3DFMT_X8R8G8B8;
break;
case PFORMAT_BYTE_GRAY:
format = D3DFMT_L8;
break;
case PFORMAT_BYTE_ALPHA:
format = D3DFMT_A8;
break;
case PFORMAT_FLOAT_XYZW:
format = D3DFMT_A32B32G32R32F;
break;
default:
RlsTraceLn1(NWT_TRACE_WARNING,
"nCreateTexture: unknown format hint: %d", formatHint);
break;
}
res = pMgr->CreateTexture(width, height, isRTT, isOpaque,
&format, dwUsage, &pTexResource);
if (SUCCEEDED(res)) {
return ptr_to_jlong(pTexResource);
}
return 0L;
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nCreateSwapChain
* Signature: (JJ)J
*/
JNIEXPORT jlong JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nCreateSwapChain
(JNIEnv *jEnv, jclass, jlong ctx, jlong hwnd, jboolean isVsyncEnabled)
{
HRESULT res;
D3DContext *pCtx = (D3DContext*)jlong_to_ptr(ctx);
HWND hWnd = (HWND)(jlong_to_ptr(hwnd));
D3DResource *pSwapChainRes = NULL;
if (!::IsWindow(hWnd)) {
TraceLn1(NWT_TRACE_ERROR, "nGetSwapChain: hwnd=%x is not a window\n", hWnd);
return 0L;
}
res = pCtx->GetResourceManager()->
CreateSwapChain(hWnd, 1,
0, 0,
// have to use COPY since we don't re-render the scene
// if it didn't change
D3DSWAPEFFECT_COPY,
isVsyncEnabled ?
D3DPRESENT_INTERVAL_ONE :
D3DPRESENT_INTERVAL_IMMEDIATE,
&pSwapChainRes);
if (SUCCEEDED(res)) {
return ptr_to_jlong(pSwapChainRes);
}
return 0L;
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nReleaseResource
*/
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nReleaseResource
(JNIEnv *env, jclass, jlong ctx, jlong resource)
{
D3DContext *pCtx = (D3DContext*)jlong_to_ptr(ctx);
IManagedResource *pResource = (IManagedResource*)jlong_to_ptr(resource);
RETURN_STATUS_IF_NULL(pResource, D3D_OK);
return pCtx->GetResourceManager()->ReleaseResource(pResource);
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nGetMaximumTextureSize
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nGetMaximumTextureSize
(JNIEnv *, jclass, jlong ctx)
{
D3DContext *pCtx = (D3DContext*)jlong_to_ptr(ctx);
D3DCAPS9 *caps = pCtx->GetDeviceCaps();
DWORD maxw = caps->MaxTextureWidth;
DWORD maxh = caps->MaxTextureHeight;
DWORD max = (maxw < maxh) ? maxw : maxh;
return (jint)max;
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nGetTextureWidth
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nGetTextureWidth
(JNIEnv *, jclass, jlong resource)
{
D3DResource *pResource = (D3DResource*)jlong_to_ptr(resource);
RETURN_STATUS_IF_NULL(pResource, -1);
return (jint)pResource->GetDesc()->Width;
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nGetTextureHeight
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nGetTextureHeight
(JNIEnv *, jclass, jlong resource)
{
D3DResource *pResource = (D3DResource*)jlong_to_ptr(resource);
RETURN_STATUS_IF_NULL(pResource, -1);
return (jint)pResource->GetDesc()->Height;
}
inline HRESULT updateTexture(
D3DContext *pCtx, D3DResource *pTexResource, PBYTE pixels, jint size, jint format,
jint dstx, jint dsty, jint srcx, jint srcy, jint srcw, jint srch, jint srcscan)
{
D3DSURFACE_DESC * desc = pTexResource->GetDesc();
bool paramsOK = TextureUpdater::validateArguments(
dstx, dsty, desc->Width, desc->Height,
srcx, srcy, srcw, srch,
size, PFormat(format), srcscan);
if (!paramsOK) return E_INVALIDARG;
TextureUpdater updater;
updater.setTarget(pTexResource->GetTexture(), desc, dstx, dsty);
updater.setSource(pixels, size, PFormat(format), srcx, srcy, srcw, srch, srcscan);
IDirect3DDevice9Ex *pDev = pCtx->Get3DExDevice();
int nBytes = pDev
? updater.updateD3D9ExTexture(pDev)
: updater.updateLockableTexture();
#if defined PERF_COUNTERS
D3DContext::FrameStats &stats = pCtx->getStats();
stats.numTextureLocks++;
stats.numTextureTransferBytes += nBytes;
#endif
return nBytes ? S_OK : E_FAIL;
}
// note that
// - Java_com_sun_prism_d3d_D3DResourceFactory_nUpdateTextureI
// - Java_com_sun_prism_d3d_D3DResourceFactory_nUpdateTextureB
// - Java_com_sun_prism_d3d_D3DResourceFactory_nUpdateTextureF
// are completely identical in the body text
// It happens because in JNI we have a baseclass for arrays : jarray,
// but we have not got something similar in java
// is it possible to optimize it somehow ?
typedef D3DContext* PD3DContext;
typedef D3DResource* PD3DResource;
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nUpdateTextureI
*/
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nUpdateTextureI
(JNIEnv *env, jclass, jlong ctx, jlong resource,
jobject buf, jintArray pixelArray,
jint dstx, jint dsty,
jint srcx, jint srcy,
jint srcw, jint srch, jint srcscan)
{
RETURN_STATUS_IF_NULL(resource, E_FAIL);
jint size = pixelArray ?
env->GetArrayLength(pixelArray) * sizeof(jint) :
jint(env->GetDirectBufferCapacity(buf));
PBYTE pixels = PBYTE((pixelArray != NULL) ?
env->GetPrimitiveArrayCritical(pixelArray, NULL) :
env->GetDirectBufferAddress(buf));
if (pixels == NULL) {
return E_OUTOFMEMORY;
}
HRESULT res = updateTexture(
PD3DContext(ctx), PD3DResource(resource), pixels, size, PFORMAT_INT_ARGB_PRE,
dstx, dsty, srcx, srcy, srcw, srch, srcscan);
if (pixelArray != NULL) {
env->ReleasePrimitiveArrayCritical(pixelArray, pixels, JNI_ABORT);
}
return res;
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nUpdateTextureB
*/
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nUpdateTextureB
(JNIEnv *env, jclass, jlong ctx, jlong resource,
jobject buf, jbyteArray pixelArray, jint formatHint,
jint dstx, jint dsty,
jint srcx, jint srcy,
jint srcw, jint srch, jint srcscan)
{
RETURN_STATUS_IF_NULL(resource, E_FAIL);
jint size = pixelArray ?
env->GetArrayLength(pixelArray) * sizeof(jbyte) :
jint(env->GetDirectBufferCapacity(buf));
PBYTE pixels = PBYTE((pixelArray != NULL) ?
env->GetPrimitiveArrayCritical(pixelArray, NULL) :
env->GetDirectBufferAddress(buf));
if (pixels == NULL) {
return E_OUTOFMEMORY;
}
HRESULT res = updateTexture(
PD3DContext(ctx), PD3DResource(resource), pixels, size, formatHint,
dstx, dsty, srcx, srcy, srcw, srch, srcscan);
if (pixelArray != NULL) {
env->ReleasePrimitiveArrayCritical(pixelArray, pixels, JNI_ABORT);
}
return res;
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nUpdateTextureF
*/
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nUpdateTextureF
(JNIEnv *env, jclass, jlong ctx, jlong resource,
jobject buf, jfloatArray pixelArray,
jint dstx, jint dsty,
jint srcx, jint srcy,
jint srcw, jint srch, jint srcscan)
{
RETURN_STATUS_IF_NULL(resource, E_FAIL);
jint size = pixelArray ?
env->GetArrayLength(pixelArray) * sizeof(jfloat) :
jint(env->GetDirectBufferCapacity(buf));
PBYTE pixels = PBYTE((pixelArray != NULL) ?
env->GetPrimitiveArrayCritical(pixelArray, NULL) :
env->GetDirectBufferAddress(buf));
if (pixels == NULL) {
return E_OUTOFMEMORY;
}
HRESULT res = updateTexture(
PD3DContext(ctx), PD3DResource(resource), pixels, size, PFORMAT_FLOAT_XYZW,
dstx, dsty, srcx, srcy, srcw, srch, srcscan);
if (pixelArray != NULL) {
env->ReleasePrimitiveArrayCritical(pixelArray, pixels, JNI_ABORT);
}
return res;
}
static void copy_X8R8G8B8(DWORD *pDstPixels, DWORD const *pSrcPixels, int n) {
for (int i = 0; i!=n; ++i) {
pDstPixels[i] = pSrcPixels[i] | 0xff000000;
}
}
static HRESULT D3DResourceFactory_nReadPixels(D3DContext *pCtx, D3DResource *pResource, BYTE *pixels, int cntW, int cntH)
{
TraceLn(NWT_TRACE_INFO, "D3DResourceFactory_nReadPixels");
IDirect3DDevice9 *pd3dDevice = pCtx->Get3DDevice();
IDirect3DSurface9 *pSrc = pResource->GetSurface();
RETURN_STATUS_IF_NULL(pd3dDevice, E_FAIL);
RETURN_STATUS_IF_NULL(pSrc, E_FAIL);
D3DFORMAT srcFmt = pResource->GetDesc()->Format;
UINT srcw = pResource->GetDesc()->Width;
UINT srch = pResource->GetDesc()->Height;
if (srcFmt != D3DFMT_A8R8G8B8 && srcFmt != D3DFMT_X8R8G8B8) {
RlsTraceLn1(NWT_TRACE_ERROR,
"D3DResourceFactory_nReadPixels doesn't support format %d", srcFmt);
return E_FAIL;
}
// the dest surface must have the same dimensions and format as
// the source, GetBlitOSPSurface ensures that
D3DResource *pLockableRes = 0;
HRESULT res = pCtx->GetResourceManager()->
GetBlitOSPSurface(srcw, srch, srcFmt, &pLockableRes);
if (SUCCEEDED(res)) {
IDirect3DSurface9 *pTmpSurface = pLockableRes->GetSurface();
pCtx->EndScene();
res = pd3dDevice->GetRenderTargetData(pSrc, pTmpSurface);
if (SUCCEEDED(res)) {
D3DLOCKED_RECT lockedRect;
if (FAILED(res = pTmpSurface->LockRect(&lockedRect, NULL,
D3DLOCK_NOSYSLOCK)))
{
RlsTraceLn1(NWT_TRACE_ERROR,
"D3DResourceFactory_nReadPixels lock failed res=%x", res);
return res;
}
// assuming int (a|x)rgb type, and 0,0 source coordinates
BYTE const *pSrcPixels = PBYTE(lockedRect.pBits);
BYTE *pDstPixels = pixels;
switch (srcFmt) {
case D3DFMT_A8R8G8B8:
for (int y=0; y!=cntH; ++y) {
// cntW, cntH are sanity checked in ReadPixelsHelper function
memcpy(pDstPixels, pSrcPixels, cntW*4);
pSrcPixels += lockedRect.Pitch;
pDstPixels += cntW*4;
}
break;
case D3DFMT_X8R8G8B8:
for (int y=0; y!=cntH; ++y) {
// cntW, cntH are sanity checked in ReadPixelsHelper function
copy_X8R8G8B8(PDWORD(pDstPixels), (DWORD const*)(pSrcPixels), cntW*4);
pSrcPixels += lockedRect.Pitch;
pDstPixels += cntW*4;
}
break;
}
res = pTmpSurface->UnlockRect();
}
}
return res;
}
static HRESULT nReadPixelsHelper(
JNIEnv *env, jlong context, jlong resource, jlong length,
jobject buf, jarray pixelArray, jint cntW, jint cntH)
{
BYTE *pixels = PBYTE( pixelArray ?
env->GetPrimitiveArrayCritical(pixelArray, 0) :
env->GetDirectBufferAddress(buf));
if (!pixels) return E_OUTOFMEMORY;
// sanity check about we have enought memory
// Since we are certain cntW and cntH are positive numbers
if ( UINT(length)/4/cntW < UINT(cntH) ) {
RlsTraceLn1(NWT_TRACE_ERROR,
"D3DResourceFactory_nReadPixels buffer too small: %ld",
length);
return E_OUTOFMEMORY;
}
D3DContext *pCtx = (D3DContext*)jlong_to_ptr(context);
D3DResource *pResource = (D3DResource*)jlong_to_ptr(resource);
if (!pResource) return E_FAIL;
HRESULT res = D3DResourceFactory_nReadPixels(pCtx, pResource, pixels, cntW, cntH);
if (pixelArray) {
env->ReleasePrimitiveArrayCritical(pixelArray, pixels, 0);
}
return res;
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nReadPixelsI and nReadPixelsB
* 2Do: better to make helper class rather than copying all parameters
*/
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nReadPixelsI
(JNIEnv *env, jclass, jlong context, jlong resource, jlong length,
jobject buf, jintArray pixelArray, jint cntW, jint cntH)
{
TraceLn(NWT_TRACE_INFO, "D3DResourceFactory_nReadPixelsI");
return nReadPixelsHelper(env, context, resource, length, buf, pixelArray, cntW, cntH);
}
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nReadPixelsB
(JNIEnv *env, jclass clazz, jlong context, jlong resource, jlong length,
jobject buf, jbyteArray pixelArray, jint cntW, jint cntH)
{
TraceLn(NWT_TRACE_INFO, "D3DResourceFactory_nReadPixelsB");
return nReadPixelsHelper(env, context, resource, length, buf, pixelArray, cntW, cntH);
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nSetDisposerRecord
* Signature: (JLcom/sun/prism/d3d/D3DResource/D3DRecord;)V
*/
JNIEXPORT jboolean JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nIsDefaultPool
(JNIEnv *env, jclass clazz, jlong resource)
{
IManagedResource *pResource = (IManagedResource*)jlong_to_ptr(resource);
RETURN_STATUS_IF_NULL(pResource, FALSE);
return pResource->IsDefaultPool();
}
/*
* Class: com_sun_prism_d3d_D3DResourceFactory
* Method: nTestCooperativeLevel
*/
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nTestCooperativeLevel
(JNIEnv *, jclass, jlong context)
{
D3DContext *pCtx = (D3DContext*)jlong_to_ptr(context);
return pCtx->TestCooperativeLevel();
}
JNIEXPORT jint JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nResetDevice
(JNIEnv *env, jclass, jlong context)
{
D3DContext *pCtx = (D3DContext*)jlong_to_ptr(context);
return pCtx->ResetContext();
}
JNIEXPORT jlong JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nGetDevice
(JNIEnv *env, jclass, jlong context)
{
D3DContext *pCtx = (D3DContext*)jlong_to_ptr(context);
return jlong(pCtx->Get3DDevice());
}
JNIEXPORT jlong JNICALL Java_com_sun_prism_d3d_D3DResourceFactory_nGetNativeTextureObject
(JNIEnv *, jclass, jlong resource)
{
D3DResource *pResource = (D3DResource*)jlong_to_ptr(resource);
return jlong(pResource->GetTexture());
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy