From 665b21f2f788a0ec649bf214196b2891c5cc461e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 23 Mar 2017 17:08:32 -0700 Subject: [PATCH 01/36] Checkpoint --- .../src/scripting/HMDScriptingInterface.h | 1 + scripts/system/selectAudioDevice.js | 160 ++++++++++-------- 2 files changed, 90 insertions(+), 71 deletions(-) diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 276e23d2d5..846aa13017 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -80,6 +80,7 @@ public: signals: bool shouldShowHandControllersChanged(); + void mountedChanged(); public: HMDScriptingInterface(); diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index f5929ce151..04215c966d 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -45,26 +45,43 @@ if (typeof String.prototype.trimEndsWith != 'function') { }; } +/**************************************** + VAR DEFINITIONS +****************************************/ const INPUT_DEVICE_SETTING = "audio_input_device"; const OUTPUT_DEVICE_SETTING = "audio_output_device"; - var selectedInputMenu = ""; var selectedOutputMenu = ""; +var audioDevicesList = []; +// Some HMDs (like Oculus CV1) have a built in audio device. If they +// do, then this function will handle switching to that device automatically +// when you goActive with the HMD active. +var wasHmdActive = false; // assume it's not active to start +var switchedAudioInputToHMD = false; +var switchedAudioOutputToHMD = false; +var previousSelectedInputAudioDevice = ""; +var previousSelectedOutputAudioDevice = ""; - var audioDevicesList = []; +/**************************************** + BEGIN FUNCTION DEFINITIONS +****************************************/ function setupAudioMenus() { removeAudioMenus(); - Menu.addSeparator("Audio", "Input Audio Device"); + /* Setup audio input devices */ + Menu.addSeparator("Audio", "Input Audio Device"); var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); var inputDevices = AudioDevice.getInputDevices(); var selectedInputDevice = AudioDevice.getInputDevice(); if (inputDevices.indexOf(inputDeviceSetting) != -1 && selectedInputDevice != inputDeviceSetting) { + print ("Audio input device SETTING does not match Input AudioDevice. Attempting to change Input AudioDevice...") if (AudioDevice.setInputDevice(inputDeviceSetting)) { selectedInputDevice = inputDeviceSetting; + } else { + print("Error setting audio input device!") } } - print("audio input devices: " + inputDevices); + print("Audio input devices: " + inputDevices); for(var i = 0; i < inputDevices.length; i++) { var thisDeviceSelected = (inputDevices[i] == selectedInputDevice); var menuItem = "Use " + inputDevices[i] + " for Input"; @@ -80,17 +97,20 @@ function setupAudioMenus() { } } + /* Setup audio output devices */ Menu.addSeparator("Audio", "Output Audio Device"); - var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); var outputDevices = AudioDevice.getOutputDevices(); var selectedOutputDevice = AudioDevice.getOutputDevice(); if (outputDevices.indexOf(outputDeviceSetting) != -1 && selectedOutputDevice != outputDeviceSetting) { + print("Audio output device SETTING does not match Output AudioDevice. Attempting to change Output AudioDevice...") if (AudioDevice.setOutputDevice(outputDeviceSetting)) { selectedOutputDevice = outputDeviceSetting; + } else { + print("Error setting audio output device!") } } - print("audio output devices: " + outputDevices); + print("Audio output devices: " + outputDevices); for (var i = 0; i < outputDevices.length; i++) { var thisDeviceSelected = (outputDevices[i] == selectedOutputDevice); var menuItem = "Use " + outputDevices[i] + " for Output"; @@ -115,127 +135,125 @@ function removeAudioMenus() { Menu.removeMenuItem("Audio", audioDevicesList[index]); } + Menu.removeMenu("Audio > Devices"); + audioDevicesList = []; } function onDevicechanged() { - print("audio devices changed, removing Audio > Devices menu..."); - Menu.removeMenu("Audio > Devices"); - print("now setting up Audio > Devices menu"); + print("System audio device changed. Removing and replacing Audio Menus..."); setupAudioMenus(); } -// Have a small delay before the menu's get setup and the audio devices can switch to the last selected ones -Script.setTimeout(function () { - print("connecting deviceChanged"); - AudioDevice.deviceChanged.connect(onDevicechanged); - print("setting up Audio > Devices menu for first time"); - setupAudioMenus(); -}, 5000); - -function scriptEnding() { - Menu.removeMenu("Audio > Devices"); -} -Script.scriptEnding.connect(scriptEnding); - - function menuItemEvent(menuItem) { if (menuItem.startsWith("Use ")) { - if (menuItem.endsWith(" for Output")) { - var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Output"); - print("output audio selection..." + selectedDevice); - Menu.menuItemEvent.disconnect(menuItemEvent); - Menu.setIsOptionChecked(selectedOutputMenu, false); - selectedOutputMenu = menuItem; - Menu.setIsOptionChecked(selectedOutputMenu, true); - if (AudioDevice.setOutputDevice(selectedDevice)) { - Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); - } - Menu.menuItemEvent.connect(menuItemEvent); - } else if (menuItem.endsWith(" for Input")) { + if (menuItem.endsWith(" for Input")) { var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Input"); - print("input audio selection..." + selectedDevice); + print("User selected a new Audio Input Device: " + selectedDevice); Menu.menuItemEvent.disconnect(menuItemEvent); Menu.setIsOptionChecked(selectedInputMenu, false); selectedInputMenu = menuItem; Menu.setIsOptionChecked(selectedInputMenu, true); if (AudioDevice.setInputDevice(selectedDevice)) { Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); + } else { + print("Error setting audio input device!") + } + Menu.menuItemEvent.connect(menuItemEvent); + } else if (menuItem.endsWith(" for Output")) { + var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Output"); + print("User selected a new Audio Output Device: " + selectedDevice); + Menu.menuItemEvent.disconnect(menuItemEvent); + Menu.setIsOptionChecked(selectedOutputMenu, false); + selectedOutputMenu = menuItem; + Menu.setIsOptionChecked(selectedOutputMenu, true); + if (AudioDevice.setOutputDevice(selectedDevice)) { + Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); + } else { + print("Error setting audio output device!") } Menu.menuItemEvent.connect(menuItemEvent); } } } -Menu.menuItemEvent.connect(menuItemEvent); - -// Some HMDs (like Oculus CV1) have a built in audio device. If they -// do, then this function will handle switching to that device automatically -// when you goActive with the HMD active. -var wasHmdMounted = false; // assume it's un-mounted to start -var switchedAudioInputToHMD = false; -var switchedAudioOutputToHMD = false; -var previousSelectedInputAudioDevice = ""; -var previousSelectedOutputAudioDevice = ""; - function restoreAudio() { if (switchedAudioInputToHMD) { - print("switching back from HMD preferred audio input to:" + previousSelectedInputAudioDevice); + print("Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); menuItemEvent("Use " + previousSelectedInputAudioDevice + " for Input"); + switchedAudioInputToHMD = false; } if (switchedAudioOutputToHMD) { - print("switching back from HMD preferred audio output to:" + previousSelectedOutputAudioDevice); + print("Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); menuItemEvent("Use " + previousSelectedOutputAudioDevice + " for Output"); + switchedAudioOutputToHMD = false; } } function checkHMDAudio() { - // Mounted state is changing... handle switching - if (HMD.mounted != wasHmdMounted) { - print("HMD mounted changed..."); + // HMD Active state is changing; handle switching + if (HMD.active != wasHmdActive) { + print("HMD Active state changed!"); - // We're putting the HMD on... switch to those devices - if (HMD.mounted) { - print("NOW mounted..."); + // We're putting the HMD on; switch to those devices + if (HMD.active) { + print("HMD is now Active."); var hmdPreferredAudioInput = HMD.preferredAudioInput(); var hmdPreferredAudioOutput = HMD.preferredAudioOutput(); - print("hmdPreferredAudioInput:" + hmdPreferredAudioInput); - print("hmdPreferredAudioOutput:" + hmdPreferredAudioOutput); + print("hmdPreferredAudioInput: " + hmdPreferredAudioInput); + print("hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); - var hmdHasPreferredAudio = (hmdPreferredAudioInput !== "") || (hmdPreferredAudioOutput !== ""); - if (hmdHasPreferredAudio) { - print("HMD has preferred audio!"); + if (hmdPreferredAudioInput !== "") { + print("HMD has preferred audio input device."); previousSelectedInputAudioDevice = Settings.getValue(INPUT_DEVICE_SETTING); - previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING); - print("previousSelectedInputAudioDevice:" + previousSelectedInputAudioDevice); - print("previousSelectedOutputAudioDevice:" + previousSelectedOutputAudioDevice); - if (hmdPreferredAudioInput != previousSelectedInputAudioDevice && hmdPreferredAudioInput !== "") { - print("switching to HMD preferred audio input to:" + hmdPreferredAudioInput); + print("previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); + if (hmdPreferredAudioInput != previousSelectedInputAudioDevice) { + print("Switching Audio Input device to HMD preferred device: " + hmdPreferredAudioInput); switchedAudioInputToHMD = true; menuItemEvent("Use " + hmdPreferredAudioInput + " for Input"); } - if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice && hmdPreferredAudioOutput !== "") { - print("switching to HMD preferred audio output to:" + hmdPreferredAudioOutput); + } + if (hmdPreferredAudioOutput !== "") { + print("HMD has preferred audio output device."); + previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING); + print("previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); + if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice) { + print("Switching Audio Output device to HMD preferred device: " + hmdPreferredAudioOutput); switchedAudioOutputToHMD = true; menuItemEvent("Use " + hmdPreferredAudioOutput + " for Output"); } } } else { - print("HMD NOW un-mounted..."); + print("HMD no longer active. Restoring audio I/O devices..."); restoreAudio(); } } - wasHmdMounted = HMD.mounted; + wasHmdActive = HMD.active; } +/**************************************** + END FUNCTION DEFINITIONS +****************************************/ -Script.update.connect(checkHMDAudio); +/**************************************** + BEGIN SCRIPT BODY +****************************************/ +// Have a small delay before the menus get setup so the audio devices can switch to the last selected ones +Script.setTimeout(function () { + print("Connecting deviceChanged() and displayModeChanged()"); + AudioDevice.deviceChanged.connect(onDevicechanged); + HMD.displayModeChanged.connect(checkHMDAudio); + print("Setting up Audio > Devices menu for the first time"); + setupAudioMenus(); +}, 2000); +print("Connecting menuItemEvent() and scriptEnding()"); +Menu.menuItemEvent.connect(menuItemEvent); Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); Menu.menuItemEvent.disconnect(menuItemEvent); - Script.update.disconnect(checkHMDAudio); + HMD.displayModeChanged.disconnect(checkHMDAudio); }); }()); // END LOCAL_SCOPE From 4473e6ba38b7830343d717a20a908888fdda9452 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 24 Mar 2017 09:50:35 -0700 Subject: [PATCH 02/36] Remove dead code --- interface/src/scripting/HMDScriptingInterface.h | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/scripting/HMDScriptingInterface.h b/interface/src/scripting/HMDScriptingInterface.h index 846aa13017..276e23d2d5 100644 --- a/interface/src/scripting/HMDScriptingInterface.h +++ b/interface/src/scripting/HMDScriptingInterface.h @@ -80,7 +80,6 @@ public: signals: bool shouldShowHandControllersChanged(); - void mountedChanged(); public: HMDScriptingInterface(); From e5741869e545e3f0a55b0c355136bf57e64580df Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 24 Mar 2017 12:22:11 -0700 Subject: [PATCH 03/36] Checkpoint --- scripts/system/selectAudioDevice.js | 152 ++++++++++++++++------------ 1 file changed, 90 insertions(+), 62 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index 04215c966d..5d1f44c1f6 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -61,28 +61,29 @@ var switchedAudioInputToHMD = false; var switchedAudioOutputToHMD = false; var previousSelectedInputAudioDevice = ""; var previousSelectedOutputAudioDevice = ""; +var menuConnected = false; /**************************************** BEGIN FUNCTION DEFINITIONS ****************************************/ function setupAudioMenus() { + if (menuConnected) { + Menu.menuItemEvent.disconnect(menuItemEvent); + menuConnected = false; + } removeAudioMenus(); /* Setup audio input devices */ Menu.addSeparator("Audio", "Input Audio Device"); - var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); var inputDevices = AudioDevice.getInputDevices(); + print("selectAudioDevice: Audio input devices: " + inputDevices); var selectedInputDevice = AudioDevice.getInputDevice(); + var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); if (inputDevices.indexOf(inputDeviceSetting) != -1 && selectedInputDevice != inputDeviceSetting) { - print ("Audio input device SETTING does not match Input AudioDevice. Attempting to change Input AudioDevice...") - if (AudioDevice.setInputDevice(inputDeviceSetting)) { - selectedInputDevice = inputDeviceSetting; - } else { - print("Error setting audio input device!") - } + print("selectAudioDevice: Input Setting & Device mismatch! Input SETTING:", inputDeviceSetting, "Input DEVICE IN USE:", selectedInputDevice); + switchAudioDevice(true, inputDeviceSetting); } - print("Audio input devices: " + inputDevices); - for(var i = 0; i < inputDevices.length; i++) { + for (var i = 0; i < inputDevices.length; i++) { var thisDeviceSelected = (inputDevices[i] == selectedInputDevice); var menuItem = "Use " + inputDevices[i] + " for Input"; Menu.addMenuItem({ @@ -99,18 +100,14 @@ function setupAudioMenus() { /* Setup audio output devices */ Menu.addSeparator("Audio", "Output Audio Device"); - var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); var outputDevices = AudioDevice.getOutputDevices(); + print("selectAudioDevice: Audio output devices: " + outputDevices); var selectedOutputDevice = AudioDevice.getOutputDevice(); + var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); if (outputDevices.indexOf(outputDeviceSetting) != -1 && selectedOutputDevice != outputDeviceSetting) { - print("Audio output device SETTING does not match Output AudioDevice. Attempting to change Output AudioDevice...") - if (AudioDevice.setOutputDevice(outputDeviceSetting)) { - selectedOutputDevice = outputDeviceSetting; - } else { - print("Error setting audio output device!") - } + print("selectAudioDevice: Output Setting & Device mismatch! Output SETTING:", outputDeviceSetting, "Output DEVICE IN USE:", selectedOutputDevice); + switchAudioDevice(false, outputDeviceSetting); } - print("Audio output devices: " + outputDevices); for (var i = 0; i < outputDevices.length; i++) { var thisDeviceSelected = (outputDevices[i] == selectedOutputDevice); var menuItem = "Use " + outputDevices[i] + " for Output"; @@ -125,6 +122,10 @@ function setupAudioMenus() { selectedOutputMenu = menuItem; } } + if (!menuConnected) { + Menu.menuItemEvent.connect(menuItemEvent); + menuConnected = true; + } } function removeAudioMenus() { @@ -141,51 +142,77 @@ function removeAudioMenus() { } function onDevicechanged() { - print("System audio device changed. Removing and replacing Audio Menus..."); + print("selectAudioDevice: System audio device changed. Removing and replacing Audio Menus..."); setupAudioMenus(); } function menuItemEvent(menuItem) { + if (menuConnected) { + Menu.menuItemEvent.disconnect(menuItemEvent); + menuConnected = false; + } if (menuItem.startsWith("Use ")) { if (menuItem.endsWith(" for Input")) { var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Input"); - print("User selected a new Audio Input Device: " + selectedDevice); - Menu.menuItemEvent.disconnect(menuItemEvent); - Menu.setIsOptionChecked(selectedInputMenu, false); - selectedInputMenu = menuItem; - Menu.setIsOptionChecked(selectedInputMenu, true); - if (AudioDevice.setInputDevice(selectedDevice)) { - Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); - } else { - print("Error setting audio input device!") - } - Menu.menuItemEvent.connect(menuItemEvent); + print("selectAudioDevice: User selected a new Audio Input Device: " + selectedDevice); + switchAudioDevice(true, selectedDevice); } else if (menuItem.endsWith(" for Output")) { var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Output"); - print("User selected a new Audio Output Device: " + selectedDevice); - Menu.menuItemEvent.disconnect(menuItemEvent); - Menu.setIsOptionChecked(selectedOutputMenu, false); - selectedOutputMenu = menuItem; - Menu.setIsOptionChecked(selectedOutputMenu, true); - if (AudioDevice.setOutputDevice(selectedDevice)) { - Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); - } else { - print("Error setting audio output device!") - } - Menu.menuItemEvent.connect(menuItemEvent); + print("selectAudioDevice: User selected a new Audio Output Device: " + selectedDevice); + switchAudioDevice(false, selectedDevice); + } else { + print("selectAudioDevice: Invalid Audio menuItem! Doesn't end with 'for Input' or 'for Output'") } + } else { + print("selectAudioDevice: Invalid Audio menuItem! Doesn't start with 'Use '") + } + if (!menuConnected) { + Menu.menuItemEvent.connect(menuItemEvent); + menuConnected = true; + } +} + +function switchAudioDevice(isInput, device) { + if (menuConnected) { + Menu.menuItemEvent.disconnect(menuItemEvent); + menuConnected = false; + } + if (isInput) { + print("selectAudioDevice: Switching audio INPUT device to:", device); + if (AudioDevice.setInputDevice(device)) { + Menu.setIsOptionChecked(selectedInputMenu, false); + selectedInputMenu = "Use " + device + " for Input"; + Menu.setIsOptionChecked(selectedInputMenu, true); + Settings.setValue(INPUT_DEVICE_SETTING, device); + } else { + print("selectAudioDevice: Error setting audio input device!") + } + } else { + print("selectAudioDevice: Switching audio OUTPUT device to:", device); + if (AudioDevice.setOutputDevice(device)) { + Menu.setIsOptionChecked(selectedOutputMenu, false); + selectedOutputMenu = "Use " + device + " for Output"; + Menu.setIsOptionChecked(selectedOutputMenu, true); + Settings.setValue(OUTPUT_DEVICE_SETTING, device); + } else { + print("selectAudioDevice: Error setting audio output device!") + } + } + if (!menuConnected) { + Menu.menuItemEvent.connect(menuItemEvent); + menuConnected = true; } } function restoreAudio() { if (switchedAudioInputToHMD) { - print("Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); - menuItemEvent("Use " + previousSelectedInputAudioDevice + " for Input"); + print("selectAudioDevice: Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); + switchAudioDevice(true, previousSelectedInputAudioDevice); switchedAudioInputToHMD = false; } if (switchedAudioOutputToHMD) { - print("Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); - menuItemEvent("Use " + previousSelectedOutputAudioDevice + " for Output"); + print("selectAudioDevice: Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); + switchAudioDevice(false, previousSelectedOutputAudioDevice); switchedAudioOutputToHMD = false; } } @@ -193,39 +220,38 @@ function restoreAudio() { function checkHMDAudio() { // HMD Active state is changing; handle switching if (HMD.active != wasHmdActive) { - print("HMD Active state changed!"); + print("selectAudioDevice: HMD Active state changed!"); // We're putting the HMD on; switch to those devices if (HMD.active) { - print("HMD is now Active."); + print("selectAudioDevice: HMD is now Active."); var hmdPreferredAudioInput = HMD.preferredAudioInput(); var hmdPreferredAudioOutput = HMD.preferredAudioOutput(); - print("hmdPreferredAudioInput: " + hmdPreferredAudioInput); - print("hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); - + print("selectAudioDevice: hmdPreferredAudioInput: " + hmdPreferredAudioInput); + print("selectAudioDevice: hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); if (hmdPreferredAudioInput !== "") { - print("HMD has preferred audio input device."); + print("selectAudioDevice: HMD has preferred audio input device."); previousSelectedInputAudioDevice = Settings.getValue(INPUT_DEVICE_SETTING); - print("previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); + print("selectAudioDevice: previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); if (hmdPreferredAudioInput != previousSelectedInputAudioDevice) { - print("Switching Audio Input device to HMD preferred device: " + hmdPreferredAudioInput); + print("selectAudioDevice: Switching Audio Input device to HMD preferred device: " + hmdPreferredAudioInput); switchedAudioInputToHMD = true; - menuItemEvent("Use " + hmdPreferredAudioInput + " for Input"); + switchAudioDevice(true, hmdPreferredAudioInput); } } if (hmdPreferredAudioOutput !== "") { - print("HMD has preferred audio output device."); + print("selectAudioDevice: HMD has preferred audio output device."); previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING); - print("previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); + print("selectAudioDevice: previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice) { - print("Switching Audio Output device to HMD preferred device: " + hmdPreferredAudioOutput); + print("selectAudioDevice: Switching Audio Output device to HMD preferred device: " + hmdPreferredAudioOutput); switchedAudioOutputToHMD = true; - menuItemEvent("Use " + hmdPreferredAudioOutput + " for Output"); + switchAudioDevice(false, hmdPreferredAudioOutput); } } } else { - print("HMD no longer active. Restoring audio I/O devices..."); + print("selectAudioDevice: HMD no longer active. Restoring audio I/O devices..."); restoreAudio(); } } @@ -240,15 +266,17 @@ function checkHMDAudio() { ****************************************/ // Have a small delay before the menus get setup so the audio devices can switch to the last selected ones Script.setTimeout(function () { - print("Connecting deviceChanged() and displayModeChanged()"); + print("selectAudioDevice: Connecting deviceChanged() and displayModeChanged()"); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); - print("Setting up Audio > Devices menu for the first time"); + print("selectAudioDevice: Setting up Audio > Devices menu for the first time"); setupAudioMenus(); -}, 2000); + checkHMDAudio(); +}, 5000); -print("Connecting menuItemEvent() and scriptEnding()"); +print("selectAudioDevice: Connecting menuItemEvent() and scriptEnding()"); Menu.menuItemEvent.connect(menuItemEvent); +menuConnected = true; Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); From 31ae326880b18ff9754989557c4b1990c7ff9914 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 24 Mar 2017 13:05:07 -0700 Subject: [PATCH 04/36] Pretty sure about this now --- scripts/system/selectAudioDevice.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index 5d1f44c1f6..cc0f25b005 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -95,6 +95,7 @@ function setupAudioMenus() { audioDevicesList.push(menuItem); if (thisDeviceSelected) { selectedInputMenu = menuItem; + print("selectAudioDevice: selectedInputMenu: " + selectedInputMenu); } } @@ -120,6 +121,7 @@ function setupAudioMenus() { audioDevicesList.push(menuItem); if (thisDeviceSelected) { selectedOutputMenu = menuItem; + print("selectAudioDevice: selectedOutputMenu: " + selectedOutputMenu); } } if (!menuConnected) { @@ -180,9 +182,6 @@ function switchAudioDevice(isInput, device) { if (isInput) { print("selectAudioDevice: Switching audio INPUT device to:", device); if (AudioDevice.setInputDevice(device)) { - Menu.setIsOptionChecked(selectedInputMenu, false); - selectedInputMenu = "Use " + device + " for Input"; - Menu.setIsOptionChecked(selectedInputMenu, true); Settings.setValue(INPUT_DEVICE_SETTING, device); } else { print("selectAudioDevice: Error setting audio input device!") @@ -190,14 +189,12 @@ function switchAudioDevice(isInput, device) { } else { print("selectAudioDevice: Switching audio OUTPUT device to:", device); if (AudioDevice.setOutputDevice(device)) { - Menu.setIsOptionChecked(selectedOutputMenu, false); - selectedOutputMenu = "Use " + device + " for Output"; - Menu.setIsOptionChecked(selectedOutputMenu, true); Settings.setValue(OUTPUT_DEVICE_SETTING, device); } else { print("selectAudioDevice: Error setting audio output device!") } } + setupAudioMenus(); if (!menuConnected) { Menu.menuItemEvent.connect(menuItemEvent); menuConnected = true; @@ -218,6 +215,10 @@ function restoreAudio() { } function checkHMDAudio() { + if (menuConnected) { + Menu.menuItemEvent.disconnect(menuItemEvent); + menuConnected = false; + } // HMD Active state is changing; handle switching if (HMD.active != wasHmdActive) { print("selectAudioDevice: HMD Active state changed!"); @@ -256,6 +257,10 @@ function checkHMDAudio() { } } wasHmdActive = HMD.active; + if (!menuConnected) { + Menu.menuItemEvent.connect(menuItemEvent); + menuConnected = true; + } } /**************************************** END FUNCTION DEFINITIONS @@ -269,10 +274,11 @@ Script.setTimeout(function () { print("selectAudioDevice: Connecting deviceChanged() and displayModeChanged()"); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); + print ("selectAudioDevice: Checking HMD audio status...") + checkHMDAudio(); print("selectAudioDevice: Setting up Audio > Devices menu for the first time"); setupAudioMenus(); - checkHMDAudio(); -}, 5000); +}, 3000); print("selectAudioDevice: Connecting menuItemEvent() and scriptEnding()"); Menu.menuItemEvent.connect(menuItemEvent); From 73a77f7f2563c37f8831c751e2d3466cd5011d4d Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 24 Mar 2017 18:19:34 -0700 Subject: [PATCH 05/36] OK, how about now --- scripts/system/selectAudioDevice.js | 102 ++++++++++------------------ 1 file changed, 34 insertions(+), 68 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index cc0f25b005..a2246bf1d5 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -50,8 +50,6 @@ if (typeof String.prototype.trimEndsWith != 'function') { ****************************************/ const INPUT_DEVICE_SETTING = "audio_input_device"; const OUTPUT_DEVICE_SETTING = "audio_output_device"; -var selectedInputMenu = ""; -var selectedOutputMenu = ""; var audioDevicesList = []; // Some HMDs (like Oculus CV1) have a built in audio device. If they // do, then this function will handle switching to that device automatically @@ -61,72 +59,59 @@ var switchedAudioInputToHMD = false; var switchedAudioOutputToHMD = false; var previousSelectedInputAudioDevice = ""; var previousSelectedOutputAudioDevice = ""; -var menuConnected = false; /**************************************** BEGIN FUNCTION DEFINITIONS ****************************************/ function setupAudioMenus() { - if (menuConnected) { - Menu.menuItemEvent.disconnect(menuItemEvent); - menuConnected = false; - } - removeAudioMenus(); + Menu.menuItemEvent.disconnect(menuItemEvent); /* Setup audio input devices */ Menu.addSeparator("Audio", "Input Audio Device"); var inputDevices = AudioDevice.getInputDevices(); print("selectAudioDevice: Audio input devices: " + inputDevices); - var selectedInputDevice = AudioDevice.getInputDevice(); - var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); - if (inputDevices.indexOf(inputDeviceSetting) != -1 && selectedInputDevice != inputDeviceSetting) { - print("selectAudioDevice: Input Setting & Device mismatch! Input SETTING:", inputDeviceSetting, "Input DEVICE IN USE:", selectedInputDevice); - switchAudioDevice(true, inputDeviceSetting); - } for (var i = 0; i < inputDevices.length; i++) { - var thisDeviceSelected = (inputDevices[i] == selectedInputDevice); var menuItem = "Use " + inputDevices[i] + " for Input"; Menu.addMenuItem({ menuName: "Audio", menuItemName: menuItem, isCheckable: true, - isChecked: thisDeviceSelected + isChecked: inputDevices[i] == AudioDevice.getInputDevice() }); audioDevicesList.push(menuItem); - if (thisDeviceSelected) { - selectedInputMenu = menuItem; - print("selectAudioDevice: selectedInputMenu: " + selectedInputMenu); - } } /* Setup audio output devices */ Menu.addSeparator("Audio", "Output Audio Device"); var outputDevices = AudioDevice.getOutputDevices(); print("selectAudioDevice: Audio output devices: " + outputDevices); - var selectedOutputDevice = AudioDevice.getOutputDevice(); - var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); - if (outputDevices.indexOf(outputDeviceSetting) != -1 && selectedOutputDevice != outputDeviceSetting) { - print("selectAudioDevice: Output Setting & Device mismatch! Output SETTING:", outputDeviceSetting, "Output DEVICE IN USE:", selectedOutputDevice); - switchAudioDevice(false, outputDeviceSetting); - } for (var i = 0; i < outputDevices.length; i++) { - var thisDeviceSelected = (outputDevices[i] == selectedOutputDevice); var menuItem = "Use " + outputDevices[i] + " for Output"; Menu.addMenuItem({ menuName: "Audio", menuItemName: menuItem, isCheckable: true, - isChecked: thisDeviceSelected + isChecked: outputDevices[i] == AudioDevice.getOutputDevice() }); audioDevicesList.push(menuItem); - if (thisDeviceSelected) { - selectedOutputMenu = menuItem; - print("selectAudioDevice: selectedOutputMenu: " + selectedOutputMenu); - } } - if (!menuConnected) { - Menu.menuItemEvent.connect(menuItemEvent); - menuConnected = true; + + Menu.menuItemEvent.connect(menuItemEvent); +} + +function checkDeviceMismatch() { + var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); + var interfaceInputDevice = AudioDevice.getInputDevice(); + if (interfaceInputDevice != inputDeviceSetting) { + print("selectAudioDevice: Input Setting & Device mismatch! Input SETTING:", inputDeviceSetting, "Input DEVICE IN USE:", AudioDevice.getInputDevice()); + switchAudioDevice(true, inputDeviceSetting); + } + + var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); + var interfaceOutputDevice = AudioDevice.getOutputDevice(); + if (interfaceOutputDevice != outputDeviceSetting) { + print("selectAudioDevice: Output Setting & Device mismatch! Output SETTING:", outputDeviceSetting, "Output DEVICE IN USE:", interfaceOutputDevice); + switchAudioDevice(false, outputDeviceSetting); } } @@ -135,7 +120,9 @@ function removeAudioMenus() { Menu.removeSeparator("Audio", "Output Audio Device"); for (var index = 0; index < audioDevicesList.length; index++) { - Menu.removeMenuItem("Audio", audioDevicesList[index]); + if (Menu.menuItemExists("Audio", audioDevicesList[index])) { + Menu.removeMenuItem("Audio", audioDevicesList[index]); + } } Menu.removeMenu("Audio > Devices"); @@ -145,14 +132,12 @@ function removeAudioMenus() { function onDevicechanged() { print("selectAudioDevice: System audio device changed. Removing and replacing Audio Menus..."); + removeAudioMenus(); setupAudioMenus(); + checkDeviceMismatch(); } function menuItemEvent(menuItem) { - if (menuConnected) { - Menu.menuItemEvent.disconnect(menuItemEvent); - menuConnected = false; - } if (menuItem.startsWith("Use ")) { if (menuItem.endsWith(" for Input")) { var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Input"); @@ -165,20 +150,10 @@ function menuItemEvent(menuItem) { } else { print("selectAudioDevice: Invalid Audio menuItem! Doesn't end with 'for Input' or 'for Output'") } - } else { - print("selectAudioDevice: Invalid Audio menuItem! Doesn't start with 'Use '") - } - if (!menuConnected) { - Menu.menuItemEvent.connect(menuItemEvent); - menuConnected = true; } } function switchAudioDevice(isInput, device) { - if (menuConnected) { - Menu.menuItemEvent.disconnect(menuItemEvent); - menuConnected = false; - } if (isInput) { print("selectAudioDevice: Switching audio INPUT device to:", device); if (AudioDevice.setInputDevice(device)) { @@ -194,11 +169,9 @@ function switchAudioDevice(isInput, device) { print("selectAudioDevice: Error setting audio output device!") } } + + removeAudioMenus(); setupAudioMenus(); - if (!menuConnected) { - Menu.menuItemEvent.connect(menuItemEvent); - menuConnected = true; - } } function restoreAudio() { @@ -215,10 +188,6 @@ function restoreAudio() { } function checkHMDAudio() { - if (menuConnected) { - Menu.menuItemEvent.disconnect(menuItemEvent); - menuConnected = false; - } // HMD Active state is changing; handle switching if (HMD.active != wasHmdActive) { print("selectAudioDevice: HMD Active state changed!"); @@ -257,10 +226,6 @@ function checkHMDAudio() { } } wasHmdActive = HMD.active; - if (!menuConnected) { - Menu.menuItemEvent.connect(menuItemEvent); - menuConnected = true; - } } /**************************************** END FUNCTION DEFINITIONS @@ -271,23 +236,24 @@ function checkHMDAudio() { ****************************************/ // Have a small delay before the menus get setup so the audio devices can switch to the last selected ones Script.setTimeout(function () { - print("selectAudioDevice: Connecting deviceChanged() and displayModeChanged()"); + print("selectAudioDevice: Connecting deviceChanged(), displayModeChanged(), and menuItemEvent()"); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); - print ("selectAudioDevice: Checking HMD audio status...") - checkHMDAudio(); + Menu.menuItemEvent.connect(menuItemEvent); print("selectAudioDevice: Setting up Audio > Devices menu for the first time"); setupAudioMenus(); + checkDeviceMismatch(); + print("selectAudioDevice: Checking HMD audio status...") + checkHMDAudio(); }, 3000); -print("selectAudioDevice: Connecting menuItemEvent() and scriptEnding()"); -Menu.menuItemEvent.connect(menuItemEvent); -menuConnected = true; +print("selectAudioDevice: Connecting scriptEnding()"); Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); Menu.menuItemEvent.disconnect(menuItemEvent); HMD.displayModeChanged.disconnect(checkHMDAudio); + AudioDevice.deviceChanged.disconnect(onDevicechanged); }); }()); // END LOCAL_SCOPE From 59008e4a40015069049cfb776d9b5efc3e38f9de Mon Sep 17 00:00:00 2001 From: humbletim Date: Sat, 25 Mar 2017 18:37:36 -0400 Subject: [PATCH 06/36] remove old ../../qml/menus import --- interface/resources/QtWebEngine/UIDelegates/Menu.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/resources/QtWebEngine/UIDelegates/Menu.qml b/interface/resources/QtWebEngine/UIDelegates/Menu.qml index 5176d9d11e..1bbbbd6cbe 100644 --- a/interface/resources/QtWebEngine/UIDelegates/Menu.qml +++ b/interface/resources/QtWebEngine/UIDelegates/Menu.qml @@ -1,7 +1,6 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 as Controls -import "../../qml/menus" import "../../qml/controls-uit" import "../../qml/styles-uit" From 0ae4ce7e985c86f7a600034c29ef176b84493c3a Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 27 Mar 2017 16:15:11 -0700 Subject: [PATCH 07/36] Have I finally tamed the beast? --- scripts/system/selectAudioDevice.js | 198 +++++++++++++++------------- 1 file changed, 110 insertions(+), 88 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index a2246bf1d5..f3d40820cb 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -45,73 +45,78 @@ if (typeof String.prototype.trimEndsWith != 'function') { }; } -/**************************************** - VAR DEFINITIONS -****************************************/ +// +// VAR DEFINITIONS +// +var debugPrintStatements = true; const INPUT_DEVICE_SETTING = "audio_input_device"; const OUTPUT_DEVICE_SETTING = "audio_output_device"; var audioDevicesList = []; -// Some HMDs (like Oculus CV1) have a built in audio device. If they -// do, then this function will handle switching to that device automatically -// when you goActive with the HMD active. var wasHmdActive = false; // assume it's not active to start var switchedAudioInputToHMD = false; var switchedAudioOutputToHMD = false; var previousSelectedInputAudioDevice = ""; var previousSelectedOutputAudioDevice = ""; -/**************************************** - BEGIN FUNCTION DEFINITIONS -****************************************/ -function setupAudioMenus() { - Menu.menuItemEvent.disconnect(menuItemEvent); +// +// BEGIN FUNCTION DEFINITIONS +// +function debug() { + if (debugPrintStatements) { + print.apply(null, [].concat.apply(["selectAudioDevice.js:"], [].map.call(arguments, JSON.stringify))); + } +} - /* Setup audio input devices */ + +function setupAudioMenus() { + Menu.menuItemEvent.disconnect(switchAudioDevice); + + removeAudioMenus(); + + // Setup audio input devices Menu.addSeparator("Audio", "Input Audio Device"); var inputDevices = AudioDevice.getInputDevices(); - print("selectAudioDevice: Audio input devices: " + inputDevices); for (var i = 0; i < inputDevices.length; i++) { - var menuItem = "Use " + inputDevices[i] + " for Input"; + var audioDeviceMenuString = "Use " + inputDevices[i] + " for Input"; Menu.addMenuItem({ menuName: "Audio", - menuItemName: menuItem, + menuItemName: audioDeviceMenuString, isCheckable: true, isChecked: inputDevices[i] == AudioDevice.getInputDevice() }); - audioDevicesList.push(menuItem); + audioDevicesList.push(audioDeviceMenuString); } - /* Setup audio output devices */ + // Setup audio output devices Menu.addSeparator("Audio", "Output Audio Device"); var outputDevices = AudioDevice.getOutputDevices(); - print("selectAudioDevice: Audio output devices: " + outputDevices); for (var i = 0; i < outputDevices.length; i++) { - var menuItem = "Use " + outputDevices[i] + " for Output"; + var audioDeviceMenuString = "Use " + outputDevices[i] + " for Output"; Menu.addMenuItem({ menuName: "Audio", - menuItemName: menuItem, + menuItemName: audioDeviceMenuString, isCheckable: true, isChecked: outputDevices[i] == AudioDevice.getOutputDevice() }); - audioDevicesList.push(menuItem); + audioDevicesList.push(audioDeviceMenuString); } - Menu.menuItemEvent.connect(menuItemEvent); + Menu.menuItemEvent.connect(switchAudioDevice); } function checkDeviceMismatch() { var inputDeviceSetting = Settings.getValue(INPUT_DEVICE_SETTING); var interfaceInputDevice = AudioDevice.getInputDevice(); if (interfaceInputDevice != inputDeviceSetting) { - print("selectAudioDevice: Input Setting & Device mismatch! Input SETTING:", inputDeviceSetting, "Input DEVICE IN USE:", AudioDevice.getInputDevice()); - switchAudioDevice(true, inputDeviceSetting); + debug("Input Setting & Device mismatch! Input SETTING: " + inputDeviceSetting + "Input DEVICE IN USE: " + interfaceInputDevice); + switchAudioDevice("Use " + inputDeviceSetting + " for Input"); } var outputDeviceSetting = Settings.getValue(OUTPUT_DEVICE_SETTING); var interfaceOutputDevice = AudioDevice.getOutputDevice(); if (interfaceOutputDevice != outputDeviceSetting) { - print("selectAudioDevice: Output Setting & Device mismatch! Output SETTING:", outputDeviceSetting, "Output DEVICE IN USE:", interfaceOutputDevice); - switchAudioDevice(false, outputDeviceSetting); + debug("Output Setting & Device mismatch! Output SETTING: " + outputDeviceSetting + "Output DEVICE IN USE: " + interfaceOutputDevice); + switchAudioDevice("Use " + outputDeviceSetting + " for Output"); } } @@ -131,129 +136,146 @@ function removeAudioMenus() { } function onDevicechanged() { - print("selectAudioDevice: System audio device changed. Removing and replacing Audio Menus..."); - removeAudioMenus(); + debug("System audio devices changed. Removing and replacing Audio Menus..."); setupAudioMenus(); + AudioDevice.setOutputDevice(AudioDevice.getOutputDevice()); + AudioDevice.setInputDevice(AudioDevice.getInputDevice()); checkDeviceMismatch(); } -function menuItemEvent(menuItem) { - if (menuItem.startsWith("Use ")) { - if (menuItem.endsWith(" for Input")) { - var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Input"); - print("selectAudioDevice: User selected a new Audio Input Device: " + selectedDevice); - switchAudioDevice(true, selectedDevice); - } else if (menuItem.endsWith(" for Output")) { - var selectedDevice = menuItem.trimStartsWith("Use ").trimEndsWith(" for Output"); - print("selectAudioDevice: User selected a new Audio Output Device: " + selectedDevice); - switchAudioDevice(false, selectedDevice); - } else { - print("selectAudioDevice: Invalid Audio menuItem! Doesn't end with 'for Input' or 'for Output'") - } - } -} +function switchAudioDevice(audioDeviceMenuString) { + Menu.menuItemEvent.disconnect(switchAudioDevice); -function switchAudioDevice(isInput, device) { - if (isInput) { - print("selectAudioDevice: Switching audio INPUT device to:", device); - if (AudioDevice.setInputDevice(device)) { - Settings.setValue(INPUT_DEVICE_SETTING, device); + if (audioDeviceMenuString.startsWith("Use ")) { + if (audioDeviceMenuString.endsWith(" for Input")) { + var selectedDevice = audioDeviceMenuString.trimStartsWith("Use ").trimEndsWith(" for Input"); + var currentInputDevice = AudioDevice.getInputDevice(); + if (selectedDevice != currentInputDevice) { + debug("Switching audio INPUT device from " + currentInputDevice + " to " + selectedDevice); + Menu.setIsOptionChecked("Use " + currentInputDevice + " for Input", false); + if (AudioDevice.setInputDevice(selectedDevice)) { + Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); + Menu.setIsOptionChecked(audioDeviceMenuString, true); + } else { + debug("Error setting audio input device!") + Menu.setIsOptionChecked(audioDeviceMenuString, false); + } + } else { + debug("Selected input device is the same as the current input device!") + Menu.setIsOptionChecked(audioDeviceMenuString, true); + AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) + } + } else if (audioDeviceMenuString.endsWith(" for Output")) { + var selectedDevice = audioDeviceMenuString.trimStartsWith("Use ").trimEndsWith(" for Output"); + var currentOutputDevice = AudioDevice.getOutputDevice(); + if (selectedDevice != currentOutputDevice) { + debug("Switching audio OUTPUT device from " + currentOutputDevice + " to " + selectedDevice); + Menu.setIsOptionChecked("Use " + currentOutputDevice + " for Output", false); + if (AudioDevice.setOutputDevice(selectedDevice)) { + Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); + Menu.setIsOptionChecked(audioDeviceMenuString, true); + } else { + debug("Error setting audio output device!") + Menu.setIsOptionChecked(audioDeviceMenuString, false); + } + } else { + debug("Selected output device is the same as the current output device!") + Menu.setIsOptionChecked(audioDeviceMenuString, true); + AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) + } } else { - print("selectAudioDevice: Error setting audio input device!") - } - } else { - print("selectAudioDevice: Switching audio OUTPUT device to:", device); - if (AudioDevice.setOutputDevice(device)) { - Settings.setValue(OUTPUT_DEVICE_SETTING, device); - } else { - print("selectAudioDevice: Error setting audio output device!") + debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'") } } - removeAudioMenus(); - setupAudioMenus(); + Menu.menuItemEvent.connect(switchAudioDevice); } function restoreAudio() { if (switchedAudioInputToHMD) { - print("selectAudioDevice: Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); - switchAudioDevice(true, previousSelectedInputAudioDevice); + debug("Switching back from HMD preferred audio input to: " + previousSelectedInputAudioDevice); + switchAudioDevice("Use " + previousSelectedInputAudioDevice + " for Input"); switchedAudioInputToHMD = false; } if (switchedAudioOutputToHMD) { - print("selectAudioDevice: Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); - switchAudioDevice(false, previousSelectedOutputAudioDevice); + debug("Switching back from HMD preferred audio output to: " + previousSelectedOutputAudioDevice); + switchAudioDevice("Use " + previousSelectedOutputAudioDevice + " for Output"); switchedAudioOutputToHMD = false; } } +// Some HMDs (like Oculus CV1) have a built in audio device. If they +// do, then this function will handle switching to that device automatically +// when you goActive with the HMD active. function checkHMDAudio() { // HMD Active state is changing; handle switching if (HMD.active != wasHmdActive) { - print("selectAudioDevice: HMD Active state changed!"); + debug("HMD Active state changed!"); // We're putting the HMD on; switch to those devices if (HMD.active) { - print("selectAudioDevice: HMD is now Active."); + debug("HMD is now Active."); var hmdPreferredAudioInput = HMD.preferredAudioInput(); var hmdPreferredAudioOutput = HMD.preferredAudioOutput(); - print("selectAudioDevice: hmdPreferredAudioInput: " + hmdPreferredAudioInput); - print("selectAudioDevice: hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); + debug("hmdPreferredAudioInput: " + hmdPreferredAudioInput); + debug("hmdPreferredAudioOutput: " + hmdPreferredAudioOutput); if (hmdPreferredAudioInput !== "") { - print("selectAudioDevice: HMD has preferred audio input device."); + debug("HMD has preferred audio input device."); previousSelectedInputAudioDevice = Settings.getValue(INPUT_DEVICE_SETTING); - print("selectAudioDevice: previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); + debug("previousSelectedInputAudioDevice: " + previousSelectedInputAudioDevice); if (hmdPreferredAudioInput != previousSelectedInputAudioDevice) { - print("selectAudioDevice: Switching Audio Input device to HMD preferred device: " + hmdPreferredAudioInput); switchedAudioInputToHMD = true; - switchAudioDevice(true, hmdPreferredAudioInput); + switchAudioDevice("Use " + hmdPreferredAudioInput + " for Input"); } } if (hmdPreferredAudioOutput !== "") { - print("selectAudioDevice: HMD has preferred audio output device."); + debug("HMD has preferred audio output device."); previousSelectedOutputAudioDevice = Settings.getValue(OUTPUT_DEVICE_SETTING); - print("selectAudioDevice: previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); + debug("previousSelectedOutputAudioDevice: " + previousSelectedOutputAudioDevice); if (hmdPreferredAudioOutput != previousSelectedOutputAudioDevice) { - print("selectAudioDevice: Switching Audio Output device to HMD preferred device: " + hmdPreferredAudioOutput); switchedAudioOutputToHMD = true; - switchAudioDevice(false, hmdPreferredAudioOutput); + switchAudioDevice("Use " + hmdPreferredAudioOutput + " for Output"); } } } else { - print("selectAudioDevice: HMD no longer active. Restoring audio I/O devices..."); + debug("HMD no longer active. Restoring audio I/O devices..."); restoreAudio(); } } wasHmdActive = HMD.active; } -/**************************************** - END FUNCTION DEFINITIONS -****************************************/ +// +// END FUNCTION DEFINITIONS +// -/**************************************** - BEGIN SCRIPT BODY -****************************************/ -// Have a small delay before the menus get setup so the audio devices can switch to the last selected ones +// +// BEGIN SCRIPT BODY +// +// Wait for the C++ systems to fire up before trying to do anything with audio devices Script.setTimeout(function () { - print("selectAudioDevice: Connecting deviceChanged(), displayModeChanged(), and menuItemEvent()"); + debug("Connecting deviceChanged(), displayModeChanged(), and switchAudioDevice()..."); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); - Menu.menuItemEvent.connect(menuItemEvent); - print("selectAudioDevice: Setting up Audio > Devices menu for the first time"); + Menu.menuItemEvent.connect(switchAudioDevice); + debug("Setting up Audio I/O menu for the first time..."); setupAudioMenus(); checkDeviceMismatch(); - print("selectAudioDevice: Checking HMD audio status...") + debug("Checking HMD audio status...") checkHMDAudio(); }, 3000); -print("selectAudioDevice: Connecting scriptEnding()"); +debug("Connecting scriptEnding()"); Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); - Menu.menuItemEvent.disconnect(menuItemEvent); + Menu.menuItemEvent.disconnect(switchAudioDevice); HMD.displayModeChanged.disconnect(checkHMDAudio); AudioDevice.deviceChanged.disconnect(onDevicechanged); }); +// +// END SCRIPT BODY +// + }()); // END LOCAL_SCOPE From 1bdef141c3626ea1bd9ab7d8c4140be8c56414b5 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 28 Mar 2017 15:33:54 -0400 Subject: [PATCH 08/36] simplify audio menu parsing --- scripts/system/selectAudioDevice.js | 110 ++++++++++++---------------- 1 file changed, 47 insertions(+), 63 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index f3d40820cb..bc7906712a 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -15,34 +15,19 @@ (function() { // BEGIN LOCAL_SCOPE -if (typeof String.prototype.startsWith != 'function') { - String.prototype.startsWith = function (str){ - return this.slice(0, str.length) == str; - }; -} - -if (typeof String.prototype.endsWith != 'function') { - String.prototype.endsWith = function (str){ - return this.slice(-str.length) == str; - }; -} - -if (typeof String.prototype.trimStartsWith != 'function') { - String.prototype.trimStartsWith = function (str){ - if (this.startsWith(str)) { - return this.substr(str.length); - } - return this; - }; -} - -if (typeof String.prototype.trimEndsWith != 'function') { - String.prototype.trimEndsWith = function (str){ - if (this.endsWith(str)) { - return this.substr(0,this.length - str.length); - } - return this; - }; +const INPUT = "Input"; +const OUTPUT = "Output"; +function parseMenuItem(item) { + const USE = "Use "; + const FOR_INPUT = " for " + INPUT; + const FOR_OUTPUT = " for " + OUTPUT; + if (item.slice(0, USE.length) == USE) { + if (item.slice(-FOR_INPUT.length) == FOR_INPUT) { + return { device: item.slice(USE.length, -FOR_INPUT.length), mode: INPUT }; + } else if (item.slice(-FOR_OUTPUT.length) == FOR_OUTPUT) { + return { device: item.slice(USE.length, -FOR_OUTPUT.length), mode: OUTPUT }; + } + } } // @@ -146,45 +131,44 @@ function onDevicechanged() { function switchAudioDevice(audioDeviceMenuString) { Menu.menuItemEvent.disconnect(switchAudioDevice); - if (audioDeviceMenuString.startsWith("Use ")) { - if (audioDeviceMenuString.endsWith(" for Input")) { - var selectedDevice = audioDeviceMenuString.trimStartsWith("Use ").trimEndsWith(" for Input"); - var currentInputDevice = AudioDevice.getInputDevice(); - if (selectedDevice != currentInputDevice) { - debug("Switching audio INPUT device from " + currentInputDevice + " to " + selectedDevice); - Menu.setIsOptionChecked("Use " + currentInputDevice + " for Input", false); - if (AudioDevice.setInputDevice(selectedDevice)) { - Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); - Menu.setIsOptionChecked(audioDeviceMenuString, true); - } else { - debug("Error setting audio input device!") - Menu.setIsOptionChecked(audioDeviceMenuString, false); - } - } else { - debug("Selected input device is the same as the current input device!") + var selection = parseMenuItem(audioDeviceMenuString); + if (!selection) { + debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'") + } else if (selection.mode == INPUT) { + var selectedDevice = selection.device; + var currentInputDevice = AudioDevice.getInputDevice(); + if (selectedDevice != currentInputDevice) { + debug("Switching audio INPUT device from " + currentInputDevice + " to " + selectedDevice); + Menu.setIsOptionChecked("Use " + currentInputDevice + " for Input", false); + if (AudioDevice.setInputDevice(selectedDevice)) { + Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); Menu.setIsOptionChecked(audioDeviceMenuString, true); - AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) - } - } else if (audioDeviceMenuString.endsWith(" for Output")) { - var selectedDevice = audioDeviceMenuString.trimStartsWith("Use ").trimEndsWith(" for Output"); - var currentOutputDevice = AudioDevice.getOutputDevice(); - if (selectedDevice != currentOutputDevice) { - debug("Switching audio OUTPUT device from " + currentOutputDevice + " to " + selectedDevice); - Menu.setIsOptionChecked("Use " + currentOutputDevice + " for Output", false); - if (AudioDevice.setOutputDevice(selectedDevice)) { - Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); - Menu.setIsOptionChecked(audioDeviceMenuString, true); - } else { - debug("Error setting audio output device!") - Menu.setIsOptionChecked(audioDeviceMenuString, false); - } } else { - debug("Selected output device is the same as the current output device!") - Menu.setIsOptionChecked(audioDeviceMenuString, true); - AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) + debug("Error setting audio input device!") + Menu.setIsOptionChecked(audioDeviceMenuString, false); } } else { - debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'") + debug("Selected input device is the same as the current input device!") + Menu.setIsOptionChecked(audioDeviceMenuString, true); + AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) + } + } else if (selection.mode == OUTPUT) { + var selectedDevice = selection.device; + var currentOutputDevice = AudioDevice.getOutputDevice(); + if (selectedDevice != currentOutputDevice) { + debug("Switching audio OUTPUT device from " + currentOutputDevice + " to " + selectedDevice); + Menu.setIsOptionChecked("Use " + currentOutputDevice + " for Output", false); + if (AudioDevice.setOutputDevice(selectedDevice)) { + Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); + Menu.setIsOptionChecked(audioDeviceMenuString, true); + } else { + debug("Error setting audio output device!") + Menu.setIsOptionChecked(audioDeviceMenuString, false); + } + } else { + debug("Selected output device is the same as the current output device!") + Menu.setIsOptionChecked(audioDeviceMenuString, true); + AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } } From 5e0cfb61376a3a0a7a5876fd0afecef0d5d697f0 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 28 Mar 2017 15:34:13 -0400 Subject: [PATCH 09/36] short-circuit audio switching on missing device --- scripts/system/selectAudioDevice.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index bc7906712a..48ab7fea7f 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -129,6 +129,11 @@ function onDevicechanged() { } function switchAudioDevice(audioDeviceMenuString) { + // if the device is not plugged in, short-circuit + if (!~audioDevicesList.indexOf(audioDeviceMenuString)) { + return; + } + Menu.menuItemEvent.disconnect(switchAudioDevice); var selection = parseMenuItem(audioDeviceMenuString); From 06bf5807ae3a0017832db495616d85a518da35e0 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 28 Mar 2017 15:34:42 -0400 Subject: [PATCH 10/36] fix audio setting persistence for already selected device --- scripts/system/selectAudioDevice.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index 48ab7fea7f..5d1d61b7d3 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -154,6 +154,7 @@ function switchAudioDevice(audioDeviceMenuString) { } } else { debug("Selected input device is the same as the current input device!") + Settings.setValue(INPUT_DEVICE_SETTING, selectedDevice); Menu.setIsOptionChecked(audioDeviceMenuString, true); AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } @@ -172,6 +173,7 @@ function switchAudioDevice(audioDeviceMenuString) { } } else { debug("Selected output device is the same as the current output device!") + Settings.setValue(OUTPUT_DEVICE_SETTING, selectedDevice); Menu.setIsOptionChecked(audioDeviceMenuString, true); AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } From 2777ad03972cc5612457ef508ab053c557c6b15a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 28 Mar 2017 21:02:49 -0700 Subject: [PATCH 11/36] fix comments --- assignment-client/src/avatars/AvatarMixer.cpp | 4 ++-- assignment-client/src/avatars/AvatarMixerSlavePool.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index d2bfdde7ea..52d04d5fc0 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -186,8 +186,8 @@ void AvatarMixer::start() { } -// NOTE: nodeData->getAvatar() might be side effected, must be called when access to node/nodeData -// is guarenteed to not be accessed by other thread +// NOTE: nodeData->getAvatar() might be side affected, must be called when access to node/nodeData +// is guaranteed to not be accessed by other thread void AvatarMixer::manageDisplayName(const SharedNodePointer& node) { AvatarMixerClientData* nodeData = reinterpret_cast(node->getLinkedData()); if (nodeData && nodeData->getAvatarSessionDisplayNameMustChange()) { diff --git a/assignment-client/src/avatars/AvatarMixerSlavePool.h b/assignment-client/src/avatars/AvatarMixerSlavePool.h index 6bef0515bb..e6ac2a1f4e 100644 --- a/assignment-client/src/avatars/AvatarMixerSlavePool.h +++ b/assignment-client/src/avatars/AvatarMixerSlavePool.h @@ -49,7 +49,7 @@ private: bool _stop { false }; }; -// Slave pool for audio mixers +// Slave pool for avatar mixers // AvatarMixerSlavePool is not thread-safe! It should be instantiated and used from a single thread. class AvatarMixerSlavePool { using Queue = tbb::concurrent_queue; From 7100f449276f44a52c76ca7011bc12cc5131fd76 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 28 Mar 2017 21:03:01 -0700 Subject: [PATCH 12/36] refresh AvatarData when receiving identity data --- libraries/avatars/src/AvatarData.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index dc806a4115..a1ea103edb 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1495,6 +1495,9 @@ void AvatarData::processAvatarIdentity(const Identity& identity, bool& identityC setAvatarEntityData(identity.avatarEntityData); identityChanged = true; } + // flag this avatar as non-stale by updating _averageBytesReceived + const int BOGUS_NUM_BYTES = 1; + _averageBytesReceived.updateAverage(BOGUS_NUM_BYTES); } QByteArray AvatarData::identityByteArray() const { From c5eb2e064200814fc94a8f106a7d415825161961 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 28 Mar 2017 21:11:32 -0700 Subject: [PATCH 13/36] restore spelling in comment --- assignment-client/src/avatars/AvatarMixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 52d04d5fc0..5ad4849f38 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -186,7 +186,7 @@ void AvatarMixer::start() { } -// NOTE: nodeData->getAvatar() might be side affected, must be called when access to node/nodeData +// NOTE: nodeData->getAvatar() might be side effected, must be called when access to node/nodeData // is guaranteed to not be accessed by other thread void AvatarMixer::manageDisplayName(const SharedNodePointer& node) { AvatarMixerClientData* nodeData = reinterpret_cast(node->getLinkedData()); From 9bc7e416427725ea869a63d8ae6375b903f54298 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 29 Mar 2017 10:57:08 -0700 Subject: [PATCH 14/36] Remove extra calls for binding default textures, not needed --- interface/src/ui/ApplicationOverlay.cpp | 22 ------------------- libraries/model/src/model/TextureMap.cpp | 6 ++--- .../render-utils/src/MeshPartPayload.cpp | 14 ------------ 3 files changed, 3 insertions(+), 39 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index f2d97a0137..0337c4cfa5 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -85,7 +85,6 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) { renderAudioScope(renderArgs); // audio scope in the very back - NOTE: this is the debug audio scope, not the VU meter renderOverlays(renderArgs); // renders Scripts Overlay and AudioScope renderQmlUi(renderArgs); // renders a unit quad with the QML UI texture, and the text overlays from scripts - renderStatsAndLogs(renderArgs); // currently renders nothing }); renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch @@ -159,27 +158,6 @@ void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) { qApp->getOverlays().renderHUD(renderArgs); } -void ApplicationOverlay::renderStatsAndLogs(RenderArgs* renderArgs) { - - // Display stats and log text onscreen - - // Determine whether to compute timing details - - /* - // Show on-screen msec timer - if (Menu::getInstance()->isOptionChecked(MenuOption::FrameTimer)) { - auto canvasSize = qApp->getCanvasSize(); - quint64 mSecsNow = floor(usecTimestampNow() / 1000.0 + 0.5); - QString frameTimer = QString("%1\n").arg((int)(mSecsNow % 1000)); - int timerBottom = - (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) - ? 80 : 20; - drawText(canvasSize.x - 100, canvasSize.y - timerBottom, - 0.30f, 0.0f, 0, frameTimer.toUtf8().constData(), WHITE_TEXT); - } - */ -} - void ApplicationOverlay::renderDomainConnectionStatusBorder(RenderArgs* renderArgs) { auto geometryCache = DependencyManager::get(); static std::once_flag once; diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index d07eae2166..7e5e01e4e4 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -345,8 +345,8 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm PROFILE_RANGE(resource_parse, "createNormalTextureFromBumpImage"); QImage image = processSourceImage(srcImage, false); - if (image.format() != QImage::Format_RGB888) { - image = image.convertToFormat(QImage::Format_RGB888); + if (image.format() != QImage::Format_Grayscale8) { + image = image.convertToFormat(QImage::Format_Grayscale8); } // PR 5540 by AlessandroSigna integrated here as a specialized TextureLoader for bumpmaps @@ -395,7 +395,7 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm glm::normalize(v); // convert to rgb from the value obtained computing the filter - QRgb qRgbValue = qRgba(mapComponent(v.x), mapComponent(v.y), mapComponent(v.z), 1.0); + QRgb qRgbValue = qRgba(mapComponent(v.z), mapComponent(v.y), mapComponent(v.x), 1.0); result.setPixel(i, j, qRgbValue); } } diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 41a1bb4c74..51ce0fffa7 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -168,8 +168,6 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat } else { batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getGrayTexture()); } - } else { - batch.setResourceTexture(ShapePipeline::Slot::ALBEDO, textureCache->getWhiteTexture()); } // Roughness map @@ -182,8 +180,6 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture()); } - } else { - batch.setResourceTexture(ShapePipeline::Slot::MAP::ROUGHNESS, textureCache->getWhiteTexture()); } // Normal map @@ -196,8 +192,6 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, textureCache->getBlueTexture()); } - } else { - batch.setResourceTexture(ShapePipeline::Slot::MAP::NORMAL, nullptr); } // Metallic map @@ -210,8 +204,6 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, textureCache->getBlackTexture()); } - } else { - batch.setResourceTexture(ShapePipeline::Slot::MAP::METALLIC, nullptr); } // Occlusion map @@ -224,8 +216,6 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, textureCache->getWhiteTexture()); } - } else { - batch.setResourceTexture(ShapePipeline::Slot::MAP::OCCLUSION, nullptr); } // Scattering map @@ -238,8 +228,6 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::SCATTERING, textureCache->getWhiteTexture()); } - } else { - batch.setResourceTexture(ShapePipeline::Slot::MAP::SCATTERING, nullptr); } // Emissive / Lightmap @@ -259,8 +247,6 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat } else { batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, textureCache->getBlackTexture()); } - } else { - batch.setResourceTexture(ShapePipeline::Slot::MAP::EMISSIVE_LIGHTMAP, nullptr); } } From 4f7cbd5b7caa70bf382673967f9906762e164ab2 Mon Sep 17 00:00:00 2001 From: Delamare2112 Date: Wed, 29 Mar 2017 12:47:58 -0700 Subject: [PATCH 15/36] Add limitless connection and scripting interface --- .../src/scripting/LimitlessConnection.cpp | 91 +++++++++++++++++++ interface/src/scripting/LimitlessConnection.h | 44 +++++++++ ...lessVoiceRecognitionScriptingInterface.cpp | 64 +++++++++++++ ...itlessVoiceRecognitionScriptingInterface.h | 50 ++++++++++ 4 files changed, 249 insertions(+) create mode 100644 interface/src/scripting/LimitlessConnection.cpp create mode 100644 interface/src/scripting/LimitlessConnection.h create mode 100644 interface/src/scripting/LimitlessVoiceRecognitionScriptingInterface.cpp create mode 100644 interface/src/scripting/LimitlessVoiceRecognitionScriptingInterface.h diff --git a/interface/src/scripting/LimitlessConnection.cpp b/interface/src/scripting/LimitlessConnection.cpp new file mode 100644 index 0000000000..b9f4eacd4b --- /dev/null +++ b/interface/src/scripting/LimitlessConnection.cpp @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include "LimitlessConnection.h" +#include "LimitlessVoiceRecognitionScriptingInterface.h" + +LimitlessConnection::LimitlessConnection() : + _streamingAudioForTranscription(false) +{ +} + +void LimitlessConnection::startListening(QString authCode) { + _transcribeServerSocket.reset(new QTcpSocket(this)); + connect(_transcribeServerSocket.get(), &QTcpSocket::readyRead, this, + &LimitlessConnection::transcriptionReceived); + connect(_transcribeServerSocket.get(), &QTcpSocket::disconnected, this, [this](){stopListening();}); + + static const auto host = "gserv_devel.studiolimitless.com"; + _transcribeServerSocket->connectToHost(host, 1407); + _transcribeServerSocket->waitForConnected(); + QString requestHeader = QString::asprintf("Authorization: %s\r\nfs: %i\r\n", + authCode.toLocal8Bit().data(), AudioConstants::SAMPLE_RATE); + qCDebug(interfaceapp) << "Sending Limitless Audio Stream Request: " << requestHeader; + _transcribeServerSocket->write(requestHeader.toLocal8Bit()); + _transcribeServerSocket->waitForBytesWritten(); +} + +void LimitlessConnection::stopListening() { + emit onFinishedSpeaking(_currentTranscription); + _streamingAudioForTranscription = false; + _currentTranscription = ""; + if (!isConnected()) + return; + _transcribeServerSocket->close(); + disconnect(_transcribeServerSocket.get(), &QTcpSocket::readyRead, this, + &LimitlessConnection::transcriptionReceived); + _transcribeServerSocket.release()->deleteLater(); + disconnect(DependencyManager::get().data(), &AudioClient::inputReceived, this, + &LimitlessConnection::audioInputReceived); + qCDebug(interfaceapp) << "Connection to Limitless Voice Server closed."; +} + +void LimitlessConnection::audioInputReceived(const QByteArray& inputSamples) { + if (isConnected()) { + _transcribeServerSocket->write(inputSamples.data(), inputSamples.size()); + _transcribeServerSocket->waitForBytesWritten(); + } +} + +void LimitlessConnection::transcriptionReceived() { + while (_transcribeServerSocket && _transcribeServerSocket->bytesAvailable() > 0) { + const QByteArray data = _transcribeServerSocket->readAll(); + _serverDataBuffer.append(data); + int begin = _serverDataBuffer.indexOf('<'); + int end = _serverDataBuffer.indexOf('>'); + while (begin > -1 && end > -1) { + const int len = end - begin; + const QByteArray serverMessage = _serverDataBuffer.mid(begin+1, len-1); + if (serverMessage.contains("1407")) { + qCDebug(interfaceapp) << "Limitless Speech Server denied the request."; + // Don't spam the server with further false requests please. + DependencyManager::get()->setListeningToVoice(true); + stopListening(); + return; + } else if (serverMessage.contains("1408")) { + qCDebug(interfaceapp) << "Limitless Audio request authenticated!"; + _serverDataBuffer.clear(); + connect(DependencyManager::get().data(), &AudioClient::inputReceived, this, + &LimitlessConnection::audioInputReceived); + return; + } + QJsonObject json = QJsonDocument::fromJson(serverMessage.data()).object(); + _serverDataBuffer.remove(begin, len+1); + _currentTranscription = json["alternatives"].toArray()[0].toObject()["transcript"].toString(); + emit onReceivedTranscription(_currentTranscription); + if (json["isFinal"] == true) { + qCDebug(interfaceapp) << "Final transcription: " << _currentTranscription; + stopListening(); + return; + } + begin = _serverDataBuffer.indexOf('<'); + end = _serverDataBuffer.indexOf('>'); + } + } +} + +bool LimitlessConnection::isConnected() const { + return _transcribeServerSocket.get() && _transcribeServerSocket->isWritable() + && _transcribeServerSocket->state() != QAbstractSocket::SocketState::UnconnectedState; +} diff --git a/interface/src/scripting/LimitlessConnection.h b/interface/src/scripting/LimitlessConnection.h new file mode 100644 index 0000000000..ee049aff8e --- /dev/null +++ b/interface/src/scripting/LimitlessConnection.h @@ -0,0 +1,44 @@ +// +// SpeechRecognitionScriptingInterface.h +// interface/src/scripting +// +// Created by Trevor Berninger on 3/24/17. +// Copyright 2017 Limitless ltd. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_LimitlessConnection_h +#define hifi_LimitlessConnection_h + +#include +#include +#include + +class LimitlessConnection : public QObject { + Q_OBJECT +public: + LimitlessConnection(); + + Q_INVOKABLE void startListening(QString authCode); + Q_INVOKABLE void stopListening(); + + std::atomic _streamingAudioForTranscription; + +signals: + void onReceivedTranscription(QString speech); + void onFinishedSpeaking(QString speech); + +private: + void transcriptionReceived(); + void audioInputReceived(const QByteArray& inputSamples); + + bool isConnected() const; + + std::unique_ptr _transcribeServerSocket; + QByteArray _serverDataBuffer; + QString _currentTranscription; +}; + +#endif //hifi_LimitlessConnection_h diff --git a/interface/src/scripting/LimitlessVoiceRecognitionScriptingInterface.cpp b/interface/src/scripting/LimitlessVoiceRecognitionScriptingInterface.cpp new file mode 100644 index 0000000000..1352630f84 --- /dev/null +++ b/interface/src/scripting/LimitlessVoiceRecognitionScriptingInterface.cpp @@ -0,0 +1,64 @@ +// +// SpeechRecognitionScriptingInterface.h +// interface/src/scripting +// +// Created by Trevor Berninger on 3/20/17. +// Copyright 2017 Limitless ltd. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include +#include "LimitlessVoiceRecognitionScriptingInterface.h" + +const float LimitlessVoiceRecognitionScriptingInterface::_audioLevelThreshold = 0.33f; +const int LimitlessVoiceRecognitionScriptingInterface::_voiceTimeoutDuration = 2000; + +LimitlessVoiceRecognitionScriptingInterface::LimitlessVoiceRecognitionScriptingInterface() : + _shouldStartListeningForVoice(false) +{ + _voiceTimer.setSingleShot(true); + connect(&_voiceTimer, &QTimer::timeout, this, &LimitlessVoiceRecognitionScriptingInterface::voiceTimeout); + connect(&_connection, &LimitlessConnection::onReceivedTranscription, this, [this](QString transcription){emit onReceivedTranscription(transcription);}); + connect(&_connection, &LimitlessConnection::onFinishedSpeaking, this, [this](QString transcription){emit onFinishedSpeaking(transcription);}); + _connection.moveToThread(&_connectionThread); + _connectionThread.setObjectName("Limitless Connection"); + _connectionThread.start(); +} + +void LimitlessVoiceRecognitionScriptingInterface::update() { + const float audioLevel = AvatarInputs::getInstance()->loudnessToAudioLevel(DependencyManager::get()->getAudioAverageInputLoudness()); + + if (_shouldStartListeningForVoice) { + if (_connection._streamingAudioForTranscription) { + if (audioLevel > _audioLevelThreshold) { + if (_voiceTimer.isActive()) { + _voiceTimer.stop(); + } + } else if (!_voiceTimer.isActive()){ + _voiceTimer.start(_voiceTimeoutDuration); + } + } else if (audioLevel > _audioLevelThreshold) { + // to make sure invoke doesn't get called twice before the method actually gets called + _connection._streamingAudioForTranscription = true; + QMetaObject::invokeMethod(&_connection, "startListening", Q_ARG(QString, authCode)); + } + } +} + +void LimitlessVoiceRecognitionScriptingInterface::setListeningToVoice(bool listening) { + _shouldStartListeningForVoice = listening; +} + +void LimitlessVoiceRecognitionScriptingInterface::setAuthKey(QString key) { + authCode = key; +} + +void LimitlessVoiceRecognitionScriptingInterface::voiceTimeout() { + if (_connection._streamingAudioForTranscription) { + QMetaObject::invokeMethod(&_connection, "stopListening"); + } +} diff --git a/interface/src/scripting/LimitlessVoiceRecognitionScriptingInterface.h b/interface/src/scripting/LimitlessVoiceRecognitionScriptingInterface.h new file mode 100644 index 0000000000..d1b1139695 --- /dev/null +++ b/interface/src/scripting/LimitlessVoiceRecognitionScriptingInterface.h @@ -0,0 +1,50 @@ +// +// SpeechRecognitionScriptingInterface.h +// interface/src/scripting +// +// Created by Trevor Berninger on 3/20/17. +// Copyright 2017 Limitless ltd. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_SpeechRecognitionScriptingInterface_h +#define hifi_SpeechRecognitionScriptingInterface_h + +#include +#include +#include +#include "LimitlessConnection.h" + +class LimitlessVoiceRecognitionScriptingInterface : public QObject, public Dependency { + Q_OBJECT +public: + LimitlessVoiceRecognitionScriptingInterface(); + + void update(); + + QString authCode; + +public slots: + void setListeningToVoice(bool listening); + void setAuthKey(QString key); + +signals: + void onReceivedTranscription(QString speech); + void onFinishedSpeaking(QString speech); + +private: + + bool _shouldStartListeningForVoice; + static const float _audioLevelThreshold; + static const int _voiceTimeoutDuration; + + QTimer _voiceTimer; + QThread _connectionThread; + LimitlessConnection _connection; + + void voiceTimeout(); +}; + +#endif //hifi_SpeechRecognitionScriptingInterface_h From db11c40a08daa38ca3f2b6fb2f86b3f7d511f2ba Mon Sep 17 00:00:00 2001 From: Delamare2112 Date: Wed, 29 Mar 2017 12:54:25 -0700 Subject: [PATCH 16/36] Add AnimationCache to Agent --- assignment-client/src/Agent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 355e47be46..baed421df7 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -403,6 +403,7 @@ void Agent::executeScript() { _scriptEngine->registerGlobalObject("Agent", this); _scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get().data()); + _scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get().data()); QScriptValue webSocketServerConstructorValue = _scriptEngine->newFunction(WebSocketServerClass::constructor); _scriptEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue); From 2f6add3398a1b25747a1678f552699c0e5d73087 Mon Sep 17 00:00:00 2001 From: Delamare2112 Date: Wed, 29 Mar 2017 12:56:08 -0700 Subject: [PATCH 17/36] Expose LimitlessSpeechRecognition to scripts --- interface/src/Application.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d48fe19a99..9f4e4a6bc6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -177,6 +177,7 @@ #include "FrameTimingsScriptingInterface.h" #include #include +#include // On Windows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU // FIXME seems to be broken. @@ -522,6 +523,7 @@ bool setupEssentials(int& argc, char** argv) { DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); + DependencyManager::set(); return previousSessionCrashed; } @@ -4557,6 +4559,8 @@ void Application::update(float deltaTime) { } AnimDebugDraw::getInstance().update(); + + DependencyManager::get()->update(); } void Application::sendAvatarViewFrustum() { @@ -5548,6 +5552,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("UserActivityLogger", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Users", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("LimitlessSpeechRecognition", DependencyManager::get().data()); + if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { scriptEngine->registerGlobalObject("Steam", new SteamScriptingInterface(scriptEngine, steamClient.get())); } From 3ebe1a0015364520104b918d89730e2229fa02dc Mon Sep 17 00:00:00 2001 From: Delamare2112 Date: Wed, 29 Mar 2017 13:05:31 -0700 Subject: [PATCH 18/36] Add AvatarInputs::loudnessToAudioLevel --- interface/src/ui/AvatarInputs.cpp | 34 ++++++++++++++++++------------- interface/src/ui/AvatarInputs.h | 1 + 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/interface/src/ui/AvatarInputs.cpp b/interface/src/ui/AvatarInputs.cpp index b09289c78a..49911c08bb 100644 --- a/interface/src/ui/AvatarInputs.cpp +++ b/interface/src/ui/AvatarInputs.cpp @@ -58,25 +58,13 @@ AvatarInputs::AvatarInputs(QQuickItem* parent) : QQuickItem(parent) { } \ } -void AvatarInputs::update() { - if (!Menu::getInstance()) { - return; - } - AI_UPDATE(mirrorVisible, Menu::getInstance()->isOptionChecked(MenuOption::MiniMirror) && !qApp->isHMDMode() - && !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)); - AI_UPDATE(cameraEnabled, !Menu::getInstance()->isOptionChecked(MenuOption::NoFaceTracking)); - AI_UPDATE(cameraMuted, Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking)); - AI_UPDATE(isHMD, qApp->isHMDMode()); - AI_UPDATE(showAudioTools, Menu::getInstance()->isOptionChecked(MenuOption::AudioTools)); - - auto audioIO = DependencyManager::get(); +float AvatarInputs::loudnessToAudioLevel(float loudness) { const float AUDIO_METER_AVERAGING = 0.5; const float LOG2 = log(2.0f); const float METER_LOUDNESS_SCALE = 2.8f / 5.0f; const float LOG2_LOUDNESS_FLOOR = 11.0f; float audioLevel = 0.0f; - auto audio = DependencyManager::get(); - float loudness = audio->getLastInputLoudness() + 1.0f; + loudness += 1.0f; _trailingAudioLoudness = AUDIO_METER_AVERAGING * _trailingAudioLoudness + (1.0f - AUDIO_METER_AVERAGING) * loudness; @@ -90,6 +78,24 @@ void AvatarInputs::update() { if (audioLevel > 1.0f) { audioLevel = 1.0; } + return audioLevel; +} + +void AvatarInputs::update() { + if (!Menu::getInstance()) { + return; + } + + AI_UPDATE(mirrorVisible, Menu::getInstance()->isOptionChecked(MenuOption::MiniMirror) && !qApp->isHMDMode() + && !Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)); + AI_UPDATE(cameraEnabled, !Menu::getInstance()->isOptionChecked(MenuOption::NoFaceTracking)); + AI_UPDATE(cameraMuted, Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking)); + AI_UPDATE(isHMD, qApp->isHMDMode()); + AI_UPDATE(showAudioTools, Menu::getInstance()->isOptionChecked(MenuOption::AudioTools)); + + auto audioIO = DependencyManager::get(); + + const float audioLevel = loudnessToAudioLevel(DependencyManager::get()->getLastInputLoudness()); AI_UPDATE_FLOAT(audioLevel, audioLevel, 0.01); AI_UPDATE(audioClipping, ((audioIO->getTimeSinceLastClip() > 0.0f) && (audioIO->getTimeSinceLastClip() < 1.0f))); AI_UPDATE(audioMuted, audioIO->isMuted()); diff --git a/interface/src/ui/AvatarInputs.h b/interface/src/ui/AvatarInputs.h index 85570ecd3c..2d203a10b9 100644 --- a/interface/src/ui/AvatarInputs.h +++ b/interface/src/ui/AvatarInputs.h @@ -35,6 +35,7 @@ class AvatarInputs : public QQuickItem { public: static AvatarInputs* getInstance(); + float loudnessToAudioLevel(float loudness); AvatarInputs(QQuickItem* parent = nullptr); void update(); From c30ab4de8b3b25ff30cb5c6e4a495e0c9b87891e Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 29 Mar 2017 18:48:22 -0400 Subject: [PATCH 19/36] rm extra setDevice --- scripts/system/selectAudioDevice.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index 5d1d61b7d3..e57bf34192 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -123,8 +123,6 @@ function removeAudioMenus() { function onDevicechanged() { debug("System audio devices changed. Removing and replacing Audio Menus..."); setupAudioMenus(); - AudioDevice.setOutputDevice(AudioDevice.getOutputDevice()); - AudioDevice.setInputDevice(AudioDevice.getInputDevice()); checkDeviceMismatch(); } From 4a9fbf2bbd5d7820b39e1efa637c9d344de3a14d Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 29 Mar 2017 19:03:05 -0400 Subject: [PATCH 20/36] delay 200ms to avoid recursive audio dev switches --- scripts/system/selectAudioDevice.js | 36 ++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/scripts/system/selectAudioDevice.js b/scripts/system/selectAudioDevice.js index e57bf34192..2dd426932f 100644 --- a/scripts/system/selectAudioDevice.js +++ b/scripts/system/selectAudioDevice.js @@ -42,6 +42,7 @@ var switchedAudioInputToHMD = false; var switchedAudioOutputToHMD = false; var previousSelectedInputAudioDevice = ""; var previousSelectedOutputAudioDevice = ""; +var skipMenuEvents = true; // // BEGIN FUNCTION DEFINITIONS @@ -54,7 +55,9 @@ function debug() { function setupAudioMenus() { - Menu.menuItemEvent.disconnect(switchAudioDevice); + // menu events can be triggered asynchronously; skip them for 200ms to avoid recursion and false switches + skipMenuEvents = true; + Script.setTimeout(function() { skipMenuEvents = false; }, 200); removeAudioMenus(); @@ -85,8 +88,6 @@ function setupAudioMenus() { }); audioDevicesList.push(audioDeviceMenuString); } - - Menu.menuItemEvent.connect(switchAudioDevice); } function checkDeviceMismatch() { @@ -126,19 +127,30 @@ function onDevicechanged() { checkDeviceMismatch(); } +function onMenuEvent(audioDeviceMenuString) { + if (!skipMenuEvents) { + switchAudioDevice(audioDeviceMenuString); + } +} + function switchAudioDevice(audioDeviceMenuString) { // if the device is not plugged in, short-circuit if (!~audioDevicesList.indexOf(audioDeviceMenuString)) { return; } - Menu.menuItemEvent.disconnect(switchAudioDevice); - var selection = parseMenuItem(audioDeviceMenuString); if (!selection) { - debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'") - } else if (selection.mode == INPUT) { - var selectedDevice = selection.device; + debug("Invalid Audio audioDeviceMenuString! Doesn't end with 'for Input' or 'for Output'"); + return; + } + + // menu events can be triggered asynchronously; skip them for 200ms to avoid recursion and false switches + skipMenuEvents = true; + Script.setTimeout(function() { skipMenuEvents = false; }, 200); + + var selectedDevice = selection.device; + if (selection.mode == INPUT) { var currentInputDevice = AudioDevice.getInputDevice(); if (selectedDevice != currentInputDevice) { debug("Switching audio INPUT device from " + currentInputDevice + " to " + selectedDevice); @@ -157,7 +169,6 @@ function switchAudioDevice(audioDeviceMenuString) { AudioDevice.setInputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } } else if (selection.mode == OUTPUT) { - var selectedDevice = selection.device; var currentOutputDevice = AudioDevice.getOutputDevice(); if (selectedDevice != currentOutputDevice) { debug("Switching audio OUTPUT device from " + currentOutputDevice + " to " + selectedDevice); @@ -176,8 +187,6 @@ function switchAudioDevice(audioDeviceMenuString) { AudioDevice.setOutputDevice(selectedDevice); // Still try to force-set the device (in case the user's trying to forcefully debug an issue) } } - - Menu.menuItemEvent.connect(switchAudioDevice); } function restoreAudio() { @@ -234,6 +243,7 @@ function checkHMDAudio() { } wasHmdActive = HMD.active; } + // // END FUNCTION DEFINITIONS // @@ -246,7 +256,7 @@ Script.setTimeout(function () { debug("Connecting deviceChanged(), displayModeChanged(), and switchAudioDevice()..."); AudioDevice.deviceChanged.connect(onDevicechanged); HMD.displayModeChanged.connect(checkHMDAudio); - Menu.menuItemEvent.connect(switchAudioDevice); + Menu.menuItemEvent.connect(onMenuEvent); debug("Setting up Audio I/O menu for the first time..."); setupAudioMenus(); checkDeviceMismatch(); @@ -258,7 +268,7 @@ debug("Connecting scriptEnding()"); Script.scriptEnding.connect(function () { restoreAudio(); removeAudioMenus(); - Menu.menuItemEvent.disconnect(switchAudioDevice); + Menu.menuItemEvent.disconnect(onMenuEvent); HMD.displayModeChanged.disconnect(checkHMDAudio); AudioDevice.deviceChanged.disconnect(onDevicechanged); }); From b6504bba56e920cbf2f328db283ef4a2dee0c5d5 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 29 Mar 2017 17:58:56 -0700 Subject: [PATCH 21/36] Moving the num mips per texture to the creator so it s immutable and simpler --- interface/src/ui/ApplicationOverlay.cpp | 4 +- .../display-plugins/OpenGLDisplayPlugin.cpp | 9 +- .../display-plugins/hmd/HmdDisplayPlugin.cpp | 3 +- .../src/gpu/gl41/GL41BackendTexture.cpp | 2 +- .../src/gpu/gl45/GL45BackendTexture.cpp | 4 +- .../gpu/gl45/GL45BackendVariableTexture.cpp | 12 +- libraries/gpu/src/gpu/Framebuffer.cpp | 6 +- libraries/gpu/src/gpu/Texture.cpp | 149 +++++++++++------- libraries/gpu/src/gpu/Texture.h | 71 +++++---- libraries/gpu/src/gpu/Texture_ktx.cpp | 3 +- libraries/model/src/model/Light.cpp | 2 +- libraries/model/src/model/TextureMap.cpp | 25 ++- .../procedural/src/procedural/Procedural.cpp | 2 +- .../src/AmbientOcclusionEffect.cpp | 4 +- .../render-utils/src/AntialiasingEffect.cpp | 2 +- .../render-utils/src/DeferredFramebuffer.cpp | 10 +- .../src/DeferredLightingEffect.cpp | 4 +- .../render-utils/src/RenderForwardTask.cpp | 4 +- .../render-utils/src/SubsurfaceScattering.cpp | 6 +- .../render-utils/src/SurfaceGeometryPass.cpp | 14 +- libraries/render-utils/src/text/Font.cpp | 2 +- libraries/render/src/render/BlurTask.cpp | 4 +- plugins/openvr/src/OpenVrDisplayPlugin.cpp | 2 +- 23 files changed, 193 insertions(+), 151 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 0337c4cfa5..c41360e776 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -207,13 +207,13 @@ void ApplicationOverlay::buildFramebufferObject() { auto width = uiSize.x; auto height = uiSize.y; if (!_overlayFramebuffer->getDepthStencilBuffer()) { - auto overlayDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(DEPTH_FORMAT, width, height, DEFAULT_SAMPLER)); + auto overlayDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(DEPTH_FORMAT, width, height, 1, DEFAULT_SAMPLER)); _overlayFramebuffer->setDepthStencilBuffer(overlayDepthTexture, DEPTH_FORMAT); } if (!_overlayFramebuffer->getRenderBuffer(0)) { const gpu::Sampler OVERLAY_SAMPLER(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP); - auto colorBuffer = gpu::TexturePointer(gpu::Texture::createRenderBuffer(COLOR_FORMAT, width, height, OVERLAY_SAMPLER)); + auto colorBuffer = gpu::TexturePointer(gpu::Texture::createRenderBuffer(COLOR_FORMAT, width, height, 1, OVERLAY_SAMPLER)); _overlayFramebuffer->setRenderBuffer(0, colorBuffer); } } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 5a317f64bc..a3cf91fcd5 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -356,15 +356,16 @@ void OpenGLDisplayPlugin::customizeContext() { cursorData.texture.reset( gpu::Texture::createStrict( - gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), - image.width(), image.height(), - gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), + image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, + gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); cursorData.texture->setSource("cursor texture"); auto usage = gpu::Texture::Usage::Builder().withColor().withAlpha(); cursorData.texture->setUsage(usage.build()); cursorData.texture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); cursorData.texture->assignStoredMip(0, image.byteCount(), image.constBits()); - cursorData.texture->autoGenerateMips(-1); + cursorData.texture->setAutoGenerateMips(true); } } } diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index c55d985a62..52c689ec00 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -299,12 +299,13 @@ void HmdDisplayPlugin::internalPresent() { gpu::Texture::createStrict( gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.width(), image.height(), + gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); _previewTexture->setSource("HMD Preview Texture"); _previewTexture->setUsage(gpu::Texture::Usage::Builder().withColor().build()); _previewTexture->setStoredMipFormat(gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA)); _previewTexture->assignStoredMip(0, image.byteCount(), image.constBits()); - _previewTexture->autoGenerateMips(-1); + _previewTexture->setAutoGenerateMips(true); } auto viewport = getViewportForSourceSize(uvec2(_previewTexture->getDimensions())); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 46672b3b65..1579e810e5 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -72,7 +72,7 @@ GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& incrementTextureGPUCount(); withPreservedTexture([&] { GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat()); - auto numMips = _gpuObject.getNumMipLevels(); + auto numMips = _gpuObject.getNumMips(); for (uint16_t mipLevel = 0; mipLevel < numMips; ++mipLevel) { // Get the mip level dimensions, accounting for the downgrade level Vec3u dimensions = _gpuObject.evalMipDimensions(mipLevel); diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index c82c13c57c..ae2a558a05 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -186,7 +186,7 @@ GL45FixedAllocationTexture::~GL45FixedAllocationTexture() { void GL45FixedAllocationTexture::allocateStorage() const { const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); const auto dimensions = _gpuObject.getDimensions(); - const auto mips = _gpuObject.getNumMipLevels(); + const auto mips = _gpuObject.getNumMips(); glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); @@ -216,7 +216,7 @@ GL45AttachmentTexture::~GL45AttachmentTexture() { using GL45StrictResourceTexture = GL45Backend::GL45StrictResourceTexture; GL45StrictResourceTexture::GL45StrictResourceTexture(const std::weak_ptr& backend, const Texture& texture) : GL45FixedAllocationTexture(backend, texture) { - auto mipLevels = _gpuObject.getNumMipLevels(); + auto mipLevels = _gpuObject.getNumMips(); for (uint16_t sourceMip = 0; sourceMip < mipLevels; ++sourceMip) { uint16_t targetMip = sourceMip; size_t maxFace = GLTexture::getFaceCount(_target); diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp index 4083f09251..e1d3912660 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp @@ -441,7 +441,7 @@ void GL45VariableAllocationTexture::executeNextTransfer(const TexturePointer& cu using GL45ResourceTexture = GL45Backend::GL45ResourceTexture; GL45ResourceTexture::GL45ResourceTexture(const std::weak_ptr& backend, const Texture& texture) : GL45VariableAllocationTexture(backend, texture) { - auto mipLevels = texture.evalNumMips(); + auto mipLevels = texture.getNumMips(); _allocatedMip = mipLevels; uvec3 mipDimensions; for (uint16_t mip = 0; mip < mipLevels; ++mip) { @@ -463,10 +463,10 @@ void GL45ResourceTexture::allocateStorage(uint16 allocatedMip) { _allocatedMip = allocatedMip; const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); const auto dimensions = _gpuObject.evalMipDimensions(_allocatedMip); - const auto totalMips = _gpuObject.getNumMipLevels(); + const auto totalMips = _gpuObject.getNumMips(); const auto mips = totalMips - _allocatedMip; glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); - auto mipLevels = _gpuObject.getNumMipLevels(); + auto mipLevels = _gpuObject.getNumMips(); _size = 0; for (uint16_t mip = _allocatedMip; mip < mipLevels; ++mip) { _size += _gpuObject.evalMipSize(mip); @@ -476,7 +476,7 @@ void GL45ResourceTexture::allocateStorage(uint16 allocatedMip) { } void GL45ResourceTexture::copyMipsFromTexture() { - auto mipLevels = _gpuObject.getNumMipLevels(); + auto mipLevels = _gpuObject.getNumMips(); size_t maxFace = GLTexture::getFaceCount(_target); for (uint16_t sourceMip = _populatedMip; sourceMip < mipLevels; ++sourceMip) { uint16_t targetMip = sourceMip - _allocatedMip; @@ -501,7 +501,7 @@ void GL45ResourceTexture::promote() { uint16_t oldAllocatedMip = _allocatedMip; // allocate storage for new level allocateStorage(_allocatedMip - std::min(_allocatedMip, 2)); - uint16_t mips = _gpuObject.getNumMipLevels(); + uint16_t mips = _gpuObject.getNumMips(); // copy pre-existing mips for (uint16_t mip = _populatedMip; mip < mips; ++mip) { auto mipDimensions = _gpuObject.evalMipDimensions(mip); @@ -534,7 +534,7 @@ void GL45ResourceTexture::demote() { const_cast(_id) = allocate(_gpuObject); allocateStorage(_allocatedMip + 1); _populatedMip = std::max(_populatedMip, _allocatedMip); - uint16_t mips = _gpuObject.getNumMipLevels(); + uint16_t mips = _gpuObject.getNumMips(); // copy pre-existing mips for (uint16_t mip = _populatedMip; mip < mips; ++mip) { auto mipDimensions = _gpuObject.evalMipDimensions(mip); diff --git a/libraries/gpu/src/gpu/Framebuffer.cpp b/libraries/gpu/src/gpu/Framebuffer.cpp index 0d3291a74d..5281f2a61d 100755 --- a/libraries/gpu/src/gpu/Framebuffer.cpp +++ b/libraries/gpu/src/gpu/Framebuffer.cpp @@ -32,7 +32,7 @@ Framebuffer* Framebuffer::create(const std::string& name) { Framebuffer* Framebuffer::create(const std::string& name, const Format& colorBufferFormat, uint16 width, uint16 height) { auto framebuffer = Framebuffer::create(name); - auto colorTexture = TexturePointer(Texture::createRenderBuffer(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT))); + auto colorTexture = TexturePointer(Texture::createRenderBuffer(colorBufferFormat, width, height, 1, Sampler(Sampler::FILTER_MIN_MAG_POINT))); colorTexture->setSource("Framebuffer::colorTexture"); framebuffer->setRenderBuffer(0, colorTexture); @@ -43,8 +43,8 @@ Framebuffer* Framebuffer::create(const std::string& name, const Format& colorBuf Framebuffer* Framebuffer::create(const std::string& name, const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height) { auto framebuffer = Framebuffer::create(name); - auto colorTexture = TexturePointer(Texture::createRenderBuffer(colorBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT))); - auto depthTexture = TexturePointer(Texture::createRenderBuffer(depthStencilBufferFormat, width, height, Sampler(Sampler::FILTER_MIN_MAG_POINT))); + auto colorTexture = TexturePointer(Texture::createRenderBuffer(colorBufferFormat, width, height, 1, Sampler(Sampler::FILTER_MIN_MAG_POINT))); + auto depthTexture = TexturePointer(Texture::createRenderBuffer(depthStencilBufferFormat, width, height, 1, Sampler(Sampler::FILTER_MIN_MAG_POINT))); framebuffer->setRenderBuffer(0, colorTexture); framebuffer->setDepthStencilBuffer(depthTexture, depthStencilBufferFormat); diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 38019c5a03..ebd0b16fce 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -149,8 +149,14 @@ PixelsPointer MemoryStorage::getMipFace(uint16 level, uint8 face) const { return PixelsPointer(); } + Size MemoryStorage::getMipFaceSize(uint16 level, uint8 face) const { - return getMipFace(level, face)->getSize(); + PixelsPointer mipFace = getMipFace(level, face); + if (mipFace) { + return mipFace->getSize(); + } else { + return 0; + } } bool MemoryStorage::isMipAvailable(uint16 level, uint8 face) const { @@ -209,44 +215,43 @@ void Texture::MemoryStorage::assignMipFaceData(uint16 level, uint8 face, const s Texture* Texture::createExternal(const ExternalRecycler& recycler, const Sampler& sampler) { Texture* tex = new Texture(TextureUsageType::EXTERNAL); tex->_type = TEX_2D; - tex->_maxMip = 0; + tex->_maxMipLevel = 0; tex->_sampler = sampler; tex->setExternalRecycler(recycler); return tex; } -Texture* Texture::createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler) { - return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, 1, 0, sampler); +Texture* Texture::createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips, const Sampler& sampler) { + return create(TextureUsageType::RENDERBUFFER, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler); } -Texture* Texture::create1D(const Element& texelFormat, uint16 width, const Sampler& sampler) { - return create(TextureUsageType::RESOURCE, TEX_1D, texelFormat, width, 1, 1, 1, 0, sampler); +Texture* Texture::create1D(const Element& texelFormat, uint16 width, uint16 numMips, const Sampler& sampler) { + return create(TextureUsageType::RESOURCE, TEX_1D, texelFormat, width, 1, 1, 1, 0, numMips, sampler); } -Texture* Texture::create2D(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler) { - return create(TextureUsageType::RESOURCE, TEX_2D, texelFormat, width, height, 1, 1, 0, sampler); +Texture* Texture::create2D(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips, const Sampler& sampler) { + return create(TextureUsageType::RESOURCE, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler); } -Texture* Texture::createStrict(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler) { - return create(TextureUsageType::STRICT_RESOURCE, TEX_2D, texelFormat, width, height, 1, 1, 0, sampler); +Texture* Texture::createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips, const Sampler& sampler) { + return create(TextureUsageType::STRICT_RESOURCE, TEX_2D, texelFormat, width, height, 1, 1, 0, numMips, sampler); } -Texture* Texture::create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, const Sampler& sampler) { - return create(TextureUsageType::RESOURCE, TEX_3D, texelFormat, width, height, depth, 1, 0, sampler); +Texture* Texture::create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips, const Sampler& sampler) { + return create(TextureUsageType::RESOURCE, TEX_3D, texelFormat, width, height, depth, 1, 0, numMips, sampler); } -Texture* Texture::createCube(const Element& texelFormat, uint16 width, const Sampler& sampler) { - return create(TextureUsageType::RESOURCE, TEX_CUBE, texelFormat, width, width, 1, 1, 0, sampler); +Texture* Texture::createCube(const Element& texelFormat, uint16 width, uint16 numMips, const Sampler& sampler) { + return create(TextureUsageType::RESOURCE, TEX_CUBE, texelFormat, width, width, 1, 1, 0, numMips, sampler); } -Texture* Texture::create(TextureUsageType usageType, Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler) +Texture* Texture::create(TextureUsageType usageType, Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, uint16 numMips, const Sampler& sampler) { Texture* tex = new Texture(usageType); tex->_storage.reset(new MemoryStorage()); tex->_type = type; tex->_storage->assignTexture(tex); - tex->_maxMip = 0; - tex->resize(type, texelFormat, width, height, depth, numSamples, numSlices); + tex->resize(type, texelFormat, width, height, depth, numSamples, numSlices, numMips); tex->_sampler = sampler; @@ -278,7 +283,7 @@ Texture::~Texture() { } } -Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices) { +Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, uint16 numMips) { if (width && height && depth && numSamples) { bool changed = false; @@ -317,6 +322,11 @@ Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 widt // Evaluate the new size with the new format uint32_t size = NUM_FACES_PER_TYPE[_type] *_width * _height * _depth * _numSamples * texelFormat.getSize(); + if ((_maxMipLevel + 1) != numMips) { + _maxMipLevel = safeNumMips(numMips) - 1; + changed = true; + } + // If size change then we need to reset if (changed || (size != getSize())) { _size = size; @@ -338,7 +348,7 @@ Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 widt return _size; } - +/* Texture::Size Texture::resize1D(uint16 width, uint16 numSamples) { return resize(TEX_1D, getTexelFormat(), width, 1, 1, numSamples, 0); } @@ -353,8 +363,9 @@ Texture::Size Texture::resizeCube(uint16 width, uint16 numSamples) { } Texture::Size Texture::reformat(const Element& texelFormat) { - return resize(_type, texelFormat, getWidth(), getHeight(), getDepth(), getNumSamples(), _numSlices); + return resize(_type, texelFormat, getWidth(), getHeight(), getDepth(), getNumSamples(), _numSlices, getNumMips()); } +*/ bool Texture::isColorRenderTarget() const { return (_texelFormat.getSemantic() == gpu::RGBA); @@ -364,7 +375,7 @@ bool Texture::isDepthStencilRenderTarget() const { return (_texelFormat.getSemantic() == gpu::DEPTH) || (_texelFormat.getSemantic() == gpu::DEPTH_STENCIL); } -uint16 Texture::evalDimNumMips(uint16 size) { +uint16 Texture::evalDimMaxNumMips(uint16 size) { double largerDim = size; double val = log(largerDim)/log(2.0); return 1 + (uint16) val; @@ -372,7 +383,7 @@ uint16 Texture::evalDimNumMips(uint16 size) { static const double LOG_2 = log(2.0); -uint16 Texture::evalNumMips(const Vec3u& dimensions) { +uint16 Texture::evalMaxNumMips(const Vec3u& dimensions) { double largerDim = glm::compMax(dimensions); double val = log(largerDim) / LOG_2; return 1 + (uint16)val; @@ -380,10 +391,30 @@ uint16 Texture::evalNumMips(const Vec3u& dimensions) { // The number mips that the texture could have if all existed // = log2(max(width, height, depth)) -uint16 Texture::evalNumMips() const { - return evalNumMips({ _width, _height, _depth }); +uint16 Texture::evalMaxNumMips() const { + return evalMaxNumMips({ _width, _height, _depth }); } + + +// Check a num of mips requested against the maximum possible specified +// if passing -1 then answer the max +// simply does (askedNumMips == 0 ? maxNumMips : (numstd::min(askedNumMips, maxNumMips)) +uint16 Texture::safeNumMips(uint16 askedNumMips, uint16 maxNumMips) { + if (askedNumMips > 0) { + return std::min(askedNumMips, maxNumMips); + } else { + return maxNumMips; + } +} + +// Same but applied to this texture's num max mips from evalNumMips() +uint16 Texture::safeNumMips(uint16 askedNumMips) const { + return safeNumMips(askedNumMips, evalMaxNumMips()); +} + + + void Texture::setStoredMipFormat(const Element& format) { _storage->setFormat(format); } @@ -408,7 +439,7 @@ void Texture::assignStoredMip(uint16 level, storage::StoragePointer& storage) { if (_autoGenerateMips) { return; } - if (level >= evalNumMips()) { + if (level >= getNumMips()) { return; } } @@ -418,7 +449,6 @@ void Texture::assignStoredMip(uint16 level, storage::StoragePointer& storage) { auto size = storage->size(); if (storage->size() == expectedSize) { _storage->assignMipData(level, storage); - _maxMip = std::max(_maxMip, level); _stamp++; } else if (size > expectedSize) { // NOTE: We are facing this case sometime because apparently QImage (from where we get the bits) is generating images @@ -426,7 +456,6 @@ void Texture::assignStoredMip(uint16 level, storage::StoragePointer& storage) { // We should probably consider something a bit more smart to get the correct result but for now (UI elements) // it seems to work... _storage->assignMipData(level, storage); - _maxMip = std::max(_maxMip, level); _stamp++; } } @@ -437,7 +466,7 @@ void Texture::assignStoredMipFace(uint16 level, uint8 face, storage::StoragePoin if (_autoGenerateMips) { return; } - if (level >= evalNumMips()) { + if (level >= getNumMips()) { return; } } @@ -447,7 +476,6 @@ void Texture::assignStoredMipFace(uint16 level, uint8 face, storage::StoragePoin auto size = storage->size(); if (size == expectedSize) { _storage->assignMipFaceData(level, face, storage); - _maxMip = std::max(_maxMip, level); _stamp++; } else if (size > expectedSize) { // NOTE: We are facing this case sometime because apparently QImage (from where we get the bits) is generating images @@ -455,19 +483,12 @@ void Texture::assignStoredMipFace(uint16 level, uint8 face, storage::StoragePoin // We should probably consider something a bit more smart to get the correct result but for now (UI elements) // it seems to work... _storage->assignMipFaceData(level, face, storage); - _maxMip = std::max(_maxMip, level); _stamp++; } } - - -uint16 Texture::autoGenerateMips(uint16 maxMip) { +/* +uint16 Texture::resizeMips(uint16 maxMip) { bool changed = false; - if (!_autoGenerateMips) { - changed = true; - _autoGenerateMips = true; - } - auto newMaxMip = std::min((uint16)(evalNumMips() - 1), maxMip); if (newMaxMip != _maxMip) { changed = true; @@ -480,46 +501,62 @@ uint16 Texture::autoGenerateMips(uint16 maxMip) { return _maxMip; } +*/ +void Texture::setAutoGenerateMips(bool enable) { + bool changed = false; + if (!_autoGenerateMips) { + changed = true; + _autoGenerateMips = true; + } + + if (changed) { + _stamp++; + } +} uint16 Texture::getStoredMipWidth(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mipFace = accessStoredMipFace(level); + if (mipFace && mipFace->getSize()) { + return evalMipWidth(level); } - return evalMipWidth(level); + return 0; } uint16 Texture::getStoredMipHeight(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mip = accessStoredMipFace(level); + if (mip && mip->getSize()) { + return evalMipHeight(level); } - return evalMipHeight(level); + return 0; } uint16 Texture::getStoredMipDepth(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mipFace = accessStoredMipFace(level); + if (mipFace && mipFace->getSize()) { + return evalMipDepth(level); } - return evalMipDepth(level); + return 0; } uint32 Texture::getStoredMipNumTexels(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mipFace = accessStoredMipFace(level); + if (mipFace && mipFace->getSize()) { + return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); } - return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); + return 0; } uint32 Texture::getStoredMipSize(uint16 level) const { - if (!isStoredMipFaceAvailable(level)) { - return 0; + PixelsPointer mipFace = accessStoredMipFace(level); + if (mipFace && mipFace->getSize()) { + return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize(); } - - return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize(); + return 0; } gpu::Resource::Size Texture::getStoredSize() const { auto size = 0; - for (int level = 0; level < evalNumMips(); ++level) { + for (int level = 0; level < getNumMips(); ++level) { size += getStoredMipSize(level); } return size; @@ -937,7 +974,7 @@ bool TextureSource::isDefined() const { bool Texture::setMinMip(uint16 newMinMip) { uint16 oldMinMip = _minMip; - _minMip = std::min(std::max(_minMip, newMinMip), _maxMip); + _minMip = std::min(std::max(_minMip, newMinMip), getMaxMip()); return oldMinMip != _minMip; } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index d6185df0d4..970921ec7b 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -322,12 +322,13 @@ public: friend class Texture; }; - static Texture* create1D(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler()); - static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler = Sampler()); - static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, const Sampler& sampler = Sampler()); - static Texture* createCube(const Element& texelFormat, uint16 width, const Sampler& sampler = Sampler()); - static Texture* createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler = Sampler()); - static Texture* createStrict(const Element& texelFormat, uint16 width, uint16 height, const Sampler& sampler = Sampler()); + static const uint16 MAX_NUM_MIPS = 0; + static Texture* create1D(const Element& texelFormat, uint16 width, uint16 numMips = 1, const Sampler& sampler = Sampler()); + static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = 1, const Sampler& sampler = Sampler()); + static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips = 1, const Sampler& sampler = Sampler()); + static Texture* createCube(const Element& texelFormat, uint16 width, uint16 numMips = 1, const Sampler& sampler = Sampler()); + static Texture* createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = 1, const Sampler& sampler = Sampler()); + static Texture* createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = 1, const Sampler& sampler = Sampler()); static Texture* createExternal(const ExternalRecycler& recycler, const Sampler& sampler = Sampler()); Texture(TextureUsageType usageType); @@ -344,6 +345,7 @@ public: // The actual size in bytes of data stored in the texture Size getStoredSize() const; + /* // Resize, unless auto mips mode would destroy all the sub mips Size resize1D(uint16 width, uint16 numSamples); Size resize2D(uint16 width, uint16 height, uint16 numSamples); @@ -352,6 +354,7 @@ public: // Reformat, unless auto mips mode would destroy all the sub mips Size reformat(const Element& texelFormat); + */ // Size and format Type getType() const { return _type; } @@ -390,21 +393,32 @@ public: // NumSamples can only have certain values based on the hw static uint16 evalNumSamplesUsed(uint16 numSamplesTried); + // max mip is in the range [ 0 if no sub mips, log2(max(width, height, depth))] + // It is defined at creation time (immutable) + uint16 getNumMips() const { return _maxMipLevel + 1; } + uint16 getMaxMip() const { return _maxMipLevel; } + // Mips size evaluation // The number mips that a dimension could haves // = 1 + log2(size) - static uint16 evalDimNumMips(uint16 size); + static uint16 evalDimMaxNumMips(uint16 size); // The number mips that the texture could have if all existed // = 1 + log2(max(width, height, depth)) - uint16 evalNumMips() const; + uint16 evalMaxNumMips() const; + static uint16 evalMaxNumMips(const Vec3u& dimensions); - static uint16 evalNumMips(const Vec3u& dimensions); + // Check a num of mips requested against the maximum possible specified + // if passing -1 then answer the max + // simply does (askedNumMips == -1 ? maxMips : (numstd::min(askedNumMips, max)) + static uint16 safeNumMips(uint16 askedNumMips, uint16 maxMips); + + // Same but applied to this texture's num max mips from evalNumMips() + uint16 safeNumMips(uint16 askedNumMips) const; // Eval the size that the mips level SHOULD have // not the one stored in the Texture - static const uint MIN_DIMENSION = 1; Vec3u evalMipDimensions(uint16 level) const; uint16 evalMipWidth(uint16 level) const { return std::max(_width >> level, 1); } @@ -432,32 +446,20 @@ public: return size * getNumSlices(); } - // max mip is in the range [ 0 if no sub mips, log2(max(width, height, depth))] - // if autoGenerateMip is on => will provide the maxMIp level specified - // else provide the deepest mip level provided through assignMip - uint16 getMaxMip() const { return _maxMip; } + + uint16 getMinMip() const { return _minMip; } - uint16 getNumMipLevels() const { return _maxMip + 1; } - uint16 usedMipLevels() const { return (_maxMip - _minMip) + 1; } + uint16 usedMipLevels() const { return (_maxMipLevel - _minMip) + 1; } const std::string& source() const { return _source; } void setSource(const std::string& source) { _source = source; } bool setMinMip(uint16 newMinMip); bool incremementMinMip(uint16 count = 1); - // Generate the mips automatically - // But the sysmem version is not available + // Generate the sub mips automatically for the texture + // If the storage version is not available (from CPU memory) // Only works for the standard formats - // Specify the maximum Mip level available - // 0 is the default one - // 1 is the first level - // ... - // nbMips - 1 is the last mip level - // - // If -1 then all the mips are generated - // - // Return the totalnumber of mips that will be available - uint16 autoGenerateMips(uint16 maxMip); + void setAutoGenerateMips(bool enable); bool isAutogenerateMips() const { return _autoGenerateMips; } // Managing Storage and mips @@ -553,9 +555,14 @@ protected: uint16 _depth { 1 }; uint16 _numSamples { 1 }; - uint16 _numSlices { 0 }; // if _numSlices is 0, the texture is not an "Array", the getNumSlices reported is 1 - uint16 _maxMip { 0 }; + // if _numSlices is 0, the texture is not an "Array", the getNumSlices reported is 1 + uint16 _numSlices { 0 }; + + // valid _maxMipLevel is in the range [ 0 if no sub mips, log2(max(width, height, depth) ] + // The num of mips returned is _maxMipLevel + 1 + uint16 _maxMipLevel { 0 }; + uint16 _minMip { 0 }; Type _type { TEX_1D }; @@ -567,9 +574,9 @@ protected: bool _isIrradianceValid = false; bool _defined = false; - static Texture* create(TextureUsageType usageType, Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler); + static Texture* create(TextureUsageType usageType, Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, uint16 numMips, const Sampler& sampler); - Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices); + Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, uint16 numMips); }; typedef std::shared_ptr TexturePointer; diff --git a/libraries/gpu/src/gpu/Texture_ktx.cpp b/libraries/gpu/src/gpu/Texture_ktx.cpp index 913ced8141..8befdf3e16 100644 --- a/libraries/gpu/src/gpu/Texture_ktx.cpp +++ b/libraries/gpu/src/gpu/Texture_ktx.cpp @@ -128,7 +128,7 @@ ktx::KTXUniquePointer Texture::serialize(const Texture& texture) { } // Number level of mips coming - header.numberOfMipmapLevels = texture.getNumMipLevels(); + header.numberOfMipmapLevels = texture.getNumMips(); ktx::Images images; for (uint32_t level = 0; level < header.numberOfMipmapLevels; level++) { @@ -224,6 +224,7 @@ Texture* Texture::unserialize(const std::string& ktxfile, TextureUsageType usage header.getPixelDepth(), 1, // num Samples header.getNumberOfSlices(), + header.getNumberOfLevels(), (isGPUKTXPayload ? gpuktxKeyValue._samplerDesc : sampler)); tex->setUsage((isGPUKTXPayload ? gpuktxKeyValue._usage : usage)); diff --git a/libraries/model/src/model/Light.cpp b/libraries/model/src/model/Light.cpp index 4ac0573cf6..11b13606b8 100755 --- a/libraries/model/src/model/Light.cpp +++ b/libraries/model/src/model/Light.cpp @@ -148,7 +148,7 @@ void Light::setAmbientSpherePreset(gpu::SphericalHarmonics::Preset preset) { void Light::setAmbientMap(gpu::TexturePointer ambientMap) { _ambientMap = ambientMap; if (ambientMap) { - setAmbientMapNumMips(_ambientMap->evalNumMips()); + setAmbientMapNumMips(_ambientMap->getNumMips()); } else { setAmbientMapNumMips(0); } diff --git a/libraries/model/src/model/TextureMap.cpp b/libraries/model/src/model/TextureMap.cpp index 7e5e01e4e4..e619a2d70f 100755 --- a/libraries/model/src/model/TextureMap.cpp +++ b/libraries/model/src/model/TextureMap.cpp @@ -210,7 +210,7 @@ const QImage& image, bool isLinear, bool doCompress) { void generateMips(gpu::Texture* texture, QImage& image, bool fastResize) { #if CPU_MIPMAPS PROFILE_RANGE(resource_parse, "generateMips"); - auto numMips = texture->evalNumMips(); + auto numMips = texture->getNumMips(); for (uint16 level = 1; level < numMips; ++level) { QSize mipSize(texture->evalMipWidth(level), texture->evalMipHeight(level)); if (fastResize) { @@ -230,7 +230,7 @@ void generateMips(gpu::Texture* texture, QImage& image, bool fastResize) { void generateFaceMips(gpu::Texture* texture, QImage& image, uint8 face) { #if CPU_MIPMAPS PROFILE_RANGE(resource_parse, "generateFaceMips"); - auto numMips = texture->evalNumMips(); + auto numMips = texture->getNumMips(); for (uint16 level = 1; level < numMips; ++level) { QSize mipSize(texture->evalMipWidth(level), texture->evalMipHeight(level)); QImage mipImage = image.scaled(mipSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); @@ -255,9 +255,9 @@ gpu::Texture* TextureUsage::process2DTextureColorFromImage(const QImage& srcImag defineColorTexelFormats(formatGPU, formatMip, image, isLinear, doCompress); if (isStrict) { - theTexture = (gpu::Texture::createStrict(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + theTexture = (gpu::Texture::createStrict(formatGPU, image.width(), image.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); } else { - theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); } theTexture->setSource(srcImageName); auto usage = gpu::Texture::Usage::Builder().withColor(); @@ -317,7 +317,7 @@ gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& src gpu::Element formatMip = gpu::Element::COLOR_BGRA_32; gpu::Element formatGPU = gpu::Element::COLOR_RGBA_32; - theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); theTexture->setStoredMipFormat(formatMip); theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); @@ -407,7 +407,7 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm gpu::Element formatGPU = gpu::Element::COLOR_RGBA_32; - theTexture = (gpu::Texture::create2D(formatGPU, result.width(), result.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + theTexture = (gpu::Texture::create2D(formatGPU, result.width(), result.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); theTexture->setStoredMipFormat(formatMip); theTexture->assignStoredMip(0, result.byteCount(), result.constBits()); @@ -443,7 +443,7 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromImage(const QImage& srcIma #endif gpu::Element formatMip = gpu::Element::COLOR_R_8; - theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); theTexture->setStoredMipFormat(formatMip); theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); @@ -483,7 +483,7 @@ gpu::Texture* TextureUsage::createRoughnessTextureFromGlossImage(const QImage& s #endif gpu::Element formatMip = gpu::Element::COLOR_R_8; - theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); theTexture->setStoredMipFormat(formatMip); theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); @@ -520,7 +520,7 @@ gpu::Texture* TextureUsage::createMetallicTextureFromImage(const QImage& srcImag #endif gpu::Element formatMip = gpu::Element::COLOR_R_8; - theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); + theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR))); theTexture->setSource(srcImageName); theTexture->setStoredMipFormat(formatMip); theTexture->assignStoredMip(0, image.byteCount(), image.constBits()); @@ -836,7 +836,7 @@ gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcIm // If the 6 faces have been created go on and define the true Texture if (faces.size() == gpu::Texture::NUM_FACES_PER_TYPE[gpu::Texture::TEX_CUBE]) { - theTexture = gpu::Texture::createCube(formatGPU, faces[0].width(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); + theTexture = gpu::Texture::createCube(formatGPU, faces[0].width(), gpu::Texture::MAX_NUM_MIPS, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP)); theTexture->setSource(srcImageName); theTexture->setStoredMipFormat(formatMip); int f = 0; @@ -848,11 +848,6 @@ gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcIm f++; } - if (generateMips) { - PROFILE_RANGE(resource_parse, "generateMips"); - theTexture->autoGenerateMips(-1); - } - // Generate irradiance while we are at it if (generateIrradiance) { PROFILE_RANGE(resource_parse, "generateIrradiance"); diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index ac6163c227..e4ce3c691a 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -325,7 +325,7 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm auto gpuTexture = _channels[i]->getGPUTexture(); if (gpuTexture) { gpuTexture->setSampler(sampler); - gpuTexture->autoGenerateMips(-1); + gpuTexture->setAutoGenerateMips(true); } batch.setResourceTexture((gpu::uint32)i, gpuTexture); } diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index 3bacf85273..b9f1dba9c2 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -74,11 +74,11 @@ void AmbientOcclusionFramebuffer::allocate() { auto width = _frameSize.x; auto height = _frameSize.y; - _occlusionTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _occlusionTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusion")); _occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture); - _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred")); _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture); } diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index f95d45de04..abbaa585fd 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -52,7 +52,7 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { _antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); auto format = gpu::Element::COLOR_SRGBA_32; // DependencyManager::get()->getLightingTexture()->getTexelFormat(); auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - _antialiasingTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(format, width, height, defaultSampler)); + _antialiasingTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(format, width, height, 1, defaultSampler)); _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); } diff --git a/libraries/render-utils/src/DeferredFramebuffer.cpp b/libraries/render-utils/src/DeferredFramebuffer.cpp index 40c22beba4..34a0c429c3 100644 --- a/libraries/render-utils/src/DeferredFramebuffer.cpp +++ b/libraries/render-utils/src/DeferredFramebuffer.cpp @@ -53,9 +53,9 @@ void DeferredFramebuffer::allocate() { auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - _deferredColorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, width, height, defaultSampler)); - _deferredNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(linearFormat, width, height, defaultSampler)); - _deferredSpecularTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, width, height, defaultSampler)); + _deferredColorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, width, height, 1, defaultSampler)); + _deferredNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(linearFormat, width, height, 1, defaultSampler)); + _deferredSpecularTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, width, height, 1, defaultSampler)); _deferredFramebuffer->setRenderBuffer(0, _deferredColorTexture); _deferredFramebuffer->setRenderBuffer(1, _deferredNormalTexture); @@ -65,7 +65,7 @@ void DeferredFramebuffer::allocate() { auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format if (!_primaryDepthTexture) { - _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(depthFormat, width, height, defaultSampler)); + _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(depthFormat, width, height, 1, defaultSampler)); } _deferredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); @@ -75,7 +75,7 @@ void DeferredFramebuffer::allocate() { auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR); - _lightingTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, defaultSampler)); + _lightingTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, 1, defaultSampler)); _lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("lighting")); _lightingFramebuffer->setRenderBuffer(0, _lightingTexture); _lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index ce340583ee..34063ea2bb 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -496,14 +496,14 @@ void PreparePrimaryFramebuffer::run(const SceneContextPointer& sceneContext, con auto colorFormat = gpu::Element::COLOR_SRGBA_32; auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - auto primaryColorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, defaultSampler)); + auto primaryColorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, 1, defaultSampler)); _primaryFramebuffer->setRenderBuffer(0, primaryColorTexture); auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format - auto primaryDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, defaultSampler)); + auto primaryDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, 1, defaultSampler)); _primaryFramebuffer->setDepthStencilBuffer(primaryDepthTexture, depthFormat); } diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index 45a32c1aaf..11d5fc8834 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -73,11 +73,11 @@ void PrepareFramebuffer::run(const SceneContextPointer& sceneContext, const Rend auto colorFormat = gpu::Element::COLOR_SRGBA_32; auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - auto colorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, frameSize.x, frameSize.y, defaultSampler)); + auto colorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, frameSize.x, frameSize.y, 1, defaultSampler)); _framebuffer->setRenderBuffer(0, colorTexture); auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format - auto depthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, frameSize.x, frameSize.y, defaultSampler)); + auto depthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, frameSize.x, frameSize.y, 1, defaultSampler)); _framebuffer->setDepthStencilBuffer(depthTexture, depthFormat); } diff --git a/libraries/render-utils/src/SubsurfaceScattering.cpp b/libraries/render-utils/src/SubsurfaceScattering.cpp index 25a01bff1b..75884f52f5 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.cpp +++ b/libraries/render-utils/src/SubsurfaceScattering.cpp @@ -414,7 +414,7 @@ gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringProfile(Rend const int PROFILE_RESOLUTION = 512; // const auto pixelFormat = gpu::Element::COLOR_SRGBA_32; const auto pixelFormat = gpu::Element::COLOR_R11G11B10; - auto profileMap = gpu::TexturePointer(gpu::Texture::createRenderBuffer(pixelFormat, PROFILE_RESOLUTION, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); + auto profileMap = gpu::TexturePointer(gpu::Texture::createRenderBuffer(pixelFormat, PROFILE_RESOLUTION, 1, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); profileMap->setSource("Generated Scattering Profile"); diffuseProfileGPU(profileMap, args); return profileMap; @@ -425,7 +425,7 @@ gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScatterin const int TABLE_RESOLUTION = 512; // const auto pixelFormat = gpu::Element::COLOR_SRGBA_32; const auto pixelFormat = gpu::Element::COLOR_R11G11B10; - auto scatteringLUT = gpu::TexturePointer(gpu::Texture::createRenderBuffer(pixelFormat, TABLE_RESOLUTION, TABLE_RESOLUTION, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); + auto scatteringLUT = gpu::TexturePointer(gpu::Texture::createRenderBuffer(pixelFormat, TABLE_RESOLUTION, TABLE_RESOLUTION, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); //diffuseScatter(scatteringLUT); scatteringLUT->setSource("Generated pre-integrated scattering"); diffuseScatterGPU(profile, scatteringLUT, args); @@ -434,7 +434,7 @@ gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScatterin gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringSpecularBeckmann(RenderArgs* args) { const int SPECULAR_RESOLUTION = 256; - auto beckmannMap = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32 /*gpu::Element(gpu::SCALAR, gpu::HALF, gpu::RGB)*/, SPECULAR_RESOLUTION, SPECULAR_RESOLUTION, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); + auto beckmannMap = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, SPECULAR_RESOLUTION, SPECULAR_RESOLUTION, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); beckmannMap->setSource("Generated beckmannMap"); computeSpecularBeckmannGPU(beckmannMap, args); return beckmannMap; diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index f713e3ce75..684fc24347 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -72,18 +72,18 @@ void LinearDepthFramebuffer::allocate() { auto height = _frameSize.y; // For Linear Depth: - _linearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), width, height, + _linearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("linearDepth")); _linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture); _linearDepthFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, _primaryDepthTexture->getTexelFormat()); // For Downsampling: - _halfLinearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), _halfFrameSize.x, _halfFrameSize.y, + const uint16_t HALF_LINEAR_DEPTH_MAX_MIP_LEVEL = 5; + _halfLinearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), _halfFrameSize.x, _halfFrameSize.y, HALF_LINEAR_DEPTH_MAX_MIP_LEVEL, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); - _halfLinearDepthTexture->autoGenerateMips(5); - _halfNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _halfFrameSize.x, _halfFrameSize.y, + _halfNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _halfFrameSize.x, _halfFrameSize.y, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _downsampleFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("halfLinearDepth")); @@ -304,15 +304,15 @@ void SurfaceGeometryFramebuffer::allocate() { auto width = _frameSize.x; auto height = _frameSize.y; - _curvatureTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _curvatureTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _curvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("surfaceGeometry::curvature")); _curvatureFramebuffer->setRenderBuffer(0, _curvatureTexture); - _lowCurvatureTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _lowCurvatureTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _lowCurvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("surfaceGeometry::lowCurvature")); _lowCurvatureFramebuffer->setRenderBuffer(0, _lowCurvatureTexture); - _blurringTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _blurringTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _blurringFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("surfaceGeometry::blurring")); _blurringFramebuffer->setRenderBuffer(0, _blurringTexture); } diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index c405f6d6ae..142e7154b9 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -207,7 +207,7 @@ void Font::read(QIODevice& in) { formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::BGRA); } - _texture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), + _texture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR))); _texture->setStoredMipFormat(formatMip); _texture->assignStoredMip(0, image.byteCount(), image.constBits()); diff --git a/libraries/render/src/render/BlurTask.cpp b/libraries/render/src/render/BlurTask.cpp index f8b5546b92..2557c5f356 100644 --- a/libraries/render/src/render/BlurTask.cpp +++ b/libraries/render/src/render/BlurTask.cpp @@ -108,7 +108,7 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra // _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); //} auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); - auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), blurringSampler)); + auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), 1, blurringSampler)); _blurredFramebuffer->setRenderBuffer(0, blurringTarget); } @@ -131,7 +131,7 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra _outputFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); }*/ auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); - auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), blurringSampler)); + auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), 1, blurringSampler)); _outputFramebuffer->setRenderBuffer(0, blurringTarget); } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 46c2cf3ff2..02526e4299 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -494,7 +494,7 @@ void OpenVrDisplayPlugin::customizeContext() { _compositeInfos[0].texture = _compositeFramebuffer->getRenderBuffer(0); for (size_t i = 0; i < COMPOSITING_BUFFER_SIZE; ++i) { if (0 != i) { - _compositeInfos[i].texture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _renderTargetSize.x, _renderTargetSize.y, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT))); + _compositeInfos[i].texture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _renderTargetSize.x, _renderTargetSize.y, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT))); } _compositeInfos[i].textureID = getGLBackend()->getTextureID(_compositeInfos[i].texture); } From f954767b8493d0ac0df313484eaa1f56cd703f52 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 30 Mar 2017 14:04:03 +1300 Subject: [PATCH 22/36] Get entities list and entity properties scrollbars working on tablet --- interface/src/ui/overlays/Web3DOverlay.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index e05ae1aacd..94699e7b42 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -350,11 +350,11 @@ void Web3DOverlay::handlePointerEventAsTouch(const PointerEvent& event) { glm::vec2 windowPos = event.getPos2D() * (METERS_TO_INCHES * _dpi); QPointF windowPoint(windowPos.x, windowPos.y); - if (event.getButtons() == PointerEvent::NoButtons && event.getType() == PointerEvent::Move) { - // Forward a mouse move event to the Web surface. + if (event.getType() == PointerEvent::Move) { + // Forward a mouse move event to the Web surface so that hover events are generated. + // Must send a mouse move event that matches up with touch move event in order for scroll bars to work. QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, Qt::NoButton, Qt::NoButton, Qt::NoModifier); QCoreApplication::postEvent(_webSurface->getWindow(), mouseEvent); - return; } if (event.getType() == PointerEvent::Press && event.getButton() == PointerEvent::PrimaryButton) { From 06910d18815429f8980c29c321f132c5c9067a65 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 30 Mar 2017 14:20:02 +1300 Subject: [PATCH 23/36] Add comment re scrollbar stability in tablet --- interface/src/ui/overlays/Web3DOverlay.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 94699e7b42..e50cf3a671 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -353,6 +353,10 @@ void Web3DOverlay::handlePointerEventAsTouch(const PointerEvent& event) { if (event.getType() == PointerEvent::Move) { // Forward a mouse move event to the Web surface so that hover events are generated. // Must send a mouse move event that matches up with touch move event in order for scroll bars to work. + + // Scroll bar dragging is a bit unstable in the tablet (content can jump up and down at times). + // This may be improved in Qt 5.8. Release notes: "Cleaned up touch and mouse event delivery". + QMouseEvent* mouseEvent = new QMouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, Qt::NoButton, Qt::NoButton, Qt::NoModifier); QCoreApplication::postEvent(_webSurface->getWindow(), mouseEvent); } From c7f648a6c269d781ab8f77d1705e5cc1d9b5fe99 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 30 Mar 2017 14:20:32 +1300 Subject: [PATCH 24/36] Disable marketplace directory and Clara.io scrollbars in tablet --- scripts/system/marketplaces/marketplaces.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index c24034b38e..3488352cc0 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -72,7 +72,7 @@ function showMarketplace() { tablet.webEventReceived.connect(function (message) { if (message === GOTO_DIRECTORY) { - tablet.gotoWebScreen(MARKETPLACES_URL, MARKETPLACES_INJECT_SCRIPT_URL); + tablet.gotoWebScreen(MARKETPLACES_URL, injectURL); } if (message === QUERY_CAN_WRITE_ASSETS) { From 55848533402790e624cc2c7bf148cefd9d656b37 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 29 Mar 2017 18:22:21 -0700 Subject: [PATCH 25/36] Keep on cleaning --- libraries/gpu/src/gpu/Texture.cpp | 33 ------------------------------- libraries/gpu/src/gpu/Texture.h | 18 ++++------------- 2 files changed, 4 insertions(+), 47 deletions(-) diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index ebd0b16fce..6a4eb547c3 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -348,24 +348,6 @@ Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 widt return _size; } -/* -Texture::Size Texture::resize1D(uint16 width, uint16 numSamples) { - return resize(TEX_1D, getTexelFormat(), width, 1, 1, numSamples, 0); -} -Texture::Size Texture::resize2D(uint16 width, uint16 height, uint16 numSamples) { - return resize(TEX_2D, getTexelFormat(), width, height, 1, numSamples, 0); -} -Texture::Size Texture::resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples) { - return resize(TEX_3D, getTexelFormat(), width, height, depth, numSamples, 0); -} -Texture::Size Texture::resizeCube(uint16 width, uint16 numSamples) { - return resize(TEX_CUBE, getTexelFormat(), width, 1, 1, numSamples, 0); -} - -Texture::Size Texture::reformat(const Element& texelFormat) { - return resize(_type, texelFormat, getWidth(), getHeight(), getDepth(), getNumSamples(), _numSlices, getNumMips()); -} -*/ bool Texture::isColorRenderTarget() const { return (_texelFormat.getSemantic() == gpu::RGBA); @@ -486,22 +468,7 @@ void Texture::assignStoredMipFace(uint16 level, uint8 face, storage::StoragePoin _stamp++; } } -/* -uint16 Texture::resizeMips(uint16 maxMip) { - bool changed = false; - auto newMaxMip = std::min((uint16)(evalNumMips() - 1), maxMip); - if (newMaxMip != _maxMip) { - changed = true; - _maxMip = newMaxMip;; - } - if (changed) { - _stamp++; - } - - return _maxMip; -} -*/ void Texture::setAutoGenerateMips(bool enable) { bool changed = false; if (!_autoGenerateMips) { diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 970921ec7b..8a5bde9eb8 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -340,22 +340,12 @@ public: Stamp getDataStamp() const { return _storage->getStamp(); } // The theoretical size in bytes of data stored in the texture + // For the master (level) first level of mip Size getSize() const override { return _size; } // The actual size in bytes of data stored in the texture Size getStoredSize() const; - /* - // Resize, unless auto mips mode would destroy all the sub mips - Size resize1D(uint16 width, uint16 numSamples); - Size resize2D(uint16 width, uint16 height, uint16 numSamples); - Size resize3D(uint16 width, uint16 height, uint16 depth, uint16 numSamples); - Size resizeCube(uint16 width, uint16 numSamples); - - // Reformat, unless auto mips mode would destroy all the sub mips - Size reformat(const Element& texelFormat); - */ - // Size and format Type getType() const { return _type; } TextureUsageType getUsageType() const { return _usageType; } @@ -395,8 +385,8 @@ public: // max mip is in the range [ 0 if no sub mips, log2(max(width, height, depth))] // It is defined at creation time (immutable) - uint16 getNumMips() const { return _maxMipLevel + 1; } uint16 getMaxMip() const { return _maxMipLevel; } + uint16 getNumMips() const { return _maxMipLevel + 1; } // Mips size evaluation @@ -448,13 +438,13 @@ public: - uint16 getMinMip() const { return _minMip; } - uint16 usedMipLevels() const { return (_maxMipLevel - _minMip) + 1; } const std::string& source() const { return _source; } void setSource(const std::string& source) { _source = source; } bool setMinMip(uint16 newMinMip); bool incremementMinMip(uint16 count = 1); + uint16 getMinMip() const { return _minMip; } + uint16 usedMipLevels() const { return (getNumMips() - _minMip); } // Generate the sub mips automatically for the texture // If the storage version is not available (from CPU memory) From 9c4414cff6083c75953940138162de1ccbc5be28 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 30 Mar 2017 14:38:17 +1300 Subject: [PATCH 26/36] No custom styling of marketplaces directory scrollbar --- scripts/system/html/css/marketplaces.css | 87 ++++++++++++++++++++++++ scripts/system/html/marketplaces.html | 1 - 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/scripts/system/html/css/marketplaces.css b/scripts/system/html/css/marketplaces.css index bb57bea3bc..04c132eab1 100644 --- a/scripts/system/html/css/marketplaces.css +++ b/scripts/system/html/css/marketplaces.css @@ -5,6 +5,93 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html */ + +/* + CSS rules copied from edit-style.css. + Edit-style.css is not used in its entirety because don't want custom scrollbars; default scrollbar styling is used in order + to match other marketplace pages. +*/ + +@font-face { + font-family: Raleway-Regular; + src: url(../../../../resources/fonts/Raleway-Regular.ttf), /* Windows production */ + url(../../../../fonts/Raleway-Regular.ttf), /* OSX production */ + url(../../../../interface/resources/fonts/Raleway-Regular.ttf); /* Development, running script in /HiFi/examples */ +} + +@font-face { + font-family: Raleway-Bold; + src: url(../../../../resources/fonts/Raleway-Bold.ttf), + url(../../../../fonts/Raleway-Bold.ttf), + url(../../../../interface/resources/fonts/Raleway-Bold.ttf); +} + +@font-face { + font-family: Raleway-SemiBold; + src: url(../../../../resources/fonts/Raleway-SemiBold.ttf), + url(../../../../fonts/Raleway-SemiBold.ttf), + url(../../../../interface/resources/fonts/Raleway-SemiBold.ttf); +} + +@font-face { + font-family: FiraSans-SemiBold; + src: url(../../../../resources/fonts/FiraSans-SemiBold.ttf), + url(../../../../fonts/FiraSans-SemiBold.ttf), + url(../../../../interface/resources/fonts/FiraSans-SemiBold.ttf); +} + +* { + margin: 0; + padding: 0; +} + +body { + padding: 21px 21px 21px 21px; + + color: #afafaf; + background-color: #404040; + font-family: Raleway-Regular; + font-size: 15px; + + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + overflow-x: hidden; + overflow-y: auto; +} + +input[type=button] { + font-family: Raleway-Bold; + font-size: 13px; + text-transform: uppercase; + vertical-align: top; + height: 28px; + min-width: 120px; + padding: 0px 18px; + margin-right: 6px; + border-radius: 5px; + border: none; + color: #fff; + background-color: #000; + background: linear-gradient(#343434 20%, #000 100%); + cursor: pointer; +} + +input[type=button].blue { + color: #fff; + background-color: #1080b8; + background: linear-gradient(#00b4ef 20%, #1080b8 100%); +} + + +/* + Marketplaces-specific CSS. +*/ + body { background: white; padding: 0 0 0 0; diff --git a/scripts/system/html/marketplaces.html b/scripts/system/html/marketplaces.html index 976c0f294f..6051a9df96 100644 --- a/scripts/system/html/marketplaces.html +++ b/scripts/system/html/marketplaces.html @@ -10,7 +10,6 @@ Marketplaces - From 1c9bc2d71ec2858db49cd0b6780f6957744cb6ab Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Wed, 29 Mar 2017 23:28:06 -0700 Subject: [PATCH 27/36] Trying to debug the crash on gl4.1 --- libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 1579e810e5..5aa0c42ee4 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -79,9 +79,14 @@ GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& uint8_t face = 0; for (GLenum target : getFaceTargets(_target)) { const Byte* mipData = nullptr; + gpu::Texture::PixelsPointer mip; if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) { - auto mip = _gpuObject.accessStoredMipFace(mipLevel, face); - mipData = mip->readData(); + mip = _gpuObject.accessStoredMipFace(mipLevel, face); + if (mip) { + mipData = mip->readData(); + } else { + mipData = nullptr; + } } glTexImage2D(target, mipLevel, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, texelFormat.type, mipData); (void)CHECK_GL_ERROR(); From 25edb44b75b8ce03fc8094a429d3eac6b272416f Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 30 Mar 2017 15:15:14 -0700 Subject: [PATCH 28/36] Fix the problem with the cursor and scattering, --- .../src/gpu/gl41/GL41BackendTexture.cpp | 28 +++++++++++++++++-- libraries/gpu/src/gpu/Context.cpp | 8 +++--- .../surfaceGeometry_downsampleDepthNormal.slf | 8 +++--- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 5aa0c42ee4..61db54bf7b 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -45,11 +45,22 @@ GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) { // If the object hasn't been created, or the object definition is out of date, drop and re-create GL41Texture* object = Backend::getGPUObject(texture); + if (!object || object->_storageStamp < texture.getStamp()) { // This automatically any previous texture object = new GL41Texture(shared_from_this(), texture); - } + object->withPreservedTexture([&] { + if (object->_contentStamp <= texture.getDataStamp()) { + // FIXME implement synchronous texture transfer here + object->syncContent(); + } + if (object->_samplerStamp <= texture.getSamplerStamp()) { + object->syncSampler(); + } + }); + } + /* // FIXME internalize to GL41Texture 'sync' function if (object->isOutdated()) { object->withPreservedTexture([&] { @@ -62,7 +73,7 @@ GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) { object->syncSampler(); } }); - } + }*/ return object; } @@ -93,6 +104,13 @@ GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& ++face; } } + glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(_target, GL_TEXTURE_MAX_LEVEL, numMips - 1); + + if (texture.isAutogenerateMips()) { + glGenerateMipmap(_target); + (void)CHECK_GL_ERROR(); + } }); } @@ -111,6 +129,7 @@ bool GL41Texture::isOutdated() const { } void GL41Texture::withPreservedTexture(std::function f) const { + GLint transferUnit = 32; GLint boundTex = -1; switch (_target) { case GL_TEXTURE_2D: @@ -126,9 +145,12 @@ void GL41Texture::withPreservedTexture(std::function f) const { } (void)CHECK_GL_ERROR(); + glActiveTexture(GL_TEXTURE0 + transferUnit); + (void)CHECK_GL_ERROR(); + glBindTexture(_target, _texture); f(); - glBindTexture(_target, boundTex); + glBindTexture(_target, 0); (void)CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index cc570f696f..0030b2fa88 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -265,7 +265,7 @@ void Context::incrementBufferGPUCount() { auto total = ++_bufferGPUCount; if (total > max.load()) { max = total; - qCDebug(gpulogging) << "New max GPU buffers " << total; + // qCDebug(gpulogging) << "New max GPU buffers " << total; } } void Context::decrementBufferGPUCount() { @@ -299,7 +299,7 @@ void Context::incrementTextureGPUCount() { auto total = ++_textureGPUCount; if (total > max.load()) { max = total; - qCDebug(gpulogging) << "New max GPU textures " << total; + // qCDebug(gpulogging) << "New max GPU textures " << total; } } void Context::decrementTextureGPUCount() { @@ -311,7 +311,7 @@ void Context::incrementTextureGPUSparseCount() { auto total = ++_textureGPUSparseCount; if (total > max.load()) { max = total; - qCDebug(gpulogging) << "New max GPU textures " << total; + // qCDebug(gpulogging) << "New max GPU textures " << total; } } void Context::decrementTextureGPUSparseCount() { @@ -378,7 +378,7 @@ void Context::incrementTextureGPUTransferCount() { auto total = ++_textureGPUTransferCount; if (total > max.load()) { max = total; - qCDebug(gpulogging) << "New max GPU textures transfers" << total; + // qCDebug(gpulogging) << "New max GPU textures transfers" << total; } } diff --git a/libraries/render-utils/src/surfaceGeometry_downsampleDepthNormal.slf b/libraries/render-utils/src/surfaceGeometry_downsampleDepthNormal.slf index 46554dd7f8..205dad124e 100644 --- a/libraries/render-utils/src/surfaceGeometry_downsampleDepthNormal.slf +++ b/libraries/render-utils/src/surfaceGeometry_downsampleDepthNormal.slf @@ -21,17 +21,17 @@ out vec4 outLinearDepth; out vec4 outNormal; void main(void) { - // Gather 2 by 2 quads from texture + // Gather 2 by 2 quads from texture and downsample // Try different filters for Z - //vec4 Zeyes = textureGather(linearDepthMap, varTexCoord0, 0); - //float Zeye = min(min(Zeyes.x, Zeyes.y), min(Zeyes.z, Zeyes.w)); - float Zeye = texture(linearDepthMap, varTexCoord0).x; + vec4 Zeyes = textureGather(linearDepthMap, varTexCoord0, 0); + // float Zeye = texture(linearDepthMap, varTexCoord0).x; vec4 rawNormalsX = textureGather(normalMap, varTexCoord0, 0); vec4 rawNormalsY = textureGather(normalMap, varTexCoord0, 1); vec4 rawNormalsZ = textureGather(normalMap, varTexCoord0, 2); + float Zeye = min(min(Zeyes.x, Zeyes.y), min(Zeyes.z, Zeyes.w)); vec3 normal = vec3(0.0); normal += unpackNormal(vec3(rawNormalsX[0], rawNormalsY[0], rawNormalsZ[0])); From a5c683192b06727a4675964392be616d44349df1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 31 Mar 2017 12:26:22 +1300 Subject: [PATCH 29/36] Improve entity properties scroll handle operation in tablet --- scripts/system/html/css/edit-style.css | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/system/html/css/edit-style.css b/scripts/system/html/css/edit-style.css index 06a60b5405..c033a2d2cd 100644 --- a/scripts/system/html/css/edit-style.css +++ b/scripts/system/html/css/edit-style.css @@ -81,6 +81,19 @@ body { overflow-y: auto; } +/* HACK + Makes entity properties dialog's scrollbar work on tablet such that don't need to keep pointer within scrollbar width when + using scroll handle. +*/ +body { + padding-right: 0; + margin-right: -21px; +} +body > * { + margin-right: 42px; +} +/* END OF HACK */ + table { font-family: FiraSans-SemiBold; font-size: 15px; From 47e9668b8fb1f833b7081ec368f6cb727fd7c29a Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 30 Mar 2017 17:59:59 -0700 Subject: [PATCH 30/36] improving the gl41 backend to mimic the gl45 --- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 50 +++- .../src/gpu/gl41/GL41BackendTexture.cpp | 220 +++++++++++++++--- 2 files changed, 233 insertions(+), 37 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index 6d2f91c436..ab66a0a302 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -39,6 +39,54 @@ public: GL41Backend() : Parent() {} class GL41Texture : public GLTexture { + using Parent = GLTexture; + friend class GL41Backend; + static GLuint allocate(const Texture& texture); + protected: + GL41Texture(const std::weak_ptr& backend, const Texture& texture); + void generateMips() const override; + void copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const; + void copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum type, const void* sourcePointer) const; + virtual void syncSampler() const; + + void withPreservedTexture(std::function f) const; + }; + + // + // Textures that have fixed allocation sizes and cannot be managed at runtime + // + + class GL41FixedAllocationTexture : public GL41Texture { + using Parent = GL41Texture; + friend class GL41Backend; + + public: + GL41FixedAllocationTexture(const std::weak_ptr& backend, const Texture& texture); + ~GL41FixedAllocationTexture(); + + protected: + uint32 size() const override { return _size; } + void allocateStorage() const; + void syncSampler() const override; + const uint32 _size { 0 }; + }; + + class GL41AttachmentTexture : public GL41FixedAllocationTexture { + using Parent = GL41FixedAllocationTexture; + friend class GL45Backend; + protected: + GL41AttachmentTexture(const std::weak_ptr& backend, const Texture& texture); + ~GL41AttachmentTexture(); + }; + + class GL41StrictResourceTexture : public GL41FixedAllocationTexture { + using Parent = GL41FixedAllocationTexture; + friend class GL41Backend; + protected: + GL41StrictResourceTexture(const std::weak_ptr& backend, const Texture& texture); + }; + + /* class GL41Texture : public GLTexture { using Parent = GLTexture; static GLuint allocate(); @@ -62,7 +110,7 @@ public: void withPreservedTexture(std::function f) const; void syncContent() const; void syncSampler() const; - }; + };*/ protected: diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 61db54bf7b..092591a538 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -19,16 +19,197 @@ using namespace gpu; using namespace gpu::gl; using namespace gpu::gl41; -using GL41TexelFormat = GLTexelFormat; +GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) { + if (!texturePointer) { + return nullptr; + } + + const Texture& texture = *texturePointer; + if (TextureUsageType::EXTERNAL == texture.getUsageType()) { + return Parent::syncGPUObject(texturePointer); + } + + if (!texture.isDefined()) { + // NO texture definition yet so let's avoid thinking + return nullptr; + } + + GL41Texture* object = Backend::getGPUObject(texture); + if (!object) { + switch (texture.getUsageType()) { + case TextureUsageType::RENDERBUFFER: + object = new GL41AttachmentTexture(shared_from_this(), texture); + break; + + case TextureUsageType::STRICT_RESOURCE: + qCDebug(gpugllogging) << "Strict texture " << texture.source().c_str(); + object = new GL41StrictResourceTexture(shared_from_this(), texture); + break; + + case TextureUsageType::RESOURCE: { + qCDebug(gpugllogging) << "variable / Strict texture " << texture.source().c_str(); + object = new GL41StrictResourceTexture(shared_from_this(), texture); + break; + } + + default: + Q_UNREACHABLE(); + } + } + + return object; +} + using GL41Texture = GL41Backend::GL41Texture; -GLuint GL41Texture::allocate() { - Backend::incrementTextureGPUCount(); +GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& texture) + : GLTexture(backend, texture, allocate(texture)) { + incrementTextureGPUCount(); +} + +GLuint GL41Texture::allocate(const Texture& texture) { GLuint result; glGenTextures(1, &result); return result; } + +void GL41Texture::withPreservedTexture(std::function f) const { + const GLint TRANSFER_TEXTURE_UNIT = 32; + glActiveTexture(GL_TEXTURE0 + TRANSFER_TEXTURE_UNIT); + glBindTexture(_target, _texture); + (void)CHECK_GL_ERROR(); + + f(); + glBindTexture(_target, 0); + (void)CHECK_GL_ERROR(); +} + + +void GL41Texture::generateMips() const { + withPreservedTexture([&] { + glGenerateMipmap(_target); + }); + (void)CHECK_GL_ERROR(); +} + +void GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum type, const void* sourcePointer) const { + if (GL_TEXTURE_2D == _target) { + glTextureSubImage2D(_id, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer); + } else if (GL_TEXTURE_CUBE_MAP == _target) { + // DSA ARB does not work on AMD, so use EXT + // unless EXT is not available on the driver + if (glTextureSubImage2DEXT) { + auto target = GLTexture::CUBE_FACE_LAYOUT[face]; + glTextureSubImage2DEXT(_id, target, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer); + } else { + glTextureSubImage3D(_id, mip, 0, yOffset, face, size.x, size.y, 1, format, type, sourcePointer); + } + } else { + Q_ASSERT(false); + } + (void)CHECK_GL_ERROR(); +} + +void GL41Texture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const { + if (!_gpuObject.isStoredMipFaceAvailable(sourceMip)) { + return; + } + auto size = _gpuObject.evalMipDimensions(sourceMip); + auto mipData = _gpuObject.accessStoredMipFace(sourceMip, face); + if (mipData) { + GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat()); + copyMipFaceLinesFromTexture(targetMip, face, size, 0, texelFormat.format, texelFormat.type, mipData->readData()); + } else { + qCDebug(gpugllogging) << "Missing mipData level=" << sourceMip << " face=" << (int)face << " for texture " << _gpuObject.source().c_str(); + } +} + +void GL41Texture::syncSampler() const { + const Sampler& sampler = _gpuObject.getSampler(); + + const auto& fm = FILTER_MODES[sampler.getFilter()]; + glTextureParameteri(_id, GL_TEXTURE_MIN_FILTER, fm.minFilter); + glTextureParameteri(_id, GL_TEXTURE_MAG_FILTER, fm.magFilter); + + if (sampler.doComparison()) { + glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTextureParameteri(_id, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]); + } else { + glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_NONE); + } + + glTextureParameteri(_id, GL_TEXTURE_WRAP_S, WRAP_MODES[sampler.getWrapModeU()]); + glTextureParameteri(_id, GL_TEXTURE_WRAP_T, WRAP_MODES[sampler.getWrapModeV()]); + glTextureParameteri(_id, GL_TEXTURE_WRAP_R, WRAP_MODES[sampler.getWrapModeW()]); + glTextureParameterf(_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy()); + glTextureParameterfv(_id, GL_TEXTURE_BORDER_COLOR, (const float*)&sampler.getBorderColor()); + glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, sampler.getMinMip()); + glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); +} + +using GL45FixedAllocationTexture = GL45Backend::GL45FixedAllocationTexture; + +GL41FixedAllocationTexture::GL41FixedAllocationTexture(const std::weak_ptr& backend, const Texture& texture) : GL45Texture(backend, texture), _size(texture.evalTotalSize()) { + allocateStorage(); + syncSampler(); +} + +GL41FixedAllocationTexture::~GL41FixedAllocationTexture() { +} + +void GL41FixedAllocationTexture::allocateStorage() const { + const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); + const auto dimensions = _gpuObject.getDimensions(); + const auto mips = _gpuObject.getNumMips(); + + glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); + glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); +} + +void GL41FixedAllocationTexture::syncSampler() const { + Parent::syncSampler(); + const Sampler& sampler = _gpuObject.getSampler(); + auto baseMip = std::max(sampler.getMipOffset(), sampler.getMinMip()); + glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, baseMip); + glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip()); + glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); +} + +// Renderbuffer attachment textures +using GL41AttachmentTexture = GL45Backend::GL41AttachmentTexture; + +GL41AttachmentTexture::GL41AttachmentTexture(const std::weak_ptr& backend, const Texture& texture) : GL45FixedAllocationTexture(backend, texture) { + Backend::updateTextureGPUFramebufferMemoryUsage(0, size()); +} + +GL41AttachmentTexture::~GL41AttachmentTexture() { + Backend::updateTextureGPUFramebufferMemoryUsage(size(), 0); +} + +// Strict resource textures +using GL41StrictResourceTexture = GL41Backend::GL41StrictResourceTexture; + +GL41StrictResourceTexture::GL41StrictResourceTexture(const std::weak_ptr& backend, const Texture& texture) : GL45FixedAllocationTexture(backend, texture) { + auto mipLevels = _gpuObject.getNumMips(); + for (uint16_t sourceMip = 0; sourceMip < mipLevels; ++sourceMip) { + uint16_t targetMip = sourceMip; + size_t maxFace = GLTexture::getFaceCount(_target); + for (uint8_t face = 0; face < maxFace; ++face) { + copyMipFaceFromTexture(sourceMip, targetMip, face); + } + } + if (texture.isAutogenerateMips()) { + generateMips(); + } +} + + +using GL41TexelFormat = GLTexelFormat; +using GL41Texture = GL41Backend::GL41Texture; + + + GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) { if (!texturePointer) { return nullptr; @@ -128,39 +309,6 @@ bool GL41Texture::isOutdated() const { return false; } -void GL41Texture::withPreservedTexture(std::function f) const { - GLint transferUnit = 32; - GLint boundTex = -1; - switch (_target) { - case GL_TEXTURE_2D: - glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTex); - break; - - case GL_TEXTURE_CUBE_MAP: - glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &boundTex); - break; - - default: - qFatal("Unsupported texture type"); - } - (void)CHECK_GL_ERROR(); - - glActiveTexture(GL_TEXTURE0 + transferUnit); - (void)CHECK_GL_ERROR(); - - glBindTexture(_target, _texture); - f(); - glBindTexture(_target, 0); - (void)CHECK_GL_ERROR(); -} - -void GL41Texture::generateMips() const { - withPreservedTexture([&] { - glGenerateMipmap(_target); - }); - (void)CHECK_GL_ERROR(); -} - void GL41Texture::syncContent() const { // FIXME actually copy the texture data _contentStamp = _gpuObject.getDataStamp() + 1; From 61d78bc93131cc524e34a5bb28f6984cec6929f9 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Thu, 30 Mar 2017 23:29:37 -0700 Subject: [PATCH 31/36] BRinging the cool texture management of the gl45 backend to gl41, which fixes the broken ao on 41 among other things --- libraries/gpu-gl/src/gpu/gl/GLTexture.h | 4 +- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 37 +-- .../src/gpu/gl41/GL41BackendTexture.cpp | 304 ++++++------------ libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 8 +- .../src/gpu/gl45/GL45BackendTexture.cpp | 5 +- .../gpu/gl45/GL45BackendVariableTexture.cpp | 2 +- libraries/gpu/src/gpu/Texture.cpp | 74 ++--- libraries/gpu/src/gpu/Texture.h | 73 ++--- 8 files changed, 177 insertions(+), 330 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLTexture.h b/libraries/gpu-gl/src/gpu/gl/GLTexture.h index 1f91e17157..b47aa3e8dd 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLTexture.h +++ b/libraries/gpu-gl/src/gpu/gl/GLTexture.h @@ -43,7 +43,7 @@ public: static const GLenum WRAP_MODES[Sampler::NUM_WRAP_MODES]; protected: - virtual uint32 size() const = 0; + virtual Size size() const = 0; virtual void generateMips() const = 0; GLTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id); @@ -57,7 +57,7 @@ public: protected: GLExternalTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id); void generateMips() const override {} - uint32 size() const override { return 0; } + Size size() const override { return 0; } }; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index ab66a0a302..93d65b74dd 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -65,15 +65,15 @@ public: ~GL41FixedAllocationTexture(); protected: - uint32 size() const override { return _size; } + Size size() const override { return _size; } void allocateStorage() const; void syncSampler() const override; - const uint32 _size { 0 }; + const Size _size { 0 }; }; class GL41AttachmentTexture : public GL41FixedAllocationTexture { using Parent = GL41FixedAllocationTexture; - friend class GL45Backend; + friend class GL41Backend; protected: GL41AttachmentTexture(const std::weak_ptr& backend, const Texture& texture); ~GL41AttachmentTexture(); @@ -86,32 +86,13 @@ public: GL41StrictResourceTexture(const std::weak_ptr& backend, const Texture& texture); }; - /* class GL41Texture : public GLTexture { - using Parent = GLTexture; - static GLuint allocate(); - - public: - ~GL41Texture(); - - private: - GL41Texture(const std::weak_ptr& backend, const Texture& buffer); - - void generateMips() const override; - uint32 size() const override; - + class GL41ResourceTexture : public GL41FixedAllocationTexture { + using Parent = GL41FixedAllocationTexture; friend class GL41Backend; - const Stamp _storageStamp; - mutable Stamp _contentStamp { 0 }; - mutable Stamp _samplerStamp { 0 }; - const uint32 _size; - - - bool isOutdated() const; - void withPreservedTexture(std::function f) const; - void syncContent() const; - void syncSampler() const; - };*/ - + protected: + GL41ResourceTexture(const std::weak_ptr& backend, const Texture& texture); + ~GL41ResourceTexture(); + }; protected: GLuint getFramebufferID(const FramebufferPointer& framebuffer) override; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 092591a538..1a2652a950 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -48,7 +48,7 @@ GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) { case TextureUsageType::RESOURCE: { qCDebug(gpugllogging) << "variable / Strict texture " << texture.source().c_str(); - object = new GL41StrictResourceTexture(shared_from_this(), texture); + object = new GL41ResourceTexture(shared_from_this(), texture); break; } @@ -95,18 +95,12 @@ void GL41Texture::generateMips() const { void GL41Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum format, GLenum type, const void* sourcePointer) const { if (GL_TEXTURE_2D == _target) { - glTextureSubImage2D(_id, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer); + glTexSubImage2D(_target, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer); } else if (GL_TEXTURE_CUBE_MAP == _target) { - // DSA ARB does not work on AMD, so use EXT - // unless EXT is not available on the driver - if (glTextureSubImage2DEXT) { - auto target = GLTexture::CUBE_FACE_LAYOUT[face]; - glTextureSubImage2DEXT(_id, target, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer); - } else { - glTextureSubImage3D(_id, mip, 0, yOffset, face, size.x, size.y, 1, format, type, sourcePointer); - } + auto target = GLTexture::CUBE_FACE_LAYOUT[face]; + glTexSubImage2D(target, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer); } else { - Q_ASSERT(false); + assert(false); } (void)CHECK_GL_ERROR(); } @@ -128,194 +122,6 @@ void GL41Texture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, void GL41Texture::syncSampler() const { const Sampler& sampler = _gpuObject.getSampler(); - const auto& fm = FILTER_MODES[sampler.getFilter()]; - glTextureParameteri(_id, GL_TEXTURE_MIN_FILTER, fm.minFilter); - glTextureParameteri(_id, GL_TEXTURE_MAG_FILTER, fm.magFilter); - - if (sampler.doComparison()) { - glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - glTextureParameteri(_id, GL_TEXTURE_COMPARE_FUNC, COMPARISON_TO_GL[sampler.getComparisonFunction()]); - } else { - glTextureParameteri(_id, GL_TEXTURE_COMPARE_MODE, GL_NONE); - } - - glTextureParameteri(_id, GL_TEXTURE_WRAP_S, WRAP_MODES[sampler.getWrapModeU()]); - glTextureParameteri(_id, GL_TEXTURE_WRAP_T, WRAP_MODES[sampler.getWrapModeV()]); - glTextureParameteri(_id, GL_TEXTURE_WRAP_R, WRAP_MODES[sampler.getWrapModeW()]); - glTextureParameterf(_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy()); - glTextureParameterfv(_id, GL_TEXTURE_BORDER_COLOR, (const float*)&sampler.getBorderColor()); - glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, sampler.getMinMip()); - glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); -} - -using GL45FixedAllocationTexture = GL45Backend::GL45FixedAllocationTexture; - -GL41FixedAllocationTexture::GL41FixedAllocationTexture(const std::weak_ptr& backend, const Texture& texture) : GL45Texture(backend, texture), _size(texture.evalTotalSize()) { - allocateStorage(); - syncSampler(); -} - -GL41FixedAllocationTexture::~GL41FixedAllocationTexture() { -} - -void GL41FixedAllocationTexture::allocateStorage() const { - const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); - const auto dimensions = _gpuObject.getDimensions(); - const auto mips = _gpuObject.getNumMips(); - - glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); - glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); -} - -void GL41FixedAllocationTexture::syncSampler() const { - Parent::syncSampler(); - const Sampler& sampler = _gpuObject.getSampler(); - auto baseMip = std::max(sampler.getMipOffset(), sampler.getMinMip()); - glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, baseMip); - glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip()); - glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); -} - -// Renderbuffer attachment textures -using GL41AttachmentTexture = GL45Backend::GL41AttachmentTexture; - -GL41AttachmentTexture::GL41AttachmentTexture(const std::weak_ptr& backend, const Texture& texture) : GL45FixedAllocationTexture(backend, texture) { - Backend::updateTextureGPUFramebufferMemoryUsage(0, size()); -} - -GL41AttachmentTexture::~GL41AttachmentTexture() { - Backend::updateTextureGPUFramebufferMemoryUsage(size(), 0); -} - -// Strict resource textures -using GL41StrictResourceTexture = GL41Backend::GL41StrictResourceTexture; - -GL41StrictResourceTexture::GL41StrictResourceTexture(const std::weak_ptr& backend, const Texture& texture) : GL45FixedAllocationTexture(backend, texture) { - auto mipLevels = _gpuObject.getNumMips(); - for (uint16_t sourceMip = 0; sourceMip < mipLevels; ++sourceMip) { - uint16_t targetMip = sourceMip; - size_t maxFace = GLTexture::getFaceCount(_target); - for (uint8_t face = 0; face < maxFace; ++face) { - copyMipFaceFromTexture(sourceMip, targetMip, face); - } - } - if (texture.isAutogenerateMips()) { - generateMips(); - } -} - - -using GL41TexelFormat = GLTexelFormat; -using GL41Texture = GL41Backend::GL41Texture; - - - -GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) { - if (!texturePointer) { - return nullptr; - } - const Texture& texture = *texturePointer; - if (TextureUsageType::EXTERNAL == texture.getUsageType()) { - return Parent::syncGPUObject(texturePointer); - } - - if (!texture.isDefined()) { - // NO texture definition yet so let's avoid thinking - return nullptr; - } - - // If the object hasn't been created, or the object definition is out of date, drop and re-create - GL41Texture* object = Backend::getGPUObject(texture); - - if (!object || object->_storageStamp < texture.getStamp()) { - // This automatically any previous texture - object = new GL41Texture(shared_from_this(), texture); - object->withPreservedTexture([&] { - if (object->_contentStamp <= texture.getDataStamp()) { - // FIXME implement synchronous texture transfer here - object->syncContent(); - } - - if (object->_samplerStamp <= texture.getSamplerStamp()) { - object->syncSampler(); - } - }); - } - /* - // FIXME internalize to GL41Texture 'sync' function - if (object->isOutdated()) { - object->withPreservedTexture([&] { - if (object->_contentStamp <= texture.getDataStamp()) { - // FIXME implement synchronous texture transfer here - object->syncContent(); - } - - if (object->_samplerStamp <= texture.getSamplerStamp()) { - object->syncSampler(); - } - }); - }*/ - - return object; -} - -GL41Texture::GL41Texture(const std::weak_ptr& backend, const Texture& texture) - : GLTexture(backend, texture, allocate()), _storageStamp { texture.getStamp() }, _size(texture.evalTotalSize()) { - incrementTextureGPUCount(); - withPreservedTexture([&] { - GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat(), _gpuObject.getStoredMipFormat()); - auto numMips = _gpuObject.getNumMips(); - for (uint16_t mipLevel = 0; mipLevel < numMips; ++mipLevel) { - // Get the mip level dimensions, accounting for the downgrade level - Vec3u dimensions = _gpuObject.evalMipDimensions(mipLevel); - uint8_t face = 0; - for (GLenum target : getFaceTargets(_target)) { - const Byte* mipData = nullptr; - gpu::Texture::PixelsPointer mip; - if (_gpuObject.isStoredMipFaceAvailable(mipLevel, face)) { - mip = _gpuObject.accessStoredMipFace(mipLevel, face); - if (mip) { - mipData = mip->readData(); - } else { - mipData = nullptr; - } - } - glTexImage2D(target, mipLevel, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, texelFormat.type, mipData); - (void)CHECK_GL_ERROR(); - ++face; - } - } - glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(_target, GL_TEXTURE_MAX_LEVEL, numMips - 1); - - if (texture.isAutogenerateMips()) { - glGenerateMipmap(_target); - (void)CHECK_GL_ERROR(); - } - }); -} - -GL41Texture::~GL41Texture() { - -} - -bool GL41Texture::isOutdated() const { - if (_samplerStamp <= _gpuObject.getSamplerStamp()) { - return true; - } - if (TextureUsageType::RESOURCE == _gpuObject.getUsageType() && _contentStamp <= _gpuObject.getDataStamp()) { - return true; - } - return false; -} - -void GL41Texture::syncContent() const { - // FIXME actually copy the texture data - _contentStamp = _gpuObject.getDataStamp() + 1; -} - -void GL41Texture::syncSampler() const { - const Sampler& sampler = _gpuObject.getSampler(); const auto& fm = FILTER_MODES[sampler.getFilter()]; glTexParameteri(_target, GL_TEXTURE_MIN_FILTER, fm.minFilter); glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, fm.magFilter); @@ -333,12 +139,106 @@ void GL41Texture::syncSampler() const { glTexParameterfv(_target, GL_TEXTURE_BORDER_COLOR, (const float*)&sampler.getBorderColor()); glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, (uint16)sampler.getMipOffset()); + glTexParameterf(_target, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip()); glTexParameterf(_target, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); + glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy()); - _samplerStamp = _gpuObject.getSamplerStamp() + 1; } -uint32 GL41Texture::size() const { - return _size; +using GL41FixedAllocationTexture = GL41Backend::GL41FixedAllocationTexture; + +GL41FixedAllocationTexture::GL41FixedAllocationTexture(const std::weak_ptr& backend, const Texture& texture) : GL41Texture(backend, texture), _size(texture.evalTotalSize()) { + withPreservedTexture([&] { + allocateStorage(); + syncSampler(); + }); +} + +GL41FixedAllocationTexture::~GL41FixedAllocationTexture() { +} + +void GL41FixedAllocationTexture::allocateStorage() const { + const GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_gpuObject.getTexelFormat()); + const auto numMips = _gpuObject.getNumMips(); + + // glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); + for (GLint level = 0; level < numMips; ++level) { + Vec3u dimensions = _gpuObject.evalMipDimensions(level); + for (GLenum target : getFaceTargets(_target)) { + glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, texelFormat.type, nullptr); + } + } + + glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(_target, GL_TEXTURE_MAX_LEVEL, numMips - 1); +} + +void GL41FixedAllocationTexture::syncSampler() const { + Parent::syncSampler(); + const Sampler& sampler = _gpuObject.getSampler(); + auto baseMip = std::max(sampler.getMipOffset(), sampler.getMinMip()); + + glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, baseMip); + glTexParameterf(_target, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip()); + glTexParameterf(_target, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); +} + +// Renderbuffer attachment textures +using GL41AttachmentTexture = GL41Backend::GL41AttachmentTexture; + +GL41AttachmentTexture::GL41AttachmentTexture(const std::weak_ptr& backend, const Texture& texture) : GL41FixedAllocationTexture(backend, texture) { + Backend::updateTextureGPUFramebufferMemoryUsage(0, size()); +} + +GL41AttachmentTexture::~GL41AttachmentTexture() { + Backend::updateTextureGPUFramebufferMemoryUsage(size(), 0); +} + +// Strict resource textures +using GL41StrictResourceTexture = GL41Backend::GL41StrictResourceTexture; + +GL41StrictResourceTexture::GL41StrictResourceTexture(const std::weak_ptr& backend, const Texture& texture) : GL41FixedAllocationTexture(backend, texture) { + withPreservedTexture([&] { + + auto mipLevels = _gpuObject.getNumMips(); + for (uint16_t sourceMip = 0; sourceMip < mipLevels; ++sourceMip) { + uint16_t targetMip = sourceMip; + size_t maxFace = GLTexture::getFaceCount(_target); + for (uint8_t face = 0; face < maxFace; ++face) { + copyMipFaceFromTexture(sourceMip, targetMip, face); + } + } + }); + + if (texture.isAutogenerateMips()) { + generateMips(); + } +} + +// resource textures +using GL41ResourceTexture = GL41Backend::GL41ResourceTexture; + +GL41ResourceTexture::GL41ResourceTexture(const std::weak_ptr& backend, const Texture& texture) : GL41FixedAllocationTexture(backend, texture) { + Backend::updateTextureGPUMemoryUsage(0, size()); + + withPreservedTexture([&] { + + auto mipLevels = _gpuObject.getNumMips(); + for (uint16_t sourceMip = 0; sourceMip < mipLevels; ++sourceMip) { + uint16_t targetMip = sourceMip; + size_t maxFace = GLTexture::getFaceCount(_target); + for (uint8_t face = 0; face < maxFace; ++face) { + copyMipFaceFromTexture(sourceMip, targetMip, face); + } + } + }); + + if (texture.isAutogenerateMips()) { + generateMips(); + } +} + +GL41ResourceTexture::~GL41ResourceTexture() { + Backend::updateTextureGPUMemoryUsage(size(), 0); } diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index 6a9811b055..ca8028aff6 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -58,10 +58,10 @@ public: ~GL45FixedAllocationTexture(); protected: - uint32 size() const override { return _size; } + Size size() const override { return _size; } void allocateStorage() const; void syncSampler() const override; - const uint32 _size { 0 }; + const Size _size { 0 }; }; class GL45AttachmentTexture : public GL45FixedAllocationTexture { @@ -173,7 +173,7 @@ public: bool canDemote() const { return _allocatedMip < _maxAllocatedMip; } bool hasPendingTransfers() const { return _populatedMip > _allocatedMip; } void executeNextTransfer(const TexturePointer& currentTexture); - uint32 size() const override { return _size; } + Size size() const override { return _size; } virtual void populateTransferQueue() = 0; virtual void promote() = 0; virtual void demote() = 0; @@ -188,7 +188,7 @@ public: // The highest (lowest resolution) mip that we will support, relative to the number // of mips in the gpu::Texture object uint16 _maxAllocatedMip { 0 }; - uint32 _size { 0 }; + Size _size { 0 }; // Contains a series of lambdas that when executed will transfer data to the GPU, modify // the _populatedMip and update the sampler in order to fully populate the allocated texture // until _populatedMip == _allocatedMip diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index ae2a558a05..ab4153c04c 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include "../gl/GLTexelFormat.h" @@ -167,8 +166,10 @@ void GL45Texture::syncSampler() const { glTextureParameteri(_id, GL_TEXTURE_WRAP_S, WRAP_MODES[sampler.getWrapModeU()]); glTextureParameteri(_id, GL_TEXTURE_WRAP_T, WRAP_MODES[sampler.getWrapModeV()]); glTextureParameteri(_id, GL_TEXTURE_WRAP_R, WRAP_MODES[sampler.getWrapModeW()]); + glTextureParameterf(_id, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy()); glTextureParameterfv(_id, GL_TEXTURE_BORDER_COLOR, (const float*)&sampler.getBorderColor()); + glTextureParameterf(_id, GL_TEXTURE_MIN_LOD, sampler.getMinMip()); glTextureParameterf(_id, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); } @@ -189,7 +190,9 @@ void GL45FixedAllocationTexture::allocateStorage() const { const auto mips = _gpuObject.getNumMips(); glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); + glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, 0); + glTextureParameteri(_id, GL_TEXTURE_MAX_LEVEL, mips - 1); } void GL45FixedAllocationTexture::syncSampler() const { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp index e1d3912660..a614d62221 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp @@ -495,7 +495,7 @@ void GL45ResourceTexture::promote() { PROFILE_RANGE(render_gpu_gl, __FUNCTION__); Q_ASSERT(_allocatedMip > 0); GLuint oldId = _id; - uint32_t oldSize = _size; + auto oldSize = _size; // create new texture const_cast(_id) = allocate(_gpuObject); uint16_t oldAllocatedMip = _allocatedMip; diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 6a4eb547c3..2f40ee20a2 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -318,15 +318,20 @@ Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 widt _depth = depth; changed = true; } - - // Evaluate the new size with the new format - uint32_t size = NUM_FACES_PER_TYPE[_type] *_width * _height * _depth * _numSamples * texelFormat.getSize(); if ((_maxMipLevel + 1) != numMips) { _maxMipLevel = safeNumMips(numMips) - 1; changed = true; } + if (texelFormat != _texelFormat) { + _texelFormat = texelFormat; + changed = true; + } + + // Evaluate the new size with the new format + Size size = NUM_FACES_PER_TYPE[_type] * _height * _depth * evalPaddedSize(_numSamples * _width * _texelFormat.getSize()); + // If size change then we need to reset if (changed || (size != getSize())) { _size = size; @@ -334,12 +339,6 @@ Texture::Size Texture::resize(Type type, const Element& texelFormat, uint16 widt _stamp++; } - // TexelFormat might have change, but it's mostly interpretation - if (texelFormat != _texelFormat) { - _texelFormat = texelFormat; - _stamp++; - } - // Here the Texture has been fully defined from the gpu point of view (size and format) _defined = true; } else { @@ -377,8 +376,6 @@ uint16 Texture::evalMaxNumMips() const { return evalMaxNumMips({ _width, _height, _depth }); } - - // Check a num of mips requested against the maximum possible specified // if passing -1 then answer the max // simply does (askedNumMips == 0 ? maxNumMips : (numstd::min(askedNumMips, maxNumMips)) @@ -395,7 +392,15 @@ uint16 Texture::safeNumMips(uint16 askedNumMips) const { return safeNumMips(askedNumMips, evalMaxNumMips()); } - +Size Texture::evalTotalSize(uint16 startingMip) const { + Size size = 0; + uint16 minMipLevel = std::max(getMinMip(), startingMip); + uint16 maxMipLevel = getMaxMip(); + for (uint16 l = minMipLevel; l <= maxMipLevel; l++) { + size += evalMipSize(l); + } + return size * getNumSlices(); +} void Texture::setStoredMipFormat(const Element& format) { _storage->setFormat(format); @@ -481,48 +486,19 @@ void Texture::setAutoGenerateMips(bool enable) { } } -uint16 Texture::getStoredMipWidth(uint16 level) const { +Size Texture::getStoredMipSize(uint16 level) const { PixelsPointer mipFace = accessStoredMipFace(level); + Size size = 0; if (mipFace && mipFace->getSize()) { - return evalMipWidth(level); + for (int face = 0; face < mipFace->getSize(); ++face) { + size += getStoredMipFaceSize(level, face); + } } - return 0; + return size; } -uint16 Texture::getStoredMipHeight(uint16 level) const { - PixelsPointer mip = accessStoredMipFace(level); - if (mip && mip->getSize()) { - return evalMipHeight(level); - } - return 0; -} - -uint16 Texture::getStoredMipDepth(uint16 level) const { - PixelsPointer mipFace = accessStoredMipFace(level); - if (mipFace && mipFace->getSize()) { - return evalMipDepth(level); - } - return 0; -} - -uint32 Texture::getStoredMipNumTexels(uint16 level) const { - PixelsPointer mipFace = accessStoredMipFace(level); - if (mipFace && mipFace->getSize()) { - return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); - } - return 0; -} - -uint32 Texture::getStoredMipSize(uint16 level) const { - PixelsPointer mipFace = accessStoredMipFace(level); - if (mipFace && mipFace->getSize()) { - return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level) * getTexelFormat().getSize(); - } - return 0; -} - -gpu::Resource::Size Texture::getStoredSize() const { - auto size = 0; +Size Texture::getStoredSize() const { + Size size = 0; for (int level = 0; level < getNumMips(); ++level) { size += getStoredMipSize(level); } diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 8a5bde9eb8..312381a7d4 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -232,9 +232,7 @@ public: bool operator!=(const Usage& usage) { return (_flags != usage._flags); } }; - using PixelsPointer = storage::StoragePointer; - - enum Type { + enum Type : uint8 { TEX_1D = 0, TEX_2D, TEX_3D, @@ -255,7 +253,13 @@ public: NUM_CUBE_FACES, // Not a valid vace index }; + // Lines of pixels are padded to be a multiple of "PACKING_SIZE" which is 4 bytes + static const uint32 PACKING_SIZE = 4; + static uint8 evalPaddingNumBytes(Size byteSize) { return (uint8) (3 - (byteSize + 3) % PACKING_SIZE); } + static Size evalPaddedSize(Size byteSize) { return byteSize + (Size) evalPaddingNumBytes(byteSize); } + + using PixelsPointer = storage::StoragePointer; class Storage { public: Storage() {} @@ -331,6 +335,9 @@ public: static Texture* createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = 1, const Sampler& sampler = Sampler()); static Texture* createExternal(const ExternalRecycler& recycler, const Sampler& sampler = Sampler()); + // After the texture has been created, it should be defined + bool isDefined() const { return _defined; } + Texture(TextureUsageType usageType); Texture(const Texture& buf); // deep copy of the sysmem texture Texture& operator=(const Texture& buf); // deep copy of the sysmem texture @@ -343,9 +350,6 @@ public: // For the master (level) first level of mip Size getSize() const override { return _size; } - // The actual size in bytes of data stored in the texture - Size getStoredSize() const; - // Size and format Type getType() const { return _type; } TextureUsageType getUsageType() const { return _usageType; } @@ -354,23 +358,18 @@ public: bool isDepthStencilRenderTarget() const; const Element& getTexelFormat() const { return _texelFormat; } - bool hasBorder() const { return false; } Vec3u getDimensions() const { return Vec3u(_width, _height, _depth); } uint16 getWidth() const { return _width; } uint16 getHeight() const { return _height; } uint16 getDepth() const { return _depth; } - uint32 getRowPitch() const { return getWidth() * getTexelFormat().getSize(); } - // The number of faces is mostly used for cube map, and maybe for stereo ? otherwise it's 1 // For cube maps, this means the pixels of the different faces are supposed to be packed back to back in a mip // as if the height was NUM_FACES time bigger. static uint8 NUM_FACES_PER_TYPE[NUM_TYPES]; uint8 getNumFaces() const { return NUM_FACES_PER_TYPE[getType()]; } - uint32 getNumTexels() const { return _width * _height * _depth * getNumFaces(); } - // The texture is an array if the _numSlices is not 0. // otherwise, if _numSLices is 0, then the texture is NOT an array // The number of slices returned is 1 at the minimum (if not an array) or the actual _numSlices. @@ -378,8 +377,6 @@ public: uint16 getNumSlices() const { return (isArray() ? _numSlices : 1); } uint16 getNumSamples() const { return _numSamples; } - - // NumSamples can only have certain values based on the hw static uint16 evalNumSamplesUsed(uint16 numSamplesTried); @@ -415,32 +412,30 @@ public: uint16 evalMipHeight(uint16 level) const { return std::max(_height >> level, 1); } uint16 evalMipDepth(uint16 level) const { return std::max(_depth >> level, 1); } + // The size of a face is a multiple of the padded line = (width * texelFormat_size + alignment padding) + Size evalMipLineSize(uint16 level) const { return evalPaddedSize(evalMipWidth(level) * getTexelFormat().getSize()); } + // Size for each face of a mip at a particular level uint32 evalMipFaceNumTexels(uint16 level) const { return evalMipWidth(level) * evalMipHeight(level) * evalMipDepth(level); } - uint32 evalMipFaceSize(uint16 level) const { return evalMipFaceNumTexels(level) * getTexelFormat().getSize(); } + Size evalMipFaceSize(uint16 level) const { return evalMipLineSize(level) * evalMipHeight(level) * evalMipDepth(level); } // Total size for the mip uint32 evalMipNumTexels(uint16 level) const { return evalMipFaceNumTexels(level) * getNumFaces(); } - uint32 evalMipSize(uint16 level) const { return evalMipNumTexels(level) * getTexelFormat().getSize(); } - - uint32 evalStoredMipFaceSize(uint16 level, const Element& format) const { return evalMipFaceNumTexels(level) * format.getSize(); } - uint32 evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); } - - uint32 evalTotalSize(uint16 startingMip = 0) const { - uint32 size = 0; - uint16 minMipLevel = std::max(getMinMip(), startingMip); - uint16 maxMipLevel = getMaxMip(); - for (uint16 l = minMipLevel; l <= maxMipLevel; l++) { - size += evalMipSize(l); - } - return size * getNumSlices(); - } - + Size evalMipSize(uint16 level) const { return evalMipFaceSize(level) * getNumFaces(); } + // Total size for all the mips of the texture + Size evalTotalSize(uint16 startingMip = 0) const; + // Compute the theorical size of the texture elements storage depending on the specified format + Size evalStoredMipLineSize(uint16 level, const Element& format) const { return evalPaddedSize(evalMipWidth(level) * format.getSize()); } + Size evalStoredMipFaceSize(uint16 level, const Element& format) const { return evalMipFaceNumTexels(level) * format.getSize(); } + Size evalStoredMipSize(uint16 level, const Element& format) const { return evalMipNumTexels(level) * format.getSize(); } + // For convenience assign a source name const std::string& source() const { return _source; } void setSource(const std::string& source) { _source = source; } + + // Potentially change the minimum mip (mostly for debugging purpose) bool setMinMip(uint16 newMinMip); bool incremementMinMip(uint16 count = 1); uint16 getMinMip() const { return _minMip; } @@ -463,30 +458,22 @@ public: // in case autoGen is on, this doesn't allocate // Explicitely assign mip data for a certain level // If Bytes is NULL then simply allocate the space so mip sysmem can be accessed - void assignStoredMip(uint16 level, Size size, const Byte* bytes); void assignStoredMipFace(uint16 level, uint8 face, Size size, const Byte* bytes); void assignStoredMip(uint16 level, storage::StoragePointer& storage); void assignStoredMipFace(uint16 level, uint8 face, storage::StoragePointer& storage); - // Access the the sub mips - bool isStoredMipFaceAvailable(uint16 level, uint8 face = 0) const { return _storage->isMipAvailable(level, face); } + // Access the stored mips and faces const PixelsPointer accessStoredMipFace(uint16 level, uint8 face = 0) const { return _storage->getMipFace(level, face); } + bool isStoredMipFaceAvailable(uint16 level, uint8 face = 0) const { return _storage->isMipAvailable(level, face); } Size getStoredMipFaceSize(uint16 level, uint8 face = 0) const { return _storage->getMipFaceSize(level, face); } + Size getStoredMipSize(uint16 level) const; + Size getStoredSize() const; void setStorage(std::unique_ptr& newStorage); void setKtxBacking(const std::string& filename); - // access sizes for the stored mips - uint16 getStoredMipWidth(uint16 level) const; - uint16 getStoredMipHeight(uint16 level) const; - uint16 getStoredMipDepth(uint16 level) const; - uint32 getStoredMipNumTexels(uint16 level) const; - uint32 getStoredMipSize(uint16 level) const; - - bool isDefined() const { return _defined; } - // Usage is a a set of flags providing Semantic about the usage of the Texture. void setUsage(const Usage& usage) { _usage = usage; } Usage getUsage() const { return _usage; } @@ -512,7 +499,7 @@ public: ExternalUpdates getUpdates() const; - // Textures can be serialized directly to ktx data file, here is how + // Textures can be serialized directly to ktx data file, here is how static ktx::KTXUniquePointer serialize(const Texture& texture); static Texture* unserialize(const std::string& ktxFile, TextureUsageType usageType = TextureUsageType::RESOURCE, Usage usage = Usage(), const Sampler::Desc& sampler = Sampler::Desc()); static bool evalKTXFormat(const Element& mipFormat, const Element& texelFormat, ktx::Header& header); @@ -537,7 +524,7 @@ protected: Sampler _sampler; Stamp _samplerStamp { 0 }; - uint32 _size { 0 }; + Size _size { 0 }; Element _texelFormat; uint16 _width { 1 }; From dd73cb7b8e9b3aef5e055174e5bebe032b36f614 Mon Sep 17 00:00:00 2001 From: Sam Cake Date: Thu, 30 Mar 2017 23:46:37 -0700 Subject: [PATCH 32/36] Use a magic number gpu::Texture::SINGLE_MIP instead of 1 --- interface/src/ui/ApplicationOverlay.cpp | 4 ++-- libraries/gpu/src/gpu/Framebuffer.cpp | 6 +++--- libraries/gpu/src/gpu/Texture.h | 11 ++++++----- libraries/render-utils/src/AmbientOcclusionEffect.cpp | 4 ++-- libraries/render-utils/src/AntialiasingEffect.cpp | 2 +- libraries/render-utils/src/DeferredFramebuffer.cpp | 10 +++++----- libraries/render-utils/src/DeferredLightingEffect.cpp | 4 ++-- libraries/render-utils/src/RenderForwardTask.cpp | 4 ++-- libraries/render-utils/src/SubsurfaceScattering.cpp | 6 +++--- libraries/render-utils/src/SurfaceGeometryPass.cpp | 10 +++++----- libraries/render-utils/src/text/Font.cpp | 2 +- libraries/render/src/render/BlurTask.cpp | 4 ++-- plugins/openvr/src/OpenVrDisplayPlugin.cpp | 2 +- 13 files changed, 35 insertions(+), 34 deletions(-) diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index c41360e776..7239e49d89 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -207,13 +207,13 @@ void ApplicationOverlay::buildFramebufferObject() { auto width = uiSize.x; auto height = uiSize.y; if (!_overlayFramebuffer->getDepthStencilBuffer()) { - auto overlayDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(DEPTH_FORMAT, width, height, 1, DEFAULT_SAMPLER)); + auto overlayDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(DEPTH_FORMAT, width, height, gpu::Texture::SINGLE_MIP, DEFAULT_SAMPLER)); _overlayFramebuffer->setDepthStencilBuffer(overlayDepthTexture, DEPTH_FORMAT); } if (!_overlayFramebuffer->getRenderBuffer(0)) { const gpu::Sampler OVERLAY_SAMPLER(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP); - auto colorBuffer = gpu::TexturePointer(gpu::Texture::createRenderBuffer(COLOR_FORMAT, width, height, 1, OVERLAY_SAMPLER)); + auto colorBuffer = gpu::TexturePointer(gpu::Texture::createRenderBuffer(COLOR_FORMAT, width, height, gpu::Texture::SINGLE_MIP, OVERLAY_SAMPLER)); _overlayFramebuffer->setRenderBuffer(0, colorBuffer); } } diff --git a/libraries/gpu/src/gpu/Framebuffer.cpp b/libraries/gpu/src/gpu/Framebuffer.cpp index 5281f2a61d..b49c681889 100755 --- a/libraries/gpu/src/gpu/Framebuffer.cpp +++ b/libraries/gpu/src/gpu/Framebuffer.cpp @@ -32,7 +32,7 @@ Framebuffer* Framebuffer::create(const std::string& name) { Framebuffer* Framebuffer::create(const std::string& name, const Format& colorBufferFormat, uint16 width, uint16 height) { auto framebuffer = Framebuffer::create(name); - auto colorTexture = TexturePointer(Texture::createRenderBuffer(colorBufferFormat, width, height, 1, Sampler(Sampler::FILTER_MIN_MAG_POINT))); + auto colorTexture = TexturePointer(Texture::createRenderBuffer(colorBufferFormat, width, height, Texture::SINGLE_MIP, Sampler(Sampler::FILTER_MIN_MAG_POINT))); colorTexture->setSource("Framebuffer::colorTexture"); framebuffer->setRenderBuffer(0, colorTexture); @@ -43,8 +43,8 @@ Framebuffer* Framebuffer::create(const std::string& name, const Format& colorBuf Framebuffer* Framebuffer::create(const std::string& name, const Format& colorBufferFormat, const Format& depthStencilBufferFormat, uint16 width, uint16 height) { auto framebuffer = Framebuffer::create(name); - auto colorTexture = TexturePointer(Texture::createRenderBuffer(colorBufferFormat, width, height, 1, Sampler(Sampler::FILTER_MIN_MAG_POINT))); - auto depthTexture = TexturePointer(Texture::createRenderBuffer(depthStencilBufferFormat, width, height, 1, Sampler(Sampler::FILTER_MIN_MAG_POINT))); + auto colorTexture = TexturePointer(Texture::createRenderBuffer(colorBufferFormat, width, height, Texture::SINGLE_MIP, Sampler(Sampler::FILTER_MIN_MAG_POINT))); + auto depthTexture = TexturePointer(Texture::createRenderBuffer(depthStencilBufferFormat, width, height, Texture::SINGLE_MIP, Sampler(Sampler::FILTER_MIN_MAG_POINT))); framebuffer->setRenderBuffer(0, colorTexture); framebuffer->setDepthStencilBuffer(depthTexture, depthStencilBufferFormat); diff --git a/libraries/gpu/src/gpu/Texture.h b/libraries/gpu/src/gpu/Texture.h index 312381a7d4..eab02141f0 100755 --- a/libraries/gpu/src/gpu/Texture.h +++ b/libraries/gpu/src/gpu/Texture.h @@ -327,12 +327,13 @@ public: }; static const uint16 MAX_NUM_MIPS = 0; - static Texture* create1D(const Element& texelFormat, uint16 width, uint16 numMips = 1, const Sampler& sampler = Sampler()); - static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = 1, const Sampler& sampler = Sampler()); - static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips = 1, const Sampler& sampler = Sampler()); + static const uint16 SINGLE_MIP = 1; + static Texture* create1D(const Element& texelFormat, uint16 width, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler()); + static Texture* create2D(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler()); + static Texture* create3D(const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler()); static Texture* createCube(const Element& texelFormat, uint16 width, uint16 numMips = 1, const Sampler& sampler = Sampler()); - static Texture* createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = 1, const Sampler& sampler = Sampler()); - static Texture* createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = 1, const Sampler& sampler = Sampler()); + static Texture* createRenderBuffer(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler()); + static Texture* createStrict(const Element& texelFormat, uint16 width, uint16 height, uint16 numMips = SINGLE_MIP, const Sampler& sampler = Sampler()); static Texture* createExternal(const ExternalRecycler& recycler, const Sampler& sampler = Sampler()); // After the texture has been created, it should be defined diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index b9f1dba9c2..678d8b1baf 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -74,11 +74,11 @@ void AmbientOcclusionFramebuffer::allocate() { auto width = _frameSize.x; auto height = _frameSize.y; - _occlusionTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _occlusionTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _occlusionFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusion")); _occlusionFramebuffer->setRenderBuffer(0, _occlusionTexture); - _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _occlusionBlurredTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _occlusionBlurredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("occlusionBlurred")); _occlusionBlurredFramebuffer->setRenderBuffer(0, _occlusionBlurredTexture); } diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index abbaa585fd..f11d62acbe 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -52,7 +52,7 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { _antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); auto format = gpu::Element::COLOR_SRGBA_32; // DependencyManager::get()->getLightingTexture()->getTexelFormat(); auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - _antialiasingTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(format, width, height, 1, defaultSampler)); + _antialiasingTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler)); _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); } diff --git a/libraries/render-utils/src/DeferredFramebuffer.cpp b/libraries/render-utils/src/DeferredFramebuffer.cpp index 34a0c429c3..52329931d0 100644 --- a/libraries/render-utils/src/DeferredFramebuffer.cpp +++ b/libraries/render-utils/src/DeferredFramebuffer.cpp @@ -53,9 +53,9 @@ void DeferredFramebuffer::allocate() { auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - _deferredColorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, width, height, 1, defaultSampler)); - _deferredNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(linearFormat, width, height, 1, defaultSampler)); - _deferredSpecularTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, width, height, 1, defaultSampler)); + _deferredColorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, width, height, gpu::Texture::SINGLE_MIP, defaultSampler)); + _deferredNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(linearFormat, width, height, gpu::Texture::SINGLE_MIP, defaultSampler)); + _deferredSpecularTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, width, height, gpu::Texture::SINGLE_MIP, defaultSampler)); _deferredFramebuffer->setRenderBuffer(0, _deferredColorTexture); _deferredFramebuffer->setRenderBuffer(1, _deferredNormalTexture); @@ -65,7 +65,7 @@ void DeferredFramebuffer::allocate() { auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format if (!_primaryDepthTexture) { - _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(depthFormat, width, height, 1, defaultSampler)); + _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(depthFormat, width, height, gpu::Texture::SINGLE_MIP, defaultSampler)); } _deferredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); @@ -75,7 +75,7 @@ void DeferredFramebuffer::allocate() { auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR); - _lightingTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, 1, defaultSampler)); + _lightingTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, gpu::Texture::SINGLE_MIP, defaultSampler)); _lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("lighting")); _lightingFramebuffer->setRenderBuffer(0, _lightingTexture); _lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 34063ea2bb..dc1822c0f5 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -496,14 +496,14 @@ void PreparePrimaryFramebuffer::run(const SceneContextPointer& sceneContext, con auto colorFormat = gpu::Element::COLOR_SRGBA_32; auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - auto primaryColorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, 1, defaultSampler)); + auto primaryColorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler)); _primaryFramebuffer->setRenderBuffer(0, primaryColorTexture); auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format - auto primaryDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, 1, defaultSampler)); + auto primaryDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(depthFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler)); _primaryFramebuffer->setDepthStencilBuffer(primaryDepthTexture, depthFormat); } diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index 11d5fc8834..49090c2f5f 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -73,11 +73,11 @@ void PrepareFramebuffer::run(const SceneContextPointer& sceneContext, const Rend auto colorFormat = gpu::Element::COLOR_SRGBA_32; auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - auto colorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, frameSize.x, frameSize.y, 1, defaultSampler)); + auto colorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler)); _framebuffer->setRenderBuffer(0, colorTexture); auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format - auto depthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, frameSize.x, frameSize.y, 1, defaultSampler)); + auto depthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, frameSize.x, frameSize.y, gpu::Texture::SINGLE_MIP, defaultSampler)); _framebuffer->setDepthStencilBuffer(depthTexture, depthFormat); } diff --git a/libraries/render-utils/src/SubsurfaceScattering.cpp b/libraries/render-utils/src/SubsurfaceScattering.cpp index 75884f52f5..a57657a353 100644 --- a/libraries/render-utils/src/SubsurfaceScattering.cpp +++ b/libraries/render-utils/src/SubsurfaceScattering.cpp @@ -414,7 +414,7 @@ gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringProfile(Rend const int PROFILE_RESOLUTION = 512; // const auto pixelFormat = gpu::Element::COLOR_SRGBA_32; const auto pixelFormat = gpu::Element::COLOR_R11G11B10; - auto profileMap = gpu::TexturePointer(gpu::Texture::createRenderBuffer(pixelFormat, PROFILE_RESOLUTION, 1, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); + auto profileMap = gpu::TexturePointer(gpu::Texture::createRenderBuffer(pixelFormat, PROFILE_RESOLUTION, 1, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); profileMap->setSource("Generated Scattering Profile"); diffuseProfileGPU(profileMap, args); return profileMap; @@ -425,7 +425,7 @@ gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScatterin const int TABLE_RESOLUTION = 512; // const auto pixelFormat = gpu::Element::COLOR_SRGBA_32; const auto pixelFormat = gpu::Element::COLOR_R11G11B10; - auto scatteringLUT = gpu::TexturePointer(gpu::Texture::createRenderBuffer(pixelFormat, TABLE_RESOLUTION, TABLE_RESOLUTION, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); + auto scatteringLUT = gpu::TexturePointer(gpu::Texture::createRenderBuffer(pixelFormat, TABLE_RESOLUTION, TABLE_RESOLUTION, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); //diffuseScatter(scatteringLUT); scatteringLUT->setSource("Generated pre-integrated scattering"); diffuseScatterGPU(profile, scatteringLUT, args); @@ -434,7 +434,7 @@ gpu::TexturePointer SubsurfaceScatteringResource::generatePreIntegratedScatterin gpu::TexturePointer SubsurfaceScatteringResource::generateScatteringSpecularBeckmann(RenderArgs* args) { const int SPECULAR_RESOLUTION = 256; - auto beckmannMap = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, SPECULAR_RESOLUTION, SPECULAR_RESOLUTION, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); + auto beckmannMap = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, SPECULAR_RESOLUTION, SPECULAR_RESOLUTION, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR, gpu::Sampler::WRAP_CLAMP))); beckmannMap->setSource("Generated beckmannMap"); computeSpecularBeckmannGPU(beckmannMap, args); return beckmannMap; diff --git a/libraries/render-utils/src/SurfaceGeometryPass.cpp b/libraries/render-utils/src/SurfaceGeometryPass.cpp index 684fc24347..a4a83bb6c5 100644 --- a/libraries/render-utils/src/SurfaceGeometryPass.cpp +++ b/libraries/render-utils/src/SurfaceGeometryPass.cpp @@ -72,7 +72,7 @@ void LinearDepthFramebuffer::allocate() { auto height = _frameSize.y; // For Linear Depth: - _linearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), width, height, 1, + _linearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _linearDepthFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("linearDepth")); _linearDepthFramebuffer->setRenderBuffer(0, _linearDepthTexture); @@ -83,7 +83,7 @@ void LinearDepthFramebuffer::allocate() { _halfLinearDepthTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::RED), _halfFrameSize.x, _halfFrameSize.y, HALF_LINEAR_DEPTH_MAX_MIP_LEVEL, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); - _halfNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _halfFrameSize.x, _halfFrameSize.y, 1, + _halfNormalTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _halfFrameSize.x, _halfFrameSize.y, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _downsampleFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("halfLinearDepth")); @@ -304,15 +304,15 @@ void SurfaceGeometryFramebuffer::allocate() { auto width = _frameSize.x; auto height = _frameSize.y; - _curvatureTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _curvatureTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _curvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("surfaceGeometry::curvature")); _curvatureFramebuffer->setRenderBuffer(0, _curvatureTexture); - _lowCurvatureTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _lowCurvatureTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _lowCurvatureFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("surfaceGeometry::lowCurvature")); _lowCurvatureFramebuffer->setRenderBuffer(0, _lowCurvatureTexture); - _blurringTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); + _blurringTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, width, height, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT))); _blurringFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("surfaceGeometry::blurring")); _blurringFramebuffer->setRenderBuffer(0, _blurringTexture); } diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 142e7154b9..00fcabd7da 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -207,7 +207,7 @@ void Font::read(QIODevice& in) { formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::BGRA); } - _texture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), 1, + _texture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR))); _texture->setStoredMipFormat(formatMip); _texture->assignStoredMip(0, image.byteCount(), image.constBits()); diff --git a/libraries/render/src/render/BlurTask.cpp b/libraries/render/src/render/BlurTask.cpp index 2557c5f356..b0329b22a5 100644 --- a/libraries/render/src/render/BlurTask.cpp +++ b/libraries/render/src/render/BlurTask.cpp @@ -108,7 +108,7 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra // _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); //} auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); - auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), 1, blurringSampler)); + auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), gpu::Texture::SINGLE_MIP, blurringSampler)); _blurredFramebuffer->setRenderBuffer(0, blurringTarget); } @@ -131,7 +131,7 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra _outputFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat()); }*/ auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); - auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), 1, blurringSampler)); + auto blurringTarget = gpu::TexturePointer(gpu::Texture::create2D(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), sourceFramebuffer->getWidth(), sourceFramebuffer->getHeight(), gpu::Texture::SINGLE_MIP, blurringSampler)); _outputFramebuffer->setRenderBuffer(0, blurringTarget); } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 02526e4299..9f95e64361 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -494,7 +494,7 @@ void OpenVrDisplayPlugin::customizeContext() { _compositeInfos[0].texture = _compositeFramebuffer->getRenderBuffer(0); for (size_t i = 0; i < COMPOSITING_BUFFER_SIZE; ++i) { if (0 != i) { - _compositeInfos[i].texture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _renderTargetSize.x, _renderTargetSize.y, 1, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT))); + _compositeInfos[i].texture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(gpu::Element::COLOR_RGBA_32, _renderTargetSize.x, _renderTargetSize.y, gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT))); } _compositeInfos[i].textureID = getGLBackend()->getTextureID(_compositeInfos[i].texture); } From 6a0c07a692230c58d3e23ff435c1dee71739a14c Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 31 Mar 2017 10:39:13 -0700 Subject: [PATCH 33/36] Fixing a bad counter for numFaces --- libraries/gpu/src/gpu/Texture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 2f40ee20a2..09582cf96a 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -490,7 +490,7 @@ Size Texture::getStoredMipSize(uint16 level) const { PixelsPointer mipFace = accessStoredMipFace(level); Size size = 0; if (mipFace && mipFace->getSize()) { - for (int face = 0; face < mipFace->getSize(); ++face) { + for (int face = 0; face < getNumFaces(); ++face) { size += getStoredMipFaceSize(level, face); } } From c8970dd704ca5581b1ffae405031185b931bbac7 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 31 Mar 2017 11:34:03 -0700 Subject: [PATCH 34/36] Fixing the warning on windows --- libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp index 8aab6abaa9..1dad72dbc1 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp @@ -229,7 +229,7 @@ void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) { _resource._textures[slot] = resourceTexture; - _stats._RSAmountTextureMemoryBounded += object->size(); + _stats._RSAmountTextureMemoryBounded += (int) object->size(); } else { releaseResourceTexture(slot); From 54c66aff079a8ecbe8e07a2bc5b687c136daf67a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 31 Mar 2017 13:18:40 -0700 Subject: [PATCH 35/36] use tablet-ui stylus as default, rather than avatar finger --- interface/src/Application.cpp | 2 +- scripts/system/controllers/handControllerGrab.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 25a585ea34..b57c404049 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -549,7 +549,7 @@ const float DEFAULT_DESKTOP_TABLET_SCALE_PERCENT = 75.0f; const bool DEFAULT_DESKTOP_TABLET_BECOMES_TOOLBAR = true; const bool DEFAULT_HMD_TABLET_BECOMES_TOOLBAR = false; const bool DEFAULT_TABLET_VISIBLE_TO_OTHERS = false; -const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = true; +const bool DEFAULT_PREFER_AVATAR_FINGER_OVER_STYLUS = false; Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bool runServer, QString runServerPathOption) : QApplication(argc, argv), diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 9a6760a37b..e1b432d09f 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -1181,7 +1181,7 @@ function MyController(hand) { this.updateStylusTip(); - var DEFAULT_USE_FINGER_AS_STYLUS = true; + var DEFAULT_USE_FINGER_AS_STYLUS = false; var USE_FINGER_AS_STYLUS = Settings.getValue("preferAvatarFingerOverStylus"); if (USE_FINGER_AS_STYLUS === "") { USE_FINGER_AS_STYLUS = DEFAULT_USE_FINGER_AS_STYLUS; From 467ea787c6bcc5b780513f2fd2b601e6de3dea8b Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 31 Mar 2017 14:54:00 -0700 Subject: [PATCH 36/36] Adress Seth's review --- .../src/gpu/gl41/GL41BackendTexture.cpp | 40 +++++++++---------- libraries/gpu/src/gpu/Texture.cpp | 8 ++-- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp index 1a2652a950..2056085091 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp @@ -37,23 +37,23 @@ GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) { GL41Texture* object = Backend::getGPUObject(texture); if (!object) { switch (texture.getUsageType()) { - case TextureUsageType::RENDERBUFFER: - object = new GL41AttachmentTexture(shared_from_this(), texture); - break; + case TextureUsageType::RENDERBUFFER: + object = new GL41AttachmentTexture(shared_from_this(), texture); + break; - case TextureUsageType::STRICT_RESOURCE: - qCDebug(gpugllogging) << "Strict texture " << texture.source().c_str(); - object = new GL41StrictResourceTexture(shared_from_this(), texture); - break; + case TextureUsageType::STRICT_RESOURCE: + qCDebug(gpugllogging) << "Strict texture " << texture.source().c_str(); + object = new GL41StrictResourceTexture(shared_from_this(), texture); + break; - case TextureUsageType::RESOURCE: { - qCDebug(gpugllogging) << "variable / Strict texture " << texture.source().c_str(); - object = new GL41ResourceTexture(shared_from_this(), texture); - break; - } + case TextureUsageType::RESOURCE: { + qCDebug(gpugllogging) << "variable / Strict texture " << texture.source().c_str(); + object = new GL41ResourceTexture(shared_from_this(), texture); + break; + } - default: - Q_UNREACHABLE(); + default: + Q_UNREACHABLE(); } } @@ -163,7 +163,7 @@ void GL41FixedAllocationTexture::allocateStorage() const { const auto numMips = _gpuObject.getNumMips(); // glTextureStorage2D(_id, mips, texelFormat.internalFormat, dimensions.x, dimensions.y); - for (GLint level = 0; level < numMips; ++level) { + for (GLint level = 0; level < numMips; level++) { Vec3u dimensions = _gpuObject.evalMipDimensions(level); for (GLenum target : getFaceTargets(_target)) { glTexImage2D(target, level, texelFormat.internalFormat, dimensions.x, dimensions.y, 0, texelFormat.format, texelFormat.type, nullptr); @@ -181,7 +181,7 @@ void GL41FixedAllocationTexture::syncSampler() const { glTexParameteri(_target, GL_TEXTURE_BASE_LEVEL, baseMip); glTexParameterf(_target, GL_TEXTURE_MIN_LOD, (float)sampler.getMinMip()); - glTexParameterf(_target, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.f : sampler.getMaxMip())); + glTexParameterf(_target, GL_TEXTURE_MAX_LOD, (sampler.getMaxMip() == Sampler::MAX_MIP_LEVEL ? 1000.0f : sampler.getMaxMip())); } // Renderbuffer attachment textures @@ -202,10 +202,10 @@ GL41StrictResourceTexture::GL41StrictResourceTexture(const std::weak_ptr& backend withPreservedTexture([&] { auto mipLevels = _gpuObject.getNumMips(); - for (uint16_t sourceMip = 0; sourceMip < mipLevels; ++sourceMip) { + for (uint16_t sourceMip = 0; sourceMip < mipLevels; sourceMip++) { uint16_t targetMip = sourceMip; size_t maxFace = GLTexture::getFaceCount(_target); - for (uint8_t face = 0; face < maxFace; ++face) { + for (uint8_t face = 0; face < maxFace; face++) { copyMipFaceFromTexture(sourceMip, targetMip, face); } } diff --git a/libraries/gpu/src/gpu/Texture.cpp b/libraries/gpu/src/gpu/Texture.cpp index 09582cf96a..1e65972114 100755 --- a/libraries/gpu/src/gpu/Texture.cpp +++ b/libraries/gpu/src/gpu/Texture.cpp @@ -396,8 +396,8 @@ Size Texture::evalTotalSize(uint16 startingMip) const { Size size = 0; uint16 minMipLevel = std::max(getMinMip(), startingMip); uint16 maxMipLevel = getMaxMip(); - for (uint16 l = minMipLevel; l <= maxMipLevel; l++) { - size += evalMipSize(l); + for (uint16 level = minMipLevel; level <= maxMipLevel; level++) { + size += evalMipSize(level); } return size * getNumSlices(); } @@ -490,7 +490,7 @@ Size Texture::getStoredMipSize(uint16 level) const { PixelsPointer mipFace = accessStoredMipFace(level); Size size = 0; if (mipFace && mipFace->getSize()) { - for (int face = 0; face < getNumFaces(); ++face) { + for (int face = 0; face < getNumFaces(); face++) { size += getStoredMipFaceSize(level, face); } } @@ -499,7 +499,7 @@ Size Texture::getStoredMipSize(uint16 level) const { Size Texture::getStoredSize() const { Size size = 0; - for (int level = 0; level < getNumMips(); ++level) { + for (int level = 0; level < getNumMips(); level++) { size += getStoredMipSize(level); } return size;