View of /trunk/DefaultRenderer/DefaultTexture.cs
Parent Directory
|
Revision Log
Revision 115 -
(download)
(annotate)
Fri Feb 6 10:40:26 2009 UTC (4 years, 4 months ago) by albert
File size: 10556 byte(s)
Fri Feb 6 10:40:26 2009 UTC (4 years, 4 months ago) by albert
File size: 10556 byte(s)
add comments
/* * this class quoted code from: * http://www.openmetaverse.org/viewvc/index.cgi/omf/libopenmetaverse/trunk/Programs/PrimWorkshop/TexturePipeline.cs?view=markup * */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; using System.IO; using System.Threading; using System.Runtime.InteropServices; using Xenki.Framework; using OpenMetaverse.Imaging; using OpenMetaverse; using Xenki.References; using log4net; using System.Reflection; namespace Xenki.DefaultRenderer { public class DefaultTexture :ITextureManage { //texture downloaded folder in the user machines. private string cachefolderPath = EnvironmentSettings.TextureCacheFolder; private string bmpFilePath = EnvironmentSettings.TextureTempFolder; private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Thread MainThread; // list of current requests in process private Dictionary<UUID, int> CurrentRequests; private Queue<UUID> RequestQueue; private static AutoResetEvent[] resetEvents; private static int[] threadpoolSlots; // maximum allowed concurrent requests at once const int MAX_TEXTURE_REQUESTS = EnvironmentSettings.DownloadTextureThreadNumber; private GridClient gridClient; public GridClient GridClient { get { return gridClient; } set { gridClient = value; } } #region Singleton private static volatile DefaultTexture singleton = new DefaultTexture(); public static DefaultTexture SingleTextureManager() { return singleton; } private DefaultTexture() { RequestQueue = new Queue<UUID>(); CurrentRequests = new Dictionary<UUID, int>(MAX_TEXTURE_REQUESTS); resetEvents = new AutoResetEvent[MAX_TEXTURE_REQUESTS]; threadpoolSlots = new int[MAX_TEXTURE_REQUESTS]; // pre-configure autoreset events/download slots for (int i = 0; i < MAX_TEXTURE_REQUESTS; i++) { resetEvents[i] = new AutoResetEvent(false); threadpoolSlots[i] = -1; } } #endregion public void StartDownload() { try { GridClient.Assets.OnImageReceived += new AssetManager.ImageReceivedCallback(Assets_OnImageReceived); MainThread = new Thread(new ThreadStart(DownloadTextureThread)); MainThread.Start(); } catch (Exception er) { m_log.Error(er); Logger.DebugLog(er.Message); } } private void DownloadTextureThread() { int reqNbr; while (true) { if (RequestQueue.Count > 0) { reqNbr = -1; // find available slot for reset event for (int i = 0; i < threadpoolSlots.Length; i++) { if (threadpoolSlots[i] == -1) { threadpoolSlots[i] = 1; reqNbr = i; break; } } if (reqNbr != -1) { UUID requestID; lock (RequestQueue) requestID = RequestQueue.Dequeue(); Logger.DebugLog(String.Format("Sending Worker thread new download request {0}", reqNbr)); ThreadPool.QueueUserWorkItem(new WaitCallback(textureRequestDoWork), new TaskInfo(requestID, reqNbr)); continue; } } Thread.Sleep(500); } } /// <summary> /// multi-thread downloading textures. /// </summary> /// <param name="threadContext">download task infomation </param> void textureRequestDoWork(Object threadContext) { TaskInfo ti = (TaskInfo)threadContext; //rwCurrentRequests.EnterWriteLock(); lock (CurrentRequests) { if (CurrentRequests.ContainsKey(ti.RequestID)) { threadpoolSlots[ti.RequestNbr] = -1; return; } else { CurrentRequests.Add(ti.RequestID, ti.RequestNbr); } } //rwCurrentRequests.ExitWriteLock(); Logger.DebugLog(String.Format("Worker {0} Requesting {1}", ti.RequestNbr, ti.RequestID)); resetEvents[ti.RequestNbr].Reset(); GridClient.Assets.RequestImage(ti.RequestID, ImageType.Normal); // don't release this worker slot until texture is downloaded or timeout occurs if (!resetEvents[ti.RequestNbr].WaitOne(30 * 1000, false)) { // Timed out Logger.Log("Worker " + ti.RequestNbr + " Timeout waiting for Texture " + ti.RequestID + " to Download", Helpers.LogLevel.Warning); //rwCurrentRequests.EnterWriteLock(); lock (CurrentRequests) CurrentRequests.Remove(ti.RequestID); //rwCurrentRequests.ExitWriteLock(); //rwRequestQueue.EnterWriteLock(); //lock (RequestQueue) // RequestQueue.Enqueue(ti.RequestID); //rwRequestQueue.ExitWriteLock(); } // free up this download slot threadpoolSlots[ti.RequestNbr] = -1; ti = null; } private void Assets_OnImageReceived(ImageDownload image, AssetTexture asset) { if (image.Success) { lock (objFileAccess) if (File.Exists(Path.Combine(bmpFilePath, image.ID.ToString() + References.EnvironmentSettings.TextureImageExtension)) == false) { SaveTexture2Image(image); } } if (OnDownloadFinished != null) { OnDownloadFinished(image.ID, image.Success); } } ManagedImage managedimg=null; Image img; Bitmap bitmap; private void SaveTexture2Image(ImageDownload image) { bool alpha = false; if (OpenJPEG.DecodeToImage(image.AssetData, out managedimg, out img)) { if (managedimg != null) { if ((managedimg.Channels & ManagedImage.ImageChannels.Alpha) != 0) alpha = true; } //System.Drawing.Image pngimage = new Bitmap(img); bitmap = new Bitmap(img); //if (alpha) // bitmap.MakeTransparent(); //System.Drawing.Imaging.EncoderParameters eps = new System.Drawing.Imaging.EncoderParameters(); //eps.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth bitmap.Save(Path.Combine(bmpFilePath, image.ID.ToString() + References.EnvironmentSettings.TextureImageExtension)); } } /// <summary> /// get the texture image via texture id /// </summary> /// <param name="textureID"></param> /// <returns></returns> public ImageDownload RetireveTextureData(UUID textureID) { ImageDownload image =null; if (gridClient.Assets.Cache.HasImage(textureID)) { image = gridClient.Assets.Cache.GetCachedImage(textureID); } else { lock (RequestQueue) { // Make sure we aren't already downloading the texture if (!RequestQueue.Contains(textureID)&& !CurrentRequests.ContainsKey(textureID)) { RequestQueue.Enqueue(textureID); } } } return image; } /// <summary> /// If the texture hasn't downloaded yet /// enter it into the download queue. /// </summary> /// <param name="textureID"></param> public void RequestTexture(UUID textureID) { lock (objFileAccess) { if (File.Exists(Path.Combine(bmpFilePath, textureID.ToString() + References.EnvironmentSettings.TextureImageExtension)) == true) return; } if (gridClient.Assets.Cache.HasImage(textureID) == false) { //rwRequestQueue.EnterWriteLock(); //rwCurrentRequests.EnterReadLock(); lock (RequestQueue) { // Make sure we aren't already downloading the texture if (!CurrentRequests.ContainsKey(textureID) && !RequestQueue.Contains(textureID)) RequestQueue.Enqueue(textureID); } //rwCurrentRequests.ExitReadLock(); //rwRequestQueue.ExitWriteLock(); } else { //lock (objFileAccess) //{ // ImageDownload d = gridClient.Assets.Cache.GetCachedImage(textureID); // SaveTexture2Image(d); //} } } object objFileAccess = new object(); public event TextureDownloadFinished OnDownloadFinished; } class TaskInfo { public UUID RequestID; public int RequestNbr; public TaskInfo(UUID reqID, int reqNbr) { RequestID = reqID; RequestNbr = reqNbr; } } }
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

