2016-08-04 36 views
1

Ich habe Skia mit GDI-Malerei auf Windows verglichen. beide zeichnen 98000 zufällige Linien. zu meiner überraschung, dass skia weit weniger effizienz als gdi (das skia malerei kostet 1600ms, während gdi kosten 0ms). Mein Testcode wurde unten eingefügt. irgendwelche Vorschläge?Warum Skia auf Windows hat schlechte Effizienz

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 
} 
+0

Bitte veröffentlichen Sie ein [minimales, vollständiges, überprüfbares Beispiel] (http://stackoverflow.com/help/mcve). –

+1

Entschuldigung, ich weiß nicht, wie man hier mehr Code posten kann. Der Code, den ich oben eingefügt habe, ist der Kern. Wie du sehen kannst, berechne ich die Zeit, die ich für das Zeichnen mit Skia und Gdi aufgewendet habe. Diese Kosten und Kosten2 sind Variablen, die die verbrachte Zeit enthalten. – qianyi

Antwort

2

Ich habe das Problem endlich gefunden. Ich gebe das Ergebnis im Debug-Modus!

im Debug-Modus, die skia mit Raster-Backend ist 20 mal langsamer als gdi. aber im Freigabemodus ist skia mit Raster-Backend 4-5 mal langsamer als gdi.

Ich hatte einen anderen Test, dass skia OpenGL als Backend verwendet. das ergebnis zeigt skia und gdi fast zeitgleich. skia ist etwa 15% langsamer als gdi.