From 565d5396ec1285508ca20544ab01569819b4b540 Mon Sep 17 00:00:00 2001 From: Pranav Kant Date: Sun, 25 Oct 2015 19:22:46 +0530 Subject: [PATCH 250/398] lokdocview: Fix memory leaks Change-Id: I5107e4fa1828145a709e1edffe02831f4faae3c8 Reviewed-on: https://gerrit.libreoffice.org/19676 Tested-by: Jenkins Reviewed-by: Miklos Vajna (cherry picked from commit cfbc36e2eade42e471056d3c32fc962cd3149c17) --- libreofficekit/source/gtk/lokdocview.cxx | 33 ++++++++++++++++---------------- libreofficekit/source/gtk/tilebuffer.cxx | 5 +++++ libreofficekit/source/gtk/tilebuffer.hxx | 8 ++++++-- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx index 29b028c7b5d0..2ec27305af4e 100644 --- a/libreofficekit/source/gtk/lokdocview.cxx +++ b/libreofficekit/source/gtk/lokdocview.cxx @@ -50,7 +50,7 @@ struct LOKDocViewPrivateImpl LibreOfficeKit* m_pOffice; LibreOfficeKitDocument* m_pDocument; - TileBuffer m_aTileBuffer; + std::unique_ptr m_pTileBuffer; GThreadPool* lokThreadPool; gfloat m_fZoom; @@ -503,9 +503,8 @@ static gboolean postDocumentLoad(gpointer pData) // Total number of columns in this document. guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); - - priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, - nColumns); + priv->m_pTileBuffer = std::unique_ptr(new TileBuffer(priv->m_pDocument, + nColumns)); gtk_widget_set_size_request(GTK_WIDGET(pLOKDocView), nDocumentWidthPixels, nDocumentHeightPixels); @@ -634,7 +633,7 @@ setTilesInvalid (LOKDocView* pDocView, const GdkRectangle& rRectangle) for (int j = aStart.y; j < aEnd.y; j++) { GTask* task = g_task_new(pDocView, NULL, NULL, NULL); - priv->m_aTileBuffer.setInvalid(i, j, priv->m_fZoom, task, priv->lokThreadPool); + priv->m_pTileBuffer->setInvalid(i, j, priv->m_fZoom, task, priv->lokThreadPool); g_object_unref(task); } } @@ -657,7 +656,7 @@ callback (gpointer pData) setTilesInvalid(pDocView, aRectangle); } else - priv->m_aTileBuffer.resetAllTiles(); + priv->m_pTileBuffer->resetAllTiles(); gtk_widget_queue_draw(GTK_WIDGET(pDocView)); } @@ -923,7 +922,7 @@ renderDocument(LOKDocView* pDocView, cairo_t* pCairo) if (bPaint) { GTask* task = g_task_new(pDocView, NULL, NULL, NULL); - Tile& currentTile = priv->m_aTileBuffer.getTile(nRow, nColumn, priv->m_fZoom, task, priv->lokThreadPool); + Tile& currentTile = priv->m_pTileBuffer->getTile(nRow, nColumn, priv->m_fZoom, task, priv->lokThreadPool); GdkPixbuf* pPixBuf = currentTile.getBuffer(); gdk_cairo_set_source_pixbuf (pCairo, pPixBuf, twipToPixel(aTileRectangleTwips.x, priv->m_fZoom), @@ -1484,10 +1483,10 @@ paintTileInThread (gpointer data) LOKDocView* pDocView = LOK_DOC_VIEW(g_task_get_source_object(task)); LOKDocViewPrivate& priv = getPrivate(pDocView); LOEvent* pLOEvent = static_cast(g_task_get_task_data(task)); - TileBuffer& buffer = priv->m_aTileBuffer; - int index = pLOEvent->m_nPaintTileX * buffer.m_nWidth + pLOEvent->m_nPaintTileY; - if (buffer.m_mTiles.find(index) != buffer.m_mTiles.end() && - buffer.m_mTiles[index].valid) + std::unique_ptr& buffer = priv->m_pTileBuffer; + int index = pLOEvent->m_nPaintTileX * buffer->m_nWidth + pLOEvent->m_nPaintTileY; + if (buffer->m_mTiles.find(index) != buffer->m_mTiles.end() && + buffer->m_mTiles[index].valid) return; GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); @@ -1518,9 +1517,11 @@ paintTileInThread (gpointer data) pixelToTwip(nTileSizePixels, pLOEvent->m_fPaintTileZoom)); //create a mapping for it - buffer.m_mTiles[index].setPixbuf(pPixBuf); - buffer.m_mTiles[index].valid = true; + buffer->m_mTiles[index].setPixbuf(pPixBuf); + buffer->m_mTiles[index].valid = true; gdk_threads_add_idle(queueDraw, GTK_WIDGET(pDocView)); + + g_object_unref(pPixBuf); } @@ -2129,8 +2130,8 @@ lok_doc_view_set_zoom (LOKDocView* pDocView, float fZoom) // Total number of columns in this document. guint nColumns = ceil((double)nDocumentWidthPixels / nTileSizePixels); - priv->m_aTileBuffer = TileBuffer(priv->m_pDocument, - nColumns); + priv->m_pTileBuffer = std::unique_ptr(new TileBuffer(priv->m_pDocument, + nColumns)); gtk_widget_set_size_request(GTK_WIDGET(pDocView), nDocumentWidthPixels, nDocumentHeightPixels); @@ -2211,7 +2212,7 @@ SAL_DLLPUBLIC_EXPORT void lok_doc_view_reset_view(LOKDocView* pDocView) { LOKDocViewPrivate& priv = getPrivate(pDocView); - priv->m_aTileBuffer.resetAllTiles(); + priv->m_pTileBuffer->resetAllTiles(); priv->m_nLoadProgress = 0.0; memset(&priv->m_aVisibleCursor, 0, sizeof(priv->m_aVisibleCursor)); diff --git a/libreofficekit/source/gtk/tilebuffer.cxx b/libreofficekit/source/gtk/tilebuffer.cxx index 2f4e6cf123c1..811fcc61ef46 100644 --- a/libreofficekit/source/gtk/tilebuffer.cxx +++ b/libreofficekit/source/gtk/tilebuffer.cxx @@ -41,6 +41,11 @@ void Tile::release() void Tile::setPixbuf(GdkPixbuf *buffer) { + if (m_pBuffer == buffer) + return; + g_clear_object(&m_pBuffer); + if (buffer != NULL) + g_object_ref(buffer); m_pBuffer = buffer; } diff --git a/libreofficekit/source/gtk/tilebuffer.hxx b/libreofficekit/source/gtk/tilebuffer.hxx index 9361a622fb7c..bef1444f9c9c 100644 --- a/libreofficekit/source/gtk/tilebuffer.hxx +++ b/libreofficekit/source/gtk/tilebuffer.hxx @@ -52,7 +52,10 @@ class Tile { public: Tile() : valid(false), m_pBuffer(0) {} - ~Tile() { } + ~Tile() + { + g_clear_object(&m_pBuffer); + } /** Tells if this tile is valid or not. Initialised to 0 (invalid) during @@ -85,10 +88,11 @@ class TileBuffer TileBuffer(LibreOfficeKitDocument *document = 0, int columns = 0) : m_pLOKDocument(document) - , m_nWidth(columns) + , m_nWidth(columns) { GdkPixbuf* pPixBuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, nTileSizePixels, nTileSizePixels); m_DummyTile.setPixbuf(pPixBuf); + g_object_unref(pPixBuf); } ~TileBuffer() {} -- 2.12.0