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

📄 dispdrvr.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
        Cleanup();
        return FALSE;
    }

    v_pClkRegs = (volatile XLLP_CLKMGR_T *)VirtualAllocCopyPhysical(sizeof(XLLP_CLKMGR_T),"DispDrvrInitialize : v_pClkRegs",(PVOID)(BULVERDE_BASE_REG_PA_CLKMGR));
    if (!v_pClkRegs)
    {
        Cleanup();
        return FALSE;
    }

    v_pGPIORegs = (volatile XLLP_GPIO_T *)VirtualAllocCopyPhysical(sizeof(XLLP_GPIO_T),"DispDrvrInitialize : v_pGPIORegs",(PVOID)(BULVERDE_BASE_REG_PA_GPIO));
    if (!v_pGPIORegs)
    {
        Cleanup();
        return FALSE;
    }

    frameDescriptorCh0fd1  = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_0_FRAME_DESCRIPTOR_BASE_VIRTUAL);
    frameDescriptorCh0fd2  = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_0_ALT_FRAME_DESCRIPTOR_BASE_VIRTUAL);
    frameDescriptorCh1     = (volatile LCD_FRAME_DESCRIPTOR *)(DMA_CHANNEL_1_FRAME_DESCRIPTOR_BASE_VIRTUAL);
    frameDescriptorPalette = (volatile LCD_FRAME_DESCRIPTOR *)(PALETTE_FRAME_DESCRIPTOR_BASE_VIRTUAL);
    v_pPaletteBuffer       = (volatile LCD_PALETTE *)(PALETTE_BUFFER_BASE_VIRTUAL);

    // Enter into Kernel mode to enable us to modify the section descriptor
    // so that we may set the bufferable bit.  This enables write coalescing
    // for frame buffer writes when using the section mapped address.
    //
    // GAPI uses the section mapped address always.


    // Now configure the frame buffer's section descriptor.
    // The function GetDescriptorAddress shows how to obtain the correct descriptor address.
    // This descriptor is one of two descriptors that map the the frame buffer.
    // The first descriptor found maps the cached virtual address, while the second
    // descriptor found maps the uncached virtual address.  We want to modify the
    // second descriptor, that which maps the uncached virtual address since the uncached virtual
    // address is the address we've chosen to use throughout the codebase.
    //
    // NOTE:
    // The section descriptor covers a 1MB section.  If the frame buffer ever exceeds 1MB
    // in size, you'll need to modify additional section descriptors.
    //

    // DDraw requires that the frame buffer pointer be in the shared memory space so
    // is can be shared between processes.
    {
        PVOID  pPhysAddr;
        size_t offset;
        size_t size;

        pPhysAddr  = (PVOID)(FRAME_BUFFER_0_BASE_PHYSICAL);
        size       = frameBufferSize * NUM_FRAME_BUFFERS;
        offset     = (unsigned)pPhysAddr & (0x1000 - 1);
        size      += (offset ? 0x1000 : 0);
        pPhysAddr  = (PVOID)((unsigned)pPhysAddr - offset);

        if (size >= 1024*1024*2)
        {
            gFrameBuffer = (PBYTE)VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);
        }
        else
        {
            gFrameBuffer = (PBYTE)VirtualAlloc(NULL, 1024*1024*2, MEM_RESERVE, PAGE_NOACCESS);
        }

        if (!VirtualCopy(gFrameBuffer, (LPVOID)((unsigned long)pPhysAddr >> 8), size, (PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL)))
        {
            gFrameBuffer = NULL;
        }
        else
        {
            gFrameBuffer += offset;
        }
    }

    if (!gFrameBuffer)
    {
        Cleanup();
        return FALSE;
    }

    if (bDoRotation)
    {
        // if rotating the display, the actual frame buffer should be configured as bufferable for max write performance into the frame buffer.
        VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 4, 4, NULL);
    }
    else
    {
        // if not rotating the dispay, we can draw directly into the frame buffer, and use write-through cache mode to improve frame buffer throughput
        VirtualSetAttributes(gFrameBuffer, frameBufferSize*NUM_FRAME_BUFFERS, 8, 8, NULL);
    }

    if (g_fEnableDMASourceSwap) {
        PVOID  pPhysAddr;
        size_t offset;
        size_t size;

        pPhysAddr  = (PVOID)(g_DisplayBlackBasePhysical);
        size       = FRAME_BUFFER_SIZE;
        offset     = (unsigned)pPhysAddr & (0x1000 - 1);
        size      += (offset ? 0x1000 : 0);
        pPhysAddr  = (PVOID)((unsigned)pPhysAddr - offset);

        gBlackFrameBuffer = (PBYTE)VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);

        if (!VirtualCopy(gBlackFrameBuffer, (LPVOID)((unsigned long)pPhysAddr >> 8), size, (PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL)))
        {
            gBlackFrameBuffer = NULL;
        }
        else
        {
            gBlackFrameBuffer += offset;
        }

        if(!gBlackFrameBuffer) {
            Cleanup();
            return FALSE;
        }
    }

    return TRUE;
}


// Free all the global memory resources
void Cleanup(void)
{
    DMA_ADAPTER_OBJECT Adapter;
    PHYSICAL_ADDRESS   PhysAddr;

    DMA_ADAPTER_OBJECT AdapterBlackScreen;
    PHYSICAL_ADDRESS   PhysAddrBlackScreen;

    if (v_pLcdRegs)
    {
        VirtualFree((PVOID)v_pLcdRegs,0,MEM_RELEASE);
        v_pLcdRegs = NULL;
    }

    if (v_pClkRegs)
    {
        VirtualFree((PVOID)v_pClkRegs,0,MEM_RELEASE);
        v_pLcdRegs = NULL;
    }

    if (v_pGPIORegs)
    {
        VirtualFree((PVOID)v_pGPIORegs,0,MEM_RELEASE);
        v_pGPIORegs = NULL;
    }

    if (gFrameBuffer)
    {
        VirtualFree((PVOID)gFrameBuffer,0,MEM_RELEASE);
        gFrameBuffer = NULL;
    }

    if (gBlackFrameBuffer)
    {
        VirtualFree((PVOID)gBlackFrameBuffer,0,MEM_RELEASE);
        gBlackFrameBuffer = NULL;
    }

    if (frameDescriptorCh2_YCbCr_Y)
    {
        VirtualFree((PVOID)frameDescriptorCh2_YCbCr_Y,0,MEM_RELEASE);
        frameDescriptorCh2_YCbCr_Y = NULL;
    }

    if (frameDescriptorCh3_YCbCr_Cb)
    {
        VirtualFree((PVOID)frameDescriptorCh3_YCbCr_Cb,0,MEM_RELEASE);
        frameDescriptorCh3_YCbCr_Cb = NULL;
    }

    if (frameDescriptorCh4_YCbCr_Cr)
    {
        VirtualFree((PVOID)frameDescriptorCh4_YCbCr_Cr,0,MEM_RELEASE);
        frameDescriptorCh4_YCbCr_Cr = NULL;
    }

    Adapter.ObjectSize    = sizeof (DMA_ADAPTER_OBJECT);
    Adapter.InterfaceType = Internal;
    Adapter.BusNumber     = 0;

    PhysAddr.HighPart = 0;
    PhysAddr.LowPart  = g_DisplayBasePhysical;

    HalFreeCommonBuffer(&Adapter, DISPLAY_BUFFER_SIZE, PhysAddr, (void *)g_DisplayBaseVirtual, FALSE);

    if( g_fEnableDMASourceSwap && g_DisplayBlackBaseVirtual)
    {
        AdapterBlackScreen.ObjectSize    = sizeof (DMA_ADAPTER_OBJECT);
        AdapterBlackScreen.InterfaceType = Internal;
        AdapterBlackScreen.BusNumber     = 0;

        PhysAddrBlackScreen.HighPart = 0;
        PhysAddrBlackScreen.LowPart  = g_DisplayBlackBasePhysical;

        HalFreeCommonBuffer(&AdapterBlackScreen, FRAME_BUFFER_SIZE, PhysAddrBlackScreen, (void *)g_DisplayBlackBaseVirtual, FALSE);
    }
}

void DispDrvrPowerHandler(BOOL    bOff)
{

    if(bOff)
    {

        if( g_fEnableDMASourceSwap )
        {
            // Before turning off, lets switch out the DMA's source address
            // Old source address: FRAME_BUFFER_BASE_PHYSICAL (in virtual land gFrameBuffer)
            // New source address: g_DisplayBlackBasePhysical (in virtual land g_DisplayBlackBaseVirtual)

            // So when we go into user idle, GWES keeps writing to the original buffer,
            // but DMA updates the LCD with the black buffer

            // Swap the DMA pointer
            XllpLCD._FRAME_BUFFER_BASE_PHYSICAL = g_DisplayBlackBasePhysical;
            XllpLCDInit(&XllpLCD);  //Let XllpLCDInit update DMA for us
            XllpOstDelayMilliSeconds((XLLP_OST_T *)v_pOSTRegs, 1);
        }

        XllpLCDSuspend(&XllpLCD, Suspend_Graceful);
    }
    else
    {
        if( g_fEnableDMASourceSwap )
        {
            // Swap back the DMA pointer
            XllpLCD._FRAME_BUFFER_BASE_PHYSICAL = FRAME_BUFFER_BASE_PHYSICAL;
            XllpLCDInit(&XllpLCD);
            XllpOstDelayMilliSeconds((XLLP_OST_T *)v_pOSTRegs, 1);
        }

        XllpLCDResume(&XllpLCD);
    }
}


void ClearFrameBuffer(unsigned * fbp, BOOL color)
{
    DWORD i;

    for(i = 0; i < (DispDrvr_cxScreen * DispDrvr_cyScreen * (bpp / 8) / 4); i++)
    {
        if (color)
        {
            *fbp++ = 0xFFFFFFFF;    // Ones turn it white
        }
        else
        {
            *fbp++ = 0x00000000;    // Zeros turn it black
        }
    }
}

//**********************************************************************
//
//DispDrvrContrastControl:
//
//    Modify the contrast according to the Cmd parameter.
// Not supported
//

BOOL DispDrvrContrastControl(int Cmd,DWORD *pValue)
{
    // currently does not support changing contrast in software.
    return TRUE;
}

void DirtyRectDumpPortraitLoop_C(BYTE    *pDstBuf, BYTE  *pSrcBuf, DWORD    yTop, DWORD yBottom,
                                 DWORD srcWidthB, DWORD    bytesPerRow, DWORD bytesPerPixel,
                                 DWORD srcMarginWidth, DWORD dstMarginWidth)
{
    DWORD row;
    DWORD i;
    DWORD j;

    if ( bytesPerPixel != 2 )
    {
        //not 16-bit
        for (i = 0; i < srcWidthB / bytesPerPixel; i++)
        {
            for (row = yTop; row < yBottom; row++)
            {
                for (j = 0; j < bytesPerPixel; j++)
                {
                    *pDstBuf++ = *(pSrcBuf + j);
                }

                pSrcBuf -= bytesPerRow;
            }

            pDstBuf += dstMarginWidth;
            pSrcBuf += srcMarginWidth + 2;
        }
    }
    else
    {
        WORD * pwDst;
        WORD * pwSrc;
        int    rowLen;

        //16-bit
        srcWidthB >>= 1;

        pwDst = (WORD *)pDstBuf;
        pwSrc = (WORD *)pSrcBuf;

        //first row for pwSrc, then column for pwDst
        rowLen = yBottom - yTop;

#ifndef _OPT_ASM
        bytesPerRow    >>= 1;
        dstMarginWidth >>= 1;
        srcMarginWidth >>= 1;

        for (i = 0; i < srcWidthB; i++)
        {
            for (row = 0; row < (rowLen >> 2); row++)
            {
                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;

                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;

                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;

                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;
            }

            for (row = 0; row < (rowLen & 0x3); row++)
            {
                *pwDst++  = *pwSrc;
                pwSrc    -= bytesPerRow;
            }

            pwDst += dstMarginWidth;
            pwSrc += srcMarginWidth + 1;
        }
#else
        dirtyRectDump_core_ASM(pwSrc, pwDst, rowLen, srcWidthB, bytesPerRow, srcMarginWidth, dstMarginWidth);
#endif
    }
}

void DispDrvrDirtyRectDump(LPCRECT prc)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -