• gdi和dx比较研究


    gdi设备获取的源头, 同样是通过底层驱动来进行实现

    PGRAPHICS_DEVICE
    NTAPI
    EngpRegisterGraphicsDevice(
        PUNICODE_STRING pustrDeviceName,
        PUNICODE_STRING pustrDiplayDrivers,
        PUNICODE_STRING pustrDescription,
        PDEVMODEW pdmDefault)
    {
        PGRAPHICS_DEVICE pGraphicsDevice;
        PDEVICE_OBJECT pDeviceObject;
        PFILE_OBJECT pFileObject;
        NTSTATUS Status;
        PWSTR pwsz;
        ULONG i, cj, cModes = 0;
        BOOL bEnable = TRUE;
        PDEVMODEINFO pdminfo;
        PDEVMODEW pdm, pdmEnd;
        PLDEVOBJ pldev;

        DPRINT("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName);

        /* Allocate a GRAPHICS_DEVICE structure */
        pGraphicsDevice = ExAllocatePoolWithTag(PagedPool,
                                                sizeof(GRAPHICS_DEVICE),
                                                GDITAG_GDEVICE);
        if (!pGraphicsDevice)
        {
            DPRINT1("ExAllocatePoolWithTag failed\n");
            return NULL;
        }

        /* Try to open the driver */
        //    找到gdi设备获取的初始源头了,就是这里
        Status = IoGetDeviceObjectPointer(pustrDeviceName,
                                          FILE_READ_DATA | FILE_WRITE_DATA,
                                          &pFileObject,
                                          &pDeviceObject);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Could not open driver %wZ, 0x%lx\n", pustrDeviceName, Status);
            ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
            return NULL;
        }

        /* Enable the device */
        EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cj);

        /* Copy the device and file object pointers */
        pGraphicsDevice->DeviceObject = pDeviceObject;
        pGraphicsDevice->FileObject = pFileObject;

        /* Copy device name */
        wcsncpy(pGraphicsDevice->szNtDeviceName,
                pustrDeviceName->Buffer,
                sizeof(pGraphicsDevice->szNtDeviceName) / sizeof(WCHAR));

        /* Create a win device name (FIXME: virtual devices!) */
        swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (CHAR)giDevNum);

        /* Allocate a buffer for the strings */
        cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR);
        pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP);
        if (!pwsz)
        {
            DPRINT1("Could not allocate string buffer\n");
            ASSERT(FALSE); // FIXME
        }

        /* Copy display driver names */
        pGraphicsDevice->pDiplayDrivers = pwsz;
        RtlCopyMemory(pGraphicsDevice->pDiplayDrivers,
                      pustrDiplayDrivers->Buffer,
                      pustrDiplayDrivers->Length);

        /* Copy description */
        pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR);
        RtlCopyMemory(pGraphicsDevice->pwszDescription,
                      pustrDescription->Buffer,
                      pustrDescription->Length + sizeof(WCHAR));

        /* Initialize the pdevmodeInfo list and default index  */
        pGraphicsDevice->pdevmodeInfo = NULL;
        pGraphicsDevice->iDefaultMode = 0;
        pGraphicsDevice->iCurrentMode = 0;

        // FIXME: initialize state flags
        pGraphicsDevice->StateFlags = 0;

        /* Loop through the driver names
         * This is a REG_MULTI_SZ string */
        for (; *pwsz; pwsz += wcslen(pwsz) + 1)
        {
            DPRINT("trying driver: %ls\n", pwsz);
            /* Try to load the display driver */
            pldev = EngLoadImageEx(pwsz, LDEV_DEVICE_DISPLAY);
            if (!pldev)
            {
                DPRINT1("Could not load driver: '%ls'\n", pwsz);
                continue;
            }

            /* Get the mode list from the driver */
            pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject);
            if (!pdminfo)
            {
                DPRINT1("Could not get mode list for '%ls'\n", pwsz);
                continue;
            }

            /* Attach the mode info to the device */
            pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
            pGraphicsDevice->pdevmodeInfo = pdminfo;

            /* Count DEVMODEs */
            pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
            for (pdm = pdminfo->adevmode;
                 pdm + 1 <= pdmEnd;
                 pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
            {
                cModes++;
            }

            // FIXME: release the driver again until it's used?
        }

        if (!pGraphicsDevice->pdevmodeInfo || cModes == 0)
        {
            DPRINT1("No devmodes\n");
            ExFreePool(pGraphicsDevice);
            return NULL;
        }

        /* Allocate an index buffer */
        pGraphicsDevice->cDevModes = cModes;
        pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool,
                                                              cModes * sizeof(DEVMODEENTRY),
                                                              GDITAG_GDEVICE);
        if (!pGraphicsDevice->pDevModeList)
        {
            DPRINT1("No devmode list\n");
            ExFreePool(pGraphicsDevice);
            return NULL;
        }

        /* Loop through all DEVMODEINFOs */
        for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0;
             pdminfo;
             pdminfo = pdminfo->pdmiNext)
        {
            /* Calculate End of the DEVMODEs */
            pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);

            /* Loop through the DEVMODEs */
            for (pdm = pdminfo->adevmode;
                 pdm + 1 <= pdmEnd;
                 pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
            {
                /* Compare with the default entry */
                if (pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel &&
                    pdm->dmPelsWidth == pdmDefault->dmPelsWidth &&
                    pdm->dmPelsHeight == pdmDefault->dmPelsHeight &&
                    pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency)
                {
                    pGraphicsDevice->iDefaultMode = i;
                    pGraphicsDevice->iCurrentMode = i;
                    DPRINT("Found default entry: %ld '%ls'\n", i, pdm->dmDeviceName);
                }

                /* Initialize the entry */
                pGraphicsDevice->pDevModeList[i].dwFlags = 0;
                pGraphicsDevice->pDevModeList[i].pdm = pdm;
                i++;
            }
         }

        /* Lock loader */
        EngAcquireSemaphore(ghsemGraphicsDeviceList);

        /* Insert the device into the global list */
        pGraphicsDevice->pNextGraphicsDevice = gpGraphicsDeviceLast;
        gpGraphicsDeviceLast = pGraphicsDevice;
        if (!gpGraphicsDeviceFirst)
            gpGraphicsDeviceFirst = pGraphicsDevice;

        /* Increment device number */
        giDevNum++;

        /* Unlock loader */
        EngReleaseSemaphore(ghsemGraphicsDeviceList);
        DPRINT("Prepared %ld modes for %ls\n", cModes, pGraphicsDevice->pwszDescription);

        return pGraphicsDevice;
    }

    static BOOL IsDirectDrawSupported()

    dx9里面的这个功能原来是直接调用 dc里面的信息来返回啊,哈哈

    gdi和dx其实使用的是同一个显示驱动, 只不过由于gdi是专门为桌面系统而进行封装的, 对象游戏使用来说显然效率、易用性方面还大大不足, 于是根据用途不同就分成了gdi和dx的区别

  • 相关阅读:
    Windows server 2008 R2充当路由器实现网络的互联(转)
    sqlserver内存释放心得
    收藏一个好用的base64编解码网址
    最后一篇,说好的开源来了!
    python五子棋
    flask使用原生ajax、不使用表单(Form)上传文件
    使用keras的LSTM进行预测----实战练习
    keras神经网络三个例子
    【强化学习】用pandas 与 numpy 分别实现 q-learning, saras, saras(lambda)算法
    【转】【强化学习】Deep Q Network(DQN)算法详解
  • 原文地址:https://www.cnblogs.com/maifengqiang/p/2128667.html
Copyright © 2020-2023  润新知