/** * First Pass: We do sweep and mark of all layers requiring a repaint, the areas behind a visible * opaque layers need no repaint */ private void sweepAndMarkLayers() { if (CGraphicsQ.DEBUG) { System.err.println("[Sweep and mark layers]"); } CLayer l; CLayerElement changed; CLayerElement le = layers.getTop(); while (le != null) { l = le.getLayer(); if (l.visible && l.opaque) { cleanLowerDirtyRegions(le); } // The dirty layer can be invisible, that means it // has been hidden since the previous paint. if (l.isDirty()) { // In the case higher layer was changed we need to // restart all the algorithm from the changed layer changed = sweepAndMarkDirtyLayer(le, !l.visible); if (changed != null) { if (CGraphicsQ.DEBUG) { System.err.println("Restart sweep and mark: " + changed.getLayer()); } le = changed; changed = null; continue; } } // Go to next lower layer le = le.getLower(); } }
/** * Copy dirty layer references to array for further painting. The copying is needed to not keep * lock on layers list when layers painting will happen. Dirty states of the layers are cleaned * after the copying. Layers painting can change layers state again, but it will be served on next * repaint only. */ private void copyAndCleanDirtyLayers() { if (CGraphicsQ.DEBUG) { System.err.println("[Copy dirty layers]"); } CLayer l; dirtyCount = 0; int layersCount = layers.size(); // Heuristics to increase array for copied dirty layers if (layersCount > dirtyMaxCount) { dirtyMaxCount += layersCount; dirtyLayers = new CLayer[dirtyMaxCount]; } // Copy dirty layer references and reset dirty layer states for (CLayerElement le = layers.getBottom(); le != null; le = le.getUpper()) { l = le.getLayer(); if (l.visible && l.isDirty()) { l.copyAndCleanDirtyState(); dirtyLayers[dirtyCount++] = l; } else { // !(visible && dirty) if (CGraphicsQ.DEBUG) { System.err.println("Skip Layer: " + l); } } // if } // for }
/** * Subtract this layer area from an underlying dirty regions. The method is designed to reduce * dirty regions of a layres below the opaque visible layer. * * @param le layer list element */ private void cleanLowerDirtyRegions(CLayerElement le) { if (CGraphicsQ.DEBUG) { System.err.println("Clean dirty regions under opaque layer: " + le.getLayer()); } CLayer l = le.getLayer(); for (CLayerElement le2 = le.getLower(); le2 != null; le2 = le2.getLower()) { CLayer l2 = le2.getLayer(); if (l2.isDirty()) { l2.subDirtyRegion( l.bounds[X] - l2.bounds[X], l.bounds[Y] - l2.bounds[Y], l.bounds[W], l.bounds[H]); } } }