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:
parent
c844f6e030
commit
e13f5676a0
@ -719,6 +719,12 @@ TBarApp::Unsubscribe(const BMessenger &subscriber)
|
||||
void
|
||||
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);
|
||||
if (!autolock.IsLocked())
|
||||
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),
|
||||
new BBitmap(IconRect(), kIconColorSpace), strdup(name.String()));
|
||||
|
||||
if ((barInfo->flags & B_BACKGROUND_APP) == 0
|
||||
&& strcasecmp(barInfo->sig, kDeskbarSignature) != 0) {
|
||||
FetchAppIcon(barInfo->sig, barInfo->icon);
|
||||
}
|
||||
|
||||
NULL, strdup(name.String()));
|
||||
FetchAppIcon(barInfo);
|
||||
barInfo->teams->AddItem((void*)(addr_t)team);
|
||||
|
||||
sBarTeamInfoList.AddItem(barInfo);
|
||||
|
||||
if (fSettings.expandNewTeams)
|
||||
@ -839,9 +839,7 @@ TBarApp::ResizeTeamIcons()
|
||||
BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i);
|
||||
if ((barInfo->flags & B_BACKGROUND_APP) == 0
|
||||
&& strcasecmp(barInfo->sig, kDeskbarSignature) != 0) {
|
||||
delete barInfo->icon;
|
||||
barInfo->icon = new BBitmap(IconRect(), kIconColorSpace);
|
||||
FetchAppIcon(barInfo->sig, barInfo->icon);
|
||||
FetchAppIcon(barInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -886,26 +884,40 @@ TBarApp::QuitPreferencesWindow()
|
||||
|
||||
|
||||
void
|
||||
TBarApp::FetchAppIcon(const char* signature, BBitmap* icon)
|
||||
TBarApp::FetchAppIcon(BarTeamInfo* barInfo)
|
||||
{
|
||||
app_info appInfo;
|
||||
icon_size size = icon->Bounds().IntegerHeight() >= 31
|
||||
? B_LARGE_ICON : B_MINI_ICON;
|
||||
int32 width = IconSize();
|
||||
int32 index = (width - kMinimumIconSize) / kIconSizeInterval;
|
||||
|
||||
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
|
||||
BFile file(&appInfo.ref, B_READ_ONLY);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// couldn't find the app icon
|
||||
// fetch the generic 3 boxes icon
|
||||
// fetch the generic 3 boxes icon and cache it
|
||||
BMimeType defaultAppMime;
|
||||
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;
|
||||
}
|
||||
|
||||
// couldn't find generic 3 boxes icon
|
||||
// fill with transparent
|
||||
@ -923,6 +935,9 @@ TBarApp::FetchAppIcon(const char* signature, BBitmap* icon)
|
||||
for (int32 i = 0; i < icon->BitsLength(); i++)
|
||||
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),
|
||||
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)),
|
||||
name(strdup(info.name))
|
||||
{
|
||||
for (int32 i = 0; i < kIconCacheCount; i++)
|
||||
iconCache[i] = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -962,6 +981,7 @@ BarTeamInfo::~BarTeamInfo()
|
||||
{
|
||||
delete teams;
|
||||
free(sig);
|
||||
delete icon;
|
||||
free(name);
|
||||
for (int32 i = 0; i < kIconCacheCount; i++)
|
||||
delete iconCache[i];
|
||||
}
|
||||
|
@ -71,15 +71,17 @@ const uint32 kSuspendSystem = 304;
|
||||
const int32 kMinimumIconSize = 16;
|
||||
const int32 kMaximumIconSize = 96;
|
||||
const int32 kIconSizeInterval = 8;
|
||||
const int32 kIconCacheCount = (kMaximumIconSize - kMinimumIconSize)
|
||||
/ kIconSizeInterval + 1;
|
||||
|
||||
// update preferences message constant
|
||||
const uint32 kUpdatePreferences = 'Pref';
|
||||
|
||||
/* --------------------------------------------- */
|
||||
|
||||
class BBitmap;
|
||||
class BFile;
|
||||
class BList;
|
||||
class BBitmap;
|
||||
class PreferencesWindow;
|
||||
class TBarView;
|
||||
class TBarWindow;
|
||||
@ -96,6 +98,7 @@ public:
|
||||
char* sig;
|
||||
BBitmap* icon;
|
||||
char* name;
|
||||
BBitmap* iconCache[kIconCacheCount];
|
||||
};
|
||||
|
||||
class TBarApp : public BApplication {
|
||||
@ -133,8 +136,7 @@ private:
|
||||
void QuitPreferencesWindow();
|
||||
|
||||
void ResizeTeamIcons();
|
||||
void FetchAppIcon(const char* signature,
|
||||
BBitmap* icon);
|
||||
void FetchAppIcon(BarTeamInfo* barInfo);
|
||||
|
||||
BRect IconRect();
|
||||
|
||||
|
@ -520,14 +520,7 @@ TExpandoMenuBar::BuildItems()
|
||||
barInfo->name, barInfo->sig, itemWidth, itemHeight,
|
||||
fDrawLabel, fVertical));
|
||||
}
|
||||
|
||||
barInfo->teams = NULL;
|
||||
barInfo->icon = NULL;
|
||||
barInfo->name = NULL;
|
||||
barInfo->sig = NULL;
|
||||
}
|
||||
|
||||
delete barInfo;
|
||||
}
|
||||
|
||||
if (CountItems() == 0) {
|
||||
|
@ -108,13 +108,7 @@ TTeamMenu::AttachedToWindow()
|
||||
menu->SetTrackingHook(barview->MenuTrackingHook,
|
||||
barview->GetTrackingHookData());
|
||||
}
|
||||
|
||||
barInfo->teams = NULL;
|
||||
barInfo->icon = NULL;
|
||||
barInfo->name = NULL;
|
||||
barInfo->sig = NULL;
|
||||
}
|
||||
delete barInfo;
|
||||
}
|
||||
|
||||
if (CountItems() == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user