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

📄 swapchain.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
        /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying */
        IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer;
        IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
        BOOL frontuptodate = front->Flags & SFLAG_INSYSMEM;
        BOOL backuptodate = back->Flags & SFLAG_INSYSMEM;

        if(front->resource.size == back->resource.size) {
            /* Flip the DC */
            {
                HDC tmp;
                tmp = front->hDC;
                front->hDC = back->hDC;
                back->hDC = tmp;
            }

            /* Flip the DIBsection */
            {
                HBITMAP tmp;
                BOOL hasDib = front->Flags & SFLAG_DIBSECTION;
                tmp = front->dib.DIBsection;
                front->dib.DIBsection = back->dib.DIBsection;
                back->dib.DIBsection = tmp;

                if(back->Flags & SFLAG_DIBSECTION) front->Flags |= SFLAG_DIBSECTION;
                else front->Flags &= ~SFLAG_DIBSECTION;
                if(hasDib) back->Flags |= SFLAG_DIBSECTION;
                else back->Flags &= ~SFLAG_DIBSECTION;
            }

            /* Flip the surface data */
            {
                void* tmp;

                tmp = front->dib.bitmap_data;
                front->dib.bitmap_data = back->dib.bitmap_data;
                back->dib.bitmap_data = tmp;

                tmp = front->resource.allocatedMemory;
                front->resource.allocatedMemory = back->resource.allocatedMemory;
                back->resource.allocatedMemory = tmp;
            }

            /* client_memory should not be different, but just in case */
            {
                BOOL tmp;
                tmp = front->dib.client_memory;
                front->dib.client_memory = back->dib.client_memory;
                back->dib.client_memory = tmp;
            }
            if(frontuptodate) back->Flags |= SFLAG_INSYSMEM;
            else back->Flags &= ~SFLAG_INSYSMEM;
            if(backuptodate) front->Flags |= SFLAG_INSYSMEM;
            else front->Flags &= ~SFLAG_INSYSMEM;
        } else {
            back->Flags &= ~SFLAG_INSYSMEM;
            front->Flags &= ~SFLAG_INSYSMEM;
        }
    }

    if(This->presentParms.PresentationInterval != WINED3DPRESENT_INTERVAL_IMMEDIATE && GL_SUPPORT(SGI_VIDEO_SYNC)) {
        retval = GL_EXTCALL(glXGetVideoSyncSGI(&sync));
        if(retval != 0) {
            ERR("glXGetVideoSyncSGI failed(retval = %d\n", retval);
        }

        switch(This->presentParms.PresentationInterval) {
            case WINED3DPRESENT_INTERVAL_DEFAULT:
            case WINED3DPRESENT_INTERVAL_ONE:
                if(sync <= This->vSyncCounter) {
                    retval = GL_EXTCALL(glXWaitVideoSyncSGI(1, 0, &This->vSyncCounter));
                } else {
                    This->vSyncCounter = sync;
                }
                break;
            case WINED3DPRESENT_INTERVAL_TWO:
                if(sync <= This->vSyncCounter + 1) {
                    retval = GL_EXTCALL(glXWaitVideoSyncSGI(2, This->vSyncCounter & 0x1, &This->vSyncCounter));
                } else {
                    This->vSyncCounter = sync;
                }
                break;
            case WINED3DPRESENT_INTERVAL_THREE:
                if(sync <= This->vSyncCounter + 2) {
                    retval = GL_EXTCALL(glXWaitVideoSyncSGI(3, This->vSyncCounter % 0x3, &This->vSyncCounter));
                } else {
                    This->vSyncCounter = sync;
                }
                break;
            case WINED3DPRESENT_INTERVAL_FOUR:
                if(sync <= This->vSyncCounter + 3) {
                    retval = GL_EXTCALL(glXWaitVideoSyncSGI(4, This->vSyncCounter & 0x3, &This->vSyncCounter));
                } else {
                    This->vSyncCounter = sync;
                }
                break;
            default:
                FIXME("Unknown presentation interval %08x\n", This->presentParms.PresentationInterval);
        }
    }

    TRACE("returning\n");
    return WINED3D_OK;
}

static HRESULT WINAPI IWineD3DSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *pDestSurface) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    POINT start;

    TRACE("(%p) : iface(%p) pDestSurface(%p)\n", This, iface, pDestSurface);

    start.x = 0;
    start.y = 0;

    if (This->presentParms.Windowed) {
        MapWindowPoints(This->win_handle, NULL, &start, 1);
    }

    IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, This->frontBuffer, NULL, 0);
    return WINED3D_OK;
}

static HRESULT WINAPI IWineD3DSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, UINT iBackBuffer, WINED3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) {

    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;

    if (iBackBuffer > This->presentParms.BackBufferCount - 1) {
        TRACE("Back buffer count out of range\n");
        /* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it here
         * in wined3d to avoid problems in other libs
         */
        *ppBackBuffer = NULL;
        return WINED3DERR_INVALIDCALL;
    }

    *ppBackBuffer = This->backBuffer[iBackBuffer];
    TRACE("(%p) : BackBuf %d Type %d  returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);

    /* Note inc ref on returned surface */
    if(*ppBackBuffer) IWineD3DSurface_AddRef(*ppBackBuffer);
    return WINED3D_OK;

}

static HRESULT WINAPI IWineD3DSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *iface, WINED3DRASTER_STATUS *pRasterStatus) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    static BOOL showFixmes = TRUE;
    pRasterStatus->InVBlank = TRUE;
    pRasterStatus->ScanLine = 0;
    /* No openGL equivalent */
    if(showFixmes) {
        FIXME("(%p) : stub (once)\n", This);
        showFixmes = FALSE;
    }
    return WINED3D_OK;
}

static HRESULT WINAPI IWineD3DSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE*pMode) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    HDC                 hdc;
    int                 bpp = 0;

    pMode->Width        = GetSystemMetrics(SM_CXSCREEN);
    pMode->Height       = GetSystemMetrics(SM_CYSCREEN);
    pMode->RefreshRate  = 85; /* FIXME: How to identify? */

    hdc = GetDC(0);
    bpp = GetDeviceCaps(hdc, BITSPIXEL);
    ReleaseDC(0, hdc);

    switch (bpp) {
    case  8: pMode->Format       = WINED3DFMT_R8G8B8; break;
    case 16: pMode->Format       = WINED3DFMT_R5G6B5; break;
    case 24: /*pMode->Format       = WINED3DFMT_R8G8B8; break; */ /* 32bpp and 24bpp can be aliased for X */
    case 32: pMode->Format       = WINED3DFMT_A8R8G8B8; break;
    default:
       FIXME("Unrecognized display mode format\n");
       pMode->Format       = WINED3DFMT_UNKNOWN;
    }

    TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
    pMode->Format, debug_d3dformat(pMode->Format));
    return WINED3D_OK;
}

static HRESULT WINAPI IWineD3DSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;

    *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;

    /* Note  Calling this method will increase the internal reference count
       on the IDirect3DDevice9 interface. */
    IWineD3DDevice_AddRef(*ppDevice);
    TRACE("(%p) : returning %p\n", This, *ppDevice);
    return WINED3D_OK;
}

static HRESULT WINAPI IWineD3DSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) {
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    TRACE("(%p)\n", This);

    *pPresentationParameters = This->presentParms;

    return WINED3D_OK;
}

static HRESULT WINAPI IWineD3DSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST WINED3DGAMMARAMP *pRamp){

    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    HDC hDC;
    TRACE("(%p) : pRamp@%p flags(%d)\n", This, pRamp, Flags);
    hDC = GetDC(This->win_handle);
    SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
    ReleaseDC(This->win_handle, hDC);
    return WINED3D_OK;

}

static HRESULT WINAPI IWineD3DSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp){

    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
    HDC hDC;
    TRACE("(%p) : pRamp@%p\n", This, pRamp);
    hDC = GetDC(This->win_handle);
    GetDeviceGammaRamp(hDC, pRamp);
    ReleaseDC(This->win_handle, hDC);
    return WINED3D_OK;

}


const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
{
    /* IUnknown */
    IWineD3DSwapChainImpl_QueryInterface,
    IWineD3DSwapChainImpl_AddRef,
    IWineD3DSwapChainImpl_Release,
    /* IWineD3DSwapChain */
    IWineD3DSwapChainImpl_GetParent,
    IWineD3DSwapChainImpl_Destroy,
    IWineD3DSwapChainImpl_GetDevice,
    IWineD3DSwapChainImpl_Present,
    IWineD3DSwapChainImpl_GetFrontBufferData,
    IWineD3DSwapChainImpl_GetBackBuffer,
    IWineD3DSwapChainImpl_GetRasterStatus,
    IWineD3DSwapChainImpl_GetDisplayMode,
    IWineD3DSwapChainImpl_GetPresentParameters,
    IWineD3DSwapChainImpl_SetGammaRamp,
    IWineD3DSwapChainImpl_GetGammaRamp
};

WineD3DContext *IWineD3DSwapChainImpl_CreateContextForThread(IWineD3DSwapChain *iface) {
    WineD3DContext *ctx;
    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
    WineD3DContext **newArray;

    TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId());

    ctx = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer,
                        This->context[0]->win_handle, FALSE /* pbuffer */, &This->presentParms);
    if(!ctx) {
        ERR("Failed to create a new context for the swapchain\n");
        return NULL;
    }

    newArray = HeapAlloc(GetProcessHeap(), 0, sizeof(*newArray) * This->num_contexts + 1);
    if(!newArray) {
        ERR("Out of memory when trying to allocate a new context array\n");
        DestroyContext(This->wineD3DDevice, ctx);
        return NULL;
    }
    memcpy(newArray, This->context, sizeof(*newArray) * This->num_contexts);
    HeapFree(GetProcessHeap(), 0, This->context);
    newArray[This->num_contexts] = ctx;
    This->context = newArray;
    This->num_contexts++;

    TRACE("Returning context %p\n", ctx);
    return ctx;
}

⌨️ 快捷键说明

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