-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Need suggestion for wdDrawString performance increase #24
Comments
I admit the lib was created with "ease of use" rather then "being as fast as possible" in mind, for purposes of GUI controls in mctrl, where the speed is not that critical. Also, quite often some design choices were dictated by limitations of GDI+ back-end support. Additionally, the support for old Windows versions (which had to use GDI+) was recently removed from mctrl code base and mctrl now uses Direct2D directly. Therefore my motivation to implement new features in WinDrawLib is quite low. That said, feel free to make a pull request. Writing the code should not be that difficult and I can point you in right directions if needed. Generally, I can see the following options:
|
Hello Martin,
Thanks for the ideas. I think choice 2 makes sense for my application (https://sourceforge.net/projects/strobetuner/). I am making the entire direct2d display buffer a pixel at a time and then calling wdCreateImageFromBuffer. The part I don't understand about choice 2 is how to merge the graphic image created with wdCreateImageFromBuffer and the text overlay image created with the new function wdCreateBitmapCanvas. I would like to overlay the text onto the graphic image and then display the result.
Thanks,
Scott
On Friday, December 27, 2019, 11:33:41 PM CST, Martin Mitáš <[email protected]> wrote:
I admit the lib was created with "ease of use" rather then "being as fast as possible" in mind, for purposes of GUI controls in mctrl, where the speed is not that critical. Also, quite often some design choices were dictated by limitations of GDI+ back-end support.
Additionally, the support for old Windows versions (which had to use GDI+) was recently removed from mctrl code base and mctrl now uses Direct2D directly. Therefore my motivation to implement new features in WinDrawLib is quite low.
That said, feel free to make a pull request. Writing the code should not be that difficult and I can point you in right directions if needed.
Generally, I can see the following options:
-
If the scene/background where the text lives changes relatively sporadically, use the canvas caching (assuming you use wdCreateCanvasWithPaintStruct()). When reusing the cached canvas, paint only those parts of the scene which do change between the frames. Direct2D implicitly uses double buffering and retains the contents of the ID2D1HwndRenderTarget which is under the hood of the canvas created with the function.
-
Or, adding a new wdCreateBitmapCanvas() so that you can paint the strings into it and then just copy the pre-painted bitmaps. It would use ID2D1Factory::CreateWicBitmapRenderTarget() with Direct2D backend or gdix_canvas_alloc() with GDI+ backend under the hood. See wdCreateCanvasWithHDC() in src/canvas.c, the new function would be likely quite similar.
This approach would have one drawback: Direct2D supports several modes of text aliasing. One which paints directly to the target background and uses that for achieving better aliasing quality; or a universal mode which does not use any target info and which is intended it for painting on any background. This would have to use the latter. I'm not sure how big impact on quality this would bring.
-
Or, adding an ability to store and reuse IDWriteTextLayout. Currently, wdDrawString() in src/string.c creates it, uses it and destroys it. So, some new wdCreateTextLayout(), wdDrawTextLayout() and wdDestroyTextLayout() could be implemented to break it into separate operations so that all the expensive glyph layouting work can be reused if the strings do not change between the frames.
Unfortunately, AFAIK, GDI+ does not support anything like that so it would have to be emulated to keep the function parity. wdCreateTextLayout() would likely just allocate some helper structure to store the text layout parameters passed to it so that wdDrawTextLayout() could retrieve them later via the handle representing the "text layout".
(Also see #17. It was meant to do something similar and also much more then that, but it was too ambitious and it would probably never fully support GDI+ backend, that's why mCtrl swtiched to Direct2D directly and I abandoned the pull request. But some simplified version of it, in order to just break the single big operations into separate ones, should not be a problem and quite likely few initial commits of that PR more or less do that.)
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
|
Hello and thanks for this library. Though I am an experienced software engineer, this is my first time using Windows graphics. My app needs to render a large window pixel by pixel at 60 frames per second and this direct2d library is getting the job done. The problem is that after the frame is rendered, it needs to be overlayed with many text labels. The text never changes. Right now, I am calling wdDrawString many times for each frame. This makes 60 frames per second difficult to achieve. Because the text never changes, it seems like there should be a way to prepare it one time, and reuse it over and over. But I do not see how to do that. If I could prepare the text overlay once and convert it to a bit map form, then I could merged it into the rendered bitmap efficiently.
The text was updated successfully, but these errors were encountered: