You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Phase 2 of the flicker fix plan: port the MapWinGIS5 drag-pan behavior (blit the cached layer frame instead of re-rasterizing every layer on each mouse move).
What changes
MapWinGISControl gains a second offscreen buffer (_layerCache, a FrameBuffer) holding the last fully rendered layer frame plus the mwg::Viewport it was rendered with.
OnDraw: after painting the background, TryBlitCachedLayers blits the cached frame — shifted by the pixel offset derived from the center difference ((cacheCenter − center) / resolution, Y flipped) — when the size and resolution match. Only the rectangle whose source lies inside the cache is blitted; the rest keeps the background. Cache miss, resize, zoom, or a clamped sub-pixel pan falls through to a real render.
DrawLayersAndUpdateCache: renders the scene into the cache (background-filled, so the blit is opaque), records the viewport, and blits it into the composed frame. Allocation/blit failures fall back to drawing straight to the target (printer/metafile paths unchanged in behavior).
Drag pan: OnMouseMove still calls _view.Pan + FireViewChange, but no longer triggers a layer re-render — OnDraw serves the frame from the cache.
Button up: OnLButtonUp invalidates the cache and fires one redraw, so the final view is rasterized exactly once (this also covers clamped pans, where the blitted frame could sit up to half a pixel off).
No changes to FrameBuffer, the renderers, or the Core — this is behavior (not code) ported from v5's Map_Drawing.cpp pan path, per the plan.
Deliberately left out
Mouse-move repaint coalescing — only needed if profiling shows it.
Phase 3 (tessellation) is untouched.
Testing
Not run here (no Windows build in this environment). The change is confined to the OCX control; existing FrameBufferTests/VectorLayerRendererTests are unaffected. Worth a manual pass in the C# host: drag-pan should show zero re-render and zero flicker; zoom/resize/layer add should re-render crisply.
- EndMousePan centralizes drag termination (button-up, WM_CAPTURECHANGED, WM_CANCELMODE, button released during move)
- Every termination path now invalidates the layer cache and requests one final redraw, so panned-in strips never keep showing the background
- OnDestroy and Close keep the non-redrawing CancelMousePan
- WM_CAPTURECHANGED, WM_CANCELMODE, and the no-button WM_MOUSEMOVE path now invalidate the layer cache and request a final redraw
- The shifted cached frame can no longer stay on screen after a drag ends outside WM_LBUTTONUP
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
The presentation-blit failure path incorrectly leaves cache reuse enabled on the destination DC, potentially producing misplaced or blank fallback frames.
- Disable the layer cache when the presentation blit fails and the frame is drawn straight to the target DC, whose bounds origin and device differ from the offscreen buffer
- CancelMousePan invalidates the layer cache so shutdown paths (Close, OnDestroy, destructor) cannot leave a shifted cached frame for a reactivated control
- Accept any cache offset within half a pixel of an integer pixel shift: center floating-point accumulation no longer forces a full layer re-render on ordinary drags, and the mandatory drag-end render still lands the final frame exactly
- Record COLOR_WINDOW with the cache and reject the cached frame after a system-color or high-contrast change instead of repainting the old background over the new one
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Cache resizing can leave an unrendered replacement bitmap marked valid after FillRect fails, allowing a later draw to display invalid content.
No open issues 🎉
2 previously missed issues
In code that hasn't changed since last review
Invalidate resized cache until rendering succeeds
src/MapWinGIS.ActiveX/MapWinGISControl.cpp:1177
An alternate-sized IViewObject::Draw can replace the cache bitmap without clearing _layerCacheValid. If the subsequent FillRect fails, the direct-render fallback leaves the replacement marked valid, so the next draw at that size can blit an unrendered bitmap. Invalidate the cache before resizing or modifying it, and revalidate only after a successful cache render.
Test drag cache reuse and invalidation scenarios
src/MapWinGIS.ActiveX/MapWinGISControl.cpp:1291
The existing drag test in tests/MapWinGIS.ActiveX.Tests/ActiveXActivationTests.cpp:1911–1946 draws only after button-up, so it does not verify cache reuse during a drag. Add control-level tests that draw between mouse moves and verify shifted pixels, background-only exposed strips, and no layer-renderer calls. Cover final rendering after button-up, capture loss, and cancellation, plus cache invalidation after navigation, resize, and layer changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 2 of the flicker fix plan: port the MapWinGIS5 drag-pan behavior (blit the cached layer frame instead of re-rasterizing every layer on each mouse move).
What changes
MapWinGISControlgains a second offscreen buffer (_layerCache, aFrameBuffer) holding the last fully rendered layer frame plus themwg::Viewportit was rendered with.TryBlitCachedLayersblits the cached frame — shifted by the pixel offset derived from the center difference ((cacheCenter − center) / resolution, Y flipped) — when the size and resolution match. Only the rectangle whose source lies inside the cache is blitted; the rest keeps the background. Cache miss, resize, zoom, or a clamped sub-pixel pan falls through to a real render.OnMouseMovestill calls_view.Pan+FireViewChange, but no longer triggers a layer re-render — OnDraw serves the frame from the cache.OnLButtonUpinvalidates the cache and fires one redraw, so the final view is rasterized exactly once (this also covers clamped pans, where the blitted frame could sit up to half a pixel off).LoadVectorDatasetImpl,ClearLayers), all programmatic view changes (FitToMap,ZoomIn/Out,Pan,ZoomAt,ZoomToLayer, mouse wheel), resize (OnSize,SetObjectRects), andput_RenderingBackendPreference.No changes to
FrameBuffer, the renderers, or the Core — this is behavior (not code) ported from v5'sMap_Drawing.cpppan path, per the plan.Deliberately left out
Testing
Not run here (no Windows build in this environment). The change is confined to the OCX control; existing
FrameBufferTests/VectorLayerRendererTestsare unaffected. Worth a manual pass in the C# host: drag-pan should show zero re-render and zero flicker; zoom/resize/layer add should re-render crisply.