HRESULT DX5Object::CreateSurface(DWORD dwCaps, DWORD ddsCaps,
				 LPDDPIXELFORMAT lpPf,
				 int width, int height,
				 DXSurface **lpDDSurface,
				 int numBackBuffers) 
{
    IDirectDrawSurface *lpSurface;
    HRESULT ddResult;
    DDSURFACEDESC ddsd;
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = dwCaps;
    ddsd.ddsCaps.dwCaps = ddsCaps;
    ddsd.dwWidth = width;
    ddsd.dwHeight = height;
    ddsd.dwBackBufferCount = numBackBuffers;
    if (lpPf) {
	memcpy(&ddsd.ddpfPixelFormat, lpPf, sizeof(DDPIXELFORMAT));
    }
    ddResult = ddObject->CreateSurface(&ddsd, &lpSurface, NULL);
    if (ddResult != DD_OK) {
	DebugPrintDirectDrawError(ddResult, "DX5Object::CreateSurface");
	return ddResult;
    }
    *lpDDSurface = new DX5Surface(lpSurface);
    
    return DD_OK;
}
BOOL DDraw::GetDDCaps(LPDDCAPS caps) {
    HRESULT ddResult;

    memset(caps, 0, sizeof(*caps));
    caps->dwSize = sizeof(*caps);
    ddResult = dxObject->GetCaps(caps, NULL);
    if (ddResult != DD_OK) {
	DebugPrintDirectDrawError(ddResult, "GetDDCaps");
	return FALSE;
    }
    return TRUE;
}
D3DObject *DX5Object::CreateD3DObject()
{
    IDirect3D2 *d3dInterface;
    D3DObject *d3dObject = NULL;
    HRESULT ddResult = ddObject->QueryInterface(IID_IDirect3D2, 
    						(void**)&d3dInterface);
    if (d3dInterface && (ddResult == DD_OK)) {
	d3dObject = new D3D5Object(d3dInterface);
    } else {
	// QueryInterface can fail here (Itanium); handle it gracefully
	DebugPrintDirectDrawError(ddResult, "Dx5Object::CreateD3DObject");
    }
    return d3dObject;
}
HRESULT DDraw::GetDDAvailableVidMem(DWORD *freeMem)
{
    DDrawDisplayMode dm;
    HRESULT ddResult;
    
    ddResult = dxObject->GetAvailableVidMem((DDSCAPS_VIDEOMEMORY |
    					     DDSCAPS_OFFSCREENPLAIN),
    					    NULL, freeMem);
    if (*freeMem == 0 || ddResult != DD_OK) {
	// Need to check it out ourselves: allocate as much as we can
	// and return that amount
	DDSURFACEDESC ddsd;
	ZeroMemory (&ddsd, sizeof(ddsd));
	ddsd.dwSize = sizeof( ddsd );
	HRESULT ddr = dxObject->GetDisplayMode(dm);
	if (ddr != DD_OK) 
	    DebugPrintDirectDrawError(ddr, "getDispMode");
	int bytesPerPixel = dm.bitDepth;
	static int maxSurfaces = 20;
	DXSurface **lpDDSOffscreenVram = (DXSurface**)
	    safe_Malloc(maxSurfaces*sizeof(DXSurface*));
	DWORD dwFlags = (DWORD)(DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH);
	DWORD ddsCaps = (DWORD)(DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN);
	int size = 1024;
	int numVramSurfaces = 0;
	int bitsAllocated = 0;
	BOOL done = FALSE;
	while (!done) {
	    HRESULT hResult = 
	    	dxObject->CreateSurface(dwFlags, ddsCaps, NULL, size, size,
					&lpDDSOffscreenVram[numVramSurfaces]);
	    if (hResult != DD_OK) {
		if (size > 1) {
		    size >>= 1;
		} else {
		    done = TRUE;
		}
	    } else {
DDraw *DDraw::CreateDDrawObject(GUID *lpGUID) {

    DTRACE_PRINTLN("DDraw::Init");
    HRESULT ddResult;
    DXObject *newDXObject;

    // First, try to create a DX7 object
    FnDDCreateExFunc ddCreateEx = NULL;

    if (getenv("NO_J2D_DX7") == NULL) {
	ddCreateEx = (FnDDCreateExFunc)
	::GetProcAddress(hLibDDraw, "DirectDrawCreateEx");
    }

    if (ddCreateEx) {

	DTRACE_PRINTLN("Using DX7");
	// Success - we are going to use the DX7 interfaces
	// create ddraw object
	IDirectDraw7 	*ddObject;

	ddResult = (*ddCreateEx)(lpGUID, (void**)&ddObject, IID_IDirectDraw7, NULL);
	if (ddResult != DD_OK) {
	    DebugPrintDirectDrawError(ddResult, "DDCreateDD dd create");
	    return NULL;
	}
	ddResult = ddObject->SetCooperativeLevel(NULL, 
						 (DDSCL_NORMAL | 
						  DDSCL_FPUPRESERVE));
	if (ddResult != DD_OK) {
	    DebugPrintDirectDrawError(ddResult,
		"DDraw::Init setting cooperative level");
	    return NULL;
	}
	newDXObject = new DX7Object(ddObject);
    
    } else {
	DTRACE_PRINTLN("Using DX5");
	// No DX7, try for DX3/5
	IDirectDraw 	*ddObject;
	IDirectDraw2 	*dd2Object;

	FnDDCreateFunc ddCreate = (FnDDCreateFunc)
	    ::GetProcAddress(hLibDDraw, "DirectDrawCreate");
	if (!ddCreate) {
	    // REMIND: might want to shut down ddraw (useDD == FALSE?)
	    // if this error occurs
	    DTRACE_PRINTLN("Could not create DDraw");
	    return NULL;
	}
	// create ddraw object
	ddResult = (*ddCreate)(lpGUID, &ddObject, NULL);
	if (ddResult != DD_OK) {
	    DebugPrintDirectDrawError(ddResult, "DDCreateDD dd create");
	    return NULL;
	}
	ddResult = ddObject->QueryInterface(IID_IDirectDraw2,
	    (void**)&dd2Object);
	if (ddResult != S_OK) {
	    // DirectDraw2 was supported in DX3; don't bother
	    // with anything less than this
	    DebugPrintDirectDrawError(ddResult,
		"DDraw::CreateDDrawObject finding dd3 interface");
	    return NULL;
	}

	ddResult = dd2Object->SetCooperativeLevel(NULL, DDSCL_NORMAL);
	if (ddResult != DD_OK) {
	    DebugPrintDirectDrawError(ddResult,
				      "DDraw::CreateDD setting coop level");
	    return NULL;
	}
	newDXObject = new DX5Object(dd2Object);
    }

    return new DDraw(newDXObject);
}
Example #6
0
/*
 * Class:     sun_java2d_d3d_D3DSurfaceData
 * Method:    initOffScreenSurface
 * Signature: (JJJIIII)I
 */
JNIEXPORT jint JNICALL
Java_sun_java2d_d3d_D3DSurfaceData_initOffScreenSurface
    (JNIEnv *env, jobject sData,
     jlong pCtx,
     jlong pData, jlong parentPdata,
     jint width, jint height,
     jint d3dSurfaceType, jint screen)
{
    Win32SDOps *wsdo = (Win32SDOps *)jlong_to_ptr(pData);
    D3DContext *pd3dc = (D3DContext *)jlong_to_ptr(pCtx);

    J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initOffScreenSurface");
    J2dTraceLn4(J2D_TRACE_VERBOSE,
                "  width=%-4d height=%-4d type=%-3d scr=%-3d",
                width, height, d3dSurfaceType, screen);

    // REMIND: ideally this should be done in initOps
    if (d3dSurfaceType == D3D_ATTACHED_SURFACE) {
        wsdo->sdOps.Dispose = Win32BBSD_Dispose;
    }

    if (init_D3DSDO(env, wsdo, width, height,
                    d3dSurfaceType, screen) == JNI_FALSE)
    {
        SurfaceData_ThrowInvalidPipeException(env,
            "Can't create offscreen surface");
        return PF_INVALID;
    }

    HMONITOR hMon = (HMONITOR)wsdo->device->GetMonitor();
    DDrawObjectStruct *ddInstance = GetDDInstanceForDevice(hMon);
    if (!ddInstance || !ddInstance->valid || !pd3dc) {
        return PF_INVALID;
    }

    if (d3dSurfaceType == D3D_ATTACHED_SURFACE) {
        // REMIND: still using the old path. ideally the creation of attached
        // surface shoudld be done in the same way as other types of surfaces,
        // that is, in D3DContext::CreateSurface, but we really don't use
        // anything from D3DContext to get an attached surface, so this
        // was left here.

        Win32SDOps *wsdo_parent = (Win32SDOps *)jlong_to_ptr(parentPdata);
        // we're being explicit here: requesting backbuffer, and render target
        DDrawSurface* pNew = wsdo_parent->lpSurface == NULL ?
            NULL :
            wsdo_parent->lpSurface->
                GetDDAttachedSurface(DDSCAPS_BACKBUFFER|DDSCAPS_3DDEVICE);
        if (pNew == NULL ||
            FAILED(pd3dc->AttachDepthBuffer(pNew->GetDXSurface())))
        {
            J2dRlsTraceLn1(J2D_TRACE_ERROR,
                           "D3DSD_initSurface: GetAttachedSurface for parent"\
                           " wsdo_parent->lpSurface=0x%x failed",
                           wsdo_parent->lpSurface);
            if (pNew != NULL) {
                delete pNew;
            }
            SurfaceData_ThrowInvalidPipeException(env,
                "Can't create attached offscreen surface");
            return PF_INVALID;
        }

        wsdo->lpSurface = pNew;
        wsdo->ddInstance = ddInstance;
        J2dTraceLn2(J2D_TRACE_VERBOSE,
                    "D3DSD_initSurface: created attached surface: "\
                    "wsdo->lpSurface=0x%x for parent "\
                    "wsdo_parent->lpSurface=0x%x",
                    wsdo->lpSurface, wsdo_parent->lpSurface);
        // we don't care about pixel format for non-texture surfaces
        return PF_INVALID;
    }

    DXSurface *dxSurface = NULL;
    jint pf = PF_INVALID;
    HRESULT res;
    if (SUCCEEDED(res = pd3dc->CreateSurface(env, wsdo->w, wsdo->h,
                                             wsdo->depth, wsdo->transparency,
                                             d3dSurfaceType,
                                             &dxSurface, &pf)))
    {
        // REMIND: put all the error-handling stuff here from
        // DDCreateOffScreenSurface
        wsdo->lpSurface = new DDrawSurface(ddInstance->ddObject, dxSurface);
        wsdo->surfacePuntData.lpSurfaceVram = wsdo->lpSurface;
        wsdo->ddInstance = ddInstance;
        // the dimensions of the surface may be adjusted in case of
        // textures
        wsdo->w = dxSurface->GetWidth();
        wsdo->h = dxSurface->GetHeight();
        J2dTraceLn1(J2D_TRACE_VERBOSE,
                    "D3DSurfaceData_initSurface: created surface: "\
                    "wsdo->lpSurface=0x%x", wsdo->lpSurface);
    } else {
        DebugPrintDirectDrawError(res,
                                  "D3DSurfaceData_initSurface: "\
                                  "CreateSurface failed");
        // REMIND: should use some other way to signal that
        // surface creation was unsuccessful
        SurfaceData_ThrowInvalidPipeException(env,
                                              "Can't create offscreen surf");
    }
    return pf;
}