Beispiel #1
0
static HDC Win32OSSD_GetDC(JNIEnv *env, Win32SDOps *wsdo,
                           jint type, jint *patrop,
                           jobject clip, jobject comp, jint color)
{
    // REMIND: Should lock around all accesses to "last<mumble>"
    DTRACE_PRINTLN1("Win32OSSD.GetDC, color = 0x%x", color);

    if (wsdo->invalid) {
	SurfaceData_ThrowInvalidPipeException(env, "invalid sd");
	return (HDC) NULL;
    }

    HDC hdc = wsdo->lpSurface->GetDC();
    if (hdc == NULL) {
	// Note: DDrawSurface::GetDC() releases its surfaceLock
	// when it returns an error here, so do not call ReleaseDC()
	// to force the release of surfaceLock
	SurfaceData_ThrowInvalidPipeException(env, "invalid sd");
	return (HDC) NULL;
    }

    // Initialize the DC
    Win32OSSD_InitDC(env, wsdo, hdc, type, patrop, clip, comp, color);
    return hdc;
}
/*
 * Class:     sun_java2d_windows_WinBackBufferSurfaceData
 * Method:    initSurface
 * Signature: (IIILsun/awt/windows/WinBackBufferSurfaceData;)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_WinBackBufferSurfaceData_initSurface(JNIEnv *env,
    jobject sData, jint depth, jint width, jint height, jint screen,
    jobject parentData)
{
    Win32SDOps *wsdo = (Win32SDOps *)SurfaceData_GetOps(env, sData);

    J2dTraceLn(J2D_TRACE_INFO, "Win32BBSD_initSurface");
    /* Set the correct dispose method */
    wsdo->sdOps.Dispose = Win32BBSD_Dispose;
    jboolean status =
        initOSSD_WSDO(env, wsdo, width, height, screen, JNI_FALSE);
    if (status == JNI_FALSE || parentData == NULL) {
        SurfaceData_ThrowInvalidPipeException(env,
            "Error initalizing back-buffer surface");
        return;
    }
    Win32SDOps *wsdo_parent = (Win32SDOps*)SurfaceData_GetOps(env, parentData);
    if (!DDGetAttachedSurface(env, wsdo_parent, wsdo)) {
        SurfaceData_ThrowInvalidPipeException(env,
            "Can't create attached surface");
    }
    J2dTraceLn1(J2D_TRACE_VERBOSE,
                "Win32BackBufferSurfaceData_initSurface: "\
                "completed wsdo->lpSurface=0x%x", wsdo->lpSurface);
}
Beispiel #3
0
/*
 * Class:     sun_java2d_windows_GDIRenderer
 * Method:    devCopyArea
 * Signature: (Lsun/java2d/windows/GDIWindowSurfaceData;IIIIII)V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_windows_GDIRenderer_devCopyArea
    (JNIEnv *env, jobject wr,
     jobject wsd,
     jint srcx, jint srcy,
     jint dx, jint dy,
     jint width, jint height)
{
    GDIWinSDOps *wsdo = GDIWindowSurfaceData_GetOps(env, wsd);
    J2dTraceLn(J2D_TRACE_INFO, "GDIWindowSurfaceData_devCopyArea");
    J2dTraceLn4(J2D_TRACE_VERBOSE, "   srcx=%-4d srcy=%-4d dx=%-4d dy=%-4d",
                srcx, srcy, dx, dy);
    J2dTraceLn2(J2D_TRACE_VERBOSE, "     w=%-4d h=%-4d", width, height);
    if (wsdo == NULL) {
        return;
    }
    if (wsdo->invalid) {
        SurfaceData_ThrowInvalidPipeException(env,
            "GDIRenderer_devCopyArea: invalid surface data");
        return;
    }

    HDC hDC = wsdo->GetDC(env, wsdo, 0, NULL, NULL, NULL, 0);
    if (hDC == NULL) {
        return;
    }

    RECT r;
    ::SetRect(&r, srcx, srcy, srcx + width, srcy + height);
    HRGN rgnUpdate = ::CreateRectRgn(0, 0, 0, 0);
    VERIFY(::ScrollDC(hDC, dx, dy, &r, NULL, rgnUpdate, NULL));

    // ScrollDC invalidates the part of the source rectangle that
    // is outside of the destination rectangle on the assumption
    // that you wanted to "move" the pixels from source to dest,
    // and so now you will want to paint new pixels in the source.
    // Since our copyarea operation involves no such semantics we
    // are only interested in the part of the update region that
    // corresponds to unavailable source pixels - i.e. the part
    // that falls within the destination rectangle.

    // The update region will be in client relative coordinates
    // but the destination rect will be in window relative coordinates
    ::OffsetRect(&r, dx-wsdo->insets.left, dy-wsdo->insets.top);
    HRGN rgnDst = ::CreateRectRgnIndirect(&r);
    int result = ::CombineRgn(rgnUpdate, rgnUpdate, rgnDst, RGN_AND);

    // Invalidate the exposed area.
    if (result != NULLREGION) {
        ::InvalidateRgn(wsdo->window, rgnUpdate, TRUE);
    }
    ::DeleteObject(rgnUpdate);
    ::DeleteObject(rgnDst);

    wsdo->ReleaseDC(env, wsdo, hDC);
}
Beispiel #4
0
JNIEXPORT Win32SDOps * JNICALL
Win32OffScreenSurfaceData_GetOps(JNIEnv *env, jobject sData)
{
    SurfaceDataOps *ops = SurfaceData_GetOps(env, sData);
    if (ops == NULL) {
	JNU_ThrowNullPointerException(env, "SurfaceData native ops");
    } else if (ops->Lock != Win32OSSD_Lock) {
	SurfaceData_ThrowInvalidPipeException(env, "not a Win32 SurfaceData");
	ops = NULL;
    }
    return (Win32SDOps *) ops;
}
Beispiel #5
0
JNIEXPORT void JNICALL 
Java_sun_awt_windows_Win32OffScreenSurfaceData_initSurface(JNIEnv *env, 
							   jobject sData, 
							   jint depth, 
							   jint width,
							   jint height,
							   jint screen,
							   jboolean isVolatile,
                                                           jint transparency)
{
    Win32SDOps *wsdo = (Win32SDOps *)SurfaceData_GetOps(env, sData);

    DTRACE_PRINTLN("Win32OSSD_initSurface");
    initOSSD_WSDO(env, wsdo, width, height, screen, transparency);
    if (!DDCreateSurface(wsdo, isVolatile /* d3d caps desired, if possible */)) {
	DTRACE_PRINTLN1("Win32OSD.initSurface: Can't create offsc surf tr=%d\n",
			transparency);
	SurfaceData_ThrowInvalidPipeException(env, 
					      "Can't create offscreen surf");
    } else {
	wsdo->surfacePuntData.lpSurfaceVram = wsdo->lpSurface;
	if (!D3DEnabled(wsdo)) {
	    // d3d enabled by default for each surface - disable if necessary
	    env->SetBooleanField(sData, localD3dEnabledID, JNI_FALSE);
	} else {
	    env->SetBooleanField(sData, d3dClippingEnabledID, 
	    			 (DDINSTANCE_USABLE(wsdo->ddInstance) && 
	    			  wsdo->ddInstance->canClipD3dLines));
	}
    }
    // 8 is somewhat arbitrary; we want the threshhold to represent a
    // significant portion of the surface area in order to avoid
    // punting for occasional, small reads
    wsdo->surfacePuntData.pixelsReadThreshold = width * height / 8;
    /**
     * Only enable our punt-to-sysmem-surface scheme for surfaces that are:
     *   - non-transparent (we really only intended this workaround for
     *     back buffers, which are usually opaque)
     *   - volatile (non-volatile images should not even get into the punt
     *     situation since they should not be a rendering destination, but
     *     we check this just to make sure)
     * And only do so if the user did not specify that punting be disabled
     */
    wsdo->surfacePuntData.disablePunts = (transparency != TR_OPAQUE) ||
                                         !isVolatile                 ||
					 ddVramForced;
}
Beispiel #6
0
static jint Win32OSSD_Lock(JNIEnv *env,
			   SurfaceDataOps *ops,
			   SurfaceDataRasInfo *pRasInfo,
			   jint lockflags)
{
    Win32SDOps *wsdo = (Win32SDOps *) ops;
    DTRACE_PRINTLN1("W32OSSD::Win32OSSD_Lock, lockflags = 0x%x", lockflags);
    wsdo->surfaceLock->Enter();
    if (wsdo->invalid) {
	wsdo->surfaceLock->Leave();
	SurfaceData_ThrowInvalidPipeException(env, "invalid sd");
	return SD_FAILURE;
    }

    if (wsdo->lockType != WIN32SD_LOCK_UNLOCKED) {
	wsdo->surfaceLock->Leave();
	JNU_ThrowInternalError(env, "Win32OSSD_Lock cannot nest locks");
	return SD_FAILURE;
    }

    if (lockflags & SD_LOCK_RD_WR) {
	if (pRasInfo->bounds.x1 < 0) pRasInfo->bounds.x1 = 0;
	if (pRasInfo->bounds.y1 < 0) pRasInfo->bounds.y1 = 0;
	if (pRasInfo->bounds.x2 > wsdo->w) pRasInfo->bounds.x2 = wsdo->w;
	if (pRasInfo->bounds.y2 > wsdo->h) pRasInfo->bounds.y2 = wsdo->h;
	if (DDUseDDraw(wsdo)) {
	    Win32OSSD_LockByDD(env, wsdo, lockflags, pRasInfo);
	}
	if (wsdo->lockType == WIN32SD_LOCK_UNLOCKED) {
	    wsdo->lockFlags = lockflags;
	    wsdo->surfaceLock->Leave();
	    return SD_FAILURE;
	}
    } else {
	// They didn't ask for a lock, so they don't get one
	wsdo->lockType = WIN32SD_LOCK_BY_NULL;
    }
    wsdo->lockFlags = lockflags;
    DTRACE_PRINTLN2("Win32OSSD_Lock: flags, type = 0x%x, %d\n", 
	wsdo->lockFlags, wsdo->lockType);
    return 0;
}
Beispiel #7
0
/*
 * Class:     sun_java2d_d3d_D3DBackBufferSurfaceData
 * Method:    restoreDepthBuffer
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_java2d_d3d_D3DBackBufferSurfaceData_restoreDepthBuffer(JNIEnv *env,
                                                                jobject sData)
{
    Win32SDOps *wsdo = Win32SurfaceData_GetOpsNoSetup(env, sData);
    J2dTraceLn1(J2D_TRACE_INFO,
                "D3DBBSD_restoreDepthBuffer: wsdo=0x%x", wsdo);

    if (wsdo != NULL) {
        if (!DDRestoreSurface(wsdo)) {
            // Failure - throw exception
            J2dRlsTraceLn(J2D_TRACE_ERROR,
                          "D3DBBSD_restoreDepthBuffer: failed to "\
                          "restore depth buffer");

            SurfaceData_ThrowInvalidPipeException(env,
                                                  "RestoreDepthBuffer failure");
        }
    }
}
Beispiel #8
0
/*
 * Class:     sun_awt_windows_Win32OffScreenSurfaceData
 * Method:    restoreSurface
 * Signature: ()V
 */
JNIEXPORT void JNICALL
Java_sun_awt_windows_Win32OffScreenSurfaceData_restoreSurface(JNIEnv *env, 
							      jobject sData)
{
    DTRACE_PRINTLN("native method Win32OSSD_RestoreSurface: restoring offscreen");
    Win32SDOps *wsdo = (Win32SDOps *)SurfaceData_GetOps(env, sData);

    // Might have gotten here by some default action.  Make sure that the
    // surface is marked as lost before bothering to try to restore it.
    if (!wsdo->surfaceLost) {
	return;
    }

    // Attempt to restore and lock the surface (to make sure the restore worked)
    if (DDRestoreSurface(wsdo) && DDLock(env, wsdo, NULL, NULL)) {
	DDUnlock(env, wsdo);
	wsdo->surfaceLost = FALSE;
    } else {
	// Failure - throw exception
	DTRACE_PRINTLN("Win32OSSD_restoreSurface: problems restoring");
	SurfaceData_ThrowInvalidPipeException(env, "RestoreSurface failure");
    }
}
Beispiel #9
0
static SurfaceDataOps *
GetSDOps(JNIEnv *env, jobject sData, jboolean callSetup)
{
    SurfaceDataOps *ops;
    if (JNU_IsNull(env, sData)) {
        JNU_ThrowNullPointerException(env, "surfaceData");
        return NULL;
    }
    ops = (SurfaceDataOps *)JNU_GetLongFieldAsPtr(env, sData, pDataID);
    if (ops == NULL) {
        if (!(*env)->ExceptionOccurred(env) &&
            !(*env)->IsInstanceOf(env, sData, pNullSurfaceDataClass))
        {
            if (!(*env)->GetBooleanField(env, sData, validID)) {
                SurfaceData_ThrowInvalidPipeException(env, "invalid data");
            } else {
                JNU_ThrowNullPointerException(env, "native ops missing");
            }
        }
    } else if (callSetup) {
        SurfaceData_InvokeSetup(env, ops);
    }
    return ops;
}
Beispiel #10
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;
}