Skip to content
Browse files

Refs #10311. Port MythUI to ReferenceCounter.

Note: MythUIButtonList::GetImage() has been renamed to GetImageFilename(),
this was done to avoid conflict as getImage was renamed GetImage() and
because it is more descriptive.

As far as I can tell all MythUI leaks have now been plugged.
  • Loading branch information...
1 parent 1b8f1f3 commit 6b04160ac3ad1666cd034aa809ed5bb939a2028c @daniel-kristjansson daniel-kristjansson committed Jun 18, 2012
Showing with 392 additions and 266 deletions.
  1. +5 −18 mythplugins/mytharchive/mytharchive/thumbfinder.cpp
  2. +0 −1 mythplugins/mytharchive/mytharchive/thumbfinder.h
  3. +5 −1 mythplugins/mythbrowser/mythbrowser/mythbrowser.cpp
  4. +7 −1 mythplugins/mythbrowser/mythbrowser/mythbrowser.h
  5. +8 −3 mythplugins/mythbrowser/mythbrowser/webpage.cpp
  6. +2 −2 mythplugins/mythmusic/mythmusic/musiccommon.cpp
  7. +1 −1 mythplugins/mythmusic/mythmusic/playlisteditorview.cpp
  8. +1 −1 mythplugins/mythmusic/mythmusic/searchview.cpp
  9. +1 −1 mythplugins/mythmusic/mythmusic/smartplaylist.cpp
  10. +2 −2 mythplugins/mythnetvision/mythnetvision/netsearch.cpp
  11. +1 −2 mythplugins/mythzoneminder/mythzoneminder/zmclient.cpp
  12. +3 −2 mythplugins/mythzoneminder/mythzoneminder/zmevents.cpp
  13. +5 −12 mythplugins/mythzoneminder/mythzoneminder/zmliveplayer.cpp
  14. +0 −2 mythplugins/mythzoneminder/mythzoneminder/zmliveplayer.h
  15. +1 −1 mythtv/libs/libmythbase/mythversion.h
  16. +1 −0 mythtv/libs/libmythtv/Bluray/bdoverlayscreen.cpp
  17. +1 −0 mythtv/libs/libmythtv/mhi.cpp
  18. +4 −0 mythtv/libs/libmythtv/subtitlescreen.cpp
  19. +2 −1 mythtv/libs/libmythtv/teletextscreen.cpp
  20. +2 −2 mythtv/libs/libmythtv/videooutbase.cpp
  21. +29 −41 mythtv/libs/libmythui/mythimage.cpp
  22. +12 −9 mythtv/libs/libmythui/mythimage.h
  23. +88 −25 mythtv/libs/libmythui/mythpainter.cpp
  24. +6 −2 mythtv/libs/libmythui/mythpainter.h
  25. +7 −3 mythtv/libs/libmythui/mythpainter_qt.cpp
  26. +29 −0 mythtv/libs/libmythui/mythpainter_yuva.cpp
  27. +30 −29 mythtv/libs/libmythui/mythuibuttonlist.cpp
  28. +16 −6 mythtv/libs/libmythui/mythuibuttonlist.h
  29. +6 −2 mythtv/libs/libmythui/mythuiguidegrid.cpp
  30. +35 −46 mythtv/libs/libmythui/mythuihelper.cpp
  31. +4 −0 mythtv/libs/libmythui/mythuihelper.h
  32. +49 −40 mythtv/libs/libmythui/mythuiimage.cpp
  33. +18 −2 mythtv/libs/libmythui/mythuiimage.h
  34. +2 −2 mythtv/libs/libmythui/mythuivideo.cpp
  35. +4 −1 mythtv/libs/libmythui/mythuiwebbrowser.cpp
  36. +3 −3 mythtv/programs/mythfrontend/playbackbox.cpp
  37. +1 −1 mythtv/programs/mythtv-setup/channeleditor.cpp
  38. +1 −1 mythtv/programs/mythtv-setup/importicons.cpp
View
23 mythplugins/mytharchive/mytharchive/thumbfinder.cpp
@@ -109,7 +109,6 @@ ThumbFinder::ThumbFinder(MythScreenStack *parent, ArchiveItem *archiveItem,
m_startPTS = -1;
m_currentPTS = -1;
m_firstIFramePTS = -1;
- m_image = NULL;
}
void ThumbFinder::Init(void)
@@ -124,12 +123,6 @@ ThumbFinder::~ThumbFinder()
m_thumbList.clear();
closeAVCodec();
-
- if (m_image)
- {
- m_image->DownRef();
- m_image = NULL;
- }
}
bool ThumbFinder::Create(void)
@@ -891,17 +884,11 @@ bool ThumbFinder::getFrameImage(bool needKeyFrame, int64_t requiredPTS)
if (m_updateFrame)
{
- if (m_image)
- {
- m_image->DownRef();
- m_image = NULL;
- }
-
- m_image = GetMythMainWindow()->GetCurrentPainter()->GetFormatImage();
- m_image->Assign(img);
- m_image->UpRef();
-
- m_frameImage->SetImage(m_image);
+ MythImage *mimage =
+ GetMythMainWindow()->GetCurrentPainter()->GetFormatImage();
+ mimage->Assign(img);
+ m_frameImage->SetImage(mimage);
+ mimage->DecrRef();
}
updateCurrentPos();
View
1 mythplugins/mytharchive/mytharchive/thumbfinder.h
@@ -101,7 +101,6 @@ class ThumbFinder : public MythScreenType
int m_thumbCount;
QList<ThumbImage *> m_thumbList;
QString m_thumbDir;
- MythImage *m_image;
// GUI stuff
MythUIButton *m_frameButton;
View
6 mythplugins/mythbrowser/mythbrowser/mythbrowser.cpp
@@ -35,6 +35,11 @@ MythBrowser::~MythBrowser()
while (!m_browserList.isEmpty())
delete m_browserList.takeFirst();
GetMythMainWindow()->PauseIdleTimer(false);
+ if (m_defaultFavIcon)
+ {
+ m_defaultFavIcon->DecrRef();
+ m_defaultFavIcon = NULL;
+ }
}
bool MythBrowser::Create(void)
@@ -70,7 +75,6 @@ bool MythBrowser::Create(void)
QImage image(favIcon);
m_defaultFavIcon = GetMythPainter()->GetFormatImage();
m_defaultFavIcon->Assign(image);
- m_defaultFavIcon->UpRef();
}
// this is the template for all other browser tabs
View
8 mythplugins/mythbrowser/mythbrowser/mythbrowser.h
@@ -27,7 +27,13 @@ class MythBrowser : public MythScreenType
void setDefaultSaveDirectory(const QString saveDir) { m_defaultSaveDir = saveDir; }
void setDefaultSaveFilename(const QString saveFile) { m_defaultSaveFilename = saveFile; }
- MythImage* getDefaultFavIcon(void) { return m_defaultFavIcon; }
+
+ MythImage *GetDefaultFavIcon(void)
+ {
+ if (m_defaultFavIcon)
+ m_defaultFavIcon->IncrRef();
+ return m_defaultFavIcon;
+ }
public slots:
void slotOpenURL(const QString &url);
View
11 mythplugins/mythbrowser/mythbrowser/webpage.cpp
@@ -100,7 +100,11 @@ void WebPage::slotIconChanged(void)
QIcon icon = m_browser->GetIcon();
if (icon.isNull())
- m_listItem->setImage(m_parent->getDefaultFavIcon(), "favicon");
+ {
+ MythImage *mimage = m_parent->GetDefaultFavIcon();
+ m_listItem->SetImage(mimage, "favicon");
+ mimage->DecrRef();
+ }
else
{
QPixmap pixmap = icon.pixmap(32, 32);
@@ -110,7 +114,8 @@ void WebPage::slotIconChanged(void)
MythImage *mimage = GetMythPainter()->GetFormatImage();
mimage->Assign(image);
- m_listItem->setImage(mimage, "favicon");
+ m_listItem->SetImage(mimage, "favicon");
+ mimage->DecrRef();
}
m_parent->m_pageList->Refresh();
@@ -120,7 +125,7 @@ void WebPage::slotLoadStarted(void)
{
m_listItem->SetText(tr("Loading..."));
m_listItem->DisplayState("loading", "loadingstate");
- m_listItem->setImage(NULL, "favicon");
+ m_listItem->SetImage(NULL, "favicon");
m_listItem->SetImage("", "favicon");
m_parent->m_pageList->Update();
View
4 mythplugins/mythmusic/mythmusic/musiccommon.cpp
@@ -1619,7 +1619,7 @@ void MusicCommon::customEvent(QEvent *event)
if (mdata && mdata->ID() == trackID)
{
// reload the albumart image if one has already been loaded for this track
- if (!item->GetImage().isEmpty())
+ if (!item->GetImageFilename().isEmpty())
{
QString artFile = mdata->getAlbumArtFile();
if (artFile.isEmpty())
@@ -1793,7 +1793,7 @@ void MusicCommon::playlistItemVisible(MythUIButtonListItem *item)
Metadata *mdata = qVariantValue<Metadata*> (item->GetData());
if (mdata)
{
- if (item->GetImage().isEmpty())
+ if (item->GetImageFilename().isEmpty())
{
QString artFile = mdata->getAlbumArtFile();
if (artFile.isEmpty())
View
2 mythplugins/mythmusic/mythmusic/playlisteditorview.cpp
@@ -706,7 +706,7 @@ void PlaylistEditorView::treeItemVisible(MythUIButtonListItem *item)
if (!mnode)
return;
- if (item->GetImage().isEmpty())
+ if (item->GetImageFilename().isEmpty())
{
QString artFile;
View
2 mythplugins/mythmusic/mythmusic/searchview.cpp
@@ -455,7 +455,7 @@ void SearchView::trackVisible(MythUIButtonListItem *item)
if (!item)
return;
- if (item->GetImage().isEmpty())
+ if (item->GetImageFilename().isEmpty())
{
Metadata *mdata = qVariantValue<Metadata*> (item->GetData());
if (mdata)
View
2 mythplugins/mythmusic/mythmusic/smartplaylist.cpp
@@ -1752,7 +1752,7 @@ void SmartPLResultViewer::trackVisible(MythUIButtonListItem *item)
if (!item)
return;
- if (item->GetImage().isEmpty())
+ if (item->GetImageFilename().isEmpty())
{
Metadata *mdata = qVariantValue<Metadata*> (item->GetData());
if (mdata)
View
4 mythplugins/mythnetvision/mythnetvision/netsearch.cpp
@@ -744,7 +744,7 @@ void NetSearch::slotItemChanged()
if (!item->GetThumbnail().isEmpty() && m_thumbImage)
{
MythUIButtonListItem *btn = m_searchResultList->GetItemCurrent();
- QString filename = btn->GetImage();
+ QString filename = btn->GetImageFilename();
if (filename.contains("%SHAREDIR%"))
filename.replace("%SHAREDIR%", GetShareDir());
m_thumbImage->Reset();
@@ -780,7 +780,7 @@ void NetSearch::slotItemChanged()
if (m_thumbImage)
{
- QString filename = item->GetImage();
+ QString filename = item->GetImageFilename();
m_thumbImage->Reset();
if (filename.contains("%SHAREDIR%"))
filename.replace("%SHAREDIR%", GetShareDir());
View
3 mythplugins/mythzoneminder/mythzoneminder/zmclient.cpp
@@ -511,7 +511,7 @@ void ZMClient::getEventFrame(Event *event, int frameNo, MythImage **image)
{
if (*image)
{
- (*image)->DownRef();
+ (*image)->DecrRef();
*image = NULL;
}
@@ -538,7 +538,6 @@ void ZMClient::getEventFrame(Event *event, int frameNo, MythImage **image)
// get a MythImage
*image = GetMythMainWindow()->GetCurrentPainter()->GetFormatImage();
- (*image)->UpRef();
// extract the image data and create a MythImage from it
if (!(*image)->loadFromData(data, imageSize, "JPEG"))
View
5 mythplugins/mythzoneminder/mythzoneminder/zmevents.cpp
@@ -256,7 +256,7 @@ void ZMEvents::eventChanged(MythUIButtonListItem *item)
continue;
MythUIButtonListItem *gridItem = m_eventGrid->GetItemAt(x);
- if (gridItem && !gridItem->getImage())
+ if (gridItem && !gridItem->HasImage())
{
if (x < 0 || x > (int)m_eventList->size() - 1)
continue;
@@ -272,8 +272,9 @@ void ZMEvents::eventChanged(MythUIButtonListItem *item)
{
MythImage *mimage = GetMythPainter()->GetFormatImage();
mimage->Assign(image);
- gridItem->setImage(mimage);
+ gridItem->SetImage(mimage);
mimage->SetChanged();
+ mimage->DecrRef();
}
}
}
View
17 mythplugins/mythzoneminder/mythzoneminder/zmliveplayer.cpp
@@ -390,7 +390,7 @@ void ZMLivePlayer::getMonitorList(void)
Player::Player() :
m_frameImage(NULL), m_statusText(NULL), m_cameraText(NULL),
- m_image(NULL), m_rgba(NULL)
+ m_rgba(NULL)
{
}
@@ -470,17 +470,10 @@ void Player::updateFrame(const unsigned char* buffer)
QImage image(m_rgba, m_monitor.width, m_monitor.height, QImage::Format_ARGB32);
- if (m_image)
- {
- m_image->DownRef();
- m_image = NULL;
- }
-
- m_image = GetMythMainWindow()->GetCurrentPainter()->GetFormatImage();
- m_image->Assign(image);
- m_image->UpRef();
-
- m_frameImage->SetImage(m_image);
+ MythImage *img = GetMythMainWindow()->GetCurrentPainter()->GetFormatImage();
+ img->Assign(image);
+ m_frameImage->SetImage(img);
+ img->DecrRef();
}
void Player::updateStatus(void)
View
2 mythplugins/mythzoneminder/mythzoneminder/zmliveplayer.h
@@ -53,8 +53,6 @@ class Player
MythUIText *m_statusText;
MythUIText *m_cameraText;
- MythImage *m_image;
-
uchar *m_rgba;
Monitor m_monitor;
View
2 mythtv/libs/libmythbase/mythversion.h
@@ -12,7 +12,7 @@
/// Update this whenever the plug-in API changes.
/// Including changes in the libmythbase, libmyth, libmythtv, libmythav* and
/// libmythui class methods used by plug-ins.
-#define MYTH_BINARY_VERSION "0.26.20120616-1"
+#define MYTH_BINARY_VERSION "0.26.20120617-1"
/** \brief Increment this whenever the MythTV network protocol changes.
*
View
1 mythtv/libs/libmythtv/Bluray/bdoverlayscreen.cpp
@@ -120,6 +120,7 @@ void BDOverlayScreen::DisplayBDOverlay(BDOverlay *overlay)
LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("Added %1 (%2 tot)")
.arg(hash).arg(m_overlayMap.size()));
}
+ image->DecrRef();
}
SetRedraw();
View
1 mythtv/libs/libmythtv/mhi.cpp
@@ -526,6 +526,7 @@ void MHIContext::UpdateOSD(InteractiveScreen *osdWindow,
uiimage->SetArea(MythRect(data->m_x, data->m_y,
data->m_image.width(), data->m_image.height()));
}
+ image->DecrRef();
}
osdWindow->OptimiseDisplayedArea();
// N.B. bypasses OSD class hence no expiry set
View
4 mythtv/libs/libmythtv/subtitlescreen.cpp
@@ -1020,6 +1020,8 @@ int SubtitleScreen::DisplayScaledAVSubtitles(const AVSubtitleRect *rect,
m_expireTimes.insert(uiimage, displayuntil);
m_avsubCache.insert(uiimage, image);
}
+ image->DecrRef();
+ image = NULL;
}
if (uiimage)
{
@@ -1407,6 +1409,7 @@ void SubtitleScreen::AddScaledImage(QImage &img, QRect &pos)
uiimage->SetImage(image);
uiimage->SetArea(MythRect(scaled));
}
+ image->DecrRef();
}
}
@@ -2341,6 +2344,7 @@ void SubtitleScreen::RenderAssTrack(uint64_t timecode)
uiimage->SetImage(image);
uiimage->SetArea(MythRect(img_rect));
}
+ image->DecrRef();
}
images = images->next;
count++;
View
3 mythtv/libs/libmythtv/teletextscreen.cpp
@@ -108,7 +108,7 @@ void TeletextScreen::OptimiseDisplayedArea(void)
while (it.hasNext())
{
it.next();
- MythImage* image = osd_painter->GetFormatImage();
+ MythImage *image = osd_painter->GetFormatImage();
if (!image || !it.value())
continue;
@@ -122,6 +122,7 @@ void TeletextScreen::OptimiseDisplayedArea(void)
uiimage->SetArea(MythRect(0, row * m_rowHeight,
m_safeArea.width(), m_rowHeight * 2));
}
+ image->DecrRef();
}
QRegion visible;
View
4 mythtv/libs/libmythtv/videooutbase.cpp
@@ -443,7 +443,7 @@ VideoOutput::VideoOutput() :
VideoOutput::~VideoOutput()
{
if (osd_image)
- osd_image->DownRef();
+ osd_image->DecrRef();
if (osd_painter)
delete osd_painter;
@@ -1355,7 +1355,7 @@ bool VideoOutput::DisplayOSD(VideoFrame *frame, OSD *osd)
if (osd_image && (osd_image->size() != osd_size))
{
LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("OSD size changed."));
- osd_image->DownRef();
+ osd_image->DecrRef();
osd_image = NULL;
}
View
70 mythtv/libs/libmythui/mythimage.cpp
@@ -25,13 +25,13 @@
MythUIHelper *MythImage::s_ui = NULL;
-MythImage::MythImage(MythPainter *parent)
+MythImage::MythImage(MythPainter *parent, const char *name) :
+ ReferenceCounter(name)
{
if (!parent)
LOG(VB_GENERAL, LOG_ERR, "Image created without parent!");
m_Parent = parent;
- m_RefCount = 0;
m_Changed = false;
@@ -59,63 +59,51 @@ MythImage::~MythImage()
m_Parent->DeleteFormatImage(this);
}
-void MythImage::UpRef(void)
+int MythImage::IncrRef(void)
{
- QMutexLocker locker(&m_RefCountLock);
- if (s_ui && m_cached && m_RefCount == 1)
+ int cnt = ReferenceCounter::IncrRef();
+ if ((2 == cnt) && s_ui && m_cached)
s_ui->ExcludeFromCacheSize(this);
- m_RefCount++;
+ return cnt;
}
-bool MythImage::DownRef(void)
+int MythImage::DecrRef(void)
{
- m_RefCountLock.lock();
- m_RefCount--;
- if (s_ui && m_cached)
+ bool cached = m_cached;
+ int cnt = ReferenceCounter::DecrRef();
+ if (cached)
{
- if (m_RefCount == 1)
+ if (s_ui && (1 == cnt))
s_ui->IncludeInCacheSize(this);
- else if (m_RefCount == 0)
- s_ui->ExcludeFromCacheSize(this);
- }
- if (m_RefCount <= 0)
- {
- m_RefCountLock.unlock();
- delete this;
- return true;
+ if (0 == cnt)
+ {
+ LOG(VB_GENERAL, LOG_INFO,
+ "Image should be removed from cache prior to deletion.");
+ }
}
- m_RefCountLock.unlock();
- return false;
-}
-
-int MythImage::RefCount(void)
-{
- QMutexLocker locker(&m_RefCountLock);
- return m_RefCount;
+ return cnt;
}
void MythImage::SetIsInCache(bool bCached)
{
- QMutexLocker locker(&m_RefCountLock);
- if (s_ui && m_RefCount == 1)
- {
- if (!m_cached && bCached)
- s_ui->IncludeInCacheSize(this);
- else if (m_cached && !bCached)
- s_ui->ExcludeFromCacheSize(this);
- }
+ IncrRef();
m_cached = bCached;
+ DecrRef();
}
void MythImage::Assign(const QImage &img)
{
- QMutexLocker locker(&m_RefCountLock);
- if (s_ui && m_RefCount == 1 && m_cached)
- s_ui->ExcludeFromCacheSize(this);
- *(static_cast<QImage *> (this)) = img;
- if (s_ui && m_RefCount == 1 && m_cached)
- s_ui->IncludeInCacheSize(this);
+ if (m_cached)
+ {
+ SetIsInCache(false);
+ *(static_cast<QImage*>(this)) = img;
+ SetIsInCache(m_cached);
+ }
+ else
+ {
+ *(static_cast<QImage*>(this)) = img;
+ }
SetChanged();
}
View
21 mythtv/libs/libmythui/mythimage.h
@@ -8,6 +8,7 @@
#include <QPixmap>
#include <QImageReader>
+#include "referencecounter.h"
#include "mythpainter.h"
enum ReflectAxis {ReflectHorizontal, ReflectVertical};
@@ -27,17 +28,17 @@ class MUI_PUBLIC MythImageReader: public QImageReader
QNetworkReply *m_networkReply;
};
-class MUI_PUBLIC MythImage : public QImage
+class MUI_PUBLIC MythImage : public QImage, public ReferenceCounter
{
public:
- MythImage(MythPainter *parent);
+ /// Creates a reference counted image, call DecrRef() to delete.
+ MythImage(MythPainter *parent, const char *name = "MythImage");
MythPainter* GetParent(void) { return m_Parent; }
void SetParent(MythPainter *parent) { m_Parent = parent; }
- void UpRef(void);
- bool DownRef(void);
- int RefCount(void);
+ virtual int IncrRef(void);
+ virtual int DecrRef(void);
virtual void SetChanged(bool change = true) { m_Changed = change; }
bool IsChanged() const { return m_Changed; }
@@ -64,7 +65,7 @@ class MUI_PUBLIC MythImage : public QImage
* @param size The size of the image.
* @param begin The beginning colour.
* @param end The ending colour.
- * @return A MythImage filled with a gradient.
+ * @return A reference counted image, call DecrRef() to delete.
*/
static MythImage *Gradient(MythPainter *painter,
const QSize & size, const QColor &beg,
@@ -81,6 +82,11 @@ class MUI_PUBLIC MythImage : public QImage
void SetIsInCache(bool bCached);
+ uint GetCacheSize(void) const
+ {
+ return (m_cached) ? numBytes() : 0;
+ }
+
protected:
virtual ~MythImage();
static void MakeGradient(QImage &image, const QColor &begin,
@@ -91,9 +97,6 @@ class MUI_PUBLIC MythImage : public QImage
bool m_Changed;
MythPainter *m_Parent;
- int m_RefCount;
- QMutex m_RefCountLock;
-
bool m_isGradient;
QColor m_gradBegin;
QColor m_gradEnd;
View
113 mythtv/libs/libmythui/mythpainter.cpp
@@ -24,6 +24,9 @@ MythPainter::MythPainter()
MythPainter::~MythPainter(void)
{
QMutexLocker locker(&m_allocationLock);
+
+ ExpireImages(0);
+
if (m_allocatedImages.isEmpty())
return;
@@ -108,6 +111,7 @@ void MythPainter::DrawText(const QRect &r, const QString &msg,
}
DrawImage(destRect, im, srcRect, alpha);
+ im->DecrRef();
}
void MythPainter::DrawTextLayout(const QRect & canvasRect,
@@ -134,19 +138,25 @@ void MythPainter::DrawTextLayout(const QRect & canvasRect,
{
LOG(VB_GENERAL, LOG_DEBUG, QString("MythPainter::DrawTextLayout: "
"Rendered image is null."));
+ im->DecrRef();
return;
}
QRect srcRect(0, 0, dest.width(), dest.height());
DrawImage(dest, im, srcRect, alpha);
+
+ im->DecrRef();
}
void MythPainter::DrawRect(const QRect &area, const QBrush &fillBrush,
const QPen &linePen, int alpha)
{
MythImage *im = GetImageFromRect(area, 0, 0, fillBrush, linePen);
if (im)
+ {
DrawImage(area.x(), area.y(), im, alpha);
+ im->DecrRef();
+ }
}
void MythPainter::DrawRoundRect(const QRect &area, int cornerRadius,
@@ -155,15 +165,21 @@ void MythPainter::DrawRoundRect(const QRect &area, int cornerRadius,
{
MythImage *im = GetImageFromRect(area, cornerRadius, 0, fillBrush, linePen);
if (im)
+ {
DrawImage(area.x(), area.y(), im, alpha);
+ im->DecrRef();
+ }
}
void MythPainter::DrawEllipse(const QRect &area, const QBrush &fillBrush,
const QPen &linePen, int alpha)
{
MythImage *im = GetImageFromRect(area, 0, 1, fillBrush, linePen);
if (im)
+ {
DrawImage(area.x(), area.y(), im, alpha);
+ im->DecrRef();
+ }
}
void MythPainter::PushTransformation(const UIEffects &zoom, QPointF center)
@@ -311,17 +327,22 @@ MythImage *MythPainter::GetImageFromString(const QString &msg,
QString::number(flags) +
QString::number(font.color().rgba()) + msg;
+ MythImage *im = NULL;
if (m_StringToImageMap.contains(incoming))
{
m_StringExpireList.remove(incoming);
m_StringExpireList.push_back(incoming);
- return m_StringToImageMap[incoming];
+ im = m_StringToImageMap[incoming];
+ if (im)
+ im->IncrRef();
}
-
- MythImage *im = GetFormatImage();
- if (im)
+ else
{
+ im = GetFormatImage();
+ im->SetFileName(QString("GetImageFromString: %1").arg(msg));
DrawTextPriv(im, msg, flags, r, font);
+
+ im->IncrRef();
m_SoftwareCacheSize += im->bytesPerLine() * im->height();
m_StringToImageMap[incoming] = im;
m_StringExpireList.push_back(incoming);
@@ -348,16 +369,20 @@ MythImage *MythPainter::GetImageFromTextLayout(const LayoutVector &layouts,
for (Ipara = layouts.begin(); Ipara != layouts.end(); ++Ipara)
incoming += (*Ipara)->text();
+ MythImage *im = NULL;
if (m_StringToImageMap.contains(incoming))
{
m_StringExpireList.remove(incoming);
m_StringExpireList.push_back(incoming);
- return m_StringToImageMap[incoming];
+ im = m_StringToImageMap[incoming];
+ if (im)
+ im->IncrRef();
}
-
- MythImage *im = GetFormatImage();
- if (im)
+ else
{
+ im = GetFormatImage();
+ im->SetFileName("GetImageFromTextLayout");
+
QImage pm(canvas.size(), QImage::Format_ARGB32_Premultiplied);
pm.fill(0);
@@ -407,6 +432,7 @@ MythImage *MythPainter::GetImageFromTextLayout(const LayoutVector &layouts,
pm.setOffset(canvas.topLeft());
im->Assign(pm.copy(0, 0, dest.width(), dest.height()));
+ im->IncrRef();
m_SoftwareCacheSize += im->bytesPerLine() * im->height();
m_StringToImageMap[incoming] = im;
m_StringExpireList.push_back(incoming);
@@ -456,17 +482,22 @@ MythImage* MythPainter::GetImageFromRect(const QRect &area, int radius,
incoming += QString::number(hash1) + QString::number(hash2);
+ MythImage *im = NULL;
if (m_StringToImageMap.contains(incoming))
{
m_StringExpireList.remove(incoming);
m_StringExpireList.push_back(incoming);
- return m_StringToImageMap[incoming];
+ im = m_StringToImageMap[incoming];
+ if (im)
+ im->IncrRef();
}
-
- MythImage *im = GetFormatImage();
- if (im)
+ else
{
+ im = GetFormatImage();
+ im->SetFileName("GetImageFromRect");
DrawRectPriv(im, area, radius, ellipse, fillBrush, linePen);
+
+ im->IncrRef();
m_SoftwareCacheSize += (im->bytesPerLine() * im->height());
m_StringToImageMap[incoming] = im;
m_StringExpireList.push_back(incoming);
@@ -479,6 +510,7 @@ MythImage *MythPainter::GetFormatImage()
{
m_allocationLock.lock();
MythImage *result = GetFormatImagePriv();
+ result->SetFileName("GetFormatImage");
m_allocatedImages.append(result);
m_allocationLock.unlock();
return result;
@@ -507,34 +539,65 @@ void MythPainter::CheckFormatImage(MythImage *im)
void MythPainter::ExpireImages(int max)
{
- if (m_StringExpireList.size() < 1)
- return;
-
- while (m_SoftwareCacheSize > max)
+ bool recompute = false;
+ while (!m_StringExpireList.empty())
{
+ if (m_SoftwareCacheSize > max)
+ break;
+
QString oldmsg = m_StringExpireList.front();
m_StringExpireList.pop_front();
- MythImage *oldim = NULL;
- if (m_StringToImageMap.contains(oldmsg))
- oldim = m_StringToImageMap[oldmsg];
-
- m_StringToImageMap.remove(oldmsg);
+ QMap<QString, MythImage*>::iterator it =
+ m_StringToImageMap.find(oldmsg);
+ if (it == m_StringToImageMap.end())
+ {
+ recompute = true;
+ continue;
+ }
+ MythImage *oldim = *it;
+ it = m_StringToImageMap.erase(it);
if (oldim)
{
m_SoftwareCacheSize -= oldim->bytesPerLine() * oldim->height();
- oldim->DownRef();
+ if (m_SoftwareCacheSize < 0)
+ {
+ m_SoftwareCacheSize = 0;
+ recompute = true;
+ }
+ oldim->DecrRef();
}
}
+ if (recompute)
+ {
+ m_SoftwareCacheSize = 0;
+ QMap<QString, MythImage*>::iterator it = m_StringToImageMap.begin();
+ for (; it != m_StringToImageMap.end(); ++it)
+ m_SoftwareCacheSize += (*it)->bytesPerLine() * (*it)->height();
+ }
}
// the following assume graphics hardware operates natively at 32bpp
void MythPainter::SetMaximumCacheSizes(int hardware, int software)
{
m_MaxHardwareCacheSize = 1024 * 1024 * hardware;
m_MaxSoftwareCacheSize = 1024 * 1024 * software;
- LOG(VB_GUI, LOG_INFO,
- QString("MythPainter cache sizes: Hardware %1Mb, Software %2Mb")
- .arg(hardware).arg(software));
+
+ bool err = false;
+ if (m_MaxHardwareCacheSize < 0)
+ {
+ m_MaxHardwareCacheSize = 0;
+ err = true;
+ }
+ if (m_MaxSoftwareCacheSize < 0)
+ {
+ m_MaxSoftwareCacheSize = 1024 * 1024 * 48;
+ err = true;
+ }
+
+ LOG((err) ? VB_GENERAL : VB_GUI, (err) ? LOG_ERR : LOG_INFO,
+ QString("MythPainter cache sizes: Hardware %1 MB, Software %2 MB")
+ .arg(m_MaxHardwareCacheSize / (1024 * 1024))
+ .arg(m_MaxSoftwareCacheSize / (1024 * 1024)));
}
View
8 mythtv/libs/libmythui/mythpainter.h
@@ -70,6 +70,9 @@ class MUI_PUBLIC MythPainter
virtual void PushTransformation(const UIEffects &zoom, QPointF center = QPointF());
virtual void PopTransformation(void) { }
+ /// Returns a blank reference counted image in the format required
+ /// for the Draw functions for this painter.
+ /// \note The reference count is set for one use, call DecrRef() to delete.
MythImage *GetFormatImage();
void DeleteFormatImage(MythImage *im);
@@ -100,6 +103,7 @@ class MUI_PUBLIC MythPainter
const QBrush &fillBrush,
const QPen &linePen);
+ /// Creates a reference counted image, call DecrRef() to delete.
virtual MythImage* GetFormatImagePriv(void) = 0;
virtual void DeleteFormatImagePriv(MythImage *im) = 0;
void ExpireImages(int max = 0);
@@ -111,8 +115,8 @@ class MUI_PUBLIC MythPainter
int m_MaxHardwareCacheSize;
private:
- int m_SoftwareCacheSize;
- int m_MaxSoftwareCacheSize;
+ int64_t m_SoftwareCacheSize;
+ int64_t m_MaxSoftwareCacheSize;
QList<MythImage*> m_allocatedImages;
QMutex m_allocationLock;
View
10 mythtv/libs/libmythui/mythpainter_qt.cpp
@@ -15,12 +15,13 @@
class MythQtImage : public MythImage
{
public:
- MythQtImage(MythPainter *parent) : MythImage(parent),
- m_Pixmap(NULL), m_bRegenPixmap(false) { }
- ~MythQtImage() { }
+ MythQtImage(MythQtPainter *parent) :
+ MythImage(parent, "MythQtImage"),
+ m_Pixmap(NULL), m_bRegenPixmap(false) { }
void SetChanged(bool change = true);
QPixmap *GetPixmap(void) { return m_Pixmap; }
+ void SetPixmap(QPixmap *p) { m_Pixmap = p; }
bool NeedsRegen(void) { return m_bRegenPixmap; }
void RegeneratePixmap(void);
@@ -145,6 +146,9 @@ void MythQtPainter::DeleteFormatImagePriv(MythImage *im)
QMutexLocker locker(&m_imageDeleteLock);
if (qim->GetPixmap())
+ {
m_imageDeleteList.push_back(qim->GetPixmap());
+ qim->SetPixmap(NULL);
+ }
}
View
29 mythtv/libs/libmythui/mythpainter_yuva.cpp
@@ -35,9 +35,17 @@ void MythYUVAPainter::DrawText(const QRect &dest, const QString &msg, int flags,
MythFontProperties *converted = GetConvertedFont(font);
if (converted)
{
+ // We pull an image here, in the hopes that when DrawText
+ // pulls an image this will still be in the cache and have
+ // the right properties.
MythImage *im = GetImageFromString(msg, flags, dest, *converted);
if (im)
+ {
im->SetToYUV();
+ im->DecrRef();
+ im = NULL;
+ }
+
MythQImagePainter::DrawText(dest, msg, flags, *converted,
alpha, boundRect);
}
@@ -51,9 +59,16 @@ void MythYUVAPainter::DrawRect(const QRect &area, const QBrush &fillBrush,
QPen pen(linePen);
pen.setColor(rgb_to_yuv(pen.color()));
+ // We pull an image here, in the hopes that when DrawRect
+ // pulls an image this will still be in the cache and have
+ // the right properties.
MythImage *im = GetImageFromRect(area, 0, 0, brush, pen);
if (im)
+ {
im->SetToYUV();
+ im->DecrRef();
+ im = NULL;
+ }
MythQImagePainter::DrawRect(area, brush, pen, alpha);
}
@@ -67,9 +82,16 @@ void MythYUVAPainter::DrawRoundRect(const QRect &area, int cornerRadius,
QPen pen(linePen);
pen.setColor(rgb_to_yuv(pen.color()));
+ // We pull an image here, in the hopes that when DrawRect
+ // pulls an image this will still be in the cache and have
+ // the right properties.
MythImage *im = GetImageFromRect(area, cornerRadius, 0, brush, pen);
if (im)
+ {
im->SetToYUV();
+ im->DecrRef();
+ im = NULL;
+ }
MythQImagePainter::DrawRoundRect(area, cornerRadius, brush, pen, alpha);
}
@@ -82,9 +104,16 @@ void MythYUVAPainter::DrawEllipse(const QRect &area, const QBrush &fillBrush,
QPen pen(linePen);
pen.setColor(rgb_to_yuv(pen.color()));
+ // We pull an image here, in the hopes that when DrawRect
+ // pulls an image this will still be in the cache and have
+ // the right properties.
MythImage *im = GetImageFromRect(area, 0, 1, brush, pen);
if (im)
+ {
im->SetToYUV();
+ im->DecrRef();
+ im = NULL;
+ }
MythQImagePainter::DrawEllipse(area, brush, pen, alpha);
}
View
59 mythtv/libs/libmythui/mythuibuttonlist.cpp
@@ -3031,15 +3031,15 @@ MythUIButtonListItem::~MythUIButtonListItem()
m_parent->RemoveItem(this);
if (m_image)
- m_image->DownRef();
+ m_image->DecrRef();
- QMapIterator<QString, MythImage *> it(m_images);
-
- while (it.hasNext())
+ QMap<QString, MythImage*>::iterator it;
+ for (it = m_images.begin(); it != m_images.end(); ++it)
{
- it.next();
- it.value()->DownRef();
+ if (*it)
+ (*it)->DecrRef();
}
+ m_images.clear();
}
void MythUIButtonListItem::SetText(const QString &text, const QString &name,
@@ -3174,36 +3174,32 @@ void MythUIButtonListItem::SetFontState(const QString &state,
m_parent->Update();
}
-void MythUIButtonListItem::setImage(MythImage *image, const QString &name)
+void MythUIButtonListItem::SetImage(MythImage *image, const QString &name)
{
+ if (image)
+ image->IncrRef();
+
if (!name.isEmpty())
{
- if (m_images.contains(name))
+ QMap<QString, MythImage*>::iterator it = m_images.find(name);
+ if (it != m_images.end())
{
- if (m_images.value(name))
- m_images.value(name)->DownRef();
+ (*it)->DecrRef();
+ if (image)
+ *it = image;
+ else
+ m_images.erase(it);
}
-
- if (image)
+ else if (image)
{
- m_images.insert(name, image);
- image->UpRef();
+ m_images[name] = image;
}
- else
- m_images.remove(name);
}
else
{
- if (image == m_image)
- return;
-
if (m_image)
- m_image->DownRef();
-
+ m_image->DecrRef();
m_image = image;
-
- if (image)
- image->UpRef();
}
if (m_parent)
@@ -3216,15 +3212,20 @@ void MythUIButtonListItem::SetImageFromMap(const InfoMap &imageMap)
m_imageFilenames = imageMap;
}
-MythImage *MythUIButtonListItem::getImage(const QString &name)
+MythImage *MythUIButtonListItem::GetImage(const QString &name)
{
if (!name.isEmpty())
{
- if (m_images.contains(name))
- return m_images.value(name);
+ QMap<QString, MythImage*>::iterator it = m_images.find(name);
+ if (it != m_images.end())
+ {
+ (*it)->IncrRef();
+ return (*it);
+ }
}
- else
+ else if (m_image)
{
+ m_image->IncrRef();
return m_image;
}
@@ -3261,7 +3262,7 @@ void MythUIButtonListItem::SetImage(
m_parent->Update();
}
-QString MythUIButtonListItem::GetImage(const QString &name) const
+QString MythUIButtonListItem::GetImageFilename(const QString &name) const
{
if (name.isEmpty())
return m_imageFilename;
View
22 mythtv/libs/libmythui/mythuibuttonlist.h
@@ -53,20 +53,30 @@ class MUI_PUBLIC MythUIButtonListItem
void SetFontState(const QString &state, const QString &name="");
/** Sets an image directly, should only be used in special circumstances
- * since it bypasses the cache
+ * since it bypasses the cache.
*/
- void setImage(MythImage *image, const QString &name="");
+ void SetImage(MythImage *image, const QString &name="");
/** Gets a MythImage which has been assigned to this button item,
- * as with setImage() it should only be used in special circumstances
- * since it bypasses the cache
+ * as with SetImage() it should only be used in special circumstances
+ * since it bypasses the cache.
+ * \note The reference count is set for one use, call DecrRef() to delete.
*/
- MythImage *getImage(const QString &name="");
+ MythImage *GetImage(const QString &name="");
+
+ /// Returns true when the image exists.
+ bool HasImage(const QString &name="")
+ {
+ MythImage *img = GetImage(name);
+ bool ret = img;
+ img->DecrRef();
+ return ret;
+ }
void SetImage(const QString &filename, const QString &name="",
bool force_reload = false);
void SetImageFromMap(const InfoMap &imageMap);
- QString GetImage(const QString &name="") const;
+ QString GetImageFilename(const QString &name="") const;
void DisplayState(const QString &state, const QString &name);
void SetStatesFromMap(const InfoMap &stateMap);
View
8 mythtv/libs/libmythui/mythuiguidegrid.cpp
@@ -84,13 +84,13 @@ MythUIGuideGrid::~MythUIGuideGrid()
for (uint x = 0; x < RECSTATUSSIZE; x++)
{
if (m_recImages[x])
- m_recImages[x]->DownRef();
+ m_recImages[x]->DecrRef();
}
for (uint x = 0; x < ARROWIMAGESIZE; x++)
{
if (m_arrowImages[x])
- m_arrowImages[x]->DownRef();
+ m_arrowImages[x]->DecrRef();
}
}
@@ -657,6 +657,8 @@ void MythUIGuideGrid::LoadImage(int recType, const QString &file)
if (pix)
{
+ if (m_recImages[recType])
+ m_recImages[recType]->DecrRef();
m_recImages[recType] = GetPainter()->GetFormatImage();
m_recImages[recType]->Assign(*pix);
delete pix;
@@ -672,6 +674,8 @@ void MythUIGuideGrid::SetArrow(int direction, const QString &file)
if (pix)
{
+ if (m_arrowImages[direction])
+ m_arrowImages[direction]->DecrRef();
m_arrowImages[direction] = GetPainter()->GetFormatImage();
m_arrowImages[direction]->Assign(*pix);
delete pix;
View
81 mythtv/libs/libmythui/mythuihelper.cpp
@@ -15,6 +15,7 @@
#include <QStyleFactory>
#include <QSize>
#include <QFile>
+#include <QAtomicInt>
#include "mythdirs.h"
#include "mythlogging.h"
@@ -110,10 +111,9 @@ class MythUIHelperPrivate
QMap<QString, MythImage *> imageCache;
QMap<QString, uint> CacheTrack;
QMutex *m_cacheLock;
- size_t m_cacheSize;
- QMutex *m_cacheSizeLock;
- uint maxImageCacheSize;
+ QAtomicInt m_cacheSize;
+ QAtomicInt m_maxCacheSize;
// The part of the screen(s) allocated for the GUI. Unless
// overridden by the user, defaults to drawable area above.
@@ -155,8 +155,8 @@ MythUIHelperPrivate::MythUIHelperPrivate(MythUIHelper *p)
m_wmult(1.0), m_hmult(1.0), m_pixelAspectRatio(-1.0),
m_xbase(0), m_ybase(0), m_height(0), m_width(0),
m_baseWidth(800), m_baseHeight(600), m_isWide(false),
- m_cacheLock(new QMutex(QMutex::Recursive)), m_cacheSize(0),
- m_cacheSizeLock(new QMutex(QMutex::Recursive)),
+ m_cacheLock(new QMutex(QMutex::Recursive)),
+ m_cacheSize(0), m_maxCacheSize(20 * 1024 * 1024),
m_screenxbase(0), m_screenybase(0), m_screenwidth(0), m_screenheight(0),
screensaver(NULL), screensaverEnabled(false), display_res(NULL),
screenSetup(false), m_imageThreadPool(new MThreadPool("MythUIHelper")),
@@ -172,14 +172,13 @@ MythUIHelperPrivate::~MythUIHelperPrivate()
{
i.next();
i.value()->SetIsInCache(false);
- i.value()->DownRef();
+ i.value()->DecrRef();
i.remove();
}
CacheTrack.clear();
delete m_cacheLock;
- delete m_cacheSizeLock;
delete m_imageThreadPool;
delete m_qtThemeSettings;
delete screensaver;
@@ -399,14 +398,12 @@ void MythUIHelper::Init(MythUIMenuCallbacks &cbs)
d->Init();
d->callbacks = cbs;
- d->m_cacheSizeLock->lock();
- d->maxImageCacheSize = GetMythDB()->GetNumSetting("UIImageCacheSize", 20)
- * 1024 * 1024;
- d->m_cacheSizeLock->unlock();
+ d->m_maxCacheSize.fetchAndStoreRelease(
+ GetMythDB()->GetNumSetting("UIImageCacheSize", 20) * 1024 * 1024);
LOG(VB_GUI, LOG_INFO, LOC +
QString("MythUI Image Cache size set to %1 bytes")
- .arg(d->maxImageCacheSize));
+ .arg(d->m_maxCacheSize.fetchAndAddRelease(0)));
}
MythUIMenuCallbacks *MythUIHelper::GetMenuCBs(void)
@@ -501,15 +498,13 @@ void MythUIHelper::UpdateImageCache(void)
{
i.next();
i.value()->SetIsInCache(false);
- i.value()->DownRef();
+ i.value()->DecrRef();
i.remove();
}
d->CacheTrack.clear();
- d->m_cacheSizeLock->lock();
- d->m_cacheSize = 0;
- d->m_cacheSizeLock->unlock();
+ d->m_cacheSize.fetchAndStoreOrdered(0);
ClearOldImageCache();
}
@@ -521,6 +516,7 @@ MythImage *MythUIHelper::GetImageFromCache(const QString &url)
if (d->imageCache.contains(url))
{
d->CacheTrack[url] = MythDate::current().toTime_t();
+ d->imageCache[url]->IncrRef();
return d->imageCache[url];
}
@@ -538,22 +534,14 @@ MythImage *MythUIHelper::GetImageFromCache(const QString &url)
void MythUIHelper::IncludeInCacheSize(MythImage *im)
{
- if (!im)
- return;
-
- d->m_cacheSizeLock->lock();
- d->m_cacheSize += im->numBytes();
- d->m_cacheSizeLock->unlock();
+ if (im)
+ d->m_cacheSize.fetchAndAddOrdered(im->numBytes());
}
void MythUIHelper::ExcludeFromCacheSize(MythImage *im)
{
- if (!im)
- return;
-
- d->m_cacheSizeLock->lock();
- d->m_cacheSize -= im->numBytes();
- d->m_cacheSizeLock->unlock();
+ if (im)
+ d->m_cacheSize.fetchAndAddOrdered(-im->numBytes());
}
MythImage *MythUIHelper::CacheImage(const QString &url, MythImage *im,
@@ -582,12 +570,11 @@ MythImage *MythUIHelper::CacheImage(const QString &url, MythImage *im,
// delete the oldest cached images until we fall below threshold.
QMutexLocker locker(d->m_cacheLock);
- d->m_cacheSizeLock->lock();
- while (d->m_cacheSize + im->numBytes() >= d->maxImageCacheSize &&
+ while (d->m_cacheSize.fetchAndAddOrdered(0) + im->numBytes() >=
+ d->m_maxCacheSize.fetchAndAddOrdered(0) &&
d->imageCache.size())
{
- d->m_cacheSizeLock->unlock();
QMap<QString, MythImage *>::iterator it = d->imageCache.begin();
uint oldestTime = MythDate::current().toTime_t();
QString oldestKey = it.key();
@@ -596,12 +583,15 @@ MythImage *MythUIHelper::CacheImage(const QString &url, MythImage *im,
for (; it != d->imageCache.end(); ++it)
{
- if (d->CacheTrack[it.key()] < oldestTime &&
- (it.value()->RefCount() == 1))
+ if (d->CacheTrack[it.key()] < oldestTime)
{
- oldestTime = d->CacheTrack[it.key()];
- oldestKey = it.key();
- count++;
+ if ((2 == it.value()->IncrRef()) && (it.value() != im))
+ {
+ oldestTime = d->CacheTrack[it.key()];
+ oldestKey = it.key();
+ count++;
+ }
+ it.value()->DecrRef();
}
}
@@ -612,28 +602,25 @@ MythImage *MythUIHelper::CacheImage(const QString &url, MythImage *im,
{
LOG(VB_GUI | VB_FILE, LOG_INFO, LOC +
QString("Cache too big (%1), removing :%2:")
- .arg(d->m_cacheSize + im->numBytes()).arg(oldestKey));
+ .arg(d->m_cacheSize.fetchAndAddOrdered(0) + im->numBytes())
+ .arg(oldestKey));
- d->imageCache[oldestKey]->DownRef();
+ d->imageCache[oldestKey]->SetIsInCache(false);
+ d->imageCache[oldestKey]->DecrRef();
d->imageCache.remove(oldestKey);
d->CacheTrack.remove(oldestKey);
-
- d->m_cacheSizeLock->lock();
}
else
{
- d->m_cacheSizeLock->lock();
break;
}
}
- d->m_cacheSizeLock->unlock();
-
QMap<QString, MythImage *>::iterator it = d->imageCache.find(url);
if (it == d->imageCache.end())
{
- im->UpRef();
+ im->IncrRef();
d->imageCache[url] = im;
d->CacheTrack[url] = MythDate::current().toTime_t();
@@ -658,7 +645,7 @@ void MythUIHelper::RemoveFromCacheByURL(const QString &url)
if (it != d->imageCache.end())
{
d->imageCache[url]->SetIsInCache(false);
- d->imageCache[url]->DownRef();
+ d->imageCache[url]->DecrRef();
d->imageCache.remove(url);
d->CacheTrack.remove(url);
}
@@ -1514,6 +1501,7 @@ MythImage *MythUIHelper::LoadCacheImage(QString srcfile, QString label,
if (d->imageCache.contains(label) &&
d->CacheTrack[label] + kImageCacheTimeout > now)
{
+ d->imageCache[label]->IncrRef();
return d->imageCache[label];
}
}
@@ -1561,7 +1549,8 @@ MythImage *MythUIHelper::LoadCacheImage(QString srcfile, QString label,
QString("LoadCacheImage: Could not load :%1")
.arg(cachefilepath));
- ret->DownRef();
+ ret->SetIsInCache(false);
+ ret->DecrRef();
ret = NULL;
}
else
View
4 mythtv/libs/libmythui/mythuihelper.h
@@ -49,6 +49,8 @@ class MUI_PUBLIC MythUIHelper
void LoadQtConfig(void);
void UpdateImageCache(void);
+ /// Returns a reference counted image base on the URL.
+ /// \note The reference count is set for one use call DecrRef() to delete.
MythImage *GetImageFromCache(const QString &url);
MythImage *CacheImage(const QString &url, MythImage *im,
bool nodisk = false);
@@ -81,6 +83,8 @@ class MUI_PUBLIC MythUIHelper
QPixmap *LoadScalePixmap(QString filename, bool fromcache = true);
QImage *LoadScaleImage(QString filename, bool fromcache = true);
+ /// Returns a reference counted image from the cache.
+ /// \note The reference count is set for one use call DecrRef() to delete.
MythImage *LoadCacheImage(QString srcfile, QString label,
MythPainter *painter,
ImageCacheMode cacheMode = kCacheNormal);
View
89 mythtv/libs/libmythui/mythuiimage.cpp
@@ -54,7 +54,7 @@ ImageProperties &ImageProperties::operator=(const ImageProperties &other)
ImageProperties::~ImageProperties()
{
if (maskImage)
- maskImage->DownRef();
+ maskImage->DecrRef();
}
void ImageProperties::Init()
@@ -96,19 +96,16 @@ void ImageProperties::Copy(const ImageProperties &other)
SetMaskImage(other.maskImage);
}
-void ImageProperties::SetMaskImage(MythImage* image)
+void ImageProperties::SetMaskImage(MythImage *image)
{
+ if (image)
+ image->IncrRef();
if (maskImage)
- maskImage->DownRef();
+ maskImage->DecrRef();
isMasked = false;
maskImage = image;
-
- if (maskImage)
- {
- maskImage->UpRef();
- isMasked = true;
- }
+ isMasked = maskImage;
}
/*!
@@ -256,12 +253,15 @@ class ImageLoader
if (image)
{
- image->UpRef();
-
- LOG(VB_GUI | VB_FILE, LOG_INFO,
- QString("ImageLoader::LoadImage(%1) Found in cache, "
- "RefCount = %2").arg(cacheKey)
- .arg(image->RefCount()));
+ if (VERBOSE_LEVEL_CHECK(VB_GUI | VB_FILE, LOG_INFO))
+ {
+ image->IncrRef();
+ int cnt = image->DecrRef();
+ LOG(VB_GUI | VB_FILE, LOG_INFO,
+ QString("ImageLoader::LoadImage(%1) Found in cache, "
+ "RefCount = %2")
+ .arg(cacheKey).arg(cnt));
+ }
if (imProps.isReflected)
image->setIsReflected(true);
@@ -275,7 +275,6 @@ class ImageLoader
"Loading Directly").arg(cacheKey));
image = painter->GetFormatImage();
- image->UpRef();
bool ok = false;
if (imageReader)
@@ -285,7 +284,7 @@ class ImageLoader
if (!ok)
{
- image->DownRef();
+ image->DecrRef();
image = NULL;
}
}
@@ -298,7 +297,7 @@ class ImageLoader
if (imProps.isMasked)
{
QRect imageArea = image->rect();
- QRect maskArea = imProps.GetMaskImage()->rect();
+ QRect maskArea = imProps.GetMaskImageRect();
// Crop the mask to the image
int x = 0;
@@ -313,7 +312,7 @@ class ImageLoader
if (x > 0 || y > 0)
imageArea.translate(x, y);
- QImage mask = imProps.GetMaskImage()->copy(imageArea);
+ QImage mask = imProps.GetMaskImageSubset(imageArea);
image->setAlphaChannel(mask.alphaChannel());
}
@@ -335,7 +334,7 @@ class ImageLoader
QString("ImageLoader::LoadImage(%1) Image is NULL")
.arg(filename));
- image->DownRef();
+ image->DecrRef();
image = NULL;
}
@@ -592,7 +591,7 @@ void MythUIImage::Clear(void)
QHash<int, MythImage *>::iterator it = m_Images.begin();
if (*it)
- (*it)->DownRef();
+ (*it)->DecrRef();
m_Images.remove(it.key());
}
@@ -743,7 +742,7 @@ void MythUIImage::SetImage(MythImage *img)
Clear();
m_Delay = -1;
- img->UpRef();
+ img->IncrRef();
QSize forceSize = m_imageProperties.forceSize;
if (!forceSize.isNull())
@@ -803,7 +802,7 @@ void MythUIImage::SetImages(QVector<MythImage *> *images)
continue;
}
- im->UpRef();
+ im->IncrRef();
QSize forceSize = m_imageProperties.forceSize;
@@ -991,16 +990,31 @@ bool MythUIImage::Load(bool allowLoadInBackground, bool forceStat)
if (forceStat)
cacheMode2 |= (int)kCacheForceStat;
- if ((allowLoadInBackground) &&
- ((bPreferLoadInBackground) ||
- (!GetMythUI()->LoadCacheImage(filename, imagelabel,
- GetPainter(),
- static_cast<ImageCacheMode>(cacheMode)))))
+ bool do_background_load = false;
+ if (allowLoadInBackground)
+ {
+ if (bPreferLoadInBackground)
+ {
+ do_background_load = true;
+ }
+ else
+ {
+ MythImage *img = GetMythUI()->LoadCacheImage(
+ filename, imagelabel, GetPainter(),
+ static_cast<ImageCacheMode>(cacheMode));
+ if (img)
+ img->DecrRef();
+ else
+ do_background_load = true;
+ }
+ }
+
+ if (do_background_load)
{
SetMinArea(MythRect());
LOG(VB_GUI | VB_FILE, LOG_DEBUG, LOC +
QString("Load(), spawning thread to load '%1'").arg(filename));
-
+
m_runningThreads++;
ImageLoadThread *bImgThread;
bImgThread = new ImageLoadThread(this, GetPainter(),
@@ -1173,7 +1187,7 @@ void MythUIImage::DrawSelf(MythPainter *p, int xoffset, int yoffset,
MythImage *currentImage = m_Images[m_CurPos];
if (currentImage)
- currentImage->UpRef();
+ currentImage->IncrRef();
m_ImagesLock.unlock();
d->m_UpdateLock.unlock();
@@ -1210,7 +1224,7 @@ void MythUIImage::DrawSelf(MythPainter *p, int xoffset, int yoffset,
srcRect = currentImageArea;
p->DrawImage(area, currentImage, srcRect, alpha);
- currentImage->DownRef();
+ currentImage->DecrRef();
d->m_UpdateLock.unlock();
}
else
@@ -1362,16 +1376,11 @@ bool MythUIImage::ParseElement(
QString maskfile = getFirstText(element);
MythImage *newMaskImage = GetPainter()->GetFormatImage();
-
if (newMaskImage->Load(maskfile))
- {
m_imageProperties.SetMaskImage(newMaskImage);
- }
else
- {
- newMaskImage->DownRef();
m_imageProperties.SetMaskImage(NULL);
- }
+ newMaskImage->DecrRef();
}
else if (element.tagName() == "grayscale" ||
element.tagName() == "greyscale")
@@ -1532,7 +1541,7 @@ void MythUIImage::customEvent(QEvent *event)
.arg(filename));
if (image)
- image->DownRef();
+ image->DecrRef();
if (animationFrames)
{
@@ -1542,7 +1551,7 @@ void MythUIImage::customEvent(QEvent *event)
++it)
{
MythImage *im = (*it).first;
- im->DownRef();
+ im->DecrRef();
}
delete animationFrames;
@@ -1582,7 +1591,7 @@ void MythUIImage::customEvent(QEvent *event)
// If we got to this point, it means this same MythUIImage
// was told to reload the same image, so we use the newest
// copy of the image.
- m_Images[number]->DownRef(); // delete the original
+ m_Images[number]->DecrRef(); // delete the original
}
m_Images[number] = image;
View
20 mythtv/libs/libmythui/mythuiimage.h
@@ -18,6 +18,7 @@ class ImageLoadThread;
/*!
* \class ImageLoader
+ * \note ImageProperties must only be used in the UI thread.
*/
class ImageProperties
{
@@ -28,8 +29,23 @@ class ImageProperties
ImageProperties &operator=(const ImageProperties &other);
- void SetMaskImage(MythImage* image);
- MythImage* GetMaskImage() { return maskImage; }
+ void SetMaskImage(MythImage *image);
+ QRect GetMaskImageRect(void)
+ {
+ QRect rect;
+ if (maskImage)
+ rect = maskImage->rect();
+ return rect;
+ }
+ QImage GetMaskImageSubset(const QRect &imageArea)
+ {
+ if (maskImage)
+ return maskImage->copy(imageArea);
+
+ QImage img(imageArea.size(), QImage::Format_ARGB32);
+ img.fill(0xFFFFFFFF);
+ return img;
+ }
QString filename;
View
4 mythtv/libs/libmythui/mythuivideo.cpp
@@ -29,7 +29,7 @@ MythUIVideo::~MythUIVideo()
{
if (m_image)
{
- m_image->DownRef();
+ m_image->DecrRef();
m_image = NULL;
}
}
@@ -41,7 +41,7 @@ void MythUIVideo::Reset(void)
{
if (m_image)
{
- m_image->DownRef();
+ m_image->DecrRef();
m_image = NULL;
}
View
5 mythtv/libs/libmythui/mythuiwebbrowser.cpp
@@ -1010,7 +1010,7 @@ MythUIWebBrowser::~MythUIWebBrowser()
if (m_image)
{
- m_image->DownRef();
+ m_image->DecrRef();
m_image = NULL;
}
}
@@ -1396,6 +1396,9 @@ void MythUIWebBrowser::UpdateBuffer(void)
{
UpdateScrollBars();
+ if (!m_image)
+ return;
+
if (!m_active || (m_active && !m_browser->hasFocus()))
{
QPainter painter(m_image);
View
6 mythtv/programs/mythfrontend/playbackbox.cpp
@@ -832,7 +832,7 @@ void PlaybackBox::UpdateUIListItem(MythUIButtonListItem *item,
item->DisplayState(rating, "ratingstate");
- QString oldimgfile = item->GetImage("preview");
+ QString oldimgfile = item->GetImageFilename("preview");
if (oldimgfile.isEmpty() || force_preview_reload)
m_preview_tokens.insert(m_helper.GetPreviewImage(*pginfo));
@@ -982,7 +982,7 @@ void PlaybackBox::ItemVisible(MythUIButtonListItem *item)
item->DisplayState(extract_commflag_state(*pginfo), "commflagged");
MythUIButtonListItem *sel_item = item->parent()->GetItemCurrent();
- if ((item != sel_item) && item->GetImage("preview").isEmpty() &&
+ if ((item != sel_item) && item->GetImageFilename("preview").isEmpty() &&
(asAvailable == pginfo->GetAvailableStatus()))
{
QString token = m_helper.GetPreviewImage(*pginfo, true);
@@ -993,7 +993,7 @@ void PlaybackBox::ItemVisible(MythUIButtonListItem *item)
// now make sure selected item is still at the top of the queue
ProgramInfo *sel_pginfo =
qVariantValue<ProgramInfo*>(sel_item->GetData());
- if (sel_pginfo && sel_item->GetImage("preview").isEmpty() &&
+ if (sel_pginfo && sel_item->GetImageFilename("preview").isEmpty() &&
(asAvailable == sel_pginfo->GetAvailableStatus()))
{
m_preview_tokens.insert(
View
2 mythtv/programs/mythtv-setup/channeleditor.cpp
@@ -207,7 +207,7 @@ void ChannelEditor::itemChanged(MythUIButtonListItem *item)
if (m_preview)
{
m_preview->Reset();
- QString iconpath = item->GetImage();
+ QString iconpath = item->GetImageFilename();
if (!iconpath.isEmpty())
{
m_preview->SetFilename(iconpath);
View
2 mythtv/programs/mythtv-setup/importicons.cpp
@@ -249,7 +249,7 @@ void ImportIconsWizard::itemChanged(MythUIButtonListItem *item)
if (m_preview)
{
m_preview->Reset();
- QString iconpath = item->GetImage("icon");
+ QString iconpath = item->GetImageFilename("icon");
if (!iconpath.isEmpty())
{
m_preview->SetFilename(iconpath);

0 comments on commit 6b04160

Please sign in to comment.
Something went wrong with that request. Please try again.