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:
+40
-20
@@ -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];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user