⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wince_ws.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -