diff options
3 files changed, 112 insertions, 16 deletions
diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs index ff2d418..5d22e2a 100644 --- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs | |||
@@ -49,8 +49,14 @@ namespace OpenSim.Region.Environment.Modules | |||
49 | private Scene m_scene; | 49 | private Scene m_scene; |
50 | private List<Scene> m_scenes = new List<Scene>(); | 50 | private List<Scene> m_scenes = new List<Scene>(); |
51 | 51 | ||
52 | /// <summary> | ||
53 | /// There is one queue for all textures waiting to be sent, regardless of the requesting user. | ||
54 | /// </summary> | ||
52 | private readonly BlockingQueue<TextureSender> m_queueSenders = new BlockingQueue<TextureSender>(); | 55 | private readonly BlockingQueue<TextureSender> m_queueSenders = new BlockingQueue<TextureSender>(); |
53 | 56 | ||
57 | /// <summary> | ||
58 | /// Each user has their own texture download queue. | ||
59 | /// </summary> | ||
54 | private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices = | 60 | private readonly Dictionary<LLUUID, UserTextureDownloadService> m_userTextureServices = |
55 | new Dictionary<LLUUID, UserTextureDownloadService>(); | 61 | new Dictionary<LLUUID, UserTextureDownloadService>(); |
56 | 62 | ||
@@ -80,13 +86,17 @@ namespace OpenSim.Region.Environment.Modules | |||
80 | } | 86 | } |
81 | } | 87 | } |
82 | 88 | ||
89 | /// <summary> | ||
90 | /// Cleanup the texture service related objects for the removed presence. | ||
91 | /// </summary> | ||
92 | /// <param name="agentId"> </param> | ||
83 | private void EventManager_OnRemovePresence(LLUUID agentId) | 93 | private void EventManager_OnRemovePresence(LLUUID agentId) |
84 | { | 94 | { |
85 | UserTextureDownloadService textureService; | 95 | UserTextureDownloadService textureService; |
86 | 96 | ||
87 | lock (m_userTextureServices) | 97 | lock (m_userTextureServices) |
88 | { | 98 | { |
89 | if( m_userTextureServices.TryGetValue( agentId, out textureService )) | 99 | if (m_userTextureServices.TryGetValue(agentId, out textureService)) |
90 | { | 100 | { |
91 | textureService.Close(); | 101 | textureService.Close(); |
92 | 102 | ||
@@ -118,6 +128,12 @@ namespace OpenSim.Region.Environment.Modules | |||
118 | client.OnRequestTexture += TextureRequest; | 128 | client.OnRequestTexture += TextureRequest; |
119 | } | 129 | } |
120 | 130 | ||
131 | /// <summary> | ||
132 | /// Does this user have a registered texture download service? | ||
133 | /// </summary> | ||
134 | /// <param name="userID"></param> | ||
135 | /// <param name="textureService"></param> | ||
136 | /// <returns>Always returns true, since a service is created if one does not already exist</returns> | ||
121 | private bool TryGetUserTextureService(LLUUID userID, out UserTextureDownloadService textureService) | 137 | private bool TryGetUserTextureService(LLUUID userID, out UserTextureDownloadService textureService) |
122 | { | 138 | { |
123 | lock (m_userTextureServices) | 139 | lock (m_userTextureServices) |
@@ -133,6 +149,11 @@ namespace OpenSim.Region.Environment.Modules | |||
133 | } | 149 | } |
134 | } | 150 | } |
135 | 151 | ||
152 | /// <summary> | ||
153 | /// Start the process of requesting a given texture. | ||
154 | /// </summary> | ||
155 | /// <param name="sender"> </param> | ||
156 | /// <param name="e"></param> | ||
136 | public void TextureRequest(Object sender, TextureRequestArgs e) | 157 | public void TextureRequest(Object sender, TextureRequestArgs e) |
137 | { | 158 | { |
138 | IClientAPI client = (IClientAPI) sender; | 159 | IClientAPI client = (IClientAPI) sender; |
@@ -141,10 +162,12 @@ namespace OpenSim.Region.Environment.Modules | |||
141 | { | 162 | { |
142 | textureService.HandleTextureRequest(client, e); | 163 | textureService.HandleTextureRequest(client, e); |
143 | m_scene.AddPendingDownloads(1); | 164 | m_scene.AddPendingDownloads(1); |
144 | } | 165 | } |
145 | |||
146 | } | 166 | } |
147 | 167 | ||
168 | /// <summary> | ||
169 | /// Entry point for the thread dedicated to processing the texture queue. | ||
170 | /// </summary> | ||
148 | public void ProcessTextureSenders() | 171 | public void ProcessTextureSenders() |
149 | { | 172 | { |
150 | TextureSender sender = null; | 173 | TextureSender sender = null; |
@@ -179,11 +202,14 @@ namespace OpenSim.Region.Environment.Modules | |||
179 | } | 202 | } |
180 | } | 203 | } |
181 | 204 | ||
205 | /// <summary> | ||
206 | /// Called when the texture has finished sending. | ||
207 | /// </summary> | ||
208 | /// <param name="sender"></param> | ||
182 | private void TextureSent(TextureSender sender) | 209 | private void TextureSent(TextureSender sender) |
183 | { | 210 | { |
184 | sender.Sending = false; | 211 | sender.Sending = false; |
185 | m_scene.AddPendingDownloads(-1); | 212 | m_scene.AddPendingDownloads(-1); |
186 | } | 213 | } |
187 | |||
188 | } | 214 | } |
189 | } | 215 | } |
diff --git a/OpenSim/Region/Environment/Modules/TextureSender.cs b/OpenSim/Region/Environment/Modules/TextureSender.cs index 08da591..f2b3173 100644 --- a/OpenSim/Region/Environment/Modules/TextureSender.cs +++ b/OpenSim/Region/Environment/Modules/TextureSender.cs | |||
@@ -34,36 +34,59 @@ using OpenSim.Framework.Console; | |||
34 | 34 | ||
35 | namespace OpenSim.Region.Environment.Modules | 35 | namespace OpenSim.Region.Environment.Modules |
36 | { | 36 | { |
37 | /// <summary> | ||
38 | /// A TextureSender handles the process of receiving a texture requested by the client from the | ||
39 | /// AssetCache, and then sending that texture back to the client. | ||
40 | /// </summary> | ||
37 | public class TextureSender | 41 | public class TextureSender |
38 | { | 42 | { |
39 | private static readonly log4net.ILog m_log | 43 | private static readonly log4net.ILog m_log |
40 | = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 44 | = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
41 | 45 | ||
46 | /// <summary> | ||
47 | /// Records the number of times texture send has been called. | ||
48 | /// </summary> | ||
42 | public int counter = 0; | 49 | public int counter = 0; |
50 | |||
51 | /// <summary> | ||
52 | /// Holds the texture asset to send. | ||
53 | /// </summary> | ||
43 | private AssetBase m_asset; | 54 | private AssetBase m_asset; |
44 | public long DataPointer = 0; | 55 | |
45 | public int NumPackets = 0; | 56 | /// <summary> |
46 | public int PacketCounter = 0; | 57 | /// This is actually the number of extra packets required to send the texture data! We always assume |
58 | /// at least one is required. | ||
59 | /// </summary> | ||
60 | private int NumPackets = 0; | ||
61 | |||
62 | /// <summary> | ||
63 | /// Holds the packet number to send next. In this case, each packet is 1000 bytes long and starts | ||
64 | /// at the 600th byte (0th indexed). | ||
65 | /// </summary> | ||
66 | private int PacketCounter = 0; | ||
67 | |||
47 | public bool Cancel = false; | 68 | public bool Cancel = false; |
48 | public bool ImageLoaded = false; | 69 | public bool ImageLoaded = false; |
49 | |||
50 | public bool Sending = false; | 70 | public bool Sending = false; |
51 | 71 | ||
52 | public IClientAPI RequestUser; | 72 | private IClientAPI RequestUser; |
53 | public LLUUID RequestedAssetID; | ||
54 | public int RequestedDiscardLevel = -1; | ||
55 | public uint StartPacketNumber = 0; | ||
56 | 73 | ||
57 | // private int m_sentDiscardLevel = -1; | 74 | private int RequestedDiscardLevel = -1; |
75 | private uint StartPacketNumber = 0; | ||
58 | 76 | ||
59 | public TextureSender(IClientAPI client, LLUUID textureID, int discardLevel, uint packetNumber) | 77 | public TextureSender(IClientAPI client, int discardLevel, uint packetNumber) |
60 | { | 78 | { |
61 | RequestUser = client; | 79 | RequestUser = client; |
62 | RequestedAssetID = textureID; | ||
63 | RequestedDiscardLevel = discardLevel; | 80 | RequestedDiscardLevel = discardLevel; |
64 | StartPacketNumber = packetNumber; | 81 | StartPacketNumber = packetNumber; |
65 | } | 82 | } |
66 | 83 | ||
84 | /// <summary> | ||
85 | /// Load up the texture data to send. | ||
86 | /// </summary> | ||
87 | /// <param name="asset"> | ||
88 | /// A <see cref="AssetBase"/> | ||
89 | /// </param> | ||
67 | public void TextureReceived(AssetBase asset) | 90 | public void TextureReceived(AssetBase asset) |
68 | { | 91 | { |
69 | m_asset = asset; | 92 | m_asset = asset; |
@@ -79,6 +102,10 @@ namespace OpenSim.Region.Environment.Modules | |||
79 | PacketCounter = (int) StartPacketNumber; | 102 | PacketCounter = (int) StartPacketNumber; |
80 | } | 103 | } |
81 | 104 | ||
105 | /// <summary> | ||
106 | /// Send a texture packet to the client. | ||
107 | /// </summary> | ||
108 | /// <returns>True if the last packet has been sent, false otherwise.</returns> | ||
82 | public bool SendTexturePacket() | 109 | public bool SendTexturePacket() |
83 | { | 110 | { |
84 | SendPacket(); | 111 | SendPacket(); |
@@ -91,6 +118,9 @@ namespace OpenSim.Region.Environment.Modules | |||
91 | return false; | 118 | return false; |
92 | } | 119 | } |
93 | 120 | ||
121 | /// <summary> | ||
122 | /// Sends a texture packet to the client. | ||
123 | /// </summary> | ||
94 | private void SendPacket() | 124 | private void SendPacket() |
95 | { | 125 | { |
96 | if (PacketCounter <= NumPackets) | 126 | if (PacketCounter <= NumPackets) |
@@ -148,6 +178,12 @@ namespace OpenSim.Region.Environment.Modules | |||
148 | } | 178 | } |
149 | } | 179 | } |
150 | 180 | ||
181 | /// <summary> | ||
182 | /// Calculate the number of packets that will be required to send the texture loaded into this sender | ||
183 | /// This is actually the number of 1000 byte packets not including an initial 600 byte packet... | ||
184 | /// </summary> | ||
185 | /// <param name="length"></param> | ||
186 | /// <returns></returns> | ||
151 | private int CalculateNumPackets(int length) | 187 | private int CalculateNumPackets(int length) |
152 | { | 188 | { |
153 | int numPackets = 0; | 189 | int numPackets = 0; |
diff --git a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs index 32bc7c3..4a94266 100644 --- a/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs +++ b/OpenSim/Region/Environment/Modules/UserTextureDownloadService.cs | |||
@@ -35,13 +35,27 @@ using OpenSim.Region.Environment.Scenes; | |||
35 | 35 | ||
36 | namespace OpenSim.Region.Environment.Modules | 36 | namespace OpenSim.Region.Environment.Modules |
37 | { | 37 | { |
38 | /// <summary> | ||
39 | /// This module sets up texture senders in response to client texture requests, and places them on a | ||
40 | /// processing queue once those senders have the appropriate data (i.e. a texture retrieved from the | ||
41 | /// asset cache). | ||
42 | /// </summary> | ||
38 | public class UserTextureDownloadService | 43 | public class UserTextureDownloadService |
39 | { | 44 | { |
40 | private static readonly log4net.ILog m_log | 45 | private static readonly log4net.ILog m_log |
41 | = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 46 | = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
42 | 47 | ||
48 | /// <summary> | ||
49 | /// Holds texture senders before they have received the appropriate texture from the asset cache. | ||
50 | /// </summary> | ||
43 | private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>(); | 51 | private readonly Dictionary<LLUUID, TextureSender> m_textureSenders = new Dictionary<LLUUID, TextureSender>(); |
52 | |||
53 | /// <summary> | ||
54 | /// Texture Senders are placed in this queue once they have received their texture from the asset | ||
55 | /// cache. Another module actually invokes the send. | ||
56 | /// </summary> | ||
44 | private readonly BlockingQueue<TextureSender> m_sharedSendersQueue; | 57 | private readonly BlockingQueue<TextureSender> m_sharedSendersQueue; |
58 | |||
45 | private readonly Scene m_scene; | 59 | private readonly Scene m_scene; |
46 | 60 | ||
47 | public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue) | 61 | public UserTextureDownloadService(Scene scene, BlockingQueue<TextureSender> sharedQueue) |
@@ -50,6 +64,12 @@ namespace OpenSim.Region.Environment.Modules | |||
50 | m_sharedSendersQueue = sharedQueue; | 64 | m_sharedSendersQueue = sharedQueue; |
51 | } | 65 | } |
52 | 66 | ||
67 | /// <summary> | ||
68 | /// Handle a texture request. This involves creating a texture sender and placing it on the | ||
69 | /// previously passed in shared queue. | ||
70 | /// </summary> | ||
71 | /// <param name="client"> </param> | ||
72 | /// <param name="e"></param> | ||
53 | public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e) | 73 | public void HandleTextureRequest(IClientAPI client, TextureRequestArgs e) |
54 | { | 74 | { |
55 | TextureSender textureSender; | 75 | TextureSender textureSender; |
@@ -72,8 +92,9 @@ namespace OpenSim.Region.Environment.Modules | |||
72 | else | 92 | else |
73 | { | 93 | { |
74 | TextureSender requestHandler = | 94 | TextureSender requestHandler = |
75 | new TextureSender(client, e.RequestedAssetID, e.DiscardLevel, e.PacketNumber); | 95 | new TextureSender(client, e.DiscardLevel, e.PacketNumber); |
76 | m_textureSenders.Add(e.RequestedAssetID, requestHandler); | 96 | m_textureSenders.Add(e.RequestedAssetID, requestHandler); |
97 | |||
77 | m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback); | 98 | m_scene.AssetCache.GetAsset(e.RequestedAssetID, TextureCallback); |
78 | } | 99 | } |
79 | } | 100 | } |
@@ -90,6 +111,12 @@ namespace OpenSim.Region.Environment.Modules | |||
90 | } | 111 | } |
91 | } | 112 | } |
92 | 113 | ||
114 | /// <summary> | ||
115 | /// The callback for the asset cache when a texture has been retrieved. This method queues the | ||
116 | /// texture sender for processing. | ||
117 | /// </summary> | ||
118 | /// <param name="textureID"></param> | ||
119 | /// <param name="asset"></param> | ||
93 | public void TextureCallback(LLUUID textureID, AssetBase asset) | 120 | public void TextureCallback(LLUUID textureID, AssetBase asset) |
94 | { | 121 | { |
95 | lock (m_textureSenders) | 122 | lock (m_textureSenders) |
@@ -115,6 +142,10 @@ namespace OpenSim.Region.Environment.Modules | |||
115 | } | 142 | } |
116 | } | 143 | } |
117 | 144 | ||
145 | /// <summary> | ||
146 | /// Place a ready texture sender on the processing queue. | ||
147 | /// </summary> | ||
148 | /// <param name="textureSender"></param> | ||
118 | private void EnqueueTextureSender(TextureSender textureSender) | 149 | private void EnqueueTextureSender(TextureSender textureSender) |
119 | { | 150 | { |
120 | textureSender.Cancel = false; | 151 | textureSender.Cancel = false; |
@@ -127,6 +158,9 @@ namespace OpenSim.Region.Environment.Modules | |||
127 | } | 158 | } |
128 | } | 159 | } |
129 | 160 | ||
161 | /// <summary> | ||
162 | /// Close this module. | ||
163 | /// </summary> | ||
130 | internal void Close() | 164 | internal void Close() |
131 | { | 165 | { |
132 | lock (m_textureSenders) | 166 | lock (m_textureSenders) |