wxDataViewCtrl with huge data fails updating on wxMSW

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
KodamaDeveloped
In need of some credit
In need of some credit
Posts: 2
Joined: Thu Nov 25, 2021 11:22 pm

wxDataViewCtrl with huge data fails updating on wxMSW

Post by KodamaDeveloped »

wxWidgets 3.1.4, wxMSW, 32/64 bits.

If wxDataViewCtrl has a huge number of data, the control cannot be updated if displayed rows are beyond a specific limit. Compile the followings by supplying appropriate lib files. If the topmost row is less than 6100806 everything is OK. Otherwise updating the control stops, that you can easily confirm by enlarging the window. I googled to find probably the same issue repored (https://groups.google.com/g/wx-users/c/XEjLpl1wTRc), which doesn't show the solution however.

Code: Select all

#include <wx/wx.h>
#include <wx/dataview.h>
class MyModel:public wxDataViewVirtualListModel
{
public:
    unsigned int GetColumnCount() const override {return 1;}
    wxString GetColumnType(unsigned int col) const override {return "string";}
    void GetValueByRow
        (wxVariant& variant,unsigned int row,unsigned int col) const override
        {variant=wxString::Format("%d",row);}
    bool SetValueByRow
        (const wxVariant& variant,unsigned int row,unsigned int col) override
        {return false;}
};
class MyFrame:public wxFrame
{
public:
    MyFrame(wxWindow* parent,wxWindowID id):wxFrame{parent,id,"DataViewCtrlTest"}
    {
        auto* ctrl=new wxDataViewCtrl{this,wxID_ANY};
        auto* model=new MyModel{};
        ctrl->AppendTextColumn("Row",0);
        ctrl->AssociateModel(model);
        model->DecRef();
        model->Reset(97612892);
        ctrl->EnsureVisible(model->GetItem(6100806));
    }
};
class MyApp:public wxApp
{
public:
    bool OnInit() override
    {
        auto* frame=new MyFrame{nullptr,wxID_ANY};
        frame->Show();
        SetTopWindow(frame);
        return true;
    }
};
wxIMPLEMENT_APP(MyApp);
The issue is located in wxDataViewMainWindow::OnPaint (src/generic/datavgen.cpp:2459). There wxScrollHelper::PrepareDC() is called to execute all drawing operations on a device context (DC) by unscrolled coordinates. In wxMSW the DC is wxBufferedPaintDC of which internal buffer is wxBufferedDC that uses a memory device context created by ::CreateCompatibleDC() winapi function. Logical coordinates of the context are set by ::SetWindowOrgEx()/::SetViewportOrgEx()/::SetWindowExtEx()/::SetViewporatExtEx() winapi functions according to the current scrolled area to match the unscrolled coodinates. Possibly because the logical coordinates are exact one-to-one mapping to the device coodinates in this case, they are only valid in "device coordinate space" which is limited up to 2^27 (https://docs.microsoft.com/en-us/window ... ate-spaces).

All drawing operations on the wxBufferedPaintDC are actually on the wxBufferedDC, before the wxBufferPaintedDC destructor (include/wx/dcbuffer.h:183) calls wxBufferedDC::UnMask() (src/common/dcbufcmn.cpp:134) to copy (BitBlt) the contents to the actual DC. If the top-left logical coordinates of the wxBufferedDC are beyond the "device cordinate space" the BitBlt fails. If the topmost row is 6100806 the top y-cordinate is 6100806*22(line height) = 2^27+4 > 2^27, which is beyond the space.

To solve the issue in a project targetting only MSW I avoided calling the wxScrollHelper::PrepareDC() in wxDataViewMainWindow::OnPaint() and changed all drawing operations on the DC from by unscrolled coordinates to by scrolled coordinates. The patch has worked well so far.

I'm not completely sure what I have guessed is right. Is there something I overlooked? Thank you.
User avatar
doublemax
Moderator
Moderator
Posts: 19103
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxDataViewCtrl with huge data fails updating on wxMSW

Post by doublemax »

I didn't double check the details, but your analysis looks reasonable. It would be great if you could either open a bug report (together with your findings) at http://trac.wxwidgets.org , or post the same at https://groups.google.com/g/wx-users so that the core wxWidgets developers can see it. This here is a user forum.
Use the source, Luke!
KodamaDeveloped
In need of some credit
In need of some credit
Posts: 2
Joined: Thu Nov 25, 2021 11:22 pm

Re: wxDataViewCtrl with huge data fails updating on wxMSW

Post by KodamaDeveloped »

Post Reply