mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-24 11:16:51 +00:00
xbmc: add PR3717
Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
parent
f6b2d09ec5
commit
42d082560c
358
packages/mediacenter/xbmc/patches/xbmc-999.80.006-PR3717.patch
Normal file
358
packages/mediacenter/xbmc/patches/xbmc-999.80.006-PR3717.patch
Normal file
@ -0,0 +1,358 @@
|
||||
From c38d57f0580372afa46602f8635d6bb284f0a2af Mon Sep 17 00:00:00 2001
|
||||
From: Ben Avison <bavison@riscosopen.org>
|
||||
Date: Tue, 26 Nov 2013 20:09:48 +0000
|
||||
Subject: [PATCH 1/2] Add caching of infolabels
|
||||
|
||||
The functions CGUIInfoLabel::GetLabel and CGUIInfoLabel::GetItemLabel take
|
||||
a number of strings returned from CGUIInfoManager::GetImage or
|
||||
CGUIInfoManager::GetLabel, and combine them with various constant strings
|
||||
which were determined during CGUIInfoLabel::Parse.
|
||||
|
||||
Rather than perform all the string operations on every call, this patch
|
||||
changes to use a two-pass process: first it queries all the GetImage/GetLabel
|
||||
strings, and then only if at least one of them has changed does it bother
|
||||
rebuilding the resultant string - otherwise it re-uses the copy built on a
|
||||
preceding call.
|
||||
|
||||
CGUIInfoLabel::GetLabel/GetItemLabel are also changed to return string
|
||||
references, rather than forcing an additional string copy.
|
||||
|
||||
I have measured the effect while the Videos window of the default skin was
|
||||
open (but idle) on a Raspberry Pi, and this reduced the CPU usage by 0.8%
|
||||
from 36.2% to 35.4%:
|
||||
|
||||
Before After
|
||||
Mean StdDev Mean StdDev Confidence Change
|
||||
IdleCPU% 36.2 0.5 35.4 0.5 99.9% +2.2%
|
||||
---
|
||||
xbmc/guilib/GUIInfoTypes.cpp | 102 +++++++++++++++++++++++++++++++++----------
|
||||
xbmc/guilib/GUIInfoTypes.h | 11 ++++-
|
||||
2 files changed, 87 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/xbmc/guilib/GUIInfoTypes.cpp b/xbmc/guilib/GUIInfoTypes.cpp
|
||||
index 5648a77..6bb0eed 100644
|
||||
--- a/xbmc/guilib/GUIInfoTypes.cpp
|
||||
+++ b/xbmc/guilib/GUIInfoTypes.cpp
|
||||
@@ -136,37 +136,64 @@ void CGUIInfoLabel::SetLabel(const CStdString &label, const CStdString &fallback
|
||||
Parse(label, context);
|
||||
}
|
||||
|
||||
-CStdString CGUIInfoLabel::GetLabel(int contextWindow, bool preferImage, CStdString *fallback /*= NULL*/) const
|
||||
+const std::string &CGUIInfoLabel::GetLabel(int contextWindow, bool preferImage, CStdString *fallback /*= NULL*/) const
|
||||
{
|
||||
- CStdString label;
|
||||
- for (unsigned int i = 0; i < m_info.size(); i++)
|
||||
+ for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
|
||||
{
|
||||
const CInfoPortion &portion = m_info[i];
|
||||
if (portion.m_info)
|
||||
{
|
||||
- CStdString infoLabel;
|
||||
+ std::string infoLabel;
|
||||
if (preferImage)
|
||||
infoLabel = g_infoManager.GetImage(portion.m_info, contextWindow, fallback);
|
||||
if (infoLabel.empty())
|
||||
infoLabel = g_infoManager.GetLabel(portion.m_info, contextWindow, fallback);
|
||||
- if (!infoLabel.empty())
|
||||
- label += portion.GetLabel(infoLabel);
|
||||
+ if (j == m_labelPortions.size())
|
||||
+ m_labelPortions.push_back(infoLabel);
|
||||
+ else if (infoLabel != m_labelPortions[j])
|
||||
+ {
|
||||
+ m_labelPortions[j] = infoLabel;
|
||||
+ m_labelDirty = true;
|
||||
+ }
|
||||
+ j++;
|
||||
}
|
||||
- else
|
||||
- { // no info, so just append the prefix
|
||||
- label += portion.m_prefix;
|
||||
+ }
|
||||
+ if (m_labelDirty)
|
||||
+ {
|
||||
+ m_label.clear();
|
||||
+ for (unsigned int i = 0, j= 0; i < m_info.size(); i++)
|
||||
+ {
|
||||
+ const CInfoPortion &portion = m_info[i];
|
||||
+ if (portion.m_info)
|
||||
+ {
|
||||
+ if (!m_labelPortions[j].empty())
|
||||
+ m_label += portion.GetLabel(m_labelPortions[j]);
|
||||
+ j++;
|
||||
+ }
|
||||
+ else
|
||||
+ { // no info, so just append the prefix
|
||||
+ m_label += portion.m_prefix;
|
||||
+ }
|
||||
}
|
||||
+ if (m_label.empty()) // empty label, use the fallback
|
||||
+ m_label = m_fallback;
|
||||
+ m_labelDirty = false;
|
||||
}
|
||||
- if (label.empty()) // empty label, use the fallback
|
||||
- return m_fallback;
|
||||
- return label;
|
||||
+ return m_label;
|
||||
}
|
||||
|
||||
-CStdString CGUIInfoLabel::GetItemLabel(const CGUIListItem *item, bool preferImages, CStdString *fallback /*= NULL*/) const
|
||||
+const std::string &CGUIInfoLabel::GetItemLabel(const CGUIListItem *item, bool preferImages, CStdString *fallback /*= NULL*/) const
|
||||
{
|
||||
- if (!item->IsFileItem()) return "";
|
||||
- CStdString label;
|
||||
- for (unsigned int i = 0; i < m_info.size(); i++)
|
||||
+ if (!item->IsFileItem())
|
||||
+ {
|
||||
+ if (m_itemLabelDirty)
|
||||
+ {
|
||||
+ m_itemLabel = "";
|
||||
+ m_itemLabelDirty = false;
|
||||
+ }
|
||||
+ return m_itemLabel;
|
||||
+ }
|
||||
+ for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
|
||||
{
|
||||
const CInfoPortion &portion = m_info[i];
|
||||
if (portion.m_info)
|
||||
@@ -176,17 +203,38 @@ CStdString CGUIInfoLabel::GetItemLabel(const CGUIListItem *item, bool preferImag
|
||||
infoLabel = g_infoManager.GetItemImage((const CFileItem *)item, portion.m_info, fallback);
|
||||
else
|
||||
infoLabel = g_infoManager.GetItemLabel((const CFileItem *)item, portion.m_info, fallback);
|
||||
- if (!infoLabel.empty())
|
||||
- label += portion.GetLabel(infoLabel);
|
||||
+ if (j == m_itemLabelPortions.size())
|
||||
+ m_itemLabelPortions.push_back(infoLabel);
|
||||
+ else if (infoLabel != m_itemLabelPortions[j])
|
||||
+ {
|
||||
+ m_itemLabelPortions[j] = infoLabel;
|
||||
+ m_itemLabelDirty = true;
|
||||
+ }
|
||||
+ j++;
|
||||
}
|
||||
- else
|
||||
- { // no info, so just append the prefix
|
||||
- label += portion.m_prefix;
|
||||
+ }
|
||||
+ if (m_itemLabelDirty)
|
||||
+ {
|
||||
+ m_itemLabel.clear();
|
||||
+ for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
|
||||
+ {
|
||||
+ const CInfoPortion &portion = m_info[i];
|
||||
+ if (portion.m_info)
|
||||
+ {
|
||||
+ if (!m_itemLabelPortions[j].empty())
|
||||
+ m_itemLabel += portion.GetLabel(m_itemLabelPortions[j]);
|
||||
+ j++;
|
||||
+ }
|
||||
+ else
|
||||
+ { // no info, so just append the prefix
|
||||
+ m_itemLabel += portion.m_prefix;
|
||||
+ }
|
||||
}
|
||||
+ if (m_itemLabel.empty())
|
||||
+ m_itemLabel = m_fallback;
|
||||
+ m_itemLabelDirty = false;
|
||||
}
|
||||
- if (label.empty())
|
||||
- return m_fallback;
|
||||
- return label;
|
||||
+ return m_itemLabel;
|
||||
}
|
||||
|
||||
bool CGUIInfoLabel::IsEmpty() const
|
||||
@@ -270,6 +318,12 @@ CStdString CGUIInfoLabel::ReplaceAddonStrings(const CStdString &label)
|
||||
void CGUIInfoLabel::Parse(const CStdString &label, int context)
|
||||
{
|
||||
m_info.clear();
|
||||
+ m_labelDirty = true;
|
||||
+ m_label.clear();
|
||||
+ m_labelPortions.clear();
|
||||
+ m_itemLabelDirty = true;
|
||||
+ m_itemLabel.clear();
|
||||
+ m_itemLabelPortions.clear();
|
||||
// Step 1: Replace all $LOCALIZE[number] with the real string
|
||||
CStdString work = ReplaceLocalize(label);
|
||||
// Step 2: Replace all $ADDON[id number] with the real string
|
||||
diff --git a/xbmc/guilib/GUIInfoTypes.h b/xbmc/guilib/GUIInfoTypes.h
|
||||
index 8c1c1dc..418b2c4 100644
|
||||
--- a/xbmc/guilib/GUIInfoTypes.h
|
||||
+++ b/xbmc/guilib/GUIInfoTypes.h
|
||||
@@ -83,7 +83,7 @@ class CGUIInfoLabel
|
||||
\param fallback if non-NULL, is set to an alternate value to use should the actual value be not appropriate. Defaults to NULL.
|
||||
\return label (or image).
|
||||
*/
|
||||
- CStdString GetLabel(int contextWindow, bool preferImage = false, CStdString *fallback = NULL) const;
|
||||
+ const std::string &GetLabel(int contextWindow, bool preferImage = false, CStdString *fallback = NULL) const;
|
||||
|
||||
/*!
|
||||
\brief Gets a label (or image) for a given listitem from the info manager.
|
||||
@@ -92,7 +92,7 @@ class CGUIInfoLabel
|
||||
\param fallback if non-NULL, is set to an alternate value to use should the actual value be not appropriate. Defaults to NULL.
|
||||
\return label (or image).
|
||||
*/
|
||||
- CStdString GetItemLabel(const CGUIListItem *item, bool preferImage = false, CStdString *fallback = NULL) const;
|
||||
+ const std::string &GetItemLabel(const CGUIListItem *item, bool preferImage = false, CStdString *fallback = NULL) const;
|
||||
|
||||
bool IsConstant() const;
|
||||
bool IsEmpty() const;
|
||||
@@ -132,6 +132,13 @@ class CGUIInfoLabel
|
||||
|
||||
CStdString m_fallback;
|
||||
std::vector<CInfoPortion> m_info;
|
||||
+
|
||||
+ mutable bool m_labelDirty;
|
||||
+ mutable std::string m_label;
|
||||
+ mutable std::vector<std::string> m_labelPortions;
|
||||
+ mutable bool m_itemLabelDirty;
|
||||
+ mutable std::string m_itemLabel;
|
||||
+ mutable std::vector<std::string> m_itemLabelPortions;
|
||||
};
|
||||
|
||||
#endif
|
||||
--
|
||||
1.8.5.1
|
||||
|
||||
|
||||
From c84740a80a94c6ed36f57f5fd48744a8fd5fc5b2 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Avison <bavison@riscosopen.org>
|
||||
Date: Tue, 10 Dec 2013 01:12:31 +0000
|
||||
Subject: [PATCH 2/2] De-duplication of string cache for non-item and item
|
||||
labels
|
||||
|
||||
---
|
||||
xbmc/guilib/GUIInfoTypes.cpp | 50 +++++++++++++++++++++++++-------------------
|
||||
xbmc/guilib/GUIInfoTypes.h | 4 +---
|
||||
2 files changed, 29 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/xbmc/guilib/GUIInfoTypes.cpp b/xbmc/guilib/GUIInfoTypes.cpp
|
||||
index 6bb0eed..d096d8e 100644
|
||||
--- a/xbmc/guilib/GUIInfoTypes.cpp
|
||||
+++ b/xbmc/guilib/GUIInfoTypes.cpp
|
||||
@@ -121,7 +121,7 @@ void CGUIInfoColor::Parse(const CStdString &label, int context)
|
||||
m_color = g_colorManager.GetColor(label);
|
||||
}
|
||||
|
||||
-CGUIInfoLabel::CGUIInfoLabel()
|
||||
+CGUIInfoLabel::CGUIInfoLabel() : m_labelDirty(true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -178,7 +178,10 @@ void CGUIInfoLabel::SetLabel(const CStdString &label, const CStdString &fallback
|
||||
if (m_label.empty()) // empty label, use the fallback
|
||||
m_label = m_fallback;
|
||||
m_labelDirty = false;
|
||||
+ m_isLabelOfListItem = false;
|
||||
}
|
||||
+ else
|
||||
+ assert(m_isLabelOfListItem == false);
|
||||
return m_label;
|
||||
}
|
||||
|
||||
@@ -186,12 +189,15 @@ void CGUIInfoLabel::SetLabel(const CStdString &label, const CStdString &fallback
|
||||
{
|
||||
if (!item->IsFileItem())
|
||||
{
|
||||
- if (m_itemLabelDirty)
|
||||
+ if (m_labelDirty)
|
||||
{
|
||||
- m_itemLabel = "";
|
||||
- m_itemLabelDirty = false;
|
||||
+ m_label = "";
|
||||
+ m_labelDirty = false;
|
||||
+ m_isLabelOfListItem = true;
|
||||
}
|
||||
- return m_itemLabel;
|
||||
+ else
|
||||
+ assert(m_isLabelOfListItem == true);
|
||||
+ return m_label;
|
||||
}
|
||||
for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
|
||||
{
|
||||
@@ -203,38 +209,41 @@ void CGUIInfoLabel::SetLabel(const CStdString &label, const CStdString &fallback
|
||||
infoLabel = g_infoManager.GetItemImage((const CFileItem *)item, portion.m_info, fallback);
|
||||
else
|
||||
infoLabel = g_infoManager.GetItemLabel((const CFileItem *)item, portion.m_info, fallback);
|
||||
- if (j == m_itemLabelPortions.size())
|
||||
- m_itemLabelPortions.push_back(infoLabel);
|
||||
- else if (infoLabel != m_itemLabelPortions[j])
|
||||
+ if (j == m_labelPortions.size())
|
||||
+ m_labelPortions.push_back(infoLabel);
|
||||
+ else if (infoLabel != m_labelPortions[j])
|
||||
{
|
||||
- m_itemLabelPortions[j] = infoLabel;
|
||||
- m_itemLabelDirty = true;
|
||||
+ m_labelPortions[j] = infoLabel;
|
||||
+ m_labelDirty = true;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
- if (m_itemLabelDirty)
|
||||
+ if (m_labelDirty)
|
||||
{
|
||||
- m_itemLabel.clear();
|
||||
+ m_label.clear();
|
||||
for (unsigned int i = 0, j = 0; i < m_info.size(); i++)
|
||||
{
|
||||
const CInfoPortion &portion = m_info[i];
|
||||
if (portion.m_info)
|
||||
{
|
||||
- if (!m_itemLabelPortions[j].empty())
|
||||
- m_itemLabel += portion.GetLabel(m_itemLabelPortions[j]);
|
||||
+ if (!m_labelPortions[j].empty())
|
||||
+ m_label += portion.GetLabel(m_labelPortions[j]);
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{ // no info, so just append the prefix
|
||||
- m_itemLabel += portion.m_prefix;
|
||||
+ m_label += portion.m_prefix;
|
||||
}
|
||||
}
|
||||
- if (m_itemLabel.empty())
|
||||
- m_itemLabel = m_fallback;
|
||||
- m_itemLabelDirty = false;
|
||||
+ if (m_label.empty())
|
||||
+ m_label = m_fallback;
|
||||
+ m_labelDirty = false;
|
||||
+ m_isLabelOfListItem = true;
|
||||
}
|
||||
- return m_itemLabel;
|
||||
+ else
|
||||
+ assert(m_isLabelOfListItem == true);
|
||||
+ return m_label;
|
||||
}
|
||||
|
||||
bool CGUIInfoLabel::IsEmpty() const
|
||||
@@ -321,9 +330,6 @@ void CGUIInfoLabel::Parse(const CStdString &label, int context)
|
||||
m_labelDirty = true;
|
||||
m_label.clear();
|
||||
m_labelPortions.clear();
|
||||
- m_itemLabelDirty = true;
|
||||
- m_itemLabel.clear();
|
||||
- m_itemLabelPortions.clear();
|
||||
// Step 1: Replace all $LOCALIZE[number] with the real string
|
||||
CStdString work = ReplaceLocalize(label);
|
||||
// Step 2: Replace all $ADDON[id number] with the real string
|
||||
diff --git a/xbmc/guilib/GUIInfoTypes.h b/xbmc/guilib/GUIInfoTypes.h
|
||||
index 418b2c4..6d9ebf7 100644
|
||||
--- a/xbmc/guilib/GUIInfoTypes.h
|
||||
+++ b/xbmc/guilib/GUIInfoTypes.h
|
||||
@@ -133,12 +133,10 @@ class CGUIInfoLabel
|
||||
CStdString m_fallback;
|
||||
std::vector<CInfoPortion> m_info;
|
||||
|
||||
+ mutable bool m_isLabelOfListItem;
|
||||
mutable bool m_labelDirty;
|
||||
mutable std::string m_label;
|
||||
mutable std::vector<std::string> m_labelPortions;
|
||||
- mutable bool m_itemLabelDirty;
|
||||
- mutable std::string m_itemLabel;
|
||||
- mutable std::vector<std::string> m_itemLabelPortions;
|
||||
};
|
||||
|
||||
#endif
|
||||
--
|
||||
1.8.5.1
|
||||
|
Loading…
x
Reference in New Issue
Block a user