Cache app icons in BarInfo to make them load faster.

This turns an IO bound problem into a CPU bound problem. In my testing this
speeds up icon resizing dramatically although the CPU is quickly pegged at
100% trying to redraw the Deskbar if you whip the icon size slider back and
forth with a dozen or so apps open and soon the CPU can't keep up and Deskbar
lags behind.
This commit is contained in:
John Scipione
2013-03-28 20:56:06 -04:00
parent c844f6e030
commit e13f5676a0
4 changed files with 45 additions and 36 deletions
+40 -20
View File
@@ -719,6 +719,12 @@ TBarApp::Unsubscribe(const BMessenger &subscriber)
void void
TBarApp::AddTeam(team_id team, uint32 flags, const char* sig, entry_ref* ref) TBarApp::AddTeam(team_id team, uint32 flags, const char* sig, entry_ref* ref)
{ {
if ((flags & B_BACKGROUND_APP) != 0
|| strcasecmp(sig, kDeskbarSignature) == 0) {
// it's a background app or Deskbar itself, don't add it
return;
}
BAutolock autolock(sSubscriberLock); BAutolock autolock(sSubscriberLock);
if (!autolock.IsLocked()) if (!autolock.IsLocked())
return; return;
@@ -761,15 +767,9 @@ TBarApp::AddTeam(team_id team, uint32 flags, const char* sig, entry_ref* ref)
} }
BarTeamInfo* barInfo = new BarTeamInfo(new BList(), flags, strdup(sig), BarTeamInfo* barInfo = new BarTeamInfo(new BList(), flags, strdup(sig),
new BBitmap(IconRect(), kIconColorSpace), strdup(name.String())); NULL, strdup(name.String()));
FetchAppIcon(barInfo);
if ((barInfo->flags & B_BACKGROUND_APP) == 0
&& strcasecmp(barInfo->sig, kDeskbarSignature) != 0) {
FetchAppIcon(barInfo->sig, barInfo->icon);
}
barInfo->teams->AddItem((void*)(addr_t)team); barInfo->teams->AddItem((void*)(addr_t)team);
sBarTeamInfoList.AddItem(barInfo); sBarTeamInfoList.AddItem(barInfo);
if (fSettings.expandNewTeams) if (fSettings.expandNewTeams)
@@ -839,9 +839,7 @@ TBarApp::ResizeTeamIcons()
BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i);
if ((barInfo->flags & B_BACKGROUND_APP) == 0 if ((barInfo->flags & B_BACKGROUND_APP) == 0
&& strcasecmp(barInfo->sig, kDeskbarSignature) != 0) { && strcasecmp(barInfo->sig, kDeskbarSignature) != 0) {
delete barInfo->icon; FetchAppIcon(barInfo);
barInfo->icon = new BBitmap(IconRect(), kIconColorSpace);
FetchAppIcon(barInfo->sig, barInfo->icon);
} }
} }
} }
@@ -886,26 +884,40 @@ TBarApp::QuitPreferencesWindow()
void void
TBarApp::FetchAppIcon(const char* signature, BBitmap* icon) TBarApp::FetchAppIcon(BarTeamInfo* barInfo)
{ {
app_info appInfo; int32 width = IconSize();
icon_size size = icon->Bounds().IntegerHeight() >= 31 int32 index = (width - kMinimumIconSize) / kIconSizeInterval;
? B_LARGE_ICON : B_MINI_ICON;
if (be_roster->GetAppInfo(signature, &appInfo) == B_OK) { // first look in the icon cache
barInfo->icon = barInfo->iconCache[index];
if (barInfo->icon != NULL)
return;
// icon wasn't in cache, get it from be_roster and cache it
app_info appInfo;
icon_size size = width >= 31 ? B_LARGE_ICON : B_MINI_ICON;
BBitmap* icon = new BBitmap(IconRect(), kIconColorSpace);
if (be_roster->GetAppInfo(barInfo->sig, &appInfo) == B_OK) {
// fetch the app icon // fetch the app icon
BFile file(&appInfo.ref, B_READ_ONLY); BFile file(&appInfo.ref, B_READ_ONLY);
BAppFileInfo appMime(&file); BAppFileInfo appMime(&file);
if (appMime.GetIcon(icon, size) == B_OK) if (appMime.GetIcon(icon, size) == B_OK) {
delete barInfo->iconCache[index];
barInfo->iconCache[index] = barInfo->icon = icon;
return; return;
}
} }
// couldn't find the app icon // couldn't find the app icon
// fetch the generic 3 boxes icon // fetch the generic 3 boxes icon and cache it
BMimeType defaultAppMime; BMimeType defaultAppMime;
defaultAppMime.SetTo(B_APP_MIME_TYPE); defaultAppMime.SetTo(B_APP_MIME_TYPE);
if (defaultAppMime.GetIcon(icon, size) == B_OK) if (defaultAppMime.GetIcon(icon, size) == B_OK) {
delete barInfo->iconCache[index];
barInfo->iconCache[index] = barInfo->icon = icon;
return; return;
}
// couldn't find generic 3 boxes icon // couldn't find generic 3 boxes icon
// fill with transparent // fill with transparent
@@ -923,6 +935,9 @@ TBarApp::FetchAppIcon(const char* signature, BBitmap* icon)
for (int32 i = 0; i < icon->BitsLength(); i++) for (int32 i = 0; i < icon->BitsLength(); i++)
iconBits[i] = B_TRANSPARENT_MAGIC_CMAP8; iconBits[i] = B_TRANSPARENT_MAGIC_CMAP8;
} }
delete barInfo->iconCache[index];
barInfo->iconCache[index] = NULL;
} }
@@ -945,6 +960,8 @@ BarTeamInfo::BarTeamInfo(BList* teams, uint32 flags, char* sig, BBitmap* icon,
icon(icon), icon(icon),
name(name) name(name)
{ {
for (int32 i = 0; i < kIconCacheCount; i++)
iconCache[i] = NULL;
} }
@@ -955,6 +972,8 @@ BarTeamInfo::BarTeamInfo(const BarTeamInfo &info)
icon(new BBitmap(*info.icon)), icon(new BBitmap(*info.icon)),
name(strdup(info.name)) name(strdup(info.name))
{ {
for (int32 i = 0; i < kIconCacheCount; i++)
iconCache[i] = NULL;
} }
@@ -962,6 +981,7 @@ BarTeamInfo::~BarTeamInfo()
{ {
delete teams; delete teams;
free(sig); free(sig);
delete icon;
free(name); free(name);
for (int32 i = 0; i < kIconCacheCount; i++)
delete iconCache[i];
} }
+5 -3
View File
@@ -71,15 +71,17 @@ const uint32 kSuspendSystem = 304;
const int32 kMinimumIconSize = 16; const int32 kMinimumIconSize = 16;
const int32 kMaximumIconSize = 96; const int32 kMaximumIconSize = 96;
const int32 kIconSizeInterval = 8; const int32 kIconSizeInterval = 8;
const int32 kIconCacheCount = (kMaximumIconSize - kMinimumIconSize)
/ kIconSizeInterval + 1;
// update preferences message constant // update preferences message constant
const uint32 kUpdatePreferences = 'Pref'; const uint32 kUpdatePreferences = 'Pref';
/* --------------------------------------------- */ /* --------------------------------------------- */
class BBitmap;
class BFile; class BFile;
class BList; class BList;
class BBitmap;
class PreferencesWindow; class PreferencesWindow;
class TBarView; class TBarView;
class TBarWindow; class TBarWindow;
@@ -96,6 +98,7 @@ public:
char* sig; char* sig;
BBitmap* icon; BBitmap* icon;
char* name; char* name;
BBitmap* iconCache[kIconCacheCount];
}; };
class TBarApp : public BApplication { class TBarApp : public BApplication {
@@ -133,8 +136,7 @@ private:
void QuitPreferencesWindow(); void QuitPreferencesWindow();
void ResizeTeamIcons(); void ResizeTeamIcons();
void FetchAppIcon(const char* signature, void FetchAppIcon(BarTeamInfo* barInfo);
BBitmap* icon);
BRect IconRect(); BRect IconRect();
-7
View File
@@ -520,14 +520,7 @@ TExpandoMenuBar::BuildItems()
barInfo->name, barInfo->sig, itemWidth, itemHeight, barInfo->name, barInfo->sig, itemWidth, itemHeight,
fDrawLabel, fVertical)); fDrawLabel, fVertical));
} }
barInfo->teams = NULL;
barInfo->icon = NULL;
barInfo->name = NULL;
barInfo->sig = NULL;
} }
delete barInfo;
} }
if (CountItems() == 0) { if (CountItems() == 0) {
-6
View File
@@ -108,13 +108,7 @@ TTeamMenu::AttachedToWindow()
menu->SetTrackingHook(barview->MenuTrackingHook, menu->SetTrackingHook(barview->MenuTrackingHook,
barview->GetTrackingHookData()); barview->GetTrackingHookData());
} }
barInfo->teams = NULL;
barInfo->icon = NULL;
barInfo->name = NULL;
barInfo->sig = NULL;
} }
delete barInfo;
} }
if (CountItems() == 0) { if (CountItems() == 0) {