📄 wince_ws.c
字号:
GetApplicationHints(&sAppHints);
surface->u.window.ws.bLockToVsync=sAppHints.bLockToVSync;
surface->u.window.ws.ui8BackBuffers=(IMG_UINT8)sAppHints.ui32BackBuffers;
if(surface->u.window.ws.ui8BackBuffers>2)
{
// some scamp is trying to create more than 2 back buffers. We shall put a stop to that!
surface->u.window.ws.ui8BackBuffers=2;
}
if( surface->u.window.ws.WndProc)
{
SetWindowLong(hWnd,GWL_WNDPROC,(IMG_UINT32)KEGLWndProc);
}
if(PVRSRVCreateCommandQueue(&surface->pvrsrv_context->s3D, GLES_COMMANDQUEUE_SIZE, &surface->psQueueInfo) != PVRSRV_OK)
{
DPF((DBG_ERROR,"Couldn't create a command queue"));
return EGL_BAD_ALLOC;
}
if(!GLESCreateRenderSurface(surface->pvrsrv_context, &sAppHints, &surface->hRenderSurface))
{
DPF((DBG_ERROR,"Couldn't create a render surface"));
return EGL_BAD_ALLOC;
}
if(surface->u.window.ws.ui8BackBuffers)
{
if(!surface->u.window.ws.bSecondaryExternalFullScreen)
{
pt.x = 0;
pt.y = 0;
ClientToScreen( hWnd, &pt );
surface->u.window.ws.n32XPos = pt.x;
surface->u.window.ws.n32YPos = pt.y;
surface->u.window.ws.sWindowRect.i32Top = pt.y;
surface->u.window.ws.sWindowRect.i32Left= pt.x;
GetClientRect(hWnd,&rc);
pt.x=rc.right;
pt.y=rc.bottom;
ClientToScreen( hWnd, &pt );
surface->u.window.ws.ui32Width = pt.x-surface->u.window.ws.n32XPos;
surface->u.window.ws.ui32Height = pt.y-surface->u.window.ws.n32YPos;
surface->u.window.ws.sWindowRect.i32Bottom= pt.y;
surface->u.window.ws.sWindowRect.i32Right= pt.x;
RotateWindowCoordinates(&surface->u.window.ws);
psCurrentRenderSurface->ui32PixelWidth = surface->u.window.ws.ui32Width;
psCurrentRenderSurface->ui32PixelHeight = surface->u.window.ws.ui32Height;
}
/* for the time being let it have a stride the same as the primary surface */
switch(psCurrentRenderSurface->ePixelFormat)
{
case PVRSRV_PIXEL_FORMAT_ARGB8888:
/* The 3D core has a texture stride alignment restriction of 8 pixel units = 32 bytes */
psCurrentRenderSurface->ui32ByteStride = ((psCurrentRenderSurface->ui32PixelWidth * 4 ) + 0x1F) & 0xFFFFFFE0;
break;
case PVRSRV_PIXEL_FORMAT_RGB565:
/* The 3D core has a texture stride alignment restriction of 8 pixel units = 16 bytes */
psCurrentRenderSurface->ui32ByteStride = ((psCurrentRenderSurface->ui32PixelWidth * 2 ) + 0x0F) & 0xFFFFFFF0;
break;
default:
// we don't know about any other kind of window surfaces so go away!
return EGL_BAD_ALLOC;
}
if(surface->u.window.ws.ui8BackBuffers)
{
if (PVRSRVAllocDeviceMem (&surface->pvrsrv_context->s3D,
0, /* flags */
psCurrentRenderSurface->ui32ByteStride
* psCurrentRenderSurface->ui32PixelHeight,
MBX1_MINIMUM_RENDER_TARGET_ALIGNMENT,
&surface->u.window.ws.apsSurfaces[1]) != PVRSRV_OK)
{
return EGL_BAD_ALLOC;
}
}
if(surface->u.window.ws.ui8BackBuffers>1)
{
if (PVRSRVAllocDeviceMem (&surface->pvrsrv_context->s3D,
0, /* flags */
psCurrentRenderSurface->ui32ByteStride
* psCurrentRenderSurface->ui32PixelHeight,
MBX1_MINIMUM_RENDER_TARGET_ALIGNMENT,
&surface->u.window.ws.apsSurfaces[2]) != PVRSRV_OK)
{
surface->u.window.ws.ui8BackBuffers=1;
}
}
// Our flip ring has upto 3 elements, the first of which will always be the primary surface (never allocate or free this */
if(surface->u.window.ws.ui8BackBuffers)
surface->u.window.ws.ui32NextDisplaySurface=1;
else
surface->u.window.ws.ui32NextDisplaySurface=0;
surface->u.window.ws.apsSurfaces[0]=dpy->ws.psPrimary_surface->psMemInfo;
psCurrentRenderSurface->psMemInfo=surface->u.window.ws.apsSurfaces[surface->u.window.ws.ui32NextDisplaySurface];
surface->u.window.ws.hShadowWnd=NULL;
if(!surface->u.window.ws.bSecondaryExternalFullScreen)
{
SetupShadowWindow(surface) ;
}
surface->u.window.ws.bFlipping=FALSE;
}
else
{
pt.x = 0;
pt.y = 0;
ClientToScreen( hWnd, &pt );
surface->u.window.ws.n32XPos = pt.x;
surface->u.window.ws.n32YPos = pt.y;
GetClientRect(hWnd,&rc);
pt.x=rc.right;
pt.y=rc.bottom;
ClientToScreen( hWnd, &pt );
surface->u.window.ws.ui32Width = pt.x-surface->u.window.ws.n32XPos;
surface->u.window.ws.ui32Height = pt.y-surface->u.window.ws.n32YPos;
psCurrentRenderSurface->ui32PixelWidth = surface->u.window.ws.ui32Width;
psCurrentRenderSurface->ui32PixelHeight = surface->u.window.ws.ui32Height;
psCurrentRenderSurface->psMemInfo = dpy->ws.psPrimary_surface->psMemInfo;
}
return EGL_SUCCESS;
}
/*
<function>
FUNCTION : WS_CreatePixmapDrawable
PURPOSE :
Validate and create a drawable from native pixmap. Must validate the
native pixmap against the surface configuration.
PARAMETERS :
In: dpy - Display.
In: surface - Surface.
In: pixmap - Native pixmap.
RETURNS :
EGL_SUCCESS: pixmap conforms to config.
EGL_BAD_NATIVE_PIXMAP: invalid pixmap handle.
EGL_BAD_MATCH: pixmap does not conform to specified config.
</function>
*/
EGLint
WS_CreatePixmapDrawable (KEGL_DISPLAY *dpy,
KEGL_SURFACE *surface,
NativePixmapType pixmap)
{
//trace ("ws (egl->ws): WS_CreatePixmapDrawable ()\n");
/* todo: validate native pixmap against surface->config */
return EGL_BAD_ALLOC;
}
/*
<function>
FUNCTION : WS_DeleteDrawable
PURPOSE : Delete a drawable.
PARAMETERS : In: surface - Surface to delete.
In: system_context - System context.
RETURNS : None
</function>
*/
void
WS_DeleteDrawable (KEGL_SURFACE *surface, GLESSysContext *pvrsrv)
{
//trace ("ws (egl->ws): WS_DeleteDrawable ()\n");
//assert (surface!=NULL);
switch (surface->type)
{
case EGL_SURFACE_WINDOW:
{
IMG_UINT32 ui32NumSurfaces = surface->u.window.ws.ui8BackBuffers + 1;
IMG_UINT32 ui32CurrentDisplaySurface =
(surface->u.window.ws.ui32NextDisplaySurface + ui32NumSurfaces - 1) % ui32NumSurfaces;
PVRSRVFlushQueue(surface->psQueueInfo);
if(surface->u.window.ws.bFlipping)
{
if(ui32CurrentDisplaySurface != 0)
{
PVRSRVQueueFlip(surface->psQueueInfo, surface->u.window.ws.apsSurfaces[0]->psSyncInfo,
surface->u.window.ws.apsSurfaces[ui32CurrentDisplaySurface]->psSyncInfo,
surface->u.window.ws.apsSurfaces[0], surface->u.window.ws.bLockToVsync, 1);
surface->u.window.ws.ui32NextDisplaySurface=0;
surface->u.window.ws.bFlipping=FALSE;
}
}
SetWindowLong((HWND)surface->u.window.native,GWL_WNDPROC,(IMG_UINT32)surface->u.window.ws.WndProc);
if(!GLESDestroyRenderSurface(surface->pvrsrv_context, surface->hRenderSurface))
{
DPF((DBG_ERROR,"Couldn't destroy a render surface"));
return;
}
if(PVRSRVDestroyCommandQueue(&pvrsrv->s3D, surface->psQueueInfo) != PVRSRV_OK)
{
DPF((DBG_ERROR,"Couldn't destroy a command queue"));
return;
}
if(surface->u.window.ws.ui8BackBuffers)
{
PVRSRVFreeDeviceMem (&surface->pvrsrv_context->s3D,surface->u.window.ws.apsSurfaces[1]);
}
if(surface->u.window.ws.ui8BackBuffers>1)
{
PVRSRVFreeDeviceMem (&surface->pvrsrv_context->s3D,surface->u.window.ws.apsSurfaces[2]);
}
if(surface->u.window.ws.hShadowWnd)
{
DestroyWindow(surface->u.window.ws.hShadowWnd);
UnregisterClass(TEXT("ShadowWindow"),GetModuleHandle(NULL));
}
break;
}
case EGL_SURFACE_PBUFFER:
{
if(!GLESDestroyRenderSurface(surface->pvrsrv_context, surface->hRenderSurface))
{
DPF((DBG_ERROR,"Couldn't destroy a render surface"));
return;
}
if(PVRSRVDestroyCommandQueue(&pvrsrv->s3D, surface->psQueueInfo) != PVRSRV_OK)
{
DPF((DBG_ERROR,"Couldn't destroy a command queue"));
return;
}
PVRSRVFreeDeviceMem (&pvrsrv->s3D, surface->u.pbuffer.memInfo);
break;
}
default:
/* nothing to do */
break;
}
}
/* OpenGL -> WS Glue API
*/
/*****************************************************************************
FUNCTION : WS_SwapDrawable
DESCRIPTION: Do whatever is required to present the new display buffer, either flip or blit
PARAMETERS : surface
RETURNS : -
*****************************************************************************/
void
WS_SwapDrawable (KEGL_SURFACE *surface)
{
PVRSRV_SURF dst_surface;
PLISTITEM psItem;
PVRSRV_SURF *psCurrentRenderSurface = &surface->sCurrentRenderSurface;
IMG_UINT32 ui32NextDisplaySurface, ui32CurrentDisplaySurface;
IMG_UINT32 ui32NumSurfaces;
IMG_BOOL bUpdate=IMG_FALSE;
//assert (surface!=NULL);
dst_surface.ui32ByteStride = surface->u.window.ws.psPrimary_surface->ui32ByteStride;
dst_surface.ui32PixelWidth = surface->u.window.ws.psPrimary_surface->ui32PixelWidth;
dst_surface.ui32PixelHeight = surface->u.window.ws.psPrimary_surface->ui32PixelHeight;
dst_surface.ePixelFormat = surface->u.window.ws.psPrimary_surface->ePixelFormat;
dst_surface.psMemInfo = surface->u.window.ws.psPrimary_surface->psMemInfo;
ui32NumSurfaces = surface->u.window.ws.ui8BackBuffers + 1;
ui32NextDisplaySurface = surface->u.window.ws.ui32NextDisplaySurface;
ui32CurrentDisplaySurface = (ui32NextDisplaySurface + ui32NumSurfaces - 1) % ui32NumSurfaces;
/* Rendering to a secondary fullscreen display */
if(surface->u.window.ws.bSecondaryExternalFullScreen)
{
PVRSRVQueueFlip(surface->psQueueInfo, surface->u.window.ws.apsSurfaces[ui32NextDisplaySurface]->psSyncInfo,
surface->u.window.ws.apsSurfaces[ui32CurrentDisplaySurface]->psSyncInfo,
surface->u.window.ws.apsSurfaces[ui32NextDisplaySurface], surface->u.window.ws.bLockToVsync, 1);
/* Increment next display surface ready for next getdrawableparams */
surface->u.window.ws.ui32NextDisplaySurface = (ui32NextDisplaySurface + 1) % ui32NumSurfaces;
psCurrentRenderSurface->psMemInfo=surface->u.window.ws.apsSurfaces[surface->u.window.ws.ui32NextDisplaySurface];
surface->u.window.ws.bFlipping=TRUE;
return;
}
if(GetForegroundWindow()==(HWND)surface->u.window.native)
{
if((psCurrentRenderSurface->ui32PixelWidth==surface->u.window.ws.psPrimary_surface->ui32PixelWidth) &&
(psCurrentRenderSurface->ui32PixelHeight==surface->u.window.ws.psPrimary_surface->ui32PixelHeight) &&
(psCurrentRenderSurface->ui32ByteStride==surface->u.window.ws.psPrimary_surface->ui32ByteStride))
{
/* We are fullscreen on the primary */
PVRSRVQueueFlip(surface->psQueueInfo, surface->u.window.ws.apsSurfaces[ui32NextDisplaySurface]->psSyncInfo,
surface->u.window.ws.apsSurfaces[ui32CurrentDisplaySurface]->psSyncInfo,
surface->u.window.ws.apsSurfaces[ui32NextDisplaySurface], surface->u.window.ws.bLockToVsync, 1);
/* Increment next display surface ready for next getdrawableparams */
surface->u.window.ws.ui32NextDisplaySurface = (ui32NextDisplaySurface + 1) % ui32NumSurfaces;
psCurrentRenderSurface->psMemInfo=surface->u.window.ws.apsSurfaces[surface->u.window.ws.ui32NextDisplaySurface];
surface->u.window.ws.bFlipping=TRUE;
return;
}
}
if((surface->u.window.ws.bFlipping) && (ui32CurrentDisplaySurface != 0))
{
/* We were fullscreen on the primary, but aren't anymore! */
PVRSRVQueueFlip(surface->psQueueInfo, surface->u.window.ws.apsSurfaces[0]->psSyncInfo,
surface->u.window.ws.apsSurfaces[ui32CurrentDisplaySurface]->psSyncInfo,
surface->u.window.ws.apsSurfaces[0], surface->u.window.ws.bLockToVsync, 1);
/* Use first backbuffer for subsequent renders */
surface->u.window.ws.ui32NextDisplaySurface = 1;
psCurrentRenderSurface->psMemInfo=surface->u.window.ws.apsSurfaces[surface->u.window.ws.ui32NextDisplaySurface];
surface->u.window.ws.bFlipping=FALSE;
}
bUpdate=DoClipping(surface->u.window.native,surface)&&(surface->u.window.ws.psClippedBlits);
// recalculate clip lists etc.
/* Do Clipped Blits will do the work to get the correct meminfo...*/
if(DoClippedBlits(dst_surface,surface))
{
PVRSRVQueueUpdateDisplay(surface->psQueueInfo, surface->u.window.ws.psPrimary_surface->psMemInfo->psSyncInfo);
}
/* Increment next display surface ready for next getdrawableparams */
ui32NextDisplaySurface = (ui32NextDisplaySurface + 1) % ui32NumSurfaces;
/* We don't use the primary as a backbuffer when blitting */
if(ui32NextDisplaySurface == 0)
ui32NextDisplaySurface = 1;
surface->u.window.ws.ui32NextDisplaySurface = ui32NextDisplaySurface;
psCurrentRenderSurface->psMemInfo=surface->u.window.ws.apsSurfaces[ui32NextDisplaySurface];
/* now do the Refresh of the screen by sending the move command to the shadow window */
if(surface->u.window.ws.hShadowWnd && bUpdate)
{
PVRSRVFlushQueue(surface->psQueueInfo);
psItem=surface->u.window.ws.psOverlappedWindowList;
while(psItem)
{
InvalidateRect((HWND)psItem->ui32Item,NULL,TRUE);
UpdateWindow((HWND)psItem->ui32Item );
psItem=psItem->psNext;
}
FreeItems(surface->u.window.ws.psOverlappedWindowList);
surface->u.window.ws.psOverlappedWindowList=NULL;
}
}
/*****************************************************************************
FUNCTION : RotateWindowCoordinates
DESCRIPTION: Adjusts the Xpos,YPos,Width and Height of the window surface based upon the Display Rotation
PARAMETERS : struct ws_native_window_tag psWindow
RETURNS : 0,90,270,180
*****************************************************************************/
void RotateWindowCoordinates(struct ws_native_window_tag *psWindow)
{
IMG_INT32 n32Temp;
switch(psWindow->ui32RotationAngle)
{
case 0:
// do nothing.
default:
break;
case 90:
// swap x and y axis
n32Temp=psWindow->ui32Height;
psWindow->ui32Height=psWindow->ui32Width;
psWindow->ui32Width=n32Temp;
n32Temp=psWindow->n32XPos;
psWindow->n32XPos=psWindow->n32YPos;
psWindow->n32YPos=psWindow->psPrimary_surface->ui32PixelHeight-(n32Temp+psWindow->ui32Height);
break;
case 180:
// Flip vertically and horizontally
psWindow->n32XPos=psWindow->psPrimary_surface->ui32PixelWidth-(psWindow->n32XPos+psWindow->ui32Width);
psWindow->n32YPos=psWindow->psPrimary_surface->ui32PixelHeight-(psWindow->n32YPos+psWindow->ui32Height);
break;
case 270:
n32Temp=psWindow->ui32Height;
psWindow->ui32Height=psWindow->ui32Width;
psWindow->ui32Width=n32Temp;
n32Temp=psWindow->n32XPos;
psWindow->n32XPos=psWindow->psPrimary_surface->ui32PixelWidth-(psWindow->n32YPos+psWindow->ui32Width);
psWindow->n32YPos=n32Temp;
break;
}
}
/*****************************************************************************
FUNCTION : UpdateSurfaceSize
DESCRIPTION: ReAllocates a surface and updates the relevant paramters
PARAMETERS : KEGL_DISPLAY *dpy, KEGL_SURFACE *surface, NativeWindowType nativeWindow
RETURNS : IMG_BOOL
*****************************************************************************/
IMG_BOOL UpdateSurfaceSize(KEGL_DISPLAY *dpy, KEGL_SURFACE *surface, NativeWindowType nativeWindow)
{
// first thing to do is to free the current buffer , update the window params then create a new buffer
HWND hWnd;
POINT pt;
RECT rc;
IMG_UINT32 ui32Flags=0;
PVRSRV_SURF *psCurrentRenderSurface = &surface->sCurrentRenderSurface;
hWnd=(HWND)nativeWindow;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -