เหตุใด skia บน windows จึงมีประสิทธิภาพไม่ดี

ฉันเปรียบเทียบสเกียกับการทาสี gdi บนหน้าต่าง ทั้งวาดเส้นสุ่ม 98,000 เส้น ฉันประหลาดใจที่ skia มีประสิทธิภาพต่ำกว่า gdi มาก (การทาสี skia มีราคา 1600ms ในขณะที่ gdi มีราคา 0ms) รหัสทดสอบของฉันถูกวางไว้ด้านล่าง ข้อเสนอแนะใด ๆ ?

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
}

person qianyi    schedule 04.08.2016    source แหล่งที่มา
comment
โปรดโพสต์ตัวอย่างขั้นต่ำ สมบูรณ์ และตรวจสอบได้   -  person Jonathan Mee    schedule 04.08.2016
comment
ขออภัย ฉันไม่รู้วิธีโพสต์โค้ดเพิ่มเติมที่นี่ รหัสที่ฉันวางด้านบนคือแกนหลัก อย่างที่คุณเห็นฉันคำนวณเวลาที่ใช้ในการวาดด้วย skia และ gdi ต้นทุนและต้นทุนนั้น 2 เป็นตัวแปรที่ประกอบด้วยเวลาที่ใช้ไป   -  person qianyi    schedule 05.08.2016


คำตอบ (1)


ในที่สุดฉันก็พบปัญหา ฉันให้ผลลัพธ์ในโหมดแก้ไขข้อบกพร่อง!

ในโหมดแก้ไขข้อบกพร่องที่ skia ที่มีแบ็กเอนด์แรสเตอร์ช้ากว่า gdi 20 เท่า อย่างไรก็ตามในโหมด release skia ที่มีแบ็กเอนด์แรสเตอร์จะช้ากว่า gdi 4-5 เท่า

ฉันมีการทดสอบอีกครั้งว่า skia ใช้ opengl เป็นแบ็กเอนด์ ผลลัพธ์แสดงว่า skia และ gdi ใช้เวลาเกือบเท่ากัน skia ช้ากว่า gdi ประมาณ 15%

person qianyi    schedule 05.08.2016