locked
VirtualSurfaceImageSource system coordinates

    Question

  • Can anyone explain the coordinates that GetUpdateRecs returns, and the offset from BeginDraw?

    I can successfully use the BeginDraw offset with the SurfaceImageSource control, but as I switch to VirtualSurfaceImageSource it's all screwed up.

    Example:
    Take a VirtualSurfaceImageSource with 1920x1080 size inside a Rectangle that is 640x360.
    - GetUpdateRecs give me 12 rectangles. This is fine.
    - for all the rectangles of the last row and last column, the BeginDraw X offset is 54 .... why? What is that? For all the others is 2 (the border, I suppose)

    Furthermore, before drawing I try to clear the entire surface but the background color is applied only to a small portion on the right.

    I already read the (small) msdn doc and the magazine sample but they didn't help me.
     Thanks


    Raffaele Rialdi  http://www.iamraf.net
    Weblog: http://blogs.ugidotnet.org/raffaele
    Microsoft MVP profile https://mvp.support.microsoft.com/profile/raffaele
    UGIdotNET - http://www.ugidotnet.org/


    Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele
    Friday, May 11, 2012 7:56 AM

Answers

All replies

  • Hello,

     

    Thanks for your feedback, I will involve more experts to investigate it.

     

    Best regards,

    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    Monday, May 14, 2012 7:32 AM
    Moderator
  • Jesse Jiang wrote:

    Hello,

     

    Thanks for your feedback, I will involve more experts to investigate it.

     

    Best regards,

    Jesse

    Thanks Jesse, i just need basic infos to correctly erase the surface and understand where to draw (coordinates).

    BeginDraw and all the initialization are exactly the same of the magazine sample.
     -- Raffaele Rialdi  http://www.iamraf.net
    Weblog: http://blogs.ugidotnet.org/raffaele
    Microsoft MVP profile https://mvp.support.microsoft.com/profile/raffaele
    UGIdotNET - http://www.ugidotnet.org/


    Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele
    Monday, May 14, 2012 8:32 AM
  • The offset returned by BeginDraw doesn't map directly to the update rects or to any coordinates on the screen.  The surface returned by BeginDraw may also change between calls.  This is all dependent on internal optimizations which will restrict updates to the updateRect area you pass to BeginDraw.  It's often easiest therefore to, for instance, apply a clip and transform via the device context (D2D) or set a viewport that take into account the offset (D3D) before drawing to the surface returned by BeginDraw.

    Clearing the surface that is returned (e.g. via ID2D1RenderTarget::Clear or ID3D11DeviceContext::ClearRenderTargetView) will similarly only clear the dimensions of the surface requested by BeginDraw. 

    Monday, May 14, 2012 5:11 PM
  • Jesse Bishop [MSFT] wrote:

    The offset returned by BeginDraw doesn't map directly to the update rects or to any coordinates on the screen.  The surface returned by BeginDraw may also change between calls. 

    exactly what I am seeing, thanks


    This is all dependent on internal optimizations which will restrict updates to the updateRect area you pass to BeginDraw.  It's often easiest therefore to, for instance, apply a clip and transform via the device context (D2D) or set a viewport that take into account the offset (D3D) before drawing to the surface returned by BeginDraw.

    Clearing the surface that is returned (e.g. via ID2D1RenderTarget::Clear or ID3D11DeviceContext::ClearRenderTargetView) will similarly only clear the dimensions of the surface requested by BeginDraw. 

    After the BeginDraw I do the following:
    - obtain a bitmap calling CreateBitmapFromDxgiSurface
    - call begindraw on the D2D context
    - SetTarget(bitmap.Get())
    - Clear on the D2DContext
    - Set the transform on D2DContext:
    D2D1::Matrix3x2F::Translation(static_cast<float>(offset.x - rect.left), static_cast<float>(offset.y - rect.top));
    - Draw a rectangle
    - SetTarget(nullptr)
    - EndDraw on D2D and on the surface

    This led me to ... nothing.
    The box is totally black background and no rectangle.
    I also tried to clear using ClearRenderTargetView on the d3d context without any result
     The same code on a non-virtual (SurfaceImageSource) works perfectly (the background is ok, the rectangle appears in the right position).

    Do you have any idea on that could I possibly miss?


    Raffaele Rialdi  http://www.iamraf.net
    Weblog: http://blogs.ugidotnet.org/raffaele
    Microsoft MVP profile https://mvp.support.microsoft.com/profile/raffaele
    UGIdotNET - http://www.ugidotnet.org/


    Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele
    Monday, May 14, 2012 5:56 PM
  • Your transform may be causing the issue you're seeing - you likely shouldn't be subtracting the updaterect from the offset as your steps imply.  I believe it's also recommended that apps call SetTarget before starting to draw.  Here's a rough outline of how to account for the offset in D2D that may help:

    POINT offset;
    ComPtr<IDXGISurface> surface;
    HRESULT beginDrawHR = m_sisNative->BeginDraw(updateRect, &surface, &offset);
    if (beginDrawHR == DXGI_ERROR_DEVICE_REMOVED || beginDrawHR == DXGI_ERROR_DEVICE_RESET)
    {
    // ... recreate device and continue drawing
    }
    else
    {
    // ... error handling
    }
    // Create render target
    ComPtr<ID2D1Bitmap1> bitmap;
    m_d2dContext->CreateBitmapFromDxgiSurface(surface.Get(), NULL, &bitmap);

    // Set context's render target
    m_d2dContext->SetTarget(bitmap.Get());

    // Begin drawing using D2D context
    m_d2dContext->BeginDraw();

    // Apply clip
    m_d2dContext->PushAxisAlignedClip(
    D2D1::RectF(
    static_cast<float>(offset.x),
    static_cast<float>(offset.y),
    static_cast<float>(offset.x + updateRect.Width),
    static_cast<float>(offset.y + updateRect.Height)
    ),
    D2D1_ANTIALIAS_MODE_ALIASED
    );

    // Apply transform
    m_d2dContext->SetTransform(
    D2D1::Matrix3x2F::Translation(
    static_cast<float>(offset.x),
    static_cast<float>(offset.y)
    ));

    // Clear update rect
    m_d2dContext->Clear(ConvertToColorF(color));

    // Draw a rectangle
    m_d2dContext->FillRectangle(ConvertToRectF(rect), m_brush.Get());

    // Reset transform and clip
    m_d2dContext->SetTransform(D2D1::IdentityMatrix());
    m_d2dContext->PopAxisAlignedClip();

    // Clear render target and end drawing
    m_d2dContext->EndDraw();
    m_d2dContext->SetTarget(NULL);
    m_sisNative->EndDraw();



    Monday, May 14, 2012 8:59 PM
  • Hi, I finally had some time to make new tests.

    The transform I used works on the non-virtual surface and took it from the sdk sample.

    Anyway I did exactly what you posted here and I could not make it work.

    The problem here is that I see different results by running the sample on the local machine and the simulator. I will assume it's a weird bug and I'll wait for the next drop before wasting time in making further tests.

    Thank you very much for your time.


    Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele

    Sunday, May 27, 2012 10:04 AM
  • Does it work on the local machine and not in the simulator?

    Do you have a minimal example project you could share (e.g. upload to SkyDrive) to look into this?

    Tuesday, June 5, 2012 8:16 PM
  • Jesse Bishop [MSFT] wrote:

    Does it work on the local machine and not in the simulator?

    Do you have a minimal example project you could share (e.g. upload to SkyDrive) to look into this?

    I confirm that it was a problem of the Developer Preview.
    Without changing the code but running on the Release Preview, it now all works as expected.

    Thanks anyway.


    Raffaele Rialdi  http://www.iamraf.net
    Weblog: http://blogs.ugidotnet.org/raffaele
    Microsoft MVP profile https://mvp.support.microsoft.com/profile/raffaele
    UGIdotNET - http://www.ugidotnet.org/


    Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele
    Monday, June 25, 2012 1:17 PM