layers: DrawState layer now support the layers settings file

DrawState use the getlayerOption()  or use default values if no options are
defined.  DrawState now has the configurable options Debug Action, Debug Level,
 and Debug Log Filename.
diff --git a/layers/draw_state.c b/layers/draw_state.c
index 143b3c3..e603fe3 100644
--- a/layers/draw_state.c
+++ b/layers/draw_state.c
@@ -31,14 +31,20 @@
 #include "xgl_struct_string_helper.h"
 #include "xgl_struct_graphviz_helper.h"
 #include "draw_state.h"
+#include "layers_config.h"
 
 static XGL_LAYER_DISPATCH_TABLE nextTable;
 static XGL_BASE_LAYER_OBJECT *pCurObj;
-static pthread_once_t tabOnce = PTHREAD_ONCE_INIT;
+static pthread_once_t g_initOnce = PTHREAD_ONCE_INIT;
 // Could be smarter about locking with unique locks for various tasks, but just using one for now
 pthread_mutex_t globalLock = PTHREAD_MUTEX_INITIALIZER;
+
 // Ptr to LL of dbg functions
-static XGL_LAYER_DBG_FUNCTION_NODE *pDbgFunctionHead = NULL;
+static XGL_LAYER_DBG_FUNCTION_NODE *g_pDbgFunctionHead = NULL;
+static XGL_LAYER_DBG_REPORT_LEVEL g_reportingLevel = XGL_DBG_LAYER_LEVEL_ERROR;
+static XGL_LAYER_DBG_ACTION g_debugAction = XGL_DBG_LAYER_ACTION_LOG_MSG;
+static FILE *g_logFile = NULL;
+
 // Utility function to handle reporting
 //  If callbacks are enabled, use them, otherwise use printf
 static XGL_VOID layerCbMsg(XGL_DBG_MSG_TYPE msgType,
@@ -49,26 +55,52 @@
     const char*          pLayerPrefix,
     const char*          pMsg)
 {
-    XGL_LAYER_DBG_FUNCTION_NODE *pTrav = pDbgFunctionHead;
-    if (pTrav) {
-        while (pTrav) {
-            pTrav->pfnMsgCallback(msgType, validationLevel, srcObject, location, msgCode, pMsg, pTrav->pUserData);
-            pTrav = pTrav->pNext;
-        }
-    }
-    else {
+    if (g_debugAction & (XGL_DBG_LAYER_ACTION_LOG_MSG | XGL_DBG_LAYER_ACTION_CALLBACK)) {
+        XGL_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
         switch (msgType) {
             case XGL_DBG_MSG_ERROR:
-                printf("{%s}ERROR : %s\n", pLayerPrefix, pMsg);
+                if (g_reportingLevel <= XGL_DBG_LAYER_LEVEL_ERROR) {
+                    if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
+                        fprintf(g_logFile, "{%s}ERROR : %s\n", pLayerPrefix, pMsg);
+                    if (g_debugAction & XGL_DBG_LAYER_ACTION_CALLBACK)
+                        while (pTrav) {
+				            pTrav->pfnMsgCallback(msgType, validationLevel, srcObject, location, msgCode, pMsg, pTrav->pUserData);
+                            pTrav = pTrav->pNext;
+                        }
+                }
                 break;
             case XGL_DBG_MSG_WARNING:
-                printf("{%s}WARN : %s\n", pLayerPrefix, pMsg);
+                if (g_reportingLevel <= XGL_DBG_LAYER_LEVEL_WARN) {
+                    if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
+                        fprintf(g_logFile, "{%s}WARN : %s\n", pLayerPrefix, pMsg);
+                    if (g_debugAction & XGL_DBG_LAYER_ACTION_CALLBACK)
+                        while (pTrav) {
+				            pTrav->pfnMsgCallback(msgType, validationLevel, srcObject, location, msgCode, pMsg, pTrav->pUserData);
+                            pTrav = pTrav->pNext;
+                        }
+                }
                 break;
             case XGL_DBG_MSG_PERF_WARNING:
-                printf("{%s}PERF_WARN : %s\n", pLayerPrefix, pMsg);
+                if (g_reportingLevel <= XGL_DBG_LAYER_LEVEL_PERF_WARN) {
+                    if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
+                        fprintf(g_logFile, "{%s}PERF_WARN : %s\n", pLayerPrefix, pMsg);
+                    if (g_debugAction & XGL_DBG_LAYER_ACTION_CALLBACK)
+                        while (pTrav) {
+				            pTrav->pfnMsgCallback(msgType, validationLevel, srcObject, location, msgCode, pMsg, pTrav->pUserData);
+                            pTrav = pTrav->pNext;
+                        }
+                }
                 break;
             default:
-                printf("{%s}INFO : %s\n", pLayerPrefix, pMsg);
+                if (g_reportingLevel <= XGL_DBG_LAYER_LEVEL_INFO) {
+                    if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
+                        fprintf(g_logFile, "{%s}INFO : %s\n", pLayerPrefix, pMsg);
+                    if (g_debugAction & XGL_DBG_LAYER_ACTION_CALLBACK)
+                        while (pTrav) {
+				            pTrav->pfnMsgCallback(msgType, validationLevel, srcObject, location, msgCode, pMsg, pTrav->pUserData);
+                            pTrav = pTrav->pNext;
+                        }
+                }
                 break;
         }
     }
@@ -885,8 +917,30 @@
     }
 }
 
-static void initLayerTable()
+static void initDrawState()
 {
+    const char *strOpt;
+    // initialize MemTracker options
+    strOpt = getLayerOption("DrawStateReportLevel");
+    if (strOpt != NULL)
+        g_reportingLevel = atoi(strOpt);
+    strOpt = getLayerOption("DrawStateDebugAction");
+    if (strOpt != NULL)
+       g_debugAction = atoi(strOpt);
+    if (g_debugAction & XGL_DBG_LAYER_ACTION_LOG_MSG)
+    {
+        strOpt = getLayerOption("DrawStateLogFilename");
+        if (strOpt)
+        {
+            g_logFile = fopen(strOpt, "w");
+
+        }
+        if (g_logFile == NULL)
+            g_logFile = stdout;
+    }
+
+    // initialize Layer dispatch table
+    // TODO handle multiple GPUs
     GetProcAddrType fpNextGPA;
     fpNextGPA = pCurObj->pGPA;
     assert(fpNextGPA);
@@ -1140,7 +1194,7 @@
 {
     XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
     pCurObj = gpuw;
-    pthread_once(&tabOnce, initLayerTable);
+    pthread_once(&g_initOnce, initDrawState);
     XGL_RESULT result = nextTable.GetGpuInfo((XGL_PHYSICAL_GPU)gpuw->nextObject, infoType, pDataSize, pData);
     return result;
 }
@@ -1149,7 +1203,7 @@
 {
     XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
     pCurObj = gpuw;
-    pthread_once(&tabOnce, initLayerTable);
+    pthread_once(&g_initOnce, initDrawState);
     XGL_RESULT result = nextTable.CreateDevice((XGL_PHYSICAL_GPU)gpuw->nextObject, pCreateInfo, pDevice);
     return result;
 }
@@ -1164,7 +1218,7 @@
 {
     XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
     pCurObj = gpuw;
-    pthread_once(&tabOnce, initLayerTable);
+    pthread_once(&g_initOnce, initDrawState);
     XGL_RESULT result = nextTable.GetExtensionSupport((XGL_PHYSICAL_GPU)gpuw->nextObject, pExtName);
     return result;
 }
@@ -1175,7 +1229,7 @@
     {
         XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
         pCurObj = gpuw;
-        pthread_once(&tabOnce, initLayerTable);
+        pthread_once(&g_initOnce, initDrawState);
         XGL_RESULT result = nextTable.EnumerateLayers((XGL_PHYSICAL_GPU)gpuw->nextObject, maxLayerCount, maxStringSize, pOutLayers, pOutLayerCount, pReserved);
         return result;
     } else
@@ -1277,7 +1331,7 @@
 {
     XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu0;
     pCurObj = gpuw;
-    pthread_once(&tabOnce, initLayerTable);
+    pthread_once(&g_initOnce, initDrawState);
     XGL_RESULT result = nextTable.GetMultiGpuCompatibility((XGL_PHYSICAL_GPU)gpuw->nextObject, gpu1, pInfo);
     return result;
 }
@@ -1950,21 +2004,21 @@
         return XGL_ERROR_OUT_OF_MEMORY;
     pNewDbgFuncNode->pfnMsgCallback = pfnMsgCallback;
     pNewDbgFuncNode->pUserData = pUserData;
-    pNewDbgFuncNode->pNext = pDbgFunctionHead;
-    pDbgFunctionHead = pNewDbgFuncNode;
+    pNewDbgFuncNode->pNext = g_pDbgFunctionHead;
+    g_pDbgFunctionHead = pNewDbgFuncNode;
     XGL_RESULT result = nextTable.DbgRegisterMsgCallback(pfnMsgCallback, pUserData);
     return result;
 }
 
 XGL_LAYER_EXPORT XGL_RESULT XGLAPI xglDbgUnregisterMsgCallback(XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
 {
-    XGL_LAYER_DBG_FUNCTION_NODE *pTrav = pDbgFunctionHead;
+    XGL_LAYER_DBG_FUNCTION_NODE *pTrav = g_pDbgFunctionHead;
     XGL_LAYER_DBG_FUNCTION_NODE *pPrev = pTrav;
     while (pTrav) {
         if (pTrav->pfnMsgCallback == pfnMsgCallback) {
             pPrev->pNext = pTrav->pNext;
-            if (pDbgFunctionHead == pTrav)
-                pDbgFunctionHead = pTrav->pNext;
+            if (g_pDbgFunctionHead == pTrav)
+                g_pDbgFunctionHead = pTrav->pNext;
             free(pTrav);
             break;
         }
@@ -2013,7 +2067,7 @@
 {
     XGL_BASE_LAYER_OBJECT* gpuw = (XGL_BASE_LAYER_OBJECT *) gpu;
     pCurObj = gpuw;
-    pthread_once(&tabOnce, initLayerTable);
+    pthread_once(&g_initOnce, initDrawState);
     XGL_RESULT result = nextTable.WsiX11AssociateConnection((XGL_PHYSICAL_GPU)gpuw->nextObject, pConnectionInfo);
     return result;
 }
@@ -2064,7 +2118,7 @@
     if (gpu == NULL)
         return NULL;
     pCurObj = gpuw;
-    pthread_once(&tabOnce, initLayerTable);
+    pthread_once(&g_initOnce, initDrawState);
 
     if (!strncmp("xglGetProcAddr", funcName, sizeof("xglGetProcAddr")))
         return xglGetProcAddr;