[Spice-devel] [PATCH v2 11/12] qxl-wddm-dod: Implement non-forced bitmap allocation
Frediano Ziglio
fziglio at redhat.com
Thu Apr 6 13:53:42 UTC 2017
>
> From: "yuri.benditovich at daynix.com" <yuri.benditovich at daynix.com>
>
> Preparation for non-forced allocations.
> Move bitmap creation to dedicated procedure which is able
> to allocate device memory forced or non-forced.
> In forced case it works as before.
> In non-forced case, if allocation fails, the procedure allocates
> memory from OS pool for entire bitmap and copies source data to it.
> Later, before sending command, memory will be allocated from device
> memory and copied from intermediate location to new one.
>
> Signed-off-by: Yuri Benditovich <yuri.benditovich at daynix.com>
Would be great to split function creation and addition of non-forced
allocation
Frediano
> ---
> qxldod/QxlDod.cpp | 162
> ++++++++++++++++++++++++++++++++++--------------------
> qxldod/QxlDod.h | 1 +
> 2 files changed, 102 insertions(+), 61 deletions(-)
>
> diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp
> index 08143ea..a807396 100755
> --- a/qxldod/QxlDod.cpp
> +++ b/qxldod/QxlDod.cpp
> @@ -4405,6 +4405,93 @@ QXLDrawable *QxlDevice::PrepareCopyBits(const RECT&
> rect, const POINT& sourcePoi
> return drawable;
> }
>
> +BOOLEAN QxlDevice::AttachNewBitmap(QXLDrawable *drawable, UINT8 *src, UINT8
> *src_end, INT pitch, BOOLEAN bForce)
> +{
> + PAGED_CODE();
> + LONG width, height;
> + size_t alloc_size;
> + UINT32 line_size;
> + Resource *image_res;
> + InternalImage *internal;
> + QXLDataChunk *chunk;
> + PLIST_ENTRY pDelayedList = NULL;
> + UINT8* dest, *dest_end;
> +
> + height = drawable->u.copy.src_area.bottom;
> + width = drawable->u.copy.src_area.right;
> + line_size = width * 4;
> +
> + 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 = (Resource*)AllocMem(MSPACE_TYPE_VRAM, alloc_size, bForce);
> +
> + if (image_res) {
> + image_res->refs = 1;
> + image_res->free = FreeBitmapImageEx;
> + image_res->ptr = this;
> +
> + internal = (InternalImage *)image_res->res;
> + SetImageId(internal, FALSE, width, height, SPICE_BITMAP_FMT_32BIT,
> 0);
> + internal->image.descriptor.flags = 0;
> + internal->image.descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
> +
> + chunk = (QXLDataChunk *)(&internal->image.bitmap + 1);
> + chunk->data_size = 0;
> + chunk->prev_chunk = 0;
> + chunk->next_chunk = 0;
> + internal->image.bitmap.data = PA(chunk, m_SurfaceMemSlot);
> + internal->image.bitmap.flags = 0;
> + internal->image.descriptor.width = internal->image.bitmap.x = width;
> + internal->image.descriptor.height = internal->image.bitmap.y =
> height;
> + internal->image.bitmap.format = SPICE_BITMAP_FMT_RGBA;
> + internal->image.bitmap.stride = line_size;
> + internal->image.bitmap.palette = 0;
> +
> + dest = chunk->data;
> + dest_end = (UINT8 *)image_res + alloc_size;
> +
> + drawable->u.copy.src_bitmap = PA(&internal->image,
> m_SurfaceMemSlot);
> +
> + DrawableAddRes(drawable, image_res);
> + RELEASE_RES(image_res);
> + alloc_size = height * line_size;
> + } else if (!bForce) {
> + alloc_size = height * line_size;
> + // allocate delayed chunck for entire bitmap without limitation
> + QXL_DELAYED_CHUNK *pChunk = (QXL_DELAYED_CHUNK *)new
> (PagedPool)BYTE[alloc_size + sizeof(QXL_DELAYED_CHUNK)];
> + if (pChunk) {
> + // add it to delayed list
> + InsertTailList(pDelayedList, &pChunk->list);
> + // PutBytesAlign do not need to allocate additional memory
> + pDelayedList = NULL;
> + chunk = &pChunk->chunk;
> + chunk->data_size = 0;
> + chunk->prev_chunk = 0;
> + chunk->next_chunk = 0;
> + // set dest and dest_end
> + dest = chunk->data;
> + dest_end = chunk->data + alloc_size;
> + } else {
> + // can't allocate memory
> + DbgPrint(TRACE_LEVEL_ERROR, ("Cannot allocate delayed bitmap for
> drawable\n"));
> + return FALSE;
> + }
> + } else {
> + // can't allocate memory (forced), driver abort flow
> + DbgPrint(TRACE_LEVEL_ERROR, ("Cannot get bitmap for drawable
> (stopping)\n"));
> + return FALSE;
> + }
> +
> + for (; src != src_end; src -= pitch, alloc_size -= line_size) {
> + BOOLEAN b = PutBytesAlign(&chunk, &dest, &dest_end, src, line_size,
> alloc_size, pDelayedList);
> + if (!b) {
> + DbgPrint(TRACE_LEVEL_WARNING, ("%s: aborting copy of lines\n",
> __FUNCTION__));
> + return FALSE;
> + }
> + }
> + return TRUE;
> +}
> +
> QXLDrawable *QxlDevice::PrepareBltBits (
> BLT_INFO* pDst,
> CONST BLT_INFO* pSrc,
> @@ -4414,11 +4501,6 @@ QXLDrawable *QxlDevice::PrepareBltBits (
> {
> PAGED_CODE();
> QXLDrawable *drawable;
> - Resource *image_res;
> - InternalImage *internal;
> - size_t alloc_size;
> - QXLDataChunk *chunk;
> - UINT32 line_size;
> LONG width;
> LONG height;
>
> @@ -4444,72 +4526,30 @@ QXLDrawable *QxlDevice::PrepareBltBits (
>
> height = pRect->bottom - pRect->top;
> width = pRect->right - pRect->left;
> - line_size = width * 4;
>
> drawable->u.copy.src_area.bottom = height;
> drawable->u.copy.src_area.left = 0;
> drawable->u.copy.src_area.top = 0;
> drawable->u.copy.src_area.right = width;
>
> - 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 = (Resource*)AllocMem(MSPACE_TYPE_VRAM, alloc_size, TRUE);
> - if (!image_res) {
> - ReleaseOutput(drawable->release_info.id);
> - DbgPrint(TRACE_LEVEL_ERROR, ("Cannot allocate bitmap for
> drawable\n"));
> - return NULL;
> - }
> -
> - image_res->refs = 1;
> - image_res->free = FreeBitmapImageEx;
> - image_res->ptr = this;
> + CopyRect(&drawable->surfaces_rects[1], pRect);
>
> - internal = (InternalImage *)image_res->res;
> - SetImageId(internal, FALSE, width, height, SPICE_BITMAP_FMT_32BIT, 0);
> - internal->image.descriptor.flags = 0;
> - internal->image.descriptor.type = SPICE_IMAGE_TYPE_BITMAP;
> - chunk = (QXLDataChunk *)(&internal->image.bitmap + 1);
> - chunk->data_size = 0;
> - chunk->prev_chunk = 0;
> - chunk->next_chunk = 0;
> - internal->image.bitmap.data = PA(chunk, m_SurfaceMemSlot);
> - internal->image.bitmap.flags = 0;
> - internal->image.descriptor.width = internal->image.bitmap.x = width;
> - internal->image.descriptor.height = internal->image.bitmap.y = height;
> - internal->image.bitmap.format = SPICE_BITMAP_FMT_RGBA;
> - internal->image.bitmap.stride = line_size;
> -
> - UINT8* src = (UINT8*)pSrc->pBits+
> - (pSourcePoint->y) * pSrc->Pitch +
> - (pSourcePoint->x * 4);
> + UINT8* src = (UINT8*)pSrc->pBits +
> + (pSourcePoint->y) * pSrc->Pitch +
> + (pSourcePoint->x * 4);
> UINT8* src_end = src - pSrc->Pitch;
> src += pSrc->Pitch * (height - 1);
> - UINT8* dest = chunk->data;
> - UINT8* dest_end = (UINT8 *)image_res + alloc_size;
> - alloc_size = height * line_size;
> -
> - for (; src != src_end; src -= pSrc->Pitch, alloc_size -= line_size) {
> - if (!PutBytesAlign(&chunk, &dest, &dest_end, src,
> - line_size, alloc_size, NULL)) {
> - // not reachable when forced allocation used
> - ReleaseOutput(drawable->release_info.id);
> - DbgPrint(TRACE_LEVEL_ERROR, ("Cannot allocate additional bitmap
> for drawable\n"));
> - return NULL;
> - }
> - }
>
> - internal->image.bitmap.palette = 0;
> -
> - drawable->u.copy.src_bitmap = PA(&internal->image, m_SurfaceMemSlot);
> -
> - CopyRect(&drawable->surfaces_rects[1], pRect);
> - DrawableAddRes(drawable, image_res);
> - RELEASE_RES(image_res);
> -
> - DbgPrint(TRACE_LEVEL_INFORMATION, ("%s drawable= %p type = %d, effect =
> %d Dest right(%d) left(%d) top(%d) bottom(%d) src_bitmap= %p.\n",
> __FUNCTION__,
> - drawable, drawable->type, drawable->effect,
> drawable->surfaces_rects[0].right, drawable->surfaces_rects[0].left,
> - drawable->surfaces_rects[0].top,
> drawable->surfaces_rects[0].bottom,
> - drawable->u.copy.src_bitmap));
> + if (!AttachNewBitmap(drawable, src, src_end, (INT)pSrc->Pitch, TRUE)) {
> + ReleaseOutput(drawable->release_info.id);
> + drawable = NULL;
> + }
> + else {
> + DbgPrint(TRACE_LEVEL_INFORMATION, ("%s drawable= %p type = %d,
> effect = %d Dest right(%d) left(%d) top(%d) bottom(%d) src_bitmap= %p.\n",
> __FUNCTION__,
> + drawable, drawable->type, drawable->effect,
> drawable->surfaces_rects[0].right, drawable->surfaces_rects[0].left,
> + drawable->surfaces_rects[0].top,
> drawable->surfaces_rects[0].bottom,
> + drawable->u.copy.src_bitmap));
> + }
>
> DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s\n", __FUNCTION__));
>
> diff --git a/qxldod/QxlDod.h b/qxldod/QxlDod.h
> index ca93322..831d2b0 100755
> --- a/qxldod/QxlDod.h
> +++ b/qxldod/QxlDod.h
> @@ -608,6 +608,7 @@ private:
> void PushCmd(void);
> void WaitForCursorRing(void);
> void PushCursor(void);
> + BOOLEAN AttachNewBitmap(QXLDrawable *drawable, UINT8 *src, UINT8
> *src_end, INT pitch, BOOLEAN forced);
> BOOLEAN PutBytesAlign(QXLDataChunk **chunk_ptr, UINT8 **now_ptr,
> UINT8 **end_ptr, UINT8 *src, int size,
> size_t alloc_size, PLIST_ENTRY pDelayed);
> --
> 2.7.0.windows.1
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel
>
More information about the Spice-devel
mailing list