diff --git a/fsl/fsleyes/gl/lightboxcanvas.py b/fsl/fsleyes/gl/lightboxcanvas.py index fa193d337dabc89b278839ff5f5d08bc3ade4d52..3a6a62721d5a998b8844593d2e2aeba7a0ba8ff9 100644 --- a/fsl/fsleyes/gl/lightboxcanvas.py +++ b/fsl/fsleyes/gl/lightboxcanvas.py @@ -317,23 +317,11 @@ class LightBoxCanvas(slicecanvas.SliceCanvas): continue globj = self._glObjects.get(overlay, None) - + if globj is None: continue - name = '{}_{}_zax{}'.format( - id(overlay), - textures.RenderTextureStack.__name__, - self.zax) - - if glresources.exists(name): - rt = glresources.get(name) - else: - - rt = textures.RenderTextureStack(globj) - rt.setAxes(self.xax, self.yax) - glresources.set(name, rt) - + rt, name = self._getPreRenderTexture(globj, overlay) self._prerenderTextures[overlay] = rt, name self._refresh() diff --git a/fsl/fsleyes/gl/slicecanvas.py b/fsl/fsleyes/gl/slicecanvas.py index b91587a471ca5fd194535d5d58c61d981fe5f355..6d062a8ef4eb4fa582826bf814a219d2ae596a47 100644 --- a/fsl/fsleyes/gl/slicecanvas.py +++ b/fsl/fsleyes/gl/slicecanvas.py @@ -227,6 +227,9 @@ class SliceCanvas(props.HasProperties): self.displayCtx .addListener('bounds', self.name, self._overlayBoundsChanged) + self.displayCtx .addListener('syncOverlayDisplay', + self.name, + self._syncOverlayDisplayChanged) def destroy(self): @@ -480,23 +483,53 @@ class SliceCanvas(props.HasProperties): # is managed by a RenderTextureStack # object. elif self.renderMode == 'prerender': - name = '{}_{}_zax{}'.format( - id(overlay), - textures.RenderTextureStack.__name__, - self.zax) - - if glresources.exists(name): - rt = glresources.get(name) - - else: - rt = textures.RenderTextureStack(globj) - rt.setAxes(self.xax, self.yax) - glresources.set(name, rt) - + rt, name = self._getPreRenderTexture(globj, overlay) self._prerenderTextures[overlay] = rt, name self._refresh() + + def _getPreRenderTexture(self, globj, overlay): + """Creates/retrieves a :class:`.RenderTextureStack` for the given + :class:`.GLObject`. A tuple containing the ``RenderTextureStack``, + and its name, as passed to the :mod:`.resources` module, is returned. + + :arg globj: The :class:`.GLObject` instance. + :arg overlay: The overlay object. + """ + + display = self.displayCtx.getDisplay(overlay) + opts = display.getDisplayOpts() + + name = '{}_{}_zax{}'.format( + id(overlay), + textures.RenderTextureStack.__name__, + self.zax) + + # If all display/opts properties + # are synchronised to the parent, + # then we use a texture stack that + # might be shared across multiple + # views. + # + # But if any display/opts properties + # are not synchronised, we'll use our + # own texture stack. + if not (display.allSyncedToParent() and + opts .allSyncedToParent()): + + name = '{}_{}'.format(id(self.displayCtx), name) + + if glresources.exists(name): + rt = glresources.get(name) + + else: + rt = textures.RenderTextureStack(globj) + rt.setAxes(self.xax, self.yax) + glresources.set(name, rt) + + return rt, name + def _renderModeChange(self, *a): """Called when the :attr:`renderMode` property changes.""" @@ -525,6 +558,22 @@ class SliceCanvas(props.HasProperties): self._updateRenderTextures() + def _syncOverlayDisplayChanged(self, *a): + """Called when the :attr:`.DisplayContext.syncOverlayDisplay` + property changes. If the current :attr:`renderMode` is ``prerender``, + the :class:`.RenderTextureStack` instances for each overlay are + re-created. + + This is done because, if all display properties for an overlay are + synchronised, then a single ``RenderTextureStack`` can be shared + across multiple displays. However, if any display properties are not + synchronised, then a separate ``RenderTextureStack`` is needed for + the :class:`.DisplayContext` used by this ``SliceCanvas``. + """ + if self.renderMode == 'prerender': + self._renderModeChange(self) + + def _resolutionLimitChange(self, *a): """Called when the :attr:`resolutionLimit` property changes. diff --git a/fsl/fsleyes/gl/textures/rendertexturestack.py b/fsl/fsleyes/gl/textures/rendertexturestack.py index f6ed133b83b3ba99d67b3ce4f81115ca309f43b7..b332ad265d150c0aa0f6e0f69a27c9e50404017c 100644 --- a/fsl/fsleyes/gl/textures/rendertexturestack.py +++ b/fsl/fsleyes/gl/textures/rendertexturestack.py @@ -73,6 +73,13 @@ class RenderTextureStack(object): import wx wx.GetApp().Bind(wx.EVT_IDLE, self.__textureUpdateLoop) + log.memory('{}.init ({})'.format(type(self).__name__, id(self))) + + + def __del__(self): + """Prints a log message.""" + log.memory('{}.del ({})'.format(type(self).__name__, id(self))) + def destroy(self): """Must be called when this ``RenderTextureStack`` is no longer needed.