summaryrefslogtreecommitdiff
path: root/display
diff options
context:
space:
mode:
authorIzik Eidus <ieidus@redhat.com>2010-03-31 01:47:12 +0300
committerIzik Eidus <ieidus@redhat.com>2010-04-03 05:22:53 +0300
commitf7540a4bbd89b25f2b5e9d30635897757ad52c04 (patch)
tree60b84b9251e139eeb253fff32424a913399b1561 /display
parent45162de0f8fbb30ae3b7d339188a78e0b91bdc9b (diff)
qxl driver: add off screen supprot
Signed-off-by: Izik Eidus <ieidus@redhat.com>
Diffstat (limited to 'display')
-rw-r--r--display/brush.c13
-rw-r--r--display/dd.c122
-rw-r--r--display/dd.h15
-rw-r--r--display/driver.c175
-rw-r--r--display/qxldd.h35
-rw-r--r--display/res.c249
-rw-r--r--display/res.h22
-rw-r--r--display/rop.c379
-rw-r--r--display/sources1
-rw-r--r--display/surface.c65
-rw-r--r--display/surface.h50
-rw-r--r--display/text.c12
-rw-r--r--display/utils.h6
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)