From 89ea7060550efa52c20f2f66f87bcbf5cc3cabd3 Mon Sep 17 00:00:00 2001 From: spx Date: Thu, 6 Jan 2011 01:44:09 +0000 Subject: [PATCH] Improved the drawing performance by using PixelFormat32bppPARGB instead of PixelFormat32bppARGB. (PARGB is faster than ARGB.) --- Library/MeterButton.cpp | 6 +-- Library/MeterWindow.cpp | 111 +++++++++++++++++++++++----------------- Library/TintedImage.cpp | 12 ++--- 3 files changed, 72 insertions(+), 57 deletions(-) diff --git a/Library/MeterButton.cpp b/Library/MeterButton.cpp index 67789b37..92c5c86f 100644 --- a/Library/MeterButton.cpp +++ b/Library/MeterButton.cpp @@ -113,7 +113,7 @@ void CMeterButton::Initialize() for (int i = 0; i < BUTTON_FRAMES; ++i) { - Bitmap bitmapPart(m_W, m_H, PixelFormat32bppARGB); + Bitmap bitmapPart(m_W, m_H, PixelFormat32bppPARGB); Graphics graphics(&bitmapPart); Rect r(0, 0, m_W, m_H); @@ -250,7 +250,7 @@ bool CMeterButton::HitTest2(int px, int py, bool checkAlpha) { if (checkAlpha) { - if (m_SolidColor.GetA() > 0 || m_SolidColor2.GetA() > 0) + if (m_SolidColor.GetA() != 0 || m_SolidColor2.GetA() != 0) { return true; } @@ -260,7 +260,7 @@ bool CMeterButton::HitTest2(int px, int py, bool checkAlpha) { Color color; Status status = m_Image.GetImage()->GetPixel(px - x + m_W * m_State, py - y, &color); - if (status != Ok || color.GetA() > 0) + if (status != Ok || color.GetA() != 0) { return true; } diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index ba9e01ea..6956d57c 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -245,7 +245,7 @@ int CMeterWindow::Initialize(CRainmeter& Rainmeter) IgnoreAeroPeek(); // Gotta have some kind of buffer during initialization - m_DoubleBuffer = new Bitmap(1, 1, PixelFormat32bppARGB); + m_DoubleBuffer = new Bitmap(1, 1, PixelFormat32bppPARGB); Refresh(true, true); if (!m_WindowStartHidden) @@ -2233,7 +2233,12 @@ bool CMeterWindow::ResizeWindow(bool reset) if (m_BackgroundMode == BGMODE_IMAGE) { - m_Background = tempBackground->Clone(0, 0, m_BackgroundSize.cx, m_BackgroundSize.cy, PixelFormat32bppARGB); + PixelFormat format = tempBackground->GetPixelFormat(); + if (format == PixelFormat32bppARGB) + { + format = PixelFormat32bppPARGB; + } + m_Background = tempBackground->Clone(0, 0, m_BackgroundSize.cx, m_BackgroundSize.cy, format); } else { @@ -2241,7 +2246,7 @@ bool CMeterWindow::ResizeWindow(bool reset) h = max(h, m_BackgroundSize.cy); // Scale the background to fill the whole window - Bitmap* background = new Bitmap(w, h, PixelFormat32bppARGB); + Bitmap* background = new Bitmap(w, h, PixelFormat32bppPARGB); Graphics graphics(background); @@ -2423,30 +2428,45 @@ void CMeterWindow::Redraw() CreateRegion(true); } - if (m_DoubleBuffer) delete m_DoubleBuffer; - if (m_WindowW == 0 || m_WindowH == 0) + // Create or clear the doublebuffer { - // Create a dummy bitmap to avoid invalid state - m_DoubleBuffer = new Bitmap(1, 1, PixelFormat32bppARGB); - } - else - { - m_DoubleBuffer = new Bitmap(m_WindowW, m_WindowH, PixelFormat32bppARGB); - } + int cx = m_WindowW; + int cy = m_WindowH; - Graphics graphics(GetDoubleBuffer()); - - if (m_Background) - { - // Copy the background over the doublebuffer - Rect r(0, 0, m_WindowW, m_WindowH); - graphics.DrawImage(m_Background, r, 0, 0, m_Background->GetWidth(), m_Background->GetHeight(), UnitPixel); - } - else if (m_BackgroundMode == BGMODE_SOLID) - { - // Draw the solid color background - if (m_WindowW != 0 && m_WindowH != 0) + if (cx == 0 || cy == 0) { + // Set dummy size to avoid invalid state + cx = 1; + cy = 1; + } + + BitmapData buf; + if (cx != m_DoubleBuffer->GetWidth() || cy != m_DoubleBuffer->GetHeight() || + Ok != m_DoubleBuffer->LockBits(&Rect(0, 0, cx, cy), ImageLockModeWrite, PixelFormat32bppPARGB, &buf)) + { + if (m_DoubleBuffer) delete m_DoubleBuffer; + m_DoubleBuffer = new Bitmap(cx, cy, PixelFormat32bppPARGB); + } + else + { + memset(buf.Scan0, 0, buf.Stride * cy); // assume that the bitmap is top-down + m_DoubleBuffer->UnlockBits(&buf); + } + } + + if (m_WindowW != 0 && m_WindowH != 0) + { + Graphics graphics(m_DoubleBuffer); + + if (m_Background) + { + // Copy the background over the doublebuffer + Rect r(0, 0, m_WindowW, m_WindowH); + graphics.DrawImage(m_Background, r, 0, 0, m_Background->GetWidth(), m_Background->GetHeight(), UnitPixel); + } + else if (m_BackgroundMode == BGMODE_SOLID) + { + // Draw the solid color background Rect r(0, 0, m_WindowW, m_WindowH); if (m_SolidColor.GetA() != 0 || m_SolidColor2.GetA() != 0) @@ -2479,28 +2499,28 @@ void CMeterWindow::Redraw() CMeter::DrawBevel(graphics, r, light, dark); } } - } - // Draw the meters - std::list::const_iterator j = m_Meters.begin(); - for( ; j != m_Meters.end(); ++j) - { - if (!(*j)->GetTransformationMatrix().IsIdentity()) + // Draw the meters + std::list::const_iterator j = m_Meters.begin(); + for( ; j != m_Meters.end(); ++j) { - // Change the world matrix - graphics.SetTransform(&((*j)->GetTransformationMatrix())); + if (!(*j)->GetTransformationMatrix().IsIdentity()) + { + // Change the world matrix + graphics.SetTransform(&((*j)->GetTransformationMatrix())); - (*j)->Draw(graphics); + (*j)->Draw(graphics); - // Set back to identity matrix - graphics.ResetTransform(); - } - else - { - (*j)->Draw(graphics); + // Set back to identity matrix + graphics.ResetTransform(); + } + else + { + (*j)->Draw(graphics); + } } } - + if (m_ResetRegion) CreateRegion(false); m_ResetRegion = false; @@ -2726,19 +2746,14 @@ void CMeterWindow::UpdateTransparency(int alpha, bool reset) BLENDFUNCTION blendPixelFunction= {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA}; POINT ptWindowScreenPosition = {m_ScreenX, m_ScreenY}; POINT ptSrc = {0, 0}; - SIZE szWindow; + SIZE szWindow = {m_WindowW, m_WindowH}; - if (m_WindowW == 0 || m_WindowH == 0) + if (szWindow.cx == 0 || szWindow.cy == 0) { // Set dummy size to avoid invalid state szWindow.cx = 1; szWindow.cy = 1; } - else - { - szWindow.cx = m_WindowW; - szWindow.cy = m_WindowH; - } HDC dcScreen = GetDC(0); HDC dcMemory = CreateCompatibleDC(dcScreen); @@ -3095,7 +3110,7 @@ bool CMeterWindow::HitTest(int x, int y) { Color color; Status status = m_DoubleBuffer->GetPixel(x, y, &color); - if (status != Ok || color.GetA() > 0) + if (status != Ok || color.GetA() != 0) { return true; } diff --git a/Library/TintedImage.cpp b/Library/TintedImage.cpp index 460c1b77..b4788b0f 100644 --- a/Library/TintedImage.cpp +++ b/Library/TintedImage.cpp @@ -267,7 +267,7 @@ void CTintedImage::ApplyCrop() { if (m_Crop.Width == 0 || m_Crop.Height == 0) { - m_BitmapTint = new Bitmap(0, 0, PixelFormat32bppARGB); // create dummy bitmap + m_BitmapTint = new Bitmap(0, 0, PixelFormat32bppPARGB); // create dummy bitmap } else { @@ -306,7 +306,7 @@ void CTintedImage::ApplyCrop() } Rect r(0, 0, m_Crop.Width, m_Crop.Height); - m_BitmapTint = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB); + m_BitmapTint = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB); Graphics graphics(m_BitmapTint); graphics.DrawImage(m_Bitmap, r, x, y, r.Width, r.Height, UnitPixel); @@ -331,7 +331,7 @@ void CTintedImage::ApplyTint() Rect r(0, 0, original->GetWidth(), original->GetHeight()); - Bitmap* tint = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB); + Bitmap* tint = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB); Graphics graphics(tint); @@ -365,7 +365,7 @@ Bitmap* CTintedImage::TurnGreyscale(Bitmap* source) // We need a blank bitmap to paint our greyscale to in case of alpha Rect r(0, 0, source->GetWidth(), source->GetHeight()); - Bitmap* bitmap = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB); + Bitmap* bitmap = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB); Graphics graphics(bitmap); graphics.DrawImage(source, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr); @@ -393,7 +393,7 @@ void CTintedImage::ApplyTransform() REAL transformW = fabs(originalW * cos_f) + fabs(originalH * sin_f); REAL transformH = fabs(originalW * sin_f) + fabs(originalH * cos_f); - Bitmap* transform = new Bitmap((int)(transformW + 0.5f), (int)(transformH + 0.5f), PixelFormat32bppARGB); + Bitmap* transform = new Bitmap((int)(transformW + 0.5f), (int)(transformH + 0.5f), PixelFormat32bppPARGB); Graphics graphics(transform); graphics.SetPixelOffsetMode(PixelOffsetModeHighQuality); @@ -427,7 +427,7 @@ void CTintedImage::ApplyTransform() Bitmap* original = GetImage(); Rect r(0, 0, original->GetWidth(), original->GetHeight()); - Bitmap* transform = new Bitmap(r.Width, r.Height, PixelFormat32bppARGB); + Bitmap* transform = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB); Graphics graphics(transform);