diff options
author | Dianne Hackborn <hackbod@google.com> | 2009-07-06 11:07:40 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2009-07-06 11:12:37 -0700 |
commit | 78c405178c57bb45e40f1e2839d6a18d91f7f02c (patch) | |
tree | 6e7137f628b8fff1f72c59e5e42f3f4878e0bb39 /libs/utils/AssetManager.cpp | |
parent | ef1f21b34f5624adb7436d3da927660ed16c97c7 (diff) | |
download | frameworks_base-78c405178c57bb45e40f1e2839d6a18d91f7f02c.zip frameworks_base-78c405178c57bb45e40f1e2839d6a18d91f7f02c.tar.gz frameworks_base-78c405178c57bb45e40f1e2839d6a18d91f7f02c.tar.bz2 |
Don't re-parse the framework resources all the time.
A small optimization to the resource code, to not re-parse the framework
resources every time we build a new AssetManager. Instead, you can now
construct a ResTable from a previously created one... of course, like the
existing code for using the data in-place, you can't delete the original
ResTable until you have deleted the one that has been constructed from it.
Diffstat (limited to 'libs/utils/AssetManager.cpp')
-rw-r--r-- | libs/utils/AssetManager.cpp | 97 |
1 files changed, 83 insertions, 14 deletions
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp index 4126bfb..5a05e6a 100644 --- a/libs/utils/AssetManager.cpp +++ b/libs/utils/AssetManager.cpp @@ -395,21 +395,41 @@ const ResTable* AssetManager::getResTable(bool required) const const size_t N = mAssetPaths.size(); for (size_t i=0; i<N; i++) { Asset* ass = NULL; + ResTable* sharedRes = NULL; bool shared = true; const asset_path& ap = mAssetPaths.itemAt(i); LOGV("Looking for resource asset in '%s'\n", ap.path.string()); if (ap.type != kFileTypeDirectory) { - ass = const_cast<AssetManager*>(this)-> - mZipSet.getZipResourceTable(ap.path); - if (ass == NULL) { - LOGV("loading resource table %s\n", ap.path.string()); + if (i == 0) { + // The first item is typically the framework resources, + // which we want to avoid parsing every time. + sharedRes = const_cast<AssetManager*>(this)-> + mZipSet.getZipResourceTable(ap.path); + } + if (sharedRes == NULL) { ass = const_cast<AssetManager*>(this)-> - openNonAssetInPathLocked("resources.arsc", - Asset::ACCESS_BUFFER, - ap); - if (ass != NULL && ass != kExcludedAsset) { + mZipSet.getZipResourceTableAsset(ap.path); + if (ass == NULL) { + LOGV("loading resource table %s\n", ap.path.string()); ass = const_cast<AssetManager*>(this)-> - mZipSet.setZipResourceTable(ap.path, ass); + openNonAssetInPathLocked("resources.arsc", + Asset::ACCESS_BUFFER, + ap); + if (ass != NULL && ass != kExcludedAsset) { + ass = const_cast<AssetManager*>(this)-> + mZipSet.setZipResourceTableAsset(ap.path, ass); + } + } + + if (i == 0 && ass != NULL) { + // If this is the first resource table in the asset + // manager, then we are going to cache it so that we + // can quickly copy it out for others. + LOGV("Creating shared resources for %s", ap.path.string()); + sharedRes = new ResTable(); + sharedRes->add(ass, (void*)(i+1), false); + sharedRes = const_cast<AssetManager*>(this)-> + mZipSet.setZipResourceTable(ap.path, sharedRes); } } } else { @@ -420,13 +440,19 @@ const ResTable* AssetManager::getResTable(bool required) const ap); shared = false; } - if (ass != NULL && ass != kExcludedAsset) { + if ((ass != NULL || sharedRes != NULL) && ass != kExcludedAsset) { if (rt == NULL) { mResources = rt = new ResTable(); updateResourceParamsLocked(); } LOGV("Installing resource asset %p in to table %p\n", ass, mResources); - rt->add(ass, (void*)(i+1), !shared); + if (sharedRes != NULL) { + LOGV("Copying existing resources for %s", ap.path.string()); + rt->add(sharedRes); + } else { + LOGV("Parsing resources for %s", ap.path.string()); + rt->add(ass, (void*)(i+1), !shared); + } if (!shared) { delete ass; @@ -1510,7 +1536,8 @@ Mutex AssetManager::SharedZip::gLock; DefaultKeyedVector<String8, wp<AssetManager::SharedZip> > AssetManager::SharedZip::gOpen; AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen) - : mPath(path), mZipFile(NULL), mModWhen(modWhen), mResourceTableAsset(NULL) + : mPath(path), mZipFile(NULL), mModWhen(modWhen), + mResourceTableAsset(NULL), mResourceTable(NULL) { //LOGI("Creating SharedZip %p %s\n", this, (const char*)mPath); mZipFile = new ZipFileRO; @@ -1563,6 +1590,25 @@ Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset) return mResourceTableAsset; } +ResTable* AssetManager::SharedZip::getResourceTable() +{ + LOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable); + return mResourceTable; +} + +ResTable* AssetManager::SharedZip::setResourceTable(ResTable* res) +{ + { + AutoMutex _l(gLock); + if (mResourceTable == NULL) { + mResourceTable = res; + return res; + } + } + delete res; + return mResourceTable; +} + bool AssetManager::SharedZip::isUpToDate() { time_t modWhen = getFileModDate(mPath.string()); @@ -1572,6 +1618,9 @@ bool AssetManager::SharedZip::isUpToDate() AssetManager::SharedZip::~SharedZip() { //LOGI("Destroying SharedZip %p %s\n", this, (const char*)mPath); + if (mResourceTable != NULL) { + delete mResourceTable; + } if (mResourceTableAsset != NULL) { delete mResourceTableAsset; } @@ -1627,7 +1676,7 @@ ZipFileRO* AssetManager::ZipSet::getZip(const String8& path) return zip->getZip(); } -Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path) +Asset* AssetManager::ZipSet::getZipResourceTableAsset(const String8& path) { int idx = getIndex(path); sp<SharedZip> zip = mZipFile[idx]; @@ -1638,7 +1687,7 @@ Asset* AssetManager::ZipSet::getZipResourceTable(const String8& path) return zip->getResourceTableAsset(); } -Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path, +Asset* AssetManager::ZipSet::setZipResourceTableAsset(const String8& path, Asset* asset) { int idx = getIndex(path); @@ -1647,6 +1696,26 @@ Asset* AssetManager::ZipSet::setZipResourceTable(const String8& path, return zip->setResourceTableAsset(asset); } +ResTable* AssetManager::ZipSet::getZipResourceTable(const String8& path) +{ + int idx = getIndex(path); + sp<SharedZip> zip = mZipFile[idx]; + if (zip == NULL) { + zip = SharedZip::get(path); + mZipFile.editItemAt(idx) = zip; + } + return zip->getResourceTable(); +} + +ResTable* AssetManager::ZipSet::setZipResourceTable(const String8& path, + ResTable* res) +{ + int idx = getIndex(path); + sp<SharedZip> zip = mZipFile[idx]; + // doesn't make sense to call before previously accessing. + return zip->setResourceTable(res); +} + /* * Generate the partial pathname for the specified archive. The caller * gets to prepend the asset root directory. |