Details
-
Bug
-
Resolution: Fixed
-
P1: Critical
-
Qt for MCUs 2.0.1
-
None
-
RH850 D1M
Description
Tested on RH850.
See Reproduction for a snippet that can can reproduce the freeze every time.
The summary is that when you make an "invisible" object by reducing height or width to 0, the object still grabs a DrawBuffer, but never sets gpuActive, so the program gets stuck in a loop. Note, this requires that only the invisible object gets updated--some other object being drawn at the same time may cause a proper draw.
Details
platform_rh850.cpp
unsigned char *getNextDrawBuffer() const { unsigned char *bits = NULL; do { //Infinite loop bits = (unsigned char *) R_WM_WindowNewDrawBufGet(WM_UNIT, &wmWindow); } while (!bits); return bits; }
platform_rh850.cpp
void blendRect(DrawingDevice *drawingDevice, const Rect &rect, Rgba32 color, BlendMode blendMode) { // gpu not active, but zero pixels. We enter the fallback engine (32bpp in our case), which does NOT set gpuactive. if (!gpuActive && rect.width() * rect.height() < GPU_PIXEL_THRESHOLD) { drawingDevice->fallbackDrawingEngine()->blendRect(drawingDevice, rect, color, blendMode); return; } const r_drw2d_BlendMode_t drw2dBlendMode = blendMode == DrawingEngine::BlendMode_Source || color.alpha() == 255 ? R_DRW2D_BLENDMODE_SRC : R_DRW2D_BLENDMODE_SRC_OVER; rh850_blendRect_impl(drawingDevice, rect, color, drw2dBlendMode); }
Reproduction
Summary: Drop the width of a rect to zero, move it along the Y axis, then restore the width (with pauses in between).
SequentialAnimation { loops: 1 running: true PauseAnimation {duration: 10000} ScriptAction {script: ani.running = true} } property real controlVal: 100 SequentialAnimation { id: ani loops: -1 running: false ScriptAction { script: root.controlVal= 0 } PauseAnimation { duration: 100 } PropertyAnimation { target: vis property: "y" from: root.height / 2 to: root.height / 2 + 40 duration: 200 } PropertyAnimation { target: vis property: "y" to: root.height / 2 duration: 200 } PauseAnimation { duration: 1 } ScriptAction { script: root.controlVal= 100 } PauseAnimation { duration: 300 } } Rectangle { id: vis height: 50 width: controlVal color: "red" x: parent.width/2 - width y: parent.height / 2 }
Fixes
(Rewritten from memory, please double check)
unsigned char *getNextDrawBuffer() const { unsigned char *bits = NULL; do { bits = (unsigned char *) R_WM_WindowNewDrawBufGet(WM_UNIT, &wmWindow); if (!bits){ R_WM_FrameWait(WM_UNIT, 0); } } while (!bits); return bits; }
Not Fixes
//This doesn't work:
QML:
visible: width > 0 //Width gets turned into an int CPP side, so the object will still be "visible" at width=0.99 but width is zero. A problem for animations