附部分 mosquito 的源代码,主要包括 overlay 层格式与初始化:
/* * Telechips 8902 支持 2 层 overlay * 只能创建一层 YUYV 的 overlay (可以再创建一层 RGB overlay) * RGB 模式可以创建多个,模式与顺序没有不影响创建 */ static DDPIXELFORMAT ddpfOverlayFormats[] = { //{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','U','Y','V'),0,0,0,0,0}, // YUYV - Leo.Zheng Telechips 8902 可以支持 //{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0}, // UYVY - Leo.Zheng Telechips 8902:Create No.1 surface return: 0x88760218 // {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x7C00, 0x03e0, 0x001F, 0}, // 16-bit RGB 5:5:5 {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0xF800, 0x07e0, 0x001F, 0}, // 16-bit RGB 5:6:5 }; #define PF_TABLE_SIZE (sizeof(ddpfOverlayFormats) / sizeof(ddpfOverlayFormats[0])) //----------------------------------------------------------------------------- // Name: InitApp() // Desc: Do work required for every instance of the application: // Create the window, initialize data //----------------------------------------------------------------------------- static HRESULT InitApp(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; WNDCLASS wc; DDSURFACEDESC ddsd; DDCAPS ddcaps; HRESULT hRet; DWORD dwUpdateFlags = 0; DDOVERLAYFX ovfx; DEVMODE DevMode; // Check for rotation support by getting the rotation angles supported. memset(&DevMode, 0, sizeof(DevMode)); DevMode.dmSize = sizeof(DevMode); DevMode.dmFields = DM_DISPLAYQUERYORIENTATION; if(DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL)) { g_RotationAngles = DevMode.dmDisplayOrientation; } else { OutputDebugString(L"MOSQUITO: Device does not support any rotation modes. Rotation disabled."); g_RotationAngles = -1; } // Get the current rotation angle. memset(&DevMode, 0, sizeof (DevMode)); DevMode.dmSize = sizeof (DevMode); DevMode.dmFields = DM_DISPLAYORIENTATION; if (DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL)) { g_CurrentAngle = DevMode.dmDisplayOrientation; } else { OutputDebugString(L"MOSQUITO: Unable to read current rotation. Rotation disabled."); g_CurrentAngle = -1; } // Set up and register window class. ...... // Create the main DirectDraw object hRet = DirectDrawCreate(NULL, &g_pDD, NULL); if(hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("DirectDrawCreate FAILED")); // Get normal mode. hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL); if (hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("SetCooperativeLevel FAILED")); // Get a primary surface interface pointer (only needed for init.) memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("CreateSurface FAILED")); // See if we can support overlays. memset(&ddcaps, 0, sizeof(ddcaps)); ddcaps.dwSize = sizeof(ddcaps); hRet = g_pDD->GetCaps(&ddcaps, NULL); if (hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("GetCaps FAILED")); if (ddcaps.dwOverlayCaps == 0) return InitFail(hWnd, hRet, TEXT("Overlays are not supported in hardware!")); /* // Leo.Zheng Add if(!(capsDrv.dwCaps & DDCAPS_OVERLAY)) return FALSE; */ // Get alignment info to compute our overlay surface size. rs.left = 0; rs.top = 0; rs.right = BUG_WIDTH; rs.bottom = BUG_HEIGHT; if (ddcaps.dwAlignSizeSrc != 0) rs.right += rs.right % ddcaps.dwAlignSizeSrc; // Create the overlay flipping surface. We will attempt the pixel formats // in our table one at a time until we find one that jives. int i = 0; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP; ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT; ddsd.dwWidth = rs.right; ddsd.dwHeight = rs.bottom; ddsd.dwBackBufferCount = 1; do { // Leo.Zheng MStar 2521 只创建 16-bit RGB 5:6:5 成功; 创建 16-bit RGB 5:5:5 失败. ddsd.ddpfPixelFormat = ddpfOverlayFormats[i]; hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL); // Leo.Zheng 此处调用后引起使用 IOCtrl 显示在 LCD 上的消失 RETAILMSG(1,(L"[mosquito]Create No.%d surface return: 0x%X\r\n",i + 1,hRet)); }while(hRet != DD_OK && (++i < PF_TABLE_SIZE)); if(hRet != DD_OK) return InitFail(hWnd, hRet, TEXT("Unable to create overlay surface!")); // Load the images. if (LoadBugImages() != DD_OK) return InitFail(hWnd, hRet, TEXT("Unable to load images to overlay surface!")); // Finish setting up the overlay. int StretchFactor1000 = ddcaps.dwMinOverlayStretch > 1000 ? ddcaps.dwMinOverlayStretch : 1000; rd.left=0; rd.top=0; // Adding 999 takes care of integer truncation problems. rd.right = (rs.right * StretchFactor1000 + 999) / 1000; rd.bottom = rs.bottom * StretchFactor1000 / 1000; if (ddcaps.dwAlignSizeDest != 0) rd.right = (int)((rd.right + ddcaps.dwAlignSizeDest - 1)/ ddcaps.dwAlignSizeDest) * ddcaps.dwAlignSizeDest; // Set the flags we'll send to UpdateOverlay dwUpdateFlags = DDOVER_SHOW; // dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX; // Leo.Zheng DDOVER_DDFX WinCE 不支持 // Does the overlay hardware support source color keying? // If so, we can hide the black background around the image. // This probably won't work with YUV formats memset(&ovfx, 0, sizeof(ovfx)); ovfx.dwSize = sizeof(ovfx); if (ddcaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYSRC) // MStar2521 不支持 color key { dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE; // Create an overlay FX structure so we can specify a source color key. // This information is ignored if the DDOVER_SRCKEYOVERRIDE flag // isn't set. ovfx.dckSrcColorkey.dwColorSpaceLowValue=0; // black as the color key ovfx.dckSrcColorkey.dwColorSpaceHighValue=0; } else { RETAILMSG(1,(L"[mosquito]cannot support color key: 0x%X(0x%x)\r\n",ddcaps.dwOverlayCaps,DDOVERLAYCAPS_CKEYSRC)); } // Update the overlay parameters. hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, dwUpdateFlags, &ovfx); if (hRet != DD_OK) { // 在 MStar 2521 设备上运行第二个此程序实例时出错。 // 在 TeleChips 8902 设备上运行第三个此程序实例时出错。 return InitFail(hWnd, hRet, TEXT("Unable to show overlay surface: 0x%x!"),hRet); } // Set a bunch of position and velocity module vars. g_nOverlayXPos = 0; g_nOverlayYPos = 0; g_nOverlayXVel = RANDOM_VELOCITY(); g_nOverlayYVel = RANDOM_VELOCITY(); g_nOverlayWidth = rd.right - rd.left; g_nOverlayHeight = rd.bottom - rd.top; // Set the "destination position alignment" global so we won't have to // keep calling GetCaps() everytime we move the overlay surface. g_dwOverlayXPositionAlignment = ddcaps.dwAlignBoundaryDest; // Create a timer to flip the pages. if (TIMER_ID != SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL)) return InitFail(hWnd, hRet, TEXT("SetTimer FAILED")); return DD_OK; }