| /* |
| * Copyright 2000-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. |
| */ |
| |
| #define INITGUID |
| #include "Trace.h" |
| #include "ddrawUtils.h" |
| #include "ddrawObject.h" |
| #include "awt_Multimon.h" |
| #include "awt_MMStub.h" |
| #include "dxInit.h" |
| #include "WindowsFlags.h" |
| #include "D3DContext.h" |
| |
| // |
| // Globals |
| // |
| DDrawObjectStruct **ddInstance; |
| int maxDDDevices = 0; |
| int currNumDevices = 0; |
| CriticalSection ddInstanceLock; |
| extern BOOL isAppActive; |
| extern HINSTANCE hLibDDraw; // DDraw Library handle |
| extern jfieldID ddSurfacePuntedID; |
| |
| extern "C" void Win32OSSD_DisableDD(JNIEnv *env, Win32SDOps *wsdo); |
| |
| // |
| // Constants |
| // |
| #define MAX_BUSY_ATTEMPTS 50 // Arbitrary number of times to attempt |
| // an operation that returns a busy error |
| |
| // |
| // Macros |
| // |
| |
| /** |
| * This macro is just a shortcut for the various places in the |
| * code where we want to call a ddraw function and print any error |
| * if the result is not equal to DD_OK. The errorString passed |
| * in is for debugging/tracing purposes only. |
| */ |
| #define DD_FUNC(func, errorString) { \ |
| HRESULT ddResult = func; \ |
| if (ddResult != DD_OK) { \ |
| DebugPrintDirectDrawError(ddResult, errorString); \ |
| } \ |
| } |
| /** |
| * Same as above, only return FALSE when done (to be used only in |
| * functions that should return FALSE on a ddraw failure). |
| */ |
| #define DD_FUNC_RETURN(func, errorString) { \ |
| HRESULT ddResult = func; \ |
| if (ddResult != DD_OK) { \ |
| DebugPrintDirectDrawError(ddResult, errorString); \ |
| return FALSE; \ |
| } \ |
| } |
| |
| // |
| // INLINE functions |
| // |
| |
| // Attaches the clipper object of a given surface to |
| // the primary. Note that this action only happens if the |
| // surface is onscreen (clipping only makes sense for onscreen windows) |
| INLINE void AttachClipper(Win32SDOps *wsdo) { |
| if (wsdo->window && wsdo->ddInstance->hwndFullScreen == NULL) { |
| J2dTraceLn(J2D_TRACE_VERBOSE, "AttachClipper"); |
| HRESULT ddResult; |
| ddResult = wsdo->ddInstance->clipper->SetHWnd(0, wsdo->window); |
| if (ddResult != DD_OK) { |
| DebugPrintDirectDrawError(ddResult, "AttachClipper"); |
| } |
| } |
| } |
| |
| // |
| // Functions |
| // |
| |
| /** |
| * Returns the ddInstance associated with a particular HMONITOR |
| */ |
| DDrawObjectStruct *GetDDInstanceForDevice(HMONITOR hMon) |
| { |
| J2dTraceLn(J2D_TRACE_VERBOSE, "GetDDInstanceForDevice"); |
| DDrawObjectStruct *tmpDdInstance = NULL; |
| ddInstanceLock.Enter(); |
| if (currNumDevices == 1) { |
| // Non multimon situation |
| if (ddInstance[0]) |
| { |
| tmpDdInstance = ddInstance[0]; |
| } |
| } else { |
| for (int i = 0; i < currNumDevices; ++i) { |
| if (ddInstance[i] |
| && hMon == ddInstance[i]->hMonitor) |
| { |
| tmpDdInstance = ddInstance[i]; |
| break; |
| } |
| } |
| } |
| if (tmpDdInstance != NULL && !tmpDdInstance->accelerated) { |
| // Some failure situations (see DDSetupDevice in dxInit.cpp) can cause |
| // a ddInstance object to become invalid. If this happens, we should |
| // not be using this ddInstance object at all, so return NULL. |
| tmpDdInstance = NULL; |
| } |
| ddInstanceLock.Leave(); |
| return tmpDdInstance; |
| } |
| |
| /** |
| * Can return FALSE if there was some problem during ddraw |
| * initialization for this screen, or if this screen does not |
| * support some of the capabilities necessary for running ddraw |
| * correctly. |
| */ |
| BOOL DDCanCreatePrimary(HMONITOR hMon) { |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| return (useDD && ddInstance && tmpDdInstance); |
| } |
| |
| /** |
| * Can return FALSE if the device that the surfaceData object |
| * resides on cannot support accelerated Blt's. Some devices |
| * can perform basic ddraw Lock/Unlock commands but cannot |
| * handle the ddraw Blt command. |
| */ |
| BOOL DDCanBlt(Win32SDOps *wsdo) { |
| return (useDD && wsdo->ddInstance && wsdo->ddInstance->canBlt); |
| } |
| |
| /** |
| * Can return FALSE if either ddraw is not enabled at all (problems |
| * during initialization) or the device associated with the hMon object |
| * cannot support the basic required capabilities (in |
| * which case the ddInstance for that device will be set to NULL). |
| */ |
| BOOL DeviceUseDDraw(HMONITOR hMon) { |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| return (useDD && tmpDdInstance && tmpDdInstance->ddObject); |
| } |
| |
| /** |
| * Can return FALSE if either ddraw is not enabled at all (problems |
| * during initialization) or the device associated with the hMon object |
| * cannot support the basic required capabilities (in |
| * which case the ddInstance for that device will be set to NULL). |
| */ |
| BOOL DeviceUseD3D(HMONITOR hMon) { |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| return (useDD && tmpDdInstance && tmpDdInstance->ddObject && |
| tmpDdInstance->ddObject->IsD3DEnabled()); |
| } |
| |
| /** |
| * Can return FALSE if either ddraw is not enabled at all (problems |
| * during initialization) or the device that the surfaceData object |
| * resides on cannot support the basic required capabilities (in |
| * which case the ddInstance for that device will be set to NULL). |
| */ |
| BOOL DDUseDDraw(Win32SDOps *wsdo) { |
| return (useDD && wsdo->ddInstance && wsdo->ddInstance->valid); |
| } |
| |
| |
| /** |
| * Release the resources consumed by ddraw. This will be called |
| * by the DllMain function when it receives a PROCESS_DETACH method, |
| * meaning that the application is done with awt. We need to release |
| * these ddraw resources because of potential memory leaks, but |
| * more importantly, because if we don't release a primary surface |
| * that has been locked and not unlocked, then we may cause |
| * ddraw to be corrupted on this system until reboot. |
| * IMPORTANT: because we do not use any locks around this release, |
| * we assume that this function is called only during the |
| * PROCESS_DETACH procedure described above. Any other situation |
| * could cause unpredictable results. |
| */ |
| void DDRelease() |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "DDRelease"); |
| |
| // Note that we do not lock the ddInstanceLock CriticalSection. |
| // Normally we should do that in this kind of situation (to ensure |
| // that the ddInstance used in all release calls is the same on). |
| // But in this case we do not want the release of a locked surface |
| // to be hampered by some bad CriticalSection deadlock, so we |
| // will just release ddInstance anyway. |
| // Anyway, if users of this function call it properly (as |
| // documented above), then there should be no problem. |
| try { |
| if (hLibDDraw) { |
| ::FreeLibrary(hLibDDraw); |
| hLibDDraw = NULL; |
| } |
| hLibDDraw = NULL; |
| if (ddInstance) { |
| for (int i = 0; i < currNumDevices; ++i) { |
| ReleaseDDInstance(ddInstance[i]); |
| } |
| free(ddInstance); |
| } |
| } catch (...) { |
| // Handle all exceptions by simply returning. |
| // There are some cases where the OS may have already |
| // released our objects for us (e.g., NT4) and we have |
| // no way of knowing, but the above call into Release will |
| // cause an exception to be thrown by dereferencing |
| // already-released ddraw objects |
| } |
| } |
| |
| |
| /** |
| * Create the primary surface. Note that we do not take the ddInstanceLock |
| * here; we assume that our callers are taking that lock for us. |
| */ |
| BOOL DDCreatePrimary(Win32SDOps *wsdo) { |
| J2dTraceLn(J2D_TRACE_INFO, "DDCreatePrimary"); |
| BOOL ret = TRUE; |
| |
| if (wsdo != NULL && wsdo->device != NULL) { |
| HMONITOR hMon; |
| hMon = (HMONITOR)wsdo->device->GetMonitor(); |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| // Check if we need to recreate the primary for this device. |
| // If we are in full-screen mode, we do not need to change |
| // the primary unless the number of back buffers has changed. |
| if (tmpDdInstance == NULL) { |
| return FALSE; |
| } |
| if (tmpDdInstance->hwndFullScreen == NULL || |
| tmpDdInstance->context != CONTEXT_NORMAL) |
| { |
| ret = DDSetupDevice(tmpDdInstance, |
| AwtWin32GraphicsDevice::GetDxCapsForDevice(hMon)); |
| tmpDdInstance->context = CONTEXT_NORMAL; |
| } |
| if (ret) { |
| tmpDdInstance->valid = TRUE; |
| } |
| return ret; |
| } |
| return ret; |
| } |
| |
| /** |
| * Returns a DDrawSurface which should be used for performing DDraw sync. |
| * |
| * On systems other than Windows Vista, a primary surface is returned. |
| * |
| * On Windows Vista, a 1x1 scratch offscreen surface will be created and |
| * maintained, because locking the primary surface will cause DWM to be |
| * disabled for the run of the application. |
| * |
| * Note: this method must be called while ddInstance lock is held. |
| * Note: a "DDINSTANCE_USABLE" non-null argument is assumed. |
| */ |
| // 4978973: Only lock one pixel to flush; avoids GDI flicker artifacts |
| // and only fill one pixel in the sync surface |
| static RECT tinyRect = { 0, 0, 1, 1 }; |
| static DDrawSurface* DDGetSyncSurface(DDrawObjectStruct *tmpDdInstance) |
| { |
| static BOOL bIsVista = IS_WINVISTA; |
| static DDBLTFX ddBltFx; |
| DDrawSurface *lpSyncSurface; |
| |
| if (bIsVista) { |
| lpSyncSurface = tmpDdInstance->syncSurface; |
| |
| if (lpSyncSurface != NULL) { |
| // return the existing surface if it wasn't lost or it was |
| // restored succesfully |
| if (SUCCEEDED(lpSyncSurface->IsLost()) || |
| SUCCEEDED(lpSyncSurface->Restore())) |
| { |
| // we need to render to the sync surface so that DDraw |
| // will flush the pipeline when we lock it in DDSync |
| lpSyncSurface->Blt(&tinyRect, NULL, NULL, |
| DDBLT_COLORFILL | DDBLT_WAIT, |
| &ddBltFx); |
| return lpSyncSurface; |
| } |
| J2dTraceLn(J2D_TRACE_WARNING, "DDGetSyncSurface: failed to restore" |
| " sync surface, recreating"); |
| delete lpSyncSurface; |
| } |
| |
| // this doesn't need to be done every time in the fast path |
| ddBltFx.dwSize = sizeof(ddBltFx); |
| ddBltFx.dwFillColor = 0xffffffff; |
| |
| lpSyncSurface = |
| tmpDdInstance->ddObject-> |
| CreateDDOffScreenSurface(1, 1, 24/*ignored*/, |
| TR_OPAQUE, |
| DDSCAPS_VIDEOMEMORY); |
| tmpDdInstance->syncSurface = lpSyncSurface; |
| } else { |
| lpSyncSurface = tmpDdInstance->primary; |
| } |
| |
| return lpSyncSurface; |
| } |
| |
| void |
| DDFreeSyncSurface(DDrawObjectStruct *tmpDdInstance) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "DDFreeSyncSurface"); |
| if (tmpDdInstance != NULL && tmpDdInstance->syncSurface != NULL) { |
| delete tmpDdInstance->syncSurface; |
| tmpDdInstance->syncSurface = NULL; |
| } |
| } |
| |
| /** |
| * Synchronize graphics pipeline by calling Lock/Unlock on primary |
| * surface |
| */ |
| void DDSync() |
| { |
| int attempts = 0; |
| HRESULT ddResult; |
| DDrawSurface *lpSyncSurface = NULL; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "DDSync"); |
| // REMIND: need to handle errors here |
| ddInstanceLock.Enter(); |
| for (int i = 0; i < currNumDevices; ++i) { |
| DDrawObjectStruct *tmpDdInstance = ddInstance[i]; |
| |
| if (!DDINSTANCE_USABLE(tmpDdInstance)) { |
| continue; |
| } |
| lpSyncSurface = DDGetSyncSurface(tmpDdInstance); |
| if (lpSyncSurface == NULL) { |
| J2dRlsTraceLn1(J2D_TRACE_ERROR, |
| "DDSync: no sync surface for device %d", i); |
| continue; |
| } |
| // Spin while busy up to some finite number of times |
| do { |
| ddResult = lpSyncSurface->Lock(&tinyRect, NULL, |
| DDLOCK_WAIT, NULL); |
| } while ((ddResult == DDERR_SURFACEBUSY) && |
| (++attempts < MAX_BUSY_ATTEMPTS)); |
| if (ddResult == DD_OK) { |
| ddResult = lpSyncSurface->Unlock(&tinyRect); |
| } |
| } |
| ddInstanceLock.Leave(); |
| J2dTraceLn(J2D_TRACE_VERBOSE, "DDSync done"); |
| } |
| |
| |
| /** |
| * Simple clip check against the window of the given surface data. |
| * If the clip list is complex or if the clip list intersects |
| * the visible region of the window then return FALSE, meaning |
| * that the clipping is sufficiently complex that the caller |
| * may want to find an alternative means (other than ddraw) of |
| * performing an operation. |
| */ |
| BOOL DDClipCheck(Win32SDOps *wsdo, RECT *operationRect) |
| { |
| static struct { |
| RGNDATAHEADER rdh; |
| RECT rects[1]; |
| } rgnData; |
| unsigned long rgnSize = sizeof(rgnData); |
| HRESULT ddResult; |
| |
| J2dTraceLn(J2D_TRACE_VERBOSE, "DDClipCheck"); |
| |
| if (!wsdo->window) { |
| // Offscreen surfaces need no clipping |
| return TRUE; |
| } |
| |
| // If ddResult not OK, could be because of a complex clipping region |
| // (Our rgnData structure only has space for a simple rectangle region). |
| // Thus, we return FALSE and attach the clipper object. |
| DDrawObjectStruct *tmpDdInstance = wsdo->ddInstance; |
| if (!DDINSTANCE_USABLE(tmpDdInstance)) { |
| return FALSE; |
| } |
| if (wsdo->window == tmpDdInstance->hwndFullScreen) { |
| // Fullscreen surfaces need no clipping |
| return TRUE; |
| } |
| DD_FUNC(tmpDdInstance->clipper->SetHWnd(0, wsdo->window), |
| "DDClipCheck: SetHWnd"); |
| ddResult = tmpDdInstance->clipper->GetClipList(NULL, (RGNDATA*)&rgnData, |
| &rgnSize); |
| if (ddResult == DDERR_REGIONTOOSMALL) { |
| // Complex clipping region |
| // REMIND: could be more clever here and actually check operationRect |
| // against all rectangles in clipList, but this works for now. |
| return FALSE; |
| } |
| // Check intersection of clip region with operationRect. If clip region |
| // smaller, then we have a simple clip case. |
| // If no operationRect, then check against entire window bounds. |
| if (operationRect) { |
| if (operationRect->left < rgnData.rects[0].left || |
| operationRect->top < rgnData.rects[0].top || |
| operationRect->right > rgnData.rects[0].right || |
| operationRect->bottom > rgnData.rects[0].bottom) |
| { |
| return FALSE; |
| } |
| } else { |
| RECT winrect; |
| ::GetWindowRect(wsdo->window, &winrect); |
| if (winrect.left < rgnData.rects[0].left || |
| winrect.top < rgnData.rects[0].top || |
| winrect.right > rgnData.rects[0].right || |
| winrect.bottom > rgnData.rects[0].bottom) |
| { |
| return FALSE; |
| } |
| } |
| return TRUE; |
| } |
| |
| |
| /** |
| * Lock the surface. |
| */ |
| BOOL DDLock(JNIEnv *env, Win32SDOps *wsdo, RECT *lockRect, |
| SurfaceDataRasInfo *pRasInfo) |
| { |
| J2dTraceLn1(J2D_TRACE_INFO, "DDLock: wsdo->lpSurface=0x%x", wsdo->lpSurface); |
| |
| int attempts = 0; |
| |
| if (wsdo->gdiOpPending) { |
| // This sync is really for flushing any pending GDI |
| // operations. On ATI boards GdiFlush() doesn't do the trick, |
| // only locking the primary works. |
| DDSync(); |
| wsdo->gdiOpPending = FALSE; |
| } |
| while (attempts++ < MAX_BUSY_ATTEMPTS) { |
| if (!wsdo->ddInstance->valid) { |
| // If dd object became invalid, don't bother calling Lock |
| // Note: This check should not be necessary because we should |
| // do the right thing in any case - catch the error, try to |
| // restore the surface, fai, etc. But there seem to be problems |
| // with ddraw that sometimes cause it to hang in the Restore and |
| // Lock calls. Better to avoid the situation as much as we can and |
| // bail out early. |
| J2dTraceLn(J2D_TRACE_ERROR, |
| "DDLock: wsdo->ddInstance invalid"); |
| return FALSE; |
| } |
| HRESULT ddResult = wsdo->lpSurface->Lock(lockRect, pRasInfo, |
| DDLOCK_WAIT, NULL); |
| // Spin on the busy-type errors, else return having failed or succeeded |
| switch (ddResult) { |
| case DD_OK: |
| return TRUE; |
| case DDERR_WASSTILLDRAWING: |
| case DDERR_SURFACEBUSY: |
| J2dTraceLn(J2D_TRACE_WARNING, "DDLock: surface busy..."); |
| break; |
| case DDERR_SURFACELOST: |
| J2dTraceLn(J2D_TRACE_WARNING, "DDLock: surface lost"); |
| wsdo->RestoreSurface(env, wsdo); |
| return FALSE; |
| case DDERR_GENERIC: |
| J2dRlsTraceLn(J2D_TRACE_ERROR, "DDLock: unexpected error"); |
| if (wsdo->window == NULL) { |
| Win32OSSD_DisableDD(env, wsdo); |
| } |
| return FALSE; |
| default: |
| DebugPrintDirectDrawError(ddResult, "DDLock"); |
| return FALSE; |
| } |
| } |
| // If we get here, then there was an error in the function and we |
| // should return false |
| return FALSE; |
| } |
| |
| |
| /** |
| * Unlock the surface |
| */ |
| void DDUnlock(JNIEnv *env, Win32SDOps *wsdo) |
| { |
| J2dTraceLn1(J2D_TRACE_INFO, "DDUnlock: wsdo->lpSurface=0x%x", wsdo->lpSurface); |
| |
| HRESULT ddResult = wsdo->lpSurface->Unlock(NULL); |
| // Spin on the busy-type errors, else return having failed or succeeded |
| switch (ddResult) { |
| case DD_OK: |
| return; |
| case DDERR_NOTLOCKED: |
| J2dTraceLn(J2D_TRACE_ERROR, "DDUnlock: Surface not locked"); |
| return; |
| case DDERR_SURFACELOST: |
| J2dTraceLn(J2D_TRACE_WARNING, "DDUnlock: Surface lost"); |
| wsdo->RestoreSurface(env, wsdo); |
| return; |
| default: |
| DebugPrintDirectDrawError(ddResult, "DDUnlock"); |
| return; |
| } |
| } |
| |
| /** |
| * Fill given surface with given color in given RECT bounds |
| */ |
| BOOL DDColorFill(JNIEnv *env, jobject sData, Win32SDOps *wsdo, |
| RECT *fillRect, jint color) |
| { |
| DDBLTFX ddBltFx; |
| HRESULT ddResult; |
| int attempts = 0; |
| |
| J2dTraceLn(J2D_TRACE_VERBOSE, "DDColorFill"); |
| J2dTraceLn5(J2D_TRACE_VERBOSE, |
| " color=0x%x l=%-4d t=%-4d r=%-4d b=%-4d", |
| color, fillRect->left, fillRect->top, fillRect->right, |
| fillRect->bottom); |
| ddBltFx.dwSize = sizeof(ddBltFx); |
| ddBltFx.dwFillColor = color; |
| AttachClipper(wsdo); |
| while (attempts++ < MAX_BUSY_ATTEMPTS) { |
| ddResult = wsdo->lpSurface->Blt(fillRect, NULL, NULL, |
| DDBLT_COLORFILL | DDBLT_WAIT, |
| &ddBltFx); |
| // Spin on the busy-type errors, else return having failed or succeeded |
| switch (ddResult) { |
| case DD_OK: |
| return TRUE; |
| case DDERR_INVALIDRECT: |
| J2dTraceLn4(J2D_TRACE_ERROR, |
| "DDColorFill: Invalid rect for colorfill "\ |
| "l=%-4d t=%-4d r=%-4d b=%-4d", |
| fillRect->left, fillRect->top, |
| fillRect->right, fillRect->bottom); |
| return FALSE; |
| case DDERR_SURFACEBUSY: |
| J2dTraceLn(J2D_TRACE_WARNING, "DDColorFill: surface busy"); |
| break; |
| case DDERR_SURFACELOST: |
| J2dTraceLn(J2D_TRACE_WARNING, "DDColorfill: surface lost"); |
| wsdo->RestoreSurface(env, wsdo); |
| return FALSE; |
| default: |
| DebugPrintDirectDrawError(ddResult, "DDColorFill"); |
| } |
| } |
| J2dTraceLn(J2D_TRACE_VERBOSE, "DDColorFill done"); |
| return FALSE; |
| } |
| |
| void ManageOffscreenSurfaceBlt(JNIEnv *env, Win32SDOps *wsdo) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "ManageOffscreenSurfaceBlt"); |
| wsdo->surfacePuntData.pixelsReadSinceBlt = 0; |
| if (wsdo->surfacePuntData.numBltsSinceRead >= |
| wsdo->surfacePuntData.numBltsThreshold) |
| { |
| if (wsdo->surfacePuntData.usingDDSystem) { |
| if (wsdo->surfacePuntData.lpSurfaceVram->Blt(NULL, |
| wsdo->surfacePuntData.lpSurfaceSystem, |
| NULL, DDBLT_WAIT, NULL) == DD_OK) |
| { |
| J2dTraceLn2(J2D_TRACE_VERBOSE, |
| " Unpunting sys to VRAM: 0x%x -> 0x%x", |
| wsdo->surfacePuntData.lpSurfaceVram, |
| wsdo->surfacePuntData.lpSurfaceSystem); |
| wsdo->lpSurface = wsdo->surfacePuntData.lpSurfaceVram; |
| wsdo->surfacePuntData.usingDDSystem = FALSE; |
| // Now: double our threshhold to prevent thrashing; we |
| // don't want to keep punting and un-punting our surface |
| wsdo->surfacePuntData.numBltsThreshold *= 2; |
| // Notify the Java level that this surface has |
| // been unpunted so that future copies to this surface |
| // from accelerated src surfaces will do the right thing. |
| jobject sdObject = env->NewLocalRef(wsdo->sdOps.sdObject); |
| if (sdObject) { |
| // Only bother with this optimization if the |
| // reference is still valid |
| env->SetBooleanField(sdObject, ddSurfacePuntedID, JNI_FALSE); |
| env->DeleteLocalRef(sdObject); |
| } |
| } |
| } |
| } else { |
| wsdo->surfacePuntData.numBltsSinceRead++; |
| } |
| } |
| |
| /** |
| * Copy data from src to dst using src and dst rectangles |
| */ |
| BOOL DDBlt(JNIEnv *env, Win32SDOps *wsdoSrc, Win32SDOps *wsdoDst, |
| RECT *rDst, RECT *rSrc, CompositeInfo *compInfo) |
| { |
| int attempts = 0; |
| DWORD bltFlags = DDBLT_WAIT; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "DDBlt"); |
| J2dTraceLn4(J2D_TRACE_INFO, " src rect: l=%-4d t=%-4d r=%-4d b=%-4d", |
| rSrc->left, rSrc->top, rSrc->right, rSrc->bottom); |
| J2dTraceLn4(J2D_TRACE_INFO, " dst rect: l=%-4d t=%-4d r=%-4d b=%-4d", |
| rDst->left, rDst->top, rDst->right, rDst->bottom); |
| |
| // Note: the primary can only have one clipper attached to it at |
| // any time. This seems weird to set it to src then dst, but this |
| // works because either: both are the same window (devCopyArea), |
| // neither are windows (both offscreen), or only one is a window |
| // (Blt). We can't get here from a windowA -> windowB copy operation. |
| AttachClipper(wsdoSrc); |
| AttachClipper(wsdoDst); |
| |
| // Administrate system-surface punt mechanism for offscreen images |
| if (!wsdoSrc->window && !wsdoSrc->surfacePuntData.disablePunts) { |
| ManageOffscreenSurfaceBlt(env, wsdoSrc); |
| } |
| if (wsdoSrc->transparency == TR_BITMASK) { |
| bltFlags |= DDBLT_KEYSRC; |
| } |
| while (attempts++ < MAX_BUSY_ATTEMPTS) { |
| HRESULT ddResult = |
| wsdoDst->lpSurface->Blt(rDst, wsdoSrc->lpSurface, |
| rSrc, bltFlags, NULL); |
| |
| // Spin on the busy-type errors or return having failed or succeeded |
| switch (ddResult) { |
| case DD_OK: |
| return TRUE; |
| case DDERR_SURFACEBUSY: |
| J2dTraceLn(J2D_TRACE_WARNING, "DDBlt: surface busy"); |
| break; |
| case DDERR_SURFACELOST: |
| /** |
| * Only restore the Dst if it is truly lost; "restoring" an |
| * offscreen surface simply sets a flag and throws an exception, |
| * thus guaranteeing that the Src restore below will not happen. |
| * So if the Src stays Lost and we keep trying to restore an un-Lost |
| * Dst, then we will never actually do the restore on the Src. |
| */ |
| if (wsdoDst->lpSurface->IsLost() != DD_OK) { |
| J2dTraceLn(J2D_TRACE_WARNING, "DDBlt: dst surface lost"); |
| wsdoDst->RestoreSurface(env, wsdoDst); |
| } |
| if (wsdoSrc->lpSurface->IsLost() != DD_OK) { |
| J2dTraceLn(J2D_TRACE_WARNING, "DDBlt: src surface lost"); |
| wsdoSrc->RestoreSurface(env, wsdoSrc); |
| } |
| return FALSE; |
| default: |
| DebugPrintDirectDrawError(ddResult, "DDBlt"); |
| return FALSE; |
| } |
| } |
| return FALSE; |
| } |
| |
| /** |
| * Set the color key information for this surface. During a |
| * blit operation, pixels of the specified color will not be |
| * drawn (resulting in transparent areas of the image). Note |
| * that the "transparency" field in the Win32SDOps structure must |
| * be set to TR_BITMASK for the color key information to have an effect. |
| */ |
| void DDSetColorKey(JNIEnv *env, Win32SDOps *wsdo, jint color) |
| { |
| J2dTraceLn(J2D_TRACE_VERBOSE, "DDSetColorKey"); |
| DDCOLORKEY ddck; |
| HRESULT ddResult; |
| |
| ddck.dwColorSpaceLowValue = color; |
| ddck.dwColorSpaceHighValue = color; |
| |
| ddResult = wsdo->lpSurface->SetColorKey(DDCKEY_SRCBLT, &ddck); |
| |
| if (ddResult != DD_OK) { |
| DebugPrintDirectDrawError(ddResult, "DDSetColorKey"); |
| } |
| } |
| |
| |
| /** |
| * Swaps the surface memory of the front and back buffers. |
| * Flips memory from the source surface to the destination surface. |
| */ |
| BOOL DDFlip(JNIEnv *env, Win32SDOps *src, Win32SDOps *dest) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "DDFlip"); |
| int attempts = 0; |
| while (attempts++ < MAX_BUSY_ATTEMPTS) { |
| HRESULT ddResult = src->lpSurface->Flip(dest->lpSurface); |
| // Spin on the busy-type errors or return having failed or succeeded |
| switch (ddResult) { |
| case DD_OK: |
| return TRUE; |
| case DDERR_SURFACEBUSY: |
| J2dTraceLn(J2D_TRACE_WARNING, "DDFlip: surface busy"); |
| break; |
| case DDERR_SURFACELOST: |
| if (dest->lpSurface->IsLost() != DD_OK) { |
| J2dTraceLn(J2D_TRACE_WARNING, "DDFlip: dst surface lost"); |
| dest->RestoreSurface(env, dest); |
| } |
| if (src->lpSurface->IsLost() != DD_OK) { |
| J2dTraceLn(J2D_TRACE_WARNING, "DDFlip: src surface lost"); |
| src->RestoreSurface(env, src); |
| } |
| return FALSE; |
| default: |
| DebugPrintDirectDrawError(ddResult, "DDFlip"); |
| return FALSE; |
| } |
| } |
| return FALSE; |
| } |
| |
| |
| /** |
| * Mark the given ddInstance structure as invalid. This flag |
| * can then be used to detect rendering with an invalid ddraw |
| * object later (to avoid further ddraw errors) or to detect |
| * when it is time to create a new ddraw object. Recreation |
| * happens when we are asked to create a new surface but the |
| * current ddInstance global structure is invalid. |
| */ |
| void DDInvalidateDDInstance(DDrawObjectStruct *ddInst) { |
| J2dTraceLn(J2D_TRACE_INFO, "DDInvalidateDDInstance"); |
| if (useDD) { |
| if (ddInst != NULL) { |
| // Invalidate given instance of ddInstance |
| ddInst->valid = FALSE; |
| } else { |
| // Invalidate global ddInstance. This occurs at the start |
| // of a display-change event. |
| for (int i = 0; i < currNumDevices; ++i) { |
| if (ddInstance[i] && ddInstance[i]->hwndFullScreen == NULL) { |
| ddInstance[i]->valid = FALSE; |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Utility routine: release all elements of given ddInst structure |
| * and free the memory consumed by ddInst. Note that this may be |
| * called during a failed DDCreateDDObject, so any null fields were |
| * not yet initialized and should not be released. |
| */ |
| void ReleaseDDInstance(DDrawObjectStruct *ddInst) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "ReleaseDDInstance"); |
| if (ddInst) { |
| if (ddInst->primary) { |
| delete ddInst->primary; |
| ddInst->primary = NULL; |
| } |
| if (ddInst->clipper) { |
| delete ddInst->clipper; |
| ddInst->clipper = NULL; |
| } |
| if (ddInst->ddObject) { |
| delete ddInst->ddObject; |
| ddInst->ddObject = NULL; |
| } |
| free(ddInst); |
| } |
| } |
| |
| /** |
| * Enters full-screen exclusive mode, setting the hwnd as the screen |
| */ |
| BOOL DDEnterFullScreen(HMONITOR hMon, HWND hwnd, HWND topLevelHwnd) |
| { |
| HRESULT ddResult = DD_OK; |
| // Sleep so that programatically full-screen cannot be entered |
| // and left multiple times quickly enough to crash the driver |
| static DWORD prevTime = 0; |
| DWORD currTime = ::GetTickCount(); |
| DWORD timeDiff = (currTime - prevTime); |
| if (timeDiff < 500) { |
| ::Sleep(500 - timeDiff); |
| } |
| prevTime = currTime; |
| |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| tmpDdInstance->ddObject->SetCooperativeLevel(topLevelHwnd, |
| DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE); |
| if (ddResult != DD_OK) { |
| DebugPrintDirectDrawError(ddResult, "DDEnterFullScreen"); |
| return FALSE; |
| } |
| if (tmpDdInstance->primary) { |
| // No clipping necessary in fullscreen mode. Elsewhere, |
| // we avoid setting the clip list for the fullscreen window, |
| // so we should also null-out the clipper object for the |
| // primary surface in that case. Bug 4737785. |
| tmpDdInstance->primary->SetClipper(NULL); |
| } |
| tmpDdInstance->hwndFullScreen = hwnd; |
| tmpDdInstance->context = CONTEXT_ENTER_FULL_SCREEN; |
| |
| return TRUE; |
| } |
| |
| |
| /** |
| * Exits full-screen exclusive mode |
| */ |
| BOOL DDExitFullScreen(HMONITOR hMon, HWND hwnd) |
| { |
| // Sleep so that programatically full-screen cannot be entered |
| // and left multiple times quickly enough to crash the driver |
| static DWORD prevTime = 0; |
| DWORD currTime = ::GetTickCount(); |
| DWORD timeDiff = (currTime - prevTime); |
| if (timeDiff < 500) { |
| ::Sleep(500 - timeDiff); |
| } |
| prevTime = currTime; |
| |
| J2dTraceLn(J2D_TRACE_INFO, "DDExitFullScreen"); |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| tmpDdInstance->context = CONTEXT_EXIT_FULL_SCREEN; |
| if (!tmpDdInstance || !tmpDdInstance->ddObject || |
| !tmpDdInstance->ddObject->RestoreDDDisplayMode()) { |
| return FALSE; |
| } |
| J2dTraceLn1(J2D_TRACE_VERBOSE, |
| "DDExitFullScreen: Restoring cooperative level hwnd=0x%x", |
| hwnd); |
| HRESULT ddResult = |
| tmpDdInstance->ddObject->SetCooperativeLevel(NULL, DDSCL_NORMAL); |
| if (ddResult != DD_OK) { |
| DebugPrintDirectDrawError(ddResult, "DDExitFullScreen"); |
| return FALSE; |
| } |
| if (tmpDdInstance->clipper == NULL) { |
| // May not have created clipper if we were in FS mode during |
| // primary creation |
| tmpDdInstance->clipper = tmpDdInstance->ddObject->CreateDDClipper(); |
| } |
| if (tmpDdInstance->clipper != NULL) { |
| tmpDdInstance->primary->SetClipper(tmpDdInstance->clipper); |
| } |
| J2dTraceLn(J2D_TRACE_VERBOSE, |
| "DDExitFullScreen: Restored cooperative level"); |
| tmpDdInstance->hwndFullScreen = NULL; |
| tmpDdInstance->context = CONTEXT_NORMAL; |
| return TRUE; |
| } |
| |
| /** |
| * Gets the current display mode; sets the values in displayMode |
| */ |
| BOOL DDGetDisplayMode(HMONITOR hMon, DDrawDisplayMode& displayMode) |
| { |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| if (tmpDdInstance && tmpDdInstance->ddObject) { |
| return tmpDdInstance->ddObject->GetDDDisplayMode(displayMode); |
| } else { |
| return FALSE; |
| } |
| } |
| |
| /** |
| * Sets the display mode to the supplied mode |
| */ |
| BOOL DDSetDisplayMode(HMONITOR hMon, DDrawDisplayMode& displayMode) |
| { |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| if (tmpDdInstance) { |
| tmpDdInstance->context = CONTEXT_DISPLAY_CHANGE; |
| } |
| if (tmpDdInstance && tmpDdInstance->ddObject) { |
| int attempts = 0; |
| while (attempts++ < MAX_BUSY_ATTEMPTS) { |
| HRESULT ddResult = tmpDdInstance->ddObject->SetDDDisplayMode( |
| displayMode); |
| // Spin on the busy-type errors or return having failed or succeeded |
| switch (ddResult) { |
| case DD_OK: |
| return TRUE; |
| case DDERR_SURFACEBUSY: |
| J2dTraceLn(J2D_TRACE_WARNING, |
| "DDSetDisplayMode: surface busy"); |
| break; |
| default: |
| DebugPrintDirectDrawError(ddResult, "DDSetDisplayMode"); |
| return FALSE; |
| } |
| } |
| return FALSE; |
| } else { |
| return FALSE; |
| } |
| } |
| |
| /** |
| * Enumerates all display modes, calling the supplied callback for each |
| * display mode returned by the system |
| */ |
| BOOL DDEnumDisplayModes(HMONITOR hMon, DDrawDisplayMode* constraint, |
| DDrawDisplayMode::Callback callback, void* context) |
| { |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| if (tmpDdInstance && tmpDdInstance->ddObject) { |
| return tmpDdInstance->ddObject->EnumDDDisplayModes( |
| constraint, callback, context); |
| } else { |
| return FALSE; |
| } |
| } |
| |
| /** |
| * Attempts to restore surface. This will only succeed if the system is |
| * in a state that allows the surface to be restored. If a restore |
| * results in a DDERR_WRONGMODE, then the surface must be recreated |
| * entirely; we do this by invalidating the surfaceData and recreating |
| * it from scratch (at the Java level). |
| */ |
| BOOL DDRestoreSurface(Win32SDOps *wsdo) |
| { |
| J2dTraceLn1(J2D_TRACE_INFO, "DDRestoreSurface, wsdo->lpSurface=0x%x", |
| wsdo->lpSurface); |
| |
| DDrawObjectStruct *tmpDdInstance = wsdo->ddInstance; |
| if (tmpDdInstance == NULL || !tmpDdInstance->accelerated) { |
| return FALSE; |
| } |
| // Don't try to restore an inactive primary in full-screen mode |
| if (!isAppActive && wsdo->window && |
| wsdo->window == tmpDdInstance->hwndFullScreen) { |
| return FALSE; |
| } |
| if (wsdo->lpSurface->IsLost() == DD_OK) { |
| J2dTraceLn(J2D_TRACE_VERBOSE, "DDRestoreSurface: surface memory ok"); |
| } |
| else { |
| J2dTraceLn(J2D_TRACE_WARNING, |
| "DDRestoreSurface: surface memory lost, trying to restore"); |
| HRESULT ddResult; |
| ddResult = wsdo->lpSurface->Restore(); |
| if (ddResult == DDERR_WRONGMODE) { |
| // Strange full-screen bug; return false to avoid a hang. |
| // Note that we should never get this error in full-screen mode. |
| if (wsdo->window == tmpDdInstance->hwndFullScreen) { |
| return FALSE; |
| } |
| // Wrong mode: display depth has been changed. |
| J2dRlsTraceLn(J2D_TRACE_ERROR, |
| "DDRestoreSurface failure: DDERR_WRONGMODE"); |
| if (wsdo->window) { |
| /** |
| * If this is a window surface, invalidate this |
| * object's ddInstance and return the approriate error. The |
| * surfaceData will later be invalidated, disposed, and |
| * re-created with the new and correct depth information. |
| * Only invalidate for windows because offscreen surfaces |
| * have other means of being re-created and do not necessarily |
| * mean that the ddInstance object is invalid for other surfaces |
| */ |
| DDInvalidateDDInstance(wsdo->ddInstance); |
| } |
| return FALSE; |
| } else if (ddResult != DD_OK) { |
| DebugPrintDirectDrawError(ddResult, "DDRestoreSurface"); |
| return FALSE; |
| } |
| } |
| if (!tmpDdInstance->valid) { |
| tmpDdInstance->valid = TRUE; |
| } |
| return TRUE; |
| } |
| |
| jint DDGetAvailableMemory(HMONITOR hMon) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "DDGetAvailableMemory"); |
| DWORD dwFree; |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| if (!useDD || !tmpDdInstance || !tmpDdInstance->valid) { |
| return 0; |
| } |
| |
| HRESULT ddResult = tmpDdInstance->ddObject->GetDDAvailableVidMem(&dwFree); |
| if (ddResult != DD_OK) { |
| DebugPrintDirectDrawError(ddResult, "GetAvailableMemory"); |
| } |
| |
| return (jint)dwFree; |
| } |
| |
| |
| /** |
| * Creates either an offscreen or onscreen ddraw surface, depending |
| * on the value of wsdo->window. Handles the common |
| * framework of surface creation, such as ddInstance management, |
| * and passes off the functionality of actual surface creation to |
| * other functions. Successful creation results in a return value |
| * of TRUE. |
| */ |
| BOOL DDCreateSurface(Win32SDOps *wsdo) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "DDCreateSurface"); |
| HMONITOR hMon; |
| hMon = (HMONITOR)wsdo->device->GetMonitor(); |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| |
| wsdo->ddInstance = NULL; // default value in case of error |
| wsdo->lpSurface = NULL; // default value in case of error |
| |
| if (wsdo->window) { |
| if (tmpDdInstance && |
| tmpDdInstance->backBufferCount != wsdo->backBufferCount && |
| tmpDdInstance->hwndFullScreen == wsdo->window) |
| { |
| tmpDdInstance->context = CONTEXT_CHANGE_BUFFER_COUNT; |
| tmpDdInstance->backBufferCount = wsdo->backBufferCount; |
| } |
| if (!tmpDdInstance || !tmpDdInstance->valid || |
| tmpDdInstance->context != CONTEXT_NORMAL |
| ) { |
| // Only recreate dd object on primary create. Given our current |
| // model of displayChange event propagation, we can only guarantee |
| // that the system has been properly prepared for a recreate when |
| // we recreate a primary surface. The offscreen surfaces may |
| // be recreated at any time. |
| // Recreating ddraw at offscreen surface creation time has caused |
| // rendering artifacts as well as unexplainable hangs in ddraw |
| // calls. |
| ddInstanceLock.Enter(); |
| BOOL success = DDCreatePrimary(wsdo); |
| ddInstanceLock.Leave(); |
| if (!success) { |
| return FALSE; |
| } |
| tmpDdInstance = GetDDInstanceForDevice(hMon); |
| } |
| // restore the primary if it's lost |
| if (tmpDdInstance->primary != NULL && |
| FAILED(tmpDdInstance->primary->IsLost()) && |
| FAILED(tmpDdInstance->primary->Restore())) |
| { |
| J2dRlsTraceLn(J2D_TRACE_ERROR, |
| "DDCreateSurface: failed to restore primary surface"); |
| return FALSE; |
| } |
| // non-null window means onscreen surface. Primary already |
| // exists, just need to cache a pointer to it in this wsdo |
| wsdo->lpSurface = tmpDdInstance->primary; |
| } else { |
| if (!tmpDdInstance || !tmpDdInstance->valid) { |
| // Don't recreate the ddraw object here (see note above), but |
| // do fail this creation. We will come back here eventually |
| // after an onscreen surface has been created (and the new |
| // ddraw object to go along with it). |
| return FALSE; |
| } |
| if (!DDCreateOffScreenSurface(wsdo, tmpDdInstance)) { |
| J2dRlsTraceLn(J2D_TRACE_ERROR, |
| "DDCreateSurface: Failed creating offscreen surface"); |
| return FALSE; |
| } |
| } |
| wsdo->ddInstance = tmpDdInstance; |
| J2dTraceLn2(J2D_TRACE_VERBOSE, |
| "DDCreateSurface: succeeded ddInst=0x%x wsdo->lpSurface=0x%x", |
| tmpDdInstance, wsdo->lpSurface); |
| return TRUE; |
| } |
| |
| /** |
| * Utility function to make sure that native and java-level |
| * surface depths are matched. They can be mismatched when display-depths |
| * change, either between the creation of the Java surfaceData structure |
| * and the native ddraw surface, or later when a surface is automatically |
| * adjusted to be the new display depth (even if it was created in a different |
| * depth to begin with) |
| */ |
| BOOL DDSurfaceDepthsCompatible(int javaDepth, int nativeDepth) |
| { |
| if (nativeDepth != javaDepth) { |
| switch (nativeDepth) { |
| case 0: // Error condition: something is wrong with the surface |
| case 8: |
| case 24: |
| // Java and native surface depths should match exactly for |
| // these cases |
| return FALSE; |
| break; |
| case 16: |
| // Java surfaceData should be 15 or 16 bits |
| if (javaDepth < 15 || javaDepth > 16) { |
| return FALSE; |
| } |
| break; |
| case 32: |
| // Could have this native depth for either 24- or 32-bit |
| // Java surfaceData |
| if (javaDepth != 24 && javaDepth != 32) { |
| return FALSE; |
| } |
| break; |
| default: |
| // should not get here, but if we do something is odd, so |
| // just register a failure |
| return FALSE; |
| } |
| } |
| return TRUE; |
| } |
| |
| |
| /** |
| * Creates offscreen surface. Examines the display mode information |
| * for the current ddraw object and uses that to create this new |
| * surface. |
| */ |
| BOOL DDCreateOffScreenSurface(Win32SDOps *wsdo, |
| DDrawObjectStruct *ddInst) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "DDCreateOffScreenSurface"); |
| |
| wsdo->lpSurface = |
| ddInst->ddObject->CreateDDOffScreenSurface(wsdo->w, wsdo->h, |
| wsdo->depth, wsdo->transparency, DDSCAPS_VIDEOMEMORY); |
| if (!ddInst->primary || (ddInst->primary->IsLost() != DD_OK)) { |
| if (wsdo->lpSurface) { |
| delete wsdo->lpSurface; |
| wsdo->lpSurface = NULL; |
| } |
| if (ddInst->primary) { |
| // attempt to restore primary |
| ddInst->primary->Restore(); |
| if (ddInst->primary->IsLost() == DD_OK) { |
| // Primary restored: create the offscreen surface again |
| wsdo->lpSurface = |
| ddInst->ddObject->CreateDDOffScreenSurface(wsdo->w, wsdo->h, |
| wsdo->depth, wsdo->transparency, |
| DDSCAPS_VIDEOMEMORY); |
| if (ddInst->primary->IsLost() != DD_OK) { |
| // doubtful, but possible that it is lost again |
| // If so, delete the surface and get out of here |
| if (wsdo->lpSurface) { |
| delete wsdo->lpSurface; |
| wsdo->lpSurface = NULL; |
| } |
| } |
| } |
| } |
| } |
| if (wsdo->lpSurface != NULL && (wsdo->transparency != TR_TRANSLUCENT)) { |
| /** |
| * 4941350: Double-check that the depth of the surface just created |
| * is compatible with the depth requested. Note that we ignore texture |
| * (translucent) surfaces as those depths may differ between Java and |
| * native representations. |
| */ |
| int surfaceDepth = wsdo->lpSurface->GetSurfaceDepth(); |
| if (!DDSurfaceDepthsCompatible(wsdo->depth, surfaceDepth)) { |
| J2dTraceLn2(J2D_TRACE_WARNING, |
| "DDCreateOffScreenSurface: Surface depth mismatch: "\ |
| "intended=%d actual=%d", |
| wsdo->depth, surfaceDepth); |
| DDReleaseSurfaceMemory(wsdo->lpSurface); |
| wsdo->lpSurface = NULL; |
| } |
| } |
| return (wsdo->lpSurface != NULL); |
| } |
| |
| |
| /** |
| * Gets an attached surface, such as a back buffer, from a parent |
| * surface. Sets the lpSurface member of the wsdo supplied to |
| * the attached surface. |
| */ |
| BOOL DDGetAttachedSurface(JNIEnv *env, Win32SDOps* wsdo_parent, |
| Win32SDOps* wsdo) |
| { |
| J2dTraceLn(J2D_TRACE_INFO, "DDGetAttachedSurface"); |
| HMONITOR hMon = (HMONITOR)wsdo_parent->device->GetMonitor(); |
| DDrawObjectStruct *tmpDdInstance = GetDDInstanceForDevice(hMon); |
| |
| wsdo->ddInstance = NULL; // default value in case of error |
| wsdo->lpSurface = NULL; // default value in case of error |
| |
| if (!tmpDdInstance || !tmpDdInstance->valid || |
| wsdo_parent->lpSurface == NULL) |
| { |
| J2dTraceLn2(J2D_TRACE_WARNING, |
| "DDGetAttachedSurface: unable to get attached "\ |
| "surface for wsdo=0%x wsdo_parent=0%x", wsdo, wsdo_parent); |
| return FALSE; |
| } |
| DDrawSurface* pNew = wsdo_parent->lpSurface->GetDDAttachedSurface(); |
| if (pNew == NULL) { |
| return FALSE; |
| } |
| wsdo->lpSurface = pNew; |
| wsdo->ddInstance = tmpDdInstance; |
| J2dTraceLn1(J2D_TRACE_VERBOSE, |
| "DDGetAttachedSurface: succeeded wsdo->lpSurface=0x%x", |
| wsdo->lpSurface); |
| return TRUE; |
| } |
| |
| |
| /** |
| * Destroys resources associated with a surface |
| */ |
| void DDDestroySurface(Win32SDOps *wsdo) |
| { |
| J2dTraceLn1(J2D_TRACE_INFO, "DDDestroySurface: wsdo->lpSurface=0x%x", |
| wsdo->lpSurface); |
| |
| if (!wsdo->lpSurface) { |
| // null surface means it was never created; simply return |
| return; |
| } |
| if (!wsdo->window) { |
| // offscreen surface |
| delete wsdo->lpSurface; |
| wsdo->lpSurface = NULL; |
| } |
| J2dTraceLn1(J2D_TRACE_VERBOSE, |
| "DDDestroySurface: ddInstance->refCount=%d", |
| wsdo->ddInstance->refCount); |
| } |
| |
| /** |
| * Releases ddraw resources associated with a surface. Note that |
| * the DDrawSurface object is still valid, but the underlying |
| * DirectDraw surface is released. |
| */ |
| void DDReleaseSurfaceMemory(DDrawSurface *lpSurface) |
| { |
| J2dTraceLn1(J2D_TRACE_INFO, |
| "DDReleaseSurfaceMemory: lpSurface=0x%x", lpSurface); |
| |
| if (!lpSurface) { |
| // null surface means it was never created; simply return |
| return; |
| } |
| HRESULT ddResult = lpSurface->ReleaseSurface(); |
| } |
| |
| /* |
| * This function returns whether or not surfaces should be replaced |
| * in response to a WM_DISPLAYCHANGE message. If we are a full-screen |
| * application that has lost its surfaces, we do not want to replace |
| * our surfaces in response to a WM_DISPLAYCHANGE. |
| */ |
| BOOL DDCanReplaceSurfaces(HWND hwnd) |
| { |
| J2dTraceLn1(J2D_TRACE_VERBOSE, "DDCanReplaceSurfaces: hwnd=0x%x", hwnd); |
| DDrawObjectStruct *tmpDdInstance = NULL; |
| ddInstanceLock.Enter(); |
| for (int i = 0; i < currNumDevices; i++) { |
| tmpDdInstance = ddInstance[i]; |
| if (DDINSTANCE_USABLE(tmpDdInstance)) { |
| J2dTraceLn2(J2D_TRACE_VERBOSE, |
| " ddInstance[%d]->hwndFullScreen=0x%x", |
| i, tmpDdInstance->hwndFullScreen); |
| if (tmpDdInstance->hwndFullScreen != NULL && |
| tmpDdInstance->context == CONTEXT_NORMAL && |
| (tmpDdInstance->hwndFullScreen == hwnd || hwnd == NULL)) { |
| ddInstanceLock.Leave(); |
| return FALSE; |
| } |
| } |
| } |
| ddInstanceLock.Leave(); |
| return TRUE; |
| } |
| |
| /* |
| * This function prints the DirectDraw error associated with |
| * the given errNum |
| */ |
| void PrintDirectDrawError(DWORD errNum, char *message) |
| { |
| char buffer[255]; |
| |
| GetDDErrorString(errNum, buffer); |
| printf("%s:: %s\n", message, buffer); |
| } |
| |
| |
| /* |
| * This function prints the DirectDraw error associated with |
| * the given errNum |
| */ |
| void DebugPrintDirectDrawError(DWORD errNum, char *message) |
| { |
| char buffer[255]; |
| |
| GetDDErrorString(errNum, buffer); |
| J2dRlsTraceLn2(J2D_TRACE_ERROR, "%s: %s", message, buffer); |
| } |
| |
| |
| /* |
| * This function prints the error string into the given buffer |
| */ |
| void GetDDErrorString(DWORD errNum, char *buffer) |
| { |
| switch (errNum) { |
| case DDERR_ALREADYINITIALIZED: |
| sprintf(buffer, "DirectDraw Error: DDERR_ALREADYINITIALIZED"); |
| break; |
| case DDERR_CANNOTATTACHSURFACE: |
| sprintf(buffer, "DirectDraw Error: DDERR_CANNOTATTACHSURFACE"); |
| break; |
| case DDERR_CANNOTDETACHSURFACE: |
| sprintf(buffer, "DirectDraw Error: DDERR_CANNOTDETACHSURFACE"); |
| break; |
| case DDERR_CURRENTLYNOTAVAIL: |
| sprintf(buffer, "DirectDraw Error: DDERR_CURRENTLYNOTAVAIL"); |
| break; |
| case DDERR_EXCEPTION: |
| sprintf(buffer, "DirectDraw Error: DDERR_EXCEPTION"); |
| break; |
| case DDERR_GENERIC: |
| sprintf(buffer, "DirectDraw Error: DDERR_GENERIC"); |
| break; |
| case DDERR_HEIGHTALIGN: |
| sprintf(buffer, "DirectDraw Error: DDERR_HEIGHTALIGN"); |
| break; |
| case DDERR_INCOMPATIBLEPRIMARY: |
| sprintf(buffer, "DirectDraw Error: DDERR_INCOMPATIBLEPRIMARY"); |
| break; |
| case DDERR_INVALIDCAPS: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDCAPS"); |
| break; |
| case DDERR_INVALIDCLIPLIST: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDCLIPLIST"); |
| break; |
| case DDERR_INVALIDMODE: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDMODE"); |
| break; |
| case DDERR_INVALIDOBJECT: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDOBJECT"); |
| break; |
| case DDERR_INVALIDPARAMS: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDPARAMS"); |
| break; |
| case DDERR_INVALIDPIXELFORMAT: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDPIXELFORMAT"); |
| break; |
| case DDERR_INVALIDRECT: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDRECT"); |
| break; |
| case DDERR_LOCKEDSURFACES: |
| sprintf(buffer, "DirectDraw Error: DDERR_LOCKEDSURFACES"); |
| break; |
| case DDERR_NO3D: |
| sprintf(buffer, "DirectDraw Error: DDERR_NO3D"); |
| break; |
| case DDERR_NOALPHAHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOALPHAHW"); |
| break; |
| case DDERR_NOCLIPLIST: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOCLIPLIST"); |
| break; |
| case DDERR_NOCOLORCONVHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOCOLORCONVHW"); |
| break; |
| case DDERR_NOCOOPERATIVELEVELSET: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOCOOPERATIVELEVELSET"); |
| break; |
| case DDERR_NOCOLORKEY: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOCOLORKEY"); |
| break; |
| case DDERR_NOCOLORKEYHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOCOLORKEYHW"); |
| break; |
| case DDERR_NODIRECTDRAWSUPPORT: |
| sprintf(buffer, "DirectDraw Error: DDERR_NODIRECTDRAWSUPPORT"); |
| break; |
| case DDERR_NOEXCLUSIVEMODE: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOEXCLUSIVEMODE"); |
| break; |
| case DDERR_NOFLIPHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOFLIPHW"); |
| break; |
| case DDERR_NOGDI: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOGDI"); |
| break; |
| case DDERR_NOMIRRORHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOMIRRORHW"); |
| break; |
| case DDERR_NOTFOUND: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOTFOUND"); |
| break; |
| case DDERR_NOOVERLAYHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOOVERLAYHW"); |
| break; |
| case DDERR_NORASTEROPHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NORASTEROPHW"); |
| break; |
| case DDERR_NOROTATIONHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOROTATIONHW"); |
| break; |
| case DDERR_NOSTRETCHHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOSTRETCHHW"); |
| break; |
| case DDERR_NOT4BITCOLOR: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOT4BITCOLOR"); |
| break; |
| case DDERR_NOT4BITCOLORINDEX: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOT4BITCOLORINDEX"); |
| break; |
| case DDERR_NOT8BITCOLOR: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOT8BITCOLOR"); |
| break; |
| case DDERR_NOTEXTUREHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOTEXTUREHW"); |
| break; |
| case DDERR_NOVSYNCHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOVSYNCHW"); |
| break; |
| case DDERR_NOZBUFFERHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOZBUFFERHW"); |
| break; |
| case DDERR_NOZOVERLAYHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOZOVERLAYHW"); |
| break; |
| case DDERR_OUTOFCAPS: |
| sprintf(buffer, "DirectDraw Error: DDERR_OUTOFCAPS"); |
| break; |
| case DDERR_OUTOFMEMORY: |
| sprintf(buffer, "DirectDraw Error: DDERR_OUTOFMEMORY"); |
| break; |
| case DDERR_OUTOFVIDEOMEMORY: |
| sprintf(buffer, "DirectDraw Error: DDERR_OUTOFVIDEOMEMORY"); |
| break; |
| case DDERR_OVERLAYCANTCLIP: |
| sprintf(buffer, "DirectDraw Error: DDERR_OVERLAYCANTCLIP"); |
| break; |
| case DDERR_OVERLAYCOLORKEYONLYONEACTIVE: |
| sprintf(buffer, "DirectDraw Error: DDERR_OVERLAYCOLORKEYONLYONEACTIVE"); |
| break; |
| case DDERR_PALETTEBUSY: |
| sprintf(buffer, "DirectDraw Error: DDERR_PALETTEBUSY"); |
| break; |
| case DDERR_COLORKEYNOTSET: |
| sprintf(buffer, "DirectDraw Error: DDERR_COLORKEYNOTSET"); |
| break; |
| case DDERR_SURFACEALREADYATTACHED: |
| sprintf(buffer, "DirectDraw Error: DDERR_SURFACEALREADYATTACHED"); |
| break; |
| case DDERR_SURFACEALREADYDEPENDENT: |
| sprintf(buffer, "DirectDraw Error: DDERR_SURFACEALREADYDEPENDENT"); |
| break; |
| case DDERR_SURFACEBUSY: |
| sprintf(buffer, "DirectDraw Error: DDERR_SURFACEBUSY"); |
| break; |
| case DDERR_CANTLOCKSURFACE: |
| sprintf(buffer, "DirectDraw Error: DDERR_CANTLOCKSURFACE"); |
| break; |
| case DDERR_SURFACEISOBSCURED: |
| sprintf(buffer, "DirectDraw Error: DDERR_SURFACEISOBSCURED"); |
| break; |
| case DDERR_SURFACELOST: |
| sprintf(buffer, "DirectDraw Error: DDERR_SURFACELOST"); |
| break; |
| case DDERR_SURFACENOTATTACHED: |
| sprintf(buffer, "DirectDraw Error: DDERR_SURFACENOTATTACHED"); |
| break; |
| case DDERR_TOOBIGHEIGHT: |
| sprintf(buffer, "DirectDraw Error: DDERR_TOOBIGHEIGHT"); |
| break; |
| case DDERR_TOOBIGSIZE: |
| sprintf(buffer, "DirectDraw Error: DDERR_TOOBIGSIZE"); |
| break; |
| case DDERR_TOOBIGWIDTH: |
| sprintf(buffer, "DirectDraw Error: DDERR_TOOBIGWIDTH"); |
| break; |
| case DDERR_UNSUPPORTED: |
| sprintf(buffer, "DirectDraw Error: DDERR_UNSUPPORTED"); |
| break; |
| case DDERR_UNSUPPORTEDFORMAT: |
| sprintf(buffer, "DirectDraw Error: DDERR_UNSUPPORTEDFORMAT"); |
| break; |
| case DDERR_UNSUPPORTEDMASK: |
| sprintf(buffer, "DirectDraw Error: DDERR_UNSUPPORTEDMASK"); |
| break; |
| case DDERR_VERTICALBLANKINPROGRESS: |
| sprintf(buffer, "DirectDraw Error: DDERR_VERTICALBLANKINPROGRESS"); |
| break; |
| case DDERR_WASSTILLDRAWING: |
| sprintf(buffer, "DirectDraw Error: DDERR_WASSTILLDRAWING"); |
| break; |
| case DDERR_XALIGN: |
| sprintf(buffer, "DirectDraw Error: DDERR_XALIGN"); |
| break; |
| case DDERR_INVALIDDIRECTDRAWGUID: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDDIRECTDRAWGUID"); |
| break; |
| case DDERR_DIRECTDRAWALREADYCREATED: |
| sprintf(buffer, "DirectDraw Error: DDERR_DIRECTDRAWALREADYCREATED"); |
| break; |
| case DDERR_NODIRECTDRAWHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NODIRECTDRAWHW"); |
| break; |
| case DDERR_PRIMARYSURFACEALREADYEXISTS: |
| sprintf(buffer, "DirectDraw Error: DDERR_PRIMARYSURFACEALREADYEXISTS"); |
| break; |
| case DDERR_NOEMULATION: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOEMULATION"); |
| break; |
| case DDERR_REGIONTOOSMALL: |
| sprintf(buffer, "DirectDraw Error: DDERR_REGIONTOOSMALL"); |
| break; |
| case DDERR_CLIPPERISUSINGHWND: |
| sprintf(buffer, "DirectDraw Error: DDERR_CLIPPERISUSINGHWND"); |
| break; |
| case DDERR_NOCLIPPERATTACHED: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOCLIPPERATTACHED"); |
| break; |
| case DDERR_NOHWND: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOHWND"); |
| break; |
| case DDERR_HWNDSUBCLASSED: |
| sprintf(buffer, "DirectDraw Error: DDERR_HWNDSUBCLASSED"); |
| break; |
| case DDERR_HWNDALREADYSET: |
| sprintf(buffer, "DirectDraw Error: DDERR_HWNDALREADYSET"); |
| break; |
| case DDERR_NOPALETTEATTACHED: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOPALETTEATTACHED"); |
| break; |
| case DDERR_NOPALETTEHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOPALETTEHW"); |
| break; |
| case DDERR_BLTFASTCANTCLIP: |
| sprintf(buffer, "DirectDraw Error: DDERR_BLTFASTCANTCLIP"); |
| break; |
| case DDERR_NOBLTHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOBLTHW"); |
| break; |
| case DDERR_NODDROPSHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NODDROPSHW"); |
| break; |
| case DDERR_OVERLAYNOTVISIBLE: |
| sprintf(buffer, "DirectDraw Error: DDERR_OVERLAYNOTVISIBLE"); |
| break; |
| case DDERR_NOOVERLAYDEST: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOOVERLAYDEST"); |
| break; |
| case DDERR_INVALIDPOSITION: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDPOSITION"); |
| break; |
| case DDERR_NOTAOVERLAYSURFACE: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOTAOVERLAYSURFACE"); |
| break; |
| case DDERR_EXCLUSIVEMODEALREADYSET: |
| sprintf(buffer, "DirectDraw Error: DDERR_EXCLUSIVEMODEALREADYSET"); |
| break; |
| case DDERR_NOTFLIPPABLE: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOTFLIPPABLE"); |
| break; |
| case DDERR_CANTDUPLICATE: |
| sprintf(buffer, "DirectDraw Error: DDERR_CANTDUPLICATE"); |
| break; |
| case DDERR_NOTLOCKED: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOTLOCKED"); |
| break; |
| case DDERR_CANTCREATEDC: |
| sprintf(buffer, "DirectDraw Error: DDERR_CANTCREATEDC"); |
| break; |
| case DDERR_NODC: |
| sprintf(buffer, "DirectDraw Error: DDERR_NODC"); |
| break; |
| case DDERR_WRONGMODE: |
| sprintf(buffer, "DirectDraw Error: DDERR_WRONGMODE"); |
| break; |
| case DDERR_IMPLICITLYCREATED: |
| sprintf(buffer, "DirectDraw Error: DDERR_IMPLICITLYCREATED"); |
| break; |
| case DDERR_NOTPALETTIZED: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOTPALETTIZED"); |
| break; |
| case DDERR_UNSUPPORTEDMODE: |
| sprintf(buffer, "DirectDraw Error: DDERR_UNSUPPORTEDMODE"); |
| break; |
| case DDERR_NOMIPMAPHW: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOMIPMAPHW"); |
| break; |
| case DDERR_INVALIDSURFACETYPE: |
| sprintf(buffer, "DirectDraw Error: DDERR_INVALIDSURFACETYPE"); |
| break; |
| case DDERR_DCALREADYCREATED: |
| sprintf(buffer, "DirectDraw Error: DDERR_DCALREADYCREATED"); |
| break; |
| case DDERR_CANTPAGELOCK: |
| sprintf(buffer, "DirectDraw Error: DDERR_CANTPAGELOCK"); |
| break; |
| case DDERR_CANTPAGEUNLOCK: |
| sprintf(buffer, "DirectDraw Error: DDERR_CANTPAGEUNLOCK"); |
| break; |
| case DDERR_NOTPAGELOCKED: |
| sprintf(buffer, "DirectDraw Error: DDERR_NOTPAGELOCKED"); |
| break; |
| case D3DERR_INVALID_DEVICE: |
| sprintf(buffer, "Direct3D Error: D3DERR_INVALID_DEVICE"); |
| break; |
| case D3DERR_INITFAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_INITFAILED"); |
| break; |
| case D3DERR_DEVICEAGGREGATED: |
| sprintf(buffer, "Direct3D Error: D3DERR_DEVICEAGGREGATED"); |
| break; |
| case D3DERR_EXECUTE_CREATE_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_EXECUTE_CREATE_FAILED"); |
| break; |
| case D3DERR_EXECUTE_DESTROY_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_EXECUTE_DESTROY_FAILED"); |
| break; |
| case D3DERR_EXECUTE_LOCK_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_EXECUTE_LOCK_FAILED"); |
| break; |
| case D3DERR_EXECUTE_UNLOCK_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_EXECUTE_UNLOCK_FAILED"); |
| break; |
| case D3DERR_EXECUTE_LOCKED: |
| sprintf(buffer, "Direct3D Error: D3DERR_EXECUTE_LOCKED"); |
| break; |
| case D3DERR_EXECUTE_NOT_LOCKED: |
| sprintf(buffer, "Direct3D Error: D3DERR_EXECUTE_NOT_LOCKED"); |
| break; |
| case D3DERR_EXECUTE_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_EXECUTE_FAILED"); |
| break; |
| case D3DERR_EXECUTE_CLIPPED_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_EXECUTE_CLIPPED_FAILED"); |
| break; |
| case D3DERR_TEXTURE_NO_SUPPORT: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_NO_SUPPORT"); |
| break; |
| case D3DERR_TEXTURE_CREATE_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_CREATE_FAILED"); |
| break; |
| case D3DERR_TEXTURE_DESTROY_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_DESTROY_FAILED"); |
| break; |
| case D3DERR_TEXTURE_LOCK_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_LOCK_FAILED"); |
| break; |
| case D3DERR_TEXTURE_UNLOCK_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_UNLOCK_FAILED"); |
| break; |
| case D3DERR_TEXTURE_LOAD_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_LOAD_FAILED"); |
| break; |
| case D3DERR_TEXTURE_SWAP_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_SWAP_FAILED"); |
| break; |
| case D3DERR_TEXTURE_LOCKED: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_LOCKED"); |
| break; |
| case D3DERR_TEXTURE_NOT_LOCKED: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_NOT_LOCKED"); |
| break; |
| case D3DERR_TEXTURE_GETSURF_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_GETSURF_FAILED"); |
| break; |
| case D3DERR_MATRIX_CREATE_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_MATRIX_CREATE_FAILED"); |
| break; |
| case D3DERR_MATRIX_DESTROY_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_MATRIX_DESTROY_FAILED"); |
| break; |
| case D3DERR_MATRIX_SETDATA_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_MATRIX_SETDATA_FAILED"); |
| break; |
| case D3DERR_MATRIX_GETDATA_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_MATRIX_GETDATA_FAILED"); |
| break; |
| case D3DERR_SETVIEWPORTDATA_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_SETVIEWPORTDATA_FAILED"); |
| break; |
| case D3DERR_INVALIDCURRENTVIEWPORT: |
| sprintf(buffer, "Direct3D Error: D3DERR_INVALIDCURRENTVIEWPORT"); |
| break; |
| case D3DERR_INVALIDPRIMITIVETYPE: |
| sprintf(buffer, "Direct3D Error: D3DERR_INVALIDPRIMITIVETYPE"); |
| break; |
| case D3DERR_INVALIDVERTEXTYPE: |
| sprintf(buffer, "Direct3D Error: D3DERR_INVALIDVERTEXTYPE"); |
| break; |
| case D3DERR_TEXTURE_BADSIZE: |
| sprintf(buffer, "Direct3D Error: D3DERR_TEXTURE_BADSIZE"); |
| break; |
| case D3DERR_INVALIDRAMPTEXTURE: |
| sprintf(buffer, "Direct3D Error: D3DERR_INVALIDRAMPTEXTURE"); |
| break; |
| case D3DERR_MATERIAL_CREATE_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_MATERIAL_CREATE_FAILED"); |
| break; |
| case D3DERR_MATERIAL_DESTROY_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_MATERIAL_DESTROY_FAILED"); |
| break; |
| case D3DERR_MATERIAL_SETDATA_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_MATERIAL_SETDATA_FAILED"); |
| break; |
| case D3DERR_MATERIAL_GETDATA_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_MATERIAL_GETDATA_FAILED"); |
| break; |
| case D3DERR_INVALIDPALETTE: |
| sprintf(buffer, "Direct3D Error: D3DERR_INVALIDPALETTE"); |
| break; |
| case D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY: |
| sprintf(buffer, "Direct3D Error: D3DERR_ZBUFF_NEEDS_SYSTEMMEMORY"); |
| break; |
| case D3DERR_ZBUFF_NEEDS_VIDEOMEMORY: |
| sprintf(buffer, "Direct3D Error: D3DERR_ZBUFF_NEEDS_VIDEOMEMORY"); |
| break; |
| case D3DERR_SURFACENOTINVIDMEM: |
| sprintf(buffer, "Direct3D Error: D3DERR_SURFACENOTINVIDMEM"); |
| break; |
| case D3DERR_LIGHT_SET_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_LIGHT_SET_FAILED"); |
| break; |
| case D3DERR_LIGHTHASVIEWPORT: |
| sprintf(buffer, "Direct3D Error: D3DERR_LIGHTHASVIEWPORT"); |
| break; |
| case D3DERR_LIGHTNOTINTHISVIEWPORT: |
| sprintf(buffer, "Direct3D Error: D3DERR_LIGHTNOTINTHISVIEWPORT"); |
| break; |
| case D3DERR_SCENE_IN_SCENE: |
| sprintf(buffer, "Direct3D Error: D3DERR_SCENE_IN_SCENE"); |
| break; |
| case D3DERR_SCENE_NOT_IN_SCENE: |
| sprintf(buffer, "Direct3D Error: D3DERR_SCENE_NOT_IN_SCENE"); |
| break; |
| case D3DERR_SCENE_BEGIN_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_SCENE_BEGIN_FAILED"); |
| break; |
| case D3DERR_SCENE_END_FAILED: |
| sprintf(buffer, "Direct3D Error: D3DERR_SCENE_END_FAILED"); |
| break; |
| case D3DERR_INBEGIN: |
| sprintf(buffer, "Direct3D Error: D3DERR_INBEGIN"); |
| break; |
| case D3DERR_NOTINBEGIN: |
| sprintf(buffer, "Direct3D Error: D3DERR_NOTINBEGIN"); |
| break; |
| case D3DERR_NOVIEWPORTS: |
| sprintf(buffer, "Direct3D Error: D3DERR_NOVIEWPORTS"); |
| break; |
| case D3DERR_VIEWPORTDATANOTSET: |
| sprintf(buffer, "Direct3D Error: D3DERR_VIEWPORTDATANOTSET"); |
| break; |
| case D3DERR_VIEWPORTHASNODEVICE: |
| sprintf(buffer, "Direct3D Error: D3DERR_VIEWPORTHASNODEVICE"); |
| break; |
| case D3DERR_NOCURRENTVIEWPORT: |
| sprintf(buffer, "Direct3D Error: D3DERR_NOCURRENTVIEWPORT"); |
| break; |
| default: |
| sprintf(buffer, "DirectX Error Unknown 0x%x", errNum); |
| break; |
| } |
| |
| } |