diff options
author | Izik Eidus <ieidus@redhat.com> | 2010-01-28 04:45:56 +0200 |
---|---|---|
committer | Izik Eidus <ieidus@redhat.com> | 2010-01-28 04:45:56 +0200 |
commit | 110bcba750ac55184490485b28c710ddd866c635 (patch) | |
tree | c2a061064781f275dc9f852a6b9352e2895c5321 | |
parent | e68811b7e15ffc3b6a7b4c55d450032dd0917ad9 (diff) |
win qxl driver: add surface 0 support
Signed-off-by: Izik Eidus <ieidus@redhat.com>
-rw-r--r-- | display/driver.c | 271 | ||||
-rw-r--r-- | display/qxldd.h | 109 | ||||
-rw-r--r-- | display/res.c | 428 | ||||
-rw-r--r-- | display/res.h | 2 | ||||
-rw-r--r-- | display/rop.c | 4 | ||||
-rw-r--r-- | display/sources | 1 | ||||
-rw-r--r-- | display/surface.c | 129 | ||||
-rw-r--r-- | display/surface.h | 20 | ||||
-rw-r--r-- | include/qxl_driver.h | 14 | ||||
-rw-r--r-- | miniport/qxl.c | 41 |
10 files changed, 678 insertions, 341 deletions
diff --git a/display/driver.c b/display/driver.c index 2f34240..df7c99d 100644 --- a/display/driver.c +++ b/display/driver.c @@ -34,6 +34,7 @@ #include "utils.h" #include "mspace.h" #include "res.h" +#include "surface.h" #define DEVICE_NAME L"qxldd" @@ -212,6 +213,8 @@ DEVINFO dev_default = { GCAPS2_ALPHACURSOR, }; +BOOL PrepareHardware(PDev *pdev); + static void mspace_print(void *user_data, char *format, ...) { PDev *pdev = (PDev *)user_data; @@ -237,6 +240,7 @@ BOOL DrvEnableDriver(ULONG engine_version, ULONG enable_data_size, PDRVENABLEDAT mspace_set_abort_func(mspace_abort); mspace_set_print_func(mspace_print); ResInitGlobals(); + InitGlobalRes(); DEBUG_PRINT((NULL, 1, "%s: end\n", __FUNCTION__)); return TRUE; } @@ -245,6 +249,7 @@ VOID DrvDisableDriver(VOID) { DEBUG_PRINT((NULL, 1, "%s\n", __FUNCTION__)); ResDestroyGlobals(); + CleanGlobalRes(); } DWORD GetAvailableModes(HANDLE driver, PVIDEO_MODE_INFORMATION *mode_info, @@ -554,6 +559,37 @@ VOID DrvCompletePDEV(DHPDEV in_pdev, HDEV gdi_dev) DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit\n", __FUNCTION__, pdev)); } +static VOID HideMouse(PDev *pdev) +{ + QXLCursorCmd *cursor_cmd; + + cursor_cmd = CursorCmd(pdev); + cursor_cmd->type = QXL_CURSOR_HIDE; + + PushCursorCmd(pdev, cursor_cmd); +} + +static VOID CreatePrimarySurface(PDev *pdev, UINT32 depth, UINT32 width, UINT32 height, + PHYSICAL phys_mem) +{ + pdev->primary_surface_create->depth = depth; + pdev->primary_surface_create->width = width; + pdev->primary_surface_create->height = height; + pdev->primary_surface_create->stride = -(INT32)width * 4; + pdev->primary_surface_create->mem = phys_mem; + + pdev->primary_surface_create->flags = 0; + pdev->primary_surface_create->type = QXL_SURF_TYPE_PRIMARY; + + WRITE_PORT_UCHAR(pdev->create_primary_port, 0); +} + +static void DestroyPrimarySurface(PDev *pdev) +{ + HideMouse(pdev); + WRITE_PORT_UCHAR(pdev->destroy_primary_port, 0); +} + BOOL SetHardwareMode(PDev *pdev) { VIDEO_MODE_INFORMATION video_info; @@ -572,40 +608,6 @@ BOOL SetHardwareMode(PDev *pdev) return TRUE; } -static BOOL InitDrawArea(PDev *pdev, UINT8 *base) -{ - HSURF bitmap; - SIZEL size; - SURFOBJ* surf_obj; - - size.cx = pdev->resolution.cx; - size.cy = pdev->resolution.cy; - - if (!(bitmap = (HSURF)EngCreateBitmap(size, size.cx << 2, BMF_32BPP, 0, base))) { - DEBUG_PRINT((pdev, 0, "%s: EngCreateBitmap failed\n", __FUNCTION__)); - return FALSE; - } - - if (!EngAssociateSurface(bitmap, pdev->eng, 0)) { - DEBUG_PRINT((pdev, 0, "%s: EngAssociateSurface failed\n", __FUNCTION__)); - goto error; - - } - - if (!(surf_obj = EngLockSurface(bitmap))) { - DEBUG_PRINT((pdev, 0, "%s: EngLockSurface failed\n", __FUNCTION__)); - goto error; - } - - pdev->draw_bitmap = bitmap; - pdev->draw_surf = surf_obj; - return TRUE; - -error: - EngDeleteSurface(bitmap); - return FALSE; -} - static VOID UpdateMainSlot(PDev *pdev, MemSlot *slot) { ADDRESS high_bits; @@ -630,6 +632,7 @@ BOOL PrepareHardware(PDev *pdev) ADDRESS high_bits; DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev)); + if (!SetHardwareMode(pdev)) { DEBUG_PRINT((NULL, 0, "%s: set mode failed, 0x%lx\n", __FUNCTION__, pdev)); return FALSE; @@ -659,12 +662,11 @@ BOOL PrepareHardware(PDev *pdev) pdev->WaitForEvent = dev_info.WaitForEvent; #endif - pdev->num_io_pages = dev_info.num_io_pages; + pdev->num_io_pages = dev_info.num_pages; pdev->io_pages_virt = dev_info.io_pages_virt; pdev->io_pages_phys = dev_info.io_pages_phys; pdev->dev_update_id = dev_info.update_id; - pdev->update_id = *pdev->dev_update_id; pdev->update_area_port = dev_info.update_area_port; pdev->update_area = dev_info.update_area; @@ -704,43 +706,100 @@ BOOL PrepareHardware(PDev *pdev) pdev->fb = (BYTE*)video_mem_Info.FrameBufferBase; pdev->fb_size = video_mem_Info.FrameBufferLength; - if (!InitDrawArea(pdev, dev_info.draw_area)) { - DEBUG_PRINT((NULL, 0, "%s: InitDrawArea failed, 0x%lx\n", __FUNCTION__, pdev)); - return FALSE; - } + pdev->destroy_surface_wait_port = dev_info.destroy_surface_wait_port; + pdev->create_primary_port = dev_info.create_primary_port; + pdev->destroy_primary_port = dev_info.destroy_primary_port; + + pdev->primary_memory_start = dev_info.surface0_area; + pdev->primary_memory_size = dev_info.surface0_area_size; + + pdev->primary_surface_create = dev_info.primary_surface_create; + + pdev->dev_id = dev_info.dev_id; DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit: 0x%lx %ul\n", __FUNCTION__, pdev, pdev->fb, pdev->fb_size)); return TRUE; } +static VOID UnmapFB(PDev *pdev) +{ + VIDEO_MEMORY video_mem; + DWORD length; + + if (!pdev->fb) { + return; + } + + video_mem.RequestedVirtualAddress = pdev->fb; + pdev->fb = 0; + pdev->fb_size = 0; + if (EngDeviceIoControl(pdev->driver, + IOCTL_VIDEO_UNMAP_VIDEO_MEMORY, + &video_mem, + sizeof(video_mem), + NULL, + 0, + &length)) { + DEBUG_PRINT((NULL, 0, "%s: unmpap failed, 0x%lx\n", __FUNCTION__, pdev)); + } +} + +VOID EnableQXLSurface(PDev *pdev) +{ + UINT32 depth; + + switch (pdev->bitmap_format) { + case BMF_8BPP: + PANIC(pdev, "bad formart type 8bpp\n"); + case BMF_16BPP: + depth = 16; + break; + case BMF_24BPP: + depth = 32; + break; + case BMF_32BPP: + depth = 32; + break; + default: + PANIC(pdev, "bad formart type\n"); + }; + + CreatePrimarySurface(pdev, depth, pdev->resolution.cx, pdev->resolution.cy, pdev->surf_phys); + pdev->surf_enable = TRUE; +} + HSURF DrvEnableSurface(DHPDEV in_pdev) { PDev *pdev; HSURF surf; + DWORD length; + PHYSICAL phys_mem; + UINT8 *base_mem; + DrawArea drawarea; DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, in_pdev)); + pdev = (PDev*)in_pdev; if (!PrepareHardware(pdev)) { - goto err; + return FALSE; } - InitResources(pdev); - DEBUG_PRINT((NULL, 1, "%s: EngCreateDeviceSurface(0x%lx, %ld:%ld, %lu)\n", - __FUNCTION__, - pdev, - pdev->resolution.cx, - pdev->resolution.cy, - pdev->bitmap_format)); - - if (!(surf = (HSURF)EngCreateDeviceSurface((DHSURF)pdev, pdev->resolution, - pdev->bitmap_format))) { + if (!(surf = (HSURF)CreateDeviceBitmap(pdev, pdev->resolution, pdev->bitmap_format, &phys_mem, + &base_mem, 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__, @@ -751,24 +810,11 @@ HSURF DrvEnableSurface(DHPDEV in_pdev) pdev->stride)); pdev->surf = surf; - if (!EngModifySurface(surf, pdev->eng, - HOOK_SYNCHRONIZE | HOOK_COPYBITS | HOOK_BITBLT | HOOK_TEXTOUT | - HOOK_STROKEPATH | HOOK_STRETCHBLT | HOOK_STRETCHBLTROP | - HOOK_TRANSPARENTBLT | HOOK_ALPHABLEND -#ifdef CALL_TEST - | HOOK_PLGBLT | HOOK_FILLPATH | HOOK_STROKEANDFILLPATH | HOOK_LINETO | - HOOK_GRADIENTFILL -#endif - , - MS_NOTSYSTEMMEMORY, - (DHSURF)pdev, - NULL, - 0, - NULL)) { - DEBUG_PRINT((NULL, 0, "%s: modify surface failed, 0x%lx\n", - __FUNCTION__, pdev)); - goto err; - } + pdev->surf_phys = phys_mem; + pdev->surf_base = base_mem; + + EnableQXLSurface(pdev); + DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit\n", __FUNCTION__, pdev)); return surf; @@ -778,81 +824,62 @@ err: return NULL; } +VOID DisableQXLSurface(PDev *pdev) +{ + DrawArea drawarea; + + if (pdev->surf_enable) { + DestroyPrimarySurface(pdev); + SyncResources(pdev); + pdev->surf_enable = FALSE; + } +} + VOID DrvDisableSurface(DHPDEV in_pdev) { PDev *pdev = (PDev*)in_pdev; + DrawArea drawarea; DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev)); - if (pdev->mem_slots) { - EngFreeMem(pdev->mem_slots); - pdev->mem_slots = NULL; - } + DisableQXLSurface(pdev); + + UnmapFB(pdev); if (pdev->surf) { - EngDeleteSurface(pdev->surf); + DeleteDeviceBitmap(pdev->surf); pdev->surf = NULL; } if (pdev->draw_surf) { - EngUnlockSurface(pdev->draw_surf); + drawarea.bitmap = pdev->draw_bitmap; + drawarea.surf_obj = pdev->draw_surf; + FreeDrawArea(&drawarea); pdev->draw_surf = NULL; - EngDeleteSurface(pdev->draw_bitmap); pdev->draw_bitmap = NULL; } - if (pdev->fb) { - VIDEO_MEMORY video_mem; - DWORD length; - - video_mem.RequestedVirtualAddress = pdev->fb; - pdev->fb = 0; - pdev->fb_size = 0; - if (EngDeviceIoControl(pdev->driver, - IOCTL_VIDEO_UNMAP_VIDEO_MEMORY, - &video_mem, - sizeof(video_mem), - NULL, - 0, - &length)) { - DEBUG_PRINT((NULL, 0, "%s: unmpap failed, 0x%lx\n", __FUNCTION__, pdev)); - } + if (pdev->mem_slots) { + EngFreeMem(pdev->mem_slots); + pdev->mem_slots = NULL; } + DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit\n", __FUNCTION__, pdev)); } BOOL DrvAssertMode(DHPDEV in_pdev, BOOL enable) { PDev* pdev = (PDev*)in_pdev; - BOOL ret; DEBUG_PRINT((NULL, 1, "%s: 0x%lx\n", __FUNCTION__, pdev)); if (enable) { - DWORD length; - QXLDriverInfo dev_info; - - ret = SetHardwareMode(pdev); - if (!ret || EngDeviceIoControl(pdev->driver, IOCTL_QXL_GET_INFO, NULL, - 0, &dev_info, sizeof(QXLDriverInfo), &length) ) { - DEBUG_PRINT((NULL, 0, "%s: get qxl info failed, 0x%lx\n", __FUNCTION__, pdev)); - ret = FALSE; - } - - UpdateMainSlot(pdev, &dev_info.main_mem_slot); - InitResources(pdev); + EnableQXLSurface(pdev); } else { - DWORD length; - if (EngDeviceIoControl(pdev->driver, IOCTL_VIDEO_RESET_DEVICE, - NULL, 0, NULL, 0, &length)) { - DEBUG_PRINT((NULL, 0, "%s: reset failed 0x%lx\n", __FUNCTION__, pdev)); - ret = FALSE; - } else { - ret = TRUE; - } + DisableQXLSurface(pdev); } - DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit %s\n", __FUNCTION__, pdev, ret ? "TRUE" : "FALSE")); - return ret; + DEBUG_PRINT((NULL, 1, "%s: 0x%lx exit TRUE\n", __FUNCTION__, pdev)); + return TRUE; } ULONG DrvGetModes(HANDLE driver, ULONG dev_modes_size, DEVMODEW *dev_modes) @@ -1242,20 +1269,20 @@ err: void CountCall(PDev *pdev, int counter) { - if (pdev->count_calls) { + if (pdev->Res.count_calls) { int i; - pdev->call_counters[counter]++; - if((++pdev->total_calls % 500) == 0) { - DEBUG_PRINT((pdev, 0, "total eng calls is %u\n", pdev->total_calls)); + pdev->Res.call_counters[counter]++; + if((++pdev->Res.total_calls % 500) == 0) { + DEBUG_PRINT((pdev, 0, "total eng calls is %u\n", pdev->Res.total_calls)); for (i = 0; i < NUM_CALL_COUNTERS; i++) { DEBUG_PRINT((pdev, 0, "%s count is %u\n", - counters_info[i].name, pdev->call_counters[i])); + counters_info[i].name, pdev->Res.call_counters[i])); } } - pdev->count_calls = FALSE; + pdev->Res.count_calls = FALSE; } else if (counters_info[counter].effective) { - pdev->count_calls = TRUE; + pdev->Res.count_calls = TRUE; } } diff --git a/display/qxldd.h b/display/qxldd.h index 67ea68b..9283c43 100644 --- a/display/qxldd.h +++ b/display/qxldd.h @@ -51,6 +51,11 @@ #define ONDBG(x) #endif +#define PANIC(pdev, str) { \ + DebugPrint(pdev, 0, "PANIC: %s @ %s\n", str, __FUNCTION__); \ + EngDebugBreak(); \ +} + typedef enum { QXL_SUCCESS, QXL_FAILED, @@ -135,11 +140,55 @@ typedef struct PMemSlot { ADDRESS high_bits; } PMemSlot; +typedef struct DevResDynamic { + CacheImage cache_image_pool[IMAGE_POOL_SIZE]; + Ring cache_image_lru; + Ring cursors_lru; + Ring palette_lru; +} DevResDynamic; + +typedef struct DevRes { + mspace _mspace; + UINT8 *mspace_start; + UINT8 *mspace_end; + BOOL need_init; + UINT64 free_outputs; + UINT32 update_id; + + DevResDynamic *dynamic; + + ImageKey image_key_lookup[IMAGE_KEY_HASH_SIZE]; + struct CacheImage *image_cache[IMAGE_HASH_SIZE]; + struct InternalCursor *cursor_cache[CURSOR_HASH_SIZE]; + UINT32 num_cursors; + UINT32 last_cursor_id; + struct InternalPalette *palette_cache[PALETTE_HASH_SIZE]; + UINT32 num_palettes; + +#ifdef DBG + int num_free_pages; + int num_outputs; + int num_path_pages; + int num_rects_pages; + int num_bits_pages; + int num_buf_pages; + int num_glyphs_pages; + int num_cursor_pages; +#endif + +#ifdef CALL_TEST + BOOL count_calls; + UINT32 total_calls; + UINT32 call_counters[NUM_CALL_COUNTERS]; +#endif +} DevRes; + typedef struct PDev { HANDLE driver; HDEV eng; HPALETTE palette; HSURF surf; + UINT8 surf_enable; DWORD video_mode_index; SIZEL resolution; UINT32 max_bitmap_size; @@ -152,6 +201,9 @@ typedef struct PDev { FLONG blue_mask; ULONG fp_state_size; + PHYSICAL surf_phys; + UINT8 *surf_base; + QuicData *quic_data; QXLCommandRing *cmd_ring; @@ -185,13 +237,6 @@ typedef struct PDev { UINT8 *io_pages_virt; UINT64 io_pages_phys; - mspace mspace; - UINT8 *mspace_start; - UINT8 *mspace_end; - - UINT64 free_outputs; - - UINT32 update_id; UINT32 *dev_update_id; UINT32 update_area_port; @@ -201,51 +246,37 @@ typedef struct PDev { UINT32 *compression_level; - ImageKey image_key_lookup[IMAGE_KEY_HASH_SIZE]; - CacheImage cache_image_pool[IMAGE_POOL_SIZE]; - Ring cache_image_lru; - struct CacheImage *image_cache[IMAGE_HASH_SIZE]; - - struct InternalCursor *cursor_cache[CURSOR_HASH_SIZE]; - Ring cursors_lru; - UINT32 num_cursors; - UINT32 last_cursor_id; FLONG cursor_trail; - struct InternalPalette *palette_cache[PALETTE_HASH_SIZE]; - Ring palette_lru; - UINT32 num_palettes; +#if (WINVER < 0x0501) + PQXLWaitForEvent WaitForEvent; +#endif - Ring update_trace; - UpdateTrace update_trace_items[NUM_UPDATE_TRACE_ITEMS]; + UINT32 create_primary_port; + UINT32 destroy_primary_port; + UINT32 destroy_surface_wait_port; -#ifdef DBG - int num_free_pages; - int num_outputs; - int num_path_pages; - int num_rects_pages; - int num_bits_pages; - int num_buf_pages; - int num_glyphs_pages; - int num_cursor_pages; -#endif + UINT8* primary_memory_start; + UINT32 primary_memory_size; -#ifdef CALL_TEST - BOOL count_calls; - UINT32 total_calls; - UINT32 call_counters[NUM_CALL_COUNTERS]; -#endif + QXLSurfaceCreate *primary_surface_create; -#if (WINVER < 0x0501) - PQXLWaitForEvent WaitForEvent; -#endif + UINT32 dev_id; + + DevRes Res; + + Ring update_trace; + UpdateTrace update_trace_items[NUM_UPDATE_TRACE_ITEMS]; } PDev; void DebugPrintV(PDev *pdev, const char *message, va_list ap); void DebugPrint(PDev *pdev, int level, const char *message, ...); +void InitGlobalRes(); +void CleanGlobalRes(); void InitResources(PDev *pdev); +void SyncResources(PDev *pdev); #ifdef CALL_TEST void CountCall(PDev *pdev, int counter); diff --git a/display/res.c b/display/res.c index cea01c6..02ec6d7 100644 --- a/display/res.c +++ b/display/res.c @@ -107,7 +107,7 @@ UINT64 ReleaseOutput(PDev *pdev, UINT64 output_id) next = *(UINT64*)output->data; FreeMem(pdev, output); DEBUG_PRINT((pdev, 10, "%s done\n", __FUNCTION__)); - ONDBG(pdev->num_outputs--); //todo: atomic + ONDBG(pdev->Res.num_outputs--); //todo: atomic return next; } @@ -164,9 +164,9 @@ static void WaitForCursorRing(PDev* pdev) } #else #if (WINVER < 0x0501) - pdev->WaitForEvent(pdev->cursor_event, NULL); + pdev->WaitForEvent(pdev->cursor_event, NULL); #else - EngWaitForSingleObject(pdev->cursor_event, NULL); + EngWaitForSingleObject(pdev->cursor_event, NULL); #endif // (WINVER < 0x0501) #endif //DBG } @@ -200,9 +200,9 @@ static void WaitForCmdRing(PDev* pdev) } #else #if (WINVER < 0x0501) - pdev->WaitForEvent(pdev->display_event, NULL); + pdev->WaitForEvent(pdev->display_event, NULL); #else - EngWaitForSingleObject(pdev->display_event, NULL); + EngWaitForSingleObject(pdev->display_event, NULL); #endif // (WINVER < 0x0501) #endif //DBG } @@ -247,14 +247,14 @@ static void WaitForReleaseRing(PDev* pdev) #ifdef DBG DEBUG_PRINT((pdev, 0, "%s: 0x%lx: timeout\n", __FUNCTION__, pdev)); DEBUG_PRINT((pdev, 0, "\tfree %d out %d path %d rect %d bits %d\n", - pdev->num_free_pages, - pdev->num_outputs, - pdev->num_path_pages, - pdev->num_rects_pages, - pdev->num_bits_pages, - pdev->num_buf_pages, - pdev->num_glyphs_pages, - pdev->num_cursor_pages)); + pdev->Res.num_free_pages, + pdev->Res.num_outputs, + pdev->Res.num_path_pages, + pdev->Res.num_rects_pages, + pdev->Res.num_bits_pages, + pdev->Res.num_buf_pages, + pdev->Res.num_glyphs_pages, + pdev->Res.num_cursor_pages)); #endif //oom WRITE_PORT_UCHAR(pdev->notify_oom_port, 0); @@ -263,91 +263,184 @@ static void WaitForReleaseRing(PDev* pdev) DEBUG_PRINT((pdev, 16, "%s: 0x%lx, done\n", __FUNCTION__, pdev)); } -static void InitMspace(PDev *pdev) -{ - size_t capacity = pdev->num_io_pages * PAGE_SIZE; - pdev->mspace = create_mspace_with_base(pdev->io_pages_virt, capacity, 0, pdev); - pdev->mspace_start = pdev->io_pages_virt; - pdev->mspace_end = pdev->io_pages_virt + capacity; -} - static void *AllocMem(PDev* pdev, size_t size) { UINT8 *ptr; - ASSERT(pdev, pdev && pdev->mspace); + ASSERT(pdev, pdev && pdev->Res._mspace); DEBUG_PRINT((pdev, 12, "%s: 0x%lx size %u\n", __FUNCTION__, pdev, size)); EngAcquireSemaphore(pdev->malloc_sem); - while (!(ptr = mspace_malloc(pdev->mspace, size))) { + while (!(ptr = mspace_malloc(pdev->Res._mspace, size))) { int notify; - if (pdev->free_outputs) { - pdev->free_outputs = ReleaseOutput(pdev, pdev->free_outputs); + if (pdev->Res.free_outputs) { + pdev->Res.free_outputs = ReleaseOutput(pdev, pdev->Res.free_outputs); continue; } WaitForReleaseRing(pdev); - pdev->free_outputs = *RING_CONS_ITEM(pdev->release_ring); + pdev->Res.free_outputs = *RING_CONS_ITEM(pdev->release_ring); RING_POP(pdev->release_ring, notify); } EngReleaseSemaphore(pdev->malloc_sem); - ASSERT(pdev, ptr >= pdev->mspace_start && ptr < pdev->mspace_end); + ASSERT(pdev, ptr >= pdev->Res.mspace_start && ptr < pdev->Res.mspace_end); DEBUG_PRINT((pdev, 13, "%s: 0x%lx done 0x%x\n", __FUNCTION__, pdev, ptr)); return ptr; } static void FreeMem(PDev* pdev, void *ptr) { - ASSERT(pdev, pdev && pdev->mspace); - ASSERT(pdev, (UINT8 *)ptr >= pdev->mspace_start && (UINT8 *)ptr < pdev->mspace_end); - mspace_free(pdev->mspace, ptr); + ASSERT(pdev, pdev && pdev->Res._mspace); + ASSERT(pdev, (UINT8 *)ptr >= pdev->Res.mspace_start && (UINT8 *)ptr < + pdev->Res.mspace_end); + mspace_free(pdev->Res._mspace, ptr); } -void InitResources(PDev *pdev) +DevRes *global_res = NULL; +UINT8 num_global_res = 0; +HSEMAPHORE res_sem = NULL; + +void CleanGlobalRes() +{ + UINT32 i; + + if (!global_res) { + for (i = 0; i < num_global_res; ++i) { + if (global_res[i].dynamic) { + EngFreeMem(global_res[i].dynamic); + global_res[i].dynamic = NULL; + } + } + EngFreeMem(global_res); + global_res = NULL; + } + num_global_res = 0; + if (res_sem) { + EngDeleteSemaphore(res_sem); + res_sem = NULL; + } +} + +void InitGlobalRes() +{ + CleanGlobalRes(); + res_sem = EngCreateSemaphore(); + if (!res_sem) { + EngDebugBreak(); + } +} + +static void InitMspace(DevRes *res, UINT8 *io_pages_virt, size_t capacity) { - int i; + res->_mspace = create_mspace_with_base(io_pages_virt, capacity, 0, NULL); + res->mspace_start = io_pages_virt; + res->mspace_end = io_pages_virt + capacity; +} - pdev->free_outputs = 0; - InitMspace(pdev); - pdev->update_id = *pdev->dev_update_id; +static void InitRes(PDev *pdev) +{ + UINT32 i; + + pdev->Res.dynamic = EngAllocMem(FL_ZERO_MEMORY, sizeof(DevResDynamic), ALLOC_TAG); + if (!pdev->Res.dynamic) { + PANIC(pdev, "Res dynamic allocation failed\n"); + } - RtlZeroMemory(pdev->image_key_lookup, sizeof(pdev->image_key_lookup)); - RtlZeroMemory(pdev->cache_image_pool, sizeof(pdev->cache_image_pool)); - RingInit(&pdev->cache_image_lru); + 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; + + RtlZeroMemory(pdev->Res.image_key_lookup, + sizeof(pdev->Res.image_key_lookup)); + RtlZeroMemory(pdev->Res.dynamic->cache_image_pool, + sizeof(pdev->Res.dynamic->cache_image_pool)); + RingInit(&pdev->Res.dynamic->cache_image_lru); for (i = 0; i < IMAGE_POOL_SIZE; i++) { - RingAdd(pdev, &pdev->cache_image_lru, &pdev->cache_image_pool[i].lru_link); + RingAdd(pdev, &pdev->Res.dynamic->cache_image_lru, + &pdev->Res.dynamic->cache_image_pool[i].lru_link); } - RtlZeroMemory(pdev->image_cache, sizeof(pdev->image_cache)); - RtlZeroMemory(pdev->cursor_cache, sizeof(pdev->cursor_cache)); - RingInit(&pdev->cursors_lru); - pdev->num_cursors = 0; - pdev->last_cursor_id = 0; + RtlZeroMemory(pdev->Res.image_cache, sizeof(pdev->Res.image_cache)); + RtlZeroMemory(pdev->Res.cursor_cache, sizeof(pdev->Res.cursor_cache)); + RingInit(&pdev->Res.dynamic->cursors_lru); + pdev->Res.num_cursors = 0; + pdev->Res.last_cursor_id = 0; + + RtlZeroMemory(pdev->Res.palette_cache, sizeof(pdev->Res.palette_cache)); + RingInit(&pdev->Res.dynamic->palette_lru); + pdev->Res.num_palettes = 0; - RtlZeroMemory(pdev->palette_cache, sizeof(pdev->palette_cache)); - RingInit(&pdev->palette_lru); - pdev->num_palettes = 0; + ONDBG(pdev->Res.num_outputs = 0); + ONDBG(pdev->Res.num_path_pages = 0); + ONDBG(pdev->Res.num_rects_pages = 0); + ONDBG(pdev->Res.num_bits_pages = 0); + ONDBG(pdev->Res.num_buf_pages = 0); + ONDBG(pdev->Res.num_glyphs_pages = 0); + ONDBG(pdev->Res.num_cursor_pages = 0); + +#ifdef CALL_TEST + pdev->Res.count_calls = TRUE; + pdev->Res.total_calls = 0; + for (i = 0; i < NUM_CALL_COUNTERS; i++) { + pdev->Res.call_counters[i] = 0; + } +#endif +} + +void InitResources(PDev *pdev) +{ + UINT32 i; + UINT32 id; + DevRes *new_global_res; RtlZeroMemory(pdev->update_trace_items, sizeof(pdev->update_trace_items)); RingInit(&pdev->update_trace); for (i = 0; i < NUM_UPDATE_TRACE_ITEMS; i++) { - RingAdd(pdev, &pdev->update_trace, &pdev->update_trace_items[i].link); + RingAdd(pdev, &pdev->update_trace, &pdev->update_trace_items[i].link); } - ONDBG(pdev->num_outputs = 0); - ONDBG(pdev->num_path_pages = 0); - ONDBG(pdev->num_rects_pages = 0); - ONDBG(pdev->num_bits_pages = 0); - ONDBG(pdev->num_buf_pages = 0); - ONDBG(pdev->num_glyphs_pages = 0); - ONDBG(pdev->num_cursor_pages = 0); + EngAcquireSemaphore(res_sem); -#ifdef CALL_TEST - pdev->count_calls = TRUE; - pdev->total_calls = 0; - for (i = 0; i < NUM_CALL_COUNTERS; i++) { - pdev->call_counters[i] = 0; + id = pdev->dev_id; + if (num_global_res > id) { + if (!global_res[id].dynamic) { + InitRes(pdev); + } else { + pdev->Res = global_res[id]; + } + EngReleaseSemaphore(res_sem); + return; } -#endif + + new_global_res = EngAllocMem(FL_ZERO_MEMORY, (id + 1) * sizeof(DevRes), ALLOC_TAG); + if (!new_global_res) { + PANIC(pdev, "new_global_res malloc failed\n"); + } + for (i = 0; i < num_global_res; ++i) { + new_global_res[i] = global_res[i]; + } + if (global_res) { + EngFreeMem(global_res); + } + num_global_res = id + 1; + global_res = new_global_res; + InitRes(pdev); + + EngReleaseSemaphore(res_sem); +} + +void SyncResources(PDev *pdev) +{ + UINT32 id; + DevRes *res; + + EngAcquireSemaphore(res_sem); + + id = pdev->dev_id; + res = &global_res[id]; + + *res = pdev->Res; + + EngReleaseSemaphore(res_sem); } static QXLDrawable *GetDrawable(PDev *pdev) @@ -358,8 +451,8 @@ static QXLDrawable *GetDrawable(PDev *pdev) output->num_res = 0; ((QXLDrawable *)output->data)->release_info.id = (UINT64)output; DEBUG_PRINT((pdev, 9, "%s 0x%x\n", __FUNCTION__, output)); - ONDBG(pdev->num_outputs++); //todo: atomic - return (QXLDrawable *)output->data; + ONDBG(pdev->Res.num_outputs++); //todo: atomic + return(QXLDrawable *)output->data; } QXLDrawable *Drawable(PDev *pdev, UINT8 type, RECTL *area, CLIPOBJ *clip) @@ -371,7 +464,7 @@ QXLDrawable *Drawable(PDev *pdev, UINT8 type, RECTL *area, CLIPOBJ *clip) drawable = GetDrawable(pdev); drawable->type = type; drawable->effect = QXL_EFFECT_BLEND; - drawable->bitmap_offset = 0; + drawable->self_bitmap = 0; drawable->mm_time = *pdev->mm_clock; CopyRect(&drawable->bbox, area); @@ -394,6 +487,25 @@ void PushDrawable(PDev *pdev, QXLDrawable *drawable) PUSH_CMD(pdev); } +_inline void GetSurfaceMemory(PDev *pdev, UINT32 x, UINT32 y, UINT32 depth, UINT8 **base_mem, + PHYSICAL *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); + + *base_mem = pdev->primary_memory_start; + *phys_mem = PA(pdev, *base_mem, pdev->main_mem_slot); +} + +BOOL QXLGetSurface(PDev *pdev, PHYSICAL *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; +} + static void FreePath(PDev *pdev, Resource *res) { PHYSICAL chunk_phys; @@ -405,10 +517,10 @@ static void FreePath(PDev *pdev, Resource *res) QXLDataChunk *chunk = (QXLDataChunk *)VA(pdev, chunk_phys, pdev->main_mem_slot); chunk_phys = chunk->next_chunk; FreeMem(pdev, chunk); - ONDBG(pdev->num_path_pages--); + ONDBG(pdev->Res.num_path_pages--); } FreeMem(pdev, res); - ONDBG(pdev->num_path_pages--); + ONDBG(pdev->Res.num_path_pages--); DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__)); } @@ -426,9 +538,9 @@ static void FreePath(PDev *pdev, Resource *res) } #ifdef DBG -#define GetPathCommon __GetPathCommon + #define GetPathCommon __GetPathCommon #else -#define GetPathCommon(pdev, path, chunk_ptr, now_ptr, end_ptr, data_size, page_counter)\ + #define GetPathCommon(pdev, path, chunk_ptr, now_ptr, end_ptr, data_size, page_counter)\ __GetPathCommon(pdev, path, chunk_ptr, now_ptr, end_ptr, data_size, NULL) #endif @@ -457,7 +569,7 @@ static void __GetPathCommon(PDev *pdev, PATHOBJ *path, QXLDataChunk **chunk_ptr, more = PATHOBJ_bEnum(path, &data); if (data.count == 0) { - break; + break; } if (end - now < sizeof(PathSeg)) { @@ -512,7 +624,7 @@ static Resource *__GetPath(PDev *pdev, PATHOBJ *path) DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__)); res = AllocMem(pdev, PATH_ALLOC_SIZE); - ONDBG(pdev->num_path_pages++); + ONDBG(pdev->Res.num_path_pages++); res->refs = 1; res->free = FreePath; @@ -525,7 +637,8 @@ static Resource *__GetPath(PDev *pdev, PATHOBJ *path) now = chunk->data; end = (UINT8 *)res + PATH_ALLOC_SIZE; - GetPathCommon(pdev, path, &chunk, &now, &end, &qxl_path->data_size, &pdev->num_path_pages); + GetPathCommon(pdev, path, &chunk, &now, &end, &qxl_path->data_size, + &pdev->Res.num_path_pages); DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__)); return res; @@ -557,10 +670,10 @@ static void FreeClipRects(PDev *pdev, Resource *res) QXLDataChunk *chunk = (QXLDataChunk *)VA(pdev, chunk_phys, pdev->main_mem_slot); chunk_phys = chunk->next_chunk; FreeMem(pdev, chunk); - ONDBG(pdev->num_rects_pages--); + ONDBG(pdev->Res.num_rects_pages--); } FreeMem(pdev, res); - ONDBG(pdev->num_rects_pages--); + ONDBG(pdev->Res.num_rects_pages--); DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__)); } @@ -583,7 +696,7 @@ static Resource *GetClipRects(PDev *pdev, CLIPOBJ *clip) DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__)); res = (Resource *)AllocMem(pdev, RECTS_ALLOC_SIZE); - ONDBG(pdev->num_rects_pages++); + ONDBG(pdev->Res.num_rects_pages++); res->refs = 1; res->free = FreeClipRects; rects = (QXLClipRects *)res->res; @@ -608,10 +721,10 @@ static Resource *GetClipRects(PDev *pdev, CLIPOBJ *clip) more = CLIPOBJ_bEnum(clip, sizeof(buf), (ULONG *)&buf); rects->num_rects += buf.count; - for(now = buf.rects, end = now + buf.count; now < end; now++, dest++) { + for (now = buf.rects, end = now + buf.count; now < end; now++, dest++) { if (dest == dest_end) { void *page = AllocMem(pdev, RECTS_CHUNK_ALLOC_SIZE); - ONDBG(pdev->num_rects_pages++); + ONDBG(pdev->Res.num_rects_pages++); chunk->next_chunk = PA(pdev, page, pdev->main_mem_slot); ((QXLDataChunk *)page)->prev_chunk = PA(pdev, chunk, pdev->main_mem_slot); chunk = (QXLDataChunk *)page; @@ -686,13 +799,13 @@ static BOOL SetClip(PDev *pdev, CLIPOBJ *clip, QXLDrawable *drawable) } #ifdef DBG -#define PutBytesAlign __PutBytesAlign -#define PutBytes(pdev, chunk, now, end, src, size, page_counter, alloc_size)\ + #define PutBytesAlign __PutBytesAlign + #define PutBytes(pdev, chunk, now, end, src, size, page_counter, alloc_size)\ __PutBytesAlign(pdev, chunk, now, end, src, size, page_counter, alloc_size, 1) #else -#define PutBytesAlign(pdev, chunk, now, end, src, size, page_counter, alloc_size, alignment)\ + #define PutBytesAlign(pdev, chunk, now, end, src, size, page_counter, alloc_size, alignment)\ __PutBytesAlign(pdev, chunk, now, end, src, size, NULL, alloc_size, alignment) -#define PutBytes(pdev, chunk, now, end, src, size, page_counter, alloc_size)\ + #define PutBytes(pdev, chunk, now, end, src, size, page_counter, alloc_size)\ __PutBytesAlign(pdev, chunk, now, end, src, size, NULL, alloc_size, 1) #endif @@ -742,7 +855,7 @@ typedef struct InternalImage { void ImageKeyPut(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 key) { - ImageKey *image_key = &pdev->image_key_lookup[IMAGE_KEY_HASH_VAL(hsurf)]; + ImageKey *image_key = &pdev->Res.image_key_lookup[IMAGE_KEY_HASH_VAL(hsurf)]; if (!unique) { return; @@ -759,7 +872,7 @@ BOOL ImageKeyGet(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 *key) if (!unique) { return FALSE; } - image_key = &pdev->image_key_lookup[IMAGE_KEY_HASH_VAL(hsurf)]; + image_key = &pdev->Res.image_key_lookup[IMAGE_KEY_HASH_VAL(hsurf)]; if (image_key->hsurf == hsurf && image_key->unique == unique) { *key = image_key->key; return TRUE; @@ -772,11 +885,11 @@ BOOL ImageKeyGet(PDev *pdev, HSURF hsurf, UINT64 unique, UINT32 *key) static CacheImage *ImageCacheGetByKey(PDev *pdev, UINT32 key, BOOL check_rest, UINT8 format, UINT32 width, UINT32 height) { - CacheImage *cache_image = pdev->image_cache[IMAGE_HASH_VAL(key)]; + CacheImage *cache_image = pdev->Res.image_cache[IMAGE_HASH_VAL(key)]; while (cache_image) { if (cache_image->key == key && (!check_rest || (cache_image->format == format && - cache_image->width == width && cache_image->height == height))) { + cache_image->width == width && cache_image->height == height))) { cache_image->hits++; return cache_image; } @@ -788,9 +901,9 @@ static CacheImage *ImageCacheGetByKey(PDev *pdev, UINT32 key, BOOL check_rest, static void ImageCacheAdd(PDev *pdev, CacheImage *cache_image) { int key = IMAGE_HASH_VAL(cache_image->key); - cache_image->next = pdev->image_cache[key]; + cache_image->next = pdev->Res.image_cache[key]; cache_image->hits = 1; - pdev->image_cache[key] = cache_image; + pdev->Res.image_cache[key] = cache_image; } static void ImageCacheRemove(PDev *pdev, CacheImage *cache_image) @@ -800,7 +913,7 @@ static void ImageCacheRemove(PDev *pdev, CacheImage *cache_image) if (!cache_image->hits) { return; } - cache_img = &pdev->image_cache[IMAGE_HASH_VAL(cache_image->key)]; + cache_img = &pdev->Res.image_cache[IMAGE_HASH_VAL(cache_image->key)]; while (*cache_img) { if ((*cache_img)->key == cache_image->key) { *cache_img = cache_image->next; @@ -813,15 +926,14 @@ static void ImageCacheRemove(PDev *pdev, CacheImage *cache_image) static CacheImage *AllocCacheImage(PDev* pdev) { RingItem *item; - - while (!(item = RingGetTail(pdev, &pdev->cache_image_lru))) { + while (!(item = RingGetTail(pdev, &pdev->Res.dynamic->cache_image_lru))) { int notify; - if (pdev->free_outputs) { - pdev->free_outputs = ReleaseOutput(pdev, pdev->free_outputs); + if (pdev->Res.free_outputs) { + pdev->Res.free_outputs = ReleaseOutput(pdev, pdev->Res.free_outputs); continue; } WaitForReleaseRing(pdev); - pdev->free_outputs = *RING_CONS_ITEM(pdev->release_ring); + pdev->Res.free_outputs = *RING_CONS_ITEM(pdev->release_ring); RING_POP(pdev->release_ring, notify); } RingRemove(pdev, item); @@ -873,14 +985,14 @@ static _inline void PaletteCacheRemove(PDev *pdev, InternalPalette *palette) DEBUG_PRINT((pdev, 15, "%s\n", __FUNCTION__)); ASSERT(pdev, palette->palette.unique); - internal = &pdev->palette_cache[PALETTE_HASH_VAL(palette->palette.unique)]; + internal = &pdev->Res.palette_cache[PALETTE_HASH_VAL(palette->palette.unique)]; while (*internal) { if ((*internal)->palette.unique == palette->palette.unique) { *internal = palette->next; RingRemove(pdev, &palette->lru_link); ReleasePalette(pdev, palette); - pdev->num_palettes--; + pdev->Res.num_palettes--; DEBUG_PRINT((pdev, 16, "%s: done\n", __FUNCTION__)); return; } @@ -898,11 +1010,11 @@ static _inline InternalPalette *PaletteCacheGet(PDev *pdev, UINT32 unique) return NULL; } - now = pdev->palette_cache[PALETTE_HASH_VAL(unique)]; + now = pdev->Res.palette_cache[PALETTE_HASH_VAL(unique)]; while (now) { if (now->palette.unique == unique) { RingRemove(pdev, &now->lru_link); - RingAdd(pdev, &pdev->palette_lru, &now->lru_link); + RingAdd(pdev, &pdev->Res.dynamic->palette_lru, &now->lru_link); now->refs++; DEBUG_PRINT((pdev, 13, "%s: found\n", __FUNCTION__)); return now; @@ -924,19 +1036,19 @@ static _inline void PaletteCacheAdd(PDev *pdev, InternalPalette *palette) return; } - if (pdev->num_palettes == PALETTE_CACHE_SIZE) { - ASSERT(pdev, RingGetTail(pdev, &pdev->palette_lru)); - PaletteCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->palette_lru), - InternalPalette, lru_link)); + if (pdev->Res.num_palettes == PALETTE_CACHE_SIZE) { + ASSERT(pdev, RingGetTail(pdev, &pdev->Res.dynamic->palette_lru)); + PaletteCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->Res.dynamic->palette_lru), + InternalPalette, lru_link)); } key = PALETTE_HASH_VAL(palette->palette.unique); - palette->next = pdev->palette_cache[key]; - pdev->palette_cache[key] = palette; + palette->next = pdev->Res.palette_cache[key]; + pdev->Res.palette_cache[key] = palette; - RingAdd(pdev, &pdev->palette_lru, &palette->lru_link); + RingAdd(pdev, &pdev->Res.dynamic->palette_lru, &palette->lru_link); palette->refs++; - pdev->num_palettes++; + pdev->Res.num_palettes++; DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__)); } @@ -958,7 +1070,7 @@ static _inline void GetPallette(PDev *pdev, Bitmap *bitmap, XLATEOBJ *color_tran } internal = (InternalPalette *)AllocMem(pdev, sizeof(InternalPalette) + - (color_trans->cEntries << 2)); + (color_trans->cEntries << 2)); internal->refs = 1; RingItemInit(&internal->lru_link); bitmap->palette = PA(pdev, &internal->palette, pdev->main_mem_slot); @@ -979,7 +1091,7 @@ static void FreeQuicImage(PDev *pdev, Resource *res) // todo: defer internal = (InternalImage *)res->res; if (internal->cache) { - RingAdd(pdev, &pdev->cache_image_lru, &internal->cache->lru_link); + RingAdd(pdev, &pdev->Res.dynamic->cache_image_lru, &internal->cache->lru_link); internal->cache->image = NULL; } @@ -988,11 +1100,11 @@ static void FreeQuicImage(PDev *pdev, Resource *res) // todo: defer QXLDataChunk *chunk = (QXLDataChunk *)VA(pdev, chunk_phys, pdev->main_mem_slot); chunk_phys = chunk->next_chunk; FreeMem(pdev, chunk); - ONDBG(pdev->num_bits_pages--); + ONDBG(pdev->Res.num_bits_pages--); } FreeMem(pdev, res); - ONDBG(pdev->num_bits_pages--); + ONDBG(pdev->Res.num_bits_pages--); DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__)); } @@ -1051,7 +1163,7 @@ static int quic_usr_more_space(QuicUsrContext *usr, uint32_t **io_ptr, int rows_ usr_data->chunk_io_words = alloc_size >> 2; - ONDBG(pdev->num_bits_pages++); + ONDBG(pdev->Res.num_bits_pages++); *io_ptr = (UINT32 *)new_chank->data; return usr_data->chunk_io_words; @@ -1091,7 +1203,7 @@ static _inline Resource *GetQuicImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color alloc_size = MAX(alloc_size, QUIC_ALLOC_BASE + QUIC_BUF_MIN); image_res = AllocMem(pdev, alloc_size); - ONDBG(pdev->num_bits_pages++); + ONDBG(pdev->Res.num_bits_pages++); image_res->refs = 1; image_res->free = FreeQuicImage; @@ -1135,7 +1247,7 @@ static void FreeBitmapImage(PDev *pdev, Resource *res) // todo: defer internal = (InternalImage *)res->res; if (internal->cache) { - RingAdd(pdev, &pdev->cache_image_lru, &internal->cache->lru_link); + RingAdd(pdev, &pdev->Res.dynamic->cache_image_lru, &internal->cache->lru_link); internal->cache->image = NULL; } @@ -1150,12 +1262,12 @@ static void FreeBitmapImage(PDev *pdev, Resource *res) // todo: defer QXLDataChunk *chunk = (QXLDataChunk *)VA(pdev, chunk_phys, pdev->main_mem_slot); chunk_phys = chunk->next_chunk; FreeMem(pdev, chunk); - ONDBG(pdev->num_bits_pages--); + ONDBG(pdev->Res.num_bits_pages--); } FreeMem(pdev, res); - ONDBG(pdev->num_bits_pages--); + ONDBG(pdev->Res.num_bits_pages--); DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__)); } @@ -1180,7 +1292,7 @@ static _inline Resource *GetBitmapImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *col alloc_size = BITMAP_ALLOC_BASE + BITS_BUF_MAX - BITS_BUF_MAX % line_size; alloc_size = MIN(BITMAP_ALLOC_BASE + height * line_size, alloc_size); image_res = AllocMem(pdev, alloc_size); - ONDBG(pdev->num_bits_pages++); + ONDBG(pdev->Res.num_bits_pages++); image_res->refs = 1; image_res->free = FreeBitmapImage; @@ -1204,8 +1316,8 @@ static _inline Resource *GetBitmapImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *col dest_end = (UINT8 *)image_res + alloc_size; alloc_size = height * line_size; for (; src != src_end; src -= surf->lDelta, alloc_size -= line_size) { - PutBytesAlign(pdev, &chunk, &dest, &dest_end, src, line_size, &pdev->num_bits_pages, - alloc_size, line_size); + PutBytesAlign(pdev, &chunk, &dest, &dest_end, src, line_size, + &pdev->Res.num_bits_pages, alloc_size, line_size); } GetPallette(pdev, &internal->image.bitmap, color_trans); @@ -1356,7 +1468,7 @@ static CacheImage *GetChachImage(PDev *pdev, SURFOBJ *surf, XLATEOBJ *color_tran cache_image->width = surf->sizlBitmap.cx; cache_image->height = surf->sizlBitmap.cy; ImageCacheAdd(pdev, cache_image); - RingAdd(pdev, &pdev->cache_image_lru, &cache_image->lru_link); + RingAdd(pdev, &pdev->Res.dynamic->cache_image_lru, &cache_image->lru_link); DEBUG_PRINT((pdev, 11, "%s: ImageCacheAdd %u\n", __FUNCTION__, key)); } return NULL; @@ -1557,7 +1669,7 @@ BOOL QXLGetAlphaBitmap(PDev *pdev, QXLDrawable *drawable, PHYSICAL *image_phys, cache_image->width = surf->sizlBitmap.cx; cache_image->height = surf->sizlBitmap.cy; ImageCacheAdd(pdev, cache_image); - RingAdd(pdev, &pdev->cache_image_lru, &cache_image->lru_link); + RingAdd(pdev, &pdev->Res.dynamic->cache_image_lru, &cache_image->lru_link); DEBUG_PRINT((pdev, 11, "%s: ImageCacheAdd %u\n", __FUNCTION__, key)); } @@ -1599,7 +1711,7 @@ BOOL QXLGetBitsFromCache(PDev *pdev, QXLDrawable *drawable, UINT32 hash_key, PHY Resource *image_res; if ((cache_image = ImageCacheGetByKey(pdev, hash_key, FALSE, 0, 0, 0)) && - (internal = cache_image->image)) { + (internal = cache_image->image)) { *image_phys = PA(pdev, &internal->image, pdev->main_mem_slot); image_res = (Resource *)((UINT8 *)internal - sizeof(Resource)); DrawableAddRes(pdev, drawable, image_res); @@ -1641,7 +1753,7 @@ BOOL QXLGetMask(PDev *pdev, QXLDrawable *drawable, QMask *qxl_mask, SURFOBJ *mas static void FreeBuf(PDev *pdev, Resource *res) { - ONDBG(pdev->num_buf_pages--); + ONDBG(pdev->Res.num_buf_pages--); FreeMem(pdev, res); } @@ -1656,7 +1768,7 @@ UINT8 *QXLGetBuf(PDev *pdev, QXLDrawable *drawable, PHYSICAL *buf_phys, UINT32 s } buf_res = (Resource *)AllocMem(pdev, sizeof(Resource) + size); - ONDBG(pdev->num_buf_pages++); + ONDBG(pdev->Res.num_buf_pages++); buf_res->refs = 1; buf_res->free = FreeBuf; @@ -1679,10 +1791,10 @@ void UpdateArea(PDev *pdev, RECTL *area) output->num_res = 0; updat_cmd = (QXLUpdateCmd *)output->data; updat_cmd->release_info.id = (UINT64)output; - ONDBG(pdev->num_outputs++); //todo: atomic + ONDBG(pdev->Res.num_outputs++); //todo: atomic CopyRect(&updat_cmd->area, area); - updat_cmd->update_id = ++pdev->update_id; + updat_cmd->update_id = ++pdev->Res.update_id; WaitForCmdRing(pdev); cmd = RING_PROD_ITEM(pdev->cmd_ring); @@ -1699,7 +1811,7 @@ void UpdateArea(PDev *pdev, RECTL *area) #else EngWaitForSingleObject(pdev->display_event, &timeout); #endif //(WINVER < 0x0501) - if (*pdev->dev_update_id != pdev->update_id) { + if (*pdev->dev_update_id != pdev->Res.update_id) { DEBUG_PRINT((pdev, 0, "%s: 0x%lx: timeout\n", __FUNCTION__, pdev)); } } @@ -1711,7 +1823,7 @@ void UpdateArea(PDev *pdev, RECTL *area) #endif //(WINVER < 0x0501) #endif // DEBUG mb(); - } while (*pdev->dev_update_id != pdev->update_id); + } while (*pdev->dev_update_id != pdev->Res.update_id); } #else @@ -1742,7 +1854,7 @@ static _inline void add_rast_glyphs(PDev *pdev, QXLString *str, ULONG count, GLY UINT32 stride; if (end - now < sizeof(*glyph)) { - NEW_DATA_CHUNK(&pdev->num_glyphs_pages, PAGE_SIZE); + NEW_DATA_CHUNK(&pdev->Res.num_glyphs_pages, PAGE_SIZE); } glyph = (RasterGlyph *)now; @@ -1782,7 +1894,7 @@ static _inline void add_rast_glyphs(PDev *pdev, QXLString *str, ULONG count, GLY UINT8 val; int i; if (end - now < sizeof(*bits_pos)) { - NEW_DATA_CHUNK(&pdev->num_glyphs_pages, PAGE_SIZE); + NEW_DATA_CHUNK(&pdev->Res.num_glyphs_pages, PAGE_SIZE); } *(UINT8 *)now = *bits_pos; now += sizeof(*bits_pos); @@ -1812,7 +1924,7 @@ static _inline void add_vec_glyphs(PDev *pdev, QXLString *str, ULONG count, GLYP VectotGlyph *glyph; if (end - now < sizeof(*glyph)) { - NEW_DATA_CHUNK(&pdev->num_glyphs_pages, PAGE_SIZE); + NEW_DATA_CHUNK(&pdev->Res.num_glyphs_pages, PAGE_SIZE); } chunk->data_size += sizeof(*glyph); str->data_size += sizeof(*glyph); @@ -1834,7 +1946,7 @@ static _inline void add_vec_glyphs(PDev *pdev, QXLString *str, ULONG count, GLYP } glyph->data_size = 0; GetPathCommon(pdev, glyps->pgdf->ppo, &chunk, &now, &end, &glyph->data_size, - &pdev->num_glyphs_pages); + &pdev->Res.num_glyphs_pages); str->data_size += glyph->data_size; } *chunk_ptr = chunk; @@ -1870,11 +1982,11 @@ static void FreeSring(PDev *pdev, Resource *res) QXLDataChunk *chunk = (QXLDataChunk *)VA(pdev, chunk_phys, pdev->main_mem_slot); chunk_phys = chunk->next_chunk; FreeMem(pdev, chunk); - ONDBG(pdev->num_glyphs_pages--); + ONDBG(pdev->Res.num_glyphs_pages--); } FreeMem(pdev, res); - ONDBG(pdev->num_glyphs_pages--); + ONDBG(pdev->Res.num_glyphs_pages--); DEBUG_PRINT((pdev, 14, "%s: done\n", __FUNCTION__)); } @@ -1898,7 +2010,7 @@ BOOL QXLGetStr(PDev *pdev, QXLDrawable *drawable, PHYSICAL *str_phys, FONTOBJ *f DEBUG_PRINT((pdev, 9, "%s\n", __FUNCTION__)); str_res = (Resource *)AllocMem(pdev, TEXT_ALLOC_SIZE); - ONDBG(pdev->num_glyphs_pages++); + ONDBG(pdev->Res.num_glyphs_pages++); str_res->refs = 1; str_res->free = FreeSring; @@ -1909,7 +2021,7 @@ BOOL QXLGetStr(PDev *pdev, QXLDrawable *drawable, PHYSICAL *str_phys, FONTOBJ *f if (font->flFontType & FO_TYPE_RASTER) { qxl_str->flags = (font->flFontType & FO_GRAY16) ? STRING_RASTER_A4 : - STRING_RASTER_A1; + STRING_RASTER_A1; } chunk = &qxl_str->chunk; @@ -1964,7 +2076,7 @@ BOOL QXLGetStr(PDev *pdev, QXLDrawable *drawable, PHYSICAL *str_phys, FONTOBJ *f DEBUG_PRINT((pdev, 10, "%s: done size %u\n", __FUNCTION__, qxl_str->data_size)); return TRUE; -error: + error: FreeSring(pdev, str_res); DEBUG_PRINT((pdev, 10, "%s: error\n", __FUNCTION__)); return FALSE; @@ -1981,7 +2093,7 @@ QXLCursorCmd *CursorCmd(PDev *pdev) output->num_res = 0; cursor_cmd = (QXLCursorCmd *)output->data; cursor_cmd->release_info.id = (UINT64)output; - ONDBG(pdev->num_outputs++); //todo: atomic + ONDBG(pdev->Res.num_outputs++); //todo: atomic DEBUG_PRINT((pdev, 8, "%s: done\n", __FUNCTION__)); return cursor_cmd; } @@ -2017,7 +2129,7 @@ static void CursorCacheRemove(PDev *pdev, InternalCursor *cursor) DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__)); ASSERT(pdev, cursor->unique); - internal = &pdev->cursor_cache[CURSOR_HASH_VAL(cursor->hsurf)]; + internal = &pdev->Res.cursor_cache[CURSOR_HASH_VAL(cursor->hsurf)]; while (*internal) { if ((*internal)->hsurf == cursor->hsurf) { @@ -2025,7 +2137,7 @@ static void CursorCacheRemove(PDev *pdev, InternalCursor *cursor) *internal = cursor->next; RingRemove(pdev, &cursor->lru_link); RELEASE_RES(pdev, (Resource *)((UINT8 *)cursor - sizeof(Resource))); - pdev->num_cursors--; + pdev->Res.num_cursors--; return; } DEBUG_PRINT((pdev, 0, "%s: unexpected\n", __FUNCTION__)); @@ -2045,19 +2157,19 @@ static void CursorCacheAdd(PDev *pdev, InternalCursor *cursor) return; } - if (pdev->num_cursors == CURSOR_CACHE_SIZE) { - ASSERT(pdev, RingGetTail(pdev, &pdev->cursors_lru)); - CursorCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->cursors_lru), + if (pdev->Res.num_cursors == CURSOR_CACHE_SIZE) { + ASSERT(pdev, RingGetTail(pdev, &pdev->Res.dynamic->cursors_lru)); + CursorCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->Res.dynamic->cursors_lru), InternalCursor, lru_link)); } key = CURSOR_HASH_VAL(cursor->hsurf); - cursor->next = pdev->cursor_cache[key]; - pdev->cursor_cache[key] = cursor; + cursor->next = pdev->Res.cursor_cache[key]; + pdev->Res.cursor_cache[key] = cursor; - RingAdd(pdev, &pdev->cursors_lru, &cursor->lru_link); + RingAdd(pdev, &pdev->Res.dynamic->cursors_lru, &cursor->lru_link); GET_RES((Resource *)((UINT8 *)cursor - sizeof(Resource))); - pdev->num_cursors++; + pdev->Res.num_cursors++; } static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique) @@ -2069,13 +2181,13 @@ static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique) return NULL; } - internal = &pdev->cursor_cache[CURSOR_HASH_VAL(hsurf)]; + internal = &pdev->Res.cursor_cache[CURSOR_HASH_VAL(hsurf)]; while (*internal) { InternalCursor *now = *internal; if (now->hsurf == hsurf) { if (now->unique == unique) { RingRemove(pdev, &now->lru_link); - RingAdd(pdev, &pdev->cursors_lru, &now->lru_link); + RingAdd(pdev, &pdev->Res.dynamic->cursors_lru, &now->lru_link); return now; } CursorCacheRemove(pdev, now); @@ -2096,11 +2208,11 @@ static void FreeCursor(PDev *pdev, Resource *res) QXLDataChunk *chunk = (QXLDataChunk *)VA(pdev, chunk_phys, pdev->main_mem_slot); chunk_phys = chunk->next_chunk; FreeMem(pdev, res); - ONDBG(pdev->num_cursor_pages--); + ONDBG(pdev->Res.num_cursor_pages--); } FreeMem(pdev, res); - ONDBG(pdev->num_cursor_pages--); + ONDBG(pdev->Res.num_cursor_pages--); DEBUG_PRINT((pdev, 13, "%s: done\n", __FUNCTION__)); } @@ -2140,7 +2252,7 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_ ASSERT(pdev, sizeof(Resource) + sizeof(InternalCursor) < CURSOR_ALLOC_SIZE); res = (Resource *)AllocMem(pdev, CURSOR_ALLOC_SIZE); - ONDBG(pdev->num_cursor_pages++); + ONDBG(pdev->Res.num_cursor_pages++); res->refs = 1; res->free = FreeCursor; @@ -2151,10 +2263,10 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_ cursor = info->cursor = &internal->cursor; cursor->header.type = type; - cursor->header.unique = unique ? ++pdev->last_cursor_id : 0; + cursor->header.unique = unique ? ++pdev->Res.last_cursor_id : 0; cursor->header.width = (UINT16)surf->sizlBitmap.cx; cursor->header.height = (type == CURSOR_TYPE_MONO) ? (UINT16)surf->sizlBitmap.cy >> 1 : - (UINT16)surf->sizlBitmap.cy; + (UINT16)surf->sizlBitmap.cy; cursor->header.hot_spot_x = (UINT16)hot_x; cursor->header.hot_spot_y = (UINT16)hot_y; @@ -2195,7 +2307,7 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_ src_end = src + (surf->lDelta * surf->sizlBitmap.cy); for (; src != src_end; src += surf->lDelta) { PutBytes(pdev, &info->chunk, &info->now, &info->end, src, line_size, - &pdev->num_cursor_pages, PAGE_SIZE); + &pdev->Res.num_cursor_pages, PAGE_SIZE); } CursorCacheAdd(pdev, internal); @@ -2292,14 +2404,14 @@ BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFO if (pdev->bitmap_format == BMF_32BPP) { PutBytes(pdev, &info.chunk, &info.now, &info.end, (UINT8 *)color_trans->pulXlate, - 256 << 2, &pdev->num_cursor_pages, PAGE_SIZE); + 256 << 2, &pdev->Res.num_cursor_pages, PAGE_SIZE); } else { int i; for (i = 0; i < 256; i++) { UINT32 ent = _16bppTo32bpp(color_trans->pulXlate[i]); PutBytes(pdev, &info.chunk, &info.now, &info.end, (UINT8 *)&ent, - 4, &pdev->num_cursor_pages, PAGE_SIZE); + 4, &pdev->Res.num_cursor_pages, PAGE_SIZE); } } info.cursor->data_size += 256 << 2; @@ -2312,14 +2424,14 @@ BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFO if (pdev->bitmap_format == BMF_32BPP) { PutBytes(pdev, &info.chunk, &info.now, &info.end, (UINT8 *)color_trans->pulXlate, - 16 << 2, &pdev->num_cursor_pages, PAGE_SIZE); + 16 << 2, &pdev->Res.num_cursor_pages, PAGE_SIZE); } else { int i; for (i = 0; i < 16; i++) { UINT32 ent = _16bppTo32bpp(color_trans->pulXlate[i]); PutBytes(pdev, &info.chunk, &info.now, &info.end, (UINT8 *)&ent, - 4, &pdev->num_cursor_pages, PAGE_SIZE); + 4, &pdev->Res.num_cursor_pages, PAGE_SIZE); } } info.cursor->data_size += 16 << 2; @@ -2331,7 +2443,7 @@ BOOL GetColorCursor(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_y, SURFO for (; src != src_end; src += mask->lDelta) { PutBytes(pdev, &info.chunk, &info.now, &info.end, src, line_size, - &pdev->num_cursor_pages, PAGE_SIZE); + &pdev->Res.num_cursor_pages, PAGE_SIZE); } } @@ -2349,7 +2461,7 @@ BOOL GetTransparentCursor(PDev *pdev, QXLCursorCmd *cmd) ASSERT(pdev, sizeof(Resource) + sizeof(InternalCursor) < PAGE_SIZE); res = (Resource *)AllocMem(pdev, sizeof(Resource) + sizeof(InternalCursor)); - ONDBG(pdev->num_cursor_pages++); + ONDBG(pdev->Res.num_cursor_pages++); res->refs = 1; res->free = FreeCursor; diff --git a/display/res.h b/display/res.h index 9e2b261..18ae081 100644 --- a/display/res.h +++ b/display/res.h @@ -25,6 +25,8 @@ UINT64 ReleaseOutput(PDev *pdev, UINT64 output_id); QXLDrawable *Drawable(PDev *pdev, UINT8 type, RECTL *area, CLIPOBJ *clip); void PushDrawable(PDev *pdev, QXLDrawable *drawable); +BOOL QXLGetSurface(PDev *pdev, PHYSICAL *surface_phys, UINT32 x, UINT32 y, UINT32 depth, + UINT8 **base_mem, UINT8 allocation_type); BOOL QXLGetPath(PDev *pdev, QXLDrawable *drawable, PHYSICAL *path_phys, PATHOBJ *path); BOOL QXLGetMask(PDev *pdev, QXLDrawable *drawable, QMask *qxl_mask, SURFOBJ *mask, POINTL *pos, BOOL invers, LONG width, LONG height); diff --git a/display/rop.c b/display/rop.c index 56ba3df..73b80b1 100644 --- a/display/rop.c +++ b/display/rop.c @@ -381,8 +381,8 @@ static BOOL GetBitmap(PDev *pdev, QXLDrawable *drawable, PHYSICAL *bitmap_phys, ASSERT(pdev, (PDev *)surf->dhpdev == pdev); DEBUG_PRINT((pdev, 9, "%s copy from self\n", __FUNCTION__)); *bitmap_phys = 0; - drawable->bitmap_offset = (UINT16)((UINT8 *)bitmap_phys - (UINT8 *)drawable); - drawable->bitmap_area = *area; + drawable->self_bitmap = TRUE; + drawable->self_bitmap_area = *area; area->right = area->right - area->left; area->left = 0; area->bottom = area->bottom - area->top; diff --git a/display/sources b/display/sources index ee5a74a..6c1d5c7 100644 --- a/display/sources +++ b/display/sources @@ -29,5 +29,6 @@ SOURCES=driver.c \ brush.c \
mspace.c \
quic.c \
+ surface.c \
driver.rc
diff --git a/display/surface.c b/display/surface.c new file mode 100644 index 0000000..c562ea7 --- /dev/null +++ b/display/surface.c @@ -0,0 +1,129 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "stddef.h" + +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include "os_dep.h" + +#include "winerror.h" +#include "windef.h" +#include "wingdi.h" +#include "winddi.h" +#include "devioctl.h" +#include "ntddvdeo.h" +#include "ioaccess.h" + +#include "qxldd.h" +#include "utils.h" +#include "mspace.h" +#include "res.h" +#include "surface.h" + +BOOL CreateDrawArea(PDev *pdev, DrawArea *drawarea, UINT8 *base_mem, UINT32 cx, UINT32 cy) +{ + SIZEL size; + + size.cx = cx; + size.cy = cy; + + if (!(drawarea->bitmap = (HSURF)EngCreateBitmap(size, size.cx << 2, BMF_32BPP, 0, base_mem))) { + DEBUG_PRINT((pdev, 0, "%s: EngCreateBitmap failed\n", __FUNCTION__)); + return FALSE; + } + + if (!EngAssociateSurface(drawarea->bitmap, pdev->eng, 0)) { + DEBUG_PRINT((pdev, 0, "%s: EngAssociateSurface failed\n", __FUNCTION__)); + goto error; + } + + if (!(drawarea->surf_obj = EngLockSurface(drawarea->bitmap))) { + DEBUG_PRINT((pdev, 0, "%s: EngLockSurface failed\n", __FUNCTION__)); + goto error; + } + + return TRUE; +error: + EngDeleteSurface(drawarea->bitmap); + return FALSE; +} + +VOID FreeDrawArea(DrawArea *drawarea) +{ + EngUnlockSurface(drawarea->surf_obj); + EngDeleteSurface(drawarea->bitmap); +} + +HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, PHYSICAL *phys_mem, + UINT8 **base_mem, UINT8 allocation_type) +{ + UINT8 depth; + HBITMAP surf; + + switch (format) { + case BMF_8BPP: + return 0; + break; + case BMF_16BPP: + depth = 16; + break; + case BMF_24BPP: + depth = 32; + break; + case BMF_32BPP: + depth = 32; + break; + default: + return 0; + }; + + if (!(surf = EngCreateDeviceBitmap((DHSURF)pdev, size, format))) { + DEBUG_PRINT((NULL, 0, "%s: create device surface failed, 0x%lx\n", + __FUNCTION__, pdev)); + goto out_error1; + } + + if (!EngAssociateSurface((HSURF)surf, pdev->eng, HOOK_SYNCHRONIZE | HOOK_COPYBITS | + HOOK_BITBLT | HOOK_TEXTOUT | HOOK_STROKEPATH | HOOK_STRETCHBLT | + HOOK_STRETCHBLTROP | HOOK_TRANSPARENTBLT | HOOK_ALPHABLEND +#ifdef CALL_TEST + | HOOK_PLGBLT | HOOK_FILLPATH | HOOK_STROKEANDFILLPATH | HOOK_LINETO | + 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)) { + goto out_error2; + } + + return surf; + +out_error2: + EngDeleteSurface((HSURF)surf); +out_error1: + return 0; +} + +VOID DeleteDeviceBitmap(HSURF surf) +{ + EngDeleteSurface(surf); +} diff --git a/display/surface.h b/display/surface.h new file mode 100644 index 0000000..92ab5fd --- /dev/null +++ b/display/surface.h @@ -0,0 +1,20 @@ +#ifndef SURFACE_H +#define SURFACE_H + +enum { + DEVICE_BITMAP_ALLOCATION_TYPE_SURF0, +}; + +typedef struct DrawArea { + HSURF bitmap; + SURFOBJ* surf_obj; +} DrawArea; + +BOOL CreateDrawArea(PDev *pdev, DrawArea *drawarea, UINT8 *base_mem, UINT32 cx, UINT32 cy); +VOID FreeDrawArea(DrawArea *drawarea); + +HBITMAP CreateDeviceBitmap(PDev *pdev, SIZEL size, ULONG format, PHYSICAL *phys_mem, + UINT8 **base_mem, UINT8 allocation_type); +VOID DeleteDeviceBitmap(HSURF surf); + +#endif diff --git a/include/qxl_driver.h b/include/qxl_driver.h index e4d8057..8391f4a 100644 --- a/include/qxl_driver.h +++ b/include/qxl_driver.h @@ -54,12 +54,12 @@ typedef struct QXLDriverInfo { PEVENT cursor_event; PEVENT sleep_event; - UINT32 num_io_pages; + UINT32 num_pages; void *io_pages_virt; UINT64 io_pages_phys; - UINT8 *draw_area; - UINT32 draw_area_size; + UINT8 *surface0_area; + UINT32 surface0_area_size; UINT32 *update_id; UINT32 *compression_level; @@ -80,6 +80,14 @@ typedef struct QXLDriverInfo { UINT8 slot_id_bits; UINT8 slot_gen_bits; MemSlot main_mem_slot; + + UINT32 destroy_surface_wait_port; + UINT32 create_primary_port; + UINT32 destroy_primary_port; + + UINT32 dev_id; + + QXLSurfaceCreate *primary_surface_create; } QXLDriverInfo; diff --git a/miniport/qxl.c b/miniport/qxl.c index 53e05af..fe5449c 100644 --- a/miniport/qxl.c +++ b/miniport/qxl.c @@ -73,6 +73,7 @@ typedef struct QXLExtension { PHYSICAL_ADDRESS vram_physical; ULONG vram_size; + ULONG current_mode; ULONG n_modes; PVIDEO_MODE_INFORMATION modes; @@ -226,7 +227,7 @@ VP_STATUS InitRam(QXLExtension *dev, PVIDEO_ACCESS_RANGE range) return ERROR_INVALID_DATA; } - if (ram_size < dev->rom->pages_offset + (dev->rom->num_io_pages << PAGE_SHIFT) ) { + if (ram_size < dev->rom->num_pages << PAGE_SHIFT) { DEBUG_PRINT((0, "%s: bad ram size\n", __FUNCTION__)); return ERROR_INVALID_DATA; } @@ -628,15 +629,15 @@ static BOOLEAN CreateMemSlots(QXLExtension *dev_ext) return FALSE; } - dev_ext->mem_slots[slot_id].start_phys_addr = dev_ext->ram_physical.QuadPart + - dev_ext->rom->pages_offset; + dev_ext->mem_slots[slot_id].start_phys_addr = dev_ext->ram_physical.QuadPart; dev_ext->mem_slots[slot_id].end_phys_addr = dev_ext->mem_slots[slot_id].start_phys_addr + - dev_ext->rom->num_io_pages * PAGE_SIZE; + dev_ext->rom->surface0_area_size + + dev_ext->rom->num_pages * PAGE_SIZE; - dev_ext->mem_slots[slot_id].start_virt_addr = (UINT64)dev_ext->ram_start + - dev_ext->rom->pages_offset; + dev_ext->mem_slots[slot_id].start_virt_addr = (UINT64)dev_ext->ram_start; dev_ext->mem_slots[slot_id].end_virt_addr = dev_ext->mem_slots[slot_id].start_virt_addr + - dev_ext->rom->num_io_pages * PAGE_SIZE; + dev_ext->rom->surface0_area_size + + dev_ext->rom->num_pages * PAGE_SIZE; dev_ext->ram_header->mem_slot.mem_start = dev_ext->mem_slots[slot_id].start_phys_addr; dev_ext->ram_header->mem_slot.mem_end = dev_ext->mem_slots[slot_id].end_phys_addr; @@ -658,6 +659,7 @@ void HWReset(QXLExtension *dev_ext) PAGED_CODE(); DEBUG_PRINT((0, "%s\n", __FUNCTION__)); VideoPortWritePortUchar((PUCHAR)dev_ext->io_base + QXL_IO_RESET, 0); + dev_ext->ram_header->int_mask = ~0; CreateMemSlots(dev_ext); DEBUG_PRINT((0, "%s: done\n", __FUNCTION__)); } @@ -828,15 +830,13 @@ BOOLEAN StartIO(PVOID dev_extension, PVIDEO_REQUEST_PACKET packet) goto err; } request_mode = ((PVIDEO_MODE)packet->InputBuffer)->RequestedMode; + + dev_ext->current_mode = request_mode; DEBUG_PRINT((0, "%s: mode %u\n", __FUNCTION__, request_mode)); if (!IsValidMode(dev_ext, request_mode)) { error = ERROR_INVALID_PARAMETER; goto err; } - VideoPortWritePortUchar((PUCHAR)dev_ext->io_base + QXL_IO_SET_MODE, - (UCHAR)request_mode); - dev_ext->ram_header->int_mask = ~0; - VideoPortWritePortUchar((PUCHAR)dev_ext->io_base + QXL_IO_UPDATE_IRQ, 0); } break; case IOCTL_VIDEO_QUERY_CURRENT_MODE: { @@ -850,7 +850,7 @@ BOOLEAN StartIO(PVOID dev_extension, PVIDEO_REQUEST_PACKET packet) goto err; } - if ((inf = FindMode(dev_ext, dev_ext->rom->mode)) == NULL) { + if ((inf = FindMode(dev_ext, dev_ext->current_mode)) == NULL) { DEBUG_PRINT((0, "%s: mod info not found\n", __FUNCTION__)); error = ERROR_INVALID_DATA; goto err; @@ -949,8 +949,8 @@ BOOLEAN StartIO(PVOID dev_extension, PVIDEO_REQUEST_PACKET packet) driver_info->log_port = dev_ext->io_port + QXL_IO_LOG; driver_info->log_buf = dev_ext->ram_header->log_buf; - driver_info->draw_area = dev_ext->ram_start + dev_ext->rom->draw_area_offset; - driver_info->draw_area_size = dev_ext->rom->draw_area_size; + driver_info->surface0_area = dev_ext->ram_start; + driver_info->surface0_area_size = dev_ext->rom->surface0_area_size; driver_info->update_id = &dev_ext->rom->update_id; driver_info->mm_clock = &dev_ext->rom->mm_clock; driver_info->compression_level = &dev_ext->rom->compression_level; @@ -958,10 +958,10 @@ BOOLEAN StartIO(PVOID dev_extension, PVIDEO_REQUEST_PACKET packet) driver_info->update_area_port = dev_ext->io_port + QXL_IO_UPDATE_AREA; driver_info->update_area = &dev_ext->ram_header->update_area; - driver_info->num_io_pages = dev_ext->rom->num_io_pages; - driver_info->io_pages_virt = dev_ext->ram_start + dev_ext->rom->pages_offset; + driver_info->num_pages = dev_ext->rom->num_pages; + driver_info->io_pages_virt = dev_ext->ram_start + driver_info->surface0_area_size; driver_info->io_pages_phys = dev_ext->ram_physical.QuadPart + - dev_ext->rom->pages_offset; + driver_info->surface0_area_size; driver_info->main_mem_slot_id = dev_ext->rom->slots_start; driver_info->num_mem_slot = dev_ext->rom->slots_end; @@ -972,6 +972,13 @@ BOOLEAN StartIO(PVOID dev_extension, PVIDEO_REQUEST_PACKET packet) #if (WINVER < 0x0501) driver_info->WaitForEvent = QXLWaitForEvent; #endif + driver_info->destroy_surface_wait_port = dev_ext->io_port + QXL_IO_DESTROY_SURFACE_WAIT; + driver_info->create_primary_port = dev_ext->io_port + QXL_IO_CREATE_PRIMARY; + driver_info->destroy_primary_port = dev_ext->io_port + QXL_IO_DESTROY_PRIMARY; + + driver_info->primary_surface_create = &dev_ext->ram_header->create_surface; + + driver_info->dev_id = dev_ext->rom->id; } break; default: |