From fe81f4ba69d64a389fc8e7ee952dcecfb025bf14 Mon Sep 17 00:00:00 2001 From: srcarter3 Date: Mon, 27 Mar 2023 15:09:01 -0700 Subject: [PATCH] Improve WWA performance AbstractWWAResource - cache current frame - cache current list of WWA entries - add color, string, and DrawableString objects to the internal WarningEntry class - use cached information when drawing, to draw faster (paintInternal method) --- .../viz/warnings/rsc/AbstractWWAResource.java | 258 +++++++++++------- 1 file changed, 163 insertions(+), 95 deletions(-) diff --git a/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/AbstractWWAResource.java b/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/AbstractWWAResource.java index 17eacbde09..e6cac15390 100644 --- a/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/AbstractWWAResource.java +++ b/cave/com.raytheon.viz.warnings/src/com/raytheon/viz/warnings/rsc/AbstractWWAResource.java @@ -98,6 +98,7 @@ import org.locationtech.jts.geom.prep.PreparedGeometryFactory; * Mar 15, 2022 srcarter@ucar Add support for display settings for outline, fill, text and time displays * Jun 24, 2022 srcarter@ucar Add 'statement/other' display settings, set enabled for only relevant WWA types * Jun 28, 2022 srcarter@ucar Display sampling based on new 'sampling' settings + * Mar 27, 2023 srcarter@ucar Optimize drawing to improve performance * * * @@ -136,6 +137,28 @@ public abstract class AbstractWWAResource extends * set to true if paint needs to re-init the shape */ protected boolean project = false; + + /** + * the display color + */ + protected RGB color = null; + + /** + * the text string that can be displayed + */ + protected String textStr = null; + /** + * the time string that can be displayed + */ + protected String timeStr = null; + /** + * the stylized emergency display string + */ + protected DrawableString emergencyDS = null; + /** + * the stylized params display string + */ + protected DrawableString paramsDS = null; } @@ -202,6 +225,12 @@ public abstract class AbstractWWAResource extends private static final String WATCH_SIG = "A"; private static final String ADVISORY_SIG = "Y"; + // Current drawing objects + private int currentFrameIdx = Integer.MIN_VALUE; + private TimeRange currentFramePeriod = null; + private boolean currentLastFrame = false; + private HashMap currentCandidates = new HashMap<>(); + /** The dialog used to change display properties */ private DrawingPropertiesDialog drawingDialog; @@ -420,47 +449,59 @@ public abstract class AbstractWWAResource extends } } int index = info.getFrameIndex(); - if (!this.recordsToLoad.isEmpty()) { - this.updateDisplay(target); + boolean framesChanged = false; + //only do the frame logic if the frame has changed + if(currentFrameIdx == Integer.MIN_VALUE || currentFrameIdx != index) { + framesChanged = true; + currentFrameIdx = index; + currentCandidates.clear(); + + if (!this.recordsToLoad.isEmpty()) { + this.updateDisplay(target); + } + + DataTime thisFrameTime = null; + if (index > -1 && index < frames.length) { + thisFrameTime = frames[index]; + } + if (thisFrameTime == null) { + return; + } + + TimeRange framePeriod = null; + boolean lastFrame = false; + if (index + 1 < frames.length) { + framePeriod = new TimeRange(thisFrameTime.getRefTime(), + frames[index + 1].getRefTime()); + } else { + framePeriod = getLastFrameTimeRange(thisFrameTime.getRefTime()); + lastFrame = true; + } + currentFramePeriod = framePeriod; + currentLastFrame = lastFrame; } - DataTime thisFrameTime = null; - if (index > -1 && index < frames.length) { - thisFrameTime = frames[index]; - } - if (thisFrameTime == null) { - return; - } - - TimeRange framePeriod = null; - boolean lastFrame = false; - if (index + 1 < frames.length) { - framePeriod = new TimeRange(thisFrameTime.getRefTime(), - frames[index + 1].getRefTime()); - } else { - framePeriod = getLastFrameTimeRange(thisFrameTime.getRefTime()); - lastFrame = true; - } synchronized (paintLock) { - HashMap candidates = new HashMap<>(); - for (WarningEntry entry : entryMap.values()) { - if (matchesFrame(entry, paintProps.getDataTime(), framePeriod, - lastFrame)) { - String key = getEventKey(entry); - WarningEntry current = candidates.get(key); - - if (current == null - || current.record.getIssueTime().before( - entry.record.getIssueTime()) - || (current.record.getIssueTime().equals( - entry.record.getIssueTime()) && current.record - .getInsertTime().before( - entry.record.getInsertTime()))) { - candidates.put(key, entry); + if(currentCandidates.size() == 0 || framesChanged) { + for (WarningEntry entry : entryMap.values()) { + if (matchesFrame(entry, paintProps.getDataTime(), currentFramePeriod, + currentLastFrame)) { + String key = getEventKey(entry); + WarningEntry current = currentCandidates.get(key); + + if (current == null + || current.record.getIssueTime().before( + entry.record.getIssueTime()) + || (current.record.getIssueTime().equals( + entry.record.getIssueTime()) && current.record + .getInsertTime().before( + entry.record.getInsertTime()))) { + currentCandidates.put(key, entry); + } } } } - for (WarningEntry entry : candidates.values()) { + for (WarningEntry entry : currentCandidates.values()) { AbstractWarningRecord record = entry.record; boolean drawShape = true; boolean drawOutline = true; @@ -510,9 +551,12 @@ public abstract class AbstractWWAResource extends entry.project = false; } - RGB displaycolor = color; - if ( ! record.getPil().equals("SPS")) { - displaycolor = RGBColors.getRGBColor(getPhensigColor(record.getPhensig())); + if(entry.color == null) { + RGB displaycolor = color; + if ( ! record.getPil().equals("SPS")) { + displaycolor = RGBColors.getRGBColor(getPhensigColor(record.getPhensig())); + } + entry.color = displaycolor; } if(entry != null){ @@ -532,71 +576,92 @@ public abstract class AbstractWWAResource extends target.drawWireframeShape( entry.wireframeShape, - displaycolor, + entry.color, outlineWidth, lineStyle); } } if (record != null && record.getGeometry() != null) { - // Calculate the upper left portion of the polygon - Coordinate upperLeft = new Coordinate(180, -90); - - for (Coordinate c : record.getGeometry().getCoordinates()) { - if (c.y - c.x > upperLeft.y - upperLeft.x) { - upperLeft = c; + //only calculate the drawable strings the first time through + if(entry.paramsDS == null || (entry.emergencyDS == null && EmergencyType.isEmergency(record.getRawmessage()))){ + // Calculate the upper left portion of the polygon + Coordinate upperLeft = new Coordinate(180, -90); + + for (Coordinate c : record.getGeometry().getCoordinates()) { + if (c.y - c.x > upperLeft.y - upperLeft.x) { + upperLeft = c; + } } + + double[] d = descriptor.worldToPixel(new double[] { + upperLeft.x, upperLeft.y }); + d[0] -= paintProps.getZoomLevel() * 100; + + double mapWidth = descriptor.getMapWidth() + * paintProps.getZoomLevel() / 1000; + String[] fullText = getText(record, mapWidth); + + String[] textToPrint = {"",""}; + if(drawText){ + textToPrint[0] = fullText[0]; + } + if(drawTime){ + textToPrint[1] = fullText[1]; + } + + + if (warningsFont == null) { + warningsFont = target.initializeFont(target + .getDefaultFont().getFontName(), 9, + new IFont.Style[0]); + emergencyFont = target.getDefaultFont().deriveWithSize( + 12); + } + + DrawableString params = new DrawableString(textToPrint, entry.color); + params.font = warningsFont; + params.setCoordinates(d[0], d[1]); + params.horizontalAlignment = HorizontalAlignment.RIGHT; + params.verticallAlignment = VerticalAlignment.BOTTOM; + params.magnification = getCapability( + MagnificationCapability.class).getMagnification(); + entry.paramsDS = params; + + // Draws the string again to have it appear bolder + if (EmergencyType.isEmergency(record.getRawmessage())) { + // moves over text to add EMER in a different font + textToPrint[1] = String.format("%1$-23" + "s", + textToPrint[1]); + params.setText(textToPrint, entry.color); + + DrawableString emergencyString = new DrawableString( + params); + emergencyString.setCoordinates(d[0], + d[1] + (paintProps.getZoomLevel()) * 90); + emergencyString.font = emergencyFont; + emergencyString.setText(new String[] { "", "", + " " + EmergencyType.EMER, "" }, entry.color); + entry.emergencyDS = emergencyString; + } + + entry.textStr = fullText[0]; + entry.timeStr = fullText[1]; } - - double[] d = descriptor.worldToPixel(new double[] { - upperLeft.x, upperLeft.y }); - d[0] -= paintProps.getZoomLevel() * 100; - - double mapWidth = descriptor.getMapWidth() - * paintProps.getZoomLevel() / 1000; - String[] fullText = getText(record, mapWidth); - - String[] textToPrint = {"",""}; - if(drawText){ - textToPrint[0] = fullText[0]; - } - if(drawTime){ - textToPrint[1] = fullText[1]; - } - - if (warningsFont == null) { - warningsFont = target.initializeFont(target - .getDefaultFont().getFontName(), 9, - new IFont.Style[0]); - emergencyFont = target.getDefaultFont().deriveWithSize( - 12); - } - - DrawableString params = new DrawableString(textToPrint, displaycolor); - params.font = warningsFont; - params.setCoordinates(d[0], d[1]); - params.horizontalAlignment = HorizontalAlignment.RIGHT; - params.verticallAlignment = VerticalAlignment.BOTTOM; - params.magnification = getCapability( - MagnificationCapability.class).getMagnification(); - - // Draws the string again to have it appear bolder if (EmergencyType.isEmergency(record.getRawmessage())) { - // moves over text to add EMER in a different font - textToPrint[1] = String.format("%1$-23" + "s", - textToPrint[1]); - params.setText(textToPrint, displaycolor); - - DrawableString emergencyString = new DrawableString( - params); - emergencyString.setCoordinates(d[0], - d[1] + (paintProps.getZoomLevel()) * 90); - emergencyString.font = emergencyFont; - emergencyString.setText(new String[] { "", "", - " " + EmergencyType.EMER, "" }, displaycolor); - target.drawStrings(emergencyString); + target.drawStrings(entry.emergencyDS); } - - target.drawStrings(params); + + String[] currentStrs = {"",""}; + if(drawText) { + currentStrs[0] = entry.textStr; + } + if(drawTime) { + currentStrs[1] = entry.timeStr; + } + + entry.paramsDS.setText(currentStrs, entry.color); + + target.drawStrings(entry.paramsDS); } } @@ -688,6 +753,9 @@ public abstract class AbstractWWAResource extends public synchronized void addRecord(PluginDataObject[] pdos) throws VizException { + //data has changed, so clear the current drawing candidates + currentCandidates.clear(); + for (PluginDataObject pdo : pdos) { if (pdo instanceof AbstractWarningRecord) { AbstractWarningRecord record = (AbstractWarningRecord) pdo; @@ -750,7 +818,7 @@ public abstract class AbstractWWAResource extends @SuppressWarnings("unchecked") protected void requestData(DataTime earliest) throws VizException { - System.out.println("requesting data"); +// System.out.println("requesting data"); Map map = (Map) resourceData .getMetadataMap().clone(); if (earliestRequested != null) {