View of /trunk/DefaultRenderer/DefaultTexture.cs
Parent Directory
|
Revision Log
Revision 54 -
(download)
(annotate)
Thu Oct 16 02:59:36 2008 UTC (4 years, 7 months ago) by albert
File size: 10646 byte(s)
Thu Oct 16 02:59:36 2008 UTC (4 years, 7 months ago) by albert
File size: 10646 byte(s)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xenki.Framework;
using OpenMetaverse;
using System.Drawing;
using System.IO;
using System.Threading;
using OpenMetaverse.Imaging;
namespace Xenki.DefaultRenderer
{
public class DefaultTexture //: ITextureManage
{
private event TextureDownloadFinished onDownloadFinished;
string cachefolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "textures");
string bmpFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "texture");
//the textures have load in memory.
// private readonly Dictionary<UUID, byte[]> CurruntTextures = new Dictionary<UUID, byte[]>();
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 = 3;
private GridClient gridClient;
public GridClient GridClient
{
get { return gridClient; }
set
{
gridClient = value;
gridClient.Settings.USE_TEXTURE_CACHE = true;
if (Directory.Exists(cachefolderPath) == false)
Directory.CreateDirectory(cachefolderPath);
gridClient.Settings.TEXTURE_CACHE_DIR = cachefolderPath;
gridClient.Settings.TEXTURE_CACHE_MAX_SIZE = 5120;//M? or number?
}
}
private static readonly 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;
}
}
public void StartDownload()
{
try
{
GridClient.Assets.OnImageReceived += new AssetManager.ImageReceivedCallback(Assets_OnImageReceived);
MainThread = new Thread(new ThreadStart(DownloadTextureThread));
MainThread.Start();
}
catch (Exception er)
{
Logger.DebugLog(er.Message);
}
}
//public void StopDownload()
//{
//}
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));
//gridClient.Assets.RequestImage(requestID, ImageType.Normal);
continue;
}
}
Thread.Sleep(1000);
}
}
void textureRequestDoWork(Object threadContext)
{
TaskInfo ti = (TaskInfo)threadContext;
lock (CurrentRequests)
{
if (CurrentRequests.ContainsKey(ti.RequestID))
{
threadpoolSlots[ti.RequestNbr] = -1;
return;
}
else
{
CurrentRequests.Add(ti.RequestID, ti.RequestNbr);
}
}
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(300 * 1000, false))
{
// Timed out
Logger.Log("Worker " + ti.RequestNbr + " Timeout waiting for Texture " + ti.RequestID + " to Download", Helpers.LogLevel.Warning);
lock (CurrentRequests)
CurrentRequests.Remove(ti.RequestID);
}
// free up this download slot
threadpoolSlots[ti.RequestNbr] = -1;
ti = null;
}
private void Assets_OnImageReceived(ImageDownload image, AssetTexture asset)
{
if (image.Success)
{
//lock (CurruntTextures)
//{
// if (!CurruntTextures.ContainsKey(image.ID))
// {
// CurruntTextures.Add(image.ID, image.AssetData);
// }
// else
// {
// CurruntTextures.Remove(image.ID);
// CurruntTextures.Add(image.ID, image.AssetData);
// }
//}
lock(objFileAccess)
if (File.Exists(Path.Combine(bmpFilePath, image.ID.ToString() + ".jpg")) == false)
{
//SaveTexture2Image(image);
}
}
if (onDownloadFinished != null)
{
onDownloadFinished(image.ID, image.Success);
}
}
private void SaveTexture2Image(ImageDownload image)
{
ManagedImage managedimg;
Image img;
//byte[] bytes = GetTextureDataByTextureID(downLoadedTextureID);
if (OpenJPEG.DecodeToImage(image.AssetData, out managedimg, out img))
{
Bitmap bitmap = new Bitmap(img);
bitmap.Save(Path.Combine(bmpFilePath, image.ID.ToString() + ".jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
bitmap.Dispose();
bitmap = null;
}
img.Dispose();
img = null;
managedimg = null;
}
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;
}
public void RequestTexture(UUID textureID)
{
//bool hasDownloaded = false;
//lock (CurruntTextures)
//{
// if (CurruntTextures.ContainsKey(textureID))
// {
// hasDownloaded = true;
// }
//}
//if (hasDownloaded)
// return;
//if (gridClient.Assets.Cache.HasImage(textureID))
//{
// // Add to rendering dictionary
// lock (CurruntTextures)
// {
// if (!CurruntTextures.ContainsKey(textureID))
// {
// CurruntTextures.Add(textureID, gridClient.Assets.Cache.GetCachedImage(textureID).AssetData);
// }
// }
//}
//else
lock (objFileAccess)
{
if (File.Exists(Path.Combine(bmpFilePath, textureID.ToString() + ".jpg")) == false)
{
if (gridClient.Assets.Cache.HasImage(textureID) == false)
{
lock (RequestQueue)
{
// Make sure we aren't already downloading the texture
if (!RequestQueue.Contains(textureID) && !CurrentRequests.ContainsKey(textureID))
{
RequestQueue.Enqueue(textureID);
}
}
}
else
{
// ImageDownload down = gridClient.Assets.Cache.GetCachedImage(textureID);
// SaveTexture2Image(down);
}
}
}
}
object objFileAccess = new object();
public TextureDownloadFinished OnDownloadFinished
{
get
{
return onDownloadFinished;
}
set
{
onDownloadFinished = value;
}
}
}
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 |

