> > From: "yuri.benditovich@xxxxxxxxxx" <yuri.benditovich@xxxxxxxxxx> > > Preparation for offload of allocations from device's memory > to separate thread. Procedure PutBytesAlign is called to > allocate memory chunk from device memory and copy data to it. > With current commit the procedure (if called with non-NULL > linked list root entry parameter) can use non-forced allocation. > If such allocation fails, it allocates 'delayed' chunk from > OS memory and copies data to it. Later before sending drawable command > this chunk shall be processed, storage allocated from device memory > (forced) and data copied to it. > > Signed-off-by: Yuri Benditovich <yuri.benditovich@xxxxxxxxxx> > --- > qxldod/QxlDod.cpp | 68 > +++++++++++++++++++++++++++++++++++-------------------- > qxldod/QxlDod.h | 9 +++++++- > 2 files changed, 51 insertions(+), 26 deletions(-) > > diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp > index 5993016..3dce65b 100755 > --- a/qxldod/QxlDod.cpp > +++ b/qxldod/QxlDod.cpp > @@ -4501,7 +4501,8 @@ QXLDrawable *QxlDevice::PrepareBltBits ( > > for (; src != src_end; src -= pSrc->Pitch, alloc_size -= line_size) { > if (!PutBytesAlign(&chunk, &dest, &dest_end, src, > - line_size, alloc_size, line_size)) { > + 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; > @@ -4526,36 +4527,54 @@ QXLDrawable *QxlDevice::PrepareBltBits ( > return drawable; > } > > +// can work in 2 modes: > +// forced - as before, when pDelayed not provided or if VSync is not in use > +// non-forced, if VSync is active and pDelayed provided. In this case, if > memory > +// can't be allocated immediately, allocates 'delayed chunk' and copies data > +// to it. Further, before send to the device, this 'delayed chunk' should be > processed, > +// regular chunk allocated from device memory and the data copied to it > BOOLEAN QxlDevice::PutBytesAlign(QXLDataChunk **chunk_ptr, UINT8 **now_ptr, > UINT8 **end_ptr, UINT8 *src, int size, > - size_t alloc_size, uint32_t alignment) > + size_t alloc_size, PLIST_ENTRY pDelayed) > { > PAGED_CODE(); > + BOOLEAN bResult = TRUE; > + BOOLEAN bForced = !g_bSupportVSync || !pDelayed; > QXLDataChunk *chunk = *chunk_ptr; > UINT8 *now = *now_ptr; > UINT8 *end = *end_ptr; > + size_t maxAllocSize = BITS_BUF_MAX - BITS_BUF_MAX % size; > + alloc_size = MIN(size, maxAllocSize); > DbgPrint(TRACE_LEVEL_VERBOSE, ("---> %s\n", __FUNCTION__)); > > while (size) { > int cp_size = (int)MIN(end - now, size); > if (!cp_size) { > - size_t aligned_size; > - aligned_size = (int)MIN(alloc_size + alignment - 1, > BITS_BUF_MAX); > - aligned_size -= aligned_size % alignment; > - > - void *ptr = AllocMem(MSPACE_TYPE_VRAM, size + > sizeof(QXLDataChunk), TRUE); > - if (!ptr) { > - return FALSE; > + void *ptr = (bForced || IsListEmpty(pDelayed)) ? > AllocMem(MSPACE_TYPE_VRAM, alloc_size + sizeof(QXLDataChunk), bForced) : > NULL; > + if (ptr) { > + chunk->next_chunk = PA(ptr, m_SurfaceMemSlot); > + ((QXLDataChunk *)ptr)->prev_chunk = PA(chunk, > m_SurfaceMemSlot); > + chunk = (QXLDataChunk *)ptr; > + chunk->next_chunk = 0; > + } > + if (!ptr && pDelayed) { > + ptr = new (PagedPool)BYTE[alloc_size + > sizeof(QXL_DELAYED_CHUNK)]; > + if (ptr) { > + QXL_DELAYED_CHUNK *pChunk = (QXL_DELAYED_CHUNK *)ptr; > + InsertTailList(pDelayed, &pChunk->list); > + pChunk->chunk.prev_chunk = (QXLPHYSICAL)chunk; > + chunk = &pChunk->chunk; > + } > + } > + if (ptr) { > + chunk->data_size = 0; > + now = chunk->data; > + end = now + alloc_size; > + cp_size = (int)MIN(end - now, size); > + } else { > + bResult = FALSE; > + break; > } > - chunk->next_chunk = PA(ptr, m_SurfaceMemSlot); > - ((QXLDataChunk *)ptr)->prev_chunk = PA(chunk, m_SurfaceMemSlot); > - chunk = (QXLDataChunk *)ptr; > - chunk->data_size = 0; > - chunk->next_chunk = 0; > - now = chunk->data; > - end = now + size; > - > - cp_size = (int)MIN(end - now, size); > } > RtlCopyMemory(now, src, cp_size); > src += cp_size; > @@ -4567,7 +4586,7 @@ BOOLEAN QxlDevice::PutBytesAlign(QXLDataChunk > **chunk_ptr, UINT8 **now_ptr, > *now_ptr = now; > *end_ptr = end; > DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s\n", __FUNCTION__)); > - return TRUE; > + return bResult; > } > > VOID QxlDevice::BlackOutScreen(CURRENT_BDD_MODE* pCurrentBddMod) > @@ -4685,12 +4704,11 @@ NTSTATUS QxlDevice::SetPointerShape(_In_ CONST > DXGKARG_SETPOINTERSHAPE* pSetPoi > end = (UINT8 *)res + CURSOR_ALLOC_SIZE; > src_end = src + (pSetPointerShape->Pitch * pSetPointerShape->Height * > num_images); > for (; src != src_end; src += pSetPointerShape->Pitch) { > - if (!PutBytesAlign(&chunk, &now, &end, src, line_size, > - PAGE_SIZE, 1)) > - { > - DbgPrint(TRACE_LEVEL_ERROR, ("%s: Failed to allocate cursor > bitmap\n", __FUNCTION__)); > - ReleaseOutput(cursor_cmd->release_info.id); > - return STATUS_INSUFFICIENT_RESOURCES; > + if (!PutBytesAlign(&chunk, &now, &end, src, line_size, PAGE_SIZE - > PAGE_SIZE % line_size, NULL)) { > + // we have a chance to get here only with color cursor bigger > than 45*45 > + // and only if we modify this procedure to use non-forced > allocation > + DbgPrint(TRACE_LEVEL_ERROR, ("%s: failed to push part of > shape\n", __FUNCTION__)); > + break; > } > } > CursorCmdAddRes(cursor_cmd, res); > diff --git a/qxldod/QxlDod.h b/qxldod/QxlDod.h > index 059e1bd..e18afac 100755 > --- a/qxldod/QxlDod.h > +++ b/qxldod/QxlDod.h > @@ -260,6 +260,13 @@ public: > }; > #endif > > +typedef struct _QXL_DELAYED_CHUNK > +{ > + LIST_ENTRY list; > + UINT32 type; > + QXLDataChunk chunk; > +} QXL_DELAYED_CHUNK; > + The name of this type is quite odd. Is suggests some Windows internal C structure. This header is only C++ compatible, so the typedef make no sense. The capital case is used for QXL protocol specific stuff, but this is not even allocate in QXL memory but in system one. I would suggest a simple QXLDelayedChunk or even DelayedChunk. The "type" field is not used in the code. > class QxlDod; > > class HwDeviceInterface { > @@ -603,7 +610,7 @@ private: > void PushCursor(void); > BOOLEAN PutBytesAlign(QXLDataChunk **chunk_ptr, UINT8 **now_ptr, > UINT8 **end_ptr, UINT8 *src, int size, > - size_t alloc_size, uint32_t alignment); > + size_t alloc_size, PLIST_ENTRY pDelayed); > void AsyncIo(UCHAR Port, UCHAR Value); > void SyncIo(UCHAR Port, UCHAR Value); > NTSTATUS UpdateChildStatus(BOOLEAN connect); Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel