为啥窗户上的skia效率低下
Posted
技术标签:
【中文标题】为啥窗户上的skia效率低下【英文标题】:why skia on windows has bad efficiency为什么窗户上的skia效率低下 【发布时间】:2016-08-04 11:59:14 【问题描述】:我将skia与Windows上的gdi绘画进行了比较。都画了98000条随机线。令我惊讶的是,skia 的效率远低于 gdi(skia 绘画花费 1600 毫秒,而 gdi 花费 0 毫秒)。我的测试代码粘贴在下面。有什么建议吗?
bool PaintCompare()
//generate ramdon points
std::default_random_engine e(std::chrono::high_resolution_clock::now().time_since_epoch().count());
std::uniform_real_distribution<float> u(10, 500);
SkPoint pts[100];
for (int i = 0; i<100; i++)
pts[i].set(u(e), u(e));
SkPaint paint;
paint.setColor(SkColorSetRGB(255, 0, 0));
//create skia canvas
sk_sp<SkSurface> rasterSurface(
SkSurface::MakeRasterN32Premul(600, 600));
SkCanvas* canvas = rasterSurface->getCanvas();
//draw lines with skia
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i<1000; i++)
for (int j = 1; j<99; j++)
canvas->drawLine(pts[j].fX, pts[j].fY, pts[j + 1].fX, pts[j + 1].fY, paint);
auto cost = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - start);
sk_sp<SkImage> img(rasterSurface->makeImageSnapshot());
if (!img) return false;
SkBitmap skBmp;
if (!img->asLegacyBitmap(&skBmp, SkImage::kRO_LegacyBitmapMode))
return false;
//show bitmap on hdc
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = 600;
bmi.bmiHeader.biHeight = -600; // top-down image
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
HDC hdc = GetDC();
LPVOID pBits = NULL;
HBITMAP hBmp = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pBits, 0, 0);
skBmp.copyPixelsTo(pBits, skBmp.getSize());
CDC memdc;
memdc.CreateCompatibleDC(hdc);
memdc.SelectBitmap(hBmp);
BitBlt(hdc, 0, 0, 600, 600, memdc, 0, 0, SRCCOPY);
memdc.DeleteDC();
//draw with gdi
CPen pen;
pen.CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
RECT rc 0,0,600,600 ;
CBitmap bmp;
bmp.CreateCompatibleBitmap(hdc, 600, 600);
memdc.CreateCompatibleDC(hdc);
memdc.SelectBitmap(bmp);
memdc.FillSolidRect(&rc, RGB(0, 0, 0));
memdc.SelectPen(pen);
start = std::chrono::high_resolution_clock::now();
for (int i = 0; i<1000; i++)
for (int j = 1; j<99; j++)
memdc.MoveTo(pts[j].fX, pts[j].fY);
memdc.LineTo(pts[j + 1].fX, pts[j + 1].fY);
auto cost2 = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - start);
//copy bitmap to window
BitBlt(hdc, 700, 0, 600, 600, memdc, 0, 0, SRCCOPY);
ReleaseDC(hdc);
memdc.DeleteDC();
//wchar_t buf[256];
//wsprintf(buf, L"left cost=%I64d, right cost=%I64d", cost.count(), cost2.count());
//GetParent().SetWindowText(buf);
//cost == 1596615 microseconds
//cost2 == 107253 microseconds
【问题讨论】:
请发Minimal, Complete, Verifiable Example。 对不起,我不知道如何在这里发布更多代码。我上面粘贴的代码是核心。如您所见,我计算了使用skia 和gdi 进行绘图所花费的时间。 cost 和 cost2 是包含所花费时间的变量。 【参考方案1】:我终于找到了问题。我在调试模式下给出结果!
在调试模式下,带有光栅后端的skia 比gdi 慢20 倍。 但是在发布模式下,带有光栅后端的skia比gdi慢4-5倍。
我有另一个测试,skia 使用 opengl 作为后端。结果显示skia和gdi花费几乎相同的时间。 skia 比 gdi 慢 15%。
【讨论】:
以上是关于为啥窗户上的skia效率低下的主要内容,如果未能解决你的问题,请参考以下文章