void LLViewerTextureList::doPrefetchImages() { if (LLAppViewer::instance()->getPurgeCache()) { // cache was purged, no point return; } // Pre-fetch textures from last logout LLSD imagelist; std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, get_texture_list_name()); llifstream file; file.open(filename); if (file.is_open()) { LLSDSerialize::fromXML(imagelist, file); } for (LLSD::array_iterator iter = imagelist.beginArray(); iter != imagelist.endArray(); ++iter) { LLSD imagesd = *iter; LLUUID uuid = imagesd["uuid"]; S32 pixel_area = imagesd["area"]; S32 texture_type = imagesd["type"]; if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type) { LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, texture_type); if (image) { image->addTextureStats((F32)pixel_area); } } } }
void LocalAssetBrowser::DelBitmap( std::vector<LLScrollListItem*> delete_vector, S32 column ) { bool change_happened = false; for( std::vector<LLScrollListItem*>::iterator list_iter = delete_vector.begin(); list_iter != delete_vector.end(); list_iter++ ) { LLScrollListItem* list_item = *list_iter; if ( list_item ) { LLUUID id = list_item->getColumn(column)->getValue().asUUID(); for (local_list_iter iter = loaded_bitmaps.begin(); iter != loaded_bitmaps.end();) { if ((*iter).getID() == id) { LLViewerFetchedTexture* image = gTextureList.findImage(id); gTextureList.deleteImage( image ); image->unref(); iter = loaded_bitmaps.erase(iter); change_happened = true; } else ++iter; } } } if (change_happened) onChangeHappened(); }
F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time) { if (gNoRender || gGLManager.mIsDisabled) return 0.0f; // // Create GL textures for all textures that need them (images which have been // decoded, but haven't been pushed into GL). // LLFastTimer t(LLFastTimer::FTM_IMAGE_CREATE); LLTimer create_timer; image_list_t::iterator enditer = mCreateTextureList.begin(); for (image_list_t::iterator iter = mCreateTextureList.begin(); iter != mCreateTextureList.end();) { image_list_t::iterator curiter = iter++; enditer = iter; LLViewerFetchedTexture *imagep = *curiter; imagep->createTexture(); if (create_timer.getElapsedTimeF32() > max_time) { break; } } mCreateTextureList.erase(mCreateTextureList.begin(), enditer); return create_timer.getElapsedTimeF32(); }
/* [maintenence functions] */ void LocalBitmap::updateSelf() { if ( this->linkstatus == LINK_ON || this->linkstatus == LINK_UPDATING ) { /* making sure file still exists */ if ( !gDirUtilp->fileExists(this->filename) ) { this->linkstatus = LINK_BROKEN; return; } /* exists, let's check if it's lastmod has changed */ llstat temp_stat; LLFile::stat(this->filename, &temp_stat); std::time_t temp_time = temp_stat.st_mtime; LLSD new_last_modified = asctime( localtime(&temp_time) ); if ( this->last_modified.asString() == new_last_modified.asString() ) { return; } /* here we update the image */ LLImageRaw* new_imgraw = new LLImageRaw(); if ( !decodeSelf(new_imgraw) ) { this->linkstatus = LINK_UPDATING; return; } else { this->linkstatus = LINK_ON; } LLViewerFetchedTexture* image = gTextureList.findImage(this->id); if (!image->forSculpt()) { image->createGLTexture( LOCAL_DISCARD_LEVEL, new_imgraw ); } else { image->setCachedRawImage(-1,new_imgraw); } /* finalizing by updating lastmod to current */ this->last_modified = new_last_modified; /* setting unit property to reflect that it has been changed */ switch (this->bitmap_type) { case TYPE_TEXTURE: { break; } case TYPE_SCULPT: { /* sets a bool to run through all visible sculpts in one go, and update the ones necessary. */ this->sculpt_dirty = true; this->volume_dirty = true; gLocalBrowser->setSculptUpdated( true ); break; } case TYPE_LAYER: { /* sets a bool to rebake layers after the iteration is done with */ gLocalBrowser->setLayerUpdated( true ); break; } default: { break; } } } }
void LLViewerTextureList::updateImages(F32 max_time) { LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); S32 global_raw_memory; { global_raw_memory = *AIAccess<S32>(LLImageRaw::sGlobalRawMemory); } sNumImagesStat.addValue(sNumImages); sNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); sGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes)); sGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes)); sRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(global_raw_memory)); sFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); updateImagesDecodePriorities(); F32 total_max_time = max_time; max_time -= updateImagesFetchTextures(max_time); max_time = llmax(max_time, total_max_time*.50f); // at least 50% of max_time max_time -= updateImagesCreateTextures(max_time); if (!mDirtyTextureList.empty()) { LLFastTimer t(LLFastTimer::FTM_IMAGE_MARK_DIRTY); gPipeline.dirtyPoolObjectTextures(mDirtyTextureList); mDirtyTextureList.clear(); } bool didone = false; for (image_list_t::iterator iter = mCallbackList.begin(); iter != mCallbackList.end(); ) { //trigger loaded callbacks on local textures immediately LLViewerFetchedTexture* image = *iter++; if (!image->getUrl().empty()) { // Do stuff to handle callbacks, update priorities, etc. didone = image->doLoadedCallbacks(); } else if (!didone) { // Do stuff to handle callbacks, update priorities, etc. didone = image->doLoadedCallbacks(); } } //Required for old media system if (!gNoRender && !gGLManager.mIsDisabled) { LLViewerMedia::updateMedia(); } updateImagesUpdateStats(); }
void LLTextureCtrl::setImageAssetName(const std::string& name) { LLPointer<LLUIImage> imagep = LLUI::getUIImage(name); if(imagep) { LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get()); if(pTexture) { LLUUID id = pTexture->getID(); setImageAssetID(id); } } }
void LLViewerTextureList::updateImagesUpdateStats() { if (mUpdateStats && mForceResetTextureStats) { for (image_priority_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; imagep->resetTextureStats(); } mUpdateStats = FALSE; mForceResetTextureStats = FALSE; } }
//static BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel) { //Note: texture atlas does not support bump texture now. LLViewerFetchedTexture* tex = LLViewerTextureManager::staticCastToFetchedTexture(texture) ; if(!tex) { //if the texture is not a fetched texture return FALSE; } LLViewerTexture* bump = NULL; switch( bump_code ) { case BE_NO_BUMP: break; case BE_BRIGHTNESS: case BE_DARKNESS: bump = gBumpImageList.getBrightnessDarknessImage( tex, bump_code ); break; default: if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) { bump = gStandardBumpmapList[bump_code].mImage; gBumpImageList.addTextureStats(bump_code, tex->getID(), vsize); } break; } if (bump) { if (channel == -2) { gGL.getTexUnit(1)->bind(bump); gGL.getTexUnit(0)->bind(bump); } else { gGL.getTexUnit(channel)->bind(bump); } return TRUE; } return FALSE; }
// virtual LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp ) { // suppress texlayerset updates while wearables are being imported. Layersets will be updated // when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed. LLOverrideBakedTextureUpdate stop_bakes(false); LLWearable::EImportResult result = LLWearable::importStream(input_stream, avatarp); if (LLWearable::FAILURE == result) return result; if (LLWearable::BAD_HEADER == result) { // Shouldn't really log the asset id for security reasons, but // we need it in this case. llwarns << "Bad Wearable asset header: " << mAssetID << llendl; //gVFS->dumpMap(); return result; } LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN ); LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN ); te_map_t::const_iterator iter = mTEMap.begin(); te_map_t::const_iterator end = mTEMap.end(); for (; iter != end; ++iter) { S32 te = iter->first; LLLocalTextureObject* lto = iter->second; LLUUID textureid = LLUUID::null; if (lto) { textureid = lto->getID(); } LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( textureid ); if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) { image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(textureid, (LLAvatarAppearanceDefines::ETextureIndex)te), NULL); } } return result; }
// static void LLInventoryBackup::download(LLInventoryItem* item, LLFloater* floater, loaded_callback_func onImage, LLGetAssetCallback onAsset) { LLInventoryBackup::callbackdata* userdata = new LLInventoryBackup::callbackdata(); userdata->floater = floater; userdata->item = item; LLViewerFetchedTexture* imagep; switch(item->getType()) { case LLAssetType::AT_TEXTURE: imagep = LLViewerTextureManager::getFetchedTexture(item->getAssetUUID(), MIPMAP_TRUE, LLViewerTexture::BOOST_UI); imagep->setLoadedCallback( onImage, 0, TRUE, FALSE, userdata, NULL ); // was setLoadedCallbackNoAuth break; case LLAssetType::AT_NOTECARD: case LLAssetType::AT_SCRIPT: case LLAssetType::AT_LSL_TEXT: // normal script download case LLAssetType::AT_LSL_BYTECODE: gAssetStorage->getInvItemAsset(LLHost::invalid, gAgent.getID(), gAgent.getSessionID(), item->getPermissions().getOwner(), LLUUID::null, item->getUUID(), item->getAssetUUID(), item->getType(), onAsset, userdata, // user_data TRUE); break; case LLAssetType::AT_SOUND: case LLAssetType::AT_CLOTHING: case LLAssetType::AT_BODYPART: case LLAssetType::AT_ANIMATION: case LLAssetType::AT_GESTURE: default: gAssetStorage->getAssetData(item->getAssetUUID(), item->getType(), onAsset, userdata, TRUE); break; } }
void LLViewerTextureList::doPreloadImages() { LL_DEBUGS("ViewerImages") << "Preloading images..." << LL_ENDL; // Set the "missing asset" image LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI); // Set the "white" image LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI); LLUIImageList* image_list = LLUIImageList::getInstance(); image_list->initFromFile(); // turn off clamping and bilinear filtering for uv picking images //LLViewerFetchedTexture* uv_test = preloadUIImage("uv_test1.tga", LLUUID::null, FALSE); //uv_test->setClamp(FALSE, FALSE); //uv_test->setMipFilterNearest(TRUE, TRUE); //uv_test = preloadUIImage("uv_test2.tga", LLUUID::null, FALSE); //uv_test->setClamp(FALSE, FALSE); //uv_test->setMipFilterNearest(TRUE, TRUE); // prefetch specific UUIDs LLViewerTextureManager::getFetchedTexture(IMG_SHOT, TRUE); LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF, TRUE); LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); if (image) { image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); if (image) { image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); if (image) { image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); if (image) { image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, 0,0,LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903")); if (image) { image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } }
void LLPanelClassifiedInfo::stretchSnapshot() { // *NOTE dzaporozhan // Could be moved to LLTextureCtrl LLViewerFetchedTexture* texture = mSnapshotCtrl->getTexture(); if(!texture) { return; } if(0 == texture->getOriginalWidth() || 0 == texture->getOriginalHeight()) { // looks like texture is not loaded yet return; } LLRect rc = mSnapshotRect; // *HACK dzaporozhan // LLTextureCtrl uses BTN_HEIGHT_SMALL as bottom for texture which causes // drawn texture to be smaller than expected. (see LLTextureCtrl::draw()) // Lets increase texture height to force texture look as expected. rc.mBottom -= BTN_HEIGHT_SMALL; F32 t_width = texture->getFullWidth(); F32 t_height = texture->getFullHeight(); F32 ratio = llmin<F32>( (rc.getWidth() / t_width), (rc.getHeight() / t_height) ); t_width *= ratio; t_height *= ratio; rc.setCenterAndSize(rc.getCenterX(), rc.getCenterY(), llfloor(t_width), llfloor(t_height)); mSnapshotCtrl->setShape(rc); mSnapshotStreched = true; }
void LLViewerTextureList::dump() { llinfos << "LLViewerTextureList::dump()" << llendl; for (image_priority_list_t::iterator it = mImageList.begin(); it != mImageList.end(); ++it) { LLViewerFetchedTexture* image = *it; llinfos << "priority " << image->getDecodePriority() << " boost " << image->getBoostLevel() << " size " << image->getWidth() << "x" << image->getHeight() << " discard " << image->getDiscardLevel() << " desired " << image->getDesiredDiscardLevel() << " http://asset.siva.lindenlab.com/" << image->getID() << ".texture" << llendl; } }
void LLLocalBitmapBrowser::delBitmap( std::vector<LLScrollListItem*> delete_vector, S32 column ) { bool change_happened = false; for( std::vector<LLScrollListItem*>::iterator list_iter = delete_vector.begin(); list_iter != delete_vector.end(); list_iter++ ) { LLScrollListItem* list_item = *list_iter; if ( list_item ) { LLUUID id = list_item->getColumn(column)->getValue().asUUID(); for (local_list_iter iter = sLoadedBitmaps.begin(); iter != sLoadedBitmaps.end();) { LLLocalBitmap* unit = (*iter)->getThis(); if ( unit->getID() == id ) { LLViewerFetchedTexture* image = gTextureList.findImage(id); gTextureList.deleteImage( image ); image->unref(); iter = sLoadedBitmaps.erase(iter); delete unit; unit = NULL; change_happened = true; } else { iter++; } } } } if ( change_happened ) { onChangeHappened(); } }
void LLViewerTextureList::decodeAllImages(F32 max_time) { LLTimer timer; if(gNoRender) return; // Update texture stats and priorities std::vector<LLPointer<LLViewerFetchedTexture> > image_list; for (image_priority_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; image_list.push_back(imagep); imagep->setInImageList(FALSE) ; } mImageList.clear(); for (std::vector<LLPointer<LLViewerFetchedTexture> >::iterator iter = image_list.begin(); iter != image_list.end(); ++iter) { LLViewerFetchedTexture* imagep = *iter; imagep->processTextureStats(); F32 decode_priority = imagep->calcDecodePriority(); imagep->setDecodePriority(decode_priority); mImageList.insert(imagep); imagep->setInImageList(TRUE) ; } image_list.clear(); // Update fetch (decode) for (image_priority_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; imagep->updateFetch(); } // Run threads S32 fetch_pending = 0; while (1) { LLAppViewer::instance()->getTextureCache()->update(1); // unpauses the texture cache thread LLAppViewer::instance()->getImageDecodeThread()->update(1); // unpauses the image thread fetch_pending = LLAppViewer::instance()->getTextureFetch()->update(1); // unpauses the texture fetch thread if (fetch_pending == 0 || timer.getElapsedTimeF32() > max_time) { break; } } // Update fetch again for (image_priority_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ) { LLViewerFetchedTexture* imagep = *iter++; imagep->updateFetch(); } max_time -= timer.getElapsedTimeF32(); max_time = llmax(max_time, .001f); F32 create_time = updateImagesCreateTextures(max_time); LL_DEBUGS("ViewerImages") << "decodeAllImages() took " << timer.getElapsedTimeF32() << " seconds. " << " fetch_pending " << fetch_pending << " create_time " << create_time << LL_ENDL; }
F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { LLTimer image_op_timer; // Update the decode priority for N images each frame // Make a list with 32 high priority entries + 256 cycled entries const size_t max_priority_count = llmin((S32) (256*10.f*gFrameIntervalSeconds)+1, 32); const size_t max_update_count = llmin((S32) (1024*10.f*gFrameIntervalSeconds)+1, 256); // 32 high priority entries typedef std::vector<LLViewerFetchedTexture*> entries_list_t; entries_list_t entries; size_t update_counter = llmin(max_priority_count, mImageList.size()); image_priority_list_t::iterator iter1 = mImageList.begin(); while(update_counter > 0) { entries.push_back(*iter1); ++iter1; update_counter--; } // 256 cycled entries update_counter = llmin(max_update_count, mUUIDMap.size()); if(update_counter > 0) { uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchUUID); uuid_map_t::iterator iter2p = iter2; while(update_counter > 0) { if (iter2 == mUUIDMap.end()) { iter2 = mUUIDMap.begin(); } entries.push_back(iter2->second); iter2p = iter2++; update_counter--; } mLastFetchUUID = iter2p->first; } S32 fetch_count = 0; S32 min_count = max_priority_count + max_update_count/4; for (entries_list_t::iterator iter3 = entries.begin(); iter3 != entries.end(); ) { LLViewerFetchedTexture* imagep = *iter3++; bool fetching = imagep->updateFetch(); if (fetching) { fetch_count++; } if (min_count <= 0 && image_op_timer.getElapsedTimeF32() > max_time) { break; } min_count--; } //if (fetch_count == 0) //{ // gDebugTimers[0].pause(); //} //else //{ // gDebugTimers[0].unpause(); //} return image_op_timer.getElapsedTimeF32(); }
void LLObjectBackup::exportNextTexture() { LLUUID id; textures_set_t::iterator iter = mTexturesList.begin(); while (true) { if (mTexturesList.empty()) { mCheckNextTexture = true; LL_INFOS() << "Finished exporting textures." << LL_ENDL; return; } if (iter == mTexturesList.end()) { // Not yet ready, wait and re-check at next idle callback... mCheckNextTexture = true; return; } id = *iter++; if (id.isNull()) { // NULL texture id: just remove and ignore. mTexturesList.erase(id); LL_DEBUGS("ObjectBackup") << "Null texture UUID found, ignoring." << LL_ENDL; continue; } LLViewerTexture* imagep = LLViewerTextureManager::findTexture(id); if (imagep) { if (imagep->getDiscardLevel() > 0) { // Boost texture loading imagep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); LL_DEBUGS("ObjectBackup") << "Boosting texture: " << id << LL_ENDL; LLViewerFetchedTexture* tex; tex = LLViewerTextureManager::staticCastToFetchedTexture(imagep); if (tex && tex->getDesiredDiscardLevel() > 0) { // Set min discard level to 0 tex->setMinDiscardLevel(0); LL_DEBUGS("ObjectBackup") << "Min discard level set to 0 for texture: " << id << LL_ENDL; } } else { // Texture is ready ! break; } } else { LL_WARNS() << "We *DON'T* have the texture " << id << LL_ENDL; mNonExportedTextures |= TEXTURE_MISSING; mTexturesList.erase(id); } } mTexturesList.erase(id); LL_INFOS() << "Requesting texture " << id << " from cache." << LL_ENDL; LLImageJ2C* mFormattedImage = new LLImageJ2C; BackupCacheReadResponder* responder; responder = new BackupCacheReadResponder(id, mFormattedImage); LLAppViewer::getTextureCache()->readFromCache(id, LLWorkerThread::PRIORITY_HIGH, 0, 999999, responder); }
/* [maintenence functions] */ void LLLocalBitmap::updateSelf() { if ( this->mLinkStatus == LS_ON || this->mLinkStatus == LS_UPDATING ) { /* making sure file still exists */ if ( !gDirUtilp->fileExists(this->mFilename) ) { this->mLinkStatus = LS_BROKEN; LLFloaterLocalBitmapBrowser::updateRightSide(); return; } /* exists, let's check if it's lastmod has changed */ const std::time_t temp_time = boost::filesystem::last_write_time( boost::filesystem::path( this->mFilename ) ); LLSD new_last_modified = asctime( localtime(&temp_time) ); if ( this->mLastModified.asString() == new_last_modified.asString() ) { return; } /* here we update the image */ LLImageRaw* new_imgraw = new LLImageRaw(); if ( !decodeSelf(new_imgraw) ) { this->mLinkStatus = LS_UPDATING; return; } else { this->mLinkStatus = LS_ON; } LLViewerFetchedTexture* image = gTextureList.findImage(this->mId); // here was a check if isForSculptOnly, but it appears the function is broken. image->createGLTexture( LOCAL_DISCARD_LEVEL, new_imgraw ); image->setCachedRawImage( LOCAL_DISCARD_LEVEL, new_imgraw ); /* finalizing by updating lastmod to current */ this->mLastModified = new_last_modified; /* setting unit property to reflect that it has been changed */ switch (this->mBitmapType) { case BT_TEXTURE: { break; } case BT_SCULPT: { /* sets a bool to run through all visible sculpts in one go, and update the ones necessary. */ this->mSculptDirty = true; this->mVolumeDirty = true; gLocalBrowser->setSculptUpdated( true ); break; } case BT_LAYER: { /* sets a bool to rebake layers after the iteration is done with */ gLocalBrowser->setLayerUpdated( true ); break; } default: { break; } } } }
void LLViewerTextureList::shutdown() { // clear out preloads mImagePreloads.clear(); // Write out list of currently loaded textures for precaching on startup typedef std::set<std::pair<S32,LLViewerFetchedTexture*> > image_area_list_t; image_area_list_t image_area_list; for (image_priority_list_t::iterator iter = mImageList.begin(); iter != mImageList.end(); ++iter) { LLViewerFetchedTexture* image = *iter; if (!image->hasGLTexture() || !image->getUseDiscard() || image->needsAux() || image->getTargetHost() != LLHost::invalid) { continue; // avoid UI, baked, and other special images } if(!image->getBoundRecently()) { continue ; } S32 desired = image->getDesiredDiscardLevel(); if (desired >= 0 && desired < MAX_DISCARD_LEVEL) { S32 pixel_area = image->getWidth(desired) * image->getHeight(desired); image_area_list.insert(std::make_pair(pixel_area, image)); } } LLSD imagelist; const S32 max_count = 1000; S32 count = 0; S32 image_type ; for (image_area_list_t::reverse_iterator riter = image_area_list.rbegin(); riter != image_area_list.rend(); ++riter) { LLViewerFetchedTexture* image = riter->second; image_type = (S32)image->getType() ; imagelist[count]["area"] = riter->first; imagelist[count]["uuid"] = image->getID(); imagelist[count]["type"] = image_type; if (++count >= max_count) break; } if (count > 0 && !gDirUtilp->getLindenUserDir(true).empty()) { std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, get_texture_list_name()); llofstream file; file.open(filename); LLSDSerialize::toPrettyXML(imagelist, file); } // // Clean up "loaded" callbacks. // mCallbackList.clear(); // Flush all of the references mLoadingStreamList.clear(); mCreateTextureList.clear(); mUUIDMap.clear(); mImageList.clear(); mInitialized = FALSE ; //prevent loading textures again. }
void FSFloaterObjectExport::onIdle() { switch(mExportState) { case IDLE: break; case INVENTORY_DOWNLOAD: if (gDisconnected) { return; } if (mInventoryRequests.empty()) { mLastRequest = mAssetRequests.size(); mWaitTimer.start(); mExportState = ASSET_DOWNLOAD; } else if (mLastRequest != mInventoryRequests.size()) { mWaitTimer.start(); mLastRequest = mInventoryRequests.size(); updateTitleProgress(INVENTORY_DOWNLOAD); } else if (mWaitTimer.getElapsedTimeF32() > MAX_INVENTORY_WAIT_TIME) { mWaitTimer.start(); for (uuid_vec_t::const_iterator iter = mInventoryRequests.begin(); iter != mInventoryRequests.end(); ++iter) { LLViewerObject* object = gObjectList.findObject((*iter)); object->dirtyInventory(); object->requestInventory(); LL_DEBUGS("export") << "re-requested inventory of " << (*iter).asString() << LL_ENDL; } } break; case ASSET_DOWNLOAD: if (gDisconnected) { return; } if (mAssetRequests.empty()) { mLastRequest = mRequestedTexture.size(); mWaitTimer.start(); mExportState = TEXTURE_DOWNLOAD; } else if (mLastRequest != mAssetRequests.size()) { mWaitTimer.start(); mLastRequest = mAssetRequests.size(); updateTitleProgress(ASSET_DOWNLOAD); } else if (mWaitTimer.getElapsedTimeF32() > MAX_ASSET_WAIT_TIME) { //abort for now LL_DEBUGS("export") << "Asset timeout with " << (S32)mAssetRequests.size() << " requests left." << LL_ENDL; for (uuid_vec_t::iterator iter = mAssetRequests.begin(); iter != mAssetRequests.end(); ++iter) { LL_DEBUGS("export") << "Asset: " << (*iter).asString() << LL_ENDL; } mAssetRequests.clear(); } break; case TEXTURE_DOWNLOAD: if (gDisconnected) { return; } if(mRequestedTexture.empty()) { mExportState = IDLE; if (!gIdleCallbacks.deleteFunction(onIdle, this)) { LL_WARNS("export") << "Failed to delete idle callback" << LL_ENDL; } mWaitTimer.stop(); llofstream file; file.open(mFilename.c_str(), std::ios_base::out | std::ios_base::binary); std::string zip_data = zip_llsd(mManifest); file.write(zip_data.data(), zip_data.size()); file.close(); LL_DEBUGS("export") << "Export finished and written to " << mFilename << LL_ENDL; LLSD args; args["FILENAME"] = mFilename; LLNotificationsUtil::add("ExportFinished", args); closeFloater(); } else if (mLastRequest != mRequestedTexture.size()) { mWaitTimer.start(); mLastRequest = mRequestedTexture.size(); updateTitleProgress(TEXTURE_DOWNLOAD); } else if (mWaitTimer.getElapsedTimeF32() > MAX_TEXTURE_WAIT_TIME) { mWaitTimer.start(); for (std::map<LLUUID, FSAssetResourceData>::iterator iter = mRequestedTexture.begin(); iter != mRequestedTexture.end(); ++iter) { LLUUID texture_id = iter->first; LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_id, FTT_DEFAULT, MIPMAP_TRUE); image->setBoostLevel(LLViewerTexture::BOOST_MAX_LEVEL); image->forceToSaveRawImage(0); image->setLoadedCallback(FSFloaterObjectExport::onImageLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList); LL_DEBUGS("export") << "re-requested texture " << texture_id.asString() << LL_ENDL; } } break; default: break; } }
bool FSFloaterObjectExport::exportTexture(const LLUUID& texture_id) { if(texture_id.isNull()) { LL_WARNS("export") << "Attempted to export NULL texture." << LL_ENDL; return false; } if (mTextureChecked.count(texture_id) != 0) { return mTextureChecked[texture_id]; } if (gAssetStorage->mStaticVFS->getExists(texture_id, LLAssetType::AT_TEXTURE)) { LL_DEBUGS("export") << "Texture " << texture_id.asString() << " is local static." << LL_ENDL; // no need to save the texture data as the viewer already has it in a local file. mTextureChecked[texture_id] = true; return true; } //TODO: check for local file static texture. The above will only get the static texture in the static db, not individual textures. LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(texture_id); bool texture_export = false; std::string name; std::string description; if (LLGridManager::getInstance()->isInSecondLife()) { if (imagep->mComment.find("a") != imagep->mComment.end()) { if (LLUUID(imagep->mComment["a"]) == gAgentID) { texture_export = true; LL_DEBUGS("export") << texture_id << " pass texture export comment check." << LL_ENDL; } } } if (texture_export) { FSExportPermsCheck::canExportAsset(texture_id, &name, &description); } else { texture_export = FSExportPermsCheck::canExportAsset(texture_id, &name, &description); } mTextureChecked[texture_id] = texture_export; if (!texture_export) { LL_DEBUGS("export") << "Texture " << texture_id << " failed export check." << LL_ENDL; return false; } LL_DEBUGS("export") << "Loading image texture " << texture_id << LL_ENDL; mRequestedTexture[texture_id].name = name; mRequestedTexture[texture_id].description = description; LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_id, FTT_DEFAULT, MIPMAP_TRUE); image->setBoostLevel(LLViewerTexture::BOOST_MAX_LEVEL); image->forceToSaveRawImage(0); image->setLoadedCallback(FSFloaterObjectExport::onImageLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList); return true; }
BOOL LLWearable::importFile( LLFILE* file ) { // *NOTE: changing the type or size of this buffer will require // changes in the fscanf() code below. You would be better off // rewriting this to use streams and not require an open FILE. char text_buffer[2048]; /* Flawfinder: ignore */ S32 fields_read = 0; // suppress texlayerset updates while wearables are being imported. Layersets will be updated // when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed. LLOverrideBakedTextureUpdate stop_bakes(false); // read header and version fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion ); if( fields_read != 1 ) { // Shouldn't really log the asset id for security reasons, but // we need it in this case. llwarns << "Bad Wearable asset header: " << mAssetID << llendl; //gVFS->dumpMap(); return FALSE; } // Temoprary hack to allow wearables with definition version 24 to still load. // This should only affect lindens and NDA'd testers who have saved wearables in 2.0 // the extra check for version == 24 can be removed before release, once internal testers // have loaded these wearables again. See hack pt 2 at bottom of function to ensure that // these wearables get re-saved with version definition 22. if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 ) { llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl; return FALSE; } // name int next_char = fgetc( file ); /* Flawfinder: ignore */ if( '\n' == next_char ) { // no name mName = ""; } else { ungetc( next_char, file ); fields_read = fscanf( /* Flawfinder: ignore */ file, "%2047[^\n]", text_buffer); if( (1 != fields_read) || (fgetc( file ) != '\n') ) /* Flawfinder: ignore */ { llwarns << "Bad Wearable asset: early end of file" << llendl; return FALSE; } mName = text_buffer; LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN ); } // description next_char = fgetc( file ); /* Flawfinder: ignore */ if( '\n' == next_char ) { // no description mDescription = ""; } else { ungetc( next_char, file ); fields_read = fscanf( /* Flawfinder: ignore */ file, "%2047[^\n]", text_buffer ); if( (1 != fields_read) || (fgetc( file ) != '\n') ) /* Flawfinder: ignore */ { llwarns << "Bad Wearable asset: early end of file" << llendl; return FALSE; } mDescription = text_buffer; LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN ); } // permissions S32 perm_version; fields_read = fscanf( file, " permissions %d\n", &perm_version ); if( (fields_read != 1) || (perm_version != 0) ) { llwarns << "Bad Wearable asset: missing permissions" << llendl; return FALSE; } if( !mPermissions.importFile( file ) ) { return FALSE; } // sale info S32 sale_info_version; fields_read = fscanf( file, " sale_info %d\n", &sale_info_version ); if( (fields_read != 1) || (sale_info_version != 0) ) { llwarns << "Bad Wearable asset: missing sale_info" << llendl; return FALSE; } // Sale info used to contain next owner perm. It is now in the // permissions. Thus, we read that out, and fix legacy // objects. It's possible this op would fail, but it should pick // up the vast majority of the tasks. BOOL has_perm_mask = FALSE; U32 perm_mask = 0; if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) ) { return FALSE; } if(has_perm_mask) { // fair use fix. if(!(perm_mask & PERM_COPY)) { perm_mask |= PERM_TRANSFER; } mPermissions.setMaskNext(perm_mask); } // wearable type S32 type = -1; fields_read = fscanf( file, "type %d\n", &type ); if( fields_read != 1 ) { llwarns << "Bad Wearable asset: bad type" << llendl; return FALSE; } if( 0 <= type && type < LLWearableType::WT_COUNT ) { setType((LLWearableType::EType)type); } else { mType = LLWearableType::WT_COUNT; llwarns << "Bad Wearable asset: bad type #" << type << llendl; return FALSE; } // parameters header S32 num_parameters = 0; fields_read = fscanf( file, "parameters %d\n", &num_parameters ); if( fields_read != 1 ) { llwarns << "Bad Wearable asset: missing parameters block" << llendl; return FALSE; } if( num_parameters != mVisualParamIndexMap.size() ) { llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. type: " << mType << llendl; } // parameters S32 i; for( i = 0; i < num_parameters; i++ ) { S32 param_id = 0; F32 param_weight = 0.f; fields_read = fscanf( file, "%d %f\n", ¶m_id, ¶m_weight ); if( fields_read != 2 ) { llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl; return FALSE; } mSavedVisualParamMap[param_id] = param_weight; } // textures header S32 num_textures = 0; fields_read = fscanf( file, "textures %d\n", &num_textures); if( fields_read != 1 ) { llwarns << "Bad Wearable asset: missing textures block" << llendl; return FALSE; } // textures for( i = 0; i < num_textures; i++ ) { S32 te = 0; fields_read = fscanf( /* Flawfinder: ignore */ file, "%d %2047s\n", &te, text_buffer); if( fields_read != 2 ) { llwarns << "Bad Wearable asset: bad texture, #" << i << llendl; return FALSE; } if( !LLUUID::validate( text_buffer ) ) { llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl; return FALSE; } LLUUID id = LLUUID(text_buffer); LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( id ); if( mTEMap.find(te) != mTEMap.end() ) { delete mTEMap[te]; } if( mSavedTEMap.find(te) != mSavedTEMap.end() ) { delete mSavedTEMap[te]; } if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime")) { image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL); } LLUUID textureid(text_buffer); mTEMap[te] = new LLLocalTextureObject(image, textureid); mSavedTEMap[te] = new LLLocalTextureObject(image, textureid); createLayers(te); } // copy all saved param values to working params revertValues(); return TRUE; }
LLSD JCExportTracker::subserialize(LLViewerObject* linkset) { //Chalice - Changed to support exporting linkset groups. LLViewerObject* object = linkset; //if(!linkset)return LLSD(); // Create an LLSD object that will hold the entire tree structure that can be serialized to a file LLSD llsd; //if (!node) // return llsd; //object = root_object = node->getObject(); if (!object) return llsd; if(!(!object->isAvatar() && object->permYouOwner() && object->permModify() && object->permCopy() && object->permTransfer() && !gAgent.getGodLevel())) return llsd; // Build a list of everything that we'll actually be exporting LLDynamicArray<LLViewerObject*> export_objects; // Add the root object to the export list export_objects.put(object); // Iterate over all of this objects children LLViewerObject::child_list_t child_list = object->getChildren(); for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i) { LLViewerObject* child = *i; if(!child->isAvatar()) { // Put the child objects on the export list export_objects.put(child); } } S32 object_index = 0; while ((object_index < export_objects.count())) { object = export_objects.get(object_index++); LLUUID id = object->getID(); llinfos << "Exporting prim " << object->getID().asString() << llendl; // Create an LLSD object that represents this prim. It will be injected in to the overall LLSD // tree structure LLSD prim_llsd; if (object_index == 1) { LLVOAvatar* avatar = find_avatar_from_object(object); if (avatar) { LLViewerJointAttachment* attachment = avatar->getTargetAttachmentPoint(object); U8 attachment_id = 0; if (attachment) { for (LLVOAvatar::attachment_map_t::iterator iter = avatar->mAttachmentPoints.begin(); iter != avatar->mAttachmentPoints.end(); ++iter) { if (iter->second == attachment) { attachment_id = iter->first; break; } } } else { // interpret 0 as "default location" attachment_id = 0; } prim_llsd["Attachment"] = attachment_id; prim_llsd["attachpos"] = object->getPosition().getValue(); prim_llsd["attachrot"] = ll_sd_from_quaternion(object->getRotation()); } prim_llsd["position"] = LLVector3(0, 0, 0).getValue(); prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation()); } else { prim_llsd["position"] = object->getPosition().getValue(); prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation()); } //prim_llsd["name"] = "";//node->mName; //prim_llsd["description"] = "";//node->mDescription; // Transforms prim_llsd["scale"] = object->getScale().getValue(); // Flags prim_llsd["shadows"] = object->flagCastShadows(); prim_llsd["phantom"] = object->flagPhantom(); prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS); LLVolumeParams params = object->getVolume()->getParams(); prim_llsd["volume"] = params.asLLSD(); if (object->isFlexible()) { LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); prim_llsd["flexible"] = flex->asLLSD(); } if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT)) { LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT); prim_llsd["light"] = light->asLLSD(); } if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) { LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); prim_llsd["sculpt"] = sculpt->asLLSD(); } // Textures LLSD te_llsd; U8 te_count = object->getNumTEs(); for (U8 i = 0; i < te_count; i++) { te_llsd.append(object->getTE(i)->asLLSD()); } if(export_textures) { std::string path = asset_dir + gDirUtilp->getDirDelimiter(); for (U8 i = 0; i < te_count; i++) { LLUUID asset_id = object->getTE(i)->getID(); JCAssetInfo* info = new JCAssetInfo; info->path = path + asset_id.asString() + ".j2c"; info->name = "Prim Texture"; //gAssetStorage->getAssetData(asset_id, LLAssetType::AT_TEXTURE, JCAssetExportCallback, info,1); if(requested_textures.count(asset_id) == 0) { requested_textures.insert(asset_id); LLViewerFetchedTexture* img = LLViewerTextureManager::getFetchedTexture(asset_id, MIPMAP_TRUE); img->setBoostLevel(LLViewerTexture::BOOST_MAX_LEVEL); img->setLoadedCallback( JCExportTracker::onFileLoadedForSave, 0, TRUE, FALSE, info, &mCallbackTextureList); llinfos << "Requesting texture " << asset_id.asString() << llendl; } } } //JCExportTracker::mirror(asset, obj, asset_dir, asset->getUUID().asString()); prim_llsd["textures"] = te_llsd; prim_llsd["id"] = object->getID().asString(); if(export_properties) { ////cmdline_printchat(llformat("yes %d",export_properties)); propertyqueries += 1; gMessageSystem->newMessageFast(_PREHASH_ObjectSelect); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); gMessageSystem->nextBlockFast(_PREHASH_ObjectData); gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); gMessageSystem->sendReliable(gAgent.getRegionHost()); if(export_inventory) { object->registerInventoryListener(sInstance,NULL); object->dirtyInventory(); object->requestInventory(); invqueries += 1; } }//else //cmdline_printchat(llformat("no %d",export_properties)); totalprims += 1; // Changed to use link numbers zero-indexed. llsd[object_index - 1] = prim_llsd; } return llsd; }