Sign in to follow this  
Tacio

Possibility to port to SimDX or something else

Recommended Posts

Tacio    100
I'm currently writing a program in c#, that decodes j2k images, makes resize to them and draw on Image control. Part of code:
private static System.Drawing.Bitmap createRawBitmap(IntPtr decoded_image_ptr, int decoded_image_size, J2K_Info info)
        {
            int stride = info.Width * ((info.Components == 1) ? 1 : 4);// info from J2K decoder
            Bitmap resized_bitmap = new Bitmap(info.Width, 2 * info.Height);
            Bitmap bitmap_from_ptr = new Bitmap(info.Width, info.Height, stride, PixelFormat.Format32bppArgb, decoded_image_ptr);
            using (Graphics g = Graphics.FromImage((Image)resized_bitmap))
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
                g.DrawImage(bitmap_from_ptr, 0, 0, info.Width, 2 * info.Height);
            }
            return resized_bitmap;
        }

Goal - try to display ~20 images per second. But as you can see all methods in code uses GDI, so it no so fast :( Is there any way to port this to SlimDX or another faster libs? HW specs: intel pentium m 1600mhz, inel 850 chipset based graphics card.

Share this post


Link to post
Share on other sites
MJP    19753
You could certainly port that to SlimDX. After your decoding process you would create a D3D9 Texture instead of a GDI+ Image, and then you could could draw that texture to a custom UserControl using the Sprite helper class.

Keep in mind though that this won't make creating the images any quicker (in fact it may be slower), but it will certainly make drawing them much much quicker. Also with SlimDX you will have to manually manage the process of creating a device, and handling device lost/reset scenarios (at least if you use D3D9). Filling a texture with data is also a somewhat cumbersome process.

Share this post


Link to post
Share on other sites
Fiddler    860
First of all, you'll have to identify *where* your bottleneck lies. For example, if the j2k decoder is slow, optimizing the drawing part won't help you at all.

If drawing through GDI+ is indeed the bottleneck, you can move to WPF, D3D (SlimDX) or OpenGL (OpenTK) and gain advantage of hardware acceleration. This will make resizing and drawing the images blindingly fast but note that all of these technologies carry a learning curve.

If the bottleneck is indeed in the decoding part, your best bet is to parallelize the decoder. In other words, spawn as many decoding threads are your CPU count (or even more, considering that disk access will never allow these threads to reach 100% utilization). Once a thread is done decoding, it will notify your main "rendering" thread that it should draw the image.

Share this post


Link to post
Share on other sites
Tacio    100
Thanks for replies!

Of course, the most resource-intensive process is decoding. But all methods for decoding I call through pinvoke (c++ dll), so I can't change here anything.
Next resource-intensive method is resizing:
g.DrawImage(bitmap_from_ptr, 0, 0, info.Width, 2 * info.Height);
so I want to replace this method with something faster.
Fiddler, what you mean in "you can move to WPF"? This is already WPF application (.NET 3.5 sp1), but with GDI+ methods :)
May be I miss something../?

Share this post


Link to post
Share on other sites
MJP    19753
With Direct3D you can take a source texture, draw it to a "render target" texture that's of a different size, and then hang onto that texture for drawing. However it would be easier and (probably) more efficient to just store the original texture, and then draw it at the desired size whenever necessary (so that the GPU does the resizing every time you draw it).

Share this post


Link to post
Share on other sites
Tacio    100
Ok... Now I render my pictures through D3DImage and SlimDX on System.Windows.Controls.Image control and everything works fine.
Next step - resizing. MJP, how I can "draw it at the desired size whenever necessary (so that the GPU does the resizing every time you draw it)."?
Currently I do following:
_pp.BackBufferWidth = (int)_picture_output_size.Width;
_pp.BackBufferHeight = (int)_picture_output_size.Height;
where _pp - PresentParameters and _picture_output_size - size of Image control.
_texture = Texture.FromFile(this.Device, file_list[i], Usage.None, Pool.Default);

With these settings, small images will not grow to the size of the Image control, and large outside its borders.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this