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

📄 surface.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
            checkGLcall("glDrawBuffer(myDevice->offscreenBuffer)");
        } else if(swapchain->backBuffer) {
            glDrawBuffer(GL_BACK);
            checkGLcall("glDrawBuffer(GL_BACK)");
        } else {
            glDrawBuffer(GL_FRONT);
            checkGLcall("glDrawBuffer(GL_FRONT)");
        }
        LEAVE_GL();

        This->dirtyRect.left   = This->currentDesc.Width;
        This->dirtyRect.top    = This->currentDesc.Height;
        This->dirtyRect.right  = 0;
        This->dirtyRect.bottom = 0;
        This->Flags |= SFLAG_INDRAWABLE;
    } else if(iface == myDevice->stencilBufferTarget) {
        FIXME("Depth Stencil buffer locking is not implemented\n");
    } else {
        /* The rest should be a normal texture */
        IWineD3DBaseTextureImpl *impl;
        /* Check if the texture is bound, if yes dirtify the sampler to force a re-upload of the texture
         * Can't load the texture here because PreLoad may destroy and recreate the gl texture, so sampler
         * states need resetting
         */
        if(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&impl) == WINED3D_OK) {
            if(impl->baseTexture.bindCount) {
                IWineD3DDeviceImpl_MarkStateDirty(myDevice, STATE_SAMPLER(impl->baseTexture.sampler));
            }
            IWineD3DBaseTexture_Release((IWineD3DBaseTexture *) impl);
        }
    }

    unlock_end:
    This->Flags &= ~SFLAG_LOCKED;
    memset(&This->lockedRect, 0, sizeof(RECT));
    return WINED3D_OK;
}

HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
    WINED3DLOCKED_RECT lock;
    UINT usage;
    BITMAPINFO* b_info;
    HDC ddc;
    DWORD *masks;
    HRESULT hr;
    RGBQUAD col[256];
    const StaticPixelFormatDesc *formatEntry = getFormatDescEntry(This->resource.format, NULL, NULL);

    TRACE("(%p)->(%p)\n",This,pHDC);

    if(This->Flags & SFLAG_USERPTR) {
        ERR("Not supported on surfaces with an application-provided surfaces\n");
        return WINEDDERR_NODC;
    }

    /* Give more detailed info for ddraw */
    if (This->Flags & SFLAG_DCINUSE)
        return WINEDDERR_DCALREADYCREATED;

    /* Can't GetDC if the surface is locked */
    if (This->Flags & SFLAG_LOCKED)
        return WINED3DERR_INVALIDCALL;

    memset(&lock, 0, sizeof(lock)); /* To be sure */

    /* Create a DIB section if there isn't a hdc yet */
    if(!This->hDC) {
        int extraline = 0;
        SYSTEM_INFO sysInfo;
        void *oldmem = This->resource.allocatedMemory;

        switch (This->bytesPerPixel) {
            case 2:
            case 4:
                /* Allocate extra space to store the RGB bit masks. */
                b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
                break;

            case 3:
                b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
                break;

            default:
                /* Allocate extra space for a palette. */
                b_info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                                  sizeof(BITMAPINFOHEADER)
                                  + sizeof(RGBQUAD)
                                  * (1 << (This->bytesPerPixel * 8)));
                break;
        }

        if (!b_info)
            return E_OUTOFMEMORY;

        /* Some apps access the surface in via DWORDs, and do not take the necessary care at the end of the
         * surface. So we need at least extra 4 bytes at the end of the surface. Check against the page size,
         * if the last page used for the surface has at least 4 spare bytes we're safe, otherwise
         * add an extra line to the dib section
         */
        GetSystemInfo(&sysInfo);
        if( ((This->resource.size + 3) % sysInfo.dwPageSize) < 4) {
            extraline = 1;
            TRACE("Adding an extra line to the dib section\n");
        }

        b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        /* TODO: Is there a nicer way to force a specific alignment? (8 byte for ddraw) */
        b_info->bmiHeader.biWidth = IWineD3DSurface_GetPitch(iface) / This->bytesPerPixel;
        b_info->bmiHeader.biHeight = -This->currentDesc.Height -extraline;
        b_info->bmiHeader.biSizeImage = ( This->currentDesc.Height + extraline) * IWineD3DSurface_GetPitch(iface);
        b_info->bmiHeader.biPlanes = 1;
        b_info->bmiHeader.biBitCount = This->bytesPerPixel * 8;

        b_info->bmiHeader.biXPelsPerMeter = 0;
        b_info->bmiHeader.biYPelsPerMeter = 0;
        b_info->bmiHeader.biClrUsed = 0;
        b_info->bmiHeader.biClrImportant = 0;

        /* Get the bit masks */
        masks = (DWORD *) &(b_info->bmiColors);
        switch (This->resource.format) {
            case WINED3DFMT_R8G8B8:
                usage = DIB_RGB_COLORS;
                b_info->bmiHeader.biCompression = BI_RGB;
                break;

            case WINED3DFMT_X1R5G5B5:
            case WINED3DFMT_A1R5G5B5:
            case WINED3DFMT_A4R4G4B4:
            case WINED3DFMT_X4R4G4B4:
            case WINED3DFMT_R3G3B2:
            case WINED3DFMT_A8R3G3B2:
            case WINED3DFMT_A2B10G10R10:
            case WINED3DFMT_A8B8G8R8:
            case WINED3DFMT_X8B8G8R8:
            case WINED3DFMT_A2R10G10B10:
            case WINED3DFMT_R5G6B5:
            case WINED3DFMT_A16B16G16R16:
                usage = 0;
                b_info->bmiHeader.biCompression = BI_BITFIELDS;
                masks[0] = formatEntry->redMask;
                masks[1] = formatEntry->greenMask;
                masks[2] = formatEntry->blueMask;
                break;

            default:
                /* Don't know palette */
                b_info->bmiHeader.biCompression = BI_RGB;
                usage = 0;
                break;
        }

        ddc = GetDC(0);
        if (ddc == 0) {
            HeapFree(GetProcessHeap(), 0, b_info);
            return HRESULT_FROM_WIN32(GetLastError());
        }

        TRACE("Creating a DIB section with size %dx%dx%d, size=%d\n", b_info->bmiHeader.biWidth, b_info->bmiHeader.biHeight, b_info->bmiHeader.biBitCount, b_info->bmiHeader.biSizeImage);
        This->dib.DIBsection = CreateDIBSection(ddc, b_info, usage, &This->dib.bitmap_data, 0 /* Handle */, 0 /* Offset */);
        ReleaseDC(0, ddc);

        if (!This->dib.DIBsection) {
            ERR("CreateDIBSection failed!\n");
            HeapFree(GetProcessHeap(), 0, b_info);
            return HRESULT_FROM_WIN32(GetLastError());
        }

        TRACE("DIBSection at : %p\n", This->dib.bitmap_data);

        /* copy the existing surface to the dib section */
        if(This->resource.allocatedMemory) {
            memcpy(This->dib.bitmap_data, This->resource.allocatedMemory, b_info->bmiHeader.biSizeImage);
            /* We won't need that any more */
        } else {
            /* This is to make LockRect read the gl Texture although memory is allocated */
            This->Flags &= ~SFLAG_INSYSMEM;
        }

        HeapFree(GetProcessHeap(), 0, b_info);

        /* Use the dib section from now on */
        This->resource.allocatedMemory = This->dib.bitmap_data;

        /* Now allocate a HDC */
        This->hDC = CreateCompatibleDC(0);
        This->dib.holdbitmap = SelectObject(This->hDC, This->dib.DIBsection);
        TRACE("using wined3d palette %p\n", This->palette);
        SelectPalette(This->hDC,
                      This->palette ? This->palette->hpal : 0,
                      FALSE);

        This->Flags |= SFLAG_DIBSECTION;

        if(This->Flags & SFLAG_CLIENT) {
            IWineD3DSurface_PreLoad(iface);
        }
        HeapFree(GetProcessHeap(), 0, oldmem);
    }

    /* Lock the surface */
    hr = IWineD3DSurface_LockRect(iface,
                                  &lock,
                                  NULL,
                                  0);
    if(FAILED(hr)) {
        ERR("IWineD3DSurface_LockRect failed with hr = %08x\n", hr);
        /* keep the dib section */
        return hr;
    }

    if(This->resource.format == WINED3DFMT_P8 ||
        This->resource.format == WINED3DFMT_A8P8) {
        unsigned int n;
        if(This->palette) {
            PALETTEENTRY ent[256];

            GetPaletteEntries(This->palette->hpal, 0, 256, ent);
            for (n=0; n<256; n++) {
                col[n].rgbRed   = ent[n].peRed;
                col[n].rgbGreen = ent[n].peGreen;
                col[n].rgbBlue  = ent[n].peBlue;
                col[n].rgbReserved = 0;
            }
        } else {
            IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;

            for (n=0; n<256; n++) {
                col[n].rgbRed   = device->palettes[device->currentPalette][n].peRed;
                col[n].rgbGreen = device->palettes[device->currentPalette][n].peGreen;
                col[n].rgbBlue  = device->palettes[device->currentPalette][n].peBlue;
                col[n].rgbReserved = 0;
            }

        }
        SetDIBColorTable(This->hDC, 0, 256, col);
    }

    *pHDC = This->hDC;
    TRACE("returning %p\n",*pHDC);
    This->Flags |= SFLAG_DCINUSE;

    return WINED3D_OK;
}

HRESULT WINAPI IWineD3DSurfaceImpl_ReleaseDC(IWineD3DSurface *iface, HDC hDC) {
    IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;

    TRACE("(%p)->(%p)\n",This,hDC);

    if (!(This->Flags & SFLAG_DCINUSE))
        return WINED3DERR_INVALIDCALL;

    /* we locked first, so unlock now */
    IWineD3DSurface_UnlockRect(iface);

    This->Flags &= ~SFLAG_DCINUSE;

    return WINED3D_OK;
}

/* ******************************************************
   IWineD3DSurface Internal (No mapping to directx api) parts follow
   ****************************************************** */

HRESULT d3dfmt_get_conv(IWineD3DSurfaceImpl *This, BOOL need_alpha_ck, BOOL use_texturing, GLenum *format, GLenum *internal, GLenum *type, CONVERT_TYPES *convert, int *target_bpp, BOOL srgb_mode) {
    BOOL colorkey_active = need_alpha_ck && (This->CKeyFlags & WINEDDSD_CKSRCBLT);
    const GlPixelFormatDesc *glDesc;
    getFormatDescEntry(This->resource.format, &GLINFO_LOCATION, &glDesc);

    /* Default values: From the surface */
    *format = glDesc->glFormat;
    *internal = srgb_mode?glDesc->glGammaInternal:glDesc->glInternal;
    *type = glDesc->glType;
    *convert = NO_CONVERSION;
    *target_bpp = This->bytesPerPixel;

    /* Ok, now look if we have to do any conversion */
    switch(This->resource.format) {
        case WINED3DFMT_P8:
            /* ****************
                Paletted Texture
                **************** */
            /* Use conversion when the paletted texture extension is not available, or when it is available make sure it is used
             * for texturing as it won't work for calls like glDraw-/glReadPixels and further also use conversion in case of color keying.
             */
            if(!GL_SUPPORT(EXT_PALETTED_TEXTURE) || colorkey_active || (!use_texturing && GL_SUPPORT(EXT_PALETTED_TEXTURE)) ) {
                *format = GL_RGBA;
                *internal = GL_RGBA;
                *type = GL_UNSIGNED_BYTE;
                *target_bpp = 4;
                if(colorkey_active) {
                    *convert = CONVERT_PALETTED_CK;
                } else {
                    *convert = 

⌨️ 快捷键说明

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