Changeset 707 for trunk/src


Ignore:
Timestamp:
Apr 26, 2010, 2:40:21 AM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: Process deferred window flush events in Dive mode to make sure the window is properly updated after resizing etc.

Location:
trunk/src/gui/painting
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gui/painting/qwindowsurface_pm.cpp

    r706 r707  
    206206struct QPMDiveWindowSurfacePrivate
    207207{
    208     QNativeImage *image;
     208    QImage *image;
    209209    HDIVE hDive;
    210210    ULONG bufNum;
     
    214214    SETUP_BLITTER setup;
    215215    QVector<RECTL> rcls;
     216
     217    struct FlushArgs
     218    {
     219        QRect from;
     220        QPoint to;
     221    };
     222    QList<FlushArgs> pending;
    216223};
    217224
     
    258265QPaintDevice *QPMDiveWindowSurface::paintDevice()
    259266{
    260     return &d->image->image;
     267    return d->image;
    261268}
    262269
     
    264271                                 const QPoint &offset)
    265272{
    266     if (d->vrnDisabled)
    267         return;
    268 
    269273    // Not ready for painting yet, bail out. This can happen in
    270274    // QWidget::create_sys()
     
    274278    QRect br = rgn.boundingRect();
    275279
     280    QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft();
     281    QRect wbr = br.translated(-wOffset);
    276282    br.translate(offset);
    277283
    278     // make sure br doesn't exceed the backing storage size (it may happen
     284    wbr.setBottom(widget->height() - wbr.bottom() - 1); // flip y coordinate
     285
     286    if (d->vrnDisabled) {
     287        // defer the flush
     288        QPMDiveWindowSurfacePrivate::FlushArgs args = { br, wbr.bottomLeft() };
     289        d->pending.append(args);
     290        return;
     291    }
     292
     293    doFlush(br, wbr.bottomLeft());
     294}
     295
     296void QPMDiveWindowSurface::doFlush(const QRect &from, const QPoint &to)
     297{
     298#if 0
     299    qDebug() << "QPMDiveWindowSurface::doFlush:" << window()
     300             << "from" << from << "to" << to;
     301#endif
     302
     303    // make sure from doesn't exceed the backing storage size (it may happen
    279304    // during resize & move due to the different event order)
    280     br = br.intersected(QRect(0, 0, d->image->width(), d->image->height()));
    281 
    282     QPoint wOffset = qt_qwidget_data(widget)->wrect.topLeft();
    283     QRect wbr = br.translated(-offset - wOffset);
    284 
    285 #if 0
    286     qDebug() << "QPMDiveWindowSurface::flush:" << widget
    287              << "br" << br << "vrnDisabled" << d->vrnDisabled;
    288 #endif
     305    QRect src = from.intersected(QRect(0, 0, d->image->width(), d->image->height()));
     306    QPoint dst = to - (src.bottomLeft() - from.bottomLeft());
    289307
    290308    HWND hwnd = window()->winId();
     
    341359
    342360    SETUP_BLITTER setupTmp = d->setup;
    343     setupTmp.ulSrcWidth = br.width();
    344     setupTmp.ulSrcHeight = br.height();
    345     setupTmp.ulSrcPosX = br.left();
    346     setupTmp.ulSrcPosY = br.top();
    347     setupTmp.ulDstWidth = wbr.width();
    348     setupTmp.ulDstHeight = wbr.height();
    349     setupTmp.lDstPosX = wbr.left();
    350     setupTmp.lDstPosY = widget->height() - wbr.bottom() - 1; // flip y coordinate
     361    setupTmp.ulSrcWidth = src.width();
     362    setupTmp.ulSrcHeight = src.height();
     363    setupTmp.ulSrcPosX = src.left();
     364    setupTmp.ulSrcPosY = src.top();
     365    setupTmp.ulDstWidth = setupTmp.ulSrcWidth;
     366    setupTmp.ulDstHeight = setupTmp.ulSrcHeight;
     367    setupTmp.lDstPosX = dst.x();
     368    setupTmp.lDstPosY = dst.y();
    351369
    352370    if (memcmp(&d->setup, &setupTmp, d->setup.ulStructLen)) {
     
    376394                d->vrnDirty = true;
    377395            d->posDirty = true;
     396
     397            // process pending flush events
     398            foreach(QPMDiveWindowSurfacePrivate::FlushArgs args, d->pending) {
     399                doFlush(args.from, args.to);
     400            }
     401            d->pending.clear();
     402
    378403            *result = 0;
    379404            return true;
     
    406431        }
    407432
    408         QNativeImage *oldImage = d->image;
    409 
    410         d->image = new QNativeImage(width, height, QNativeImage::systemFormat(),
    411                                     false, window());
    412 
    413         // Associate the image data pointer with the buffer number. Note: this
    414         // will reassociate the existing buffer number with a new data pointer
    415         // if the buffer number is not 0
    416         // @todo???
     433        QImage *oldImage = d->image;
     434
     435        d->image = new QImage(width, height, QImage::Format_RGB32);
     436
     437        // associate the image data pointer with the buffer number
    417438        DiveFreeImageBuffer(d->hDive, d->bufNum);
    418439        d->bufNum = 0;
    419440        ULONG rc = DiveAllocImageBuffer(d->hDive, &d->bufNum, FOURCC_BGR4,
    420441                                        width, height,
    421                                         d->image->image.bytesPerLine(),
    422                                         (PBYTE)const_cast<const QImage &>(d->image->image).bits());
     442                                        d->image->bytesPerLine(),
     443                                        (PBYTE)const_cast<const QImage *>(d->image)->bits());
    423444
    424445        if (rc != DIVE_SUCCESS) {
     
    432453        if (oldImage && hasStaticContents()) {
    433454            // Make sure we use the const version of bits() (no detach).
    434             const uchar *src = const_cast<const QImage &>(oldImage->image).bits();
    435             uchar *dst = d->image->image.bits();
    436 
    437             const int srcBytesPerLine = oldImage->image.bytesPerLine();
    438             const int dstBytesPerLine = d->image->image.bytesPerLine();
    439             const int bytesPerPixel = oldImage->image.depth() >> 3;
     455            const uchar *src = const_cast<const QImage *>(oldImage)->bits();
     456            uchar *dst = d->image->bits();
     457
     458            const int srcBytesPerLine = oldImage->bytesPerLine();
     459            const int dstBytesPerLine = d->image->bytesPerLine();
     460            const int bytesPerPixel = oldImage->depth() >> 3;
    440461
    441462            QRegion staticRegion(staticContents());
    442463            // Make sure we're inside the boundaries of the old image.
    443             staticRegion &= QRect(0, 0, oldImage->image.width(), oldImage->image.height());
     464            staticRegion &= QRect(0, 0, oldImage->width(), oldImage->height());
    444465            const QVector<QRect> &rects = staticRegion.rects();
    445466            const QRect *srcRect = rects.constData();
     
    476497bool QPMDiveWindowSurface::scroll(const QRegion &area, int dx, int dy)
    477498{
    478     if (!d->image || d->image->image.isNull())
     499    if (!d->image || d->image->isNull())
    479500        return false;
    480501
    481502    const QVector<QRect> rects = area.rects();
    482503    for (int i = 0; i < rects.size(); ++i)
    483         qt_scrollRectInImage(d->image->image, rects.at(i), QPoint(dx, dy));
     504        qt_scrollRectInImage(*d->image, rects.at(i), QPoint(dx, dy));
    484505
    485506    return true;
  • trunk/src/gui/painting/qwindowsurface_pm_p.h

    r706 r707  
    7171    QPaintDevice *paintDevice();
    7272    void flush(QWidget *widget, const QRegion &rgn, const QPoint &offset);
     73    void doFlush(const QRect &from, const QPoint &to);
    7374    void setGeometry(const QRect &rect);
    7475    bool scroll(const QRegion &area, int dx, int dy);
Note: See TracChangeset for help on using the changeset viewer.