📄 sa2video.cpp
字号:
/*
** INTEL CONFIDENTIAL
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors. Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
*/
#include <windows.h>
#include <types.h>
#include <drv_glob.h>
#include <nkintr.h>
#include <oalintr.h>
#include "bvd1.h"
#include "bcr.h"
#include "precomp.h"
#include "cursor.h"
#include "xllp_lcd.h"
#include "camera.h"
#ifndef BSP_NOIPM
#include "IPM_DrvCommon.h"
#endif
extern "C" PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
extern "C" void DispDrvrSetPalette(const PALETTEENTRY *,USHORT,USHORT);
extern "C" void *gFrameBuffer;
extern "C" volatile LCD_PALETTE *v_pPaletteBuffer;
extern "C" BOOL bDoRotation;
extern "C" void ScrollBuffer(int direction);
extern "C" void DispDrvrDirtyRectDump2(LPCRECT prc,DWORD color);
extern "C" void DispDrvrDirtyRectDump_rectfill(LPCRECT prc,DWORD color);
extern "C" BOOL gDrawCursorFlag;
extern "C" XLLP_LCD_T XllpLCD;
extern "C" void Overlay2_Enable(P_XLLP_OVERLAY_T pXllpOverlay);
extern "C" void Overlay2_Disable(P_XLLP_OVERLAY_T pXllpOverlay);
extern "C" void Overlay2_DMA_Length(P_XLLP_OVERLAY_T pXllpOverlay);
extern "C" volatile LCD_FRAME_DESCRIPTOR *frameDescriptorCh2_YCbCr_Y;
extern "C" volatile LCD_FRAME_DESCRIPTOR *frameDescriptorCh3_YCbCr_Cb;
extern "C" volatile LCD_FRAME_DESCRIPTOR *frameDescriptorCh4_YCbCr_Cr;
extern "C" volatile unsigned int *pOSCR;
extern "C" volatile BLR_REGS *v_pBoardLevelRegister;
extern "C" void CameraInterruptHandler(void);
extern "C" volatile unsigned int * v_pCameraDMABuffers;
extern "C" void ApplicationImageProcessingHandler(void);
extern "C" void msWait(unsigned int);
extern "C" void CameraStartVideoCapture(void);
extern "C" void CameraStopVideoCapture(void);
extern "C" int CameraInit(P_CAMERA_APP_T pCameraApp);
extern "C" void CameraCaptureStillImage(void);
extern "C" void CameraReleaseFrame(P_CAMERA_APP_T pCameraApp);
extern "C" HANDLE hIntEventKnown;
extern "C" HANDLE hIntEvent;
volatile LCDRegs *v_pLcdRegs = NULL;
volatile XLLP_GPIO_T *v_pGPIORegs = NULL;
HANDLE hCameraFrameComplete;
BOOL bCapturingVideo = TRUE;
#define NUM_FRAME_BUFFERS 2
#ifdef DD_ENABLE
DDGPE *pGPE = (DDGPE *)NULL;
#else // DD_ENABLE
static GPE *pGPE = (GPE *)NULL;
#endif // DD_ENABLE
// These masks are used to extract the color component for a 16 bit pixel value. 5 bits red, 6 bits green, 5 bits blue.
ulong BitMasks[] = {0xF800, 0x07E0, 0x001F};
INSTANTIATE_GPE_ZONES(0x3,"GDI Driver","unused1","unused2") /* Start with Errors, warnings, and temporary messages */
BOOL APIENTRY GPEEnableDriver(
ULONG iEngineVersion,
ULONG cj,
DRVENABLEDATA *pded,
PENGCALLBACKS pEngCallbacks);
BOOL APIENTRY DrvEnableDriver(
ULONG iEngineVersion,
ULONG cj,
DRVENABLEDATA *data,
PENGCALLBACKS pEngineCallbacks)
{
GPEEnableDriver(iEngineVersion,cj,data,pEngineCallbacks);
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////
#define CAMERA_EVENT_NAME _T("CameraFrameComplete")
#define DMA_CHANNEL_0 _T("DMA_CHANNEL_0")
BOOL SA2Video::IsrThreadProc()
{
#ifdef FRAME_RATE_COUNTER
int count = 0;
int frame = 0;
unsigned int prev;
unsigned int current;
unsigned int delta;
unsigned int fps;
#endif
CeSetThreadPriority(GetCurrentThread(),1);
hCameraFrameComplete = CreateEvent(NULL,FALSE,FALSE,CAMERA_EVENT_NAME);
WaitForSingleObject(hIntEventKnown, INFINITE);
#ifdef FRAME_RATE_COUNTER
prev = current = *pOSCR;
delta = 1;
fps = 0;
#endif
while (1)
{
WaitForSingleObject(hIntEvent,INFINITE);
CameraInterruptHandler();
SetEvent(hCameraFrameComplete);
#ifdef FRAME_RATE_COUNTER
current = *pOSCR;
delta = current - prev;
// if (current < prev)
// {
// delta = current + (0xFFFFFFFF - prev);
// }
prev = current;
fps = 3250000 / delta;
v_pBoardLevelRegister->hex_led = (count++ << 16) | fps;
#endif
}
return TRUE;
}
DWORD IsrThread(SA2Video *p)
{
p->IsrThreadProc();
return 0;
}
BOOL SA2Video::IsrThreadStart()
{
HANDLE hthrd;
hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)IsrThread,this,0,NULL);
CloseHandle(hthrd);
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////
// Main entry point for a GPE-compliant driver
GPE *GetGPE(void)
{
if(!pGPE) {
pGPE = new SA2Video();
}
return pGPE;
}
VOID SA2Video::PowerHandler(BOOL bOff)
{
//新增调试信息
//RETAILMSG(1,(TEXT("Enter PowerHandler\r\n")));
DispDrvrPowerHandler(bOff);
}
SA2Video::SA2Video(void)
{
DEBUGMSG(GPE_ZONE_INIT,(TEXT("SA2Video::SA2Video\r\n")));
//RETAILMSG(1,(TEXT("Display Driver SA2Video pri\r\n")));
// Determine the display type
// Setup the LCD controller for that display
// Power up and enable the display
DispDrvrInitialize();
m_ModeInfo.modeId = 0;
m_ModeInfo.width = m_nScreenWidth = DispDrvr_cxScreen;
m_ModeInfo.height = m_nScreenHeight = DispDrvr_cyScreen;
m_ModeInfo.Bpp = bpp;
m_ModeInfo.frequency = 60;
m_ModeInfo.format = bpp == 8 ? gpe8Bpp : gpe16Bpp;
m_pMode = &m_ModeInfo;
#ifdef DD_ENABLE
m_pModeEx.modeInfo.modeId = 0;
m_pModeEx.modeInfo.width = m_nScreenWidth = DispDrvr_cxScreen;
m_pModeEx.modeInfo.height = m_nScreenHeight = DispDrvr_cyScreen;
m_pModeEx.modeInfo.Bpp = bpp;
m_pModeEx.modeInfo.frequency = 60;
m_pModeEx.modeInfo.format = bpp == 8 ? gpe8Bpp : gpe16Bpp;
#endif
if (bDoRotation)
{
// The GPE will allocate a virtual frame buffer and draw to that.
// The driver will copy this virtual frame buffer to the physical frame buffer
// using the dirty rectangle algorithm.
#ifdef DD_ENABLE
m_pPrimarySurface = new DDGPESurf(m_nScreenWidth,m_nScreenHeight,m_ModeInfo.format);
#else
m_pPrimarySurface = new GPESurf(m_nScreenWidth,m_nScreenHeight,m_ModeInfo.format);
#endif
// Clear the video memory
memset(m_pPrimarySurface->Buffer(),0,m_pPrimarySurface->Height()*m_pPrimarySurface->Width());
DispDrvrSetDibBuffer(m_pPrimarySurface->Buffer());
} else
{
// The GPE will draw directly to the physical frame buffer.
m_pVirtualFrameBuffer = gFrameBuffer;
#ifdef DD_ENABLE
m_pPrimarySurface = new DDGPESurf(m_nScreenWidth,m_nScreenHeight,m_pVirtualFrameBuffer,
DispDrvr_cdwStride,m_ModeInfo.format);
#else
m_pPrimarySurface = new GPESurf(m_nScreenWidth,m_nScreenHeight,m_pVirtualFrameBuffer,
DispDrvr_cdwStride,m_ModeInfo.format);
#endif
}
m_VirtualFrameBuffer = (ULONG)FRAME_BUFFER_0_BASE_VIRTUAL;
//RETAILMSG(1,(TEXT("Display Driver SA2Video comeplete\r\n")));
IsrThreadStart();
}
SCODE SA2Video::SetMode(int modeId,HPALETTE *pPalette)
{
if(modeId != 0)
return E_INVALIDARG;
// Here, we use EngCreatePalette to create a palette that that MGDI will use as a
// stock palette
if(pPalette) {
*pPalette = EngCreatePalette(PAL_BITFIELDS,0,NULL,BitMasks[0],BitMasks[1],BitMasks[2]);
}
return S_OK;
}
SCODE SA2Video::GetModeInfo(GPEMode *pMode,int modeNumber)
{
if(modeNumber != 0)
return E_INVALIDARG;
*pMode = m_ModeInfo;
return S_OK;
}
int SA2Video::NumModes(void)
{
return 1;
}
SCODE SA2Video::SetPointerShape(GPESurf *pMask,GPESurf *pColorSurf,int xHot,int yHot,int cX,int cY)
{
int row,colByte;
BYTE *pAND;
BYTE *pXOR;
BYTE bitMask;
unsigned i;
if (!pMask) { // Turn off the cursor.
memset((BYTE *)gCursorMask,0xFF,sizeof(gCursorMask));
memset((BYTE *)gCursorData,0x00,sizeof(gCursorData));
} else
{
i=0;
for (row=0;row<cY;row++)
{
for (colByte=0;colByte<cX/8;colByte++)
{
pAND=(unsigned char *)pMask->Buffer()+(row*pMask->Stride())+colByte;
pXOR=pAND+(cY*pMask->Stride());
for (bitMask=0x0080;bitMask;bitMask>>=1)
{
gCursorMask[i] = (*pAND & bitMask) ? 0xFFFF : 0x0000;
gCursorData[i] = (*pXOR & bitMask) ? 0xFFFF : 0x0000;
i++;
}
}
}
gxHot=xHot;
gyHot=yHot;
}
return S_OK;
}
SCODE SA2Video::MovePointer(int xPosition,int yPosition)
{
if(xPosition == -1)
{
// disable cursor
DispDrvrMoveCursor(DispDrvr_cxScreen,DispDrvr_cyScreen);
} else
{
// enable cursor
DispDrvrMoveCursor(xPosition,yPosition);
}
return S_OK;
}
void SA2Video::WaitForNotBusy(void)
{
return;
}
int SA2Video::IsBusy(void)
{
return 0; // Never busy as there is no acceleration
}
void SA2Video::GetPhysicalVideoMemory(unsigned long *pPhysicalMemoryBase,unsigned long *pVideoMemorySize)
{
*pPhysicalMemoryBase = (ULONG)FRAME_BUFFER_0_BASE_VIRTUAL;
*pVideoMemorySize = DispDrvr_cdwStride * DispDrvr_cyScreen;
}
SCODE SA2Video::AllocSurface(GPESurf **surface,INT width,INT height,EGPEFormat format,INT surfaceFlags)
{
if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY) {
// Can't allocate video-memory surfaces in the SA2Video environment
return E_OUTOFMEMORY;
}
// Allocate from system memory
*surface = new GPESurf(width,height,format);
if (*surface != NULL) {
// Check that the bits were allocated succesfully
if (((*surface)->Buffer()) == NULL)
{
delete *surface;
} else
{
return S_OK;
}
}
return E_OUTOFMEMORY;
}
SCODE SA2Video::WrappedEmulatedLine(GPELineParms *pParms)
{
SCODE code = EmulatedLine(pParms); // Draw to the backup framebuffer
if(FAILED(code))
return code;
if (bDoRotation)
{
// Now, calculate the dirty-rect to refresh to the actual hardware
RECT bounds;
int N_plus_1; // Minor length of bounding rect + 1
if( pParms->dN) // The line has a diagonal component (we'll refresh the bounding rect)
N_plus_1 = 2 + ((pParms->cPels * pParms->dN) / pParms->dM);
else
N_plus_1 = 1;
switch(pParms->iDir) {
case 0:
bounds.left = pParms->xStart;
bounds.top = pParms->yStart;
bounds.right = pParms->xStart + pParms->cPels + 1;
bounds.bottom = bounds.top + N_plus_1;
break;
case 1:
bounds.left = pParms->xStart;
bounds.top = pParms->yStart;
bounds.bottom = pParms->yStart + pParms->cPels + 1;
bounds.right = bounds.left + N_plus_1;
break;
case 2:
bounds.right = pParms->xStart + 1;
bounds.top = pParms->yStart;
bounds.bottom = pParms->yStart + pParms->cPels + 1;
bounds.left = bounds.right - N_plus_1;
break;
case 3:
bounds.right = pParms->xStart + 1;
bounds.top = pParms->yStart;
bounds.left = pParms->xStart - pParms->cPels;
bounds.bottom = bounds.top + N_plus_1;
break;
case 4:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -