Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jul 20 05:51
    dongyado commented #113
  • Jul 19 21:07
    LostVector closed #116
  • Jul 19 01:07
    LostVector commented #116
  • Jul 18 21:19
    kobalicek commented #116
  • Jul 18 21:18
    kobalicek commented #116
  • Jul 18 19:55
    LostVector opened #116
  • Jul 17 02:47
    bizehao commented #114
  • Jul 14 23:42
    kobalicek commented #113
  • Jul 14 23:42
    kobalicek commented #114
  • Jul 14 23:41
    kobalicek commented #114
  • Jul 14 23:39
    kobalicek closed #115
  • Jul 14 23:39
    kobalicek commented #115
  • Jul 14 23:38

    kobalicek on master

    [Bug] Don't refuse to stroke ge… (compare)

  • Jul 14 08:56
    kobalicek commented #115
  • Jul 14 08:53
    kobalicek commented #115
  • Jul 14 08:22
    yzrmn commented #115
  • Jul 14 07:45
    LostVector opened #115
  • Jul 14 01:39
    bizehao commented #114
  • Jul 14 01:39
    bizehao opened #114
  • Jul 10 17:39
    kobalicek closed #112
Petr Kobalicek
@kobalicek
it would actually make sense to think of making the rasterizer itself use SIMD, not just the pipeline
because the rasterizer is still pretty significant cycle consumer when rendering vector geometry
Federico Pietrobono
@fjpietr
I think that this is far more useful than having a GPU path
Pierre Joye
@pierrejoye
Federico Pietrobono
@fjpietr
@pierrejoye interesting
Check this too https://ispc.github.io/ my favourite toy lately
Petr Kobalicek
@kobalicek
It's all interesting, but if the target arch is missing some instructions that are the foundation of your algos, it's all wasted :)
I was for example kinda surprised that vector shuffling is so difficult on ARM/AArch64
it's almost impossible to apply the same techniques we are used to in AVX world
but then you discover that ARM/AArch64 has a "component" load, so you can decompose components of RGB/RGBA pixel into separate vectors at load/store
so in X86 mode you want pixels packed, on ARM unpacked - I see no common path here :)
Federico Pietrobono
@fjpietr
Programmer's life is full of suffering
Federico Pietrobono
@fjpietr
On a side note, ispc does support arm (and apple silicon too) so while it is out of scope for something like blend2d it is surely useful e.g. for code laid above it
Pierre Joye
@pierrejoye

On a side note, ispc does support arm (and apple silicon too) so while it is out of scope for something like blend2d it is surely useful e.g. for code laid above it

nice! Thanks!

@kobalicek very good papers! https://blend2d.com/research.html amazingly found them while googling the same topic )
I was reading "Fast approaches to simplify and offset Bézier curves within specified error limits" and found what I was looking for :)
Petr Kobalicek
@kobalicek
Thanks! Let's credit @yzrmn for these as it's entirely his work :)
Pierre Joye
@pierrejoye
I think at some point I will need his knowledge, when I come to do proper dash support (kind of fighting to keep them consistent after flattening ;)

Thanks! Let's credit @yzrmn for these as it's entirely his work :)

thanks @yzrmn :)

Petr Kobalicek
@kobalicek
Blend2D will have a proper dash support too :)
But this was delayed as it's not really trivial to do
Pierre Joye
@pierrejoye
really not, well, simple ones is, but bcurve division and non on/off dashes are totally not trivial :)
or paths for what matter
Fabian Yzerman
@yzrmn
Hi, thanks! I'm glad to see this can be of use and also that the papers are able to be googled :)
Well the algorithms for dashing all work in my prototype and degenerate cases are caught i.e. reasonably solved
The big problem is a nice abstraction over the implementation which is also performant
Fabian Yzerman
@yzrmn
E.g. we would like to avoid two separate codepaths for regular stroking and dashing+stroking
Then again, we could make APIs available to the user which allow dashing only (another unwanted codepath if not properly abstracted)
In addition to that, if we would give a choice of method (recursive vs iterative) this might quickly turn into a mess
Petr Kobalicek
@kobalicek
True, nice API is what we need :)
Pierre Joye
@pierrejoye
nice api, harder than math ;)
by iterative you mean forward diff?
challenging to avoid two different codepaths, without splitting both, but again, I am not much of a math guy so maybe there are solutions :)
https://hal.inria.fr/file/index/docid/907326/filename/paper.pdf < interesting one, Shader-Based Antialiased Dashed Stroked Polylines
Seppo Pietarinen
@spietari
Is there a simple example where I can draw a BLContext to a window in Windows? I know next to nothing about Windows API. I'm working on a wxWidgets application and I seem to be able to get a hWND of the pane I want to draw to.
Petr Kobalicek
@kobalicek
I think the easiest way is to create a DIBSECTION, pass its buffer to BLImage (create external image), paint to it, and then blit it to the HWND's HDC, but this is just how I would start, maybe there is much better way with recent Windows API
William Adams
@Wiladams
Even with modern Windows APIs, this is still the easiest way to do it.
William Adams
@Wiladams
class User32Surface : public AppSurface
{
    // This is a most generic window message handler.  If the window sub-class
    // has a message handler, call that.
    // Otherwise, call default Window's Procedure
    static LRESULT CALLBACK ClassMsgHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        LRESULT res = 0;

        // get userdata from window handle
        User32Surface* winObject = (User32Surface *)::GetWindowLongPtr(hWnd, GWLP_USERDATA);
        if (winObject != nullptr) {
            return winObject->handleMsg(hWnd, msg, wParam, lParam);
        }

        // handle message in default way
        return DefWindowProcA(hWnd, msg, wParam, lParam);
    }

    User32Window *fAppWindow = nullptr;
    HWND fWindowHandle;
    HBITMAP fDIBHandle = nullptr;
    void* fData = nullptr;       // A pointer to the data
    size_t fDataSize = 0;       // How much data is allocated
    HDC     fBitmapDC = nullptr;    // Device Context that has dibsection selected

    BLImage fImage;

    User32Surface(size_t w, size_t h, HWND hWnd)
        :AppSurface(w, h),
        fWindowHandle(hWnd)
    {
        // Construct a layered window
        User32WindowClass wKind("appsurface", CS_GLOBALCLASS | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, ClassMsgHandler);
        fAppWindow = wKind.createWindow("User32 Surface", w, h, WS_POPUP, WS_EX_LAYERED | WS_EX_NOREDIRECTIONBITMAP);
        ::SetWindowLongPtr(fAppWindow->getHandle(), GWLP_USERDATA, (LONG_PTR)this);

        // construct an in memory bitmap used for rendering
        int bytesPerRow = w * alignment;
        BITMAPINFO bminfo = {};

        bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bminfo.bmiHeader.biWidth = w;
        bminfo.bmiHeader.biHeight = -(LONG)h;    // top-down DIB Section
        bminfo.bmiHeader.biPlanes = 1;
        bminfo.bmiHeader.biBitCount = bitsPerPixel;
        bminfo.bmiHeader.biSizeImage = bytesPerRow * h;
        bminfo.bmiHeader.biClrImportant = 0;
        bminfo.bmiHeader.biClrUsed = 0;
        bminfo.bmiHeader.biCompression = BI_RGB;

        // Create the actual bitmap that's used for rendering
        fDIBHandle = CreateDIBSection(nullptr, &bminfo, DIB_RGB_COLORS, &fData, nullptr, 0);
        fDataSize = bminfo.bmiHeader.biSizeImage;

        // Create a device context so we can connect out bitmap
        // to GDI/User32 drawing routines
        fBitmapDC = CreateCompatibleDC(nullptr);

        // select the DIBSection into the memory context so we can 
        // peform operations with it
        ::SelectObject(fBitmapDC, fDIBHandle);

        // Initialize the BLImage
        // MUST use the PRGB32 in order for SRC_OVER operations to work correctly
        BLResult bResult = blImageInitAsFromData(&fImage, w, h, BL_FORMAT_PRGB32, fData, (intptr_t)bytesPerRow, nullptr, nullptr);

    }
CreateDIBSection
CreateCompatibleDC
SelectObject
blImageInitAsFromData
William Adams
@Wiladams
fBitmapDC can then be used in a BitBlt call to transfer the DIBSection to the Window's DC.
Windows esoterica, but it works out.
https://github.com/wiladams/ndt has a ton of stuff and simple frameworks that play around with this. If you get to the point where speed matters on the BLT, you can looking into the more advanced framebuffer transfers.
Petr Kobalicek
@kobalicek
I think the first thing to try when running into performance issues would be to not create the DIBSECTION on every paint request - that should be cached otherwise a lot of cycles would be spent creating it
But so far even for my purposes DIBSECTION always worked reliably well
It's much easier to create DIBSECTION on Windows than to do anything else on Linux :-D
William Adams
@Wiladams
I cache DIB just like that. Other than programming with DirectX surfaces, DIB Has be my fastest, most flexible, easiest go-to for about 20 years.
Seppo Pietarinen
@spietari
Beautiful! Thanks so much guys, works perfectly.
Seppo Pietarinen
@spietari
Is dashed line support back?
Fabian Yzerman
@yzrmn
It's coming, but no time frame yet sorry