[mapguide-commits] r6561 - in sandbox/liuar: . mtr mtr/Common/Renderers mtr/Common/Stylization mtr/Server/src/Common/Manager mtr/Server/src/Core mtr/Server/src/Services/Mapping mtr/Server/src/Services/Rendering mtr/Server/src/Services/Site

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Fri Mar 30 22:18:48 EDT 2012


Author: liuar
Date: 2012-03-30 19:18:48 -0700 (Fri, 30 Mar 2012)
New Revision: 6561

Added:
   sandbox/liuar/mtr/
Modified:
   sandbox/liuar/mtr/Common/Renderers/AGGImageIO.cpp
   sandbox/liuar/mtr/Common/Renderers/AGGImageIO.h
   sandbox/liuar/mtr/Common/Renderers/AGGRenderer.cpp
   sandbox/liuar/mtr/Common/Renderers/AGGRenderer.h
   sandbox/liuar/mtr/Common/Renderers/Renderers.vcxproj
   sandbox/liuar/mtr/Common/Stylization/LabelRenderer.cpp
   sandbox/liuar/mtr/Common/Stylization/LabelRenderer.h
   sandbox/liuar/mtr/Common/Stylization/Stylization.vcxproj
   sandbox/liuar/mtr/Server/src/Common/Manager/FdoConnectionManager.cpp
   sandbox/liuar/mtr/Server/src/Core/Server.cpp
   sandbox/liuar/mtr/Server/src/Core/serverconfig.ini
   sandbox/liuar/mtr/Server/src/Services/Mapping/MappingUtil.cpp
   sandbox/liuar/mtr/Server/src/Services/Mapping/MappingUtil.h
   sandbox/liuar/mtr/Server/src/Services/Mapping/ServerMappingService.cpp
   sandbox/liuar/mtr/Server/src/Services/Mapping/ServerMappingService.vcxproj
   sandbox/liuar/mtr/Server/src/Services/Rendering/ServerRenderingService.cpp
   sandbox/liuar/mtr/Server/src/Services/Rendering/ServerRenderingService.h
   sandbox/liuar/mtr/Server/src/Services/Rendering/ServerRenderingService.vcxproj
   sandbox/liuar/mtr/Server/src/Services/Site/SiteOperation.cpp
Log:
Multi-threads rendering branch


Property changes on: sandbox/liuar/mtr
___________________________________________________________________
Added: svn:mergeinfo
   + /sandbox/rfc94:5099-5163

Modified: sandbox/liuar/mtr/Common/Renderers/AGGImageIO.cpp
===================================================================
--- trunk/MgDev/Common/Renderers/AGGImageIO.cpp	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Common/Renderers/AGGImageIO.cpp	2012-03-31 02:18:48 UTC (rev 6561)
@@ -1119,7 +1119,162 @@
     gdImageDestroy(img2);
 }
 
+RS_ByteData* AGGImageIO::Combine(vector<RS_ByteData*>* data, const size_t start, const size_t end)
+{
+    vector<gdImagePtr> imgs;
+    imgs.reserve(end-start);
 
+    //TODO:
+    //TO BE Optimized
+    size_t firstNonEmptyData = 0;
+    for(size_t i = start; i<end; i++)
+    {
+        if((*data)[i]->GetNumBytes() != 0)
+        {
+            gdImagePtr img = gdImageCreateFromPngPtr((*data)[i]->GetNumBytes(),(*data)[i]->GetBytes());
+            imgs.push_back(img);
+            firstNonEmptyData = i;
+            break;
+        }
+    }
+
+    for(size_t i = firstNonEmptyData+1; i<end; i++)
+    {
+        if((*data)[i]->GetNumBytes() == 0)
+        {
+            continue;
+        }
+        gdImagePtr img = gdImageCreateFromPngPtr((*data)[i]->GetNumBytes(),(*data)[i]->GetBytes());
+        
+        gdImageSetTile(imgs[0], img);
+        gdImageFilledRectangle(imgs[0], 0, 0, gdImageSX(imgs[0])-1, gdImageSY(imgs[0])-1, gdTiled);
+        gdImageSaveAlpha(imgs[0], 1);
+        gdImageDestroy(img);
+    }
+
+    auto_ptr<RS_ByteData> byteData;
+    if(imgs.size() == 0)
+    {
+        byteData.reset(new RS_ByteData());
+    }
+    else
+    {
+        unsigned char* imgdata = NULL;
+        int size = 0;
+        imgdata = (unsigned char*)gdImagePngPtr(imgs[0], &size);
+
+    
+        byteData.reset((NULL == imgdata)? new RS_ByteData() : new RS_ByteData(imgdata, size));
+
+        gdFree(imgdata);
+        vector<gdImagePtr>::iterator it = imgs.begin();
+        while(it != imgs.end())
+        {
+            gdImageDestroy(*it);
+            it++;
+        }
+    }
+
+    return byteData.release();
+
+}
+
+RS_ByteData* AGGImageIO::Combine(vector<RS_ByteData*>* data,RS_ByteData* labelImg)
+{
+    vector<gdImagePtr> imgs;
+    imgs.reserve(data->size());
+
+    vector<RS_ByteData*>::iterator i = data->begin();
+
+    while(i != data->end())
+    {
+        if((*i)->GetNumBytes() != 0)
+        {
+            gdImagePtr img = gdImageCreateFromPngPtr((*i)->GetNumBytes(),(*i)->GetBytes());
+            imgs.push_back(img);
+            i++;
+            break;
+        }
+        i++;
+    }
+
+    while(i != data->end())
+    {
+        if((*i)->GetNumBytes() == 0)
+        {
+            i++;
+            continue;
+        }
+        gdImagePtr img = gdImageCreateFromPngPtr((*i)->GetNumBytes(),(*i)->GetBytes());
+        
+        gdImageSetTile(imgs[0], img);
+        gdImageFilledRectangle(imgs[0], 0, 0, gdImageSX(imgs[0])-1, gdImageSY(imgs[0])-1, gdTiled);
+        gdImageSaveAlpha(imgs[0], 1);
+        gdImageDestroy(img);
+        i++;
+    }
+    
+    if(imgs.size() != 0)
+    {
+        gdImagePtr labelImgPtr = gdImageCreateFromPngPtr(labelImg->GetNumBytes(),labelImg->GetBytes());
+        gdImageSetTile(imgs[0], labelImgPtr);
+        gdImageFilledRectangle(imgs[0], 0, 0, gdImageSX(imgs[0])-1, gdImageSY(imgs[0])-1, gdTiled);
+        gdImageSaveAlpha(imgs[0], 1);
+        gdImageDestroy(labelImgPtr);
+    }
+    else
+    {
+        imgs.push_back(gdImageCreateFromPngPtr(labelImg->GetNumBytes(),labelImg->GetBytes()));
+    }
+
+    unsigned char* imgdata = NULL;
+    int size = 0;
+    imgdata = (unsigned char*)gdImagePngPtr(imgs[0], &size);
+
+    auto_ptr<RS_ByteData> byteData;
+    byteData.reset((NULL == imgdata)? NULL : new RS_ByteData(imgdata, size));
+
+    gdFree(imgdata);
+    vector<gdImagePtr>::iterator it = imgs.begin();
+    while(it != imgs.end())
+    {
+        gdImageDestroy(*it);
+        it++;
+    }
+
+    return byteData.release();
+}
+
+RS_ByteData* AGGImageIO::ReadPNG(const RS_String& src)
+{
+    char mbfileIn[1024];
+    wcstombs(mbfileIn, src.c_str(), 1024);
+
+    // read in the images
+    FILE* fIn = fopen(mbfileIn, "rb");
+    
+    // get the size
+    fseek (fIn , 0 , SEEK_END);
+    int size = ftell (fIn);
+    rewind (fIn);
+
+    gdImagePtr img = gdImageCreateFromPng(fIn);
+
+    fclose(fIn);
+
+
+    unsigned char* data = NULL;
+
+    data = (unsigned char*)gdImagePngPtr(img, &size);
+
+    auto_ptr<RS_ByteData> byteData;
+    byteData.reset((NULL == data)? NULL : new RS_ByteData(data, size));
+
+    gdFree(data);
+
+    return byteData.release();
+}
+
 // NOTE: the returned buffer contains the *inverted* image
 unsigned int* AGGImageIO::DecodePNG(const unsigned char* src, size_t len, int& width, int& height)
 {

Modified: sandbox/liuar/mtr/Common/Renderers/AGGImageIO.h
===================================================================
--- trunk/MgDev/Common/Renderers/AGGImageIO.h	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Common/Renderers/AGGImageIO.h	2012-03-31 02:18:48 UTC (rev 6561)
@@ -30,16 +30,22 @@
     static RS_ByteData* Save(const RS_String& format,
                       unsigned int* src, int src_width, int src_height,
                       int dst_width, int dst_height, RS_Color& bgColor,
-                      RS_ColorVector* baseColorPalette = NULL);
+                      RS_ColorVector* baseColorPalette = NULL); 
 
     static void Combine(const RS_String& src1, const RS_String& src2, const RS_String& dst);
 
+    static RS_ByteData* Combine(std::vector<RS_ByteData*>* data,RS_ByteData* labelImg);
+
+    static RS_ByteData* Combine(std::vector<RS_ByteData*>* data, const size_t start, const size_t end);
+
     // NOTE: the returned buffer contains the *inverted* image
     static unsigned int* DecodePNG(const unsigned char* src, size_t len, int& width, int& height);
 
     // NOTE: the returned buffer contains the *non-inverted* image
     static unsigned int* DecodeJPEG(const unsigned char* src, size_t len, int& width, int& height);
 
+    static RS_ByteData* ReadPNG(const RS_String& src);
+
 private:
     static unsigned char* ReadFile(const RS_String& fname, size_t& len);
     static void UnmultiplyAlpha(unsigned int* argb, int len);

Modified: sandbox/liuar/mtr/Common/Renderers/AGGRenderer.cpp
===================================================================
--- trunk/MgDev/Common/Renderers/AGGRenderer.cpp	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Common/Renderers/AGGRenderer.cpp	2012-03-31 02:18:48 UTC (rev 6561)
@@ -237,7 +237,13 @@
     return m_rows;
 }
 
+void AGGRenderer::ClearBuffer()
+{
+    c()->ren.clear(agg::argb8_packed(m_bgcolor.argb()).premultiply());
 
+    //TODO: anything eles to clear??
+    //m_imsym->ren.clear(agg::argb8_packed(0x0));
+}
 //////////////////////////////////////////////////////////////////////////////
 // This one writes into a file not returning a bytestream using
 // default parameters for the width and height.
@@ -272,7 +278,21 @@
     AGGImageIO::Combine(fileIn1, fileIn2, fileOut);
 }
 
+RS_ByteData* AGGRenderer::Combine(vector<RS_ByteData*>* in, RS_ByteData* label)
+{
+    return AGGImageIO::Combine(in,label);
+}
 
+RS_ByteData* AGGRenderer::Combine(vector<RS_ByteData*>* in, size_t start, size_t end)
+{
+    return AGGImageIO::Combine(in,start,end);
+}
+
+RS_ByteData* AGGRenderer::ReadPNG(const RS_String& src)
+{
+    return AGGImageIO::ReadPNG(src);
+}
+
 //////////////////////////////////////////////////////////////////////////////
 void AGGRenderer::StartMap(RS_MapUIInfo* mapInfo,
                            RS_Bounds&    extents,
@@ -1103,7 +1123,17 @@
     return m_mapInfo;
 }
 
+LabelRendererBase* AGGRenderer::GetLabeler()
+{
+    return m_labeler;
+}
 
+
+void AGGRenderer::SetLabeler(LabelRendererBase* labeler)
+{
+    m_labeler = labeler;
+}
+
 //////////////////////////////////////////////////////////////////////////////
 RS_LayerUIInfo* AGGRenderer::GetLayerInfo()
 {

Modified: sandbox/liuar/mtr/Common/Renderers/AGGRenderer.h
===================================================================
--- trunk/MgDev/Common/Renderers/AGGRenderer.h	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Common/Renderers/AGGRenderer.h	2012-03-31 02:18:48 UTC (rev 6561)
@@ -149,12 +149,25 @@
     /////////////////////////////////////////////
     // AGGRenderer specific
     //
+    RENDERERS_API virtual LabelRendererBase* GetLabeler();
+    RENDERERS_API virtual void SetLabeler(LabelRendererBase* labeler);
+
+
     RENDERERS_API void Save(const RS_String& filename, const RS_String& format);
     RENDERERS_API void Save(const RS_String& filename, const RS_String& format, int width, int height);
     RENDERERS_API RS_ByteData* Save(const RS_String& format, int width, int height,
                                     RS_ColorVector* baseColorPalette = NULL);
 
     RENDERERS_API void Combine(const RS_String& fileIn1, const RS_String& fileIn2, const RS_String& fileOut);
+
+    RENDERERS_API RS_ByteData* Combine(vector<RS_ByteData*>*, RS_ByteData*);
+
+    RENDERERS_API RS_ByteData* Combine(vector<RS_ByteData*>* in, size_t start, size_t end);
+
+    RENDERERS_API RS_ByteData* ReadPNG(const RS_String& src);
+
+    RENDERERS_API void ClearBuffer();
+
     RENDERERS_API void SetWorldToScreenTransform(SE_Matrix& xform);
 
     RENDERERS_API void DrawString(const RS_String& s,

Modified: sandbox/liuar/mtr/Common/Renderers/Renderers.vcxproj
===================================================================
--- trunk/MgDev/Common/Renderers/Renderers.vcxproj	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Common/Renderers/Renderers.vcxproj	2012-03-31 02:18:48 UTC (rev 6561)
@@ -184,7 +184,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
       <OmitFramePointers>true</OmitFramePointers>
-      <AdditionalIncludeDirectories>..\MdfModel;..\Stylization;..\..\Oem\FDO\inc;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Oem\gd\gd;..\..\Oem\gd\freetype\include;..\..\Oem\agg-2.4\include;..\..\Oem\gd\lpng;..\..\Oem\agg-2.4\font_freetype;..\..\Oem\gd\zlib;..\..\Oem\FDO\inc\ExpressionEngine;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalIncludeDirectories>..\MdfModel;..\Stylization;..\..\Oem\ACE\ACE_wrappers;..\..\Oem\FDO\inc;..\..\Oem\DWFTK7.1\develop\global\src;..\..\Oem\DWFTK7.1\develop\global\src\dwf;..\..\Oem\gd\gd;..\..\Oem\gd\freetype\include;..\..\Oem\agg-2.4\include;..\..\Oem\gd\lpng;..\..\Oem\agg-2.4\font_freetype;..\..\Oem\gd\zlib;..\..\Oem\FDO\inc\ExpressionEngine;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;RENDERERS_EXPORTS;DWFCORE_STATIC;DWFTK_STATIC;DWFTK_USE_DWFCORE_ZLIB;DWFTK_BUILD_EXPAT;WHIP_STATIC_LIB;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>

Modified: sandbox/liuar/mtr/Common/Stylization/LabelRenderer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/LabelRenderer.cpp	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Common/Stylization/LabelRenderer.cpp	2012-03-31 02:18:48 UTC (rev 6561)
@@ -23,6 +23,10 @@
 
 extern void ProcessStylizerException(FdoException* exception, int line, wchar_t* file);
 
+#ifdef MULTI_RENDERERS
+ACE_Recursive_Thread_Mutex LabelRenderer::m_mutex;
+ACE_Recursive_Thread_Mutex LabelRenderer::m_mutex2;
+#endif
 
 //////////////////////////////////////////////////////////////////////////////
 LabelRenderer::LabelRenderer(SE_Renderer* se_renderer)
@@ -88,6 +92,9 @@
                                       LineBuffer*      path,
                                       double           scaleLimit)
 {
+    #ifdef MULTI_RENDERERS
+    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, m_mutex));
+    #endif
     // get the geometry type
     int geomType = (path != NULL)? path->geom_type() : FdoGeometryType_None;
 
@@ -182,6 +189,10 @@
                                       bool             exclude,
                                       LineBuffer*      /*path*/)
 {
+    #ifdef MULTI_RENDERERS
+    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, m_mutex));
+    #endif
+
     BeginOverpostGroup(type, true, exclude);
 
     // Add a new style SE label to the overpost groups.
@@ -346,7 +357,12 @@
     for (int i=0; i<npts; ++i)
         m_serenderer->ScreenToWorldPoint(pts[i].x, pts[i].y, tmp[i].x, tmp[i].y);
 
+    #ifdef MULTI_RENDERERS
+    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, m_mutex2));
+    #endif
+
     m_overpost.AddRegion(tmp, npts);
+
 }
 
 

Modified: sandbox/liuar/mtr/Common/Stylization/LabelRenderer.h
===================================================================
--- trunk/MgDev/Common/Stylization/LabelRenderer.h	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Common/Stylization/LabelRenderer.h	2012-03-31 02:18:48 UTC (rev 6561)
@@ -22,7 +22,9 @@
 #include "SimpleOverpost.h"
 #include "RS_FontEngine.h"
 #include "BIDIConverter.h"
-
+#ifdef MULTI_RENDERERS
+#include "ace/Thread_Manager.h" //For mutex
+#endif
 struct SE_RenderStyle;
 
 //////////////////////////////////////////////////////////////////////////////
@@ -139,6 +141,11 @@
     std::map<RS_String, size_t>  m_hStitchTable;
     SimpleOverpost               m_overpost;
     BIDIConverter                m_bidiConverter;
+
+#ifdef MULTI_RENDERERS
+    static ACE_Recursive_Thread_Mutex m_mutex;
+    static ACE_Recursive_Thread_Mutex m_mutex2;
+#endif
 };
 
 #endif

Modified: sandbox/liuar/mtr/Common/Stylization/Stylization.vcxproj
===================================================================
--- trunk/MgDev/Common/Stylization/Stylization.vcxproj	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Common/Stylization/Stylization.vcxproj	2012-03-31 02:18:48 UTC (rev 6561)
@@ -122,7 +122,7 @@
       <AdditionalOptions>$(USRCFLAGS) %(AdditionalOptions)</AdditionalOptions>
       <Optimization>Disabled</Optimization>
       <AdditionalIncludeDirectories>..\MdfModel;..\Foundation;..\..\Oem\ACE\ACE_wrappers;..\..\Oem\FDO\inc;..\..\Oem\FDO\inc\ExpressionEngine;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;STYLIZATION_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;STYLIZATION_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;MULTI_RENDERERS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -132,9 +132,9 @@
       <ShowIncludes>false</ShowIncludes>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>FDO.lib;FDOCommon.lib;ExpressionEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACEd.lib;FDO.lib;FDOCommon.lib;ExpressionEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgStylizationd.dll</OutputFile>
-      <AdditionalLibraryDirectories>..\..\Oem\FDO\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\..\Oem\FDO\lib64;MULTI_RENDERERS;..\..\Oem\ACE\ACE_wrappers\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <DelayLoadDLLs>FDO.dll;FDOCommon.dll;ExpressionEngine.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgStylizationd.pdb</ProgramDatabaseFile>
@@ -188,16 +188,16 @@
       <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
       <OmitFramePointers>false</OmitFramePointers>
       <AdditionalIncludeDirectories>..\MdfModel;..\Foundation;..\..\Oem\ACE\ACE_wrappers;..\..\Oem\FDO\inc;..\..\Oem\FDO\inc\ExpressionEngine;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;STYLIZATION_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;STYLIZATION_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;MULTI_RENDERERS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
     </ClCompile>
     <Link>
-      <AdditionalDependencies>FDO.lib;FDOCommon.lib;ExpressionEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>ACE.lib;FDO.lib;FDOCommon.lib;ExpressionEngine.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>$(OutDir)MgStylization.dll</OutputFile>
-      <AdditionalLibraryDirectories>..\..\Oem\FDO\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalLibraryDirectories>..\..\Oem\FDO\lib64;..\..\Oem\ACE\ACE_wrappers\lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <DelayLoadDLLs>FDO.dll;FDOCommon.dll;ExpressionEngine.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
       <GenerateDebugInformation>true</GenerateDebugInformation>
       <ProgramDatabaseFile>$(OutDir)MgStylization.pdb</ProgramDatabaseFile>

Modified: sandbox/liuar/mtr/Server/src/Common/Manager/FdoConnectionManager.cpp
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.cpp	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Common/Manager/FdoConnectionManager.cpp	2012-03-31 02:18:48 UTC (rev 6561)
@@ -250,15 +250,16 @@
             pFdoConnection = FindFdoConnection(resourceIdentifier);
         }
 
+        STRING longTransactionName = (STRING)featureSource->GetLongTransaction();
+
+        // Update the long transaction name to any active one for the current request
+        MgLongTransactionManager::GetLongTransactionName(resourceIdentifier, longTransactionName);
+
         if(NULL == pFdoConnection)
         {
             // Parse XML and get properties
             STRING configDocumentName = (STRING)featureSource->GetConfigurationDocument();
-            STRING longTransactionName = (STRING)featureSource->GetLongTransaction();
 
-            // Update the long transaction name to any active one for the current request
-            MgLongTransactionManager::GetLongTransactionName(resourceIdentifier, longTransactionName);
-
             // Create a new connection
             pFdoConnection = m_connManager->CreateConnection(provider.c_str());
 
@@ -294,6 +295,23 @@
                                resourceIdentifier->ToString(),
                                longTransactionName);
         }
+        // Workaround for TB job issue. 
+        // The job state of a TB connection may be changed during the connection life cycle. 
+        // But MG Server have no API to set the job state now. If we want to set the correct  
+        // job state for the connection, we need to call ActivateLongTransaction() to set the 
+        // job id again. 
+        else
+        {
+            if (providerInfo->GetProviderName() == L"Autodesk.Topobase" && longTransactionName != L"")
+            {
+                STRING tmpLtName = L"1";
+                if (longTransactionName != tmpLtName)
+                {
+                    ActivateLongTransaction(pFdoConnection, tmpLtName);
+                    ActivateLongTransaction(pFdoConnection, longTransactionName);
+                }
+            }
+        }
 
         #ifdef _DEBUG_FDOCONNECTION_MANAGER
         ShowProviderInfoCache();
@@ -684,9 +702,10 @@
                                 INT32 useLimit = providerInfo->GetUseLimit();
                                 if (useLimit == -1 || pFdoConnectionCacheEntry->nUseTotal <= useLimit)
                                 {
-                                    if((!pFdoConnectionCacheEntry->bInUse) ||
-                                       (providerInfo->GetThreadModel() == FdoThreadCapability_PerCommandThreaded) ||
-                                       (providerInfo->GetThreadModel() == FdoThreadCapability_MultiThreaded))
+                                    if((!pFdoConnectionCacheEntry->bInUse))
+                                    //if((!pFdoConnectionCacheEntry->bInUse) ||
+                                    //   (providerInfo->GetThreadModel() == FdoThreadCapability_PerCommandThreaded) ||
+                                    //   (providerInfo->GetThreadModel() == FdoThreadCapability_MultiThreaded))
                                     {
                                         // It is not in use or the provider is a PerCommandThreaded/MultiThreaded provider so claim it
                                         pFdoConnectionCacheEntry->lastUsed = ACE_OS::gettimeofday();

Modified: sandbox/liuar/mtr/Server/src/Core/Server.cpp
===================================================================
--- trunk/MgDev/Server/src/Core/Server.cpp	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Core/Server.cpp	2012-03-31 02:18:48 UTC (rev 6561)
@@ -36,6 +36,110 @@
 #include "Renderer.h"
 #include "MappingUtil.h"
 
+#ifdef _REALDWG
+#include "dbmain.h"
+#include "acestext.h"
+#include <dbapserv.h>
+
+class AcDsHostApp : public AcDbHostApplicationServices
+{
+    Acad::ErrorStatus findFile(wchar_t* pcFullPathOut, int nBufferLength,
+                         const wchar_t* pcFilename, AcDbDatabase* pDb = NULL,
+                         AcDbHostApplicationServices::FindFileHint hint = kDefault)
+    {
+        wchar_t pExtension[5];
+        switch (hint)
+        {
+            case kCompiledShapeFile:
+                wcscpy(pExtension, L".shx");
+                break;
+            case kTrueTypeFontFile:
+                wcscpy(pExtension, L".ttf");
+                break;
+            case kPatternFile:
+                wcscpy(pExtension, L".pat");
+                break;
+            case kARXApplication:
+                wcscpy(pExtension, L".dbx");
+                break;
+            case kFontMapFile:
+                wcscpy(pExtension, L".fmp");
+                break;
+            case kXRefDrawing:
+                wcscpy(pExtension, L".AcDs");
+                break;
+            case kFontFile:                // Fall through.  These could have
+            case kEmbeddedImageFile:       // various extensions
+            default:
+                pExtension[0] = L'\0';
+                break;
+        }
+        wchar_t* filePart;
+        DWORD result;
+        result = SearchPath(NULL, pcFilename, pExtension, nBufferLength,
+                            pcFullPathOut, &filePart);
+        if (result && result < (DWORD)nBufferLength)
+            return Acad::eOk;
+        else
+            return Acad::eFileNotFound;
+    }
+};
+static AcDsHostApp *s_pApp = NULL;
+static AcDbDatabase *s_pWorkingDatabase = NULL;
+
+const STRING RealDWGLCID            = L"RealDWGLCID";
+
+void initRealDWG(long lcid)
+{
+    MG_TRY()
+
+    // Initialization: needs to be done when MapGuide executable initializes.
+    //
+    // We are running outside ACAD.
+    // Create application services
+    //
+    s_pApp = new AcDsHostApp;
+    Acad::ErrorStatus stat = acdbSetHostApplicationServices(s_pApp);
+    if ( stat != Acad::eOk )
+        throw FdoException::Create(acadErrorStatusText(stat));
+
+    MgConfiguration* pConfiguration = MgConfiguration::GetInstance();
+    ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Initializing RealDWG with language:%d.\n"), lcid));
+    stat = acdbValidateSetup(lcid);
+    ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) RealDWG is initialized with language:%d.\n"), lcid));
+    if ( stat != Acad::eOk )
+        throw FdoException::Create(acadErrorStatusText(stat));
+
+    // RealDWG needs the working database to be set. Create a dummy database
+    // for this purpose. Setting it as the working database does not affect
+    // the access of other databases.
+    s_pWorkingDatabase = new AcDbDatabase(Adesk::kTrue, Adesk::kTrue);
+    s_pApp->setWorkingDatabase(s_pWorkingDatabase);
+
+    MG_CATCH_AND_THROW(L"initRealDWG");
+}
+
+void cleanupRealDWG()
+{
+    MG_TRY()
+
+    if (s_pApp)
+    {
+        if ( s_pWorkingDatabase ) 
+        {
+            s_pApp->setWorkingDatabase(NULL);
+            delete s_pWorkingDatabase;
+        }
+        acdbCleanUp();
+        delete s_pApp;
+    }
+
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%t) RealDWG is cleaned up.\n")));
+
+    MG_CATCH_AND_THROW(L"cleanupRealDWG");
+}
+#endif
+
 #ifdef _DEBUG
 void DebugOutput(const ACE_TCHAR* format, ...)
 {
@@ -926,6 +1030,12 @@
             ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) MgServer::open() - Initializing Event Timer Manager.\n")));
             m_eventTimerManager.Initialize();
 
+#ifdef _REALDWG
+            int lcid = 0x00000409;  // English
+            pConfiguration->GetIntValue(MgConfigProperties::GeneralPropertiesSection, RealDWGLCID, lcid, 0x00000409);
+            initRealDWG(lcid);
+#endif
+
             // Feature Service
             bool bDataConnectionPoolEnabled = MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolEnabled;
             INT32 nDataConnectionPoolSize = MgConfigProperties::DefaultFeatureServicePropertyDataConnectionPoolSize;
@@ -1233,6 +1343,10 @@
         nResult = svc();
     }
 
+#ifdef _REALDWG
+    cleanupRealDWG();
+#endif
+
     MG_LOG_TRACE_ENTRY(L"MgServer::open() - End");
     return nResult;
 }

Modified: sandbox/liuar/mtr/Server/src/Core/serverconfig.ini
===================================================================
--- trunk/MgDev/Server/src/Core/serverconfig.ini	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Core/serverconfig.ini	2012-03-31 02:18:48 UTC (rev 6561)
@@ -41,6 +41,8 @@
 # DefaultMessageLocale             ISO 639-1 name for the message locale
 #                                       Length = 2
 #                                       Example: en
+# RealDWGLCID                      LCID of the locale of RealDWG. (not used by MapGuide Open Source)
+#                                       Example: 1033
 # DisplayName                      Display name of the server
 #                                       0 <= Length <= 255
 #                                       Reserved Characters: \/:*?"<>|
@@ -86,6 +88,7 @@
 ConnectionTimeout                  = 120
 ConnectionTimerInterval            = 60
 DefaultMessageLocale               = en
+RealDWGLCID                        = 1033
 DisplayName                        =
 FdoPath                            = FDO/
 LicenseServerPath                  = @localhost

Modified: sandbox/liuar/mtr/Server/src/Services/Mapping/MappingUtil.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/MappingUtil.cpp	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Services/Mapping/MappingUtil.cpp	2012-03-31 02:18:48 UTC (rev 6561)
@@ -30,8 +30,8 @@
 #include "Stylizer.h"
 #include "SymbolVisitor.h"
 #include "SymbolDefinition.h"
-#include "TransformCache.h"
 
+
 #include <algorithm>
 
 //For logging
@@ -49,6 +49,8 @@
 extern long GetTickCount();
 #endif
 
+#define POOL_SIZE 4
+#define MAX_TIMEOUT 100000000
 
 ///////////////////////////////////////////////////////////////////////////////
 MdfModel::MapDefinition* MgMappingUtil::GetMapDefinition(MgResourceService* svcResource, MgResourceIdentifier* resId)
@@ -369,7 +371,12 @@
                                   double scale,
                                   bool selection,
                                   bool extractColors,
-                                  ProfileRenderLayersResultBase* pPRLsResult)
+                                  ProfileRenderLayersResultBase* pPRLsResult,
+                                  deque<Renderer*>* subRenderers,
+                                  vector<RS_ByteData*>* subImgs,
+                                  INT32 saveWidth,
+                                  INT32 saveHeight,
+                                  STRING format)
 {
     #ifdef _DEBUG
     long dwStart = GetTickCount();
@@ -380,6 +387,16 @@
     // stylization operation.
     TransformCacheMap transformCache;
 
+    #ifdef MULTI_RENDERERS    
+
+    // Create a LayerRenderingWorkers pool
+    LayerRenderingWorkers pool;
+    pool.activate(THR_NEW_LWP | THR_JOINABLE, POOL_SIZE);
+    //vector<RenderData> renderData;
+    //renderData.reserve(layers->GetCount());
+
+    #endif
+
     // Get the layers' resource content in a single request by adding them to a collection
     for (int i = layers->GetCount()-1; i >= 0; i--)
     {
@@ -387,7 +404,7 @@
         RSMgFeatureReader* rsReader = NULL;
 
         Ptr<MgLayerBase> mapLayer = layers->GetItem(i);
-
+        
         //don't send data if layer is not currently visible
         if ((!selection) && (!mapLayer->IsVisible()))
             continue;
@@ -405,8 +422,42 @@
             if (!needsRefresh)
                 continue;
         }
+#ifdef MULTI_RENDERERS
 
+        
+        RenderData renderData;
 
+        renderData.pPRLsResult = pPRLsResult;
+        renderData.i = i;
+        renderData.mapLayer = mapLayer;
+        renderData.scale = scale;
+        renderData.svcResource = svcResource;
+        renderData.svcDrawing = svcDrawing;
+        renderData.svcFeature = svcFeature;
+        renderData.map = map;
+        renderData.selection = selection;
+        renderData.expandExtents = expandExtents;
+        renderData.csFactory = csFactory;
+        renderData.dstCs = dstCs;
+        renderData.overrideFilters = overrideFilters;
+        renderData.extractColors = extractColors;
+        renderData.sub_drs = subRenderers;
+        renderData.transformCache = &transformCache;
+        renderData.saveWidth = saveWidth;
+        renderData.saveHeight = saveHeight;
+        renderData.format = format;
+        size_t displayOrder = subImgs->size()-(size_t)(mapLayer->GetDisplayOrder()/100);
+        renderData.subImg = (RS_ByteData**)(&subImgs->at(displayOrder));
+
+        
+        ACE_Message_Block *mb = new ACE_Message_Block(sizeof(RenderData));
+        //ACE_CDR::mb_align(mb); //MR_TODO: I need to figure out why.
+        ACE_OS::memcpy(mb->wr_ptr(), &renderData, sizeof(RenderData)); 
+
+        // Ask the worker pool to do the job.
+        pool.putq (mb);
+
+#else
         #ifdef _DEBUG
         long dwLayerStart = GetTickCount();
         ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **LAYERSTART** Name:%W  VAS:%W\n", i, (mapLayer->GetName()).c_str(), mapLayer->IsVisibleAtScale(scale)? L"True" : L"False"));
@@ -917,9 +968,15 @@
                 pPRLResult->SetError(message);
             }
         } // if exception
+#endif
+        
     } // for all layers
-
-
+#ifdef MULTI_RENDERERS
+    ACE_Message_Block *mb = new ACE_Message_Block(0,ACE_Message_Block::MB_HANGUP);
+    pool.putq (mb);
+    
+    ACE_Thread_Manager::instance()->wait_grp(pool.grp_id());
+#endif
     #ifdef _DEBUG
     ACE_DEBUG((LM_INFO, L"(%t)StylizeLayers() **MAPDONE** Layers:%d  Total Time:%6.4f (s)\n\n", layers->GetCount(), (GetTickCount()-dwStart)/1000.0));
     #endif
@@ -927,7 +984,10 @@
     TransformCache::Clear(transformCache);
 }
 
-
+void* MgMappingUtil::RenderLayer(void* param)
+{
+    return NULL;
+}
 ///////////////////////////////////////////////////////////////////////////////
 // When rendering a tile, we need to compute the extent used to determine
 // which features to render into it.  Features in adjacent tiles, but not
@@ -1581,3 +1641,619 @@
         }
     }
 }
+
+int LayerRenderingWorkers::svc()
+{
+    while(true)
+    {
+        ACE_Message_Block *mb = NULL;
+        if (this->getq (mb) == -1)
+          {
+            ACE_DEBUG ((LM_DEBUG,
+                        ACE_TEXT ("LayerRenderingWorkers shutting down\n")));
+            break;
+          }
+
+        if (mb->msg_type () == ACE_Message_Block::MB_HANGUP)
+          {
+            ACE_DEBUG ((LM_DEBUG,
+                        ACE_TEXT ("LayerRenderingWorkers shutting down\n")));
+            this->putq(mb);
+            break;
+          }
+
+        // Process the message.
+        process_message (mb);
+
+    }
+
+    return 0;
+}
+
+void LayerRenderingWorkers::process_message(ACE_Message_Block *mb)
+{
+    static ACE_Recursive_Thread_Mutex sg_subRenderersMutex;
+
+    ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Processing message\n")));
+
+    RenderData* renderData = new RenderData();
+    ACE_OS::memcpy(renderData, mb->rd_ptr(), sizeof(RenderData));
+    mb->release ();
+
+
+    Ptr<MgUserInformation> adminUserInfo = new MgUserInformation(MgUser::Administrator, L"");
+    MgUserInformation::SetCurrentUserInfo(adminUserInfo);
+
+    auto_ptr<MdfModel::LayerDefinition> ldf;
+    RSMgFeatureReader* rsReader = NULL;
+
+    //RenderData* renderData = static_cast<RenderData*>(mb->data_block());
+    int i = renderData->i;
+    MgLayerBase* mapLayer = renderData->mapLayer;
+    double scale = renderData->scale;
+    ProfileRenderLayersResultBase* pPRLsResult = renderData->pPRLsResult;
+    MgResourceService* svcResource = renderData->svcResource;
+    MgFeatureService* svcFeature = renderData->svcFeature;
+    MgDrawingService* svcDrawing = renderData->svcDrawing;
+    MgMap* map = renderData->map;
+    bool selection = renderData->selection;
+    bool expandExtents = renderData->expandExtents;
+    MgCoordinateSystemFactory* csFactory = renderData->csFactory;
+    MgCoordinateSystem* dstCs = renderData->dstCs;
+    MgStringCollection* overrideFilters = renderData->overrideFilters;
+    TransformCacheMap* pTransformCache = renderData->transformCache;
+    bool extractColors = renderData->extractColors;
+    deque<Renderer*>* subRenderers = renderData->sub_drs;
+    
+    Renderer* dr = NULL;
+    {
+        ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sg_subRenderersMutex));
+        if(subRenderers->front() != NULL)
+        {
+            dr = subRenderers->front();
+            subRenderers->pop_front();
+        }
+        else
+        {
+            ACE_DEBUG ((LM_INFO,ACE_TEXT ("Renderers Fetching Error!")));
+        }
+        
+    }
+
+    INT32 saveWidth = renderData->saveWidth;
+    INT32 saveHeight = renderData->saveHeight;
+    STRING format = renderData->format;
+    
+
+    // initialize the stylizer
+    RSMgSymbolManager mgr(svcResource);
+    dr->SetSymbolManager(&mgr);
+
+    SEMgSymbolManager semgr(svcResource);
+    DefaultStylizer* ds = new DefaultStylizer(&semgr);
+
+    RS_Color bgcolor(0, 0, 0, 255); //not used -- GDRenderer is already initialized to the correct bgcolor
+
+    #ifdef _DEBUG
+    long dwLayerStart = GetTickCount();
+    ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **LAYERSTART** Name:%W  VAS:%W\n", i, (mapLayer->GetName()).c_str(), mapLayer->IsVisibleAtScale(scale)? L"True" : L"False"));
+    #endif
+
+
+
+    MG_SERVER_MAPPING_SERVICE_TRY()
+
+        // Just profile visible layers?
+        TransformCache* TCForProfile = NULL;
+        double minScale_Profile = 0.0;
+        double maxScale_Profile = MdfModel::VectorScaleRange::MAX_MAP_SCALE;
+        if(NULL != pPRLsResult)
+        {
+            ProfileRenderLayerResult* pPRLResult = new ProfileRenderLayerResult(); // points points to Profile Render Layers Result
+               
+            // Set the start time of stylizing layer
+            pPRLResult->SetRenderTime(MgTimerUtil::GetTime());
+
+            ProfileRenderLayerResultCollection* pPRLResultColl = pPRLsResult->GetProfileRenderLayerResults();
+            pPRLResultColl->Adopt(pPRLResult);
+        }
+
+        //get layer definition
+        Ptr<MgResourceIdentifier> layerid = mapLayer->GetLayerDefinition();
+        ldf.reset(MgLayerBase::GetLayerDefinition(svcResource, layerid));
+     
+
+        Ptr<MgLayerGroup> group = mapLayer->GetGroup();
+
+        MgLogDetail logDetail(MgServiceType::MappingService, MgLogDetail::InternalTrace, L"MgMappingUtil.StylizeLayers", mgStackParams);
+        logDetail.AddString(L"Map",map->GetName());
+
+        logDetail.AddResourceIdentifier(L"LayerId",layerid);
+        logDetail.Create();
+
+        //base map layers are not editable
+        bool bEditable = true;
+        if (mapLayer->GetLayerType() == MgLayerType::BaseMap)
+            bEditable = false;
+
+        //layer legend and ui specific information
+        RS_UIGraphic uig(NULL, 0, mapLayer->GetLegendLabel());
+        RS_LayerUIInfo layerInfo( mapLayer->GetName(),
+                                    mapLayer->GetObjectId(),
+                                    mapLayer->GetSelectable(),
+                                    mapLayer->GetVisible(),
+                                    bEditable,
+                                    (group.p)? group->GetName() : L"",
+                                    (group.p)? group->GetObjectId() : L"",
+                                    mapLayer->GetDisplayInLegend(),
+                                    mapLayer->GetExpandInLegend(),
+                                    -mapLayer->GetDisplayOrder(),
+                                    uig);
+
+        MdfModel::VectorLayerDefinition* vl = dynamic_cast<MdfModel::VectorLayerDefinition*>(ldf.get());
+        MdfModel::DrawingLayerDefinition* dl = dynamic_cast<MdfModel::DrawingLayerDefinition*>(ldf.get());
+        MdfModel::GridLayerDefinition* gl = dynamic_cast<MdfModel::GridLayerDefinition*>(ldf.get());
+
+        if (vl) //############################################################################ vector layer
+        {
+            // Modify the layer scale range to also support infinite
+            // Need to apply default style as one will not be defined
+            if (selection)
+            {
+                MdfModel::VectorScaleRangeCollection* scaleRanges = vl->GetScaleRanges();
+                if (scaleRanges)
+                {
+                    MdfModel::VectorScaleRange* scaleRange = scaleRanges->GetAt(0);
+                    if (scaleRange)
+                    {
+                        scaleRange->SetMinScale(0.0);
+                        scaleRange->SetMaxScale(MdfModel::VectorScaleRange::MAX_MAP_SCALE);
+                    }
+                }
+            }
+
+            // make sure we have a valid scale range
+            MdfModel::VectorScaleRange* scaleRange = Stylizer::FindScaleRange(*vl->GetScaleRanges(), scale);
+
+            if (scaleRange)
+            {
+                minScale_Profile = scaleRange->GetMinScale();
+                maxScale_Profile = scaleRange->GetMaxScale();
+
+                #ifdef _DEBUG
+                ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **Stylizing** Name:%W\n", i, (mapLayer->GetName()).c_str()));
+                #endif
+
+                // get feature source id
+                STRING sfeatResId = vl->GetResourceID();
+                Ptr<MgResourceIdentifier> featResId = new MgResourceIdentifier(sfeatResId);
+
+                // get the feature extent to use with the query
+                RS_Bounds extent = dr->GetBounds();
+
+                // if requested, expand the feature extent to account for stylization
+                if (expandExtents)
+                {
+                    // get the additional offset to account for stylization
+                    double mcsOffset = MgMappingUtil::ComputeStylizationOffset(map, scaleRange, scale);
+                    extent.minx -= mcsOffset;
+                    extent.miny -= mcsOffset;
+                    extent.maxx += mcsOffset;
+                    extent.maxy += mcsOffset;
+                }
+
+                #ifdef _DEBUG
+                ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **Stylizing** Name:%W  Extents:%f,%f to %f,%f Expanded:%d\n", i, (mapLayer->GetName()).c_str(), extent.minx, extent.miny, extent.maxx, extent.maxy, expandExtents));
+                #endif
+
+                //get a transform from layer coord sys to map coord sys
+                TransformCache* item = TransformCache::GetLayerToMapTransform(*pTransformCache, vl->GetFeatureName(), featResId, dstCs, csFactory, svcFeature);
+                TCForProfile = item;
+                Ptr<MgCoordinateSystem> layerCs = item? item->GetCoordSys() : NULL;
+                MgCSTrans* xformer = item? item->GetTransform() : NULL;
+
+                //extract hyperlink and tooltip info
+                if (!vl->GetToolTip().empty()) layerInfo.hastooltips() = true;
+                if (vl->GetUrlData() && !vl->GetUrlData()->GetUrlContent().empty())
+                {
+                    layerInfo.hashyperlinks() = true;
+                }
+
+                //set up the property name mapping -- it tells us what
+                //string the viewer should be displaying as the name of each
+                //feature property
+                // TODO: check to see if name is FeatureClass or Extension name
+                RS_FeatureClassInfo fcinfo(vl->GetFeatureName());
+
+                MdfModel::NameStringPairCollection* pmappings = vl->GetPropertyMappings();
+                for (int j=0; j<pmappings->GetCount(); j++)
+                {
+                    MdfModel::NameStringPair* m = pmappings->GetAt(j);
+                    fcinfo.add_mapping(m->GetName(), m->GetValue());
+                }
+
+                // check for overridden feature query filter and remember it.
+                // we will use this when making feature queries
+                STRING overrideFilter = L"";
+                if (overrideFilters)
+                    overrideFilter = overrideFilters->GetItem(i);
+
+                #ifdef _DEBUG
+                ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **Stylizing** Name:%W  Override Filter(size=%d):\n%W\n", i, (mapLayer->GetName()).c_str(), overrideFilter.length(), overrideFilter.empty() ? L"(Empty)" : overrideFilter.c_str()));
+                #endif
+
+                // create the reader we'll use
+                rsReader = MgMappingUtil::ExecuteFeatureQuery(svcFeature, extent, vl, overrideFilter.c_str(), dstCs, layerCs, item);
+                // create an automatic FdoPtr around the reader
+                FdoPtr<FdoIFeatureReader> fdoReader = (NULL == rsReader) ? NULL : rsReader->GetInternalReader();
+
+                #ifdef _DEBUG
+                ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **Stylizing** Name:%W  Query Done.\n", i, (mapLayer->GetName()).c_str()));
+                #endif
+
+                if (NULL != fdoReader.p)
+                {
+                    // stylize into output format
+                    dr->StartLayer(&layerInfo, &fcinfo);
+                    ds->StylizeVectorLayer(vl, dr, rsReader, xformer, scale, NULL, NULL);
+                    dr->EndLayer();
+
+                    // color extraction for RFC60 only when needed
+                    if (extractColors)
+                    {
+                        #ifdef _DEBUG
+                        ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) //ExtractColors// -Vector- Name:%W  Time:%6.4f (s)\n", i, (mapLayer->GetName()).c_str(), (GetTickCount()-dwLayerStart)/1000.0));
+                        #endif
+                        MgMappingUtil::ExtractColors(map, scaleRange, ds);
+                        #ifdef _DEBUG
+                        ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) ##ExtractColors## -Vector- Name:%W  Time:%6.4f (s)\n", i, (mapLayer->GetName()).c_str(), (GetTickCount()-dwLayerStart)/1000.0));
+                        #endif
+                    }
+                }
+            }
+            else  // not scaleRange
+            {
+                #ifdef _DEBUG
+                ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **NOT Stylizing - NO SCALE RANGE** Name:%W\n", i, (mapLayer->GetName()).c_str()));
+                #endif
+            }
+
+            #ifdef _DEBUG
+            ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **LAYEREND** -Vector- Name:%W  Time:%6.4f (s)\n", i, (mapLayer->GetName()).c_str(), (GetTickCount()-dwLayerStart)/1000.0));
+            #endif
+        }
+        else if (gl) //############################################################################ grid layer
+        {
+            // TODO: FDO RFP - Make FdoPtr's reference counter thread-safe.
+            static ACE_Recursive_Thread_Mutex sg_fdoRfpMutex;
+
+            // make sure we have a valid scale range
+            MdfModel::GridScaleRange* scaleRange = Stylizer::FindScaleRange(*gl->GetScaleRanges(), scale);
+
+            if (scaleRange)
+            {
+                minScale_Profile = scaleRange->GetMinScale();
+                maxScale_Profile = scaleRange->GetMaxScale();
+
+                //get feature source id
+                STRING sfeatResId = gl->GetResourceID();
+                Ptr<MgResourceIdentifier> featResId = new MgResourceIdentifier(sfeatResId);
+
+                // get the feature extent to use with the query
+                RS_Bounds extent = dr->GetBounds();
+
+                #ifdef _DEBUG
+                ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **Stylizing** Name:%W  Extents:%f,%f to %f,%f\n", i, (mapLayer->GetName()).c_str(), extent.minx, extent.miny, extent.maxx, extent.maxy));
+                #endif
+
+                //now get the coordinate system of the layer data
+                // Feature Service caches these so we only take the performance hit on
+                // the 1st one that is not cached.
+
+                // Need to determine the name of the spatial context for this layer
+                MdfModel::MdfString featureName = gl->GetFeatureName();
+
+                //get a transform from layer coord sys to map coord sys
+                TransformCache* item = NULL;
+                {
+                    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sg_fdoRfpMutex));
+                    item = TransformCache::GetLayerToMapTransform(*pTransformCache, gl->GetFeatureName(), featResId, dstCs, csFactory, svcFeature);
+                }
+                TCForProfile = item;
+
+                Ptr<MgCoordinateSystem> layerCs = item? item->GetCoordSys() : NULL;
+                MgCSTrans* xformer = item? item->GetTransform() : NULL;
+
+                // Test if layer and map are using the same coordinate systems
+                if (NULL == layerCs.p || NULL == dstCs || layerCs->GetCsCode() == dstCs->GetCsCode())
+                {
+                    // No transform required
+                    xformer = NULL;
+                }
+
+                //set up the property name mapping -- it tells us what
+                //string the viewer should be displaying as the name of each
+                //feature property
+                // TODO: check to see if name is FeatureClass or Extension name
+                RS_FeatureClassInfo fcinfo(gl->GetFeatureName());
+
+                //check for overridden feature query filter and remember it.
+                //we will use this when making feature queries
+                STRING overrideFilter = L"";
+                if (overrideFilters)
+                    overrideFilter = overrideFilters->GetItem(i);
+
+                // Clip request bounds to limits of spatial context for layer
+                // Some WMS/WFS servers fail if request bounds are out of range.
+                // On error, ignore the exception and use the original extent.
+                MG_TRY()
+                Ptr<MgSpatialContextReader> contextReader = svcFeature->GetSpatialContexts(featResId, false);
+                STRING layerWkt = layerCs->ToString();
+                while (contextReader.p != NULL && contextReader->ReadNext())
+                {
+                    // Try to find wkt for feature's coordinate system
+                    STRING code = contextReader->GetCoordinateSystem();
+                    STRING wkt = contextReader->GetCoordinateSystemWkt();
+                    if (wkt.empty() && !code.empty())
+                    {
+                        MgCoordinateSystemFactory factory;
+                        wkt = factory.ConvertCoordinateSystemCodeToWkt(code);
+                    }
+
+                    // If the source data does not have a coordinate system, or it is the same
+                    // as the layer then we are probably using the right spatial context
+                    if (wkt.empty() || wkt == layerWkt)
+                    {
+                        // If the extent is known, clip the request to it.
+                        Ptr<MgByteReader> agfExtent = contextReader->GetExtent();
+                        MgAgfReaderWriter agfReader;
+                        Ptr<MgGeometry> geom = agfReader.Read(agfExtent);
+                        if (geom != NULL)
+                        {
+                            Ptr<MgEnvelope> envelope = geom->Envelope();
+                            Ptr<MgCoordinate> ll = envelope->GetLowerLeftCoordinate();
+                            Ptr<MgCoordinate> ur = envelope->GetUpperRightCoordinate();
+                            double llx = ll->GetX();
+                            double lly = ll->GetY();
+                            double urx = ur->GetX();
+                            double ury = ur->GetY();
+
+                            #ifdef _DEBUG
+                            ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **Stylizing** Name:%W  Extents(SpatialContext):%f,%f to %f,%f\n", i, (mapLayer->GetName()).c_str(), llx, lly, urx, ury));
+                            #endif
+
+                            if (NULL != xformer)
+                                xformer->TransformExtent(llx, lly, urx, ury);
+                            RS_Bounds layerExtent(llx, lly, urx, ury);
+                            RS_Bounds clippedExtent = RS_Bounds::Intersect(extent, layerExtent);
+                            if (clippedExtent.IsValid())
+                            {
+                                extent = clippedExtent;
+                            }
+                        }
+                        break;
+                    }
+                }
+                if(contextReader.p != NULL)
+                    contextReader->Close();
+
+                MG_CATCH_AND_RELEASE()
+
+                #ifdef _DEBUG
+                ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **Stylizing** Name:%W  Extents(Using):%f,%f to %f,%f\n", i, (mapLayer->GetName()).c_str(), extent.minx, extent.miny, extent.maxx, extent.maxy));
+                #endif
+
+                double pixelsPerMapUnit = dr->GetMetersPerUnit() / METERS_PER_INCH * dr->GetDpi() / dr->GetMapScale();
+                int width = (int)(extent.width() * pixelsPerMapUnit + 0.5);
+                int height = (int)(extent.height() * pixelsPerMapUnit + 0.5);
+
+                //perform the raster query
+                FdoPtr<FdoIFeatureReader> fdoReader;
+                {
+                    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sg_fdoRfpMutex));
+                    rsReader = MgMappingUtil::ExecuteRasterQuery(svcFeature, extent, gl, overrideFilter.c_str(), dstCs, layerCs, width, height);
+                    fdoReader = (NULL == rsReader) ? NULL : rsReader->GetInternalReader();
+                }
+
+                if (NULL != fdoReader.p)
+                {
+                    //stylize grid layer
+                    dr->StartLayer(&layerInfo, &fcinfo);
+                    ds->StylizeGridLayer(gl, dr, rsReader, xformer, scale, NULL, NULL);
+                    dr->EndLayer();
+                }
+            }
+
+            #ifdef _DEBUG
+            ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **LAYEREND** -Grid- Name:%W  Time:%6.4f (s)\n", i, (mapLayer->GetName()).c_str(), (GetTickCount()-dwLayerStart)/1000.0));
+            #endif
+        }
+        else if (dl) //############################################################################ drawing layer
+        {
+            minScale_Profile = dl->GetMinScale();
+            maxScale_Profile = dl->GetMaxScale();
+
+            // make sure we have a valid scale range
+            if (scale >= dl->GetMinScale() && scale < dl->GetMaxScale())
+            {
+                Ptr<MgResourceIdentifier> resId = new MgResourceIdentifier(dl->GetResourceID());
+
+                //get the resource content to see if there is a coordinate system
+                Ptr<MgByteReader> rdr = svcResource->GetResourceContent(resId);
+                STRING st = rdr->ToString();
+
+                //now look for a coordinate space tag and extract the contents
+                size_t i0 = st.find(L"<CoordinateSpace>");
+                size_t i1 = st.find(L"</CoordinateSpace>");
+
+                TransformCache* cached = NULL;
+                MgCSTrans* xformer = NULL;
+
+                if (i0 != STRING::npos && i1 != STRING::npos)
+                {
+                    i0 += wcslen(L"<CoordinateSpace>");
+                    STRING cs = st.substr(i0, i1 - i0);
+
+                    if (!cs.empty() && cs != dstCs->ToString())
+                    {
+                        // Create coordinate system transformer
+                        TransformCacheMap::const_iterator iter = pTransformCache->find(cs);
+                        if (pTransformCache->end() != iter) cached = (*iter).second;
+                        if (NULL != cached)
+                        {
+                            xformer = cached->GetTransform();
+                        }
+                        else
+                        {
+                            Ptr<MgCoordinateSystem> srcCs = csFactory->Create(cs);
+                            if (srcCs.p)
+                            {
+                                xformer = new MgCSTrans(srcCs, dstCs);
+                                cached = new TransformCache(xformer, srcCs);
+                                pTransformCache->operator[](cs) = cached;
+                            }
+                        }
+                    }
+                }
+                TCForProfile = cached;
+
+                //get DWF from drawing service
+                Ptr<MgByteReader> reader = svcDrawing->GetSection(resId, dl->GetSheet());
+
+                RSMgInputStream is(reader);
+
+                dr->StartLayer(&layerInfo, NULL);
+                ds->StylizeDrawingLayer(dl, dr, &is, xformer, scale);
+                dr->EndLayer();
+            }
+
+            #ifdef _DEBUG
+            ACE_DEBUG((LM_INFO, L"(%t)  StylizeLayers(%d) **LAYEREND** -Drawing- Name:%W  Time = %6.4f (s)\n", i, (mapLayer->GetName()).c_str(), (GetTickCount()-dwLayerStart)/1000.0));
+            #endif
+        } // end layer switch
+
+        
+
+        //dr->EndMap();
+        *(renderData->subImg) = ((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight,NULL);
+        ((AGGRenderer*)dr)->ClearBuffer();
+        {
+            ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sg_subRenderersMutex));
+            subRenderers->push_back(dr);       
+        }
+
+        if(NULL != pPRLsResult)
+        {
+            ProfileRenderLayerResultCollection* pPRLResultColl = pPRLsResult->GetProfileRenderLayerResults();
+                
+            // Get current ProfileRenderLayerResult
+            ProfileRenderLayerResult* pPRLResult = pPRLResultColl->GetAt(pPRLResultColl->GetCount()-1); //TODO: check index
+                
+            // Calculate the time spent on stylizing layer
+            double stylizeLayerTime = MgTimerUtil::GetTime() - pPRLResult->GetRenderTime();
+            pPRLResult->SetRenderTime(stylizeLayerTime);
+
+            pPRLResult->SetResourceId(layerid->ToString());
+            pPRLResult->SetLayerName(mapLayer->GetName());
+
+            if(vl)
+            {
+                pPRLResult->SetLayerType(L"Vector Layer"); //NOXLATE?
+            }
+            else if(dl)
+            {
+                pPRLResult->SetLayerType(L"Drawing Layer"); //NOXLATE?
+            }
+            else if(gl)
+            {
+                pPRLResult->SetLayerType(L"Grid Layer"); //NOXLATE?
+            }
+            else
+            {
+                pPRLResult->SetLayerType(L"Unknown Type"); //NOXLATE?
+            }
+                
+            pPRLResult->SetFeatureClassName(mapLayer->GetFeatureClassName());
+
+            STRING layerCsCode = L"";
+            if(NULL != TCForProfile)
+            {
+                Ptr<MgCoordinateSystem> layerCS = TCForProfile->GetCoordSys();
+                layerCsCode = layerCS->GetCsCode();
+            }
+            pPRLResult->SetCoordinateSystem(layerCsCode);
+
+            ScaleRange* pScaleRange = new ScaleRange();
+            pScaleRange->SetMinScale(minScale_Profile);
+            pScaleRange->SetMaxScale(maxScale_Profile);
+            pPRLResult->AdoptScaleRange(pScaleRange);
+
+            STRING filter = L""; // NOXLATE
+            if (overrideFilters)
+            {
+                filter = overrideFilters->GetItem(i);
+            }
+            pPRLResult->SetFilter(filter.empty()? mapLayer->GetFilter() : filter);
+        }
+
+    MG_SERVER_MAPPING_SERVICE_CATCH(L"MgMappingUtil.StylizeLayers");
+
+    delete rsReader;
+    //delete renderData;
+
+    if (mgException.p)
+    {
+        // TODO: Eventually this should be used to indicate visually to the client what
+        //       layer failed in addition to logging the error.
+        MgServerManager* serverManager = MgServerManager::GetInstance();
+        STRING locale = (NULL == serverManager)? MgResources::DefaultMessageLocale : serverManager->GetDefaultMessageLocale();
+
+        // Get the layer that failed
+        MgStringCollection arguments;
+        arguments.Add(mapLayer->GetName());
+
+        // Get the reason why the layer failed to stylize
+        MgStringCollection argumentsWhy;
+        argumentsWhy.Add(mgException->GetExceptionMessage(locale));
+
+        Ptr<MgStylizeLayerFailedException> exception;
+        exception = new MgStylizeLayerFailedException(L"MgMappingUtil.StylizeLayers", __LINE__, __WFILE__, &arguments, L"MgFormatInnerExceptionMessage", &argumentsWhy);
+
+        STRING message = exception->GetExceptionMessage(locale);
+        STRING stackTrace = exception->GetStackTrace(locale);
+        MG_LOG_EXCEPTION_ENTRY(message.c_str(), stackTrace.c_str());
+
+#if defined(_DEBUG) || defined(_DEBUG_PNG8)
+        STRING details = mgException->GetDetails(locale);
+
+        wstring err = L"\n %t Error during stylization of layer ";
+        err += mapLayer->GetName();
+        err += L"\n";
+        err += L"Details: ";
+        err += details;
+        err += L"\n";
+        ACE_DEBUG( (LM_DEBUG, err.c_str()) );
+#endif
+        // TODO could throw here depending on a serverconfig setting (RFC64)
+//          throw exception;
+
+
+        if(NULL != pPRLsResult)
+        {
+            ProfileRenderLayerResultCollection* pPRLResultColl = pPRLsResult->GetProfileRenderLayerResults();
+                
+            // Get current ProfileRenderLayerResult
+            ProfileRenderLayerResult* pPRLResult = pPRLResultColl->GetAt(pPRLResultColl->GetCount()-1); //TODO: check index
+                
+            // Calculate the time spent on stylizing layer
+            double stylizeLayerTime = MgTimerUtil::GetTime() - pPRLResult->GetRenderTime();
+            pPRLResult->SetRenderTime(stylizeLayerTime);
+
+            Ptr<MgResourceIdentifier> layerid = mapLayer->GetLayerDefinition();
+            pPRLResult->SetResourceId(layerid->ToString());
+            pPRLResult->SetLayerName(mapLayer->GetName());
+
+            pPRLResult->SetError(message);
+        }
+    } // if exception
+}

Modified: sandbox/liuar/mtr/Server/src/Services/Mapping/MappingUtil.h
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/MappingUtil.h	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Services/Mapping/MappingUtil.h	2012-03-31 02:18:48 UTC (rev 6561)
@@ -23,6 +23,7 @@
 
 //For profiling
 #include "ProfileRenderLayersResult.h"
+#include "TransformCache.h"
 
 //fwd declare
 class MgResourceService;
@@ -38,6 +39,7 @@
 class RSMgFeatureReader;
 class TransformCache;
 class SE_SymbolManager;
+class RS_ByteData;
 
 namespace MdfModel
 {
@@ -65,7 +67,12 @@
                               double scale,
                               bool selection = false,
                               bool extractColors = false,
-                              ProfileRenderLayersResultBase* = NULL);
+                              ProfileRenderLayersResultBase* = NULL,
+                              deque<Renderer*>* = NULL,
+                              vector<RS_ByteData*>* = NULL,
+                              INT32 saveWidth = 0,
+                              INT32 saveHeight = 0,
+                              STRING format = NULL);
 
     static RSMgFeatureReader* ExecuteFeatureQuery(MgFeatureService* svcFeature,
                                                  RS_Bounds& extent,
@@ -108,6 +115,44 @@
     // TODO: currently they are interpreted as ffffffff 32 bit RGBA string values.
     // The color palette passed to the renderer is a std::vector<RS_Color>
     static void ParseColorStrings(RS_ColorVector* tileColorPalette, MgMap* map);
+
+    static void* MgMappingUtil::RenderLayer(void* param);
 };
 
+struct RenderData
+{
+    ProfileRenderLayersResultBase* pPRLsResult;
+    int i;
+    MgLayerBase* mapLayer;
+    double scale;
+    MgResourceService* svcResource;
+    MgFeatureService* svcFeature;
+    MgDrawingService* svcDrawing;
+    MgMap* map;
+    bool selection;
+    bool expandExtents;
+    MgCoordinateSystemFactory* csFactory;
+    MgCoordinateSystem* dstCs;
+    MgStringCollection* overrideFilters;
+    TransformCacheMap* transformCache;
+    bool extractColors;
+    Stylizer* ds;
+    deque<Renderer*>* sub_drs;
+    INT32 saveWidth;
+    INT32 saveHeight;
+    STRING format;
+    RS_ByteData** subImg;
+};
+
+class LayerRenderingWorkers : public ACE_Task<ACE_MT_SYNCH>
+{
+public:
+   // LayerRenderingWorkers();
+
+    virtual int svc(void);
+
+    void process_message(ACE_Message_Block *mb);
+
+};
+
 #endif

Modified: sandbox/liuar/mtr/Server/src/Services/Mapping/ServerMappingService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.cpp	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Services/Mapping/ServerMappingService.cpp	2012-03-31 02:18:48 UTC (rev 6561)
@@ -709,8 +709,8 @@
         }
 
         //finally generate graphics data for the layers that need it
-        MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
-                                     rolc, NULL, &ds, &dr, dstCs, false, true, map->GetViewScale());
+        //MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
+        //                             rolc, NULL, &ds, &dr, dstCs, false, true, map->GetViewScale(),m_subImgs);
 
     dr.EndMap();
 
@@ -1292,8 +1292,8 @@
         }
 
         //stylize all the map layers
-        MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
-                                     rolc, NULL, &ds, &dr, dstCs, false, false, dMapScale);
+       // MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
+       //                              rolc, NULL, &ds, &dr, dstCs, false, false, dMapScale);
 
         // Finish adding the map to the page
         // Calculate the the height of the map bounds on the page (in page units)

Modified: sandbox/liuar/mtr/Server/src/Services/Mapping/ServerMappingService.vcxproj
===================================================================
--- trunk/MgDev/Server/src/Services/Mapping/ServerMappingService.vcxproj	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Services/Mapping/ServerMappingService.vcxproj	2012-03-31 02:18:48 UTC (rev 6561)
@@ -118,7 +118,7 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <AdditionalIncludeDirectories>..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Feature;..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\..\..\Common\Renderers;..\..\..\..\Common\Stylization;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\FDO\inc\ExpressionEngine;..\..\Gws\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_SERVER_MAPPING_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_SERVER_MAPPING_EXPORTS;MULTI_RENDERERS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -172,7 +172,7 @@
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
       <AdditionalIncludeDirectories>..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Feature;..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\MdfParser;..\..\..\..\Common\Renderers;..\..\..\..\Common\Stylization;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\FDO\inc\ExpressionEngine;..\..\Gws\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_SERVER_MAPPING_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_SERVER_MAPPING_EXPORTS;MULTI_RENDERERS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>

Modified: sandbox/liuar/mtr/Server/src/Services/Rendering/ServerRenderingService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.cpp	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Services/Rendering/ServerRenderingService.cpp	2012-03-31 02:18:48 UTC (rev 6561)
@@ -33,8 +33,8 @@
 // Profile
 #include "ProfileRenderMapResult.h"
 
+#define POOL_SIZE 4
 
-
 // the maximum number of allowed pixels for rendered images
 static const INT32 MAX_PIXELS = 16384*16384;
 static const INT32 FILTER_VISIBLE = 1;
@@ -378,9 +378,6 @@
     StylizationUtil::ParseColor(map->GetBackgroundColor(), bgColor);
     bgColor.alpha() = 0;
 
-    // initialize the renderer
-    auto_ptr<SE_Renderer> dr(CreateRenderer(width, height, bgColor, true));
-
     // create a temporary collection containing all the dynamic layers
     Ptr<MgLayerCollection> layers = map->GetLayers();
     Ptr<MgReadOnlyLayerCollection> roLayers = new MgReadOnlyLayerCollection();
@@ -392,6 +389,13 @@
             roLayers->Add(layer);
     }
 
+    // initialize the renderer
+#ifdef MULTI_RENDERERS
+    auto_ptr<SE_Renderer> dr(CreateRendererWithSubRenderers(roLayers->GetCount(), width, height, bgColor, true));
+#else
+    auto_ptr<SE_Renderer> dr(CreateRenderer(width, height, bgColor, true));
+#endif
+
     if(NULL != pPRMResult)
     {
         Ptr<MgResourceIdentifier> mapResId = map->GetMapDefinition();
@@ -984,7 +988,12 @@
 
     // begin map stylization
     dr->StartMap(&mapInfo, b, scale, map->GetDisplayDpi(), map->GetMetersPerUnit(), NULL);
-
+#ifdef MULTI_RENDERERS
+    for(int i =0; i<m_subRenderers.size(); i++)
+    {
+        m_subRenderers[i]->StartMap(&mapInfo, b, scale, map->GetDisplayDpi(), map->GetMetersPerUnit(), NULL);
+    }
+#endif
     MG_TRY()
 
         // if no layer collection is supplied, then put all layers in a temporary collection
@@ -1004,7 +1013,7 @@
 
         if (behavior & MgRenderingOptions::RenderLayers)    // this is for tiles so observer colormaps
         {
-            RenderLayers(map, tempLayers, &ds, dr, dstCs, expandExtents, scale, format, pPRMResult);
+            RenderLayers(map, tempLayers, &ds, dr, dstCs, expandExtents, scale, format, pPRMResult, saveWidth, saveHeight);
         }
 
         // now we need to stylize the selection on top (this is not for tiles!)
@@ -1037,6 +1046,17 @@
 
     dr->EndMap();
 
+#ifdef MULTI_RENDERERS   
+    deque<Renderer*>::iterator it = m_subRenderers.begin();
+    while(it != m_subRenderers.end())
+    {
+        ((AGGRenderer*)(*it))->SetLabeler(NULL);
+        delete (*it);
+        (*it) = NULL;
+        it++;
+    }
+#endif
+
     if(NULL != pPRMResult)
     {
         ProfileRenderLabelsResult* pPRLablesResult = pPRMResult->GetProfileRenderLabelsResult();
@@ -1531,7 +1551,36 @@
     // Do nothing.  No connection properties are required for server-side service objects.
 }
 
+SE_Renderer* MgServerRenderingService::CreateRendererWithSubRenderers(int subRenderersCount,
+                                                                      int width,
+                                                                      int height,
+                                                                      RS_Color& bgColor,
+                                                                      bool requiresClipping,
+                                                                      bool localOverposting,
+                                                                      double tileExtentOffset)
+{
+    SE_Renderer* mainRenderer = CreateRenderer(width,height,bgColor,requiresClipping,localOverposting,tileExtentOffset);
 
+    //m_subRenderers.reserve(POOL_SIZE);
+    m_subImgs.reserve(subRenderersCount);
+
+    for(int i = 0; i<POOL_SIZE; i++)
+    {
+        SE_Renderer* subRenderer = CreateRenderer(width,height,bgColor,requiresClipping,localOverposting,tileExtentOffset);
+        ((AGGRenderer*)subRenderer)->SetLabeler(((AGGRenderer*)mainRenderer)->GetLabeler());
+        m_subRenderers.push_back(subRenderer);
+    }
+    for(int i =0; i<subRenderersCount; i++)
+    {
+        //m_subRenderers.push_back(CreateRenderer(width,height,bgColor,requiresClipping,localOverposting,tileExtentOffset));
+        //((AGGRenderer*)m_subRenderers[i])->SetLabeler(((AGGRenderer*)mainRenderer)->GetLabeler());
+
+        RS_ByteData* img = new RS_ByteData();
+        m_subImgs.push_back(img);
+    }
+
+    return mainRenderer;
+}
 ///////////////////////////////////////////////////////////////////////////////
 SE_Renderer* MgServerRenderingService::CreateRenderer(int width,
                                                       int height,
@@ -1567,7 +1616,9 @@
                                                    bool expandExtents,
                                                    double scale,
                                                    CREFSTRING format,
-                                                   ProfileRenderMapResult* pPRMResult)
+                                                   ProfileRenderMapResult* pPRMResult,
+                                                   INT32 saveWidth,
+                                                   INT32 saveHeight)
 {
     ProfileRenderLayersResult* pPRLsResult = NULL; // pointer points to Profile Render Layers Result
 
@@ -1582,7 +1633,7 @@
 
     MgMappingUtil::StylizeLayers(m_svcResource, m_svcFeature, m_svcDrawing, m_pCSFactory, map,
                                     layers, NULL, ds, dr, dstCs, expandExtents, false, scale,
-                                    false, hasColorMap(format), pPRLsResult);
+                                    false, hasColorMap(format), pPRLsResult, &m_subRenderers,&m_subImgs,saveWidth,saveHeight,format);
 
     if(NULL != pPRMResult)
     {
@@ -1591,7 +1642,7 @@
         // Calculate the time spent on stylizing layers
         double stylizeLayersTime = MgTimerUtil::GetTime() - pPRLsResult->GetRenderTime();
         pPRLsResult->SetRenderTime(stylizeLayersTime);
-    }
+    }  
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1929,6 +1980,23 @@
     }
 }
 
+ACE_THR_FUNC_RETURN GetCombineWorker(void* param)
+{
+    // get the data for this thread
+    CreateImgThreadData* threadData = (CreateImgThreadData*)param;
+
+    try
+    {
+        threadData->data = ((AGGRenderer*)threadData->dr)->Combine(threadData->pSubImgs,threadData->start,threadData->end);
+    }
+    catch (...)
+    {
+        throw;
+    }
+
+    return 0;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 inline MgByteReader* MgServerRenderingService::CreateImage(MgMap* map,
                                                            Renderer* dr,
@@ -1968,9 +2036,150 @@
     // get a byte representation of the image
     auto_ptr<RS_ByteData> data;
     Ptr<MgByteSource> bs;
+#ifdef MULTI_RENDERERS
+    long lSize;
+    char * buffer;
 
+    
+
     try
     {
+    //    for(int i = 0; i<10; i++)
+    //    {
+    //        if (wcscmp(m_rendererName.c_str(), L"AGG") == 0)
+    //        {
+    //            //-------------------------------------------------------
+    //            /// RFC60 code to correct colormaps by UV
+    //            //-------------------------------------------------------
+    //            // We examine the expressions collected from xml definitions of all layers.
+    //            // The map object has a list from all color entries found in the most recent
+    //            // layer stylization.
+    //            // * TODO - currently they are interpreted as ffffffff 32-bit RGBA string values
+    //            // * adding expresssions and other interpretations should be done in ParseColorStrings
+    //            // * the color Palette for the renderer is a vector<RS_Color>
+    //            if (hasColorMap(format))
+    //            {
+    //                RS_ColorVector tileColorPalette;
+    //                MgMappingUtil::ParseColorStrings(&tileColorPalette, map);
+    ////              printf("<<<<<<<<<<<<<<<<<<<<< MgServerRenderingService::ColorPalette->size(): %d\n", tileColorPalette.size());
+    //                
+    //                
+
+    //                ((AGGRenderer*)m_subRenderers[i])->Save(fileName,format, saveWidth, saveHeight);
+    //                //data.reset(((AGGRenderer*)dr)->ReadPNG(fileName));
+    //                //data.reset( ((AGGRenderer*)m_subRenderers[i])->Save(format, saveWidth, saveHeight,&tileColorPalette));
+    //                //break;
+    //            }
+    //            else
+    //                //((AGGRenderer*)m_subRenderers[i])->Save(fileName,format, saveWidth, saveHeight);
+    //                //data.reset(((AGGRenderer*)m_subRenderers[i])->Save(format, saveWidth, saveHeight,NULL));
+    //                //data.reset(((AGGRenderer*)m_subRenderers[i])->ReadPNG(fileName));
+    //                //break;
+    //                
+    //        }
+    //        else
+    //            ((GDRenderer*)m_subRenderers[i])->Save(fileName,format, saveWidth, saveHeight);
+    //    }
+        
+        double comineStart = MgTimerUtil::GetTime(); 
+        //RS_String file2;
+        //for(int i = 0; i<10; i++)
+        //{
+        //    
+        //    if(i==9)
+        //    {
+        //        //the last image don't need to be combined
+        //        break;
+        //    }
+        //    RS_String file1;
+        //    MgUtil::Int32ToString(i,file1);
+        //    file1.append(L".");
+        //    file1.append(format);
+        //    MgUtil::Int32ToString(i+1,file2);
+        //    file2.append(L".");
+        //    file2.append(format);
+
+        //    if (wcscmp(m_rendererName.c_str(), L"AGG") == 0)
+        //    {
+        //        ((AGGRenderer*)dr)->Combine(file1,file2,file2);
+        //    }
+        //    else
+        //    {
+        //        _ASSERT("NOT SUPPORT");
+        //        //((GDRenderer*)dr)->Combine(file1,file2,file2);
+        //    }
+        //}
+
+        
+
+#ifdef MULTI_THREAD_COMBINE
+        ACE_Thread_Manager* manager = ACE_Thread_Manager::instance();
+        const int THREAD_GROUP = 65535;
+        CreateImgThreadData threadData1, threadData2;
+        threadData1.dr = dr;
+        threadData1.pSubImgs = &m_subImgs;
+        threadData1.start = 0;
+        threadData1.end = m_subImgs.size()/2;
+
+        threadData2.dr = dr;
+        threadData2.pSubImgs = &m_subImgs;
+        threadData2.start = m_subImgs.size()/2;
+        threadData2.end = m_subImgs.size();
+
+        manager->spawn(ACE_THR_FUNC(GetCombineWorker), &threadData1, 0, NULL, NULL, 0, THREAD_GROUP);
+        manager->spawn(ACE_THR_FUNC(GetCombineWorker), &threadData2, 0, NULL, NULL, 0, THREAD_GROUP);
+
+        vector<RS_ByteData*> tempSubImgs;
+        tempSubImgs.reserve(3); // label thread1 thread2
+        RS_ByteData* labelImg = ((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight,NULL);
+        
+
+        manager->wait_grp(THREAD_GROUP);
+
+        // Clear m_subImgs
+        vector<RS_ByteData*>::iterator it = m_subImgs.begin();
+        while(it != m_subImgs.end())
+        {
+            delete *it;
+            *it = NULL;
+            it++;
+        }
+
+        // combine temp images
+        tempSubImgs.push_back(threadData1.data);
+        tempSubImgs.push_back(threadData2.data);
+        tempSubImgs.push_back(labelImg);
+
+        data.reset(((AGGRenderer*)dr)->Combine(&tempSubImgs,0,3));
+
+        // Clear temp subImgs
+        it = tempSubImgs.begin();
+        while(it != tempSubImgs.end())
+        {
+            delete *it;
+            *it = NULL;
+            it++;
+        }
+#else
+        RS_ByteData* labelImg = ((AGGRenderer*)dr)->Save(format, saveWidth, saveHeight,NULL);
+        data.reset(((AGGRenderer*)dr)->Combine(&m_subImgs,labelImg));
+        // Clear m_subImgs
+        vector<RS_ByteData*>::iterator it = m_subImgs.begin();
+        while(it != m_subImgs.end())
+        {
+            delete *it;
+            *it = NULL;
+            it++;
+        }
+#endif
+
+        
+
+        ACE_DEBUG((LM_INFO, L"(%t)  CombineImage() total time = %6.4f (ms)\n", (MgTimerUtil::GetTime()- comineStart)));
+    }
+#else
+    try
+    {
         // call the image renderer to create the image
         if (wcscmp(m_rendererName.c_str(), L"AGG") == 0)
         {
@@ -1996,6 +2205,7 @@
         else
             data.reset(((GDRenderer*)dr)->Save(format, saveWidth, saveHeight));
     }
+#endif
     catch (exception e)
     {
         ACE_DEBUG((LM_DEBUG, L"(%t) %w caught in RenderingService ColorPaletteGeneration\n", e.what()));

Modified: sandbox/liuar/mtr/Server/src/Services/Rendering/ServerRenderingService.h
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.h	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Services/Rendering/ServerRenderingService.h	2012-03-31 02:18:48 UTC (rev 6561)
@@ -24,6 +24,7 @@
 class FeatureInfoRenderer;
 class MgFeatureInformation;
 class Stylizer;
+class RS_ByteData;
 
 namespace MdfModel
 {
@@ -235,6 +236,14 @@
                                 bool localOverposting = false,
                                 double tileExtentOffset = 0.0);
 
+    SE_Renderer* MgServerRenderingService::CreateRendererWithSubRenderers(int subRenderersCount,
+                                                                          int width,
+                                                                          int height,
+                                                                          RS_Color& bgColor,
+                                                                          bool requiresClipping,
+                                                                          bool localOverposting = false,
+                                                                          double tileExtentOffset = 0.0);
+
     void RenderLayers(MgMap* map,
                       MgReadOnlyLayerCollection* layers,
                       Stylizer* ds,
@@ -243,7 +252,9 @@
                       bool expandExtents,
                       double scale,
                       CREFSTRING format,
-                      ProfileRenderMapResult* pPRMResult);
+                      ProfileRenderMapResult* pPRMResult,
+                      INT32 saveWidth,
+                      INT32 saveHeight);
 
     void RenderSelection(MgMap* map,
                          MgSelection* selection,
@@ -288,6 +299,17 @@
     INT32 m_renderSelectionBatchSize;
     INT32 m_maxRasterImageWidth;
     INT32 m_maxRasterImageHeight;
+
+    deque<Renderer*> m_subRenderers;
+    vector<RS_ByteData*> m_subImgs;
 };
 
+struct CreateImgThreadData
+{
+    Renderer* dr;
+    vector<RS_ByteData*>* pSubImgs;
+    size_t start;
+    size_t end;
+    RS_ByteData* data;
+};
 #endif

Modified: sandbox/liuar/mtr/Server/src/Services/Rendering/ServerRenderingService.vcxproj
===================================================================
--- trunk/MgDev/Server/src/Services/Rendering/ServerRenderingService.vcxproj	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Services/Rendering/ServerRenderingService.vcxproj	2012-03-31 02:18:48 UTC (rev 6561)
@@ -117,7 +117,7 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       <AdditionalIncludeDirectories>..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Feature;..\Mapping;..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\Renderers;..\..\..\..\Common\Stylization;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\FDO\inc\ExpressionEngine;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_SERVER_RENDERING_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MG_SERVER_RENDERING_EXPORTS;MULTI_RENDERERS;MULTI_THREAD_COMBINE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <MinimalRebuild>true</MinimalRebuild>
       <ExceptionHandling>Async</ExceptionHandling>
       <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@@ -169,7 +169,7 @@
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
       <AdditionalIncludeDirectories>..\..\Common;..\..\Common\Base;..\..\Common\Manager;..\Feature;..\Mapping;..\..\..\..\Common\Foundation;..\..\..\..\Common\Geometry;..\..\..\..\Common\PlatformBase;..\..\..\..\Common\MapGuideCommon;..\..\..\..\Common\MdfModel;..\..\..\..\Common\Renderers;..\..\..\..\Common\Stylization;..\..\..\..\Oem\ACE\ACE_wrappers;..\..\..\..\Oem\dbxml\xerces-c-src\src;..\..\..\..\Oem\FDO\inc;..\..\..\..\Oem\FDO\inc\ExpressionEngine;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_SERVER_RENDERING_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MG_SERVER_RENDERING_EXPORTS;MULTI_RENDERERS;MULTI_THREAD_COMBINE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <ExceptionHandling>Async</ExceptionHandling>
       <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>

Modified: sandbox/liuar/mtr/Server/src/Services/Site/SiteOperation.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Site/SiteOperation.cpp	2012-01-31 01:16:56 UTC (rev 6468)
+++ sandbox/liuar/mtr/Server/src/Services/Site/SiteOperation.cpp	2012-03-31 02:18:48 UTC (rev 6561)
@@ -83,5 +83,5 @@
 void MgSiteOperation::Validate()
 {
     AuthenticateCurrentUser();
-    CheckLicense();
+    //CheckLicense();
 }



More information about the mapguide-commits mailing list