Skip to content
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

Optimize drawing bitmaps with alpha on WXMSW. #144

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/msw/dc.cpp
Expand Up @@ -2620,15 +2620,23 @@ static bool AlphaBlt(wxMSWDCImpl* dcDst,
// Notice the extra block: we must destroy wxAlphaPixelData
// before selecting the bitmap into the DC again.
{
// Since drawn bitmap can only partially overlap
// with destination bitmap we need to calculate
// efective drawing area location.
const wxRect rectDst(bmpOld.GetSize());
const wxRect rectDrawn(x, y, dstWidth, dstHeight);
const wxRect r = rectDrawn.Intersect(rectDst);

wxAlphaPixelData data(bmpOld);
if ( data )
{
wxAlphaPixelData::Iterator p(data);
for ( int old_y = 0; old_y < data.GetHeight(); old_y++ )

p.Offset(data, r.GetLeft(), r.GetTop());
for ( int old_y = 0; old_y < r.GetHeight(); old_y++ )
{
wxAlphaPixelData::Iterator rowStart = p;

for ( int old_x = 0; old_x < data.GetWidth(); old_x++ )
for ( int old_x = 0; old_x < r.GetWidth(); old_x++ )
{
// We choose to use wxALPHA_TRANSPARENT instead
// of perhaps more logical wxALPHA_OPAQUE here
Expand Down
59 changes: 51 additions & 8 deletions tests/benchmarks/graphics.cpp
Expand Up @@ -137,7 +137,9 @@ class GraphicsBenchmarkFrame : public wxFrame

Connect(wxEVT_SIZE, wxSizeEventHandler(GraphicsBenchmarkFrame::OnSize));

m_bitmap.Create(64, 64, 32);
m_bitmapARGB.Create(64, 64, 32);
m_bitmapARGB.UseAlpha(true);
m_bitmapRGB.Create(64, 64, 24);

Show();
}
Expand Down Expand Up @@ -228,10 +230,33 @@ class GraphicsBenchmarkFrame : public wxFrame

if ( opts.useMemory )
{
wxBitmap bmp(opts.width, opts.height);
wxMemoryDC dc(bmp);
wxGCDC gcdc(dc);
BenchmarkDCAndGC("memory", dc, gcdc);
{
wxBitmap bmp(opts.width, opts.height);
wxMemoryDC dc(bmp);
wxGCDC gcdc(dc);
BenchmarkDCAndGC("default memory", dc, gcdc);
}
{
wxBitmap bmp(opts.width, opts.height, 24);
wxMemoryDC dc(bmp);
wxGCDC gcdc(dc);
BenchmarkDCAndGC("RGB memory", dc, gcdc);
}
{
wxBitmap bmp(opts.width, opts.height, 32);
bmp.UseAlpha(false);
wxMemoryDC dc(bmp);
wxGCDC gcdc(dc);
BenchmarkDCAndGC("0RGB memory", dc, gcdc);
}
{
wxBitmap bmp(opts.width, opts.height, 32);
bmp.UseAlpha(true);
wxMemoryDC dc(bmp);
wxGCDC gcdc(dc);
BenchmarkDCAndGC("ARGB memory", dc, gcdc);
}

}

wxTheApp->ExitMainLoop();
Expand Down Expand Up @@ -337,13 +362,30 @@ class GraphicsBenchmarkFrame : public wxFrame
int x = rand() % opts.width,
y = rand() % opts.height;

dc.DrawBitmap(m_bitmap, x, y, true);
dc.DrawBitmap(m_bitmapARGB, x, y, true);
}

const long t = sw.Time();

wxPrintf("%ld bitmaps done in %ldms = %gus/bitmap\n",
wxPrintf("%ld ARGB bitmaps done in %ldms = %gus/bitmap\n",
opts.numIters, t, (1000. * t)/opts.numIters);

wxPrintf("Benchmarking %s: ", msg);
fflush(stdout);

sw.Start();
for ( int n = 0; n < opts.numIters; n++ )
{
int x = rand() % opts.width,
y = rand() % opts.height;

dc.DrawBitmap(m_bitmapRGB, x, y, true);
}
const long t2 = sw.Time();

wxPrintf("%ld RGB bitmaps done in %ldms = %gus/bitmap\n",
opts.numIters, t2, (1000. * t2)/opts.numIters);

}

void BenchmarkImages(const wxString& msg, wxDC& dc)
Expand Down Expand Up @@ -422,7 +464,8 @@ class GraphicsBenchmarkFrame : public wxFrame
}


wxBitmap m_bitmap;
wxBitmap m_bitmapARGB;
wxBitmap m_bitmapRGB;
#if wxUSE_GLCANVAS
wxGLCanvas* m_glCanvas;
wxGLContext* m_glContext;
Expand Down