[Qgis-developer] [Qgis-user] WMS Rendering Problems

Marco Hugentobler marco.hugentobler at karto.baug.ethz.ch
Mon Nov 5 05:19:15 EST 2007


Hi Tom,

You are right, resizing is a problem. I did some further tests on Linux and 
Mac, and found that resizing is a problem on both plattforms (maybe also on 
win, I didn't test). So I don't think it is a Mac specific issue. Also I 
found resizing can be a problem with large vector layers.

> r7316 doesn't fix the Mac WMS rendering problem; I am also using a Mac
> G4. To reproduce the bug, open a WMS layer and then resize or maximize
> the window. The layer is cleared and not redrawn. Other widgets such as
> the status and tool bars are sometimes drawn at incorrect locations too.

Maximizing worked on my G4 perfectly. I observed problems with the status and 
tool bar when resizing the window with the mouse (both on G4 and Linux).

> My guess is that the begin() of the second draw event is ignored as
> superfluous because the painter is already active. The second draw event
> then draws and successfully closes the painter. At this point, the
> resumed first draw is attempting to draw into an inactive painter.

That's why I tried to protect the QGraphicsRectItem from paint events in 
r7316:

if (mCanvas->isDirty())
  {
    setEnabled(false);
    mCanvas->render();
    setEnabled(true);
  }

If the item is disabled, it does not receive events during the rendering. I 
have the impression that concurrent paint events are not the only problem. 
Maybe Qts update optimisation of QWidget and QGraphicsView is also a cause?


> It's probably best
> left for QGIS 1.1. For now, we should see if nested draw events can be
> eliminated without a major redesign.

I totally agree. As 0.9.1 is meant as a bugfix release, it would be nice to 
have a solution with minimal code changes.  

Regards,
Marco


On Sunday 04 November 2007 06:51:46 Tom Elwertowski wrote:
> Marco Hugentobler wrote:
> > I think that the WMS refresh problem is due to a problem with
> > QGraphicsView/QGraphicsRectItem, which I tried to adress with r7316. This
> > fix works for me on Kubuntu7.10, Win XP (msys) and Mac (G4).
> >
> > From what I can see, the synchronous requesting works as expected and is
> > left at the time QHttp sends the done() signal (once all the requested
> > data is available). The painting is then done into QImage, which I think
> > is plattform independent (software rendering).
> >
> > Asynchronous requesting of WMS layers could still be a possibility for
> > the future. Maybe combined with Tims idea of a composite manager? I think
> > that such functionality should be developed in a branch as there is a
> > high risk of side effects.
>
> Hi Marco,
>
> r7316 doesn't fix the Mac WMS rendering problem; I am also using a Mac
> G4. To reproduce the bug, open a WMS layer and then resize or maximize
> the window. The layer is cleared and not redrawn. Other widgets such as
> the status and tool bars are sometimes drawn at incorrect locations too.
>
> Resizing a window by dragging the size control is a "gold standard" for
> testing Mac drawing code. If there are problems, they are most likely to
> show up while resizing a window.
>
> The problem is that the WMS implementation is not "Qt processEvent
> safe." Moving to asynchronous network events is one way to make the code
> processEvent safe. Moving the synchronous transfer outside the draw
> event might also work. Using threads for drawing is probably the best
> solution. I chose the asynchronous approach because it seemed closest to
> a bug fix than a redesign.
>
> This is the problematic sequence of events:
>
> 1. Resize window
> 2. WMS provider initiates draw event.
> 3. draw routine discovers layer needs refresh from WMS server.
> 4. draw routine issues network request.
> 5. QgsHttpTransaction calls processEvents so that network request can
> leave local machine.
> 6. processEvents now runs other events while waiting for the remote
> response.
> 7. there are drawing events pending due to setStatus signals from
> QgsHttpTransaction and QgsRasterLayer as well as for drawing the
> overview canvas. If a drag resize is in progress, there are also
> additional draw events due to the continued resizing of the main canvas.
> This is the bug -- a Mac draw event cannot be interrupted by another
> draw event.
> 8. eventually we resume interrupted draw events which are not able to be
> resumed.
>
> Here is the Mac terminal log:
>
> Warning: QWidget::repaint: Recursive repaint detected
> Warning: QCoreGraphicsPaintEngine::begin: Painter already active
> Warning: QPainter::begin(): Returned false
> Warning: QPainter::end: Painter not active, aborted
>
> followed by many of:
>
> Warning: QWidget: It is dangerous to leave painters active on a widget
> outside of the PaintEvent
>
> My guess is that the begin() of the second draw event is ignored as
> superfluous because the painter is already active. The second draw event
> then draws and successfully closes the painter. At this point, the
> resumed first draw is attempting to draw into an inactive painter.
>
> If we don't change anything, we need to tell users that QGIS/Mac does
> not support resizing or maximizing project windows containing WMS layers.
>
> I have been thinking along the same lines as Tim's composite manager but
> that's a bigger project than I want to do right now. It's probably best
> left for QGIS 1.1. For now, we should see if nested draw events can be
> eliminated without a major redesign.
>
> It would also be nice to have some development guidelines about
> processEvents since this problem keeps reappearing. A good rule would be
> that calls to processEvents cannot be made while drawing is in progress.
> Another good rule is not to allow QtPainter warnings in code which
> appears to work. These usually indicate code that is not cross-platform
> safe.
>
> Tom



-- 
Dr. Marco Hugentobler
Institute of Cartography
ETH Zurich
Technical Advisor QGIS Project Steering Committee
marco.hugentobler at karto.baug.ethz.ch



More information about the Qgis-developer mailing list