From 9548cd834156447ef8a36a038f0b48eb8992fa8b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 7 Jan 2013 15:07:40 -0500 Subject: [PATCH] js: Explicitly dispose all cairo contexts Due to limitations and bugs in SpiderMonkey's GC, wrapper objects for cairo contexts and similar may not get cleaned up immediately after repainting, leading to leaking memory. Explicitly disposing of such objects after they're not needed can clean up large portions of memory for cairo surfaces. https://bugzilla.gnome.org/show_bug.cgi?id=685513 --- js/gdm/loginDialog.js | 1 + js/ui/boxpointer.js | 2 ++ js/ui/dateMenu.js | 1 + js/ui/panel.js | 23 ++++++++++++----------- js/ui/popupMenu.js | 2 ++ js/ui/separator.js | 1 + js/ui/switcherPopup.js | 1 + 7 files changed, 20 insertions(+), 11 deletions(-) diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js index 17103227d..6bdd9af93 100644 --- a/js/gdm/loginDialog.js +++ b/js/gdm/loginDialog.js @@ -532,6 +532,7 @@ const SessionListItem = new Lang.Class({ color.alpha / 255); cr.arc(width / 2, height / 2, width / 3, 0, 2 * Math.PI); cr.fill(); + cr.$dispose(); }, _onClicked: function() { diff --git a/js/ui/boxpointer.js b/js/ui/boxpointer.js index cc8d0acbf..233432e5f 100644 --- a/js/ui/boxpointer.js +++ b/js/ui/boxpointer.js @@ -388,6 +388,8 @@ const BoxPointer = new Lang.Class({ cr.setLineWidth(borderWidth); cr.stroke(); } + + cr.$dispose(); }, setPosition: function(sourceActor, alignment) { diff --git a/js/ui/dateMenu.js b/js/ui/dateMenu.js index a60d85ff7..bf8244365 100644 --- a/js/ui/dateMenu.js +++ b/js/ui/dateMenu.js @@ -32,6 +32,7 @@ function _onVertSepRepaint (area) cr.setDash([1, 3], 1); // Hard-code for now cr.setLineWidth(stippleWidth); cr.stroke(); + cr.$dispose(); }; const DateMenuButton = new Lang.Class({ diff --git a/js/ui/panel.js b/js/ui/panel.js index 3618c7814..dada027a3 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -865,8 +865,8 @@ const PanelCorner = new Lang.Class({ let backgroundColor = node.get_color('-panel-corner-background-color'); let borderColor = node.get_color('-panel-corner-border-color'); - let noOverlap = borderColor.alpha == 0; - let offsetY = noOverlap ? borderWidth : 0; + let overlap = borderColor.alpha != 0; + let offsetY = overlap ? 0 : borderWidth; let cr = this.actor.get_context(); cr.setOperator(Cairo.Operator.SOURCE); @@ -890,17 +890,18 @@ const PanelCorner = new Lang.Class({ Clutter.cairo_set_source_color(cr, over); cr.fill(); - if (noOverlap) - return; + if (overlap) { + let offset = borderWidth; + Clutter.cairo_set_source_color(cr, backgroundColor); - let offset = borderWidth; - Clutter.cairo_set_source_color(cr, backgroundColor); + cr.save(); + cr.translate(xOffsetDirection * offset, - offset); + cr.appendPath(savedPath); + cr.fill(); + cr.restore(); + } - cr.save(); - cr.translate(xOffsetDirection * offset, - offset); - cr.appendPath(savedPath); - cr.fill(); - cr.restore(); + cr.$dispose(); }, _styleChanged: function() { diff --git a/js/ui/popupMenu.js b/js/ui/popupMenu.js index 6bcc994a9..58b7cb8ec 100644 --- a/js/ui/popupMenu.js +++ b/js/ui/popupMenu.js @@ -207,6 +207,7 @@ const PopupBaseMenuItem = new Lang.Class({ color.alpha / 255); cr.arc(width / 2, height / 2, width / 3, 0, 2 * Math.PI); cr.fill(); + cr.$dispose(); }, // This returns column widths in logical order (i.e. from the dot @@ -604,6 +605,7 @@ const PopupSliderMenuItem = new Lang.Class({ color.alpha / 255); cr.arc(handleX, handleY, handleRadius, 0, 2 * Math.PI); cr.fill(); + cr.$dispose(); }, _startDragging: function(actor, event) { diff --git a/js/ui/separator.js b/js/ui/separator.js index 1f414481c..1de1d89c3 100644 --- a/js/ui/separator.js +++ b/js/ui/separator.js @@ -30,5 +30,6 @@ const HorizontalSeparator = new Lang.Class({ cr.setSource(pattern); cr.rectangle(margin, gradientOffset, gradientWidth, gradientHeight); cr.fill(); + cr.$dispose(); } }); diff --git a/js/ui/switcherPopup.js b/js/ui/switcherPopup.js index b8ba0d248..c3a4ce0d9 100644 --- a/js/ui/switcherPopup.js +++ b/js/ui/switcherPopup.js @@ -637,5 +637,6 @@ function drawArrow(area, side) { Clutter.cairo_set_source_color(cr, bodyColor); cr.fill(); + cr.$dispose(); }