--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/windows/native/sun/java2d/d3d/D3DSurfaceData.cpp Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2005-2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "D3DSurfaceData.h"
+#include "D3DContext.h"
+#include "jlong.h"
+#include "jni_util.h"
+#include "Trace.h"
+#include "ddrawUtils.h"
+#include "Devices.h"
+
+#include "Win32SurfaceData.h"
+#include "sun_java2d_d3d_D3DBackBufferSurfaceData.h"
+
+extern LockFunc Win32OSSD_Lock;
+extern GetRasInfoFunc Win32OSSD_GetRasInfo;
+extern UnlockFunc Win32OSSD_Unlock;
+extern DisposeFunc Win32OSSD_Dispose;
+extern GetDCFunc Win32OSSD_GetDC;
+extern ReleaseDCFunc Win32OSSD_ReleaseDC;
+extern InvalidateSDFunc Win32OSSD_InvalidateSD;
+extern RestoreSurfaceFunc Win32OSSD_RestoreSurface;
+extern DisposeFunc Win32BBSD_Dispose;
+
+extern "C" {
+
+RestoreSurfaceFunc D3DSD_RestoreSurface;
+
+/*
+ * D3D-surface specific restore function.
+ * We need to make sure the D3DContext is notified if the
+ * surface is lost (only if this surface is the current target,
+ * otherwise it's possible that it'll get restored (along with its
+ * depth buffer), and the context will still think that the clipping
+ * that's set for this surface is valid.
+ * Consider this scenario:
+ * do {
+ * vi.validate(gc); // validated, vi's surface is restored, clipping is lost
+ * // render stuff using d3d, clipping is reset
+ * // -> surface loss event happens
+ * // do a DD blit of the VI to the screen
+ * // at this point the VI surface will be marked lost
+ * // and will be restored in validate() next time around,
+ * // losing the clipping w/o notifying the D3D context
+ * } while (vi.surfaceLost());
+ */
+void D3DSD_RestoreSurface(JNIEnv *env, Win32SDOps *wsdo) {
+ J2dTraceLn(J2D_TRACE_INFO, "D3DSD_RestoreSurface");
+ D3DSDOps *d3dsdo = (D3DSDOps *)wsdo;
+ // This is needed only for non-textures, since textures can't
+ // lose their surfaces, as they're managed.
+ if (!(d3dsdo->d3dType & D3D_TEXTURE_SURFACE) && wsdo->lpSurface != NULL)
+ {
+ if (wsdo->ddInstance != NULL && wsdo->ddInstance->ddObject != NULL) {
+ D3DContext *d3dContext =
+ wsdo->ddInstance->ddObject->GetD3dContext();
+ if (d3dContext != NULL) {
+ d3dContext->InvalidateIfTarget(env, wsdo->lpSurface);
+ }
+ }
+ }
+ Win32OSSD_RestoreSurface(env, wsdo);
+}
+
+/*
+ * Class: sun_java2d_d3d_D3DSurfaceData
+ * Method: initOps
+ * Signature: (Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_d3d_D3DSurfaceData_initOps(JNIEnv *env,
+ jobject wsd,
+ jint depth,
+ jint transparency)
+{
+ J2dTraceLn(J2D_TRACE_INFO, "D3DSurfaceData_initOps");
+ Win32SDOps *wsdo = (Win32SDOps *)SurfaceData_InitOps(env, wsd,
+ sizeof(D3DSDOps));
+ wsdo->sdOps.Lock = Win32OSSD_Lock;
+ wsdo->sdOps.GetRasInfo = Win32OSSD_GetRasInfo;
+ wsdo->sdOps.Unlock = Win32OSSD_Unlock;
+ wsdo->sdOps.Dispose = Win32OSSD_Dispose;
+ wsdo->RestoreSurface = D3DSD_RestoreSurface;
+ wsdo->GetDC = Win32OSSD_GetDC;
+ wsdo->ReleaseDC = Win32OSSD_ReleaseDC;
+ wsdo->InvalidateSD = Win32OSSD_InvalidateSD;
+ wsdo->invalid = JNI_FALSE;
+ wsdo->lockType = WIN32SD_LOCK_UNLOCKED;
+ wsdo->window = NULL;
+ wsdo->backBufferCount = 0;
+ wsdo->depth = depth;
+ switch (depth) {
+ case 8:
+ wsdo->pixelStride = 1;
+ break;
+ case 15: //555
+ wsdo->pixelStride = 2;
+ wsdo->pixelMasks[0] = 0x1f << 10;
+ wsdo->pixelMasks[1] = 0x1f << 5;
+ wsdo->pixelMasks[2] = 0x1f;
+ break;
+ case 16: //565
+ wsdo->pixelStride = 2;
+ wsdo->pixelMasks[0] = 0x1f << 11;
+ wsdo->pixelMasks[1] = 0x3f << 5;
+ wsdo->pixelMasks[2] = 0x1f;
+ break;
+ case 24:
+ wsdo->pixelStride = 3;
+ break;
+ case 32: //x888
+ wsdo->pixelStride = 4;
+ wsdo->pixelMasks[0] = 0xff0000;
+ wsdo->pixelMasks[1] = 0x00ff00;
+ wsdo->pixelMasks[2] = 0x0000ff;
+ break;
+ }
+ wsdo->surfaceLock = new CriticalSection();
+ wsdo->surfaceLost = FALSE;
+ wsdo->transparency = transparency;
+ wsdo->surfacePuntData.usingDDSystem = FALSE;
+ wsdo->surfacePuntData.lpSurfaceSystem = NULL;
+ wsdo->surfacePuntData.lpSurfaceVram = NULL;
+ wsdo->surfacePuntData.numBltsSinceRead = 0;
+ wsdo->surfacePuntData.pixelsReadSinceBlt = 0;
+ wsdo->surfacePuntData.numBltsThreshold = 2;
+ wsdo->gdiOpPending = FALSE;
+}
+
+jboolean init_D3DSDO(JNIEnv* env, Win32SDOps* wsdo, jint width, jint height,
+ jint d3dSurfaceType, jint screen)
+{
+ // default in case of an error
+ wsdo->lpSurface = NULL;
+ wsdo->ddInstance = NULL;
+
+ {
+ Devices::InstanceAccess devices;
+ wsdo->device = devices->GetDeviceReference(screen, FALSE);
+ }
+ if (wsdo->device == NULL) {
+ J2dTraceLn1(J2D_TRACE_WARNING,
+ "init_D3DSDO: Incorrect "\
+ "screen number (screen=%d)", screen);
+ wsdo->invalid = TRUE;
+ return JNI_FALSE;
+ }
+ wsdo->w = width;
+ wsdo->h = height;
+ wsdo->surfacePuntData.disablePunts = TRUE;
+ return JNI_TRUE;
+}
+
+/*
+ * 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;
+}
+
+/*
+ * 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");
+ }
+ }
+}
+
+}