Skip to content

Instantly share code, notes, and snippets.

@beru
Last active January 22, 2019 16:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beru/b8e585d92d91f73dc64f74584116ffeb to your computer and use it in GitHub Desktop.
Save beru/b8e585d92d91f73dc64f74584116ffeb to your computer and use it in GitHub Desktop.
#include <Windows.h>
#include <stdio.h>
#include <algorithm>
struct CStopWatch final
{
const char* title;
const char* type;
LARGE_INTEGER frequency;
LARGE_INTEGER startTime;
CStopWatch( const char* pszTitle, const char* pszType )
: title( pszTitle ), type( pszType )
{
::QueryPerformanceFrequency( &frequency );
::QueryPerformanceCounter( &startTime );
}
~CStopWatch( void )
{
LARGE_INTEGER endTime;
::QueryPerformanceCounter( &endTime );
double elapsedSec = 1000 * (endTime.QuadPart - startTime.QuadPart) / (double)frequency.QuadPart;
char buf[128];
::sprintf_s( buf, "%.3f msec, %s, %s\n", elapsedSec, title, type );
::OutputDebugStringA( buf );
}
};
constexpr size_t MAX_COUNT = 60;
void case_FillRect(HDC hDC, const RECT& rc, const char* pszType)
{
CStopWatch sw( __FUNCTION__, pszType );
for ( size_t n = 0; n < MAX_COUNT; n++ ) {
COLORREF color = RGB(n, n, n);
HBRUSH brush = ::CreateSolidBrush( color );
::FillRect( hDC, &rc, brush );
::DeleteObject( brush );
}
}
void case_ExtTextOut(HDC hDC, const RECT& rc, const char* pszType)
{
CStopWatch sw( __FUNCTION__, pszType );
for ( size_t n = 0; n < MAX_COUNT; n++ ) {
COLORREF color = RGB(n, n, n);
COLORREF bkColorOld = ::SetBkColor( hDC, color );
::ExtTextOutW( hDC, rc.left, rc.top, ETO_OPAQUE, &rc, L"", 0, NULL );
::SetBkColor( hDC, bkColorOld );
}
}
void case_PatBlt(HDC hDC, const RECT& rc, const char* pszType)
{
CStopWatch sw( __FUNCTION__, pszType );
for ( size_t n = 0; n < MAX_COUNT; n++ ) {
COLORREF color = RGB(n, n, n);
HBRUSH brush = ::CreateSolidBrush( color );
HGDIOBJ brushOld = ::SelectObject( hDC, brush );
::PatBlt( hDC, rc.left, rc.top, rc.right, rc.bottom, PATCOPY );
::SelectObject( hDC, brushOld );
::DeleteObject( brush );
}
}
static void FillRect_DIB(DWORD* pDIBPixels, RECT rc, int cx, int cy, COLORREF color)
{
LONG width = rc.right - rc.left;
LONG height = rc.bottom - rc.top;
if (rc.top < 0)
{
height += rc.top;
rc.top = 0;
}
if (rc.left < 0)
{
width += rc.left;
rc.left = 0;
}
if (rc.top >= cy || rc.left >= cx || height < 1 || width < 1)
{
return;
}
if (rc.left + width > cx)
{
width = cx - rc.left;
}
if (rc.top + height > cy)
{
height = cy - rc.top;
}
BYTE r = GetRValue(color);
BYTE g = GetGValue(color);
BYTE b = GetBValue(color);
DWORD dwColor = (r << 16) | (g << 8) | b;
pDIBPixels += cx * rc.top + rc.left;
if (width == cx)
{
std::fill_n(pDIBPixels, cx * height, dwColor);
}
else
{
for (LONG i = 0; i < height; ++i)
{
std::fill_n(pDIBPixels, width, dwColor);
pDIBPixels += cx;
}
}
}
void case_std_fill(DWORD* pDIBPixels, const RECT& rc, int cx, int cy)
{
CStopWatch sw( __FUNCTION__, "DIB" );
for ( size_t n = 0; n < MAX_COUNT; n++ ) {
COLORREF color = RGB(n, n, n);
::FillRect_DIB( pDIBPixels, rc, cx, cy, color );
}
}
//! Main関数
int WINAPI wWinMain(
HINSTANCE hInstance, //!< handle to current instance
HINSTANCE hPrevInstance, //!< handle to previous instance
LPWSTR lpCmdLine, //!< pointer to command line
int nCmdShow //!< show state of window
)
{
::SetProcessDPIAware();
HWND hDesktopWnd = ::GetDesktopWindow();
RECT rc;
::GetWindowRect( hDesktopWnd, &rc );
int cx = rc.right - rc.left;
int cy = rc.bottom - rc.top;
HDC hDesktopDC = ::GetDC( hDesktopWnd );
HDC hCompatibleDC_DDB = ::CreateCompatibleDC( NULL );
HDC hCompatibleDC_DIB = ::CreateCompatibleDC( NULL );
HBITMAP hDDB = ::CreateBitmap( cx, cy, 3, 32, NULL );
::SelectObject( hCompatibleDC_DDB, hDDB );
BITMAPINFO bmi = {0};
BITMAPINFOHEADER& bmih = bmi.bmiHeader;
bmih.biSize = sizeof(bmih);
bmih.biBitCount = 32;
bmih.biWidth = cx;
bmih.biHeight = -cy;
bmih.biPlanes = 1;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biXPelsPerMeter = 0;
bmih.biYPelsPerMeter = 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
void* pvBits = nullptr;
HBITMAP hDIB = CreateDIBSection(
NULL,
&bmi,
DIB_RGB_COLORS,
&pvBits,
NULL,
0
);
::SelectObject( hCompatibleDC_DIB, hDIB );
for (int i = 0; i < 8; ++i)
{
char buff[64];
sprintf_s(buff, "x, y, w, h : %d, %d, %d, %d\n", rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top);
::OutputDebugStringA(buff);
case_FillRect( hCompatibleDC_DDB, rc, "DDB" );
case_ExtTextOut( hCompatibleDC_DDB, rc, "DDB" );
case_PatBlt( hCompatibleDC_DDB, rc, "DDB" );
case_FillRect( hCompatibleDC_DIB, rc, "DIB" );
case_ExtTextOut( hCompatibleDC_DIB, rc, "DIB" );
case_PatBlt( hCompatibleDC_DIB, rc, "DIB" );
case_std_fill( (DWORD*)pvBits, rc, cx, cy );
rc.right >>= 1;
rc.bottom >>= 1;
}
::DeleteObject( hDDB );
::DeleteObject( hDIB );
::DeleteDC( hCompatibleDC_DDB );
::DeleteDC( hCompatibleDC_DIB );
::ReleaseDC( hDesktopWnd, hDesktopDC );
return 0;
}
@beru
Copy link
Author

beru commented Jan 20, 2019

実行環境

OS : Windows 10 バージョン 1803
CPU : Core i5-4670
GPU : NVIDIA GeForce GTX 1070

実行結果

x, y, w, h : 0, 0, 3840, 2160
0.229 msec, case_FillRect, DDB
0.037 msec, case_ExtTextOut, DDB
0.101 msec, case_PatBlt, DDB
246.221 msec, case_FillRect, DIB
229.643 msec, case_ExtTextOut, DIB
226.226 msec, case_PatBlt, DIB
97.882 msec, case_std_fill, DIB
x, y, w, h : 0, 0, 1920, 1080
0.416 msec, case_FillRect, DDB
0.022 msec, case_ExtTextOut, DDB
0.125 msec, case_PatBlt, DDB
57.648 msec, case_FillRect, DIB
56.706 msec, case_ExtTextOut, DIB
66.966 msec, case_PatBlt, DIB
19.206 msec, case_std_fill, DIB
x, y, w, h : 0, 0, 960, 540
0.301 msec, case_FillRect, DDB
0.023 msec, case_ExtTextOut, DDB
0.188 msec, case_PatBlt, DDB
8.992 msec, case_FillRect, DIB
8.079 msec, case_ExtTextOut, DIB
8.232 msec, case_PatBlt, DIB
4.418 msec, case_std_fill, DIB
x, y, w, h : 0, 0, 480, 270
0.773 msec, case_FillRect, DDB
0.023 msec, case_ExtTextOut, DDB
0.185 msec, case_PatBlt, DDB
2.385 msec, case_FillRect, DIB
2.401 msec, case_ExtTextOut, DIB
2.793 msec, case_PatBlt, DIB
1.148 msec, case_std_fill, DIB
x, y, w, h : 0, 0, 240, 135
0.537 msec, case_FillRect, DDB
0.023 msec, case_ExtTextOut, DDB
0.133 msec, case_PatBlt, DDB
0.918 msec, case_FillRect, DIB
0.982 msec, case_ExtTextOut, DIB
0.822 msec, case_PatBlt, DIB
0.337 msec, case_std_fill, DIB
x, y, w, h : 0, 0, 120, 67
0.492 msec, case_FillRect, DDB
0.030 msec, case_ExtTextOut, DDB
0.384 msec, case_PatBlt, DDB
0.464 msec, case_FillRect, DIB
0.308 msec, case_ExtTextOut, DIB
0.392 msec, case_PatBlt, DIB
0.109 msec, case_std_fill, DIB
x, y, w, h : 0, 0, 60, 33
0.290 msec, case_FillRect, DDB
0.030 msec, case_ExtTextOut, DDB
0.236 msec, case_PatBlt, DDB
0.320 msec, case_FillRect, DIB
0.146 msec, case_ExtTextOut, DIB
0.304 msec, case_PatBlt, DIB
0.039 msec, case_std_fill, DIB
x, y, w, h : 0, 0, 30, 16
0.283 msec, case_FillRect, DDB
0.037 msec, case_ExtTextOut, DDB
0.165 msec, case_PatBlt, DDB
0.441 msec, case_FillRect, DIB
0.189 msec, case_ExtTextOut, DIB
0.289 msec, case_PatBlt, DIB
0.011 msec, case_std_fill, DIB

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment