473,387 Members | 3,820 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Fastest BitBlt in C#/.NET

_AV
I need to do ultra-fast bitblts in a C# program. Is it necessary to go
back to the older GDI DLL, or is are there fast calls within GDI+?

Basically what I'm doing is creating an array of 32-bit ints (pixels) in
memory, writiing individual pixels in the array, and then blitting it to
the screen. The in-mem image is relatively simple 2-D vector graphics,
so the Blit is the biggest bottleneck at present.
Nov 16 '05 #1
11 21956
GDI+ is not known for it's speed *S*.

For fast graphics I would recomend using Direct X ( or assembler / c++) ;)

--
Patrik Löwendahl [C# MVP]
www.cshrp.net - "Elegant code by witty programmers"
"_AV" <_a*@nospam.net> wrote in message
news:il********************************@4ax.com...
I need to do ultra-fast bitblts in a C# program. Is it necessary to go
back to the older GDI DLL, or is are there fast calls within GDI+?

Basically what I'm doing is creating an array of 32-bit ints (pixels) in
memory, writiing individual pixels in the array, and then blitting it to
the screen. The in-mem image is relatively simple 2-D vector graphics,
so the Blit is the biggest bottleneck at present.

Nov 16 '05 #2
DrawImageUnscaled and DrawCachedBitmap are your fastest two managed
alternatives. DrawCachedBitmap approaches the same speed as BitBlt (not
quite, but almost) with the only problem being that it doesn't have a C#
equivalent and is part of the GDI+ flat API (consumed by C++).

Use GDI, you can get some pretty good frame-rates out of it. Take major
advantage of dirty rectangles so you only copy the area of the buffer that
changes and you should be fine.
--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"Patrik Löwendahl [C# MVP]" <pa**************@csharpsweden.com> wrote in message
news:%2******************@TK2MSFTNGP11.phx.gbl...
GDI+ is not known for it's speed *S*.

For fast graphics I would recomend using Direct X ( or assembler / c++) ;)

--
Patrik Löwendahl [C# MVP]
www.cshrp.net - "Elegant code by witty programmers"
"_AV" <_a*@nospam.net> wrote in message
news:il********************************@4ax.com...
I need to do ultra-fast bitblts in a C# program. Is it necessary to go
back to the older GDI DLL, or is are there fast calls within GDI+?

Basically what I'm doing is creating an array of 32-bit ints (pixels) in
memory, writiing individual pixels in the array, and then blitting it to
the screen. The in-mem image is relatively simple 2-D vector graphics,
so the Blit is the biggest bottleneck at present.


Nov 16 '05 #3
This link may be helpful

http://support.crainiate.net/?s=Know...AQ/bitblt.html

Regards
James

--
Create interactive diagrams and flowcharts with ERM Diagram at
http://www.crainiate.net

"_AV" <_a*@nospam.net> wrote in message
news:il********************************@4ax.com...
I need to do ultra-fast bitblts in a C# program. Is it necessary to go
back to the older GDI DLL, or is are there fast calls within GDI+?

Basically what I'm doing is creating an array of 32-bit ints (pixels) in
memory, writiing individual pixels in the array, and then blitting it to
the screen. The in-mem image is relatively simple 2-D vector graphics,
so the Blit is the biggest bottleneck at present.

Nov 16 '05 #4
He points out well in the FAQ how careful you have to be with unmanaged
code. Primarily, you have to be prepared to harden your methods. In 99.99%
of all cases the code in the tutorial will work, but there is an ever expanding
percentage that an exception will be thrown during various portions of the
method and help to create a nasty resource leak.

Make sure you either wrap your IntPtr's into a handle with GC protection if
you plan on not doing error handling, or place in the appropriate error handling
to make sure resources are properly cleaned.

To be purely hardened would take an immense amount of work. A basic hardening
can be performed by assuming that all work done in the finally block won't fail
(but
it still can fail, which creates a bad situation for everyone).

--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"James Westgate" <ja***********@nospam.nospam> wrote in message
news:u9**************@TK2MSFTNGP11.phx.gbl...
This link may be helpful

http://support.crainiate.net/?s=Know...AQ/bitblt.html

Regards
James

--
Create interactive diagrams and flowcharts with ERM Diagram at
http://www.crainiate.net

"_AV" <_a*@nospam.net> wrote in message
news:il********************************@4ax.com...
I need to do ultra-fast bitblts in a C# program. Is it necessary to go
back to the older GDI DLL, or is are there fast calls within GDI+?

Basically what I'm doing is creating an array of 32-bit ints (pixels) in
memory, writiing individual pixels in the array, and then blitting it to
the screen. The in-mem image is relatively simple 2-D vector graphics,
so the Blit is the biggest bottleneck at present.


Nov 16 '05 #5
_AV
On Sun, 10 Oct 2004 15:22:29 -0700, "Justin Rogers"
<Ju****@games4dotnet.com> wrote:
Make sure you either wrap your IntPtr's into a handle with GC protection if
you plan on not doing error handling,


Not sure I follow this, Justin. Is it possible to illustrate what you
mean re wrapping IntPtrs?

Nov 16 '05 #6
You need some intricate knowledge of how the run-time works. Take for instance
something like (pseudo)

IntPtr i1 = GetHdc();
DoSomethingWithDC(new HandleRef(null, i1), ...);
ReleaseDC(i1);

Okay, that code demonstrates the problem. DoSomethingWithDC can throw an
exception (OOM, SOE,
TAE, or any number of others)... If it does i1 is lost for good, and you can't
release it. Now, if you do this
with a Graphics object, the IntPtr is actually stored INTERNALLY first... The
Graphics object actually
has an internal member variable allowing it to wrap and then return the hDC...
If an exception occurs,
then at some point the GC will kick in and run the finalizer for the Graphics
and collect the resource by
calling ReleaseDC explicitly.

That is what I mean by wrapping the IntPtr in a managed object. For instance,
the CreateCompatibleDC
in the tutorial allocates an hDC, but doesn't wrap it in a managed object. If
the method fails later, there is
no storage of the IntPtr to be cleaned up, it just leaks. If you placed this in
say a new class called HandleDC
then a finalizer could enforce the release of the resource.

public class CompatibleDC {
private IntPtr dc = IntPtr.Zero;
~CompatibleDC() { Release(); }

private CompatibleDC() {}

public static CompatibleDC CreateCompatibleDC(IntPtr initialDC) {
CompatibleDC cDC = new CompatibleDC(); // allocate memory here, if OOM,
then no leakage.
cDC.dc = Win32.CreateCompatibleDC(initialDC); // Wrapped in an object
instance now.
return cDC; // Give this to the client
}

// Not thread-safe
public IntPtr DC { get { return this.dc; } }
public void Release() {
if ( dc != IntPtr.Zero ) { Win32.ReleaseDC(dc); dc = IntPtr.Zero; }
}
}

--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"_AV" <_a*@nospam.net> wrote in message
news:cs********************************@4ax.com...
On Sun, 10 Oct 2004 15:22:29 -0700, "Justin Rogers"
<Ju****@games4dotnet.com> wrote:
Make sure you either wrap your IntPtr's into a handle with GC protection if
you plan on not doing error handling,


Not sure I follow this, Justin. Is it possible to illustrate what you
mean re wrapping IntPtrs?

Nov 16 '05 #7
Instead of relying on garbage collection to (eventually) release the
resource, it would be better to make the wrapper class derive from
IDisposable and implement Dispose to release the resource. You would then
use the wrapper class like so:

using (CompatibleDC cdc = CompatibleDC.CreateCompatibleDC(initialDC))
{
// ...
}

Relying on garbage collection to release unmanaged resources is not a too
robust practice.

Regards,
Sami

"Justin Rogers" <Ju****@games4dotnet.com> wrote in message
news:Oh**************@TK2MSFTNGP14.phx.gbl...
You need some intricate knowledge of how the run-time works. Take for instance something like (pseudo)

IntPtr i1 = GetHdc();
DoSomethingWithDC(new HandleRef(null, i1), ...);
ReleaseDC(i1);

Okay, that code demonstrates the problem. DoSomethingWithDC can throw an
exception (OOM, SOE,
TAE, or any number of others)... If it does i1 is lost for good, and you can't release it. Now, if you do this
with a Graphics object, the IntPtr is actually stored INTERNALLY first... The Graphics object actually
has an internal member variable allowing it to wrap and then return the hDC... If an exception occurs,
then at some point the GC will kick in and run the finalizer for the Graphics and collect the resource by
calling ReleaseDC explicitly.

That is what I mean by wrapping the IntPtr in a managed object. For instance, the CreateCompatibleDC
in the tutorial allocates an hDC, but doesn't wrap it in a managed object. If the method fails later, there is
no storage of the IntPtr to be cleaned up, it just leaks. If you placed this in say a new class called HandleDC
then a finalizer could enforce the release of the resource.

public class CompatibleDC {
private IntPtr dc = IntPtr.Zero;
~CompatibleDC() { Release(); }

private CompatibleDC() {}

public static CompatibleDC CreateCompatibleDC(IntPtr initialDC) {
CompatibleDC cDC = new CompatibleDC(); // allocate memory here, if OOM, then no leakage.
cDC.dc = Win32.CreateCompatibleDC(initialDC); // Wrapped in an object instance now.
return cDC; // Give this to the client
}

// Not thread-safe
public IntPtr DC { get { return this.dc; } }
public void Release() {
if ( dc != IntPtr.Zero ) { Win32.ReleaseDC(dc); dc = IntPtr.Zero; } }
}

--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"_AV" <_a*@nospam.net> wrote in message
news:cs********************************@4ax.com...
On Sun, 10 Oct 2004 15:22:29 -0700, "Justin Rogers"
<Ju****@games4dotnet.com> wrote:
Make sure you either wrap your IntPtr's into a handle with GC protection ifyou plan on not doing error handling,


Not sure I follow this, Justin. Is it possible to illustrate what you
mean re wrapping IntPtrs?


Nov 16 '05 #8
That was an example. Unfortunately, in the realm of GDI, you'd wind up with 5 or
6
using statements per behavior, and it can get ugly very fast. If you were to
harden
the method, I certainly wouldn't go the path of the bloated using statement, and
would
probably rely on more appropriately specific try...finally blocks.

You won't find very many using blocks in Microsoft's own code. In fact, you
won't find
very many try...catch blocks around many protected resources. The idea being
that the
managed object eventually cleans up the resource if failure does occur. This is
extensively
done in the Windows Forms API. Still up in the air as to what a best practice
might be
when you want to leverage code brevity, performance, and robust/reliable
operation all
at the same time.

--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"Sami Vaaraniemi" <sa**********@pleasejippii.fi> wrote in message
news:ck**********@phys-news1.kolumbus.fi...
Instead of relying on garbage collection to (eventually) release the
resource, it would be better to make the wrapper class derive from
IDisposable and implement Dispose to release the resource. You would then
use the wrapper class like so:

using (CompatibleDC cdc = CompatibleDC.CreateCompatibleDC(initialDC))
{
// ...
}

Relying on garbage collection to release unmanaged resources is not a too
robust practice.

Regards,
Sami

"Justin Rogers" <Ju****@games4dotnet.com> wrote in message
news:Oh**************@TK2MSFTNGP14.phx.gbl...
You need some intricate knowledge of how the run-time works. Take for

instance
something like (pseudo)

IntPtr i1 = GetHdc();
DoSomethingWithDC(new HandleRef(null, i1), ...);
ReleaseDC(i1);

Okay, that code demonstrates the problem. DoSomethingWithDC can throw an
exception (OOM, SOE,
TAE, or any number of others)... If it does i1 is lost for good, and you

can't
release it. Now, if you do this
with a Graphics object, the IntPtr is actually stored INTERNALLY first...

The
Graphics object actually
has an internal member variable allowing it to wrap and then return the

hDC...
If an exception occurs,
then at some point the GC will kick in and run the finalizer for the

Graphics
and collect the resource by
calling ReleaseDC explicitly.

That is what I mean by wrapping the IntPtr in a managed object. For

instance,
the CreateCompatibleDC
in the tutorial allocates an hDC, but doesn't wrap it in a managed object.

If
the method fails later, there is
no storage of the IntPtr to be cleaned up, it just leaks. If you placed

this in
say a new class called HandleDC
then a finalizer could enforce the release of the resource.

public class CompatibleDC {
private IntPtr dc = IntPtr.Zero;
~CompatibleDC() { Release(); }

private CompatibleDC() {}

public static CompatibleDC CreateCompatibleDC(IntPtr initialDC) {
CompatibleDC cDC = new CompatibleDC(); // allocate memory here, if

OOM,
then no leakage.
cDC.dc = Win32.CreateCompatibleDC(initialDC); // Wrapped in an

object
instance now.
return cDC; // Give this to the client
}

// Not thread-safe
public IntPtr DC { get { return this.dc; } }
public void Release() {
if ( dc != IntPtr.Zero ) { Win32.ReleaseDC(dc); dc =

IntPtr.Zero; }
}
}

--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"_AV" <_a*@nospam.net> wrote in message
news:cs********************************@4ax.com...
> On Sun, 10 Oct 2004 15:22:29 -0700, "Justin Rogers"
> <Ju****@games4dotnet.com> wrote:
>
>>Make sure you either wrap your IntPtr's into a handle with GC protection if >>you plan on not doing error handling,
>
> Not sure I follow this, Justin. Is it possible to illustrate what you
> mean re wrapping IntPtrs?
>



Nov 16 '05 #9

"Justin Rogers" <Ju****@games4dotnet.com> wrote in message
news:eR**************@TK2MSFTNGP14.phx.gbl...
That was an example. Unfortunately, in the realm of GDI, you'd wind up with 5 or 6
using statements per behavior, and it can get ugly very fast. If you were to harden
the method, I certainly wouldn't go the path of the bloated using statement, and would
probably rely on more appropriately specific try...finally blocks.
Agreed, the code gets quickly ugly with nested using statements. I use
sometimes a custom resource manager object that can dispose other disposable
objects to replace many nested 'usings' with just one:

using (ResourceManager resMan = new ResourceManager())
{
CompatibleDC cdc1 =
(CompatibleDC)resMan.Add(CompatibleDC.CreateDC(ini tialDC));
CompatibleDC cdc2 =
(CompatibleDC)resMan.Add(CompatibleDC.CreateDC(ini tialDC));
// both cdc1 and cdc2 will be Disposed automatically
}

You won't find very many using blocks in Microsoft's own code. In fact, you won't find
very many try...catch blocks around many protected resources. The idea being that the
managed object eventually cleans up the resource if failure does occur. This is extensively
done in the Windows Forms API. Still up in the air as to what a best practice might be
when you want to leverage code brevity, performance, and robust/reliable
operation all
at the same time.


I wonder how well that approach works in practice. For example, if a game
leaves e.g., a device context or DirectX interfaces for the garbage
collector to release whenever there is an exception, then the application
could be fragile on a system with plenty of free memory because then the GC
feels no need to run often.

Regards,
Sami
Nov 16 '05 #10
In fact, there is a very clean way to avoid nesting using statements:

using (Pen p = new Pen())
using (Brush b = new Brush())
{
.....
}

So use them as much as possible! They are simply great.

Regards,
Frank Hileman

check out VG.net: www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor

"Sami Vaaraniemi" <sa**********@pleasejippii.fi> wrote in message
news:ck**********@phys-news1.kolumbus.fi...

"Justin Rogers" <Ju****@games4dotnet.com> wrote in message
news:eR**************@TK2MSFTNGP14.phx.gbl...
That was an example. Unfortunately, in the realm of GDI, you'd wind up with 5 or
6
using statements per behavior, and it can get ugly very fast. If you

were to
harden
the method, I certainly wouldn't go the path of the bloated using statement, and
would
probably rely on more appropriately specific try...finally blocks.


Agreed, the code gets quickly ugly with nested using statements. I use
sometimes a custom resource manager object that can dispose other

disposable objects to replace many nested 'usings' with just one:

Nov 16 '05 #11
I would say you've only beautified your code here. You haven't changed the
performance characteristics or the code bloat that results from a using
statement. You also assume that all resource allocations happen up-front,
which is definitely note true in good old GDI where you need to allocate an
object, use it for a few calls, allocate a second object, store so you can
restore
a third object, etc...

I wish using was the end all answer.
--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"Frank Hileman" <fr******@no.spamming.prodigesoftware.com> wrote in message
news:ee**************@TK2MSFTNGP10.phx.gbl...
In fact, there is a very clean way to avoid nesting using statements:

using (Pen p = new Pen())
using (Brush b = new Brush())
{
....
}

So use them as much as possible! They are simply great.

Regards,
Frank Hileman

check out VG.net: www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor

"Sami Vaaraniemi" <sa**********@pleasejippii.fi> wrote in message
news:ck**********@phys-news1.kolumbus.fi...

"Justin Rogers" <Ju****@games4dotnet.com> wrote in message
news:eR**************@TK2MSFTNGP14.phx.gbl...
> That was an example. Unfortunately, in the realm of GDI, you'd wind up

with 5 or
> 6
> using statements per behavior, and it can get ugly very fast. If you

were
to
> harden
> the method, I certainly wouldn't go the path of the bloated using

statement, and
> would
> probably rely on more appropriately specific try...finally blocks.


Agreed, the code gets quickly ugly with nested using statements. I use
sometimes a custom resource manager object that can dispose other

disposable
objects to replace many nested 'usings' with just one:


Nov 16 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: DraguVaso | last post by:
Hi, In the override of the Paint-method of a DataGridTextBoxColumn I want to show an image with BitBlt, to see what I can gain there on performance. The problem is: It doesn't show me the image...
5
by: JackS | last post by:
I am trying to use GDI32 bitblt to write a bitmap to a control's window, but all I get is an empty rectangle of some rop-dependent color. In short, I use the following logic in a paint event handler:...
1
by: _R | last post by:
I'm porting an old app from VC++6 to .NET and need to update the bitblt functions from DibSection to managed code. The older functions ran fine but I may as well opt for the fastest, most...
7
by: VB Programmer | last post by:
I am using the BitBlt operation to capture various controls into jpegs. It's almost like a screen capture, but of just the control. (This is a VB.NET application.) Because of BitBlt limitations...
7
by: kebalex | last post by:
Hi, I have an app (written in .NET 2.0) which updates a picturebox according to some user input (a slider control). when the user makes a change i loop through all of the pixels, do a...
6
by: Martijn Mulder | last post by:
/* BitBlt.cs C# code using P/Invoke I have good reasons to use P/Invoke to get access to the Win32 API function BitBlt(). But I have trouble understanding the workings of it. Below is a...
1
by: =?Utf-8?B?Y3JhbmtlX2JveQ==?= | last post by:
Hi Folks, I'm not sure where this post belongs since I'm using managed vc.net, but the issue is around GDI BitBlt. Here is a summary of the problem: - I am trying to copy a bitmap of my main...
0
by: crankeboy | last post by:
Hi Folks, My setup: Visual Studio Express 2008, VC++, .NET, BitBlt Here is a summary of the problem: - I am trying to copy a bitmap of my main form into a picture box. - To do this, I bitblt...
0
by: laviewpbt | last post by:
Fist ,Add a new class named "CImage",then copythe following codes and paste to it. Option Explicit Private Type BITMAPFILEHEADER bfType As Integer bfSize As Long ...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.