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); }
/* * 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); }
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; }
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; }
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; }
/* * 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"); } } }
/* * 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"); } }
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; }
/* * 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; }