From 09d33177fcfadabae4a85b5b778d65d412ec3925 Mon Sep 17 00:00:00 2001
From: Sam Gateau <samuel.gateau@gmail.com>
Date: Mon, 6 Aug 2018 15:36:25 -0700
Subject: [PATCH] Adjust Workload and better representation of the workload
 debuging features

---
 .../render-utils/src/WorkloadResource.slh     |  82 +++++++++++++
 .../render-utils/src/drawWorkloadProxy.slf    |   4 +-
 .../render-utils/src/drawWorkloadProxy.slv    |  36 +-----
 .../render-utils/src/drawWorkloadView.slf     |   4 +-
 .../render-utils/src/drawWorkloadView.slv     |  44 +------
 libraries/workload/src/workload/ViewTask.cpp  |  19 ++-
 libraries/workload/src/workload/ViewTask.h    |   6 +-
 .../developer/utilities/workload/workload.js  | 109 +++++++++++++-----
 .../utilities/workload/workloadInspector.qml  |  71 ++++++++++--
 9 files changed, 256 insertions(+), 119 deletions(-)
 create mode 100644 libraries/render-utils/src/WorkloadResource.slh

diff --git a/libraries/render-utils/src/WorkloadResource.slh b/libraries/render-utils/src/WorkloadResource.slh
new file mode 100644
index 0000000000..c1d0d21fa1
--- /dev/null
+++ b/libraries/render-utils/src/WorkloadResource.slh
@@ -0,0 +1,82 @@
+//
+//  Created by Sam Gateau on 7/31/2018.
+//  Copyright 2018 High Fidelity, Inc.
+//
+//  Distributed under the Apache License, Version 2.0.
+//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+<@if not WORKLOAD_RESOURCE_SLH@>
+<@def WORKLOAD_RESOURCE_SLH@>
+
+<@include gpu/Color.slh@>
+<$declareColorWheel()$>
+
+const vec4 REGION_COLOR[4] = vec4[4](
+    vec4(0.0, 1.0, 0.0, 1.0),
+    vec4(1.0, 0.6, 0.0, 1.0),
+    vec4(1.0, 0.0, 0.0, 1.0),
+    vec4(0.3, 0.0, 0.8, 1.0)
+);
+
+<@func declareWorkloadProxies() @>
+
+struct WorkloadProxy {
+    vec4 sphere;
+    vec4 region;
+};
+
+#if defined(GPU_GL410)
+uniform samplerBuffer workloadProxiesBuffer;
+WorkloadProxy getWorkloadProxy(int i) {
+    int offset = 2 * i;
+    WorkloadProxy proxy;
+    proxy.sphere = texelFetch(workloadProxiesBuffer, offset);
+    proxy.region = texelFetch(workloadProxiesBuffer, offset + 1);
+    return proxy;
+}
+#else
+layout(std140) buffer workloadProxiesBuffer {
+    WorkloadProxy _proxies[];
+};
+WorkloadProxy getWorkloadProxy(int i) {
+    WorkloadProxy proxy = _proxies[i];
+    return proxy;
+}
+#endif
+
+<@endfunc@>
+
+
+<@func declareWorkloadViews() @>
+
+struct WorkloadView {
+    vec4 direction_far;
+    vec4 fov;
+    vec4 origin;
+    vec4 backFront[2];
+    vec4 regions[3];
+};
+
+#if defined(GPU_GL410)
+uniform samplerBuffer workloadViewsBuffer;
+WorkloadView getWorkloadView(int i) {
+    int offset = 2 * i;
+    WorkloadView view;
+    view.origin = texelFetch(workloadViewsBuffer, offset);
+    view.radiuses = texelFetch(workloadViewsBuffer, offset + 1);
+    return view;
+}
+#else
+layout(std140) buffer workloadViewsBuffer {
+    WorkloadView _views[];
+};
+WorkloadView getWorkloadView(int i) {
+    WorkloadView view = _views[i];
+    return view;
+}
+#endif
+
+<@endfunc@>
+
+<@endif@>
+
diff --git a/libraries/render-utils/src/drawWorkloadProxy.slf b/libraries/render-utils/src/drawWorkloadProxy.slf
index 1304e68c7f..32dceab00a 100644
--- a/libraries/render-utils/src/drawWorkloadProxy.slf
+++ b/libraries/render-utils/src/drawWorkloadProxy.slf
@@ -15,11 +15,13 @@
 
 in vec4 varColor;
 in vec3 varTexcoord;
+in vec3 varEyePos;
 
 void main(void) {
     if (varColor.w > 0.0) {
         float r = sqrt(dot(varTexcoord.xyz,varTexcoord.xyz));
-        float a = paintStripe(r * varColor.w, 0.0, 1.0 / varColor.w, 0.05 / varColor.w);
+        float d = varColor.w / abs(varEyePos.z);
+        float a = paintStripe(r * d, 0.0, 1.0 / d, 0.002 / d);
         if (a <= 0.1 || r > 1.1) {
             discard;
         }
diff --git a/libraries/render-utils/src/drawWorkloadProxy.slv b/libraries/render-utils/src/drawWorkloadProxy.slv
index 64fb335fd6..1b91e349ab 100644
--- a/libraries/render-utils/src/drawWorkloadProxy.slv
+++ b/libraries/render-utils/src/drawWorkloadProxy.slv
@@ -15,40 +15,13 @@
 <@include gpu/Transform.slh@>
 <$declareStandardTransform()$>
 
-<@include gpu/Color.slh@>
-<$declareColorWheel()$>
-
-uniform vec4 inColor;
-
-
-struct WorkloadProxy {
-    vec4 sphere;
-    vec4 region;
-};
-
-#if defined(GPU_GL410)
-uniform samplerBuffer workloadProxiesBuffer;
-WorkloadProxy getWorkloadProxy(int i) {
-    int offset = 2 * i;
-    WorkloadProxy proxy;
-    proxy.sphere = texelFetch(workloadProxiesBuffer, offset);
-    proxy.region = texelFetch(workloadProxiesBuffer, offset + 1);
-    return proxy;
-}
-#else
-layout(std140) buffer workloadProxiesBuffer {
-    WorkloadProxy _proxies[];
-};
-WorkloadProxy getWorkloadProxy(int i) {
-    WorkloadProxy proxy = _proxies[i];
-    return proxy;
-}
-#endif
-
+<@include WorkloadResource.slh@>
+<$declareWorkloadProxies()$>
 
 
 out vec4 varColor;
 out vec3 varTexcoord;
+out vec3 varEyePos;
 
 void main(void) {
     const vec4 UNIT_SPRITE[3] = vec4[3](
@@ -79,6 +52,7 @@ void main(void) {
     vec3 dirY = vec3(0.0, 1.0, 0.0);
 
     vec4 pos = vec4(proxyPosEye.xyz + proxy.sphere.w * ( dirX * spriteVert.x + dirY * spriteVert.y /* + dirZ * spriteVert.z*/), 1.0);
+    varEyePos = pos.xyz;
     varTexcoord = spriteVert.xyz;
     <$transformEyeToClipPos(cam, pos, gl_Position)$>
 
@@ -86,7 +60,7 @@ void main(void) {
     int region = floatBitsToInt(proxy.region.x);
     region = (0x000000FF & region);
 
-    varColor = vec4(colorWheel(float(region) / 4.0), proxy.sphere.w);
+    varColor = vec4(REGION_COLOR[region].xyz, proxy.sphere.w);
 
     if (region == 4) {
         gl_Position = vec4(0.0);
diff --git a/libraries/render-utils/src/drawWorkloadView.slf b/libraries/render-utils/src/drawWorkloadView.slf
index 1304e68c7f..a3779ad6f4 100644
--- a/libraries/render-utils/src/drawWorkloadView.slf
+++ b/libraries/render-utils/src/drawWorkloadView.slf
@@ -15,11 +15,13 @@
 
 in vec4 varColor;
 in vec3 varTexcoord;
+in vec3 varEyePos;
 
 void main(void) {
     if (varColor.w > 0.0) {
         float r = sqrt(dot(varTexcoord.xyz,varTexcoord.xyz));
-        float a = paintStripe(r * varColor.w, 0.0, 1.0 / varColor.w, 0.05 / varColor.w);
+        float d = varColor.w / abs(varEyePos.z);
+        float a = paintStripe(r * d, 0.0, 1.0 / d, 0.005 / d);
         if (a <= 0.1 || r > 1.1) {
             discard;
         }
diff --git a/libraries/render-utils/src/drawWorkloadView.slv b/libraries/render-utils/src/drawWorkloadView.slv
index f5497d250c..3212bc055c 100644
--- a/libraries/render-utils/src/drawWorkloadView.slv
+++ b/libraries/render-utils/src/drawWorkloadView.slv
@@ -15,45 +15,12 @@
 <@include gpu/Transform.slh@>
 <$declareStandardTransform()$>
 
-<@include gpu/Color.slh@>
-<$declareColorWheel()$>
-
-uniform vec4 inColor;
-
-
-struct WorkloadView {
-    vec4 direction_far;
-    vec4 fov;
-    vec4 origin;
-    vec4 backFront[2];
-    vec4 regions[3];
-};
-
-#if defined(GPU_GL410)
-uniform samplerBuffer workloadViewsBuffer;
-WorkloadView getWorkloadView(int i) {
-    int offset = 2 * i;
-    WorkloadView view;
-    view.origin = texelFetch(workloadViewsBuffer, offset);
-    view.radiuses = texelFetch(workloadViewsBuffer, offset + 1);
-    return view;
-}
-#else
-layout(std140) buffer workloadViewsBuffer {
-    WorkloadView _views[];
-};
-WorkloadView getWorkloadView(int i) {
-    WorkloadView view = _views[i];
-    return view;
-}
-#endif
-
-
-
-
+<@include WorkloadResource.slh@>
+<$declareWorkloadViews()$>
 
 out vec4 varColor;
 out vec3 varTexcoord;
+out vec3 varEyePos;
 
 const int NUM_VERTICES_PER_SEGMENT = 2;
 const int NUM_SEGMENT_PER_VIEW_REGION = 65;
@@ -109,12 +76,13 @@ void main(void) {
     <$transformModelToEyeDir(cam, obj, originSpaceTan, tanEye)$>
 
     lateralDir = normalize(cross(vec3(0.0, 0.0, 1.0), normalize(tanEye)));
-    posEye.xyz += (0.05 * (regionID + 1)) * (-1.0 + 2.0 * float(segmentVertexID)) * lateralDir;
+    posEye.xyz += (0.005 * abs(posEye.z) * (regionID + 1)) * (-1.0 + 2.0 * float(segmentVertexID)) * lateralDir;
+    varEyePos = posEye.xyz;
 
     <$transformEyeToClipPos(cam, posEye, gl_Position)$>
 
     varTexcoord = spriteVert.xyz;
 
     // Convert region to color
-    varColor = vec4(colorWheel(float(regionID) / 4.0), -1.0);
+    varColor = vec4(REGION_COLOR[regionID].xyz, -1.0);
 }
diff --git a/libraries/workload/src/workload/ViewTask.cpp b/libraries/workload/src/workload/ViewTask.cpp
index 4b77733c52..5d9953cdf4 100644
--- a/libraries/workload/src/workload/ViewTask.cpp
+++ b/libraries/workload/src/workload/ViewTask.cpp
@@ -91,12 +91,24 @@ void ControlViews::run(const workload::WorkloadContextPointer& runContext, const
         regulateViews(outViews, inTimings);
     }
 
-    // Export the timings for debuging
+    // Export the ranges for debuging
+    bool doExport = false;
+    if (outViews.size()) {
+        _dataExport.ranges[workload::Region::R1] = outViews[0].regionBackFronts[workload::Region::R1];
+        _dataExport.ranges[workload::Region::R2] = outViews[0].regionBackFronts[workload::Region::R2];
+        _dataExport.ranges[workload::Region::R3] = outViews[0].regionBackFronts[workload::Region::R3];
+        doExport = true;
+    }
+
+    // Export the ranges and timings for debuging
     if (inTimings.size()) {
         _dataExport.timings[workload::Region::R1] = std::chrono::duration<float, std::milli>(inTimings[0]).count();
         _dataExport.timings[workload::Region::R2] = _dataExport.timings[workload::Region::R1];
         _dataExport.timings[workload::Region::R3] = std::chrono::duration<float, std::milli>(inTimings[1]).count();
+        doExport = true;
+    }
 
+    if (doExport) {
         auto config = std::static_pointer_cast<Config>(runContext->jobConfig);
         config->dataExport = _dataExport;
         config->emitDirty();
@@ -129,11 +141,6 @@ void ControlViews::regulateViews(workload::Views& outViews, const workload::Timi
     regionBackFronts[workload::Region::R3] = regionRegulators[workload::Region::R3].run(loopDuration, timings[1], regionBackFronts[workload::Region::R3]);
 
     enforceRegionContainment();
-
-    _dataExport.ranges[workload::Region::R1] = regionBackFronts[workload::Region::R1];
-    _dataExport.ranges[workload::Region::R2] = regionBackFronts[workload::Region::R2];
-    _dataExport.ranges[workload::Region::R3] = regionBackFronts[workload::Region::R3];
-
     for (auto& outView : outViews) {
         outView.regionBackFronts[workload::Region::R1] = regionBackFronts[workload::Region::R1];
         outView.regionBackFronts[workload::Region::R2] = regionBackFronts[workload::Region::R2];
diff --git a/libraries/workload/src/workload/ViewTask.h b/libraries/workload/src/workload/ViewTask.h
index 867f22d534..c20314d514 100644
--- a/libraries/workload/src/workload/ViewTask.h
+++ b/libraries/workload/src/workload/ViewTask.h
@@ -32,9 +32,9 @@ namespace workload {
     };
 
     const std::vector<glm::vec2> MAX_VIEW_BACK_FRONTS = {
-        { 100.0f, 200.0f },
-        { 150.0f, 300.0f },
-        { 250.0f, 500.0f }
+        { 100.0f, 1600.0f },
+        { 150.0f, 10000.0f },
+        { 250.0f, 16000.0f }
     };
 
     const float RELATIVE_STEP_DOWN = 0.05f;
diff --git a/scripts/developer/utilities/workload/workload.js b/scripts/developer/utilities/workload/workload.js
index d74eb4e6d5..ce41e0ecb8 100644
--- a/scripts/developer/utilities/workload/workload.js
+++ b/scripts/developer/utilities/workload/workload.js
@@ -16,16 +16,9 @@
     var ICON_URL = Script.resolvePath("../../../system/assets/images/luci-i.svg");
     var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/luci-a.svg");
 
-   
-    var onAppScreen = false;
+    var onTablet = false; // set this to true to use the tablet, false use a floating window
 
-    function onClicked() {
-        if (onAppScreen) {
-            tablet.gotoHomeScreen();
-        } else {
-            tablet.loadQMLSource(QMLAPP_URL);
-        }
-    }
+    var onAppScreen = false;
 
     var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
     var button = tablet.addButton({
@@ -36,33 +29,82 @@
 
     var hasEventBridge = false;
 
-    function wireEventBridge(on) {
-        if (!tablet) {
-            print("Warning in wireEventBridge(): 'tablet' undefined!");
-            return;
-        }
-        if (on) {
-            if (!hasEventBridge) {
-                tablet.fromQml.connect(fromQml);
-                hasEventBridge = true;
+    var onScreen = false;
+    var window;
+    
+    function onClicked() {
+        if (onTablet) {
+            if (onAppScreen) {
+                tablet.gotoHomeScreen();
+            } else {
+                tablet.loadQMLSource(QMLAPP_URL);
             }
         } else {
-            if (hasEventBridge) {
-                tablet.fromQml.disconnect(fromQml);
-                hasEventBridge = false;
+            if (onScreen) {
+                killWindow()
+            } else {
+                createWindow()    
+            }
+        }
+    }
+
+    function createWindow() {
+        var qml = Script.resolvePath(QMLAPP_URL);
+        window = Desktop.createWindow(Script.resolvePath(QMLAPP_URL), {
+            title: 'Workload Inspector',
+            flags: Desktop.ALWAYS_ON_TOP,
+            presentationMode: Desktop.PresentationMode.NATIVE,
+            size: {x: 400, y: 600}
+        });
+        window.setPosition(200, 50);
+        window.closed.connect(killWindow);
+        window.fromQml.connect(fromQml);
+        onScreen = true
+        button.editProperties({isActive: true});
+    }
+
+    function killWindow() {
+        if (window !==  undefined) { 
+            window.closed.disconnect(killWindow);
+            window.fromQml.disconnect(fromQml);
+            window.close()
+            window = undefined
+        }
+        onScreen = false
+        button.editProperties({isActive: false})
+    }
+
+    function wireEventBridge(on) {
+        if (onTablet) {
+            if (!tablet) {
+                print("Warning in wireEventBridge(): 'tablet' undefined!");
+                return;
+            }
+            if (on) {
+                if (!hasEventBridge) {
+                    tablet.fromQml.connect(fromQml);
+                    hasEventBridge = true;
+                }
+            } else {
+                if (hasEventBridge) {
+                    tablet.fromQml.disconnect(fromQml);
+                    hasEventBridge = false;
+                }
             }
         }
     }
 
     function onScreenChanged(type, url) {
-        if (url === QMLAPP_URL) {
-            onAppScreen = true;
-        } else { 
-            onAppScreen = false;
+        if (onTablet) {
+            if (url === QMLAPP_URL) {
+                onAppScreen = true;
+            } else { 
+                onAppScreen = false;
+            }
+            
+            button.editProperties({isActive: onAppScreen});
+            wireEventBridge(onAppScreen);
         }
-        
-        button.editProperties({isActive: onAppScreen});
-        wireEventBridge(onAppScreen);
     }
 
     function fromQml(message) {
@@ -72,6 +114,7 @@
     tablet.screenChanged.connect(onScreenChanged);
 
     Script.scriptEnding.connect(function () {
+        killWindow()
         if (onAppScreen) {
             tablet.gotoHomeScreen();
         }
@@ -113,8 +156,14 @@
     }
 
     function sendToQml(message) {
-        tablet.sendToQml(message);
+        if (onTablet) {
+            tablet.sendToQml(message);
+        } else {
+            if (window) {
+                window.sendToQml(message);
+            }
+        }
     }
 
     updateGridInQML()
-}()); 
\ No newline at end of file
+}()); 
diff --git a/scripts/developer/utilities/workload/workloadInspector.qml b/scripts/developer/utilities/workload/workloadInspector.qml
index 8076f5c1c2..c55fdee040 100644
--- a/scripts/developer/utilities/workload/workloadInspector.qml
+++ b/scripts/developer/utilities/workload/workloadInspector.qml
@@ -259,18 +259,71 @@ Rectangle {
                 }
             ]
         }
+      /*  PlotPerf {
+            title: "Ranges"
+            height: 100
+            object: stats.controlViews
+            valueScale: 1.0
+            valueUnit: "m"
+            plots: [
+                {
+                    prop: "r3RangeFront",
+                    label: "R3 F",
+                    color: "#FF0000"
+                },
+                {
+                    prop: "r3RangeBack",
+                    label: "R3 B",
+                    color: "#EF0000"
+                },
+                {
+                    prop: "r2RangeFront",
+                    label: "R2 F",
+                    color: "orange"
+                },
+                {
+                    prop: "r2RangeBack",
+                    label: "R2 B",
+                    color: "magenta"
+                },
+                {
+                    prop: "r1RangeFront",
+                    label: "R1 F",
+                    color: "#00FF00"
+                },
+                {
+                    prop: "r1RangeBack",
+                    label: "R1 B",
+                    color: "#00EF00"
+                },
+            ]
+        }*/
         Separator {} 
         HifiControls.Label {
-            text: "Numbers:";     
+            text: "Ranges & Numbers:";     
         }
-        HifiControls.Label {
-            text: "R1= " + Workload.getConfig("regionState")["numR1"];     
-        } 
-        HifiControls.Label {
-            text: "R2= " + Workload.getConfig("regionState")["numR2"];     
-        } 
-        HifiControls.Label {
-            text: "R3= " + Workload.getConfig("regionState")["numR3"];     
+        Repeater {
+            model: [ 
+                "green:R1:numR1:r1RangeBack:r1RangeFront",
+                "orange:R2:numR2:r2RangeBack:r2RangeFront",
+                "red:R3:numR3:r3RangeBack:r3RangeFront"
+            ]
+            RowLayout {
+                anchors.left: parent.left
+                anchors.right: parent.right 
+                HifiControls.Label {
+                    text: modelData.split(":")[1] + " : " + Workload.getConfig("regionState")[modelData.split(":")[2]] ;
+                    color: modelData.split(":")[0]     
+                }
+                HifiControls.Label {
+                    text: Workload.getConfig("controlViews")[modelData.split(":")[3]].toFixed(0) ;
+                    color: modelData.split(":")[0]     
+                }
+                HifiControls.Label {
+                    text: Workload.getConfig("controlViews")[modelData.split(":")[4]].toFixed(0) ;
+                    color: modelData.split(":")[0]     
+                } 
+            } 
         }
 
         Separator {}