diff options
Diffstat (limited to 'display')
-rw-r--r-- | display/brush.c | 13 | ||||
-rw-r--r-- | display/dd.c | 122 | ||||
-rw-r--r-- | display/dd.h | 15 | ||||
-rw-r--r-- | display/driver.c | 175 | ||||
-rw-r--r-- | display/qxldd.h | 35 | ||||
-rw-r--r-- | display/res.c | 249 | ||||
-rw-r--r-- | display/res.h | 22 | ||||
-rw-r--r-- | display/rop.c | 379 | ||||
-rw-r--r-- | display/sources | 1 | ||||
-rw-r--r-- | display/surface.c | 65 | ||||
-rw-r--r-- | display/surface.h | 50 | ||||
-rw-r--r-- | display/text.c | 12 | ||||
-rw-r--r-- | display/utils.h | 6 |
13 files changed, 946 insertions, 198 deletions
diff --git a/display/brush.c b/display/brush.c index 802c0a9..d69cb76 100644 --- a/display/brush.c +++ b/display/brush.c @@ -315,7 +315,8 @@ BOOL APIENTRY DrvRealizeBrush(BRUSHOBJ *brush, SURFOBJ *target, SURFOBJ *pattern static _inline BOOL GetPattern(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *pattern, - InternalBrush *brush) + InternalBrush *brush, INT32 *surface_dest, + SpiceRect *surface_rect) { HSURF hsurf; SURFOBJ *surf_obj; @@ -342,7 +343,9 @@ static _inline BOOL GetPattern(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *p area.right = brush->size.cx; area.bottom = brush->size.cy; - if (!QXLGetBitmap(pdev, drawable, pattern, surf_obj, &area, NULL, &key, TRUE)) { + CopyRect(surface_rect, &area); + + if (!QXLGetBitmap(pdev, drawable, pattern, surf_obj, &area, NULL, &key, TRUE, surface_dest)) { goto error_2; } @@ -361,7 +364,8 @@ error_1: BOOL QXLGetBrush(PDev *pdev, QXLDrawable *drawable, SpiceBrush *qxl_brush, - BRUSHOBJ *brush, POINTL *brush_pos) + BRUSHOBJ *brush, POINTL *brush_pos, INT32 *surface_dest, + SpiceRect *surface_rect) { DEBUG_PRINT((pdev, 9, "%s\n", __FUNCTION__)); ASSERT(pdev, brush); @@ -377,7 +381,8 @@ BOOL QXLGetBrush(PDev *pdev, QXLDrawable *drawable, SpiceBrush *qxl_brush, qxl_brush->type = SPICE_BRUSH_TYPE_PATTERN; qxl_brush->u.pattern.pos.x = brush_pos->x; qxl_brush->u.pattern.pos.y = brush_pos->y; - if (!GetPattern(pdev, drawable, &qxl_brush->u.pattern.pat, brush->pvRbrush)) { + if (!GetPattern(pdev, drawable, &qxl_brush->u.pattern.pat, brush->pvRbrush, + surface_dest, surface_rect)) { return FALSE; } } else { diff --git a/display/dd.c b/display/dd.c new file mode 100644 index 0000000..211a4fb --- /dev/null +++ b/display/dd.c @@ -0,0 +1,122 @@ +#include <ddrawi.h> +#include <ddraw.h> +#include <dxmini.h> +#include "os_dep.h" +#include "devioctl.h" +#include "ntddvdeo.h" +#include "ioaccess.h" +#include "qxldd.h" + +static UINT8 get_depth(PDev *pdev) +{ + if (pdev->bitmap_format == BMF_32BPP) { + return 32; + } else { + return 16; + } +} + +BOOL DrvGetDirectDrawInfo(DHPDEV dhpdev, DD_HALINFO *pHallInfo, + DWORD *pdvNumHeaps, VIDEOMEMORY *pvmList, + DWORD *pdvNumFourCCCodes, + DWORD *pdvFourCC) +{ + PDev *pdev; + DWORD offset; + + pdev = (PDev *)dhpdev; + + *pdvNumHeaps = 1; + *pdvNumFourCCCodes = 0; + + if (!pdev->dd_slot_initialized) { + return FALSE; + } + + offset = pdev->resolution.cy * pdev->stride; + + if (pvmList) { + VIDEOMEMORY *pvmobj = pvmList; + + pvmobj->dwFlags = VIDMEM_ISLINEAR; + + pvmobj->fpStart = (FLATPTR)pdev->fb; + pvmobj->fpEnd = pvmobj->fpStart + pdev->fb_size - 1; + + pvmobj->ddsCaps.dwCaps = 0; + pvmobj->ddsCapsAlt.dwCaps = 0; + + pdev->pvmList = pvmList; + } + + memset(pHallInfo, 0, sizeof(DD_HALINFO)); + + pHallInfo->vmiData.pvPrimary = pdev->fb; + pHallInfo->vmiData.fpPrimary = 0; + + pHallInfo->dwSize = sizeof (DD_HALINFO); + + pHallInfo->vmiData.dwFlags = 0; + pHallInfo->vmiData.dwDisplayWidth = pdev->resolution.cx; + pHallInfo->vmiData.dwDisplayHeight = pdev->resolution.cy; + pHallInfo->vmiData.lDisplayPitch = pdev->stride; + pHallInfo->vmiData.ddpfDisplay.dwSize = sizeof(DDPIXELFORMAT); + pHallInfo->vmiData.ddpfDisplay.dwFlags = DDPF_RGB; + + pHallInfo->vmiData.ddpfDisplay.dwRGBBitCount = get_depth(pdev); + + pHallInfo->vmiData.ddpfDisplay.dwRBitMask = pdev->red_mask; + pHallInfo->vmiData.ddpfDisplay.dwGBitMask = pdev->green_mask; + pHallInfo->vmiData.ddpfDisplay.dwBBitMask = pdev->blue_mask; + + pHallInfo->vmiData.dwOffscreenAlign = 4; + pHallInfo->vmiData.dwOverlayAlign = 4; + pHallInfo->vmiData.dwTextureAlign = 4; + pHallInfo->vmiData.dwZBufferAlign = 4; + pHallInfo->vmiData.dwAlphaAlign = 4; + + pHallInfo->ddCaps.dwSize = sizeof (DDCORECAPS); + pHallInfo->ddCaps.dwVidMemTotal = pdev->fb_size; + pHallInfo->ddCaps.dwVidMemFree = pdev->fb_size; + + pdev->dd_initialized = TRUE; + + return TRUE; +} + +DWORD CALLBACK QxlCanCreateSurface(PDD_CANCREATESURFACEDATA data) +{ + return DDHAL_DRIVER_NOTHANDLED; +} + +DWORD CALLBACK QxlFlip(PDD_FLIPDATA lpFlip) +{ + return DDHAL_DRIVER_NOTHANDLED; +} + +BOOL DrvEnableDirectDraw(DHPDEV dhpdev, DD_CALLBACKS *pCallBacks, + DD_SURFACECALLBACKS *pSurfaceCallBacks, + DD_PALETTECALLBACKS *pPaletteCallBacks) +{ + memset(pCallBacks, 0, sizeof (DD_CALLBACKS)); + memset(pSurfaceCallBacks, 0, sizeof (DD_SURFACECALLBACKS)); + memset(pPaletteCallBacks, 0, sizeof (DD_PALETTECALLBACKS)); + + pCallBacks->dwSize = sizeof (DD_CALLBACKS); + pCallBacks->CanCreateSurface = QxlCanCreateSurface; + + pSurfaceCallBacks->dwSize = sizeof (DD_SURFACECALLBACKS); + pSurfaceCallBacks->Flip = QxlFlip; + + pPaletteCallBacks->dwSize = sizeof (DD_PALETTECALLBACKS); + + return TRUE; +} + +void DrvDisableDirectDraw(DHPDEV dhpdev) +{ + PDev *pdev; + + pdev = (PDev *)dhpdev; + pdev->dd_initialized = FALSE; +} diff --git a/display/dd.h b/display/dd.h new file mode 100644 index 0000000..ffcd8e1 --- /dev/null +++ b/display/dd.h @@ -0,0 +1,15 @@ +#ifndef DD_H +#define DD_H + +BOOL DrvGetDirectDrawInfo(DHPDEV dhpdev, DD_HALINFO *pHallInfo, + DWORD *pdvNumHeaps, VIDEOMEMORY *pvmList, + DWORD *pdvNumFourCCCodes, + DWORD *pdvFourCC); + +BOOL DrvEnableDirectDraw(DHPDEV dhpdev, DD_CALLBACKS *pCallBacks, + DD_SURFACECALLBACKS *pSurfaceCallBacks, + DD_PALETTECALLBACKS *pPaletteCallBacks); + +void DrvDisableDirectDraw(DHPDEV dhpdev); + +#endif diff --git a/display/driver.c b/display/driver.c index d3737e3..321d6fe 100644 --- a/display/driver.c +++ b/display/driver.c @@ -35,6 +35,7 @@ #include "mspace.h" #include "res.h" #include "surface.h" +#include "dd.h" #define DEVICE_NAME L"qxldd" @@ -61,6 +62,12 @@ static DRVFN drv_calls[] = { {INDEX_DrvStretchBltROP, (PFN)DrvStretchBltROP}, {INDEX_DrvTransparentBlt, (PFN)DrvTransparentBlt}, {INDEX_DrvAlphaBlend, (PFN)DrvAlphaBlend}, + {INDEX_DrvCreateDeviceBitmap, (PFN)DrvCreateDeviceBitmap}, + {INDEX_DrvDeleteDeviceBitmap, (PFN)DrvDeleteDeviceBitmap}, + + {INDEX_DrvGetDirectDrawInfo, (PFN)DrvGetDirectDrawInfo}, + {INDEX_DrvEnableDirectDraw, (PFN)DrvEnableDirectDraw}, + {INDEX_DrvDisableDirectDraw, (PFN)DrvDisableDirectDraw}, #ifdef CALL_TEST {INDEX_DrvFillPath, (PFN)DrvFillPath}, @@ -512,9 +519,14 @@ DHPDEV DrvEnablePDEV(DEVMODEW *dev_mode, PWSTR ignore1, ULONG ignore2, HSURF *ig goto err3; } + if (!(pdev->cmd_sem = EngCreateSemaphore())) { + DEBUG_PRINT((NULL, 0, "%s: create cmd sem failed\n", __FUNCTION__)); + goto err4; + } + if (!ResInit(pdev)) { DEBUG_PRINT((NULL, 0, "%s: init res failed\n", __FUNCTION__)); - goto err4; + goto err5; } RtlCopyMemory(dev_caps, &gdi_info, dev_caps_size); @@ -523,6 +535,8 @@ DHPDEV DrvEnablePDEV(DEVMODEW *dev_mode, PWSTR ignore1, ULONG ignore2, HSURF *ig DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev)); return(DHPDEV)pdev; +err5: + EngDeleteSemaphore(pdev->cmd_sem); err4: EngDeleteSemaphore(pdev->print_sem); @@ -543,8 +557,10 @@ VOID DrvDisablePDEV(DHPDEV in_pdev) PDev* pdev = (PDev*)in_pdev; DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev)); + EngFreeMem(pdev->surfaces_info); ResDestroy(pdev); DestroyPalette(pdev); + EngDeleteSemaphore(pdev->cmd_sem); EngDeleteSemaphore(pdev->malloc_sem); EngDeleteSemaphore(pdev->print_sem); EngFreeMem(pdev); @@ -591,6 +607,12 @@ static void DestroyPrimarySurface(PDev *pdev) WRITE_PORT_UCHAR(pdev->destroy_primary_port, 0); } +static void DestroyAllSurfaces(PDev *pdev) +{ + HideMouse(pdev); + WRITE_PORT_UCHAR(pdev->destroy_all_surfaces_port, 0); +} + BOOL SetHardwareMode(PDev *pdev) { VIDEO_MODE_INFORMATION video_info; @@ -624,6 +646,49 @@ static VOID UpdateMainSlot(PDev *pdev, MemSlot *slot) pdev->va_slot_mask = (~(QXLPHYSICAL)0) >> (pdev->slot_id_bits + pdev->slot_gen_bits); } +static void RemoveVRamSlot(PDev *pdev) +{ + WRITE_PORT_UCHAR(pdev->memslot_del_port, pdev->dd_mem_slot); + pdev->dd_slot_initialized = FALSE; +} + +static BOOLEAN CreateVRamSlot(PDev *pdev) +{ + QXLMemSlot *slot; + UINT64 high_bits; + UINT8 slot_id = pdev->main_mem_slot + 1; + + if (slot_id >= pdev->num_mem_slot) { + return FALSE; + } + + pdev->va_slot_mask = (~(QXLPHYSICAL)0) >> (pdev->slot_id_bits + pdev->slot_gen_bits); + + + *pdev->ram_slot_start = pdev->fb_phys; + *pdev->ram_slot_end = pdev->fb_phys + pdev->fb_size; + + WRITE_PORT_UCHAR(pdev->memslot_add_port, slot_id); + + pdev->dd_mem_slot = slot_id; + + pdev->mem_slots[slot_id].slot.generation = *pdev->slots_generation; + pdev->mem_slots[slot_id].slot.start_phys_addr = pdev->fb_phys; + pdev->mem_slots[slot_id].slot.end_phys_addr = pdev->fb_phys + pdev->fb_size; + pdev->mem_slots[slot_id].slot.start_virt_addr = (UINT64)pdev->fb; + pdev->mem_slots[slot_id].slot.end_virt_addr = (UINT64)pdev->fb + pdev->fb_size; + + high_bits = slot_id << pdev->slot_gen_bits; + high_bits |= pdev->mem_slots[slot_id].slot.generation; + high_bits <<= (64 - (pdev->slot_gen_bits + pdev->slot_id_bits)); + pdev->mem_slots[slot_id].high_bits = high_bits; + + pdev->dd_slot_initialized = TRUE; + + return TRUE; +} + + BOOL PrepareHardware(PDev *pdev) { VIDEO_MEMORY video_mem; @@ -671,6 +736,7 @@ BOOL PrepareHardware(PDev *pdev) pdev->update_area_port = dev_info.update_area_port; pdev->update_area = dev_info.update_area; + pdev->update_surface = dev_info.update_surface; pdev->mm_clock = dev_info.mm_clock; @@ -680,6 +746,14 @@ BOOL PrepareHardware(PDev *pdev) pdev->log_buf = dev_info.log_buf; pdev->log_level = dev_info.log_level; + pdev->n_surfaces = dev_info.n_surfaces; + if (!(pdev->surfaces_info = (SurfaceInfo *)EngAllocMem(FL_ZERO_MEMORY, + sizeof(SurfaceInfo) * + pdev->n_surfaces, ALLOC_TAG))) { + DEBUG_PRINT((NULL, 0, "%s: surfaces_info alloc failed\n", __FUNCTION__)); + return FALSE; + } + pdev->mem_slots = EngAllocMem(FL_ZERO_MEMORY, sizeof(PMemSlot) * dev_info.num_mem_slot, ALLOC_TAG); if (!pdev->mem_slots) { @@ -687,6 +761,9 @@ BOOL PrepareHardware(PDev *pdev) return FALSE; } + pdev->slots_generation = dev_info.slots_generation; + pdev->ram_slot_start = dev_info.ram_slot_start; + pdev->ram_slot_end = dev_info.ram_slot_end; pdev->slot_id_bits = dev_info.slot_id_bits; pdev->slot_gen_bits = dev_info.slot_gen_bits; pdev->main_mem_slot = dev_info.main_mem_slot_id; @@ -706,8 +783,13 @@ BOOL PrepareHardware(PDev *pdev) video_mem_Info.FrameBufferBase, video_mem_Info.FrameBufferLength)); pdev->fb = (BYTE*)video_mem_Info.FrameBufferBase; pdev->fb_size = video_mem_Info.FrameBufferLength; + pdev->fb_phys = dev_info.fb_phys; pdev->destroy_surface_wait_port = dev_info.destroy_surface_wait_port; + pdev->destroy_all_surfaces_port = dev_info.destroy_all_surfaces_port; + pdev->memslot_add_port = dev_info.memslot_add_port; + pdev->memslot_del_port = dev_info.memslot_del_port; + pdev->create_primary_port = dev_info.create_primary_port; pdev->destroy_primary_port = dev_info.destroy_primary_port; @@ -718,6 +800,10 @@ BOOL PrepareHardware(PDev *pdev) pdev->dev_id = dev_info.dev_id; + pdev->dd_initialized = FALSE; + + CreateVRamSlot(pdev); + DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit: 0x%lx %ul\n", __FUNCTION__, pdev, pdev->fb, pdev->fb_size)); return TRUE; @@ -746,7 +832,7 @@ static VOID UnmapFB(PDev *pdev) } } -VOID EnableQXLSurface(PDev *pdev) +VOID EnableQXLPrimarySurface(PDev *pdev) { UINT32 depth; @@ -777,7 +863,6 @@ HSURF DrvEnableSurface(DHPDEV in_pdev) DWORD length; QXLPHYSICAL phys_mem; UINT8 *base_mem; - DrawArea drawarea; DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, in_pdev)); @@ -788,19 +873,12 @@ HSURF DrvEnableSurface(DHPDEV in_pdev) InitResources(pdev); if (!(surf = (HSURF)CreateDeviceBitmap(pdev, pdev->resolution, pdev->bitmap_format, &phys_mem, - &base_mem, DEVICE_BITMAP_ALLOCATION_TYPE_SURF0))) { + &base_mem, 0, DEVICE_BITMAP_ALLOCATION_TYPE_SURF0))) { DEBUG_PRINT((NULL, 0, "%s: create device surface failed, 0x%lx\n", __FUNCTION__, pdev)); goto err; } - if (!CreateDrawArea(pdev, &drawarea, base_mem, pdev->resolution.cx, pdev->resolution.cy)) { - goto err; - } - - pdev->draw_bitmap = drawarea.bitmap; - pdev->draw_surf = drawarea.surf_obj; - DEBUG_PRINT((NULL, 1, "%s: EngModifySurface(0x%lx, 0x%lx, 0, MS_NOTSYSTEMMEMORY, " "0x%lx, 0x%lx, %lu, NULL)\n", __FUNCTION__, @@ -814,7 +892,7 @@ HSURF DrvEnableSurface(DHPDEV in_pdev) pdev->surf_phys = phys_mem; pdev->surf_base = base_mem; - EnableQXLSurface(pdev); + EnableQXLPrimarySurface(pdev); DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit\n", __FUNCTION__, pdev)); return surf; @@ -825,7 +903,7 @@ err: return NULL; } -VOID DisableQXLSurface(PDev *pdev) +VOID DisableQXLPrimarySurface(PDev *pdev) { DrawArea drawarea; @@ -836,6 +914,11 @@ VOID DisableQXLSurface(PDev *pdev) } } +VOID DisableQXLAllSurfaces(PDev *pdev) +{ + DestroyAllSurfaces(pdev); +} + VOID DrvDisableSurface(DHPDEV in_pdev) { PDev *pdev = (PDev*)in_pdev; @@ -843,12 +926,13 @@ VOID DrvDisableSurface(DHPDEV in_pdev) DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev)); - DisableQXLSurface(pdev); + DisableQXLPrimarySurface(pdev); + //DisableQXLAllSurfaces(pdev); UnmapFB(pdev); if (pdev->surf) { - DeleteDeviceBitmap(pdev->surf); + DeleteDeviceBitmap(pdev, 0, DEVICE_BITMAP_ALLOCATION_TYPE_SURF0); pdev->surf = NULL; } @@ -860,6 +944,11 @@ VOID DrvDisableSurface(DHPDEV in_pdev) pdev->draw_bitmap = NULL; } + if (pdev->surfaces_info) { + EngFreeMem(pdev->surfaces_info); + pdev->surfaces_info = NULL; + } + if (pdev->mem_slots) { EngFreeMem(pdev->mem_slots); pdev->mem_slots = NULL; @@ -875,9 +964,11 @@ BOOL DrvAssertMode(DHPDEV in_pdev, BOOL enable) DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev)); if (enable) { InitResources(pdev); - EnableQXLSurface(pdev); + EnableQXLPrimarySurface(pdev); + CreateVRamSlot(pdev); } else { - DisableQXLSurface(pdev); + DisableQXLPrimarySurface(pdev); + RemoveVRamSlot(pdev); } DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit TRUE\n", __FUNCTION__, pdev)); return TRUE; @@ -1217,7 +1308,7 @@ BOOL APIENTRY DrvStrokePath(SURFOBJ *surf, PATHOBJ *path, CLIPOBJ *clip, XFORMOB } } - if (!(drawable = Drawable(pdev, QXL_DRAW_STROKE, &area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_STROKE, &area, clip, GetSurfaceId(surf)))) { return FALSE; } @@ -1226,7 +1317,8 @@ BOOL APIENTRY DrvStrokePath(SURFOBJ *surf, PATHOBJ *path, CLIPOBJ *clip, XFORMOB if (!((fore_rop->flags | back_rop->flags) & ROP3_BRUSH)) { drawable->u.stroke.brush.type = SPICE_BRUSH_TYPE_NONE; - } else if (!QXLGetBrush(pdev, drawable, &drawable->u.stroke.brush, brush, brush_pos)) { + } else if (!QXLGetBrush(pdev, drawable, &drawable->u.stroke.brush, brush, brush_pos, + &drawable->surfaces_dest[0], &drawable->surfaces_rects[0])) { goto err; } @@ -1266,6 +1358,51 @@ err: return FALSE; } +HBITMAP APIENTRY DrvCreateDeviceBitmap(DHPDEV dhpdev, SIZEL size, ULONG format) +{ + PDev *pdev; + UINT8 *base_mem; + UINT32 surface_id; + QXLPHYSICAL phys_mem; + HBITMAP hbitmap; + + pdev = (PDev *)dhpdev; + + if (!pdev->dd_initialized) { + return 0; + } + + surface_id = GetFreeSurface(pdev); + if (!surface_id) { + goto out_error; + } + + hbitmap = CreateDeviceBitmap(pdev, size, pdev->bitmap_format, &phys_mem, &base_mem, surface_id, + DEVICE_BITMAP_ALLOCATION_TYPE_VRAM); + if (!hbitmap) { + goto out_error; + } + + return hbitmap; + + // to optimize the failure case +out_error: + return 0; +} + +VOID APIENTRY DrvDeleteDeviceBitmap(DHSURF dhsurf) +{ + UINT32 surface_id; + PDev *pdev; + SurfaceInfo *surface; + + surface = (SurfaceInfo *)dhsurf; + pdev = surface->pdev; + surface_id = surface - pdev->surfaces_info; + + DeleteDeviceBitmap(pdev, surface_id, DEVICE_BITMAP_ALLOCATION_TYPE_VRAM); +} + #ifdef CALL_TEST void CountCall(PDev *pdev, int counter) diff --git a/display/qxldd.h b/display/qxldd.h index 80dd30a..f1623d1 100644 --- a/display/qxldd.h +++ b/display/qxldd.h @@ -166,6 +166,8 @@ typedef struct DevRes { struct InternalPalette *palette_cache[PALETTE_HASH_SIZE]; UINT32 num_palettes; + UINT8 *surfaces_used; + #ifdef DBG int num_free_pages; int num_outputs; @@ -187,6 +189,20 @@ typedef struct DevRes { #define SSE_MASK 15 #define SSE_ALIGN 16 + +typedef struct DrawArea { + HSURF bitmap; + SURFOBJ* surf_obj; + UINT8 *base_mem; +} DrawArea; + +typedef struct PDev PDev; + +typedef struct SurfaceInfo { + DrawArea draw_area; + PDev *pdev; +} SurfaceInfo; + typedef struct PDev { HANDLE driver; HDEV eng; @@ -197,8 +213,14 @@ typedef struct PDev { SIZEL resolution; UINT32 max_bitmap_size; ULONG bitmap_format; + ULONG fb_size; BYTE* fb; + UINT64 fb_phys; + UINT8 dd_initialized; + UINT8 dd_slot_initialized; + UINT8 dd_mem_slot; + ULONG stride; FLONG red_mask; FLONG green_mask; @@ -229,12 +251,16 @@ typedef struct PDev { HSEMAPHORE malloc_sem; HSEMAPHORE print_sem; + HSEMAPHORE cmd_sem; PMemSlot *mem_slots; UINT8 num_mem_slot; UINT8 main_mem_slot; UINT8 slot_id_bits; UINT8 slot_gen_bits; + UINT8 *slots_generation; + UINT64 *ram_slot_start; + UINT64 *ram_slot_end; SPICE_ADDRESS va_slot_mask; UINT32 num_io_pages; @@ -245,6 +271,7 @@ typedef struct PDev { UINT32 update_area_port; SpiceRect *update_area; + UINT32 *update_surface; UINT32 *mm_clock; @@ -259,6 +286,9 @@ typedef struct PDev { UINT32 create_primary_port; UINT32 destroy_primary_port; UINT32 destroy_surface_wait_port; + UINT32 memslot_add_port; + UINT32 memslot_del_port; + UINT32 destroy_all_surfaces_port; UINT8* primary_memory_start; UINT32 primary_memory_size; @@ -273,6 +303,11 @@ typedef struct PDev { UpdateTrace update_trace_items[NUM_UPDATE_TRACE_ITEMS]; UINT8 FPUSave[16 * 4 + 15]; + + UINT32 n_surfaces; + SurfaceInfo *surfaces_info; + + VIDEOMEMORY *pvmList; } PDev; diff --git a/display/res.c b/display/res.c index 041bf2e..318ea9c 100644 --- a/display/res.c +++ b/display/res.c @@ -15,6 +15,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <ddrawi.h> +#include <ddraw.h> +#include <dxmini.h> #include "os_dep.h" #include "res.h" #include "ioaccess.h" @@ -22,6 +25,8 @@ #include "mspace.h" #include "quic.h" #include "murmur_hash2a.h" +#include "surface.h" +#include "dd.h" #if (WINVER < 0x0501) #define WAIT_FOR_EVENT(pdev, event, timeout) (pdev)->WaitForEvent(event, timeout) @@ -67,10 +72,12 @@ static BOOL SetClip(PDev *pdev, CLIPOBJ *clip, QXLDrawable *drawable); #define PUSH_CMD(pdev) do { \ int notify; \ + EngAcquireSemaphore(pdev->cmd_sem); \ SPICE_RING_PUSH(pdev->cmd_ring, notify); \ if (notify) { \ WRITE_PORT_UCHAR(pdev->notify_cmd_port, 0); \ } \ + EngReleaseSemaphore(pdev->cmd_sem); \ } while (0); #define PUSH_CURSOR_CMD(pdev) do { \ @@ -130,6 +137,15 @@ static _inline void DrawableAddRes(PDev *pdev, QXLDrawable *drawable, Resource * AddRes(pdev, output, res); } + +static _inline void SurfaceAddRes(PDev *pdev, QXLSurfaceCmd *surface, Resource *res) +{ + QXLOutput *output; + + output = (QXLOutput *)((UINT8 *)surface - sizeof(QXLOutput)); + AddRes(pdev, output, res); +} + static _inline void CursorCmdAddRes(PDev *pdev, QXLCursorCmd *cmd, Resource *res) { QXLOutput *output; @@ -311,6 +327,10 @@ void CleanGlobalRes() EngFreeMem(global_res[i].dynamic); global_res[i].dynamic = NULL; } + if (global_res[i].surfaces_used) { + EngFreeMem(global_res[i].surfaces_used); + global_res[i].surfaces_used = NULL; + } } EngFreeMem(global_res); global_res = NULL; @@ -347,6 +367,12 @@ static void InitRes(PDev *pdev) PANIC(pdev, "Res dynamic allocation failed\n"); } + pdev->Res.surfaces_used = EngAllocMem(FL_ZERO_MEMORY, sizeof(UINT8) * pdev->n_surfaces, + ALLOC_TAG); + if (!pdev->Res.surfaces_used) { + PANIC(pdev, "Res surfaces_used allocation failed\n"); + } + pdev->Res.free_outputs = 0; InitMspace(&pdev->Res, pdev->io_pages_virt, pdev->num_io_pages * PAGE_SIZE); pdev->Res.update_id = *pdev->dev_update_id; @@ -457,17 +483,21 @@ static QXLDrawable *GetDrawable(PDev *pdev) return(QXLDrawable *)output->data; } -QXLDrawable *Drawable(PDev *pdev, UINT8 type, RECTL *area, CLIPOBJ *clip) +QXLDrawable *Drawable(PDev *pdev, UINT8 type, RECTL *area, CLIPOBJ *clip, UINT32 surface_id) { QXLDrawable *drawable; ASSERT(pdev, pdev && area); drawable = GetDrawable(pdev); + drawable->surface_id = surface_id; drawable->type = type; drawable->effect = QXL_EFFECT_BLEND; drawable->self_bitmap = 0; drawable->mm_time = *pdev->mm_clock; + drawable->surfaces_dest[0] = -1; + drawable->surfaces_dest[1] = - 1; + drawable->surfaces_dest[2] = -1; CopyRect(&drawable->bbox, area); if (!SetClip(pdev, clip, drawable)) { @@ -489,23 +519,141 @@ void PushDrawable(PDev *pdev, QXLDrawable *drawable) PUSH_CMD(pdev); } -_inline void GetSurfaceMemory(PDev *pdev, UINT32 x, UINT32 y, UINT32 depth, UINT8 **base_mem, - QXLPHYSICAL *phys_mem, UINT8 allocation_type) +static QXLSurfaceCmd *GetSurfaceCmd(PDev *pdev) +{ + QXLOutput *output; + + output = (QXLOutput *)AllocMem(pdev, sizeof(QXLOutput) + sizeof(QXLSurfaceCmd)); + output->num_res = 0; + ((QXLSurfaceCmd *)output->data)->release_info.id = (UINT64)output; + DEBUG_PRINT((pdev, 9, "%s 0x%x\n", __FUNCTION__, output)); + ONDBG(pdev->Res.num_outputs++); //todo: atomic + return(QXLSurfaceCmd *)output->data; +} + +QXLSurfaceCmd *SurfaceCmd(PDev *pdev, UINT8 type, UINT32 surface_id) +{ + QXLSurfaceCmd *surface_cmd; + + ASSERT(pdev, pdev && area); + + surface_cmd = GetSurfaceCmd(pdev); + surface_cmd->surface_id = surface_id; + surface_cmd->type = type; + surface_cmd->flags = 0; + + return surface_cmd; +} + +void PushSurfaceCmd(PDev *pdev, QXLSurfaceCmd *surface_cmd) +{ + QXLCommand *cmd; + + WaitForCmdRing(pdev); + cmd = SPICE_RING_PROD_ITEM(pdev->cmd_ring); + cmd->type = QXL_CMD_SURFACE; + cmd->data = PA(pdev, surface_cmd, pdev->main_mem_slot); + PUSH_CMD(pdev); +} + + +_inline void GetSurfaceMemory(PDev *pdev, UINT32 x, UINT32 y, UINT32 depth, UINT32 *stride, + UINT8 **base_mem, QXLPHYSICAL *phys_mem, UINT8 allocation_type) { DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__)); - ASSERT(pdev, allocation_type == DEVICE_BITMAP_ALLOCATION_TYPE_SURF0); - ASSERT(pdev, x * y * depth /8 <= pdev->primary_memory_size); + switch (allocation_type) { + case DEVICE_BITMAP_ALLOCATION_TYPE_SURF0: + ASSERT(pdev, x * y * depth /8 <= pdev->primary_memory_size); + *base_mem = pdev->primary_memory_start; + *phys_mem = PA(pdev, *base_mem, pdev->main_mem_slot); + *stride = x * depth / 8; + break; + case DEVICE_BITMAP_ALLOCATION_TYPE_DEVRAM: + *base_mem = AllocMem(pdev, x * y * depth / 8); + *phys_mem = PA(pdev, *base_mem, pdev->main_mem_slot); + *stride = x * depth / 8; + break; + case DEVICE_BITMAP_ALLOCATION_TYPE_VRAM: { + SURFACEALIGNMENT surfacealignment; + + memset(&surfacealignment, 0, sizeof(surfacealignment)); + surfacealignment.Linear.dwStartAlignment = 4; + surfacealignment.Linear.dwPitchAlignment = 4; + *base_mem = (UINT8 *)HeapVidMemAllocAligned((LPVIDMEM)pdev->pvmList, x * depth / 8, y, + &surfacealignment, stride); + *phys_mem = PA(pdev, (PVOID)((UINT64)*base_mem), pdev->dd_mem_slot); + break; + } + default: + PANIC(pdev, "No allocation type"); + } +} - *base_mem = pdev->primary_memory_start; - *phys_mem = PA(pdev, *base_mem, pdev->main_mem_slot); +void QXLGetSurface(PDev *pdev, QXLPHYSICAL *surface_phys, UINT32 x, UINT32 y, UINT32 depth, + UINT32 *stride, UINT8 **base_mem, UINT8 allocation_type) +{ + GetSurfaceMemory(pdev, x, y, depth, stride, base_mem, surface_phys, allocation_type); } -BOOL QXLGetSurface(PDev *pdev, QXLPHYSICAL *surface_phys, UINT32 x, UINT32 y, UINT32 depth, - UINT8 **base_mem, UINT8 allocation_type) { - ASSERT(pdev, allocation_type == DEVICE_BITMAP_ALLOCATION_TYPE_SURF0); - GetSurfaceMemory(pdev, x, y, depth, base_mem, surface_phys, allocation_type); - return TRUE; +void QXLDelSurface(PDev *pdev, UINT8 *base_mem, UINT8 allocation_type) +{ + if (allocation_type == DEVICE_BITMAP_ALLOCATION_TYPE_DEVRAM) { + FreeMem(pdev, base_mem); + } +} + +typedef struct InternalDelSurface { + UINT32 surface_id; + UINT8 allocation_type; +} InternalDelSurface; + + +static void FreeDelSurface(PDev *pdev, Resource *res) +{ + InternalDelSurface *internal; + DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__)); + + internal = (InternalDelSurface *)res->res; + switch (internal->allocation_type) { + case DEVICE_BITMAP_ALLOCATION_TYPE_DEVRAM: + FreeMem(pdev, pdev->surfaces_info[internal->surface_id].draw_area.base_mem); + break; + case DEVICE_BITMAP_ALLOCATION_TYPE_VRAM: + VidMemFree(pdev->pvmList->lpHeap, + (FLATPTR)pdev->surfaces_info[internal->surface_id].draw_area.base_mem); + break; + default: + PANIC(pdev, "bad allocation type"); + } + FreeSurface(pdev, internal->surface_id); + FreeMem(pdev, res); + + DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__)); +} + +#define SURFACEDEL_ALLOC_BASE (sizeof(Resource) + sizeof(InternalDelSurface)) + +void QXLGetDelSurface(PDev *pdev, QXLSurfaceCmd *surface, UINT32 surface_id, UINT8 allocation_type) +{ + Resource *surface_res; + InternalDelSurface *internal; + size_t alloc_size; + + DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__)); + + alloc_size = SURFACEDEL_ALLOC_BASE; + surface_res = AllocMem(pdev, alloc_size); + + surface_res->refs = 1; + surface_res->free = FreeDelSurface; + + internal = (InternalDelSurface *)surface_res->res; + internal->surface_id = surface_id; + internal->allocation_type = allocation_type; + + SurfaceAddRes(pdev, surface, surface_res); + RELEASE_RES(pdev, surface_res); } static void FreePath(PDev *pdev, Resource *res) @@ -1512,6 +1660,15 @@ static _inline void SaveFPU(PDev *pdev) } } +static void FreeSurfaceImage(PDev *pdev, Resource *res) +{ + DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__)); + + FreeMem(pdev, res); + + DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__)); +} + #define BITMAP_ALLOC_BASE (sizeof(Resource) + sizeof(InternalImage) + sizeof(QXLDataChunk)) static _inline Resource *GetBitmapImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_trans, @@ -1789,7 +1946,8 @@ static _inline UINT32 get_image_serial() } BOOL QXLGetBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phys, SURFOBJ *surf, - SpiceRect *area, XLATEOBJ *color_trans, UINT32 *hash_key, BOOL use_cache) + SpiceRect *area, XLATEOBJ *color_trans, UINT32 *hash_key, BOOL use_cache, + INT32 *surface_dest) { Resource *image_res; InternalImage *internal; @@ -1804,8 +1962,29 @@ BOOL QXLGetBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phys, SU ASSERT(pdev, !hash_key || use_cache); DEBUG_PRINT((pdev, 9, "%s\n", __FUNCTION__)); if (surf->iType != STYPE_BITMAP) { - DEBUG_PRINT((pdev, 0, "%s: copy from device doing nothing!!!\n", __FUNCTION__)); - return FALSE; + UINT32 alloc_size; + + DEBUG_PRINT((pdev, 9, "%s: copy from device\n", __FUNCTION__)); + + alloc_size = sizeof(Resource) + sizeof(InternalImage); + image_res = AllocMem(pdev, alloc_size); + + ONDBG(pdev->num_bits_pages++); + image_res->refs = 1; + image_res->free = FreeSurfaceImage; + + internal = (InternalImage *)image_res->res; + + internal->image.descriptor.type = SPICE_IMAGE_TYPE_SURFACE; + *surface_dest = internal->image.surface_image.surface_id = GetSurfaceId(surf); + + *image_phys = PA(pdev, &internal->image, pdev->main_mem_slot); + + DrawableAddRes(pdev, drawable, image_res); + + RELEASE_RES(pdev, image_res); + + return TRUE; } if (area->left < 0 || area->right > surf->sizlBitmap.cx || @@ -1910,7 +2089,7 @@ BOOL QXLGetBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phys, SU } BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phys, - SURFOBJ *surf, SpiceRect *area) + SURFOBJ *surf, SpiceRect *area, INT32 *surface_dest) { Resource *image_res; InternalImage *internal; @@ -1922,7 +2101,6 @@ BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phy INT32 height = area->bottom - area->top; DEBUG_PRINT((pdev, 9, "%s\n", __FUNCTION__)); - ASSERT(pdev, surf->iBitmapFormat == BMF_32BPP && surf->iType == STYPE_BITMAP); ASSERT(pdev, area->left >= 0 && area->right <= surf->sizlBitmap.cx && area->top >= 0 && area->bottom <= surf->sizlBitmap.cy); @@ -1932,6 +2110,32 @@ BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phy surf->sizlBitmap.cx, surf->sizlBitmap.cy, surf->hsurf, surf->iBitmapFormat)); + if (surf->iType != STYPE_BITMAP) { + UINT32 alloc_size; + + DEBUG_PRINT((pdev, 9, "%s: copy from device\n", __FUNCTION__)); + + alloc_size = sizeof(Resource) + sizeof(InternalImage); + image_res = AllocMem(pdev, alloc_size); + + ONDBG(pdev->num_bits_pages++); + image_res->refs = 1; + image_res->free = FreeSurfaceImage; + + internal = (InternalImage *)image_res->res; + + internal->image.descriptor.type = SPICE_IMAGE_TYPE_SURFACE; + *surface_dest = internal->image.surface_image.surface_id = GetSurfaceId(surf); + + *image_phys = PA(pdev, &internal->image, pdev->main_mem_slot); + DrawableAddRes(pdev, drawable, image_res); + RELEASE_RES(pdev, image_res); + + return TRUE; + } + + ASSERT(pdev, surf->iBitmapFormat == BMF_32BPP && surf->iType == STYPE_BITMAP); + //todo: use GetChachImage // NOTE: Same BMF_DONTCACHE issue as in QXLGetBitmap @@ -2024,7 +2228,7 @@ BOOL QXLGetBitsFromCache(PDev *pdev, QXLDrawable *drawable, UINT32 hash_key, QXL } BOOL QXLGetMask(PDev *pdev, QXLDrawable *drawable, SpiceQMask *qxl_mask, SURFOBJ *mask, POINTL *pos, - BOOL invers, LONG width, LONG height) + BOOL invers, LONG width, LONG height, INT32 *surface_dest) { SpiceRect area; @@ -2046,7 +2250,8 @@ BOOL QXLGetMask(PDev *pdev, QXLDrawable *drawable, SpiceQMask *qxl_mask, SURFOBJ area.top = pos->y; area.bottom = area.top + height; - if (QXLGetBitmap(pdev, drawable, &qxl_mask->bitmap, mask, &area, NULL, NULL, TRUE)) { + if (QXLGetBitmap(pdev, drawable, &qxl_mask->bitmap, mask, &area, NULL, NULL, TRUE, + surface_dest)) { qxl_mask->pos.x = area.left; qxl_mask->pos.y = area.top; return TRUE; @@ -2082,7 +2287,7 @@ UINT8 *QXLGetBuf(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *buf_phys, UINT3 } #ifdef UPDATE_CMD -void UpdateArea(PDev *pdev, RECTL *area) +void UpdateArea(PDev *pdev, RECTL *area, UINT32 surface_id) { QXLCommand *cmd; QXLOutput *output; @@ -2098,6 +2303,7 @@ void UpdateArea(PDev *pdev, RECTL *area) CopyRect(&updat_cmd->area, area); updat_cmd->update_id = ++pdev->Res.update_id; + updat_cmd->surface_id = surface_id; WaitForCmdRing(pdev); cmd = SPICE_RING_PROD_ITEM(pdev->cmd_ring); @@ -2131,10 +2337,11 @@ void UpdateArea(PDev *pdev, RECTL *area) #else -void UpdateArea(PDev *pdev, RECTL *area) +void UpdateArea(PDev *pdev, RECTL *area, UINT32 surface_id) { DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__)); CopyRect(pdev->update_area, area); + *pdev->update_surface = surface_id; WRITE_PORT_UCHAR(pdev->update_area_port, 0); } diff --git a/display/res.h b/display/res.h index 5af8a26..90223ae 100644 --- a/display/res.h +++ b/display/res.h @@ -22,26 +22,32 @@ UINT64 ReleaseOutput(PDev *pdev, UINT64 output_id); -QXLDrawable *Drawable(PDev *pdev, UINT8 type, RECTL *area, CLIPOBJ *clip); +QXLDrawable *Drawable(PDev *pdev, UINT8 type, RECTL *area, CLIPOBJ *clip, UINT32 surface_id); void PushDrawable(PDev *pdev, QXLDrawable *drawable); +QXLSurfaceCmd *SurfaceCmd(PDev *pdev, UINT8 type, UINT32 surface_id); +void PushSurfaceCmd(PDev *pdev, QXLSurfaceCmd *surface_cmd); -BOOL QXLGetSurface(PDev *pdev, QXLPHYSICAL *surface_phys, UINT32 x, UINT32 y, UINT32 depth, - UINT8 **base_mem, UINT8 allocation_type); +void QXLGetSurface(PDev *pdev, QXLPHYSICAL *surface_phys, UINT32 x, UINT32 y, UINT32 depth, + UINT32 *stride, UINT8 **base_mem, UINT8 allocation_type); +void QXLGetDelSurface(PDev *pdev, QXLSurfaceCmd *surface, UINT32 surface_id, UINT8 allocation_type); +void QXLDelSurface(PDev *pdev, UINT8 *base_mem, UINT8 allocation_type); BOOL QXLGetPath(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *path_phys, PATHOBJ *path); BOOL QXLGetMask(PDev *pdev, QXLDrawable *drawable, SpiceQMask *qxl_mask, SURFOBJ *mask, POINTL *pos, - BOOL invers, LONG width, LONG height); + BOOL invers, LONG width, LONG height, INT32 *surface_dest); BOOL QXLGetBrush(PDev *pdev, QXLDrawable *drawable, SpiceBrush *qxl_brush, - BRUSHOBJ *brush, POINTL *brush_pos); + BRUSHOBJ *brush, POINTL *brush_pos, INT32 *surface_dest, + SpiceRect *surface_rect); BOOL QXLGetBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phys, SURFOBJ *surf, - SpiceRect *area, XLATEOBJ *color_trans, UINT32 *hash_key, BOOL use_cache); + SpiceRect *area, XLATEOBJ *color_trans, UINT32 *hash_key, BOOL use_cache, + INT32 *surface_dest); BOOL QXLGetBitsFromCache(PDev *pdev, QXLDrawable *drawable, UINT32 hash_key, QXLPHYSICAL *image_phys); BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *image_phys, SURFOBJ *surf, - SpiceRect *area); + SpiceRect *area, INT32 *surface_dest); BOOL CheckIfCacheImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_trans); UINT8 *QXLGetBuf(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *buf_phys, UINT32 size); BOOL QXLGetStr(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *str_phys, FONTOBJ *font, STROBJ *str); -void UpdateArea(PDev *pdev, RECTL *area); +void UpdateArea(PDev *pdev, RECTL *area, UINT32 surface_id); QXLCursorCmd *CursorCmd(PDev *pdev); void PushCursorCmd(PDev *pdev, QXLCursorCmd *cursor_cmd); diff --git a/display/rop.c b/display/rop.c index 83efdd3..82cd723 100644 --- a/display/rop.c +++ b/display/rop.c @@ -20,6 +20,7 @@ #include "utils.h" #include "res.h" #include "rop.h" +#include "surface.h" enum ROP3type { @@ -382,21 +383,28 @@ ROP3Info rops3[] = { }; -static BOOL DoFill(PDev *pdev, RECTL *area, CLIPOBJ *clip, BRUSHOBJ *brush, POINTL *brush_pos, - ROP3Info *rop_info, SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask) +static BOOL DoFill(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, BRUSHOBJ *brush, + POINTL *brush_pos, ROP3Info *rop_info, SURFOBJ *mask, POINTL *mask_pos, + BOOL invers_mask) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area && brush); - if (!(drawable = Drawable(pdev, QXL_DRAW_FILL, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_FILL, area, clip, surface_id))) { return FALSE; } - if (!QXLGetBrush(pdev, drawable, &drawable->u.fill.brush, brush, brush_pos) || + width = area->right - area->left; + height = area->bottom - area->top; + + if (!QXLGetBrush(pdev, drawable, &drawable->u.fill.brush, brush, brush_pos, + &drawable->surfaces_dest[0], &drawable->surfaces_rects[0]) || !QXLGetMask(pdev, drawable, &drawable->u.fill.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top)) { + width, height, &drawable->surfaces_dest[1])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } @@ -405,28 +413,37 @@ static BOOL DoFill(PDev *pdev, RECTL *area, CLIPOBJ *clip, BRUSHOBJ *brush, POIN drawable->effect = mask ? QXL_EFFECT_BLEND : rop_info->effect; + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[1], mask_pos, width, height); + } + PushDrawable(pdev, drawable); return TRUE; } static BOOL GetBitmap(PDev *pdev, QXLDrawable *drawable, QXLPHYSICAL *bitmap_phys, SURFOBJ *surf, - SpiceRect *area, XLATEOBJ *color_trans, BOOL use_cache) + SpiceRect *area, XLATEOBJ *color_trans, BOOL use_cache, INT32 *surface_dest) { DEBUG_PRINT((pdev, 9, "%s\n", __FUNCTION__)); if (surf->iType != STYPE_BITMAP) { + UINT32 surface_id; + ASSERT(pdev, (PDev *)surf->dhpdev == pdev); - DEBUG_PRINT((pdev, 9, "%s copy from self\n", __FUNCTION__)); - *bitmap_phys = 0; - drawable->self_bitmap = TRUE; - drawable->self_bitmap_area = *area; - area->right = area->right - area->left; - area->left = 0; - area->bottom = area->bottom - area->top; - area->top = 0; - return TRUE; + surface_id = GetSurfaceId(surf); + if (surface_id == drawable->surface_id) { + DEBUG_PRINT((pdev, 9, "%s copy from self\n", __FUNCTION__)); + *bitmap_phys = 0; + drawable->self_bitmap = TRUE; + drawable->self_bitmap_area = *area; + area->right = area->right - area->left; + area->left = 0; + area->bottom = area->bottom - area->top; + area->top = 0; + return TRUE; + } } return QXLGetBitmap(pdev, drawable, &drawable->u.opaque.src_bitmap, surf, - area, color_trans, NULL, use_cache); + area, color_trans, NULL, use_cache, surface_dest); } static _inline UINT8 GdiScaleModeToQxl(ULONG scale_mode) @@ -435,31 +452,44 @@ static _inline UINT8 GdiScaleModeToQxl(ULONG scale_mode) SPICE_IMAGE_SCALE_MODE_NEAREST; } -static BOOL DoOpaque(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, +static BOOL DoOpaque(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, + RECTL *src_rect, XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, UINT16 rop_decriptor, SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area && brush && src_rect && src); - if (!(drawable = Drawable(pdev, QXL_DRAW_OPAQUE, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_OPAQUE, area, clip, surface_id))) { return FALSE; } drawable->u.opaque.scale_mode = GdiScaleModeToQxl(scale_mode); CopyRect(&drawable->u.opaque.src_area, src_rect); - if (!QXLGetBrush(pdev, drawable, &drawable->u.opaque.brush, brush, brush_pos) || + + width = area->right - area->left; + height = area->bottom - area->top; + + if (!QXLGetBrush(pdev, drawable, &drawable->u.opaque.brush, brush, brush_pos, + &drawable->surfaces_dest[0], &drawable->surfaces_rects[0]) || !QXLGetMask(pdev, drawable, &drawable->u.opaque.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top) || + width, height, &drawable->surfaces_dest[1]) || !GetBitmap(pdev, drawable, &drawable->u.opaque.src_bitmap, src, - &drawable->u.opaque.src_area, color_trans, TRUE)) { + &drawable->u.opaque.src_area, color_trans, TRUE, + &drawable->surfaces_dest[2])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[1], mask_pos, width, height); + } + CopyRect(&drawable->surfaces_rects[2], src_rect); + drawable->u.opaque.rop_decriptor = rop_decriptor; drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_OPAQUE; PushDrawable(pdev, drawable); @@ -521,7 +551,7 @@ static BOOL StreamTest(PDev *pdev, SURFOBJ *src_surf, XLATEOBJ *color_trans, REC return TRUE; } -static BOOL TestSplitClips(PDev *pdev, RECTL *src_rect, CLIPOBJ *clip, SURFOBJ *mask) +static BOOL TestSplitClips(PDev *pdev, SURFOBJ *src, RECTL *src_rect, CLIPOBJ *clip, SURFOBJ *mask) { UINT32 width; UINT32 height; @@ -533,6 +563,10 @@ static BOOL TestSplitClips(PDev *pdev, RECTL *src_rect, CLIPOBJ *clip, SURFOBJ * return FALSE; } + if (src->iType != STYPE_BITMAP) { + return FALSE; + } + width = src_rect->right - src_rect->left; height = src_rect->bottom - src_rect->top; src_space = width * height; @@ -574,19 +608,24 @@ static BOOL TestSplitClips(PDev *pdev, RECTL *src_rect, CLIPOBJ *clip, SURFOBJ * return FALSE; } -static _inline BOOL DoPartialCopy(PDev *pdev, SURFOBJ *src, RECTL *src_rect, RECTL *area_rect, - RECTL *clip_rect, XLATEOBJ *color_trans, ULONG scale_mode, - UINT16 rop_decriptor) +static _inline BOOL DoPartialCopy(PDev *pdev, UINT32 surface_id, SURFOBJ *src, RECTL *src_rect, + RECTL *area_rect, RECTL *clip_rect, XLATEOBJ *color_trans, + ULONG scale_mode, UINT16 rop_decriptor) { QXLDrawable *drawable; RECTL clip_area; + UINT32 width; + UINT32 height; SectRect(area_rect, clip_rect, &clip_area); if (IsEmptyRect(&clip_area)) { return TRUE; } - if (!(drawable = Drawable(pdev, QXL_DRAW_COPY, &clip_area, NULL))) { + width = clip_area.right - clip_area.left; + height = clip_area.bottom - clip_area.top; + + if (!(drawable = Drawable(pdev, QXL_DRAW_COPY, &clip_area, NULL, surface_id))) { return FALSE; } @@ -603,36 +642,41 @@ static _inline BOOL DoPartialCopy(PDev *pdev, SURFOBJ *src, RECTL *src_rect, REC clip_area.left; if(!GetBitmap(pdev, drawable, &drawable->u.copy.src_bitmap, src, &drawable->u.copy.src_area, - color_trans, FALSE)) { + color_trans, FALSE, &drawable->surfaces_dest[0])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + CopyRect(&drawable->surfaces_rects[0], src_rect); PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoCopy(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, UINT16 rop_decriptor, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask, ULONG scale_mode) +static BOOL DoCopy(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, + RECTL *src_rect, XLATEOBJ *color_trans, UINT16 rop_decriptor, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) { QXLDrawable *drawable; BOOL use_cache; + UINT32 width; + UINT32 height; ASSERT(pdev, pdev && area && src_rect && src); DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); + width = area->right - area->left; + height = area->bottom - area->top; + if (mask) { use_cache = TRUE; } else { use_cache = StreamTest(pdev, src, color_trans, src_rect, area); } - if (use_cache && TestSplitClips(pdev, src_rect, clip, mask) && + if (use_cache && TestSplitClips(pdev, src, src_rect, clip, mask) && !CheckIfCacheImage(pdev, src, color_trans)) { - if (clip->iDComplexity == DC_RECT) { - if (!DoPartialCopy(pdev, src, src_rect, area, &clip->rclBounds, color_trans, scale_mode, - rop_decriptor)) { + if (!DoPartialCopy(pdev, surface_id, src, src_rect, area, &clip->rclBounds, color_trans, + scale_mode, rop_decriptor)) { return FALSE; } } else { @@ -649,8 +693,8 @@ static BOOL DoCopy(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL * } buf; more = CLIPOBJ_bEnum(clip, sizeof(buf), (ULONG *)&buf); for(now = buf.rects, end = now + buf.count; now < end; now++) { - if (!DoPartialCopy(pdev, src, src_rect, area, now, color_trans, scale_mode, - rop_decriptor)) { + if (!DoPartialCopy(pdev, surface_id, src, src_rect, area, now, color_trans, + scale_mode, rop_decriptor)) { return FALSE; } } @@ -659,7 +703,7 @@ static BOOL DoCopy(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL * return TRUE; } - if (!(drawable = Drawable(pdev, QXL_DRAW_COPY, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_COPY, area, clip, surface_id))) { return FALSE; } @@ -672,22 +716,29 @@ static BOOL DoCopy(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL * drawable->u.copy.scale_mode = GdiScaleModeToQxl(scale_mode); CopyRect(&drawable->u.copy.src_area, src_rect); if (!QXLGetMask(pdev, drawable, &drawable->u.copy.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top) || + width, height, &drawable->surfaces_dest[0]) || !GetBitmap(pdev, drawable, &drawable->u.copy.src_bitmap, src, &drawable->u.copy.src_area, - color_trans, use_cache)) { + color_trans, use_cache, &drawable->surfaces_dest[1])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + CopyRect(&drawable->surfaces_rects[1], src_rect); + drawable->u.copy.rop_decriptor = rop_decriptor; PushDrawable(pdev, drawable); DEBUG_PRINT((pdev, 7, "%s: done\n", __FUNCTION__)); return TRUE; } -static BOOL DoCopyBits(PDev *pdev, CLIPOBJ *clip, RECTL *area, POINTL *src_pos) +static BOOL DoCopyBits(PDev *pdev, UINT32 surface_id, CLIPOBJ *clip, RECTL *area, POINTL *src_pos) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; ASSERT(pdev, pdev && area && src_pos); DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); @@ -697,144 +748,199 @@ static BOOL DoCopyBits(PDev *pdev, CLIPOBJ *clip, RECTL *area, POINTL *src_pos) return TRUE; } - if (!(drawable = Drawable(pdev, QXL_COPY_BITS, area, clip))) { + width = area->right - area->left; + height = area->bottom - area->top; + + if (!(drawable = Drawable(pdev, QXL_COPY_BITS, area, clip, surface_id))) { return FALSE; } + + drawable->surfaces_dest[0] = surface_id; + CopyRectPoint(&drawable->surfaces_rects[0], src_pos, width, height); + CopyPoint(&drawable->u.copy_bits.src_pos, src_pos); drawable->effect = QXL_EFFECT_OPAQUE; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoBlend(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, ROP3Info *rop_info, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask, ULONG scale_mode) +static BOOL DoBlend(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, + RECTL *src_rect, XLATEOBJ *color_trans, ROP3Info *rop_info, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area && src_rect && src); - if (!(drawable = Drawable(pdev, QXL_DRAW_BLEND, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_BLEND, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + drawable->u.blend.scale_mode = GdiScaleModeToQxl(scale_mode); CopyRect(&drawable->u.blend.src_area, src_rect); if (!QXLGetMask(pdev, drawable, &drawable->u.blend.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top) || + width, height, &drawable->surfaces_dest[0]) || !GetBitmap(pdev, drawable, &drawable->u.blend.src_bitmap, src, &drawable->u.blend.src_area, - color_trans, TRUE)) { + color_trans, TRUE, &drawable->surfaces_dest[1])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + CopyRect(&drawable->surfaces_rects[1], src_rect); + drawable->u.blend.rop_decriptor = rop_info->method_data; drawable->effect = mask ? QXL_EFFECT_BLEND : rop_info->effect; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoBlackness(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask) +static BOOL DoBlackness(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area); - if (!(drawable = Drawable(pdev, QXL_DRAW_BLACKNESS, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_BLACKNESS, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + if (!QXLGetMask(pdev, drawable, &drawable->u.blackness.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top)) { + width, height, &drawable->surfaces_dest[0])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_OPAQUE; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoWhiteness(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask) +static BOOL DoWhiteness(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area); - if (!(drawable = Drawable(pdev, QXL_DRAW_WHITENESS, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_WHITENESS, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + if (!QXLGetMask(pdev, drawable, &drawable->u.whiteness.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top)) { + width, height, &drawable->surfaces_dest[0])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_OPAQUE; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoInvers(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, POINTL *mask_pos, - BOOL invers_mask) +static BOOL DoInvers(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *mask, + POINTL *mask_pos, BOOL invers_mask) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area); - if (!(drawable = Drawable(pdev, QXL_DRAW_INVERS, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_INVERS, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + if (!QXLGetMask(pdev, drawable, &drawable->u.invers.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top)) { + width, height, &drawable->surfaces_dest[0])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[0], mask_pos, width, height); + } + drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_REVERT_ON_DUP; PushDrawable(pdev, drawable); return TRUE; } -static BOOL DoROP3(PDev *pdev, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, UINT8 rop3, - SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) +static BOOL DoROP3(PDev *pdev, UINT32 surface_id, RECTL *area, CLIPOBJ *clip, SURFOBJ *src, + RECTL *src_rect, XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, + UINT8 rop3, SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) { QXLDrawable *drawable; + UINT32 width; + UINT32 height; DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); ASSERT(pdev, pdev && area && brush && src_rect && src); - if (!(drawable = Drawable(pdev, QXL_DRAW_ROP3, area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_ROP3, area, clip, surface_id))) { return FALSE; } + width = area->right - area->left; + height = area->bottom - area->top; + drawable->u.rop3.scale_mode = GdiScaleModeToQxl(scale_mode); CopyRect(&drawable->u.rop3.src_area, src_rect); - if (!QXLGetBrush(pdev, drawable, &drawable->u.rop3.brush, brush, brush_pos) || + if (!QXLGetBrush(pdev, drawable, &drawable->u.rop3.brush, brush, brush_pos, + &drawable->surfaces_dest[0], &drawable->surfaces_rects[0]) || !QXLGetMask(pdev, drawable, &drawable->u.rop3.mask, mask, mask_pos, invers_mask, - area->right - area->left, area->bottom - area->top) || + width, height, &drawable->surfaces_dest[1]) || !GetBitmap(pdev, drawable, &drawable->u.rop3.src_bitmap, src, &drawable->u.rop3.src_area, - color_trans, TRUE)) { + color_trans, TRUE, &drawable->surfaces_dest[2])) { ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } + if (mask_pos) { + CopyRectPoint(&drawable->surfaces_rects[1], mask_pos, width, height); + } + CopyRect(&drawable->surfaces_rects[2], src_rect); + drawable->u.rop3.rop3 = rop3; drawable->effect = mask ? QXL_EFFECT_BLEND : QXL_EFFECT_BLEND; //for now PushDrawable(pdev, drawable); return TRUE; } -static SURFOBJ *Copy16bppArea(PDev *pdev, RECTL *area) +static SURFOBJ *Copy16bppArea(PDev *pdev, SURFOBJ *src, RECTL *area) { SIZEL size; HSURF bitmap; @@ -843,6 +949,9 @@ static SURFOBJ *Copy16bppArea(PDev *pdev, RECTL *area) UINT8 *dest_end_line; LONG src_stride; UINT8 *src_line; + SurfaceInfo *surface; + + surface = (SurfaceInfo *)src->dhsurf; size.cx = area->right - area->left; size.cy = area->bottom - area->top; @@ -864,8 +973,9 @@ static SURFOBJ *Copy16bppArea(PDev *pdev, RECTL *area) dest_line = surf_obj->pvScan0; dest_end_line = dest_line + surf_obj->lDelta * surf_obj->sizlBitmap.cy; - src_stride = pdev->draw_surf->lDelta; - src_line = (UINT8 *)pdev->draw_surf->pvScan0 + area->top * src_stride + (area->left << 2); + src_stride = surface->draw_area.surf_obj->lDelta; + src_line = (UINT8 *)surface->draw_area.surf_obj->pvScan0 + area->top * src_stride + + (area->left << 2); for (; dest_line != dest_end_line; dest_line += surf_obj->lDelta, src_line += src_stride) { UINT16 *dest = (UINT16 *)dest_line; @@ -885,13 +995,16 @@ error: } -static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *clip, +static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *src, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *clip, XLATEOBJ *color_trans, RECTL *dest_rect, POINTL src_pos, POINTL *mask_pos, BRUSHOBJ *brush, POINTL *brush_pos, ROP4 rop4) { RECTL area; SURFOBJ* surf_obj; BOOL ret; + UINT32 surface_id; + + surface_id = GetSurfaceId(src); DEBUG_PRINT((pdev, 6, "%s\n", __FUNCTION__)); @@ -900,17 +1013,20 @@ static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *cli area.left = MAX(0, src_pos.x); area.right = MIN(src_pos.x + dest_rect->right - dest_rect->left, pdev->resolution.cx); - UpdateArea(pdev, &area); + UpdateArea(pdev, &area, surface_id); if (pdev->bitmap_format == BMF_16BPP) { - surf_obj = Copy16bppArea(pdev, &area); + surf_obj = Copy16bppArea(pdev, src, &area); if (!surf_obj) { return FALSE; } src_pos.y = src_pos.y - area.top; src_pos.x = src_pos.x - area.left; } else { - surf_obj = pdev->draw_surf; + SurfaceInfo *surface; + + surface = (SurfaceInfo *)src->dhsurf; + surf_obj = surface->draw_area.surf_obj; } if (rop4 == 0xcccc) { @@ -930,9 +1046,10 @@ static BOOL BitBltFromDev(PDev *pdev, SURFOBJ *dest, SURFOBJ *mask, CLIPOBJ *cli return ret; } -BOOL _inline __DrvBitBlt(PDev *pdev, RECTL *dest_rect, CLIPOBJ *clip, SURFOBJ *src, RECTL *src_rect, - XLATEOBJ *color_trans, BRUSHOBJ *brush, POINTL *brush_pos, ULONG rop3, - SURFOBJ *mask, POINTL *mask_pos, BOOL invers_mask, ULONG scale_mode) +BOOL _inline __DrvBitBlt(PDev *pdev, UINT32 surface_id, RECTL *dest_rect, CLIPOBJ *clip, + SURFOBJ *src, RECTL *src_rect, XLATEOBJ *color_trans, BRUSHOBJ *brush, + POINTL *brush_pos, ULONG rop3, SURFOBJ *mask, POINTL *mask_pos, + BOOL invers_mask, ULONG scale_mode) { ROP3Info *rop_info = &rops3[rop3]; @@ -940,26 +1057,27 @@ BOOL _inline __DrvBitBlt(PDev *pdev, RECTL *dest_rect, CLIPOBJ *clip, SURFOBJ *s switch (rop_info->method_type) { case ROP3_TYPE_FILL: - return DoFill(pdev, dest_rect, clip, brush, brush_pos, rop_info, mask, mask_pos, + return DoFill(pdev, surface_id, dest_rect, clip, brush, brush_pos, rop_info, mask, mask_pos, invers_mask); case ROP3_TYPE_OPAQUE: - return DoOpaque(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, - rop_info->method_data, mask, mask_pos, invers_mask, scale_mode); + return DoOpaque(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, rop_info->method_data, mask, mask_pos, invers_mask, scale_mode); case ROP3_TYPE_COPY: - return DoCopy(pdev, dest_rect, clip, src, src_rect, color_trans, rop_info->method_data, - mask, mask_pos, invers_mask, scale_mode); + return DoCopy(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, + rop_info->method_data, mask, mask_pos, invers_mask, scale_mode); case ROP3_TYPE_BLEND: - return DoBlend(pdev, dest_rect, clip, src, src_rect, color_trans, rop_info, mask, mask_pos, - invers_mask, scale_mode); + return DoBlend(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, rop_info, + mask, mask_pos, invers_mask, scale_mode); case ROP3_TYPE_BLACKNESS: - return DoBlackness(pdev, dest_rect, clip, mask, mask_pos, invers_mask); + return DoBlackness(pdev, surface_id, dest_rect, clip, mask, mask_pos, invers_mask); case ROP3_TYPE_WHITENESS: - return DoWhiteness(pdev, dest_rect, clip, mask, mask_pos, invers_mask); + return DoWhiteness(pdev, surface_id, dest_rect, clip, mask, mask_pos, invers_mask); case ROP3_TYPE_INVERS: - return DoInvers(pdev, dest_rect, clip, mask, mask_pos, invers_mask); + return DoInvers(pdev, surface_id, dest_rect, clip, mask, mask_pos, invers_mask); case ROP3_TYPE_ROP3: - return DoROP3(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, - (UINT8)rop_info->method_data, mask, mask_pos, invers_mask, scale_mode); + return DoROP3(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, (UINT8)rop_info->method_data, mask, mask_pos, invers_mask, + scale_mode); case ROP3_TYPE_NOP: return TRUE; default: @@ -1055,14 +1173,20 @@ static QXLRESULT BitBltCommon(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ * SURFOBJ *brush_mask = NULL; #endif QXLRESULT res; + UINT32 surface_id; + + ASSERT(pdev, dest->iType != STYPE_BITMAP); + + surface_id = GetSurfaceId(dest); if (!PrepareBrush(brush)) { return QXL_FAILED; } if ((rop3 = rop4 & 0xff) == (second_rop3 = ((rop4 >> 8) & 0xff))) { - return __DrvBitBlt(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, - rop3, NULL, NULL, FALSE, scale_mode) ? QXL_SUCCESS : QXL_FAILED; + return __DrvBitBlt(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, rop3, NULL, NULL, FALSE, scale_mode) ? QXL_SUCCESS : + QXL_FAILED; } if (!mask) { @@ -1080,15 +1204,17 @@ static QXLRESULT BitBltCommon(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ * } DEBUG_PRINT((pdev, 5, "%s: mask, rop4 is 0x%x\n", __FUNCTION__, rop4)); ASSERT(pdev, mask_pos); - res = (__DrvBitBlt(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, rop3, - mask, mask_pos, FALSE, scale_mode) && - __DrvBitBlt(pdev, dest_rect, clip, src, src_rect, color_trans, brush, brush_pos, - second_rop3, mask, mask_pos, TRUE, scale_mode)) ? QXL_SUCCESS : QXL_FAILED; + res = (__DrvBitBlt(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, rop3, mask, mask_pos, FALSE, scale_mode) && + __DrvBitBlt(pdev, surface_id, dest_rect, clip, src, src_rect, color_trans, brush, + brush_pos, second_rop3, mask, mask_pos, TRUE, scale_mode)) ? QXL_SUCCESS : + QXL_FAILED; #ifdef SUPPORT_BRUSH_AS_MASK if (brush_mask) { //free brush_mask; } #endif + return res; } @@ -1151,8 +1277,6 @@ static QXLRESULT _BitBlt(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, } #endif - ASSERT(pdev, dest->iType == STYPE_BITMAP || dest->hsurf == pdev->surf); - ASSERT(pdev, !src || src->iType == STYPE_BITMAP || src->hsurf == pdev->surf); ASSERT(pdev, dest_rect && dest_rect->left < dest_rect->right && dest_rect->top < dest_rect->bottom); @@ -1169,12 +1293,14 @@ static QXLRESULT _BitBlt(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, local_pos.y = src_pos->y + (area.top - dest_rect->top); if (dest->iType == STYPE_BITMAP) { - return BitBltFromDev(pdev, dest, mask, clip, color_trans, &area, local_pos, mask_pos, - brush, brush_pos, rop4) ? QXL_SUCCESS : QXL_FAILED; + return BitBltFromDev(pdev, src, dest, mask, clip, color_trans, &area, local_pos, + mask_pos, brush, brush_pos, rop4) ? QXL_SUCCESS : QXL_FAILED; } - if (src->iType != STYPE_BITMAP && rop4 == 0xcccc) { //SRCCOPY no mask - return DoCopyBits(pdev, clip, &area, &local_pos) ? QXL_SUCCESS : QXL_FAILED; + if (src->iType != STYPE_BITMAP + && GetSurfaceId(src) == GetSurfaceId(dest) && rop4 == 0xcccc) { //SRCCOPY no mask + return DoCopyBits(pdev, GetSurfaceId(src), clip, &area, &local_pos) ? + QXL_SUCCESS : QXL_FAILED; } src_rect.left = local_pos.x; @@ -1185,6 +1311,7 @@ static QXLRESULT _BitBlt(PDev *pdev, SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, } else { src_rect_ptr = NULL; } + return BitBltCommon(pdev, dest, src, mask, clip, color_trans, &area, src_rect_ptr, mask_pos, brush, brush_pos, rop4, COLORONCOLOR, NULL); } @@ -1197,14 +1324,13 @@ BOOL APIENTRY DrvBitBlt(SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, CLIPOBJ *cli QXLRESULT res; if (dest->iType == STYPE_BITMAP) { - ASSERT(NULL, src && src->iType != STYPE_BITMAP && src->dhpdev && src_pos); pdev = (PDev *)src->dhpdev; } else { - ASSERT(NULL, dest->dhpdev); pdev = (PDev *)dest->dhpdev; - CountCall(pdev, CALL_COUNTER_BIT_BLT); } + CountCall(pdev, CALL_COUNTER_BIT_BLT); + DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); if ((res = _BitBlt(pdev, dest, src, mask, clip, color_trans, dest_rect, src_pos, mask_pos, brush, brush_pos, rop4))) { @@ -1216,6 +1342,7 @@ BOOL APIENTRY DrvBitBlt(SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, CLIPOBJ *cli return FALSE; } + DEBUG_PRINT((pdev, 4, "%s: done\n", __FUNCTION__)); return TRUE; } @@ -1226,14 +1353,13 @@ BOOL APIENTRY DrvCopyBits(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, PDev *pdev; if (dest->iType == STYPE_BITMAP) { - ASSERT(NULL, src && src->iType != STYPE_BITMAP && src->dhpdev && src_pos); pdev = (PDev *)src->dhpdev; } else { - ASSERT(NULL, dest->dhpdev); pdev = (PDev *)dest->dhpdev; - CountCall(pdev, CALL_COUNTER_BIT_BLT); } + CountCall(pdev, CALL_COUNTER_BIT_BLT); + DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); return _BitBlt(pdev, dest, src, NULL, clip, color_trans, dest_rect, src_pos, NULL, NULL, @@ -1389,13 +1515,12 @@ BOOL APIENTRY DrvStretchBltROP(SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, CLIPO PDev *pdev; QXLRESULT res; - if (!src || src->iType != STYPE_BITMAP) { - ASSERT(NULL, src->dhpdev); + if (src && src->iType != STYPE_BITMAP) { pdev = (PDev *)src->dhpdev; - goto punt; + } else { + pdev = (PDev *)dest->dhpdev; } - ASSERT(NULL, dest && dest->iType != STYPE_BITMAP && dest->dhpdev); pdev = (PDev *)dest->dhpdev; DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); CountCall(pdev, CALL_COUNTER_STRETCH_BLT_ROP); @@ -1425,11 +1550,10 @@ BOOL APIENTRY DrvStretchBlt(SURFOBJ *dest, SURFOBJ *src, SURFOBJ *mask, CLIPOBJ ASSERT(NULL, src); if (src->iType != STYPE_BITMAP) { - ASSERT(NULL, src->dhpdev); pdev = (PDev *)src->dhpdev; - goto punt; + } else { + pdev = (PDev *)dest->dhpdev; } - ASSERT(NULL, dest && dest->iType != STYPE_BITMAP && dest->dhpdev); pdev = (PDev *)dest->dhpdev; DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); @@ -1522,11 +1646,11 @@ BOOL APIENTRY DrvAlphaBlend(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLATEOBJ ASSERT(NULL, src && dest); if (src->iType != STYPE_BITMAP) { - ASSERT(NULL, src->dhpdev); pdev = (PDev *)src->dhpdev; - goto punt; + } else { + pdev = (PDev *)dest->dhpdev; } - ASSERT(NULL, dest->iType != STYPE_BITMAP && dest->dhpdev); + pdev = (PDev *)dest->dhpdev; DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); @@ -1562,7 +1686,7 @@ BOOL APIENTRY DrvAlphaBlend(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLATEOBJ return TRUE; } - if (!(drawable = Drawable(pdev, QXL_DRAW_ALPHA_BLEND, &area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_ALPHA_BLEND, &area, clip, GetSurfaceId(dest)))) { DEBUG_PRINT((pdev, 0, "%s: Drawable failed\n", __FUNCTION__)); return FALSE; } @@ -1571,18 +1695,21 @@ BOOL APIENTRY DrvAlphaBlend(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLATEOBJ src_rect = &local_src; } + CopyRect(&drawable->surfaces_rects[0], src_rect); CopyRect(&drawable->u.alpha_blend.src_area, src_rect); if (bland->BlendFunction.AlphaFormat == AC_SRC_ALPHA) { ASSERT(pdev, src->iBitmapFormat == BMF_32BPP); if (!QXLGetAlphaBitmap(pdev, drawable, &drawable->u.alpha_blend.src_bitmap, src, - &drawable->u.alpha_blend.src_area)) { + &drawable->u.alpha_blend.src_area, + &drawable->surfaces_dest[0])) { DEBUG_PRINT((pdev, 0, "%s: QXLGetAlphaBitmap failed\n", __FUNCTION__)); ReleaseOutput(pdev, drawable->release_info.id); return FALSE; } } else { if (!QXLGetBitmap(pdev, drawable, &drawable->u.alpha_blend.src_bitmap, src, - &drawable->u.alpha_blend.src_area, color_trans, NULL, TRUE)) { + &drawable->u.alpha_blend.src_area, color_trans, NULL, TRUE, + &drawable->surfaces_dest[0])) { DEBUG_PRINT((pdev, 0, "%s: QXLGetBitmap failed\n", __FUNCTION__)); ReleaseOutput(pdev, drawable->release_info.id); return FALSE; @@ -1613,11 +1740,11 @@ BOOL APIENTRY DrvTransparentBlt(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLAT if (src->iType != STYPE_BITMAP) { ASSERT(NULL, src->dhpdev); pdev = (PDev *)src->dhpdev; - goto punt; + } else { + ASSERT(NULL, dest->dhpdev); + pdev = (PDev *)dest->dhpdev; } - ASSERT(NULL, dest->iType != STYPE_BITMAP && dest->dhpdev); - pdev = (PDev *)dest->dhpdev; DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); ASSERT(pdev, src_rect && src_rect->left < src_rect->right && @@ -1643,7 +1770,7 @@ BOOL APIENTRY DrvTransparentBlt(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLAT return TRUE; } - if (!(drawable = Drawable(pdev, QXL_DRAW_TRANSPARENT, &area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_TRANSPARENT, &area, clip, GetSurfaceId(dest)))) { DEBUG_PRINT((pdev, 0, "%s: Drawable failed\n", __FUNCTION__)); return FALSE; } @@ -1653,8 +1780,10 @@ BOOL APIENTRY DrvTransparentBlt(SURFOBJ *dest, SURFOBJ *src, CLIPOBJ *clip, XLAT } CopyRect(&drawable->u.transparent.src_area, src_rect); + CopyRect(&drawable->surfaces_rects[0], src_rect); if (!QXLGetBitmap(pdev, drawable, &drawable->u.transparent.src_bitmap, src, - &drawable->u.transparent.src_area, color_trans, NULL, TRUE)) { + &drawable->u.transparent.src_area, color_trans, NULL, TRUE, + &drawable->surfaces_dest[0])) { DEBUG_PRINT((pdev, 0, "%s: QXLGetBitmap failed\n", __FUNCTION__)); ReleaseOutput(pdev, drawable->release_info.id); return FALSE; diff --git a/display/sources b/display/sources index 6c1d5c7..617f42c 100644 --- a/display/sources +++ b/display/sources @@ -30,5 +30,6 @@ SOURCES=driver.c \ mspace.c \
quic.c \
surface.c \
+ dd.c \
driver.rc
diff --git a/display/surface.c b/display/surface.c index 36ae44c..f15255a 100644 --- a/display/surface.c +++ b/display/surface.c @@ -36,14 +36,18 @@ #include "res.h" #include "surface.h" -BOOL CreateDrawArea(PDev *pdev, DrawArea *drawarea, UINT8 *base_mem, UINT32 cx, UINT32 cy) +BOOL CreateDrawArea(PDev *pdev, UINT8 *base_mem, UINT32 cx, UINT32 cy, UINT32 stride, + UINT32 surface_id) { SIZEL size; + DrawArea *drawarea; size.cx = cx; size.cy = cy; - if (!(drawarea->bitmap = (HSURF)EngCreateBitmap(size, size.cx << 2, BMF_32BPP, 0, base_mem))) { + drawarea = &pdev->surfaces_info[surface_id].draw_area; + + if (!(drawarea->bitmap = (HSURF)EngCreateBitmap(size, stride, BMF_32BPP, 0, base_mem))) { DEBUG_PRINT((pdev, 0, "%s: EngCreateBitmap failed\n", __FUNCTION__)); return FALSE; } @@ -58,6 +62,8 @@ BOOL CreateDrawArea(PDev *pdev, DrawArea *drawarea, UINT8 *base_mem, UINT32 cx, goto error; } + drawarea->base_mem = base_mem; + return TRUE; error: EngDeleteSurface(drawarea->bitmap); @@ -66,15 +72,19 @@ error: VOID FreeDrawArea(DrawArea *drawarea) { - EngUnlockSurface(drawarea->surf_obj); - EngDeleteSurface(drawarea->bitmap); + if (drawarea->surf_obj) { + EngUnlockSurface(drawarea->surf_obj); + EngDeleteSurface(drawarea->bitmap); + drawarea->surf_obj = NULL; + } } HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *phys_mem, - UINT8 **base_mem, UINT8 allocation_type) + UINT8 **base_mem, UINT32 surface_id, UINT8 allocation_type) { UINT8 depth; HBITMAP surf; + UINT32 stride; switch (format) { case BMF_8BPP: @@ -93,7 +103,7 @@ HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *ph return 0; }; - if (!(surf = EngCreateDeviceBitmap((DHSURF)pdev, size, format))) { + if (!(surf = EngCreateDeviceBitmap((DHSURF)&pdev->surfaces_info[surface_id], size, format))) { DEBUG_PRINT((NULL, 0, "%s: create device surface failed, 0x%lx\n", __FUNCTION__, pdev)); goto out_error1; @@ -104,26 +114,61 @@ HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *ph HOOK_STRETCHBLTROP | HOOK_TRANSPARENTBLT | HOOK_ALPHABLEND #ifdef CALL_TEST | HOOK_PLGBLT | HOOK_FILLPATH | HOOK_STROKEANDFILLPATH | HOOK_LINETO | - HOOK_GRADIENTFILL + HOOK_GRADIENTFILL #endif )) { DEBUG_PRINT((pdev, 0, "%s: EngAssociateSurface failed\n", __FUNCTION__)); goto out_error2; } - if (!QXLGetSurface(pdev, phys_mem, size.cx, size.cy, 32, base_mem, allocation_type)) { + pdev->surfaces_info[surface_id].pdev = pdev; + + QXLGetSurface(pdev, phys_mem, size.cx, size.cy, depth, &stride, base_mem, allocation_type); + if (!*base_mem) { goto out_error2; } + if (!CreateDrawArea(pdev, *base_mem, size.cx, size.cy, stride, surface_id)) { + goto out_error3; + } + + if (allocation_type != DEVICE_BITMAP_ALLOCATION_TYPE_SURF0) { + QXLSurfaceCmd *surface; + + surface = SurfaceCmd(pdev, QXL_SURFACE_CMD_CREATE, surface_id); + surface->u.surface_create.depth = depth; + surface->u.surface_create.width = size.cx; + surface->u.surface_create.height = size.cy; + surface->u.surface_create.stride = -(INT32)stride; + surface->u.surface_create.data = *phys_mem; + PushSurfaceCmd(pdev, surface); + } + return surf; +out_error3: + QXLDelSurface(pdev, *base_mem, allocation_type); out_error2: + FreeSurface(pdev, surface_id); EngDeleteSurface((HSURF)surf); out_error1: return 0; } -VOID DeleteDeviceBitmap(HSURF surf) +VOID DeleteDeviceBitmap(PDev *pdev, UINT32 surface_id, UINT8 allocation_type) { - EngDeleteSurface(surf); + DrawArea *drawarea; + + drawarea = &pdev->surfaces_info[surface_id].draw_area; + + FreeDrawArea(drawarea); + + if (allocation_type != DEVICE_BITMAP_ALLOCATION_TYPE_SURF0 && + pdev->Res.surfaces_used[surface_id]) { + QXLSurfaceCmd *surface; + + surface = SurfaceCmd(pdev, QXL_SURFACE_CMD_DESTROY, surface_id); + QXLGetDelSurface(pdev, surface, surface_id, allocation_type); + PushSurfaceCmd(pdev, surface); + } } diff --git a/display/surface.h b/display/surface.h index a384020..e0ecc57 100644 --- a/display/surface.h +++ b/display/surface.h @@ -1,20 +1,54 @@ #ifndef SURFACE_H #define SURFACE_H +#include "qxldd.h" + +static _inline UINT32 GetSurfaceId(SURFOBJ *surf) +{ + PDev *pdev; + SurfaceInfo *surface; + UINT32 surface_id; + + pdev = (PDev *)surf->dhpdev; + + surface = (SurfaceInfo *)surf->dhsurf; + surface_id = surface - pdev->surfaces_info; + return surface_id; +} + +static _inline void FreeSurface(PDev *pdev, UINT32 surface_id) +{ + pdev->Res.surfaces_used[surface_id] = 0; +} + + +static UINT32 GetFreeSurface(PDev *pdev) +{ + UINT32 x; + + //not effective, fix me + for (x = 1; x < pdev->n_surfaces; ++x) { + if (!pdev->Res.surfaces_used[x]) { + pdev->Res.surfaces_used[x] = 1; + return x; + } + } + + return 0; +} + enum { DEVICE_BITMAP_ALLOCATION_TYPE_SURF0, + DEVICE_BITMAP_ALLOCATION_TYPE_DEVRAM, + DEVICE_BITMAP_ALLOCATION_TYPE_VRAM, }; -typedef struct DrawArea { - HSURF bitmap; - SURFOBJ* surf_obj; -} DrawArea; - -BOOL CreateDrawArea(PDev *pdev, DrawArea *drawarea, UINT8 *base_mem, UINT32 cx, UINT32 cy); +BOOL CreateDrawArea(PDev *pdev, UINT8 *base_mem, UINT32 cx, UINT32 cy, UINT32 stride, + UINT32 surface_id); VOID FreeDrawArea(DrawArea *drawarea); HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, QXLPHYSICAL *phys_mem, - UINT8 **base_mem, UINT8 allocation_type); -VOID DeleteDeviceBitmap(HSURF surf); + UINT8 **base_mem, UINT32 surface_id, UINT8 allocation_type); +VOID DeleteDeviceBitmap(PDev *pdev, UINT32 surface_id, UINT8 allocation_type); #endif diff --git a/display/text.c b/display/text.c index c661544..9d04472 100644 --- a/display/text.c +++ b/display/text.c @@ -20,6 +20,7 @@ #include "utils.h" #include "res.h" #include "rop.h" +#include "surface.h" BOOL APIENTRY DrvTextOut(SURFOBJ *surf, STROBJ *str, FONTOBJ *font, CLIPOBJ *clip, RECTL *ignored, RECTL *opaque_rect, @@ -31,12 +32,15 @@ BOOL APIENTRY DrvTextOut(SURFOBJ *surf, STROBJ *str, FONTOBJ *font, CLIPOBJ *cli ROP3Info *back_rop; PDev* pdev; RECTL area; + UINT32 surface_id; if (!(pdev = (PDev *)surf->dhpdev)) { DEBUG_PRINT((NULL, 0, "%s: err no pdev\n", __FUNCTION__)); return FALSE; } + surface_id = GetSurfaceId(surf); + CountCall(pdev, CALL_COUNTER_TEXT_OUT); DEBUG_PRINT((pdev, 3, "%s\n", __FUNCTION__)); @@ -62,13 +66,14 @@ BOOL APIENTRY DrvTextOut(SURFOBJ *surf, STROBJ *str, FONTOBJ *font, CLIPOBJ *cli } } - if (!(drawable = Drawable(pdev, QXL_DRAW_TEXT, &area, clip))) { + if (!(drawable = Drawable(pdev, QXL_DRAW_TEXT, &area, clip, surface_id))) { return FALSE; } if (opaque_rect) { ASSERT(pdev, back_brash && brushs_origin); - if (!QXLGetBrush(pdev, drawable, &drawable->u.text.back_brush, back_brash, brushs_origin)) { + if (!QXLGetBrush(pdev, drawable, &drawable->u.text.back_brush, back_brash, brushs_origin, + &drawable->surfaces_dest[0], &drawable->surfaces_rects[0])) { goto error; } CopyRect(&drawable->u.text.back_area, &area); @@ -87,7 +92,8 @@ BOOL APIENTRY DrvTextOut(SURFOBJ *surf, STROBJ *str, FONTOBJ *font, CLIPOBJ *cli if (!((fore_rop->flags | back_rop->flags) & ROP3_BRUSH)) { drawable->u.stroke.brush.type = SPICE_BRUSH_TYPE_NONE; } else if (!QXLGetBrush(pdev, drawable, &drawable->u.text.fore_brush, fore_brush, - brushs_origin)) { + brushs_origin, &drawable->surfaces_dest[1], + &drawable->surfaces_rects[1])) { DEBUG_PRINT((pdev, 0, "%s: get brush failed\n", __FUNCTION__)); goto error; } diff --git a/display/utils.h b/display/utils.h index 74f3476..124aff7 100644 --- a/display/utils.h +++ b/display/utils.h @@ -46,6 +46,12 @@ static _inline LONG RectSize(RECTL *rect) return (rect->right - rect->left) * (rect->bottom - rect->top); } +#define CopyRectPoint(dest, src, width, height) \ + (dest)->left = (src)->x; \ + (dest)->right = (src)->x + width; \ + (dest)->top = (src)->y; \ + (dest)->bottom = (src)->y + height; + #define SameRect(r1, r2) ((r1)->left == (r2)->left && (r1)->right == (r2)->right && \ (r1)->top == (r2)->top && (r1)->bottom == (r2)->bottom) |