<html><body><div style="font-family: times new roman, new york, times, serif; font-size: 12pt; color: #000000"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 10, 2017 at 3:33 PM, Frediano Ziglio <span dir="ltr"><<a href="mailto:fziglio@redhat.com" target="_blank" data-mce-href="mailto:fziglio@redhat.com">fziglio@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex" data-mce-style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><div class="HOEnZb"><div class="h5">><br> > From: "<a href="mailto:yuri.benditovich@daynix.com" target="_blank" data-mce-href="mailto:yuri.benditovich@daynix.com">yuri.benditovich@daynix.com</a>" <<a href="mailto:yuri.benditovich@daynix.com" target="_blank" data-mce-href="mailto:yuri.benditovich@daynix.com">yuri.benditovich@daynix.com</a>><br> ><br> > Preparation for offload of allocations from device's memory<br> > to separate thread. Procedure PutBytesAlign is called to<br> > allocate memory chunk from device memory and copy data to it.<br> > With current commit the procedure (if called with non-NULL<br> > linked list root entry parameter) can use non-forced allocation.<br> > If such allocation fails, it allocates 'delayed' chunk from<br> > OS memory and copies data to it. Later before sending drawable command<br> > this chunk shall be processed, storage allocated from device memory<br> > (forced) and data copied to it.<br> ><br> > Signed-off-by: Yuri Benditovich <<a href="mailto:yuri.benditovich@daynix.com" target="_blank" data-mce-href="mailto:yuri.benditovich@daynix.com">yuri.benditovich@daynix.com</a>><br> > ---<br> >  qxldod/QxlDod.cpp | 68<br> >  +++++++++++++++++++++++++++++++++++--------------------<br> >  qxldod/QxlDod.h   |  9 +++++++-<br> >  2 files changed, 51 insertions(+), 26 deletions(-)<br> ><br> > diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp<br> > index 5993016..3dce65b 100755<br> > --- a/qxldod/QxlDod.cpp<br> > +++ b/qxldod/QxlDod.cpp<br> > @@ -4501,7 +4501,8 @@ QXLDrawable *QxlDevice::PrepareBltBits (<br> ><br> >      for (; src != src_end; src -= pSrc->Pitch, alloc_size -= line_size) {<br> >          if (!PutBytesAlign(&chunk, &dest, &dest_end, src,<br> > -            line_size, alloc_size, line_size)) {<br> > +            line_size, alloc_size, NULL)) {<br> > +            // not reachable when forced allocation used<br> >              ReleaseOutput(drawable-><a href="http://release_info.id" rel="noreferrer" target="_blank" data-mce-href="http://release_info.id">release_info.id</a>);<br> >              DbgPrint(TRACE_LEVEL_ERROR, ("Cannot allocate additional bitmap<br> >              for drawable\n"));<br> >              return NULL;<br> > @@ -4526,36 +4527,54 @@ QXLDrawable *QxlDevice::PrepareBltBits (<br> >      return drawable;<br> >  }<br> ><br> > +// can work in 2 modes:<br> > +// forced - as before, when pDelayed not provided or if VSync is not in use<br> > +// non-forced, if VSync is active and pDelayed provided. In this case, if<br> > memory<br> > +// can't be allocated immediately, allocates 'delayed chunk' and copies data<br> > +// to it. Further, before send to the device, this 'delayed chunk' should be<br> > processed,<br> > +// regular chunk allocated from device memory and the data copied to it<br> >  BOOLEAN QxlDevice::PutBytesAlign(QXLDataChunk **chunk_ptr, UINT8 **now_ptr,<br> >                              UINT8 **end_ptr, UINT8 *src, int size,<br> > -                            size_t alloc_size, uint32_t alignment)<br> > +                            size_t alloc_size, PLIST_ENTRY pDelayed)<br> >  {<br> >      PAGED_CODE();<br> > +    BOOLEAN bResult = TRUE;<br> > +    BOOLEAN bForced = !g_bSupportVSync || !pDelayed;<br> >      QXLDataChunk *chunk = *chunk_ptr;<br> >      UINT8 *now = *now_ptr;<br> >      UINT8 *end = *end_ptr;<br> > +    size_t maxAllocSize = BITS_BUF_MAX - BITS_BUF_MAX % size;<br> > +    alloc_size = MIN(size, maxAllocSize);<br> >      DbgPrint(TRACE_LEVEL_VERBOSE, ("---> %s\n", __FUNCTION__));<br> ><br> >      while (size) {<br> >          int cp_size = (int)MIN(end - now, size);<br> >          if (!cp_size) {<br> > -            size_t aligned_size;<br> > -            aligned_size = (int)MIN(alloc_size + alignment - 1,<br> > BITS_BUF_MAX);<br> > -            aligned_size -=  aligned_size % alignment;<br> > -<br> > -            void *ptr = AllocMem(MSPACE_TYPE_VRAM, size +<br> > sizeof(QXLDataChunk), TRUE);<br> > -            if (!ptr) {<br> > -                return FALSE;<br> > +            void *ptr = (bForced || IsListEmpty(pDelayed)) ?<br> > AllocMem(MSPACE_TYPE_VRAM, alloc_size + sizeof(QXLDataChunk), bForced) :<br> > NULL;<br> > +            if (ptr) {<br> > +                chunk->next_chunk = PA(ptr, m_SurfaceMemSlot);<br> > +                ((QXLDataChunk *)ptr)->prev_chunk = PA(chunk,<br> > m_SurfaceMemSlot);<br> > +                chunk = (QXLDataChunk *)ptr;<br> > +                chunk->next_chunk = 0;<br> > +            }<br> > +            if (!ptr && pDelayed) {<br> > +                ptr = new (PagedPool)BYTE[alloc_size +<br> > sizeof(QXL_DELAYED_CHUNK)];<br> > +                if (ptr) {<br> > +                    QXL_DELAYED_CHUNK *pChunk = (QXL_DELAYED_CHUNK *)ptr;<br> > +                    InsertTailList(pDelayed, &pChunk->list);<br> > +                    pChunk->chunk.prev_chunk = (QXLPHYSICAL)chunk;<br> > +                    chunk = &pChunk->chunk;<br> > +                }<br> > +            }<br> > +            if (ptr) {<br> > +                chunk->data_size = 0;<br> > +                now = chunk->data;<br> > +                end = now + alloc_size;<br> > +                cp_size = (int)MIN(end - now, size);<br> > +            } else {<br> > +                bResult = FALSE;<br> > +                break;<br> >              }<br> > -            chunk->next_chunk = PA(ptr, m_SurfaceMemSlot);<br> > -            ((QXLDataChunk *)ptr)->prev_chunk = PA(chunk, m_SurfaceMemSlot);<br> > -            chunk = (QXLDataChunk *)ptr;<br> > -            chunk->data_size = 0;<br> > -            chunk->next_chunk = 0;<br> > -            now = chunk->data;<br> > -            end = now + size;<br> > -<br> > -            cp_size = (int)MIN(end - now, size);<br> >          }<br> >          RtlCopyMemory(now, src, cp_size);<br> >          src += cp_size;<br> > @@ -4567,7 +4586,7 @@ BOOLEAN QxlDevice::PutBytesAlign(QXLDataChunk<br> > **chunk_ptr, UINT8 **now_ptr,<br> >      *now_ptr = now;<br> >      *end_ptr = end;<br> >      DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s\n", __FUNCTION__));<br> > -    return TRUE;<br> > +    return bResult;<br> >  }<br> ><br> >  VOID QxlDevice::BlackOutScreen(CURRENT_BDD_MODE* pCurrentBddMod)<br> > @@ -4685,12 +4704,11 @@ NTSTATUS  QxlDevice::SetPointerShape(_In_ CONST<br> > DXGKARG_SETPOINTERSHAPE* pSetPoi<br> >      end = (UINT8 *)res + CURSOR_ALLOC_SIZE;<br> >      src_end = src + (pSetPointerShape->Pitch * pSetPointerShape->Height *<br> >      num_images);<br> >      for (; src != src_end; src += pSetPointerShape->Pitch) {<br> > -        if (!PutBytesAlign(&chunk, &now, &end, src, line_size,<br> > -                 PAGE_SIZE, 1))<br> > -        {<br> > -            DbgPrint(TRACE_LEVEL_ERROR, ("%s: Failed to allocate cursor<br> > bitmap\n", __FUNCTION__));<br> > -            ReleaseOutput(cursor_cmd-><a href="http://release_info.id" rel="noreferrer" target="_blank" data-mce-href="http://release_info.id">release_info.id</a>);<br> > -            return STATUS_INSUFFICIENT_RESOURCES;<br> > +        if (!PutBytesAlign(&chunk, &now, &end, src, line_size, PAGE_SIZE -<br> > PAGE_SIZE % line_size, NULL)) {<br> > +            // we have a chance to get here only with color cursor bigger<br> > than 45*45<br> > +            // and only if we modify this procedure to use non-forced<br> > allocation<br> > +            DbgPrint(TRACE_LEVEL_ERROR, ("%s: failed to push part of<br> > shape\n", __FUNCTION__));<br> > +            break;<br> >          }<br> >      }<br> >      CursorCmdAddRes(cursor_cmd, res);<br> > diff --git a/qxldod/QxlDod.h b/qxldod/QxlDod.h<br> > index 059e1bd..e18afac 100755<br> > --- a/qxldod/QxlDod.h<br> > +++ b/qxldod/QxlDod.h<br> > @@ -260,6 +260,13 @@ public:<br> >  };<br> >  #endif<br> ><br> > +typedef struct _QXL_DELAYED_CHUNK<br> > +{<br> > +    LIST_ENTRY list;<br> > +    UINT32 type;<br> > +    QXLDataChunk chunk;<br> > +} QXL_DELAYED_CHUNK;<br> > +<br><br></div></div>The name of this type is quite odd.<br> Is suggests some Windows internal C structure.<br> This header is only C++ compatible, so the typedef make no sense.<br> The capital case is used for QXL protocol specific stuff, but<br> this is not even allocate in QXL memory but in system one.<br> I would suggest a simple QXLDelayedChunk or even DelayedChunk.<br><br> The "type" field is not used in the code.<br></blockquote><div><br></div><div>The type field is preparation for further extension - we'll need it if we decide to make also allocations of empty Drawable objects and cursor objects non-forced. </div></div></div></div></blockquote><div>I'd prefer to avoid it or put as a comment.<br></div><div>Is not clear for instance which type should be, we could use an enumeration.<br></div><div>I don't see to meaning to add a possible field without knowing the usage.<br></div><div><br></div><div>Are you fine with the type name change?<br></div><div>I can easily change it (on this and following).<br></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex" data-mce-style="margin: 0 0 0 .8ex; border-left: 1px #ccc solid; padding-left: 1ex;"><div class="HOEnZb"><div class="h5"><br> >  class QxlDod;<br> ><br> >  class HwDeviceInterface {<br> > @@ -603,7 +610,7 @@ private:<br> >      void PushCursor(void);<br> >      BOOLEAN PutBytesAlign(QXLDataChunk **chunk_ptr, UINT8 **now_ptr,<br> >                              UINT8 **end_ptr, UINT8 *src, int size,<br> > -                            size_t alloc_size, uint32_t alignment);<br> > +                            size_t alloc_size, PLIST_ENTRY pDelayed);<br> >      void AsyncIo(UCHAR  Port, UCHAR Value);<br> >      void SyncIo(UCHAR  Port, UCHAR Value);<br> >      NTSTATUS UpdateChildStatus(BOOLEAN connect);<br><br></div></div><span class="HOEnZb"><span data-mce-style="color: #888888;" style="color: #888888;">Frediano<br> </span></span></blockquote></div><br></div></div></blockquote><div><br></div></div></body></html>