2011-09-21 14 views
8

từ những gì tôi đã đọc here có vẻ như hầu hết các chức năng GDI của Windows đều được tăng tốc. Vì vậy, ví dụ: gọi tới BitBlt hoặc AlphaBlend sử dụng tăng tốc phần cứng nếu có. Nó cũng đề cập rằng nội dung của một cửa sổ được giữ chỉ trong bộ nhớ video. Bây giờ điều này là tốt và đúng cho một cửa sổ DC, nhưng làm cách nào tôi có thể sử dụng bộ nhớ DC nằm trong bộ nhớ thẻ video? Và một khi chúng tôi đã hoàn thành cách truy cập trực tiếp vào các điểm ảnh, tôi nghĩ điều đó sẽ liên quan đến 1. tạm thời sao chép dữ liệu vào bộ nhớ hệ thống 2. thay đổi dữ liệu pixel 3. sao chép lại vào bộ nhớ video.CreateCompatibleBitmap và CreateDIBSection (Bộ nhớ DC)

Tôi đã thử hai cách tiếp cận, cả hai cấp phát bộ nhớ hệ thống như tôi có thể nhìn thấy trong công việc quản lý ...

  1. CreateCompatibleBitmap

    HDC hDC = GetDC(NULL); 
    m_hDC = CreateCompatibleDC(hDC); 
    m_hBmp = CreateCompatibleBitmap(hDC, cx, cy); 
    ReleaseDC(NULL, hDC); 
    
    m_hOldBmp = (HBITMAP)SelectObject(m_hDC, m_hBmp); 
    

    và sau đó gọi để có được các bit

    GetBitmapBits(...) 
    

    theo các nhận xét khác nhau, điều này thực sự sẽ tạo bitmap tương thích trong bộ ghi video y, nhưng tại sao tôi vẫn có thể thấy sự gia tăng bộ nhớ hệ thống (ngay cả khi tôi không gọi GetBitmapBits)?

  2. CreateDIBSection

    HDC hDC = GetDC(NULL); 
    m_hDC = CreateCompatibleDC(hDC); 
    
    BITMAPINFO bmi; 
    memset(&bmi, 0, sizeof(BITMAPINFO)); 
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    bmi.bmiHeader.biWidth = cx; 
    bmi.bmiHeader.biHeight = -cy; // top-down 
    bmi.bmiHeader.biPlanes = 1; 
    bmi.bmiHeader.biBitCount = 32; 
    bmi.bmiHeader.biCompression = BI_RGB; 
    m_hBmp = CreateDIBSection(hDC, &bmi, DIB_RGB_COLORS, (void**)&m_pBits, NULL, NULL); 
    
    ReleaseDC(NULL, hDC); 
    
    m_hOldBmp = (HBITMAP)SelectObject(m_hDC, m_hBmp); 
    

    trong trường hợp này chúng tôi nhận được con trỏ đến các bit ngay lập tức (m_pBits) do đó, nó rõ ràng rằng những cư trú trong bộ nhớ hệ thống ...

Hoặc là nó một sao chép được lưu giữ trong bộ nhớ hệ thống cho cả hai phương pháp? Nhưng nếu tôi thay đổi các bit trong bộ nhớ hệ thống, một cuộc gọi đến BitBlt sẽ vẫn phải kiểm tra/sao chép từ bộ nhớ hệ thống một lần nữa ... không được tối ưu hóa rất nhiều IMHO.

EDIT: Tôi cũng đã thử tạo bộ nhớ DC bằng cách sử dụng BeginBufferedPaintGetBufferedPaintBits. Nó phân bổ bộ nhớ hệ thống là tốt, vì vậy trong khía cạnh đó tôi cho rằng nó chỉ là một wrapper cho các phương pháp trên nhưng lưu trữ của DC để một cuộc gọi tiếp theo không nhất thiết phải tái tạo một bộ nhớ DC. Xem article của Raymond Chen.

EDIT # 2: Tôi đoán câu hỏi thực tế là: Tôi có đang tạo bộ nhớ DC đúng trong phương pháp 1 hoặc 2 để có các hoạt động GDI tăng tốc phần cứng không? Với tôi tất cả đều có vẻ nhanh, và cả hai phương pháp đều cung cấp cùng một tốc độ, do đó, không thực sự là một cách để kiểm tra ...

+0

Tôi nghĩ rằng nó luôn nằm trong bộ nhớ hệ thống và chỉ được đổi thành bộ nhớ video khi được hiển thị ... – AJG85

+0

Điều đó có nghĩa là chúng tôi không thể tạo bộ nhớ trong bộ nhớ video và chức năng GDI không tăng tốc phần cứng khi làm việc một bộ nhớ DC? – demorge

+2

Các chức năng GDI chỉ dành cho các thao tác * blitting * là phần cứng được tăng tốc trên Windows 7 độc quyền. GDI + vẫn là phần mềm được hiển thị ngay cả trên Windows 7 và vẫn còn chậm hơn. Nếu bạn đang làm bất cứ điều gì phức tạp mà yêu cầu thực hiện câu trả lời đơn giản là không sử dụng GDI. Sử dụng OpenGL hoặc DirectX nếu bạn muốn truy cập trực tiếp vào phần cứng. GDI luôn là một trừu tượng. – AJG85

Trả lời

3

Bộ nhớ DC không được tạo trên thiết bị. Chúng được thiết kế để đưa đầu ra GDI vào bộ nhớ.

Từ Memory Device Contexts trên MSDN:

Để kích hoạt các ứng dụng để đặt ra trong bộ nhớ thay vì gửi nó vào một thiết bị thực tế, sử dụng một bối cảnh thiết bị đặc biệt cho bitmap hoạt động được gọi là một thiết bị bộ nhớ bối cảnh. Bộ nhớ DC cho phép hệ thống xử lý một phần bộ nhớ dưới dạng thiết bị ảo.

Nếu bạn muốn đồ họa tăng tốc phần cứng 2d, bạn nên cân nhắc sử dụng Direct2D.

+0

Aah làm rõ mọi thứ, và nó cũng nói: * Khi hiển thị DIB hoặc DDB được tạo từ DIB trên thiết bị bảng màu, bạn có thể cải thiện tốc độ hình ảnh được vẽ bằng cách sắp xếp bảng hợp lý Bố cục của bảng hệ thống. * Làm rõ rằng 'CreateCompatibleBitmap' phải là phương pháp nhanh nhất, nhưng vì hệ thống của tôi chạy trong màu 32 bit,' CreateDIBSection' sử dụng bố cục 32 bit cũng nhanh như vậy cùng một định dạng bitmap được tạo bởi cả hai hàm). – demorge

+0

Từ kinh nghiệm của tôi với hiệu suất của Direct2D và GDI, tôi không khuyên bạn sử dụng Direct2D. Nó chậm, về cùng tốc độ với GDI. – Trinidad

Các vấn đề liên quan