High Fidelity, Inc. ("High Fidelity") respects the privacy of its online visitors and users of its products and services. We recognize the importance of protecting information collected from our users and have adopted this Privacy Policy to inform you about how we gather, store and use information derived from your use of our products, services and online sites in accordance with local law in the places where we operate.
+By using our online sites, products, and services (collectively, the "Service"), you agree that we may collect personally identifiable information (as defined below). We will not share your personally identifiable information except as described herein.
+
+1. Types of Information We Collect
+
+ We collect two basic types of information - personal information and anonymous information - and we may use personal and anonymous information to create a third type of information, aggregate information. Personal Information means information that identifies (whether directly or indirectly) a particular individual, such as the individual's first and last name, postal address, e-mail address and/or telephone number. Anonymous Information means information that does not directly or indirectly identify, and cannot reasonably be used to identify, an individual (including an individual's computing device). Aggregate Information means information about groups or categories of individuals which does not identify and cannot reasonably be used to identify an individual. We may share Aggregate and Anonymous Information with other parties without restriction.
+
+ We collect the following categories of information:
+
+ Registration information you provide when you create an account, which may include your first name and surname, country of residence, gender, date of birth, e-mail address, username and password.
+
+ Transaction information you provide when you request information or purchase a product or service from us, whether on our sites or through our applications, including your postal address, telephone number and payment information. If you conduct transactions, we may collect and retain some or all of the information related to these transactions, including transaction amount(s), parties involved, time and manner of exchange, and other transaction circumstances.
+
+ Information you provide in public forums on our Service. Please note that our sites and applications may offer chat, forums, community environments (including multiplayer gameplay) or other tools that do not have a restricted audience. If you provide Personal Information when you use any of these features, that Personal Information may be publicly posted and otherwise disclosed without limitation as to its use by us or by a third party. We have no obligation to keep private personally identifiable information that you have made available to other users or the public using these functions. To request removal of your Personal Information from a public forum on one of our sites or applications, please contact Customer Support.
+
+ Information sent either one-to-one or within a limited group using our message, chat, post or similar functionality, where we are permitted by law to collect this information.
+
+ Information you provide to us when you use our sites and applications, our applications on third-party sites or platforms (such as social networking sites), or link your profile from a third-party site or platform to your registered account.
+
+ Location information when you visit our sites or use our applications, including location information either provided by a mobile device interacting with one of our sites or applications, or associated with your IP address, where we are permitted by law to process this information.
+
+ Usage, viewing and technical data, including your device identifier or IP address, when you visit our sites, use our applications on third-party sites or platforms, or open e-mails that we send.
+
+ Additionally there are a few special circumstances to note:
+
+ Intellectual Property Claim Notices: If you notify us of an intellectual property claim, the information in your claim notice may be shared with other parties to the disagreement or third parties in our discretion and as required by law.
+
+ Beta Service User: If you volunteer to serve as a beta participant for our pre-commercial content, we may track bug reports and individual system performance in an effort to test our technology rigorously before it is deployed.
+
+ Former Customer: If you discontinue your use of our Service, we may keep your registration file in our database for use in the event that you elect to renew your use of our Service, as well as for anti-fraud and other such protective measures.
+
+ Job Postings or Unsolicited Communications: Please note that information we receive in reference to a job posting or by unsolicited communications does not fall within the terms outlined in this Privacy Policy, however information from your resume will be used solely for the purpose of evaluating your candidacy for employment.
+
+ 2. How We Collect Your Information
+
+
+ We collect information you provide to us when you request products, services or information from us, register with us, participate in public forums or other activities on our sites and applications, respond to customer inquiries or surveys, or otherwise interact with us.
+
+ We collect information through technology, such as cookies and other technologies (such as web beacons and pixel tags), including when you visit our sites and applications or use our applications on third-party sites or platforms. A cookie is a small string of data which often includes an anonymous unique identifier sent to your Internet browser from a website's computers, which is stored on your computer's hard drive and is used to customize your use of a product or online site, keep records of your access to an online site or product, or store information needed by you on a regular basis (e.g. password retention functionality). High Fidelity (itself or through third parties acting on our behalf) use cookies for a number of purposes relating to our websites, applications and services, including to access your account information where you "login" to our websites, forums or other areas and to keep track of your website session data. You can configure your browser to accept all cookies, reject all cookies, or notify you when a cookie is set. Each browser is different, so consult the "Help" menu of your browser to learn how you change your cookie preferences. Please note that if you reject all cookies, you may not be able to use certain of our (or other companies') web pages.
+
+ We may participate in ad and/or affiliate networks operated by various third party companies. These companies collect and may use certain anonymous information about your visits to our Service as a function of referring Internet traffic to our Service. We do not permit these companies to collect any Personal Information about you; however these companies may collect your IP address. These companies may set and use cookies, web beacons, pixels and other technologies to collect anonymous information about your visits to our Service, and may otherwise aggregate, analyze and anonymize that data. If you would like to learn more about these specialized advertising technologies, the Network Advertising Initiative offers useful information about Internet advertising companies, including information about how to opt-out of certain information collection.
+
+ We acquire information from other trusted sources to update or supplement the information you provided or we collected automatically. Local law may require that you authorize the third party to share your information with us before we can acquire it.
+
+ 3. Use of Your Information by High Fidelity
+
+ High Fidelity will be the data controller for your information, and will have access to your information for use for the following purposes (unless prohibited by law):
+
+ Provide you with the products and services you request
+
+ Communicate with you about your account or transactions with us and send you information about features on our sites and applications or changes to our policies
+
+ Consistent with local law and choices and controls that may be available to you:
+
+ Send you offers and promotions for our products and services or, as permitted, third-party products and services
+
+ Personalize content and experiences on our sites and applications
+
+ Provide you with advertising based on your activity on our sites and applications and on third-party sites and applications.
+ Optimize or improve our products, services and operations
+
+ Detect, investigate and prevent activities that may violate our policies or be illegal
+
+ Except under certain limited circumstances as set forth here and in our Terms of Service, High Fidelity does not disclose to third parties the Personal Information or other account-related information that you provide to us without your permission. You understand, however, that High Fidelity may disclose your Personal Information or other account-related information under the following circumstances:
+
+ If we believe in good faith that such disclosure is necessary under applicable law, or to comply with legal process served on High Fidelity;
+
+ In order to protect and defend the rights or interests of High Fidelity, its products and services, and/or the other users of such products and services;
+
+ In order to report to law enforcement authorities, or assist in their investigation of suspected illegal or wrongful activity, or to report any instance in which we believe a person may be in danger;
+
+ To service providers with whom we have contracted to assist us with the features or operations (such as anti-fraud functions, billing, collections, registration, customer support, e-mail delivery, age verification), to fulfill your service requests, offer new content or help us improve our products and/or services.
+ Our contracts with third parties prohibit them from using any of your Personal Information for purposes unrelated to the product or services they are providing;
+
+ To other third parties (a) to provide you with services you have requested, (b) to offer you information about our products or services (e.g. events or features), or (c) to whom you explicitly ask us to send your information (or about whom you are otherwise explicitly notified and consent to when using a specific service). For instance, we may provide certain information to our payment processor, to credit card associations, banks or issuers (if you are using a credit card), to PayPal (if you are using a PayPal account), or to providers of other services you request. If you choose to use these third parties' products or services, then their use of your information is governed by their privacy policies. You should evaluate the practices of third party providers before deciding to use their services; and
+
+ To other business entities, should we plan to merge with or be acquired by that business entity.
+
+
+ 4. Sharing Your Information with Other Companies
+
+
+ We will not share your Personal Information outside of High Fidelity except in limited circumstances, including:
+
+ When you allow us to share your Personal Information with another company, such as:
+
+ Directing us to share your Personal Information with third-party sites or platforms, such as social networking sites
+ Please note that once we share your Personal Information with another company, the information received by the other company becomes subject to the other company's privacy practices.
+
+ When companies perform services on our behalf; however, these companies are prohibited from using your Personal Information for purposes other than those requested by us or required by law.
+
+ When we share Personal Information with third parties in connection with the sale of a business, to enforce our Terms of Service or rules, to ensure the safety and security of our users and third parties, to comply with legal process or in other cases if we believe in good faith that disclosure is required by law.
+
+ 5. Data Transfers, Storage and Processing Globally
+
+
+ We operate globally and may transfer your Personal Information to locations around the world for the purposes described in this Privacy Policy. Whenever your Personal Information is transferred, stored or processed by us, we will take reasonable steps to safeguard the privacy of your Personal Information in accordance with applicable law.
+
+ 6. Changes to this Privacy Policy
+
+
+ From time to time, we may change this Privacy Policy to accommodate new technologies, industry practices, regulatory requirements or for other purposes. If we decide to change our privacy policy, we will post those changes to this privacy statement, and other places we deem appropriate so that you are aware of what information we collect, how we use it, and under what circumstances, if any, we disclose it. We reserve the right to modify this privacy statement at any time, so please review it frequently. If we make material changes to this policy, we will notify you here, by email, or by means of a notice on our home page.
+
+
+ 7. Comments and Questions
+
+
+ If you have a comment or question about this Privacy Policy or our privacy practices, please send an e-mail to privacy@highfidelity.com.
+
+
+Notice to California Residents:
+
+If you are a California resident, California Civil Code Section 1798.83 permits you to request information regarding the disclosure of your Personal Information by High Fidelity to third parties for the third parties' direct marketing purposes. With respect to these entities, this Privacy Policy applies only to their activities within the State of California. To make such a request, please send an e-mail to privacy@highfidelity.com or write us at the address listed immediately above.
+
+
+
\ No newline at end of file
From 55a946c6c7bfc35903c3ad5425794e69e94b6811 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Tue, 24 Apr 2018 14:48:41 -0300
Subject: [PATCH 04/80] Fix non-android builds(performHapticFeedback)
---
interface/src/Application.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index eab6986f24..454848c87d 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -7943,7 +7943,9 @@ void Application::openAndroidActivity(const QString& activityName) {
}
void Application::performHapticFeedback(const QString& feedbackConstant) {
+#if defined(Q_OS_ANDROID)
AndroidHelper::instance().performHapticFeedback(feedbackConstant);
+#endif
}
#if defined(Q_OS_ANDROID)
From 11d232146774f63cb9373561c31eae2316ffa2f5 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Tue, 24 Apr 2018 16:43:48 -0300
Subject: [PATCH 05/80] New default avatar photo. Support relative url for
profile picture. Refactor download profile picture as async task
---
.../highfidelity/hifiinterface/HifiUtils.java | 25 +++++++
.../hifiinterface/MainActivity.java | 37 ++--------
.../task/DownloadProfileImageTask.java | 71 +++++++++++++++++++
.../res/drawable/default_profile_avatar.xml | 17 +++++
.../src/main/res/layout/navigation_header.xml | 1 +
5 files changed, 120 insertions(+), 31 deletions(-)
create mode 100644 android/app/src/main/java/io/highfidelity/hifiinterface/task/DownloadProfileImageTask.java
create mode 100644 android/app/src/main/res/drawable/default_profile_avatar.xml
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java
index 15d716548f..408929c20f 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java
@@ -1,11 +1,16 @@
package io.highfidelity.hifiinterface;
+import java.net.URI;
+import java.net.URISyntaxException;
+
/**
* Created by Gabriel Calero & Cristian Duarte on 4/13/18.
*/
public class HifiUtils {
+ public static final String METAVERSE_BASE_URL = "https://metaverse.highfidelity.com";
+
private static HifiUtils instance;
private HifiUtils() {
@@ -18,6 +23,26 @@ public class HifiUtils {
return instance;
}
+ public String absoluteHifiAssetUrl(String urlString) {
+ return absoluteHifiAssetUrl(urlString, METAVERSE_BASE_URL);
+ }
+
+ public String absoluteHifiAssetUrl(String urlString, String baseUrl) {
+ urlString = urlString.trim();
+ if (!urlString.isEmpty()) {
+ URI uri;
+ try {
+ uri = new URI(urlString);
+ } catch (URISyntaxException e) {
+ return urlString;
+ }
+ if (uri.getScheme() == null || uri.getScheme().isEmpty()) {
+ urlString = baseUrl + urlString;
+ }
+ }
+ return urlString;
+ }
+
public native String getCurrentAddress();
}
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
index 0c15730643..274ad95347 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
@@ -35,13 +35,14 @@ import io.highfidelity.hifiinterface.fragment.GotoFragment;
import io.highfidelity.hifiinterface.fragment.HomeFragment;
import io.highfidelity.hifiinterface.fragment.LoginFragment;
import io.highfidelity.hifiinterface.fragment.PolicyFragment;
+import io.highfidelity.hifiinterface.task.DownloadProfileImageTask;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,
LoginFragment.OnLoginInteractionListener,
HomeFragment.OnHomeInteractionListener,
GotoFragment.OnGotoInteractionListener {
- private static final int PROFILE_PICTURE_PLACEHOLDER = R.drawable.ic_person;
+ private static final int PROFILE_PICTURE_PLACEHOLDER = R.drawable.default_profile_avatar;
private String TAG = "HighFidelity";
public native boolean nativeIsLoggedIn();
@@ -234,36 +235,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
* TODO: this should be get from an API (at the moment there is no one for this)
*/
private void updateProfilePicture(String username) {
- Picasso.get().load(PROFILE_PICTURE_PLACEHOLDER).into(mProfilePicture);
-
- new Thread(() -> {
- try {
- URL userPage = new URL("https://highfidelity.com/users/" + username);
- BufferedReader in = new BufferedReader(
- new InputStreamReader(
- userPage.openStream()));
-
- StringBuffer strBuff = new StringBuffer();
- String inputLine;
- while ((inputLine = in.readLine()) != null) {
- strBuff.append(inputLine);
- }
- in.close();
- String substr = "img class=\"users-img\" src=\"";
- int indexBegin = strBuff.indexOf(substr) + substr.length();
- if (indexBegin >= substr.length()) {
- int indexEnd = strBuff.indexOf("\"", indexBegin);
- runOnUiThread(() -> {
- if (indexEnd > 0) {
- Picasso.get().load(strBuff.substring(indexBegin, indexEnd)).into(mProfilePicture, new RoundProfilePictureCallback());
- }
- });
- }
- } catch (IOException e) {
- Log.e(TAG, "Error getting profile picture for username " + username);
- }
- }).start();
-
+ mProfilePicture.setImageResource(PROFILE_PICTURE_PLACEHOLDER);
+ new DownloadProfileImageTask(url -> { if (url!=null && !url.isEmpty()) {
+ Picasso.get().load(url).into(mProfilePicture, new RoundProfilePictureCallback());
+ } } ).execute(username);
}
public void onPrivacyPolicyClicked(View view) {
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/task/DownloadProfileImageTask.java b/android/app/src/main/java/io/highfidelity/hifiinterface/task/DownloadProfileImageTask.java
new file mode 100644
index 0000000000..f32227a31e
--- /dev/null
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/task/DownloadProfileImageTask.java
@@ -0,0 +1,71 @@
+package io.highfidelity.hifiinterface.task;
+
+import android.os.AsyncTask;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+import io.highfidelity.hifiinterface.HifiUtils;
+
+/**
+ * This is a temporary solution until the profile picture URL is
+ * available in an API
+ */
+public class DownloadProfileImageTask extends AsyncTask {
+
+ private static final String BASE_PROFILE_URL = "https://highfidelity.com";
+ private static final String TAG = "Interface";
+
+ private final DownloadProfileImageResultProcessor mResultProcessor;
+
+ public interface DownloadProfileImageResultProcessor {
+ void onResultAvailable(String url);
+ }
+
+ public DownloadProfileImageTask(DownloadProfileImageResultProcessor resultProcessor) {
+ mResultProcessor = resultProcessor;
+ }
+
+ @Override
+ protected String doInBackground(String... usernames) {
+ URL userPage = null;
+ for (String username: usernames) {
+ try {
+ userPage = new URL(BASE_PROFILE_URL + "/users/" + username);
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(
+ userPage.openStream()));
+
+ StringBuffer strBuff = new StringBuffer();
+ String inputLine;
+ while ((inputLine = in.readLine()) != null) {
+ strBuff.append(inputLine);
+ }
+ in.close();
+ String substr = "img class=\"users-img\" src=\"";
+ int indexBegin = strBuff.indexOf(substr) + substr.length();
+ if (indexBegin >= substr.length()) {
+ int indexEnd = strBuff.indexOf("\"", indexBegin);
+ if (indexEnd > 0) {
+ String url = strBuff.substring(indexBegin, indexEnd);
+ return HifiUtils.getInstance().absoluteHifiAssetUrl(url, BASE_PROFILE_URL);
+ }
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Error getting profile picture for username " + username);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(String url) {
+ super.onPostExecute(url);
+ if (mResultProcessor != null) {
+ mResultProcessor.onResultAvailable(url);
+ }
+ }
+}
diff --git a/android/app/src/main/res/drawable/default_profile_avatar.xml b/android/app/src/main/res/drawable/default_profile_avatar.xml
new file mode 100644
index 0000000000..5db00acdd6
--- /dev/null
+++ b/android/app/src/main/res/drawable/default_profile_avatar.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/layout/navigation_header.xml b/android/app/src/main/res/layout/navigation_header.xml
index 3ded5a515d..b61e701f48 100644
--- a/android/app/src/main/res/layout/navigation_header.xml
+++ b/android/app/src/main/res/layout/navigation_header.xml
@@ -9,6 +9,7 @@
android:id="@+id/profilePicture"
android:layout_width="64dp"
android:layout_height="64dp"
+ android:src="@drawable/default_profile_avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
From d33855b860d702a002027c5684c79fc6ee2fd719 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Tue, 24 Apr 2018 17:15:05 -0300
Subject: [PATCH 06/80] Advance the haptic feedback from onClick to onPressDown
---
scripts/system/+android/actionbar.js | 11 ++++++++---
scripts/system/+android/audio.js | 9 ++++++---
scripts/system/+android/modes.js | 17 ++++++++++++-----
3 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/scripts/system/+android/actionbar.js b/scripts/system/+android/actionbar.js
index 368f5b373c..c23ce89d4c 100644
--- a/scripts/system/+android/actionbar.js
+++ b/scripts/system/+android/actionbar.js
@@ -33,19 +33,24 @@ function init() {
hoverBgOpacity: 0.0,
activeBgOpacity: 0.0
});
-
- backButton.clicked.connect(onBackPressed);
+
+ backButton.entered.connect(onBackPressed);
+ backButton.clicked.connect(onBackClicked);
}
function onBackPressed() {
App.performHapticFeedback("CONTEXT_CLICK");
+}
+
+function onBackClicked() {
App.openAndroidActivity("Home");
}
Script.scriptEnding.connect(function() {
if(backButton) {
- backButton.clicked.disconnect(onBackPressed);
+ backButton.entered.disconnect(onBackPressed);
+ backButton.clicked.disconnect(onBackClicked);
}
});
diff --git a/scripts/system/+android/audio.js b/scripts/system/+android/audio.js
index 1661c11315..5eb13a3198 100644
--- a/scripts/system/+android/audio.js
+++ b/scripts/system/+android/audio.js
@@ -15,7 +15,7 @@
var audiobar;
var audioButton;
-var logEnabled = true;
+var logEnabled = false;
function printd(str) {
if (logEnabled)
@@ -40,13 +40,15 @@ function init() {
onMuteToggled();
audioButton.clicked.connect(onMuteClicked);
+ audioButton.entered.connect(onMutePressed);
Audio.mutedChanged.connect(onMuteToggled);
}
function onMuteClicked() {
- printd("On Mute Clicked");
- //Menu.setIsOptionChecked("Mute Microphone", !Menu.isOptionChecked("Mute Microphone"));
Audio.muted = !Audio.muted;
+}
+
+function onMutePressed() {
App.performHapticFeedback("CONTEXT_CLICK");
}
@@ -59,6 +61,7 @@ function onMuteToggled() {
Script.scriptEnding.connect(function () {
if(audioButton) {
audioButton.clicked.disconnect(onMuteClicked);
+ audioButton.entered.disconnect(onMutePressed);
Audio.mutedChanged.connect(onMuteToggled);
}
});
diff --git a/scripts/system/+android/modes.js b/scripts/system/+android/modes.js
index 3743e1d068..c75377b976 100644
--- a/scripts/system/+android/modes.js
+++ b/scripts/system/+android/modes.js
@@ -57,15 +57,22 @@ function init() {
});
switchToMode(getCurrentModeSetting());
-
- modeButton.clicked.connect(function() {
- App.performHapticFeedback("CONTEXT_CLICK");
- switchToMode(nextMode[currentMode]);
- });
+
+ modeButton.entered.connect(modeButtonPressed);
+ modeButton.clicked.connect(modeButtonClicked);
}
function shutdown() {
+ modeButton.entered.disconnect(modeButtonPressed);
+ modeButton.clicked.disconnect(modeButtonClicked);
+}
+function modeButtonPressed() {
+ App.performHapticFeedback("CONTEXT_CLICK");
+}
+
+function modeButtonClicked() {
+ switchToMode(nextMode[currentMode]);
}
function saveCurrentModeSetting(mode) {
From 2673a06d6f083f5899df347742e39e3963193a12 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Wed, 25 Apr 2018 17:47:05 -0300
Subject: [PATCH 07/80] Tweak UI (status bar, action bar, privacy policy,
login)
---
.../hifiinterface/MainActivity.java | 14 +++--
.../app/src/main/res/font/raleway_italic.xml | 7 +++
.../app/src/main/res/layout/activity_main.xml | 5 +-
.../src/main/res/layout/fragment_login.xml | 55 +++++++++++--------
.../src/main/res/layout/fragment_policy.xml | 16 +++---
android/app/src/main/res/values/colors.xml | 5 +-
android/app/src/main/res/values/dimens.xml | 3 +
.../src/main/res/values/preloaded_fonts.xml | 1 +
8 files changed, 64 insertions(+), 42 deletions(-)
create mode 100644 android/app/src/main/res/font/raleway_italic.xml
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
index 274ad95347..2298308541 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
@@ -9,6 +9,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
+import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.support.v4.view.GravityCompat;
@@ -16,21 +17,17 @@ import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
-import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-
import io.highfidelity.hifiinterface.fragment.GotoFragment;
import io.highfidelity.hifiinterface.fragment.HomeFragment;
import io.highfidelity.hifiinterface.fragment.LoginFragment;
@@ -74,6 +71,11 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
mDrawerLayout = findViewById(R.id.drawer_layout);
+ Window window = getWindow();
+ window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
+ window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+ window.setStatusBarColor(ContextCompat.getColor(this, R.color.statusbar_color));
+
loadHomeFragment();
}
diff --git a/android/app/src/main/res/font/raleway_italic.xml b/android/app/src/main/res/font/raleway_italic.xml
new file mode 100644
index 0000000000..6bf9dfa29c
--- /dev/null
+++ b/android/app/src/main/res/font/raleway_italic.xml
@@ -0,0 +1,7 @@
+
+
+
diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml
index 3401c962b3..31bed89e91 100644
--- a/android/app/src/main/res/layout/activity_main.xml
+++ b/android/app/src/main/res/layout/activity_main.xml
@@ -16,8 +16,9 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
- android:background="?attr/colorPrimary"
- android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
+ android:background="?attr/colorPrimaryDark"
+ android:elevation="4dp"
+ />
+ app:srcCompat="@drawable/hifi_header" />
+ app:layout_constraintTop_toBottomOf="@id/password" />
diff --git a/android/app/src/main/res/layout/fragment_policy.xml b/android/app/src/main/res/layout/fragment_policy.xml
index 2a282ef631..9009a29a6d 100644
--- a/android/app/src/main/res/layout/fragment_policy.xml
+++ b/android/app/src/main/res/layout/fragment_policy.xml
@@ -6,23 +6,23 @@
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="io.highfidelity.hifiinterface.MainActivity"
- tools:showIn="@layout/activity_main">
+ android:background="@color/backgroundLight">
+ app:srcCompat="@drawable/hifi_header" />
+ android:textSize="12sp" />
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
index 6e756a85fa..8d351542e6 100644
--- a/android/app/src/main/res/values/colors.xml
+++ b/android/app/src/main/res/values/colors.xml
@@ -1,8 +1,8 @@
#ffffff
- #272727
- #000000
+ @color/backgroundLight
+ @color/backgroundDark#54D7FD#E3E3E3#575757
@@ -15,4 +15,5 @@
#9e9e9e#F2F2F2#FF7171
+ #33000000
diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml
index 440adcf6b9..a7640e4313 100644
--- a/android/app/src/main/res/values/dimens.xml
+++ b/android/app/src/main/res/values/dimens.xml
@@ -11,4 +11,7 @@
12dp12dp8dp
+ 40dp
+ 88dp
+ 372dp
\ No newline at end of file
diff --git a/android/app/src/main/res/values/preloaded_fonts.xml b/android/app/src/main/res/values/preloaded_fonts.xml
index 6f9d0e424e..11b7a7c9f7 100644
--- a/android/app/src/main/res/values/preloaded_fonts.xml
+++ b/android/app/src/main/res/values/preloaded_fonts.xml
@@ -2,6 +2,7 @@
@font/raleway_bold
+ @font/raleway_italic@font/raleway_light_italic@font/raleway_medium@font/raleway_semibold
From f9fc549e7d50893dd37f7c37386f608f6ef4c3c7 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Thu, 26 Apr 2018 11:49:28 -0300
Subject: [PATCH 08/80] Avoid switch from landscape to portrait during
bootstrap
---
android/app/src/main/AndroidManifest.xml | 2 +-
.../java/io/highfidelity/hifiinterface/InterfaceActivity.java | 3 +++
android/app/src/main/res/layout/activity_splash.xml | 2 +-
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 05d76598f9..cd298aad1e 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -47,7 +47,6 @@
android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
android:name=".InterfaceActivity"
android:label="@string/app_name"
- android:screenOrientation="landscape"
android:launchMode="singleTop"
>
@@ -72,6 +71,7 @@
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
index 1567c864e9..a48093eaf5 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
@@ -128,6 +128,9 @@ public class InterfaceActivity extends QtActivity {
@Override
protected void onStart() {
super.onStart();
+ if (!isLoading) {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ }
nativeEnterForeground();
}
diff --git a/android/app/src/main/res/layout/activity_splash.xml b/android/app/src/main/res/layout/activity_splash.xml
index b38fe3e53c..5b4f91e733 100644
--- a/android/app/src/main/res/layout/activity_splash.xml
+++ b/android/app/src/main/res/layout/activity_splash.xml
@@ -5,7 +5,7 @@
android:id="@+id/root_activity_splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@android:color/transparent">
+ android:background="@color/backgroundLight">
From 0d08bc6e7c19cd9e276c7c34af5cc5caed6d7f29 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Fri, 27 Apr 2018 12:38:38 -0300
Subject: [PATCH 09/80] Fix dimensions in android login
---
.../src/main/res/layout/fragment_login.xml | 35 ++++++++++---------
android/app/src/main/res/values/colors.xml | 2 +-
android/app/src/main/res/values/dimens.xml | 6 ++--
3 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/android/app/src/main/res/layout/fragment_login.xml b/android/app/src/main/res/layout/fragment_login.xml
index 481d133bc4..6b147e315d 100644
--- a/android/app/src/main/res/layout/fragment_login.xml
+++ b/android/app/src/main/res/layout/fragment_login.xml
@@ -32,12 +32,13 @@
+ app:layout_constraintTop_toBottomOf="@id/password"
+ app:layout_goneMarginTop="4dp"/>
#9e9e9e
#F2F2F2#FF7171
- #33000000
+ #292929
diff --git a/android/app/src/main/res/values/dimens.xml b/android/app/src/main/res/values/dimens.xml
index a7640e4313..d10b294587 100644
--- a/android/app/src/main/res/values/dimens.xml
+++ b/android/app/src/main/res/values/dimens.xml
@@ -11,7 +11,7 @@
12dp12dp8dp
- 40dp
- 88dp
- 372dp
+ 56dp
+ 101dp
+ 425dp
\ No newline at end of file
From c27f415fea2e28979cba0204940979049e78157a Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Fri, 27 Apr 2018 12:55:16 -0300
Subject: [PATCH 10/80] Fix dimensions in android privacy policy
---
android/app/src/main/res/layout/fragment_policy.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/android/app/src/main/res/layout/fragment_policy.xml b/android/app/src/main/res/layout/fragment_policy.xml
index 9009a29a6d..a08f2b9c9c 100644
--- a/android/app/src/main/res/layout/fragment_policy.xml
+++ b/android/app/src/main/res/layout/fragment_policy.xml
@@ -22,7 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
- android:layout_marginTop="162dp"
+ android:layout_marginTop="195dp"
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintBottom_toBottomOf="parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
From ce8bd1368510fc73348ffa8e9745731bd7a6a97a Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Fri, 27 Apr 2018 18:58:09 -0300
Subject: [PATCH 11/80] Cleanup android code
---
android/app/src/main/cpp/native.cpp | 4 --
.../hifiinterface/InterfaceActivity.java | 5 ---
.../hifiinterface/MainActivity.java | 40 ++++++-------------
interface/src/AndroidHelper.cpp | 4 --
interface/src/AndroidHelper.h | 2 -
5 files changed, 13 insertions(+), 42 deletions(-)
diff --git a/android/app/src/main/cpp/native.cpp b/android/app/src/main/cpp/native.cpp
index 79611dd695..cdecc12df6 100644
--- a/android/app/src/main/cpp/native.cpp
+++ b/android/app/src/main/cpp/native.cpp
@@ -182,10 +182,6 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnResu
JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnExitVr(JNIEnv* env, jobject obj) {
}
-JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeGoBackFromAndroidActivity(JNIEnv *env, jobject instance) {
- AndroidHelper::instance().goBackFromAndroidActivity();
-}
-
// HifiUtils
JNIEXPORT jstring JNICALL Java_io_highfidelity_hifiinterface_HifiUtils_getCurrentAddress(JNIEnv *env, jobject instance) {
QSharedPointer addressManager = DependencyManager::get();
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
index a48093eaf5..7b32f72148 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
@@ -41,11 +41,8 @@ public class InterfaceActivity extends QtActivity {
//private native void nativeOnResume();
private native void nativeOnDestroy();
private native void nativeGotoUrl(String url);
- private native void nativeGoBackFromAndroidActivity();
private native void nativeEnterBackground();
private native void nativeEnterForeground();
- //private native void saveRealScreenSize(int width, int height);
- //private native void setAppVersion(String version);
private native long nativeOnExitVr();
private AssetManager assetManager;
@@ -92,7 +89,6 @@ public class InterfaceActivity extends QtActivity {
Point size = new Point();
getWindowManager().getDefaultDisplay().getRealSize(size);
-// saveRealScreenSize(size.x, size.y);
try {
PackageInfo pInfo = this.getPackageManager().getPackageInfo(getPackageName(), 0);
@@ -201,7 +197,6 @@ public class InterfaceActivity extends QtActivity {
if (intent.hasExtra(DOMAIN_URL)) {
nativeGotoUrl(intent.getStringExtra(DOMAIN_URL));
}
- nativeGoBackFromAndroidActivity();
}
public void openAndroidActivity(String activityName) {
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
index 2298308541..ff5aff1f1c 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
@@ -82,54 +82,40 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private void loadHomeFragment() {
Fragment fragment = HomeFragment.newInstance();
- FragmentManager fragmentManager = getFragmentManager();
- FragmentTransaction ft = fragmentManager.beginTransaction();
- ft.replace(R.id.content_frame, fragment);
- ft.commit();
-
- setTitle(getString(R.string.home));
- mDrawerLayout.closeDrawer(mNavigationView);
+ loadFragment(fragment, getString(R.string.home), false);
}
private void loadLoginFragment() {
Fragment fragment = LoginFragment.newInstance();
- FragmentManager fragmentManager = getFragmentManager();
- FragmentTransaction ft = fragmentManager.beginTransaction();
- ft.replace(R.id.content_frame, fragment).addToBackStack(null);
- ft.commit();
-
- // update selected item title, then close the drawer
- setTitle(getString(R.string.login));
- mDrawerLayout.closeDrawer(mNavigationView);
+ loadFragment(fragment, getString(R.string.login), true);
}
private void loadGotoFragment() {
Fragment fragment = GotoFragment.newInstance();
- FragmentManager fragmentManager = getFragmentManager();
- FragmentTransaction ft = fragmentManager.beginTransaction();
- ft.replace(R.id.content_frame, fragment).addToBackStack(null);
- ft.commit();
-
- // update selected item title, then close the drawer
- setTitle(getString(R.string.go_to));
- mDrawerLayout.closeDrawer(mNavigationView);
+ loadFragment(fragment, getString(R.string.go_to), true);
}
private void loadPrivacyPolicyFragment() {
Fragment fragment = PolicyFragment.newInstance();
+ loadFragment(fragment, getString(R.string.privacyPolicy), true);
+ }
+
+ private void loadFragment(Fragment fragment, String title, boolean addToBackStack) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
- ft.replace(R.id.content_frame, fragment).addToBackStack(null);
+ ft.replace(R.id.content_frame, fragment);
+ if (addToBackStack) {
+ ft.addToBackStack(null);
+ }
ft.commit();
-
- // update selected item title, then close the drawer
- setTitle(getString(R.string.privacyPolicy));
+ setTitle(title);
mDrawerLayout.closeDrawer(mNavigationView);
}
+
private void updateLoginMenu() {
TextView loginOption = findViewById(R.id.login);
TextView logoutOption = findViewById(R.id.logout);
diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp
index 6dea89b1d0..cd1b4cb3a9 100644
--- a/interface/src/AndroidHelper.cpp
+++ b/interface/src/AndroidHelper.cpp
@@ -40,10 +40,6 @@ void AndroidHelper::notifyLoadComplete() {
emit qtAppLoadComplete();
}
-void AndroidHelper::goBackFromAndroidActivity() {
- emit backFromAndroidActivity();
-}
-
void AndroidHelper::notifyLoginComplete(bool success) {
emit loginComplete(success);
}
diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h
index 52d9c9ab12..e1d00a080b 100644
--- a/interface/src/AndroidHelper.h
+++ b/interface/src/AndroidHelper.h
@@ -25,7 +25,6 @@ public:
}
void requestActivity(const QString &activityName);
void notifyLoadComplete();
- void goBackFromAndroidActivity();
void notifyLoginComplete(bool success);
void performHapticFeedback(const QString& feedbackConstant);
@@ -36,7 +35,6 @@ public:
void operator=(AndroidHelper const&) = delete;
signals:
void androidActivityRequested(const QString &activityName);
- void backFromAndroidActivity();
void qtAppLoadComplete();
void loginComplete(bool success);
void hapticFeedbackRequested(const QString &feedbackConstant);
From 0f08bd8fa1f153b0d1d3dcb5186f262ac94b2786 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Wed, 2 May 2018 12:11:11 -0300
Subject: [PATCH 12/80] Use a single AccountManager for android.
---
android/app/src/main/cpp/native.cpp | 5 +-
.../hifiinterface/InterfaceActivity.java | 9 ++-
.../hifiinterface/MainActivity.java | 63 ++++++++++++++++++-
interface/src/AndroidHelper.cpp | 22 ++++---
interface/src/AndroidHelper.h | 9 ++-
interface/src/Application.cpp | 17 ++++-
interface/src/Application.h | 2 +-
interface/src/commerce/Wallet.cpp | 9 ++-
interface/src/ui/LoginDialog.cpp | 3 +
scripts/system/+android/actionbar.js | 2 +-
10 files changed, 114 insertions(+), 27 deletions(-)
diff --git a/android/app/src/main/cpp/native.cpp b/android/app/src/main/cpp/native.cpp
index cdecc12df6..bdbbe4193f 100644
--- a/android/app/src/main/cpp/native.cpp
+++ b/android/app/src/main/cpp/native.cpp
@@ -151,9 +151,10 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnCrea
unpackAndroidAssets();
qInstallMessageHandler(oldMessageHandler);
- QObject::connect(&AndroidHelper::instance(), &AndroidHelper::androidActivityRequested, [](const QString& a) {
+ QObject::connect(&AndroidHelper::instance(), &AndroidHelper::androidActivityRequested, [](const QString& a, const bool backToScene) {
QAndroidJniObject string = QAndroidJniObject::fromString(a);
- __interfaceActivity.callMethod("openAndroidActivity", "(Ljava/lang/String;)V", string.object());
+ jboolean jBackToScene = (jboolean) backToScene;
+ __interfaceActivity.callMethod("openAndroidActivity", "(Ljava/lang/String;Z)V", string.object(), jBackToScene);
});
QObject::connect(&AndroidHelper::instance(), &AndroidHelper::hapticFeedbackRequested, [](const QString &c) {
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
index 7b32f72148..fbefcf5b9a 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
@@ -199,10 +199,13 @@ public class InterfaceActivity extends QtActivity {
}
}
- public void openAndroidActivity(String activityName) {
+ public void openAndroidActivity(String activityName, boolean backToScene) {
switch (activityName) {
- case "Home": {
+ case "Home":
+ case "Login": {
Intent intent = new Intent(this, MainActivity.class);
+ intent.putExtra(MainActivity.EXTRA_FRAGMENT, activityName);
+ intent.putExtra(MainActivity.EXTRA_BACK_TO_SCENE, backToScene);
startActivity(intent);
break;
}
@@ -228,7 +231,7 @@ public class InterfaceActivity extends QtActivity {
@Override
public void onBackPressed() {
- openAndroidActivity("Home");
+ openAndroidActivity("Home", false);
}
}
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
index ff5aff1f1c..5fb93ba099 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
@@ -17,6 +17,7 @@ import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -40,6 +41,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
GotoFragment.OnGotoInteractionListener {
private static final int PROFILE_PICTURE_PLACEHOLDER = R.drawable.default_profile_avatar;
+ public static final String DEFAULT_FRAGMENT = "Home";
+ public static final String EXTRA_FRAGMENT = "fragment";
+ public static final String EXTRA_BACK_TO_SCENE = "backToScene";
+
private String TAG = "HighFidelity";
public native boolean nativeIsLoggedIn();
@@ -51,6 +56,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private ImageView mProfilePicture;
private TextView mDisplayName;
+ private boolean backToScene;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -76,7 +83,34 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(ContextCompat.getColor(this, R.color.statusbar_color));
- loadHomeFragment();
+ if (getIntent() != null) {
+ if (getIntent().hasExtra(EXTRA_FRAGMENT)) {
+ loadFragment(getIntent().getStringExtra(EXTRA_FRAGMENT));
+ } else {
+ loadFragment(DEFAULT_FRAGMENT);
+ }
+
+ if (getIntent().hasExtra(EXTRA_BACK_TO_SCENE)) {
+ backToScene = getIntent().getBooleanExtra(EXTRA_BACK_TO_SCENE, false);
+ }
+ }
+ }
+
+ private void loadFragment(String fragment) {
+ switch (fragment) {
+ case "Login":
+ loadLoginFragment();
+ break;
+ case "Home":
+ loadHomeFragment();
+ break;
+ case "Privacy Policy":
+ loadPrivacyPolicyFragment();
+ break;
+ default:
+ Log.e(TAG, "Unknown fragment " + fragment);
+ }
+
}
private void loadHomeFragment() {
@@ -200,6 +234,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
goToDomain(domainUrl);
}
+ private void goToLastLocation() {
+ goToDomain("");
+ }
+
private void goToDomain(String domainUrl) {
Intent intent = new Intent(this, InterfaceActivity.class);
intent.putExtra(InterfaceActivity.DOMAIN_URL, domainUrl);
@@ -212,6 +250,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
public void onLoginCompleted() {
loadHomeFragment();
updateLoginMenu();
+ if (backToScene) {
+ backToScene = false;
+ goToLastLocation();
+ }
}
public void handleUsernameChanged(String username) {
@@ -246,7 +288,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
@Override
public void onError(Exception e) {
mProfilePicture.setImageResource(PROFILE_PICTURE_PLACEHOLDER);
-
}
}
@@ -255,8 +296,24 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
int index = getFragmentManager().getBackStackEntryCount() - 1;
if (index > -1) {
super.onBackPressed();
+ if (backToScene) {
+ backToScene = false;
+ goToLastLocation();
+ }
} else {
- finishAffinity();
+ finishAffinity();
}
}
+
+ @Override
+ public void onSaveInstanceState(Bundle savedInstanceState) {
+ super.onSaveInstanceState(savedInstanceState);
+ savedInstanceState.putBoolean(EXTRA_BACK_TO_SCENE, backToScene);
+ }
+
+ @Override
+ protected void onRestoreInstanceState(Bundle savedInstanceState) {
+ super.onRestoreInstanceState(savedInstanceState);
+ backToScene = savedInstanceState.getBoolean(EXTRA_BACK_TO_SCENE, false);
+ }
}
diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp
index cd1b4cb3a9..2365a87a5f 100644
--- a/interface/src/AndroidHelper.cpp
+++ b/interface/src/AndroidHelper.cpp
@@ -14,7 +14,6 @@
AndroidHelper::AndroidHelper() :
_accountManager ()
{
- workerThread.start();
}
AndroidHelper::~AndroidHelper() {
@@ -22,18 +21,20 @@ AndroidHelper::~AndroidHelper() {
workerThread.wait();
}
+void AndroidHelper::init() {
+ qDebug() << "[LOGIN] AndroidHelper::init";
+ workerThread.start();
+ _accountManager = DependencyManager::get();
+ _accountManager->moveToThread(&workerThread);
+}
+
QSharedPointer AndroidHelper::getAccountManager() {
- if (!_accountManager) {
- _accountManager = QSharedPointer(new AccountManager, &QObject::deleteLater);
- _accountManager->setIsAgent(true);
- _accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL());
- _accountManager->moveToThread(&workerThread);
- }
+ assert(_accountManager);
return _accountManager;
}
-void AndroidHelper::requestActivity(const QString &activityName) {
- emit androidActivityRequested(activityName);
+void AndroidHelper::requestActivity(const QString &activityName, const bool backToScene) {
+ emit androidActivityRequested(activityName, backToScene);
}
void AndroidHelper::notifyLoadComplete() {
@@ -48,3 +49,6 @@ void AndroidHelper::performHapticFeedback(const QString& feedbackConstant) {
emit hapticFeedbackRequested(feedbackConstant);
}
+void AndroidHelper::showLoginDialog() {
+ emit androidActivityRequested("Login", true);
+}
diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h
index e1d00a080b..f3fe8389ce 100644
--- a/interface/src/AndroidHelper.h
+++ b/interface/src/AndroidHelper.h
@@ -23,7 +23,8 @@ public:
static AndroidHelper instance;
return instance;
}
- void requestActivity(const QString &activityName);
+ void init();
+ void requestActivity(const QString &activityName, const bool backToScene);
void notifyLoadComplete();
void notifyLoginComplete(bool success);
@@ -33,8 +34,12 @@ public:
AndroidHelper(AndroidHelper const&) = delete;
void operator=(AndroidHelper const&) = delete;
+
+public slots:
+ void showLoginDialog();
+
signals:
- void androidActivityRequested(const QString &activityName);
+ void androidActivityRequested(const QString &activityName, const bool backToScene);
void qtAppLoadComplete();
void loginComplete(bool success);
void hapticFeedbackRequested(const QString &feedbackConstant);
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 454848c87d..175b3b8492 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -830,7 +830,11 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
DependencyManager::set();
DependencyManager::set();
DependencyManager::set();
+#if defined(Q_OS_ANDROID)
+ DependencyManager::set(); // use the default user agent getter
+#else
DependencyManager::set(std::bind(&Application::getUserAgent, qApp));
+#endif
DependencyManager::set();
DependencyManager::set(ScriptEngine::CLIENT_SCRIPT);
DependencyManager::set();
@@ -1189,7 +1193,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
nodeList.data(), SLOT(reset()));
auto dialogsManager = DependencyManager::get();
+#if defined(Q_OS_ANDROID)
+ connect(accountManager.data(), &AccountManager::authRequired, this, []() {
+ AndroidHelper::instance().showLoginDialog();
+ });
+#else
connect(accountManager.data(), &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
+#endif
connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
// set the account manager's root URL and trigger a login request if we don't have the access token
@@ -2166,6 +2176,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID());
#if defined(Q_OS_ANDROID)
+ AndroidHelper::instance().init();
AndroidHelper::instance().notifyLoadComplete();
#endif
}
@@ -3673,7 +3684,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
#if defined(Q_OS_ANDROID)
if (event->key() == Qt::Key_Back) {
event->accept();
- openAndroidActivity("Home");
+ openAndroidActivity("Home", false);
}
#endif
_controllerScriptingInterface->emitKeyReleaseEvent(event); // send events to any registered scripts
@@ -7936,9 +7947,9 @@ void Application::saveNextPhysicsStats(QString filename) {
_physicsEngine->saveNextPhysicsStats(filename);
}
-void Application::openAndroidActivity(const QString& activityName) {
+void Application::openAndroidActivity(const QString& activityName, const bool backToScene) {
#if defined(Q_OS_ANDROID)
- AndroidHelper::instance().requestActivity(activityName);
+ AndroidHelper::instance().requestActivity(activityName, backToScene);
#endif
}
diff --git a/interface/src/Application.h b/interface/src/Application.h
index 50812a00ec..f22620a96a 100644
--- a/interface/src/Application.h
+++ b/interface/src/Application.h
@@ -403,7 +403,7 @@ public slots:
Q_INVOKABLE bool askBeforeSetAvatarUrl(const QString& avatarUrl) { return askToSetAvatarUrl(avatarUrl); }
- Q_INVOKABLE void openAndroidActivity(const QString& activityName);
+ Q_INVOKABLE void openAndroidActivity(const QString& activityName, const bool backToScene);
Q_INVOKABLE void performHapticFeedback(const QString& feedbackConstant);
private slots:
diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp
index 3e0e4adf18..57165ef90c 100644
--- a/interface/src/commerce/Wallet.cpp
+++ b/interface/src/commerce/Wallet.cpp
@@ -615,9 +615,12 @@ void Wallet::updateImageProvider() {
securityImageProvider->setSecurityImage(_securityImage);
// inform tablet security image provider
- QQmlEngine* tabletEngine = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system")->getTabletSurface()->getSurfaceContext()->engine();
- securityImageProvider = reinterpret_cast(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
- securityImageProvider->setSecurityImage(_securityImage);
+ OffscreenQmlSurface * tabletSurface = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system")->getTabletSurface();
+ if (tabletSurface) {
+ QQmlEngine* tabletEngine = tabletSurface->getSurfaceContext()->engine();
+ securityImageProvider = reinterpret_cast(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
+ securityImageProvider->setSecurityImage(_securityImage);
+ }
}
void Wallet::chooseSecurityImage(const QString& filename) {
diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp
index 2e40d3c087..39a5849d85 100644
--- a/interface/src/ui/LoginDialog.cpp
+++ b/interface/src/ui/LoginDialog.cpp
@@ -31,10 +31,13 @@ HIFI_QML_DEF(LoginDialog)
LoginDialog::LoginDialog(QQuickItem *parent) : OffscreenQmlDialog(parent) {
auto accountManager = DependencyManager::get();
+#if !defined(Q_OS_ANDROID)
connect(accountManager.data(), &AccountManager::loginComplete,
this, &LoginDialog::handleLoginCompleted);
connect(accountManager.data(), &AccountManager::loginFailed,
this, &LoginDialog::handleLoginFailed);
+#endif
+
}
void LoginDialog::showWithSelection()
diff --git a/scripts/system/+android/actionbar.js b/scripts/system/+android/actionbar.js
index c23ce89d4c..357e7853e7 100644
--- a/scripts/system/+android/actionbar.js
+++ b/scripts/system/+android/actionbar.js
@@ -43,7 +43,7 @@ function onBackPressed() {
}
function onBackClicked() {
- App.openAndroidActivity("Home");
+ App.openAndroidActivity("Home", false);
}
From a653c7df0b61a197b0b55b4f914e18b127e70b49 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Wed, 2 May 2018 14:59:46 -0300
Subject: [PATCH 13/80] Fix build
---
interface/src/Application.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/interface/src/Application.h b/interface/src/Application.h
index 998543d1d0..ea590545c2 100644
--- a/interface/src/Application.h
+++ b/interface/src/Application.h
@@ -405,7 +405,7 @@ public slots:
Q_INVOKABLE bool askBeforeSetAvatarUrl(const QString& avatarUrl) { return askToSetAvatarUrl(avatarUrl); }
void updateVerboseLogging();
- Q_INVOKABLE void openAndroidActivity(const QString& activityName);
+ Q_INVOKABLE void openAndroidActivity(const QString& activityName, const bool backToScene);
Q_INVOKABLE void performHapticFeedback(const QString& feedbackConstant);
private slots:
From 5558bb784a7242136f22dcc83cb7d1926265e46c Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Wed, 2 May 2018 16:59:26 -0300
Subject: [PATCH 14/80] Splash screen with High Fidelity logo
---
.../hifiinterface/InterfaceActivity.java | 10 ++--
.../hifiinterface/SplashActivity.java | 10 ++++
.../main/res/drawable/hifi_logo_splash.xml | 50 +++++++++++++++++++
.../src/main/res/layout/activity_splash.xml | 11 ++--
4 files changed, 70 insertions(+), 11 deletions(-)
create mode 100644 android/app/src/main/res/drawable/hifi_logo_splash.xml
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
index fbefcf5b9a..6a89a8a819 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
@@ -101,13 +101,9 @@ public class InterfaceActivity extends QtActivity {
final View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
// This is a workaround to hide the menu bar when the virtual keyboard is shown from Qt
- rootView.getViewTreeObserver().addOnGlobalLayoutListener(new android.view.ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- int heightDiff = rootView.getRootView().getHeight() - rootView.getHeight();
- if (getActionBar().isShowing()) {
- getActionBar().hide();
- }
+ rootView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
+ if (getActionBar() != null && getActionBar().isShowing()) {
+ getActionBar().hide();
}
});
startActivity(new Intent(this, SplashActivity.class));
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java
index 388592d2ed..484673bf4f 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/SplashActivity.java
@@ -3,6 +3,7 @@ package io.highfidelity.hifiinterface;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
+import android.view.View;
public class SplashActivity extends Activity {
@@ -20,6 +21,15 @@ public class SplashActivity extends Activity {
super.onStart();
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+ View decorView = getWindow().getDecorView();
+ // Hide the status bar.
+ int uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ decorView.setSystemUiVisibility(uiOptions);
+ }
+
@Override
protected void onStop() {
super.onStop();
diff --git a/android/app/src/main/res/drawable/hifi_logo_splash.xml b/android/app/src/main/res/drawable/hifi_logo_splash.xml
new file mode 100644
index 0000000000..919b2737e8
--- /dev/null
+++ b/android/app/src/main/res/drawable/hifi_logo_splash.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/layout/activity_splash.xml b/android/app/src/main/res/layout/activity_splash.xml
index 5b4f91e733..ed25797917 100644
--- a/android/app/src/main/res/layout/activity_splash.xml
+++ b/android/app/src/main/res/layout/activity_splash.xml
@@ -5,8 +5,11 @@
android:id="@+id/root_activity_splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/backgroundLight">
-
-
-
+ android:background="@android:color/black">
+
From ec838b141781ba1f4c5fde97d7272c2d6d9e7819 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Wed, 2 May 2018 18:51:44 -0300
Subject: [PATCH 15/80] Trying to fix non-android builds
---
interface/src/AndroidHelper.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp
index 2365a87a5f..7e2661e8e4 100644
--- a/interface/src/AndroidHelper.cpp
+++ b/interface/src/AndroidHelper.cpp
@@ -29,7 +29,7 @@ void AndroidHelper::init() {
}
QSharedPointer AndroidHelper::getAccountManager() {
- assert(_accountManager);
+ Q_ASSERT(_accountManager);
return _accountManager;
}
From a767540b76f59b9fd5dc76de68a953f07fcd094f Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Thu, 3 May 2018 17:53:18 -0300
Subject: [PATCH 16/80] Fix connection issue syncing two AccountManagers
---
interface/src/AndroidHelper.cpp | 16 ++++++++++++++--
libraries/networking/src/AccountManager.cpp | 14 ++++++++++++++
libraries/networking/src/AccountManager.h | 1 +
3 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp
index 7e2661e8e4..0d15d2b1b9 100644
--- a/interface/src/AndroidHelper.cpp
+++ b/interface/src/AndroidHelper.cpp
@@ -22,9 +22,21 @@ AndroidHelper::~AndroidHelper() {
}
void AndroidHelper::init() {
- qDebug() << "[LOGIN] AndroidHelper::init";
workerThread.start();
- _accountManager = DependencyManager::get();
+ _accountManager = QSharedPointer(new AccountManager, &QObject::deleteLater);
+ _accountManager->setIsAgent(true);
+ _accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL());
+ _accountManager->setSessionID(DependencyManager::get()->getSessionID());
+
+ connect(_accountManager.data(), &AccountManager::loginComplete, [](const QUrl& authURL) {
+ DependencyManager::get()->setAccountInfo(AndroidHelper::instance().getAccountManager()->getAccountInfo());
+ DependencyManager::get()->setAuthURL(authURL);
+ });
+
+ connect(_accountManager.data(), &AccountManager::logoutComplete, [] () {
+ DependencyManager::get()->logout();
+ });
+
_accountManager->moveToThread(&workerThread);
}
diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp
index 049129b2ba..e70e3e26d0 100644
--- a/libraries/networking/src/AccountManager.cpp
+++ b/libraries/networking/src/AccountManager.cpp
@@ -453,6 +453,20 @@ void AccountManager::removeAccountFromFile() {
<< "from settings file.";
}
+void AccountManager::setAccountInfo(const DataServerAccountInfo &newAccountInfo) {
+ _accountInfo = newAccountInfo;
+ _pendingPrivateKey.clear();
+ if (_isAgent && !_accountInfo.getAccessToken().token.isEmpty() && !_accountInfo.hasProfile()) {
+ // we are missing profile information, request it now
+ requestProfile();
+ }
+
+ // prepare to refresh our token if it is about to expire
+ if (needsToRefreshToken()) {
+ refreshAccessToken();
+ }
+}
+
bool AccountManager::hasValidAccessToken() {
if (_accountInfo.getAccessToken().token.isEmpty() || _accountInfo.getAccessToken().isExpired()) {
diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h
index 87b17d00d5..88ebaf5656 100644
--- a/libraries/networking/src/AccountManager.h
+++ b/libraries/networking/src/AccountManager.h
@@ -88,6 +88,7 @@ public:
void requestProfile();
DataServerAccountInfo& getAccountInfo() { return _accountInfo; }
+ void setAccountInfo(const DataServerAccountInfo &newAccountInfo);
static QJsonObject dataObjectFromResponse(QNetworkReply& requestReply);
From 868b58e66d9f8232c53c1ede78a5ae5fdf9be7eb Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Fri, 4 May 2018 18:01:01 -0300
Subject: [PATCH 17/80] Un-expose Application from javascript. Restore
displayplugin deactivation when goes to background
---
.../hifiinterface/InterfaceActivity.java | 1 +
interface/src/Application.cpp | 31 +++++++------------
interface/src/Application.h | 5 ---
.../scripting/WindowScriptingInterface.cpp | 23 ++++++++++++--
.../src/scripting/WindowScriptingInterface.h | 14 +++++++++
.../TouchscreenVirtualPadDevice.cpp | 7 +++++
.../TouchscreenVirtualPadDevice.h | 2 ++
libraries/ui/src/VirtualPadManager.cpp | 4 +++
libraries/ui/src/VirtualPadManager.h | 6 +++-
scripts/system/+android/actionbar.js | 4 +--
scripts/system/+android/audio.js | 2 +-
scripts/system/+android/modes.js | 2 +-
scripts/system/+android/radar.js | 4 +--
.../shapes/modules/createPalette.js | 2 +-
.../marketplace/shapes/modules/groups.js | 4 +--
.../marketplace/shapes/modules/preload.js | 4 +--
.../marketplace/shapes/modules/selection.js | 2 +-
.../marketplace/shapes/modules/toolIcon.js | 2 +-
.../marketplace/shapes/modules/toolsMenu.js | 10 +++---
.../marketplace/shapes/shapes.js | 2 +-
20 files changed, 84 insertions(+), 47 deletions(-)
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
index 6a89a8a819..b3edd59acc 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
@@ -198,6 +198,7 @@ public class InterfaceActivity extends QtActivity {
public void openAndroidActivity(String activityName, boolean backToScene) {
switch (activityName) {
case "Home":
+ case "Privacy Policy":
case "Login": {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(MainActivity.EXTRA_FRAGMENT, activityName);
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 0e39e9229f..f0838bae9f 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -2764,6 +2764,13 @@ void Application::initializeUi() {
}
if (TouchscreenVirtualPadDevice::NAME == inputPlugin->getName()) {
_touchscreenVirtualPadDevice = std::dynamic_pointer_cast(inputPlugin);
+#if defined(Q_OS_ANDROID)
+ auto& virtualPadManager = VirtualPad::Manager::instance();
+ connect(&virtualPadManager, &VirtualPad::Manager::hapticFeedbackRequested,
+ this, []() {
+ AndroidHelper::instance().performHapticFeedback("CONTEXT_CLICK");
+ });
+#endif
}
}
@@ -3766,7 +3773,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
#if defined(Q_OS_ANDROID)
if (event->key() == Qt::Key_Back) {
event->accept();
- openAndroidActivity("Home", false);
+ AndroidHelper::instance().requestActivity("Home", false);
}
#endif
_controllerScriptingInterface->emitKeyReleaseEvent(event); // send events to any registered scripts
@@ -6376,8 +6383,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
scriptEngine->registerGlobalObject("Wallet", DependencyManager::get().data());
scriptEngine->registerGlobalObject("AddressManager", DependencyManager::get().data());
- scriptEngine->registerGlobalObject("App", this);
-
qScriptRegisterMetaType(scriptEngine.data(), OverlayIDtoScriptValue, OverlayIDfromScriptValue);
DependencyManager::get()->registerMetaTypes(scriptEngine.data());
@@ -8083,32 +8088,18 @@ void Application::saveNextPhysicsStats(QString filename) {
_physicsEngine->saveNextPhysicsStats(filename);
}
-void Application::openAndroidActivity(const QString& activityName, const bool backToScene) {
-#if defined(Q_OS_ANDROID)
- AndroidHelper::instance().requestActivity(activityName, backToScene);
-#endif
-}
-
-void Application::performHapticFeedback(const QString& feedbackConstant) {
-#if defined(Q_OS_ANDROID)
- AndroidHelper::instance().performHapticFeedback(feedbackConstant);
-#endif
-}
-
#if defined(Q_OS_ANDROID)
void Application::enterBackground() {
QMetaObject::invokeMethod(DependencyManager::get().data(),
"stop", Qt::BlockingQueuedConnection);
- //GC: commenting it out until we fix it
- //getActiveDisplayPlugin()->deactivate();
+ getActiveDisplayPlugin()->deactivate();
}
void Application::enterForeground() {
QMetaObject::invokeMethod(DependencyManager::get().data(),
"start", Qt::BlockingQueuedConnection);
- //GC: commenting it out until we fix it
- /*if (!getActiveDisplayPlugin() || !getActiveDisplayPlugin()->activate()) {
+ if (!getActiveDisplayPlugin() || !getActiveDisplayPlugin()->activate()) {
qWarning() << "Could not re-activate display plugin";
- }*/
+ }
}
#endif
diff --git a/interface/src/Application.h b/interface/src/Application.h
index c610d9b19c..24bd6c255b 100644
--- a/interface/src/Application.h
+++ b/interface/src/Application.h
@@ -406,12 +406,7 @@ public slots:
void setIsServerlessMode(bool serverlessDomain);
void loadServerlessDomain(QUrl domainURL);
- Q_INVOKABLE bool askBeforeSetAvatarUrl(const QString& avatarUrl) { return askToSetAvatarUrl(avatarUrl); }
-
void updateVerboseLogging();
- Q_INVOKABLE void openAndroidActivity(const QString& activityName, const bool backToScene);
- Q_INVOKABLE void performHapticFeedback(const QString& feedbackConstant);
-
private slots:
void onDesktopRootItemCreated(QQuickItem* qmlContext);
diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp
index 9c46f9e98a..7dc9dd2137 100644
--- a/interface/src/scripting/WindowScriptingInterface.cpp
+++ b/interface/src/scripting/WindowScriptingInterface.cpp
@@ -15,12 +15,13 @@
#include
#include
#include
-
+#include
#include
#include
#include
-
+#include
+#include "AndroidHelper.h"
#include "Application.h"
#include "DomainHandler.h"
#include "MainWindow.h"
@@ -131,6 +132,24 @@ void WindowScriptingInterface::disconnectedFromDomain() {
emit domainChanged(QUrl());
}
+void WindowScriptingInterface::openUrl(const QUrl& url) {
+ if (!url.isEmpty()) {
+ if (url.scheme() == URL_SCHEME_HIFI) {
+ DependencyManager::get()->handleLookupString(url.toString());
+ } else {
+ // address manager did not handle - ask QDesktopServices to handle
+ QDesktopServices::openUrl(url);
+ }
+ }
+}
+
+void WindowScriptingInterface::openAndroidActivity(const QString& activityName, const bool backToScene) {
+#if defined(Q_OS_ANDROID)
+ AndroidHelper::instance().requestActivity(activityName, backToScene);
+#endif
+}
+
+
QString fixupPathForMac(const QString& directory) {
// On OS X `directory` does not work as expected unless a file is included in the path, so we append a bogus
// filename if the directory is valid.
diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h
index 0b766d2097..ff03b87bb2 100644
--- a/interface/src/scripting/WindowScriptingInterface.h
+++ b/interface/src/scripting/WindowScriptingInterface.h
@@ -504,6 +504,20 @@ public slots:
*/
int openMessageBox(QString title, QString text, int buttons, int defaultButton);
+ /**jsdoc
+ * Open the given resource in the Interface window or in a web browser depending on the url scheme
+ * @function Window.openUrl
+ * @param {string} url - The resource to open
+ */
+ void openUrl(const QUrl& url);
+
+ /**jsdoc
+ * (Android only) Open the requested Activity and optionally back to the scene when the activity is done
+ * @function Window.openAndroidActivity
+ * @param {string} activityName - The name of the activity to open. One of "Home", "Login" or "Privacy Policy"
+ */
+ void openAndroidActivity(const QString& activityName, const bool backToScene);
+
/**jsdoc
* Update the content of a message box that was opened with {@link Window.openMessageBox|openMessageBox}.
* @function Window.updateMessageBox
diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp
index 7ee2135325..a8e509b7ce 100644
--- a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp
+++ b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp
@@ -187,6 +187,13 @@ void TouchscreenVirtualPadDevice::InputDevice::update(float deltaTime, const con
_axisStateMap.clear();
}
+bool TouchscreenVirtualPadDevice::InputDevice::triggerHapticPulse(float strength, float duration, controller::Hand hand) {
+ auto& virtualPadManager = VirtualPad::Manager::instance();
+ virtualPadManager.requestHapticFeedback();
+ return true;
+}
+
+
void TouchscreenVirtualPadDevice::InputDevice::focusOutEvent() {
}
diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.h
index e7e540b503..ef1e7a4d89 100644
--- a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.h
+++ b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.h
@@ -63,6 +63,8 @@ protected:
// Device functions
virtual controller::Input::NamedVector getAvailableInputs() const override;
virtual QString getDefaultMappingConfig() const override;
+
+ virtual bool triggerHapticPulse(float strength, float duration, controller::Hand hand) override;
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
virtual void focusOutEvent() override;
diff --git a/libraries/ui/src/VirtualPadManager.cpp b/libraries/ui/src/VirtualPadManager.cpp
index dae19b52c2..e62a439ab8 100644
--- a/libraries/ui/src/VirtualPadManager.cpp
+++ b/libraries/ui/src/VirtualPadManager.cpp
@@ -84,6 +84,10 @@ namespace VirtualPad {
_jumpButtonPosition = point;
}
+ void Manager::requestHapticFeedback() {
+ emit hapticFeedbackRequested();
+ }
+
Instance* Manager::getLeftVirtualPad() {
return &_leftVPadInstance;
}
diff --git a/libraries/ui/src/VirtualPadManager.h b/libraries/ui/src/VirtualPadManager.h
index 6f7fbcc921..f5afde9a64 100644
--- a/libraries/ui/src/VirtualPadManager.h
+++ b/libraries/ui/src/VirtualPadManager.h
@@ -31,8 +31,8 @@ namespace VirtualPad {
};
class Manager : public QObject, public Dependency {
+ Q_OBJECT
SINGLETON_DEPENDENCY
-
Manager();
Manager(const Manager& other) = delete;
public:
@@ -46,6 +46,7 @@ namespace VirtualPad {
void setExtraBottomMargin(int margin);
glm::vec2 getJumpButtonPosition();
void setJumpButtonPosition(glm::vec2 point);
+ void requestHapticFeedback();
static const float DPI;
static const float BASE_DIAMETER_PIXELS;
@@ -56,6 +57,9 @@ namespace VirtualPad {
static const float JUMP_BTN_BOTTOM_MARGIN_PIXELS;
static const float JUMP_BTN_RIGHT_MARGIN_PIXELS;
+ signals:
+ void hapticFeedbackRequested();
+
private:
Instance _leftVPadInstance;
bool _enabled;
diff --git a/scripts/system/+android/actionbar.js b/scripts/system/+android/actionbar.js
index 357e7853e7..8c476933ef 100644
--- a/scripts/system/+android/actionbar.js
+++ b/scripts/system/+android/actionbar.js
@@ -39,11 +39,11 @@ function init() {
}
function onBackPressed() {
- App.performHapticFeedback("CONTEXT_CLICK");
+ Controller.triggerHapticPulse(Controller.findDevice("TouchscreenVirtualPad"), 0.1, 1.0, 0);
}
function onBackClicked() {
- App.openAndroidActivity("Home", false);
+ Window.openAndroidActivity("Home", false);
}
diff --git a/scripts/system/+android/audio.js b/scripts/system/+android/audio.js
index 5eb13a3198..6e0f0f7b03 100644
--- a/scripts/system/+android/audio.js
+++ b/scripts/system/+android/audio.js
@@ -49,7 +49,7 @@ function onMuteClicked() {
}
function onMutePressed() {
- App.performHapticFeedback("CONTEXT_CLICK");
+ Controller.triggerHapticPulse(Controller.findDevice("TouchscreenVirtualPad"), 0.1, 1.0, 0);
}
function onMuteToggled() {
diff --git a/scripts/system/+android/modes.js b/scripts/system/+android/modes.js
index c75377b976..941ecf7422 100644
--- a/scripts/system/+android/modes.js
+++ b/scripts/system/+android/modes.js
@@ -68,7 +68,7 @@ function shutdown() {
}
function modeButtonPressed() {
- App.performHapticFeedback("CONTEXT_CLICK");
+ Controller.triggerHapticPulse(Controller.findDevice("TouchscreenVirtualPad"), 0.1, 1.0, 0);
}
function modeButtonClicked() {
diff --git a/scripts/system/+android/radar.js b/scripts/system/+android/radar.js
index 455299dd5f..8d4c462f78 100644
--- a/scripts/system/+android/radar.js
+++ b/scripts/system/+android/radar.js
@@ -99,7 +99,7 @@ function actionOnObjectFromEvent(event) {
var entity = Entities.getEntityProperties(
entitiesByOverlayID[rayIntersection.overlayID],
[ "sourceUrl" ]);
- App.openUrl(entity.sourceUrl);
+ Window.openUrl(entity.sourceUrl);
return true;
}
}
@@ -110,7 +110,7 @@ function actionOnObjectFromEvent(event) {
if (rayIntersection.properties.type == "Web") {
printd("found web element to "
+ rayIntersection.properties.sourceUrl);
- App.openUrl(rayIntersection.properties.sourceUrl);
+ Window.openUrl(rayIntersection.properties.sourceUrl);
return true;
}
}
diff --git a/unpublishedScripts/marketplace/shapes/modules/createPalette.js b/unpublishedScripts/marketplace/shapes/modules/createPalette.js
index 38dad5b827..a7afc8a17e 100644
--- a/unpublishedScripts/marketplace/shapes/modules/createPalette.js
+++ b/unpublishedScripts/marketplace/shapes/modules/createPalette.js
@@ -466,7 +466,7 @@ CreatePalette = function (side, leftInputs, rightInputs, uiCommandCallback) {
if (handJointIndex === NONE) {
// Don't display if joint isn't available (yet) to attach to.
// User can clear this condition by toggling the app off and back on once avatar finishes loading.
- App.log(side, "ERROR: CreatePalette: Hand joint index isn't available!");
+ console.log(side, "ERROR: CreatePalette: Hand joint index isn't available!");
return;
}
diff --git a/unpublishedScripts/marketplace/shapes/modules/groups.js b/unpublishedScripts/marketplace/shapes/modules/groups.js
index 3153a622ee..3c96b014dd 100644
--- a/unpublishedScripts/marketplace/shapes/modules/groups.js
+++ b/unpublishedScripts/marketplace/shapes/modules/groups.js
@@ -180,11 +180,11 @@ Groups = function () {
}
if (entitiesSelectedCount === 0) {
- App.log("ERROR: Groups: Nothing to ungroup!");
+ console.log("ERROR: Groups: Nothing to ungroup!");
return;
}
if (entitiesSelectedCount === 1) {
- App.log("ERROR: Groups: Cannot ungroup sole entity!");
+ console.log("ERROR: Groups: Cannot ungroup sole entity!");
return;
}
diff --git a/unpublishedScripts/marketplace/shapes/modules/preload.js b/unpublishedScripts/marketplace/shapes/modules/preload.js
index e93ef9ac71..a075a0728c 100644
--- a/unpublishedScripts/marketplace/shapes/modules/preload.js
+++ b/unpublishedScripts/marketplace/shapes/modules/preload.js
@@ -54,7 +54,7 @@ Preload = (function () {
findURLsInObject(items[i]);
break;
default:
- App.log("ERROR: Cannot find URL in item type " + (typeof items[i]));
+ console.log("ERROR: Cannot find URL in item type " + (typeof items[i]));
}
}
@@ -120,7 +120,7 @@ Preload = (function () {
deleteTimer = Script.setTimeout(deleteOverlay, DELETE_INTERVAL);
}
} else {
- App.log("ERROR: Cannot preload asset " + url);
+ console.log("ERROR: Cannot preload asset " + url);
}
}
diff --git a/unpublishedScripts/marketplace/shapes/modules/selection.js b/unpublishedScripts/marketplace/shapes/modules/selection.js
index 955cde6bda..7849469733 100644
--- a/unpublishedScripts/marketplace/shapes/modules/selection.js
+++ b/unpublishedScripts/marketplace/shapes/modules/selection.js
@@ -654,7 +654,7 @@ SelectionManager = function (side) {
try {
userData = JSON.parse(userDataString);
} catch (e) {
- App.log(side, "ERROR: Invalid userData in entity being updated! " + userDataString);
+ console.log(side, "ERROR: Invalid userData in entity being updated! " + userDataString);
}
}
diff --git a/unpublishedScripts/marketplace/shapes/modules/toolIcon.js b/unpublishedScripts/marketplace/shapes/modules/toolIcon.js
index 143d768466..c8ea4d7f8b 100644
--- a/unpublishedScripts/marketplace/shapes/modules/toolIcon.js
+++ b/unpublishedScripts/marketplace/shapes/modules/toolIcon.js
@@ -108,7 +108,7 @@ ToolIcon = function (side) {
if (handJointIndex === -1) {
// Don't display if joint isn't available (yet) to attach to.
// User can clear this condition by toggling the app off and back on once avatar finishes loading.
- App.log(side, "ERROR: ToolIcon: Hand joint index isn't available!");
+ console.log(side, "ERROR: ToolIcon: Hand joint index isn't available!");
return;
}
diff --git a/unpublishedScripts/marketplace/shapes/modules/toolsMenu.js b/unpublishedScripts/marketplace/shapes/modules/toolsMenu.js
index 04bb88d040..78cafb4244 100644
--- a/unpublishedScripts/marketplace/shapes/modules/toolsMenu.js
+++ b/unpublishedScripts/marketplace/shapes/modules/toolsMenu.js
@@ -2929,7 +2929,7 @@ ToolsMenu = function (side, leftInputs, rightInputs, uiCommandCallback) {
break;
default:
- App.log(side, "ERROR: ToolsMenu: Unexpected command! " + command);
+ console.log(side, "ERROR: ToolsMenu: Unexpected command! " + command);
}
};
@@ -2946,7 +2946,7 @@ ToolsMenu = function (side, leftInputs, rightInputs, uiCommandCallback) {
Settings.setValue(optionsSettings[parameter].key, null); // Delete settings value.
break;
default:
- App.log(side, "ERROR: ToolsMenu: Unexpected command! " + command);
+ console.log(side, "ERROR: ToolsMenu: Unexpected command! " + command);
}
}
@@ -3199,7 +3199,7 @@ ToolsMenu = function (side, leftInputs, rightInputs, uiCommandCallback) {
// Nothing to do.
break;
default:
- App.log(side, "ERROR: ToolsMenu: Unexpected hover item! " + hoveredElementType);
+ console.log(side, "ERROR: ToolsMenu: Unexpected hover item! " + hoveredElementType);
}
// Update status variables.
@@ -3317,7 +3317,7 @@ ToolsMenu = function (side, leftInputs, rightInputs, uiCommandCallback) {
// Nothing to do.
break;
default:
- App.log(side, "ERROR: ToolsMenu: Unexpected hover item! " + hoveredElementType);
+ console.log(side, "ERROR: ToolsMenu: Unexpected hover item! " + hoveredElementType);
}
}
@@ -3566,7 +3566,7 @@ ToolsMenu = function (side, leftInputs, rightInputs, uiCommandCallback) {
if (handJointIndex === NONE) {
// Don't display if joint isn't available (yet) to attach to.
// User can clear this condition by toggling the app off and back on once avatar finishes loading.
- App.log(side, "ERROR: ToolsMenu: Hand joint index isn't available!");
+ console.log(side, "ERROR: ToolsMenu: Hand joint index isn't available!");
return;
}
diff --git a/unpublishedScripts/marketplace/shapes/shapes.js b/unpublishedScripts/marketplace/shapes/shapes.js
index bb35d9089e..c68e9927d7 100644
--- a/unpublishedScripts/marketplace/shapes/shapes.js
+++ b/unpublishedScripts/marketplace/shapes/shapes.js
@@ -1932,7 +1932,7 @@
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
if (!tablet) {
- App.log("ERROR: Tablet not found! App not started.");
+ console.log("ERROR: Tablet not found! App not started.");
return;
}
From 087c6ff730afe126fb19e09da05b6d312db27972 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Fri, 4 May 2018 18:45:39 -0300
Subject: [PATCH 18/80] Patch for secondary camera assert error on Android
---
interface/src/Application.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 08e28327e3..21257dffe6 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -5249,9 +5249,8 @@ void Application::updateSecondaryCameraViewFrustum() {
auto renderConfig = _renderEngine->getConfiguration();
assert(renderConfig);
auto camera = dynamic_cast(renderConfig->getConfig("SecondaryCamera"));
- assert(camera);
- if (!camera->isEnabled()) {
+ if (!camera || !camera->isEnabled()) {
_hasSecondaryViewFrustum = false;
return;
}
From e24523a29e292dd667580628676fa455ff349528 Mon Sep 17 00:00:00 2001
From: Thijs Wenker
Date: Fri, 11 May 2018 01:48:13 +0200
Subject: [PATCH 19/80] updated eslint config to be more sorted and complete
---
.eslintrc.js | 47 +++++++++++++++++++++++++++--------------------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/.eslintrc.js b/.eslintrc.js
index 5667a04984..ddcc03055a 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -6,34 +6,45 @@ module.exports = {
},
"globals": {
"Account": false,
+ "Agent": false,
"AnimationCache": false,
"Assets": false,
"Audio": false,
"AudioDevice": false,
"AudioEffectOptions": false,
+ "Avatar": false,
"AvatarList": false,
"AvatarManager": false,
"Camera": false,
"Clipboard": false,
+ "console": false,
+ "ContextOverlay": false,
"Controller": false,
- "DialogsManager": false,
"DebugDraw": false,
+ "DialogsManager": false,
"Entities": false,
+ "EntityViewer": false,
"FaceTracker": false,
"GlobalServices": false,
"HMD": false,
+ "LaserPointers": false,
+ "location": true,
"LODManager": false,
"Mat4": false,
"Menu": false,
"Messages": false,
"ModelCache": false,
+ "module": false,
"MyAvatar": false,
"Overlays": false,
"OverlayWebWindow": false,
"Paths": false,
+ "print": false,
"Quat": false,
"Rates": false,
+ "RayPick": false,
"Recording": false,
+ "Render": false,
"Resource": false,
"Reticle": false,
"Scene": false,
@@ -45,40 +56,36 @@ module.exports = {
"Tablet": false,
"TextureCache": false,
"Toolbars": false,
- "Uuid": false,
"UndoStack": false,
+ "Users": false,
"UserActivityLogger": false,
+ "Uuid": false,
"Vec3": false,
"WebSocket": false,
"WebWindow": false,
"Window": false,
- "XMLHttpRequest": false,
- "location": false,
- "print": false,
- "RayPick": false,
- "LaserPointers": false,
- "ContextOverlay": false,
- "module": false
+ "XMLHttpRequest": false
},
"rules": {
- "brace-style": ["error", "1tbs", { "allowSingleLine": false }],
- "comma-dangle": ["error", "never"],
+ "brace-style": ["error", "1tbs", {"allowSingleLine": false}],
"camelcase": ["error"],
+ "comma-dangle": ["error", "never"],
"curly": ["error", "all"],
"eqeqeq": ["error", "always"],
- "indent": ["error", 4, { "SwitchCase": 1 }],
- "keyword-spacing": ["error", { "before": true, "after": true }],
+ "indent": ["error", 4, {"SwitchCase": 1}],
+ "key-spacing": ["error", {"beforeColon": false, "afterColon": true, "mode": "strict"}],
+ "keyword-spacing": ["error", {"before": true, "after": true}],
"max-len": ["error", 128, 4],
"new-cap": ["error"],
+ "no-console": ["off"],
"no-floating-decimal": ["error"],
- //"no-magic-numbers": ["error", { "ignore": [0, 1], "ignoreArrayIndexes": true }],
- "no-multiple-empty-lines": ["error"],
+ // "no-magic-numbers": ["error", {"ignore": [0, 1], "ignoreArrayIndexes": true}],
"no-multi-spaces": ["error"],
- "no-unused-vars": ["error", { "args": "none", "vars": "local" }],
+ "no-multiple-empty-lines": ["error"],
+ "no-unused-vars": ["error", {"args": "none", "vars": "local"}],
"semi": ["error", "always"],
- "spaced-comment": ["error", "always", {
- "line": { "markers": ["/"] }
- }],
- "space-before-function-paren": ["error", {"anonymous": "ignore", "named": "never"}]
+ "space-before-blocks": ["error"],
+ "space-before-function-paren": ["error", {"anonymous": "ignore", "named": "never"}],
+ "spaced-comment": ["error", "always", {"line": {"markers": ["/"]}}]
}
};
From 3891ebe7039432c288414234a9c7cb46d025d775 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Fri, 11 May 2018 20:20:07 +1200
Subject: [PATCH 20/80] Agent API JSDoc stubs
---
assignment-client/src/Agent.h | 30 +++++++++++++++++++
libraries/networking/src/ThreadedAssignment.h | 20 +++++++++++++
tools/jsdoc/plugins/hifi.js | 1 +
3 files changed, 51 insertions(+)
diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h
index 0cdc9e0029..00ef034ad5 100644
--- a/assignment-client/src/Agent.h
+++ b/assignment-client/src/Agent.h
@@ -33,6 +33,19 @@
#include "entities/EntityTreeHeadlessViewer.h"
#include "avatars/ScriptableAvatar.h"
+/**jsdoc
+ * @namespace Agent
+ *
+ * @hifi-assignment-client
+ *
+ * @property {boolean} isAvatar
+ * @property {boolean} isPlayingAvatarSound Read-only.
+ * @property {boolean} isListeningToAudioStream
+ * @property {boolean} isNoiseGateEnabled
+ * @property {number} lastReceivedAudioLoudness Read-only.
+ * @property {Uuid} sessionUUID Read-only.
+ */
+
class Agent : public ThreadedAssignment {
Q_OBJECT
@@ -60,10 +73,27 @@ public:
virtual void aboutToFinish() override;
public slots:
+ /**jsdoc
+ * @function Agent.run
+ */
void run() override;
+
+ /**jsdoc
+ * @function Agent.playAvatarSound
+ * @param {object} avatarSound
+ */
void playAvatarSound(SharedSoundPointer avatarSound);
+ /**jsdoc
+ * @function Agent.setIsAvatar
+ * @param {boolean} isAvatar
+ */
void setIsAvatar(bool isAvatar);
+
+ /**jsdoc
+ * @function Agent.isAvatar
+ * @returns {boolean}
+ */
bool isAvatar() const { return _isAvatar; }
private slots:
diff --git a/libraries/networking/src/ThreadedAssignment.h b/libraries/networking/src/ThreadedAssignment.h
index 007e41a543..d19617357b 100644
--- a/libraries/networking/src/ThreadedAssignment.h
+++ b/libraries/networking/src/ThreadedAssignment.h
@@ -29,13 +29,30 @@ public:
void addPacketStatsAndSendStatsPacket(QJsonObject statsObject);
public slots:
+ // JSDoc: Overridden in Agent.h.
/// threaded run of assignment
virtual void run() = 0;
+
+ /**jsdoc
+ * @function Agent.stop
+ */
Q_INVOKABLE virtual void stop() { setFinished(true); }
+
+ /**jsdoc
+ * @function Agent.sendStatsPacket
+ */
virtual void sendStatsPacket();
+
+ /**jsdoc
+ * @function Agent.clearQueuedCheckIns
+ */
void clearQueuedCheckIns() { _numQueuedCheckIns = 0; }
signals:
+ /**jsdoc
+ * @function Agent.finished
+ * @returns {Signal}
+ */
void finished();
protected:
@@ -47,6 +64,9 @@ protected:
int _numQueuedCheckIns { 0 };
protected slots:
+ /**jsdoc
+ * @function Agent.domainSettingsRequestFailed
+ */
void domainSettingsRequestFailed();
private slots:
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index 5092e8b809..eb47bec430 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -20,6 +20,7 @@ exports.handlers = {
// directories to scan for jsdoc comments
var dirList = [
+ '../../assignment-client/src',
'../../interface/src',
'../../interface/src/assets',
'../../interface/src/audio',
From fb175d7110a8c2b4901cdaaefd9ef12c7fc55172 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Fri, 11 May 2018 20:36:10 +1200
Subject: [PATCH 21/80] AudioEffectOptions API JSDoc stubs
---
interface/src/scripting/Audio.h | 2 +-
libraries/audio/src/AudioEffectOptions.h | 31 ++++++++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h
index f0a4328c2f..8d16b06995 100644
--- a/interface/src/scripting/Audio.h
+++ b/interface/src/scripting/Audio.h
@@ -89,7 +89,7 @@ public:
/**jsdoc
* @function Audio.setReverbOptions
- * @param {} options
+ * @param {AudioEffectOptions} options
*/
Q_INVOKABLE void setReverbOptions(const AudioEffectOptions* options);
diff --git a/libraries/audio/src/AudioEffectOptions.h b/libraries/audio/src/AudioEffectOptions.h
index 9a65301473..09f8afc2b9 100644
--- a/libraries/audio/src/AudioEffectOptions.h
+++ b/libraries/audio/src/AudioEffectOptions.h
@@ -15,6 +15,37 @@
#include
#include
+/**jsdoc
+ * @class AudioEffectOptions
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ * @hifi-server-entity
+ * @hifi-assignment-client
+ *
+ * @property {number} bandwidth
+ * @property {number} preDelay
+ * @property {number} lateDelay
+ * @property {number} reverbTime
+ * @property {number} earlyDiffusion
+ * @property {number} lateDiffusion
+ * @property {number} roomSize
+ * @property {number} density
+ * @property {number} bassMult
+ * @property {number} bassFreq
+ * @property {number} highGain
+ * @property {number} highFreq
+ * @property {number} modRate
+ * @property {number} modDepth
+ * @property {number} earlyGain
+ * @property {number} lateGain
+ * @property {number} earlyMixLeft
+ * @property {number} earlyMixRight
+ * @property {number} lateMixLeft
+ * @property {number} lateMixRight
+ * @property {number} wetDryMix
+ */
+
class AudioEffectOptions : public QObject {
Q_OBJECT
From 42d0620fd1a0b4f04673cc3ac6362ce55e709953 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Fri, 11 May 2018 20:56:00 +1200
Subject: [PATCH 22/80] EntityViewer API JSDoc stubs
---
.../src/entities/EntityTreeHeadlessViewer.h | 7 ++
.../src/octree/OctreeHeadlessViewer.h | 72 +++++++++++++++++++
tools/jsdoc/plugins/hifi.js | 2 +
3 files changed, 81 insertions(+)
diff --git a/assignment-client/src/entities/EntityTreeHeadlessViewer.h b/assignment-client/src/entities/EntityTreeHeadlessViewer.h
index 17bb37186a..f4d5911821 100644
--- a/assignment-client/src/entities/EntityTreeHeadlessViewer.h
+++ b/assignment-client/src/entities/EntityTreeHeadlessViewer.h
@@ -23,6 +23,13 @@
class EntitySimulation;
+/**jsdoc
+ * @namespace EntityViewer
+ *
+ * @hifi-assignment-client
+ */
+// API functions are defined in OctreeHeadlessViewer.
+
// Generic client side Octree renderer class.
class EntityTreeHeadlessViewer : public OctreeHeadlessViewer {
Q_OBJECT
diff --git a/assignment-client/src/octree/OctreeHeadlessViewer.h b/assignment-client/src/octree/OctreeHeadlessViewer.h
index dea91ce66f..a1d0331e26 100644
--- a/assignment-client/src/octree/OctreeHeadlessViewer.h
+++ b/assignment-client/src/octree/OctreeHeadlessViewer.h
@@ -26,28 +26,100 @@ public:
static void trackIncomingOctreePacket(const QByteArray& packet, const SharedNodePointer& sendingNode, bool wasStatsPacket);
public slots:
+
+ /**jsdoc
+ * @function EntityViewer.queryOctree
+ */
void queryOctree();
+
// setters for camera attributes
+
+ /**jsdoc
+ * @function EntityViewer.setPosition
+ * @param {Vec3} position
+ */
void setPosition(const glm::vec3& position) { _hasViewFrustum = true; _viewFrustum.setPosition(position); }
+
+ /**jsdoc
+ * @function EntityViewer.setOrientation
+ * @param {Quat} orientation
+ */
void setOrientation(const glm::quat& orientation) { _hasViewFrustum = true; _viewFrustum.setOrientation(orientation); }
+
+ /**jsdoc
+ * @function EntityViewer.setCenterRadius
+ * @param {number} radius
+ */
void setCenterRadius(float radius) { _hasViewFrustum = true; _viewFrustum.setCenterRadius(radius); }
+
+ /**jsdoc
+ * @function EntityViewer.setKeyholeRadius
+ * @param {number} radius
+ * @deprecated Use {@link EntityViewer.setCenterRadius|setCenterRadius} instead.
+ */
void setKeyholeRadius(float radius) { _hasViewFrustum = true; _viewFrustum.setCenterRadius(radius); } // TODO: remove this legacy support
+
// setters for LOD and PPS
+
+ /**jsdoc
+ * @function EntityViewer.setVoxelSizeScale
+ * @param {number} sizeScale
+ */
void setVoxelSizeScale(float sizeScale) { _octreeQuery.setOctreeSizeScale(sizeScale) ; }
+
+ /**jsdoc
+ * @function EntityViewer.setBoundaryLevelAdjust
+ * @param {number} boundaryLevelAdjust
+ */
void setBoundaryLevelAdjust(int boundaryLevelAdjust) { _octreeQuery.setBoundaryLevelAdjust(boundaryLevelAdjust); }
+
+ /**jsdoc
+ * @function EntityViewer.setMaxPacketsPerSecond
+ * @param {number} maxPacketsPerSecond
+ */
void setMaxPacketsPerSecond(int maxPacketsPerSecond) { _octreeQuery.setMaxQueryPacketsPerSecond(maxPacketsPerSecond); }
// getters for camera attributes
+
+ /**jsdoc
+ * @function EntityViewer.getPosition
+ * @returns {Vec3}
+ */
const glm::vec3& getPosition() const { return _viewFrustum.getPosition(); }
+
+ /**jsdoc
+ * @function EntityViewer.getOrientation
+ * @returns {Quat}
+ */
const glm::quat& getOrientation() const { return _viewFrustum.getOrientation(); }
+
// getters for LOD and PPS
+
+ /**jsdoc
+ * @function EntityViewer.getVoxelSizeScale
+ * @returns {number}
+ */
float getVoxelSizeScale() const { return _octreeQuery.getOctreeSizeScale(); }
+
+ /**jsdoc
+ * @function EntityViewer.
+ * @returns {number}
+ */
int getBoundaryLevelAdjust() const { return _octreeQuery.getBoundaryLevelAdjust(); }
+ /**jsdoc
+ * @function EntityViewer.getMaxPacketsPerSecond
+ * @returns {number}
+ */
int getMaxPacketsPerSecond() const { return _octreeQuery.getMaxQueryPacketsPerSecond(); }
+
+ /**jsdoc
+ * @function EntityViewer.getOctreeElementsCount
+ * @returns {number}
+ */
unsigned getOctreeElementsCount() const { return _tree->getOctreeElementsCount(); }
private:
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index eb47bec430..de53f52f32 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -21,6 +21,8 @@ exports.handlers = {
// directories to scan for jsdoc comments
var dirList = [
'../../assignment-client/src',
+ '../../assignment-client/src/entities',
+ '../../assignment-client/src/octree',
'../../interface/src',
'../../interface/src/assets',
'../../interface/src/audio',
From 496154fdbee616d062e7b42551db68c732249870 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Fri, 11 May 2018 21:07:12 +1200
Subject: [PATCH 23/80] File API JSDoc stubs
---
.../src/FileScriptingInterface.h | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/libraries/script-engine/src/FileScriptingInterface.h b/libraries/script-engine/src/FileScriptingInterface.h
index 5cbe417130..7b833399e0 100644
--- a/libraries/script-engine/src/FileScriptingInterface.h
+++ b/libraries/script-engine/src/FileScriptingInterface.h
@@ -16,6 +16,15 @@
#include
#include
+/**jsdoc
+ * @namespace File
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ * @hifi-server-entity
+ * @hifi-assignment-client
+ */
+
class FileScriptingInterface : public QObject {
Q_OBJECT
@@ -23,11 +32,41 @@ public:
FileScriptingInterface(QObject* parent);
public slots:
+
+ /**jsdoc
+ * @function File.convertUrlToPath
+ * @param {string} url
+ * @returns {string}
+ */
QString convertUrlToPath(QUrl url);
+
+ /**jsdoc
+ * @function File.runUnzip
+ * @param {string} path
+ * @param {string} url
+ * @param {boolean} autoAdd
+ * @param {boolean} isZip
+ * @param {boolean} isBlocks
+ */
void runUnzip(QString path, QUrl url, bool autoAdd, bool isZip, bool isBlocks);
+
+ /**jsdoc
+ * @function File.getTempDir
+ * @returns {string}
+ */
QString getTempDir();
signals:
+
+ /**jsdoc
+ * @function File.unzipResult
+ * @param {string} zipFile
+ * @param {string} unzipFile
+ * @param {boolean} autoAdd
+ * @param {boolean} isZip
+ * @param {boolean} isBlocks
+ * @returns {Signal}
+ */
void unzipResult(QString zipFile, QStringList unzipFile, bool autoAdd, bool isZip, bool isBlocks);
private:
From e255fa3863d61a27189148d46947b82d751c1be1 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Fri, 11 May 2018 21:08:57 +1200
Subject: [PATCH 24/80] JSDoc typos
---
assignment-client/src/octree/OctreeHeadlessViewer.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/assignment-client/src/octree/OctreeHeadlessViewer.h b/assignment-client/src/octree/OctreeHeadlessViewer.h
index a1d0331e26..a2a49dceb8 100644
--- a/assignment-client/src/octree/OctreeHeadlessViewer.h
+++ b/assignment-client/src/octree/OctreeHeadlessViewer.h
@@ -105,10 +105,11 @@ public slots:
float getVoxelSizeScale() const { return _octreeQuery.getOctreeSizeScale(); }
/**jsdoc
- * @function EntityViewer.
+ * @function EntityViewer.getBoundaryLevelAdjust
* @returns {number}
*/
int getBoundaryLevelAdjust() const { return _octreeQuery.getBoundaryLevelAdjust(); }
+
/**jsdoc
* @function EntityViewer.getMaxPacketsPerSecond
* @returns {number}
From 6d000f3362d6c08534887dcbb7a8992ec8eeb30a Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sat, 12 May 2018 11:41:42 +1200
Subject: [PATCH 25/80] JSDoc parameter for AudioEffectOptions constructor
---
libraries/audio/src/AudioEffectOptions.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/libraries/audio/src/AudioEffectOptions.h b/libraries/audio/src/AudioEffectOptions.h
index 09f8afc2b9..18e019731e 100644
--- a/libraries/audio/src/AudioEffectOptions.h
+++ b/libraries/audio/src/AudioEffectOptions.h
@@ -17,6 +17,7 @@
/**jsdoc
* @class AudioEffectOptions
+ * @param {object} [properties=null]
*
* @hifi-interface
* @hifi-client-entity
From a2bb9de4416d5589f692651c97dd38572a0b4531 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sat, 12 May 2018 12:53:43 +1200
Subject: [PATCH 26/80] Graphics API JSDoc stubs
---
.../src/graphics-scripting/Forward.h | 26 ++++++++++++++-
.../GraphicsScriptingInterface.cpp | 11 +++++++
.../GraphicsScriptingInterface.h | 32 +++++++++++++------
.../src/graphics-scripting/ScriptableMesh.h | 4 +++
.../graphics-scripting/ScriptableMeshPart.h | 6 ++++
.../src/graphics-scripting/ScriptableModel.h | 2 +-
libraries/graphics/src/graphics/Geometry.h | 17 ++++++++++
tools/jsdoc/plugins/hifi.js | 1 +
8 files changed, 88 insertions(+), 11 deletions(-)
diff --git a/libraries/graphics-scripting/src/graphics-scripting/Forward.h b/libraries/graphics-scripting/src/graphics-scripting/Forward.h
index ed8e96a12f..104674eddc 100644
--- a/libraries/graphics-scripting/src/graphics-scripting/Forward.h
+++ b/libraries/graphics-scripting/src/graphics-scripting/Forward.h
@@ -36,6 +36,30 @@ namespace scriptable {
using ModelProviderPointer = std::shared_ptr;
using WeakModelProviderPointer = std::weak_ptr;
+ /**jsdoc
+ * @typedef {object} Graphics.Material
+ * @property {string} name
+ * @property {string} model
+ * @property {number} opacity
+ * @property {number} roughness
+ * @property {number} metallic
+ * @property {number} scattering
+ * @property {boolean} unlit
+ * @propety {Vec3} emissive
+ * @propety {Vec3} albedo
+ * @property {string} emissiveMap
+ * @property {string} albedoMap
+ * @property {string} opacityMap
+ * @property {string} metallicMap
+ * @property {string} specularMap
+ * @property {string} roughnessMap
+ * @property {string} glossMap
+ * @property {string} normalMap
+ * @property {string} bumpMap
+ * @property {string} occlusionMap
+ * @property {string} lightmapMap
+ * @property {string} scatteringMap
+ */
class ScriptableMaterial {
public:
ScriptableMaterial() {}
@@ -68,7 +92,7 @@ namespace scriptable {
/**jsdoc
* @typedef {object} Graphics.MaterialLayer
- * @property {Material} material - This layer's material.
+ * @property {Graphics.Material} material - This layer's material.
* @property {number} priority - The priority of this layer. If multiple materials are applied to a mesh part, only the highest priority layer is used.
*/
class ScriptableMaterialLayer {
diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp
index 20b54b02c9..6fd0017ae2 100644
--- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp
+++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.cpp
@@ -166,6 +166,17 @@ bool GraphicsScriptingInterface::updateMeshPart(scriptable::ScriptableMeshPointe
scriptable::ScriptableMeshPointer GraphicsScriptingInterface::newMesh(const QVariantMap& ifsMeshData) {
// TODO: this is bare-bones way for now to improvise a new mesh from the scripting side
// in the future we want to support a formal C++ structure data type here instead
+
+ /**jsdoc
+ * @typedef {object} Graphics.IFSData
+ * @property {string} [name=""] - mesh name (useful for debugging / debug prints).
+ * @property {string} [topology=""]
+ * @property {number[]} indices - vertex indices to use for the mesh faces.
+ * @property {Vec3[]} vertices - vertex positions (model space)
+ * @property {Vec3[]} [normals=[]] - vertex normals (normalized)
+ * @property {Vec3[]} [colors=[]] - vertex colors (normalized)
+ * @property {Vec2[]} [texCoords0=[]] - vertex texture coordinates (normalized)
+ */
QString meshName = ifsMeshData.value("name").toString();
QString topologyName = ifsMeshData.value("topology").toString();
QVector indices = buffer_helpers::variantToVector(ifsMeshData.value("indices"));
diff --git a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h
index b88c6345cf..1ec60c4244 100644
--- a/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h
+++ b/libraries/graphics-scripting/src/graphics-scripting/GraphicsScriptingInterface.h
@@ -46,10 +46,28 @@ public slots:
*/
scriptable::ScriptableModelPointer getModel(QUuid uuid);
+ /**jsdoc
+ * @function Graphics.updateModel
+ * @param {Uuid} id
+ * @param {Graphics.Model} model
+ * @returns {boolean}
+ */
bool updateModel(QUuid uuid, const scriptable::ScriptableModelPointer& model);
+ /**jsdoc
+ * @function Graphics.canUpdateModel
+ * @param {Uuid} id
+ * @param {number} [meshIndex=-1]
+ * @param {number} [partNumber=-1]
+ * @returns {boolean}
+ */
bool canUpdateModel(QUuid uuid, int meshIndex = -1, int partNumber = -1);
+ /**jsdoc
+ * @function Graphics.newModel
+ * @param {Graphics.Mesh[]} meshes
+ * @returns {Graphics.Model}
+ */
scriptable::ScriptableModelPointer newModel(const scriptable::ScriptableMeshes& meshes);
/**jsdoc
@@ -59,15 +77,6 @@ public slots:
* @param {Graphics.IFSData} ifsMeshData Index-Faced Set (IFS) arrays used to create the new mesh.
* @returns {Graphics.Mesh} the resulting Mesh / Mesh Part object
*/
- /**jsdoc
- * @typedef {object} Graphics.IFSData
- * @property {string} [name] - mesh name (useful for debugging / debug prints).
- * @property {number[]} indices - vertex indices to use for the mesh faces.
- * @property {Vec3[]} vertices - vertex positions (model space)
- * @property {Vec3[]} [normals] - vertex normals (normalized)
- * @property {Vec3[]} [colors] - vertex colors (normalized)
- * @property {Vec2[]} [texCoords0] - vertex texture coordinates (normalized)
- */
scriptable::ScriptableMeshPointer newMesh(const QVariantMap& ifsMeshData);
#ifdef SCRIPTABLE_MESH_TODO
@@ -77,6 +86,11 @@ public slots:
bool updateMeshPart(scriptable::ScriptableMeshPointer mesh, scriptable::ScriptableMeshPartPointer part);
#endif
+ /**jsdoc
+ * @function Graphics.exportModelToOBJ
+ * @param {Graphics.Model} model
+ * @returns {string}
+ */
QString exportModelToOBJ(const scriptable::ScriptableModel& in);
private:
diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.h
index 62a67aa5e6..dcb1c53759 100644
--- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.h
+++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMesh.h
@@ -36,6 +36,10 @@ namespace scriptable {
* @property {number} numIndices - Total number of vertex indices in the mesh.
* @property {number} numVertices - Total number of vertices in the Mesh.
* @property {number} numAttributes - Number of currently defined vertex attributes.
+ * @property {boolean} valid
+ * @property {boolean} strong
+ * @property {object} extents
+ * @property {object} bufferFormats
*/
class ScriptableMesh : public ScriptableMeshBase, QScriptable {
Q_OBJECT
diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMeshPart.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMeshPart.h
index dd71d9b998..7352fcd0f6 100644
--- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableMeshPart.h
+++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableMeshPart.h
@@ -12,7 +12,11 @@
namespace scriptable {
/**jsdoc
* @typedef {object} Graphics.MeshPart
+ * @property {boolean} valid
* @property {number} partIndex - The part index (within the containing Mesh).
+ * @property {number} firstVertexIndex
+ * @property {number} baseVertexIndex
+ * @property {number} lastVertexIndex
* @property {Graphics.Topology} topology - element interpretation (currently only 'triangles' is supported).
* @property {string[]} attributeNames - Vertex attribute names (color, normal, etc.)
* @property {number} numIndices - Number of vertex indices that this mesh part refers to.
@@ -20,6 +24,8 @@ namespace scriptable {
* @property {number} numFaces - Number of faces represented by the mesh part (numIndices / numVerticesPerFace).
* @property {number} numVertices - Total number of vertices in the containing Mesh.
* @property {number} numAttributes - Number of currently defined vertex attributes.
+ * @property {object} extents
+ * @property {object} bufferFormats
*/
class ScriptableMeshPart : public QObject, QScriptable {
diff --git a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h
index ac0b7b9623..7d1ca5f560 100644
--- a/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h
+++ b/libraries/graphics-scripting/src/graphics-scripting/ScriptableModel.h
@@ -21,7 +21,7 @@ namespace scriptable {
* @property {Uuid} objectID - UUID of corresponding inworld object (if model is associated)
* @property {number} numMeshes - The number of submeshes contained in the model.
* @property {Graphics.Mesh[]} meshes - Array of submesh references.
- * @property {Object.} materialLayers - Map of materials layer lists. You can look up a material layer list by mesh part number or by material name.
+ * @property {Object.} materialLayers - Map of materials layer lists. You can look up a material layer list by mesh part number or by material name.
* @property {string[]} materialNames - Array of all the material names used by the mesh parts of this model, in order (e.g. materialNames[0] is the name of the first mesh part's material).
*/
diff --git a/libraries/graphics/src/graphics/Geometry.h b/libraries/graphics/src/graphics/Geometry.h
index 485542d26b..eddfdbd1b6 100755
--- a/libraries/graphics/src/graphics/Geometry.h
+++ b/libraries/graphics/src/graphics/Geometry.h
@@ -76,6 +76,23 @@ public:
// Access vertex position value
const Vec3& getPos(Index index) const { return _vertexBuffer.get(index); }
+ /**jsdoc
+ *
+ *
+ *
Value
Description
+ *
+ *
+ *
0
Points.
+ *
1
Lines.
+ *
2
Line strip.
+ *
3
Triangles.
+ *
4
Triangle strip.
+ *
5
Quads.
+ *
6
Quad strip.
+ *
+ *
+ * @typedef {number} Graphics.Topology
+ */
enum Topology {
POINTS = 0,
LINES,
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index de53f52f32..8606007b89 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -44,6 +44,7 @@ exports.handlers = {
'../../libraries/controllers/src/controllers/impl/',
'../../libraries/display-plugins/src/display-plugins/',
'../../libraries/entities/src',
+ '../../libraries/graphics/src/graphics/',
'../../libraries/graphics-scripting/src/graphics-scripting/',
'../../libraries/input-plugins/src/input-plugins',
'../../libraries/model-networking/src/model-networking/',
From bf7863ad10ee2a0ae0ee0a827bf45c138f00f3e2 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sat, 12 May 2018 14:23:03 +1200
Subject: [PATCH 27/80] LocationBookmarks API JSDoc stubs
---
interface/src/Bookmarks.h | 3 +++
interface/src/LocationBookmarks.h | 16 ++++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/interface/src/Bookmarks.h b/interface/src/Bookmarks.h
index 7bd32ce7f1..dc08d4b279 100644
--- a/interface/src/Bookmarks.h
+++ b/interface/src/Bookmarks.h
@@ -51,6 +51,9 @@ protected slots:
/**jsdoc
* @function AvatarBookmarks.deleteBookmark
*/
+ /**jsdoc
+ * @function LocationBookmarks.deleteBookmark
+ */
void deleteBookmark();
private:
diff --git a/interface/src/LocationBookmarks.h b/interface/src/LocationBookmarks.h
index 39abea9ba4..70ea50e2e7 100644
--- a/interface/src/LocationBookmarks.h
+++ b/interface/src/LocationBookmarks.h
@@ -16,6 +16,13 @@
#include "Bookmarks.h"
+/**jsdoc
+ * @namespace LocationBookmarks
+ *
+ * @hifi-client-entity
+ * @hifi-interface
+ */
+
class LocationBookmarks : public Bookmarks, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
@@ -27,7 +34,16 @@ public:
static const QString HOME_BOOKMARK;
public slots:
+
+ /**jsdoc
+ * @function LocationBookmarks.addBookmark
+ */
void addBookmark();
+
+ /**jsdoc
+ * @function LocationBookmarks.setHomeLocationToAddress
+ * @param {string} address
+ */
void setHomeLocationToAddress(const QVariant& address);
protected:
From 6e1a091447f7416bc87b08df19b7d2c9f1387f8d Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sat, 12 May 2018 14:44:38 +1200
Subject: [PATCH 28/80] Mat4 API JSDoc stubs
---
libraries/script-engine/src/Mat4.h | 114 +++++++++++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/libraries/script-engine/src/Mat4.h b/libraries/script-engine/src/Mat4.h
index ceeea3ccec..288a101234 100644
--- a/libraries/script-engine/src/Mat4.h
+++ b/libraries/script-engine/src/Mat4.h
@@ -21,33 +21,147 @@
#include
#include "RegisteredMetaTypes.h"
+/**jsdoc
+ * @namespace Mat4
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ * @hifi-server-entity
+ * @hifi-assignment-client
+ */
+
/// Scriptable Mat4 object. Used exclusively in the JavaScript API
class Mat4 : public QObject, protected QScriptable {
Q_OBJECT
public slots:
+
+ /**jsdoc
+ * @function Mat4.multiply
+ * @param {Mat4} m1
+ * @param {Mat4} m2
+ * @returns {Mat4}
+ */
glm::mat4 multiply(const glm::mat4& m1, const glm::mat4& m2) const;
+
+ /**jsdoc
+ * @function Mat4.createFromRotAndTrans
+ * @param {Quat} rot
+ * @param {Vec3} trans
+ * @returns {Mat4}
+ */
glm::mat4 createFromRotAndTrans(const glm::quat& rot, const glm::vec3& trans) const;
+
+ /**jsdoc
+ * @function Mat4.createFromScaleRotAndTrans
+ * @param {Vec3} scale
+ * @param {Quat} rot
+ * @param {Vec3} trans
+ * @returns {Mat4}
+ */
glm::mat4 createFromScaleRotAndTrans(const glm::vec3& scale, const glm::quat& rot, const glm::vec3& trans) const;
+
+ /**jsdoc
+ * @function Mat4.createFromColumns
+ * @param {Vec4} col0
+ * @param {Vec4} col1
+ * @param {Vec4} col2
+ * @param {Vec4} col
+ * @returns {Mat4}
+ */
glm::mat4 createFromColumns(const glm::vec4& col0, const glm::vec4& col1, const glm::vec4& col2, const glm::vec4& col3) const;
+
+ /**jsdoc
+ * @function Mat4.createFromArray
+ * @param {number[]} numbers
+ * @returns {Mat4}
+ */
glm::mat4 createFromArray(const QVector& floats) const;
+
+ /**jsdoc
+ * @function Mat4.extractTranslation
+ * @param {Mat4} m
+ * @returns {Vec3}
+ */
glm::vec3 extractTranslation(const glm::mat4& m) const;
+
+ /**jsdoc
+ * @function Mat4.extractRotation
+ * @param {Mat4} m
+ * @returns {Vec3}
+ */
glm::quat extractRotation(const glm::mat4& m) const;
+
+ /**jsdoc
+ * @function Mat4.extractScale
+ * @param {Mat4} m
+ * @returns {Vec3}
+ */
glm::vec3 extractScale(const glm::mat4& m) const;
+
+ /**jsdoc
+ * @function Mat4.transformPoint
+ * @param {Mat4} m
+ * @param {Vec3} point
+ * @returns {Vec3}
+ */
glm::vec3 transformPoint(const glm::mat4& m, const glm::vec3& point) const;
+
+ /**jsdoc
+ * @function Mat4.transformVector
+ * @param {Mat4} m
+ * @param {Vec3} vector
+ * @returns {Vec3}
+ */
glm::vec3 transformVector(const glm::mat4& m, const glm::vec3& vector) const;
+
+ /**jsdoc
+ * @function Mat4.inverse
+ * @param {Mat4} m
+ * @returns {Mat4}
+ */
glm::mat4 inverse(const glm::mat4& m) const;
+
+ /**jsdoc
+ * @function Mat4.getFront
+ * @param {Mat4} m
+ * @returns {Vec3}
+ */
// redundant, calls getForward which better describes the returned vector as a direction
glm::vec3 getFront(const glm::mat4& m) const { return getForward(m); }
+
+ /**jsdoc
+ * @function Mat4.getForward
+ * @param {Mat4} m
+ * @returns {Vec3}
+ */
glm::vec3 getForward(const glm::mat4& m) const;
+
+ /**jsdoc
+ * @function Mat4.getRight
+ * @param {Mat4} m
+ * @returns {Vec3}
+ */
glm::vec3 getRight(const glm::mat4& m) const;
+
+ /**jsdoc
+ * @function Mat4.getUp
+ * @param {Mat4} m
+ * @returns {Vec3}
+ */
glm::vec3 getUp(const glm::mat4& m) const;
+ /**jsdoc
+ * @function Mat4.print
+ * @param {string} label
+ * @param {Mat4} m
+ * @param {boolean} [transpose=false]
+ */
void print(const QString& label, const glm::mat4& m, bool transpose = false) const;
};
From 841161068c63f0cf4489abcfdf831087f775c171 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sat, 12 May 2018 15:01:52 +1200
Subject: [PATCH 29/80] Midi API JSDoc stubs
---
libraries/midi/src/Midi.h | 131 +++++++++++++++++++++++++++++-------
tools/jsdoc/plugins/hifi.js | 1 +
2 files changed, 109 insertions(+), 23 deletions(-)
diff --git a/libraries/midi/src/Midi.h b/libraries/midi/src/Midi.h
index f7940bbe5d..e5c44c6b7e 100644
--- a/libraries/midi/src/Midi.h
+++ b/libraries/midi/src/Midi.h
@@ -20,6 +20,13 @@
#include
#include
+/**jsdoc
+ * @namespace Midi
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ */
+
class Midi : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
@@ -46,57 +53,135 @@ signals:
void midiReset();
public slots:
- // Send Raw Midi Packet to all connected devices
+
+ /**jsdoc
+ * Send Raw MIDI packet to a particular device.
+ * @function Midi.sendRawDword
+ * @param {number} device - Integer device number.
+ * @param {number} raw - Integer (DWORD) raw MIDI message.
+ */
Q_INVOKABLE void sendRawDword(int device, int raw);
- /// Send Raw Midi message to selected device
- /// @param {int} device: device number
- /// @param {int} raw: raw midi message (DWORD)
- // Send Midi Message to all connected devices
+ /**jsdoc
+ * Send MIDI message to a particular device.
+ * @function Midi.sendMidiMessage
+ * @param {number} device - Integer device number.
+ * @param {number} channel - Integer channel number.
+ * @param {number} type - 0x8 is note off, 0x9 is note on (if velocity=0, note off), etc.
+ * @param {number} note - MIDI note number.
+ * @param {number} velocity - Note velocity (0 means note off).
+ */
Q_INVOKABLE void sendMidiMessage(int device, int channel, int type, int note, int velocity);
- /// Send midi message to selected device/devices
- /// @param {int} device: device number
- /// @param {int} channel: channel number
- /// @param {int} type: 0x8 is noteoff, 0x9 is noteon (if velocity=0, noteoff), etc
- /// @param {int} note: midi note number
- /// @param {int} velocity: note velocity (0 means noteoff)
- // Send Midi Message to all connected devices
+ /**jsdoc
+ * Play a note on all connected devices.
+ * @function Midi.playMidiNote
+ * @param {number} status - 0x80 is note off, 0x90 is note on (if velocity=0, note off), etc.
+ * @param {number} note - MIDI note number.
+ * @param {number} velocity - Note velocity (0 means note off).
+ */
Q_INVOKABLE void playMidiNote(int status, int note, int velocity);
- /// play a note on all connected devices
- /// @param {int} status: 0x80 is noteoff, 0x90 is noteon (if velocity=0, noteoff), etc
- /// @param {int} note: midi note number
- /// @param {int} velocity: note velocity (0 means noteoff)
- /// turn off all notes on all connected devices
+ /**jsdoc
+ * Turn off all notes on all connected devices.
+ * @function Midi.allNotesOff
+ */
Q_INVOKABLE void allNotesOff();
- /// clean up and re-discover attached devices
+ /**jsdoc
+ * Clean up and re-discover attached devices.
+ * @function Midi.resetDevices
+ */
Q_INVOKABLE void resetDevices();
- /// ask for a list of inputs/outputs
+ /**jsdoc
+ * Get a list of inputs/outputs.
+ * @function Midi.listMidiDevices
+ * @param {boolean} output
+ * @returns {string[]}
+ */
Q_INVOKABLE QStringList listMidiDevices(bool output);
- /// block an input/output by name
+ /**jsdoc
+ * Block an input/output by name.
+ * @function Midi.blockMidiDevice
+ * @param {string} name
+ * @param {boolean} output
+ */
Q_INVOKABLE void blockMidiDevice(QString name, bool output);
- /// unblock an input/output by name
+ /**jsdoc
+ * Unblock an input/output by name.
+ * @function Midi.unblockMidiDevice
+ * @param {string} name
+ * @param {boolean} output
+ */
Q_INVOKABLE void unblockMidiDevice(QString name, bool output);
- /// repeat all incoming notes to all outputs (default disabled)
+ /**jsdoc
+ * Repeat all incoming notes to all outputs (default disabled).
+ * @function Midi.thruModeEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void thruModeEnable(bool enable);
- /// broadcast on all unblocked devices
+
+ /**jsdoc
+ * Broadcast on all unblocked devices.
+ * @function Midi.broadcastEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void broadcastEnable(bool enable);
+
/// filter by event types
+
+ /**jsdoc
+ * @function Midi.typeNoteOffEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void typeNoteOffEnable(bool enable);
+
+ /**jsdoc
+ * @function Midi.typeNoteOnEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void typeNoteOnEnable(bool enable);
+
+ /**jsdoc
+ * @function Midi.typePolyKeyPressureEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void typePolyKeyPressureEnable(bool enable);
+
+ /**jsdoc
+ * @function Midi.typeControlChangeEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void typeControlChangeEnable(bool enable);
+
+ /**jsdoc
+ * @function Midi.typeProgramChangeEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void typeProgramChangeEnable(bool enable);
+
+ /**jsdoc
+ * @function Midi.typeChanPressureEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void typeChanPressureEnable(bool enable);
+
+ /**jsdoc
+ * @function Midi.typePitchBendEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void typePitchBendEnable(bool enable);
+
+ /**jsdoc
+ * @function Midi.typeSystemMessageEnable
+ * @param {boolean} enable
+ */
Q_INVOKABLE void typeSystemMessageEnable(bool enable);
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index 8606007b89..37cabdc533 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -47,6 +47,7 @@ exports.handlers = {
'../../libraries/graphics/src/graphics/',
'../../libraries/graphics-scripting/src/graphics-scripting/',
'../../libraries/input-plugins/src/input-plugins',
+ '../../libraries/midi/src',
'../../libraries/model-networking/src/model-networking/',
'../../libraries/networking/src',
'../../libraries/octree/src',
From 11f984f05b601c34db2880974cc33faf575fb108 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sat, 12 May 2018 15:08:41 +1200
Subject: [PATCH 30/80] OffscreenFlags API JSDoc stubs
---
libraries/ui/src/OffscreenUi.cpp | 19 +++++++++++++++++++
tools/jsdoc/plugins/hifi.js | 1 +
2 files changed, 20 insertions(+)
diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp
index a1d09139e3..25f0652496 100644
--- a/libraries/ui/src/OffscreenUi.cpp
+++ b/libraries/ui/src/OffscreenUi.cpp
@@ -30,6 +30,15 @@
#include
+/**jsdoc
+ * @namespace OffscreenFlags
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ * @property {boolean} navigationFocused
+ * @property {boolean} navigationFocusDisabled
+ */
+
// Needs to match the constants in resources/qml/Global.js
class OffscreenFlags : public QObject {
Q_OBJECT
@@ -58,7 +67,17 @@ public:
}
signals:
+
+ /**jsdoc
+ * @function OffscreenFlags.navigationFocusedChanged
+ * @returns {Signal}
+ */
void navigationFocusedChanged();
+
+ /**jsdoc
+ * @function OffscreenFlags.navigationFocusDisabledChanged
+ * @returns {Signal}
+ */
void navigationFocusDisabledChanged();
private:
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index 37cabdc533..8a2a5cd0b5 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -57,6 +57,7 @@ exports.handlers = {
'../../libraries/shared/src',
'../../libraries/shared/src/shared',
'../../libraries/trackers/src/trackers',
+ '../../libraries/ui/src',
'../../libraries/ui/src/ui',
'../../plugins/oculus/src',
'../../plugins/openvr/src'
From b445371ad84f3b9d20ddd38cb55d4e7aea603b14 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sat, 12 May 2018 16:24:34 +1200
Subject: [PATCH 31/80] Resources API JSDoc stubs
---
.../src/ResourceScriptingInterface.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/libraries/networking/src/ResourceScriptingInterface.h b/libraries/networking/src/ResourceScriptingInterface.h
index d9777e7514..cc3f12f990 100644
--- a/libraries/networking/src/ResourceScriptingInterface.h
+++ b/libraries/networking/src/ResourceScriptingInterface.h
@@ -17,11 +17,30 @@
#include
+/**jsdoc
+ * @namespace Resources
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ * @hifi-server-entity
+ * @hifi-assignment-client
+ */
+
class ResourceScriptingInterface : public QObject, public Dependency {
Q_OBJECT
public:
+
+ /**jsdoc
+ * @function Resources.overrideUrlPrefix
+ * @param {string} prefix
+ * @param {string} replacement
+ */
Q_INVOKABLE void overrideUrlPrefix(const QString& prefix, const QString& replacement);
+ /**jsdoc
+ * @function Resources.restoreUrlPrefix
+ * @param {string} prefix
+ */
Q_INVOKABLE void restoreUrlPrefix(const QString& prefix) {
overrideUrlPrefix(prefix, "");
}
From 74617822fa518d0453c7d0649214c4570a462558 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sat, 12 May 2018 16:32:33 +1200
Subject: [PATCH 32/80] Snapshot API JSDoc stubs
---
interface/src/ui/Snapshot.h | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/interface/src/ui/Snapshot.h b/interface/src/ui/Snapshot.h
index 606313f3c3..4dc937382b 100644
--- a/interface/src/ui/Snapshot.h
+++ b/interface/src/ui/Snapshot.h
@@ -34,6 +34,14 @@ private:
QUrl _URL;
};
+
+/**jsdoc
+ * @namespace Snapshot
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ */
+
class Snapshot : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
@@ -46,11 +54,28 @@ public:
static void uploadSnapshot(const QString& filename, const QUrl& href = QUrl(""));
signals:
+
+ /**jsdoc
+ * @function Snapshot.snapshotLocationSet
+ * @param {string} location
+ * @returns {Signal}
+ */
void snapshotLocationSet(const QString& value);
public slots:
+
+ /**jsdoc
+ * @function Snapshot.getSnapshotsLocation
+ * @returns {string}
+ */
Q_INVOKABLE QString getSnapshotsLocation();
+
+ /**jsdoc
+ * @function Snapshot.setSnapshotsLocation
+ * @param {String} location
+ */
Q_INVOKABLE void setSnapshotsLocation(const QString& location);
+
private:
static QFile* savedFileForSnapshot(QImage& image,
bool isTemporary,
From 81a621890a2a0db41151ae093526cfa972970709 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sat, 12 May 2018 18:01:55 +1200
Subject: [PATCH 33/80] Stats API JSDoc stubs
---
interface/src/ui/Stats.h | 988 +++++++++++++++++++++++++++++++++++++++
1 file changed, 988 insertions(+)
diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h
index af3189f20b..f44d780d30 100644
--- a/interface/src/ui/Stats.h
+++ b/interface/src/ui/Stats.h
@@ -23,6 +23,149 @@ private: \
type _##name{ initialValue };
+/**jsdoc
+ * @namespace Stats
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ * @hifi-server-entity
+ * @hifi-assignment-client
+ *
+ * @property {boolean} expanded
+ * @property {boolean} timingExpanded - Read-only.
+ * @property {string} monospaceFont - Read-only.
+ *
+ * @property {number} serverCount - Read-only.
+ * @property {number} renderrate - How often the app is creating new gpu::Frames. Read-only.
+ * @property {number} presentrate - How often the display plugin is presenting to the device. Read-only.
+ * @property {number} stutterrate - How often the display device is reprojecting old frames. Read-only.
+ *
+ * @property {number} appdropped - Read-only.
+ * @property {number} longsubmits - Read-only.
+ * @property {number} longrenders - Read-only.
+ * @property {number} longframes - Read-only.
+ *
+ * @property {number} presentnewrate - Read-only.
+ * @property {number} presentdroprate - Read-only.
+ * @property {number} gameLoopRate - Read-only.
+ * @property {number} avatarCount - Read-only.
+ * @property {number} updatedAvatarCount - Read-only.
+ * @property {number} notUpdatedAvatarCount - Read-only.
+ * @property {number} packetInCount - Read-only.
+ * @property {number} packetOutCount - Read-only.
+ * @property {number} mbpsIn - Read-only.
+ * @property {number} mbpsOut - Read-only.
+ * @property {number} assetMbpsIn - Read-only.
+ * @property {number} assetMbpsOut - Read-only.
+ * @property {number} audioPing - Read-only.
+ * @property {number} avatarPing - Read-only.
+ * @property {number} entitiesPing - Read-only.
+ * @property {number} assetPing - Read-only.
+ * @property {number} messagePing - Read-only.
+ * @property {Vec3} position - Read-only.
+ * @property {number} speed - Read-only.
+ * @property {number} yaw - Read-only.
+ * @property {number} avatarMixerInKbps - Read-only.
+ * @property {number} avatarMixerInPps - Read-only.
+ * @property {number} avatarMixerOutKbps - Read-only.
+ * @property {number} avatarMixerOutPps - Read-only.
+ * @property {number} myAvatarSendRate - Read-only.
+ *
+ * @property {number} audioMixerInKbps - Read-only.
+ * @property {number} audioMixerInPps - Read-only.
+ * @property {number} audioMixerOutKbps - Read-only.
+ * @property {number} audioMixerOutPps - Read-only.
+ * @property {number} audioMixerKbps - Read-only.
+ * @property {number} audioMixerPps - Read-only.
+ * @property {number} audioOutboundPPS - Read-only.
+ * @property {number} audioSilentOutboundPPS - Read-only.
+ * @property {number} audioAudioInboundPPS - Read-only.
+ * @property {number} audioSilentInboundPPS - Read-only.
+ * @property {number} audioPacketLoss - Read-only.
+ * @property {string} audioCodec - Read-only.
+ * @property {string} audioNoiseGate - Read-only.
+ * @property {number} entityPacketsInKbps - Read-only.
+ *
+ * @property {number} downloads - Read-only.
+ * @property {number} downloadLimit - Read-only.
+ * @property {number} downloadsPending - Read-only.
+ * @property {string[]} downloadUrls - Read-only.
+ * @property {number} processing - Read-only.
+ * @property {number} processingPending - Read-only.
+ * @property {number} triangles - Read-only.
+ * @property {number} quads - Read-only.
+ * @property {number} materialSwitches - Read-only.
+ * @property {number} itemConsidered - Read-only.
+ * @property {number} itemOutOfView - Read-only.
+ * @property {number} itemTooSmall - Read-only.
+ * @property {number} itemRendered - Read-only.
+ * @property {number} shadowConsidered - Read-only.
+ * @property {number} shadowOutOfView - Read-only.
+ * @property {number} shadowTooSmall - Read-only.
+ * @property {number} shadowRendered - Read-only.
+ * @property {string} sendingMode - Read-only.
+ * @property {string} packetStats - Read-only.
+ * @property {string} lodStatus - Read-only.
+ * @property {string} timingStats - Read-only.
+ * @property {string} gameUpdateStats - Read-only.
+ * @property {number} serverElements - Read-only.
+ * @property {number} serverInternal - Read-only.
+ * @property {number} serverLeaves - Read-only.
+ * @property {number} localElements - Read-only.
+ * @property {number} localInternal - Read-only.
+ * @property {number} localLeaves - Read-only.
+ * @property {number} rectifiedTextureCount - Read-only.
+ * @property {number} decimatedTextureCount - Read-only.
+ * @property {number} gpuBuffers - Read-only.
+ * @property {number} gpuBufferMemory - Read-only.
+ * @property {number} gpuTextures - Read-only.
+ * @property {number} glContextSwapchainMemory - Read-only.
+ * @property {number} qmlTextureMemory - Read-only.
+ * @property {number} texturePendingTransfers - Read-only.
+ * @property {number} gpuTextureMemory - Read-only.
+ * @property {number} gpuTextureResidentMemory - Read-only.
+ * @property {number} gpuTextureFramebufferMemory - Read-only.
+ * @property {number} gpuTextureResourceMemory - Read-only.
+ * @property {number} gpuTextureResourcePopulatedMemory - Read-only.
+ * @property {number} gpuTextureExternalMemory - Read-only.
+ * @property {string} gpuTextureMemoryPressureState - Read-only.
+ * @property {number} gpuFreeMemory - Read-only.
+ * @property {number} gpuFrameTime - Read-only.
+ * @property {number} batchFrameTime - Read-only.
+ * @property {number} engineFrameTime - Read-only.
+ * @property {number} avatarSimulationTime - Read-only.
+ *
+ *
+ * @property {number} x
+ * @property {number} y
+ * @property {number} z
+ * @property {number} width
+ * @property {number} height
+ *
+ * @property {number} opacity
+ * @property {boolean} enabled
+ * @property {boolean} visible
+ *
+ * @property {string} state
+ * @property {number} baselineOffset
+ *
+ * @property {boolean} clip
+ *
+ * @property {boolean} focus
+ * @property {boolean} activeFocus - Read-only.
+ * @property {boolean} activeFocusOnTab
+ *
+ * @property {number} rotation
+ * @property {number} scale
+ * @property {number} transformOrigin
+ *
+ * @property {boolean} smooth
+ * @property {boolean} antialiasing
+ * @property {number} implicitWidth
+ * @property {number} implicitHeight
+ */
+// Properties from x onwards are QQuickItem properties.
+
class Stats : public QQuickItem {
Q_OBJECT
HIFI_QML_DECL
@@ -161,105 +304,950 @@ public slots:
void forceUpdateStats() { updateStats(true); }
signals:
+
+ /**jsdoc
+ * Triggered when the value of the longsubmits property changes.
+ * @function Stats.longsubmitsChanged
+ * @returns {Signal}
+ */
void longsubmitsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the longrenders property changes.
+ * @function Stats.longrendersChanged
+ * @returns {Signal}
+ */
void longrendersChanged();
+
+ /**jsdoc
+ * Triggered when the value of the longframes property changes.
+ * @function Stats.longframesChanged
+ * @returns {Signal}
+ */
void longframesChanged();
+
+ /**jsdoc
+ * Triggered when the value of the appdropped property changes.
+ * @function Stats.appdroppedChanged
+ * @returns {Signal}
+ */
void appdroppedChanged();
+
+ /**jsdoc
+ * Triggered when the value of the expanded property changes.
+ * @function Stats.expandedChanged
+ * @returns {Signal}
+ */
void expandedChanged();
+
+ /**jsdoc
+ * Triggered when the value of the timingExpanded property changes.
+ * @function Stats.timingExpandedChanged
+ * @returns {Signal}
+ */
void timingExpandedChanged();
+
+ /**jsdoc
+ * Triggered when the value of the serverCount property changes.
+ * @function Stats.serverCountChanged
+ * @returns {Signal}
+ */
void serverCountChanged();
+
+ /**jsdoc
+ * Triggered when the value of the renderrate property changes.
+ * @function Stats.renderrateChanged
+ * @returns {Signal}
+ */
void renderrateChanged();
+
+ /**jsdoc
+ * Triggered when the value of the presentrate property changes.
+ * @function Stats.presentrateChanged
+ * @returns {Signal}
+ */
void presentrateChanged();
+
+ /**jsdoc
+ * Triggered when the value of the presentnewrate property changes.
+ * @function Stats.presentnewrateChanged
+ * @returns {Signal}
+ */
void presentnewrateChanged();
+
+ /**jsdoc
+ * Triggered when the value of the presentdroprate property changes.
+ * @function Stats.presentdroprateChanged
+ * @returns {Signal}
+ */
void presentdroprateChanged();
+
+ /**jsdoc
+ * Triggered when the value of the stutterrate property changes.
+ * @function Stats.stutterrateChanged
+ * @returns {Signal}
+ */
void stutterrateChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gameLoopRate property changes.
+ * @function Stats.gameLoopRateChanged
+ * @returns {Signal}
+ */
void gameLoopRateChanged();
+
+ /**jsdoc
+ * Triggered when the value of the avatarCount property changes.
+ * @function Stats.avatarCountChanged
+ * @returns {Signal}
+ */
void avatarCountChanged();
+
+ /**jsdoc
+ * Triggered when the value of the updatedAvatarCount property changes.
+ * @function Stats.updatedAvatarCountChanged
+ * @returns {Signal}
+ */
void updatedAvatarCountChanged();
+
+ /**jsdoc
+ * Triggered when the value of the notUpdatedAvatarCount property changes.
+ * @function Stats.notUpdatedAvatarCountChanged
+ * @returns {Signal}
+ */
void notUpdatedAvatarCountChanged();
+
+ /**jsdoc
+ * Triggered when the value of the packetInCount property changes.
+ * @function Stats.packetInCountChanged
+ * @returns {Signal}
+ */
void packetInCountChanged();
+
+ /**jsdoc
+ * Triggered when the value of the packetOutCount property changes.
+ * @function Stats.packetOutCountChanged
+ * @returns {Signal}
+ */
void packetOutCountChanged();
+
+ /**jsdoc
+ * Triggered when the value of the mbpsIn property changes.
+ * @function Stats.mbpsInChanged
+ * @returns {Signal}
+ */
void mbpsInChanged();
+
+ /**jsdoc
+ * Triggered when the value of the mbpsOut property changes.
+ * @function Stats.mbpsOutChanged
+ * @returns {Signal}
+ */
void mbpsOutChanged();
+
+ /**jsdoc
+ * Triggered when the value of the assetMbpsIn property changes.
+ * @function Stats.assetMbpsInChanged
+ * @returns {Signal}
+ */
void assetMbpsInChanged();
+
+ /**jsdoc
+ * Triggered when the value of the assetMbpsOut property changes.
+ * @function Stats.assetMbpsOutChanged
+ * @returns {Signal}
+ */
void assetMbpsOutChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioPing property changes.
+ * @function Stats.audioPingChanged
+ * @returns {Signal}
+ */
void audioPingChanged();
+
+ /**jsdoc
+ * Triggered when the value of the avatarPing property changes.
+ * @function Stats.avatarPingChanged
+ * @returns {Signal}
+ */
void avatarPingChanged();
+
+ /**jsdoc
+ * Triggered when the value of the entitiesPing property changes.
+ * @function Stats.entitiesPingChanged
+ * @returns {Signal}
+ */
void entitiesPingChanged();
+
+ /**jsdoc
+ * Triggered when the value of the assetPing property changes.
+ * @function Stats.assetPingChanged
+ * @returns {Signal}
+ */
void assetPingChanged();
+
+ /**jsdoc
+ * Triggered when the value of the messagePing property changes.
+ * @function Stats.messagePingChanged
+ * @returns {Signal}
+ */
void messagePingChanged();
+
+ /**jsdoc
+ * Triggered when the value of the position property changes.
+ * @function Stats.positionChanged
+ * @returns {Signal}
+ */
void positionChanged();
+
+ /**jsdoc
+ * Triggered when the value of the speed property changes.
+ * @function Stats.speedChanged
+ * @returns {Signal}
+ */
void speedChanged();
+
+ /**jsdoc
+ * Triggered when the value of the yaw property changes.
+ * @function Stats.yawChanged
+ * @returns {Signal}
+ */
void yawChanged();
+
+ /**jsdoc
+ * Triggered when the value of the avatarMixerInKbps property changes.
+ * @function Stats.avatarMixerInKbpsChanged
+ * @returns {Signal}
+ */
void avatarMixerInKbpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the avatarMixerInPps property changes.
+ * @function Stats.avatarMixerInPpsChanged
+ * @returns {Signal}
+ */
void avatarMixerInPpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the avatarMixerOutKbps property changes.
+ * @function Stats.avatarMixerOutKbpsChanged
+ * @returns {Signal}
+ */
void avatarMixerOutKbpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the avatarMixerOutPps property changes.
+ * @function Stats.avatarMixerOutPpsChanged
+ * @returns {Signal}
+ */
void avatarMixerOutPpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the myAvatarSendRate property changes.
+ * @function Stats.myAvatarSendRateChanged
+ * @returns {Signal}
+ */
void myAvatarSendRateChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioMixerInKbps property changes.
+ * @function Stats.audioMixerInKbpsChanged
+ * @returns {Signal}
+ */
void audioMixerInKbpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioMixerInPps property changes.
+ * @function Stats.audioMixerInPpsChanged
+ * @returns {Signal}
+ */
void audioMixerInPpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioMixerOutKbps property changes.
+ * @function Stats.audioMixerOutKbpsChanged
+ * @returns {Signal}
+ */
void audioMixerOutKbpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioMixerOutPps property changes.
+ * @function Stats.audioMixerOutPpsChanged
+ * @returns {Signal}
+ */
void audioMixerOutPpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioMixerKbps property changes.
+ * @function Stats.audioMixerKbpsChanged
+ * @returns {Signal}
+ */
void audioMixerKbpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioMixerPps property changes.
+ * @function Stats.audioMixerPpsChanged
+ * @returns {Signal}
+ */
void audioMixerPpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioOutboundPPS property changes.
+ * @function Stats.audioOutboundPPSChanged
+ * @returns {Signal}
+ */
void audioOutboundPPSChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioSilentOutboundPPS property changes.
+ * @function Stats.audioSilentOutboundPPSChanged
+ * @returns {Signal}
+ */
void audioSilentOutboundPPSChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioAudioInboundPPS property changes.
+ * @function Stats.audioAudioInboundPPSChanged
+ * @returns {Signal}
+ */
void audioAudioInboundPPSChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioSilentInboundPPS property changes.
+ * @function Stats.audioSilentInboundPPSChanged
+ * @returns {Signal}
+ */
void audioSilentInboundPPSChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioPacketLoss property changes.
+ * @function Stats.audioPacketLossChanged
+ * @returns {Signal}
+ */
void audioPacketLossChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioCodec property changes.
+ * @function Stats.audioCodecChanged
+ * @returns {Signal}
+ */
void audioCodecChanged();
+
+ /**jsdoc
+ * Triggered when the value of the audioNoiseGate property changes.
+ * @function Stats.audioNoiseGateChanged
+ * @returns {Signal}
+ */
void audioNoiseGateChanged();
+
+ /**jsdoc
+ * Triggered when the value of the entityPacketsInKbps property changes.
+ * @function Stats.entityPacketsInKbpsChanged
+ * @returns {Signal}
+ */
void entityPacketsInKbpsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the downloads property changes.
+ * @function Stats.downloadsChanged
+ * @returns {Signal}
+ */
void downloadsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the downloadLimit property changes.
+ * @function Stats.downloadLimitChanged
+ * @returns {Signal}
+ */
void downloadLimitChanged();
+
+ /**jsdoc
+ * Triggered when the value of the downloadsPending property changes.
+ * @function Stats.downloadsPendingChanged
+ * @returns {Signal}
+ */
void downloadsPendingChanged();
+
+ /**jsdoc
+ * Triggered when the value of the downloadUrls property changes.
+ * @function Stats.downloadUrlsChanged
+ * @returns {Signal}
+ */
void downloadUrlsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the processing property changes.
+ * @function Stats.processingChanged
+ * @returns {Signal}
+ */
void processingChanged();
+
+ /**jsdoc
+ * Triggered when the value of the processingPending property changes.
+ * @function Stats.processingPendingChanged
+ * @returns {Signal}
+ */
void processingPendingChanged();
+
+ /**jsdoc
+ * Triggered when the value of the triangles property changes.
+ * @function Stats.trianglesChanged
+ * @returns {Signal}
+ */
void trianglesChanged();
+
+ /**jsdoc
+ * Triggered when the value of the quads property changes.
+ * @function Stats.quadsChanged
+ * @returns {Signal}
+ */
void quadsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the materialSwitches property changes.
+ * @function Stats.materialSwitchesChanged
+ * @returns {Signal}
+ */
void materialSwitchesChanged();
+
+ /**jsdoc
+ * Triggered when the value of the itemConsidered property changes.
+ * @function Stats.itemConsideredChanged
+ * @returns {Signal}
+ */
void itemConsideredChanged();
+
+ /**jsdoc
+ * Triggered when the value of the itemOutOfView property changes.
+ * @function Stats.itemOutOfViewChanged
+ * @returns {Signal}
+ */
void itemOutOfViewChanged();
+
+ /**jsdoc
+ * Triggered when the value of the itemTooSmall property changes.
+ * @function Stats.itemTooSmallChanged
+ * @returns {Signal}
+ */
void itemTooSmallChanged();
+
+ /**jsdoc
+ * Triggered when the value of the itemRendered property changes.
+ * @function Stats.itemRenderedChanged
+ * @returns {Signal}
+ */
void itemRenderedChanged();
+
+ /**jsdoc
+ * Triggered when the value of the shadowConsidered property changes.
+ * @function Stats.shadowConsideredChanged
+ * @returns {Signal}
+ */
void shadowConsideredChanged();
+
+ /**jsdoc
+ * Triggered when the value of the shadowOutOfView property changes.
+ * @function Stats.shadowOutOfViewChanged
+ * @returns {Signal}
+ */
void shadowOutOfViewChanged();
+
+ /**jsdoc
+ * Triggered when the value of the shadowTooSmall property changes.
+ * @function Stats.shadowTooSmallChanged
+ * @returns {Signal}
+ */
void shadowTooSmallChanged();
+
+ /**jsdoc
+ * Triggered when the value of the shadowRendered property changes.
+ * @function Stats.shadowRenderedChanged
+ * @returns {Signal}
+ */
void shadowRenderedChanged();
+
+ /**jsdoc
+ * Triggered when the value of the sendingMode property changes.
+ * @function Stats.sendingModeChanged
+ * @returns {Signal}
+ */
void sendingModeChanged();
+
+ /**jsdoc
+ * Triggered when the value of the packetStats property changes.
+ * @function Stats.packetStatsChanged
+ * @returns {Signal}
+ */
void packetStatsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the lodStatus property changes.
+ * @function Stats.lodStatusChanged
+ * @returns {Signal}
+ */
void lodStatusChanged();
+
+ /**jsdoc
+ * Triggered when the value of the serverElements property changes.
+ * @function Stats.serverElementsChanged
+ * @returns {Signal}
+ */
void serverElementsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the serverInternal property changes.
+ * @function Stats.serverInternalChanged
+ * @returns {Signal}
+ */
void serverInternalChanged();
+
+ /**jsdoc
+ * Triggered when the value of the serverLeaves property changes.
+ * @function Stats.serverLeavesChanged
+ * @returns {Signal}
+ */
void serverLeavesChanged();
+
+ /**jsdoc
+ * Triggered when the value of the localElements property changes.
+ * @function Stats.localElementsChanged
+ * @returns {Signal}
+ */
void localElementsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the localInternal property changes.
+ * @function Stats.localInternalChanged
+ * @returns {Signal}
+ */
void localInternalChanged();
+
+ /**jsdoc
+ * Triggered when the value of the localLeaves property changes.
+ * @function Stats.localLeavesChanged
+ * @returns {Signal}
+ */
void localLeavesChanged();
+
+ /**jsdoc
+ * Triggered when the value of the timingStats property changes.
+ * @function Stats.timingStatsChanged
+ * @returns {Signal}
+ */
void timingStatsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gameUpdateStats property changes.
+ * @function Stats.gameUpdateStatsChanged
+ * @returns {Signal}
+ */
void gameUpdateStatsChanged();
+
+ /**jsdoc
+ * Triggered when the value of the glContextSwapchainMemory property changes.
+ * @function Stats.glContextSwapchainMemoryChanged
+ * @returns {Signal}
+ */
void glContextSwapchainMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the qmlTextureMemory property changes.
+ * @function Stats.qmlTextureMemoryChanged
+ * @returns {Signal}
+ */
void qmlTextureMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the texturePendingTransfers property changes.
+ * @function Stats.texturePendingTransfersChanged
+ * @returns {Signal}
+ */
void texturePendingTransfersChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuBuffers property changes.
+ * @function Stats.gpuBuffersChanged
+ * @returns {Signal}
+ */
void gpuBuffersChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuBufferMemory property changes.
+ * @function Stats.gpuBufferMemoryChanged
+ * @returns {Signal}
+ */
void gpuBufferMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuTextures property changes.
+ * @function Stats.gpuTexturesChanged
+ * @returns {Signal}
+ */
void gpuTexturesChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuTextureMemory property changes.
+ * @function Stats.gpuTextureMemoryChanged
+ * @returns {Signal}
+ */
void gpuTextureMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuTextureResidentMemory property changes.
+ * @function Stats.gpuTextureResidentMemoryChanged
+ * @returns {Signal}
+ */
void gpuTextureResidentMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuTextureFramebufferMemory property changes.
+ * @function Stats.gpuTextureFramebufferMemoryChanged
+ * @returns {Signal}
+ */
void gpuTextureFramebufferMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuTextureResourceMemory property changes.
+ * @function Stats.gpuTextureResourceMemoryChanged
+ * @returns {Signal}
+ */
void gpuTextureResourceMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuTextureResourcePopulatedMemory property changes.
+ * @function Stats.gpuTextureResourcePopulatedMemoryChanged
+ * @returns {Signal}
+ */
void gpuTextureResourcePopulatedMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuTextureExternalMemory property changes.
+ * @function Stats.gpuTextureExternalMemoryChanged
+ * @returns {Signal}
+ */
void gpuTextureExternalMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuTextureMemoryPressureState property changes.
+ * @function Stats.gpuTextureMemoryPressureStateChanged
+ * @returns {Signal}
+ */
void gpuTextureMemoryPressureStateChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuFreeMemory property changes.
+ * @function Stats.gpuFreeMemoryChanged
+ * @returns {Signal}
+ */
void gpuFreeMemoryChanged();
+
+ /**jsdoc
+ * Triggered when the value of the gpuFrameTime property changes.
+ * @function Stats.gpuFrameTimeChanged
+ * @returns {Signal}
+ */
void gpuFrameTimeChanged();
+
+ /**jsdoc
+ * Triggered when the value of the batchFrameTime property changes.
+ * @function Stats.batchFrameTimeChanged
+ * @returns {Signal}
+ */
void batchFrameTimeChanged();
+
+ /**jsdoc
+ * Triggered when the value of the engineFrameTime property changes.
+ * @function Stats.engineFrameTimeChanged
+ * @returns {Signal}
+ */
void engineFrameTimeChanged();
+
+ /**jsdoc
+ * Triggered when the value of the avatarSimulationTime property changes.
+ * @function Stats.avatarSimulationTimeChanged
+ * @returns {Signal}
+ */
void avatarSimulationTimeChanged();
+
+ /**jsdoc
+ * Triggered when the value of the rectifiedTextureCount property changes.
+ * @function Stats.rectifiedTextureCountChanged
+ * @returns {Signal}
+ */
void rectifiedTextureCountChanged();
+
+ /**jsdoc
+ * Triggered when the value of the decimatedTextureCount property changes.
+ * @function Stats.decimatedTextureCountChanged
+ * @returns {Signal}
+ */
void decimatedTextureCountChanged();
+
+ // QQuickItem signals.
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {Rect} childrenRect
+ * @returns {Signal}
+ */
+ void childrenRectChanged(const QRectF &);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {number} baselineOffset
+ * @returns {Signal}
+ */
+ void baselineOffsetChanged(qreal);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {string} state
+ * @returns {Signal}
+ */
+ void stateChanged(const QString &);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {boolean} focus
+ * @returns {Signal}
+ */
+ void focusChanged(bool);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {boolean} activeFocus
+ * @returns {Signal}
+ */
+ void activeFocusChanged(bool);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {boolean} activeFocusOnTab
+ * @returns {Signal}
+ */
+ void activeFocusOnTabChanged(bool);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {object} parent
+ * @returns {Signal}
+ */
+ void parentChanged(QQuickItem *);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {number} transformOrigin
+ * @returns {Signal}
+ */
+ void transformOriginChanged(TransformOrigin);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {boolean} smooth
+ * @returns {Signal}
+ */
+ void smoothChanged(bool);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {boolean} antialiasing
+ * @returns {Signal}
+ */
+ void antialiasingChanged(bool);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {boolean} clip
+ * @returns {Signal}
+ */
+ void clipChanged(bool);
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @param {object} window
+ * @returns {Signal}
+ */
+ void windowChanged(QQuickWindow* window);
+
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void childrenChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void opacityChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void enabledChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void visibleChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void visibleChildrenChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void rotationChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void scaleChanged();
+
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void xChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void yChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void widthChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void heightChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void zChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void implicitWidthChanged();
+
+ /**jsdoc
+ * Triggered when the value of the TODO property changes.
+ * @function Stats.TODO
+ * @returns {Signal}
+ */
+ void implicitHeightChanged();
+
+
+ // QQuickItem functions.
+
+ /**jsdoc
+ * @function Stats.grabToImage
+ * @param {object} callback
+ * @param {Size} [targetSize=0,0]
+ * @returns {boolean}
+ */
+ Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize());
+
+ /**jsdoc
+ * @function Stats.contains
+ * @param {Vec2} point
+ * @returns {boolean}
+ */
+ Q_INVOKABLE virtual bool contains(const QPointF &point) const;
+
+ /**jsdoc
+ * @function Stats.mapFromItem
+ * @param {object} item
+ */
+ Q_INVOKABLE void mapFromItem(QQmlV4Function*) const;
+
+ /**jsdoc
+ * @function Stats.mapToItem
+ * @param {object} item
+ */
+ Q_INVOKABLE void mapToItem(QQmlV4Function*) const;
+
+ /**jsdoc
+ * @function Stats.mapFromGlobal
+ * @param {object} global
+ */
+ Q_INVOKABLE void mapFromGlobal(QQmlV4Function*) const;
+
+ /**jsdoc
+ * @function Stats.mapToGlobal
+ * @param {object} global
+ */
+ Q_INVOKABLE void mapToGlobal(QQmlV4Function*) const;
+
+ /**jsdoc
+ * @function Stats.forceActiveFocus
+ * @param {number} [reason=7]
+ */
+ Q_INVOKABLE void forceActiveFocus();
+ Q_INVOKABLE void forceActiveFocus(Qt::FocusReason reason);
+
+ /**jsdoc
+ * @function Stats.nextItemInFocusChain
+ * @param {boolean} [forward=true]
+ * @returns {object}
+ */
+ Q_INVOKABLE QQuickItem *nextItemInFocusChain(bool forward = true);
+
+ /**jsdoc
+ * @function Stats.childAt
+ * @param {number} x
+ * @param {number} y
+ * @returns {object}
+ */
+ Q_INVOKABLE QQuickItem *childAt(qreal x, qreal y) const;
+
private:
int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process
bool _resetRecentMaxPacketsSoon{ true };
From fb1f7fea90f358868c88fe24879a784007604559 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sun, 13 May 2018 10:32:46 +1200
Subject: [PATCH 34/80] Steam API JSDoc stubs
---
.../plugins/src/plugins/SteamClientPlugin.h | 18 ++++++++++++++++++
tools/jsdoc/plugins/hifi.js | 1 +
2 files changed, 19 insertions(+)
diff --git a/libraries/plugins/src/plugins/SteamClientPlugin.h b/libraries/plugins/src/plugins/SteamClientPlugin.h
index 343ed40402..fc1b85c572 100644
--- a/libraries/plugins/src/plugins/SteamClientPlugin.h
+++ b/libraries/plugins/src/plugins/SteamClientPlugin.h
@@ -40,6 +40,15 @@ public:
virtual int getSteamVRBuildID() = 0;
};
+/**jsdoc
+ * @namespace Steam
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ *
+ * @property {boolean} running - Read-only.
+ */
+
class SteamScriptingInterface : public QObject {
Q_OBJECT
@@ -49,7 +58,16 @@ public:
SteamScriptingInterface(QObject* parent, SteamClientPlugin* plugin) : QObject(parent), _plugin(plugin) {}
public slots:
+
+ /**jsdoc
+ * @function Steam.isRunning
+ * @returns {boolean}
+ */
bool isRunning() const { return _plugin && _plugin->isRunning(); }
+
+ /**jsdoc
+ * @function Steam.openInviteOverlay
+ */
void openInviteOverlay() const { if (_plugin) { _plugin->openInviteOverlay(); } }
private:
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index 8a2a5cd0b5..91f6476772 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -52,6 +52,7 @@ exports.handlers = {
'../../libraries/networking/src',
'../../libraries/octree/src',
'../../libraries/physics/src',
+ '../../libraries/plugins/src/plugins',
'../../libraries/pointers/src',
'../../libraries/script-engine/src',
'../../libraries/shared/src',
From 46ebb0457e41839182050c47de0271a19415f2cf Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sun, 13 May 2018 10:56:21 +1200
Subject: [PATCH 35/80] Toolbars API JSDoc stubs
---
.../ui/src/ui/ToolbarScriptingInterface.h | 45 +++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/libraries/ui/src/ui/ToolbarScriptingInterface.h b/libraries/ui/src/ui/ToolbarScriptingInterface.h
index 108cf6bdd5..4b9bd79fb3 100644
--- a/libraries/ui/src/ui/ToolbarScriptingInterface.h
+++ b/libraries/ui/src/ui/ToolbarScriptingInterface.h
@@ -19,14 +19,30 @@
class QQuickItem;
+/**jsdoc
+ * @class ToolbarButtonProxy
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ */
class ToolbarButtonProxy : public QmlWrapper {
Q_OBJECT
public:
ToolbarButtonProxy(QObject* qmlObject, QObject* parent = nullptr);
+
+ /**jsdoc
+ * @function ToolbarButtonProxy#editProperties
+ * @param {object} properties
+ */
Q_INVOKABLE void editProperties(const QVariantMap& properties);
signals:
+
+ /**jsdoc
+ * @function ToolbarButtonProxy#clicked
+ * @returns {Signal}
+ */
void clicked();
protected:
@@ -36,19 +52,48 @@ protected:
Q_DECLARE_METATYPE(ToolbarButtonProxy*);
+/**jsdoc
+ * @class ToolbarProxy
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ */
class ToolbarProxy : public QmlWrapper {
Q_OBJECT
public:
ToolbarProxy(QObject* qmlObject, QObject* parent = nullptr);
+
+ /**jsdoc
+ * @function ToolbarProxy#addButton
+ * @property {object} properties
+ * @returns {ToolbarButtonProxy}
+ */
Q_INVOKABLE ToolbarButtonProxy* addButton(const QVariant& properties);
+
+ /**jsdoc
+ * @function ToolbarProxy#removeButton
+ * @property {string} name
+ */
Q_INVOKABLE void removeButton(const QVariant& name);
};
Q_DECLARE_METATYPE(ToolbarProxy*);
+/**jsdoc
+ * @namespace Toolbars
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ */
class ToolbarScriptingInterface : public QObject, public Dependency {
Q_OBJECT
public:
+
+ /**jsdoc
+ * @function Toolbars.getToolbar
+ * @param {string} toolbarID
+ * @returns {ToolbarProxy}
+ */
Q_INVOKABLE ToolbarProxy* getToolbar(const QString& toolbarId);
};
From 176dbb5557196453046fbae656b20c08a28bf95c Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sun, 13 May 2018 11:02:09 +1200
Subject: [PATCH 36/80] Wallet API JSDoc stubs
---
.../src/scripting/WalletScriptingInterface.h | 44 +++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h
index 9e40aad087..45661d939b 100644
--- a/interface/src/scripting/WalletScriptingInterface.h
+++ b/interface/src/scripting/WalletScriptingInterface.h
@@ -30,6 +30,14 @@ public:
};
+/**jsdoc
+ * @namespace Wallet
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ *
+ * @property {number} walletStatus
+ */
class WalletScriptingInterface : public QObject, public Dependency {
Q_OBJECT
@@ -38,17 +46,53 @@ class WalletScriptingInterface : public QObject, public Dependency {
public:
WalletScriptingInterface();
+ /**jsdoc
+ * @function Wallet.refreshWalletStatus
+ */
Q_INVOKABLE void refreshWalletStatus();
+
+ /**jsdoc
+ * @function Wallet.getWalletStatus
+ * @returns {number}
+ */
Q_INVOKABLE uint getWalletStatus() { return _walletStatus; }
+
+ /**jsdoc
+ * @function Wallet.proveAvatarEntityOwnershipVerification
+ * @param {Uuid} entityID
+ */
Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID);
+
// setWalletStatus() should never be made Q_INVOKABLE. If it were,
// scripts could cause the Wallet to incorrectly report its status.
void setWalletStatus(const uint& status);
signals:
+
+ /**jsdoc
+ * @function Wallet.walletStatusChanged
+ * @returns {Signal}
+ */
void walletStatusChanged();
+
+ /**jsdoc
+ * @function Wallet.walletNotSetup
+ * @returns {Signal}
+ */
void walletNotSetup();
+
+ /**jsdoc
+ * @function Wallet.ownershipVerificationSuccess
+ * @property {Uuid} entityID
+ * @returns {Signal}
+ */
void ownershipVerificationSuccess(const QUuid& entityID);
+
+ /**jsdoc
+ * @function Wallet.ownershipVerificationFailed
+ * @property {Uuid} entityID
+ * @returns {Signal}
+ */
void ownershipVerificationFailed(const QUuid& entityID);
private:
From 7cef32993999b4ca63e3c571840dc55a41d98d90 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sun, 13 May 2018 11:53:57 +1200
Subject: [PATCH 37/80] Render API JSDoc stubs
---
libraries/task/src/task/Config.h | 50 ++++++++++++++++++++++++++++++--
tools/jsdoc/plugins/hifi.js | 1 +
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/libraries/task/src/task/Config.h b/libraries/task/src/task/Config.h
index 36dfb35f25..ceb7e6c245 100644
--- a/libraries/task/src/task/Config.h
+++ b/libraries/task/src/task/Config.h
@@ -104,8 +104,17 @@ public:
virtual void setPresetList(const QJsonObject& object);
+ /**jsdoc
+ * @function Render.toJSON
+ * @returns {string}
+ */
// This must be named toJSON to integrate with the global scripting JSON object
Q_INVOKABLE QString toJSON() { return QJsonDocument(toJsonValue(*this).toObject()).toJson(QJsonDocument::Compact); }
+
+ /**jsdoc
+ * @function Render.load
+ * @param {object} map
+ */
Q_INVOKABLE void load(const QVariantMap& map) { qObjectFromJsonValue(QJsonObject::fromVariantMap(map), *this); emit loaded(); }
// Running Time measurement
@@ -114,11 +123,31 @@ public:
double getCPURunTime() const { return _msCPURunTime; }
public slots:
+
+ /**jsdoc
+ * @function Render.load
+ * @param {object} map
+ */
void load(const QJsonObject& val) { qObjectFromJsonValue(val, *this); emit loaded(); }
signals:
+
+ /**jsdoc
+ * @function Render.loaded
+ * @returns {Signal}
+ */
void loaded();
+
+ /**jsdoc
+ * @function Render.newStats
+ * @returns {Signal}
+ */
void newStats();
+
+ /**jsdoc
+ * @function Render.dirtyEnabled
+ * @returns {Signal}
+ */
void dirtyEnabled();
};
@@ -127,6 +156,16 @@ public:
using Config = JobConfig;
};
+
+/**jsdoc
+ * @namespace Render
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ *
+ * @property {number} cpuRunTime - Read-only.
+ * @property {boolean} enabled
+ */
class TaskConfig : public JobConfig {
Q_OBJECT
public:
@@ -137,8 +176,11 @@ public:
TaskConfig() = default ;
TaskConfig(bool enabled) : JobConfig(enabled) {}
-
-
+ /**jsdoc
+ * @function Render.getConfig
+ * @param {string} name
+ * @returns {object}
+ */
// Get a sub job config through task.getConfig(path)
// where path can be:
// - search for the first job named job_name traversing the the sub graph of task and jobs (from this task as root)
@@ -176,6 +218,10 @@ public:
JobConcept* _task;
public slots:
+
+ /**jsdoc
+ * @function Render.refresh
+ */
void refresh();
};
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index 91f6476772..d063d43990 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -57,6 +57,7 @@ exports.handlers = {
'../../libraries/script-engine/src',
'../../libraries/shared/src',
'../../libraries/shared/src/shared',
+ '../../libraries/task/src/task',
'../../libraries/trackers/src/trackers',
'../../libraries/ui/src',
'../../libraries/ui/src/ui',
From 9fdce4df65111084b7b7e37cfa8fdc9ec1c5332e Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sun, 13 May 2018 16:38:38 +1200
Subject: [PATCH 38/80] OverlayWindow and OverlayWebWindow API JSDoc stubs
---
libraries/ui/src/QmlWebWindowClass.h | 29 ++++++
libraries/ui/src/QmlWindowClass.h | 146 +++++++++++++++++++++++++++
2 files changed, 175 insertions(+)
diff --git a/libraries/ui/src/QmlWebWindowClass.h b/libraries/ui/src/QmlWebWindowClass.h
index cdc07265cd..95ac2eac4a 100644
--- a/libraries/ui/src/QmlWebWindowClass.h
+++ b/libraries/ui/src/QmlWebWindowClass.h
@@ -11,6 +11,17 @@
#include "QmlWindowClass.h"
+/**jsdoc
+ * @class OverlayWebWindow
+ * @augments OverlayWindow
+ * @param {object} [properties=null]
+ *
+ * @hifi-interface
+ * @hifi-client-en
+ *
+ * @property {string} url - Read-only.
+ */
+
// FIXME refactor this class to be a QQuickItem derived type and eliminate the needless wrapping
class QmlWebWindowClass : public QmlWindowClass {
Q_OBJECT
@@ -20,11 +31,29 @@ public:
static QScriptValue constructor(QScriptContext* context, QScriptEngine* engine);
public slots:
+
+ /**jsdoc
+ * @function OverlayWebWindow.getURL
+ * @returns {string}
+ */
QString getURL();
+ /**jsdoc
+ * @function OverlayWebWindow.setURL
+ * @param {string} url
+ */
void setURL(const QString& url);
+
+ /**jsdoc
+ * @function OverlayWebWindow.getURL
+ * @param {string} script
+ */
void setScriptURL(const QString& script);
signals:
+ /**jsdoc
+ * @function OverlayWebWindow.getURL
+ * @returns {Signal}
+ */
void urlChanged();
protected:
diff --git a/libraries/ui/src/QmlWindowClass.h b/libraries/ui/src/QmlWindowClass.h
index f274501d35..34b4d2f7c0 100644
--- a/libraries/ui/src/QmlWindowClass.h
+++ b/libraries/ui/src/QmlWindowClass.h
@@ -19,6 +19,18 @@
class QScriptEngine;
class QScriptContext;
+/**jsdoc
+ * @class OverlayWindow
+ * @param {object} [properties=null]
+ *
+ * @hifi-interface
+ * @hifi-client-en
+ *
+ * @property {Vec2} position
+ * @property {Vec2} size
+ * @property {boolean} visible
+ */
+
// FIXME refactor this class to be a QQuickItem derived type and eliminate the needless wrapping
class QmlWindowClass : public QObject {
Q_OBJECT
@@ -31,46 +43,180 @@ public:
QmlWindowClass();
~QmlWindowClass();
+ /**jsdoc
+ * @function OverlayWindow.initQml
+ * @param {object} properties
+ */
Q_INVOKABLE virtual void initQml(QVariantMap properties);
+
QQuickItem* asQuickItem() const;
public slots:
+
+ /**jsdoc
+ * @function OverlayWindow.isVisible
+ * @returns {boolean}
+ */
bool isVisible();
+
+ /**jsdoc
+ * @function OverlayWindow.setVisible
+ * @param {boolean} visible
+ */
void setVisible(bool visible);
+
+ /**jsdoc
+ * @function OverlayWindow.getPosition
+ * @returns {Vec2}
+ */
glm::vec2 getPosition();
+
+ /**jsdoc
+ * @function OverlayWindow.setPosition
+ * @param {Vec2} position
+ */
void setPosition(const glm::vec2& position);
+
+ /**jsdoc
+ * @function OverlayWindow.setPosition
+ * @param {number} x
+ * @param {number} y
+ */
void setPosition(int x, int y);
+
+ /**jsdoc
+ * @function OverlayWindow.getSize
+ * @returns {Vec2}
+ */
glm::vec2 getSize();
+
+ /**jsdoc
+ * @function OverlayWindow.setSize
+ * @param {Vec2} size
+ */
void setSize(const glm::vec2& size);
+
+ /**jsdoc
+ * @function OverlayWindow.setSize
+ * @param {number} width
+ * @param {number} height
+ */
void setSize(int width, int height);
+
+ /**jsdoc
+ * @function OverlayWindow.setTitle
+ * @param {string} title
+ */
void setTitle(const QString& title);
+
+ /**jsdoc
+ * @function OverlayWindow.raise
+ */
Q_INVOKABLE void raise();
+
+ /**jsdoc
+ * @function OverlayWindow.close
+ */
Q_INVOKABLE void close();
+
+ /**jsdoc
+ * @function OverlayWindow.getEventBridge
+ * @returns {object}
+ */
Q_INVOKABLE QObject* getEventBridge() { return this; };
+
+ /**jsdoc
+ * @function OverlayWindow.sendToQml
+ * @param {object} message
+ */
// Scripts can use this to send a message to the QML object
void sendToQml(const QVariant& message);
+
+ /**jsdoc
+ * @function OverlayWindow.clearDebugWindow
+ */
void clearDebugWindow();
+
+ /**jsdoc
+ * @function OverlayWindow.emitScriptEvent
+ * @param {object} message
+ */
// QmlWindow content may include WebView requiring EventBridge.
void emitScriptEvent(const QVariant& scriptMessage);
+
+ /**jsdoc
+ * @function OverlayWindow.emitWebEvent
+ * @param {object} message
+ */
void emitWebEvent(const QVariant& webMessage);
signals:
+
+ /**jsdoc
+ * @function OverlayWindow.visibleChanged
+ * @returns {Signal}
+ */
void visibleChanged();
+
+ /**jsdoc
+ * @function OverlayWindow.positionChanged
+ * @returns {Signal}
+ */
void positionChanged();
+
+ /**jsdoc
+ * @function OverlayWindow.sizeChanged
+ * @returns {Signal}
+ */
void sizeChanged();
+
+ /**jsdoc
+ * @function OverlayWindow.moved
+ * @param {Vec2} position
+ * @returns {Signal}
+ */
void moved(glm::vec2 position);
+
+ /**jsdoc
+ * @function OverlayWindow.resized
+ * @param {Size} size
+ * @returns {Signal}
+ */
void resized(QSizeF size);
+
+ /**jsdoc
+ * @function OverlayWindow.closed
+ * @returns {Signal}
+ */
void closed();
+
+ /**jsdoc
+ * @function OverlayWindow.fromQml
+ * @param {object} message
+ * @returns {Signal}
+ */
// Scripts can connect to this signal to receive messages from the QML object
void fromQml(const QVariant& message);
+
+ /**jsdoc
+ * @function OverlayWindow.scriptEventReceived
+ * @param {object} message
+ * @returns {Signal}
+ */
// QmlWindow content may include WebView requiring EventBridge.
void scriptEventReceived(const QVariant& message);
+
+ /**jsdoc
+ * @function OverlayWindow.webEventReceived
+ * @param {object} message
+ * @returns {Signal}
+ */
void webEventReceived(const QVariant& message);
protected slots:
From 5378d649133d746c94633ac2b27c3aecd1247b24 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Sun, 13 May 2018 18:06:30 +1200
Subject: [PATCH 39/80] Remove erroneously added function declarations
---
interface/src/ui/Stats.h | 38 --------------------------------------
1 file changed, 38 deletions(-)
diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h
index f44d780d30..ed6e3c9540 100644
--- a/interface/src/ui/Stats.h
+++ b/interface/src/ui/Stats.h
@@ -994,7 +994,6 @@ signals:
* @param {Rect} childrenRect
* @returns {Signal}
*/
- void childrenRectChanged(const QRectF &);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1002,7 +1001,6 @@ signals:
* @param {number} baselineOffset
* @returns {Signal}
*/
- void baselineOffsetChanged(qreal);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1010,7 +1008,6 @@ signals:
* @param {string} state
* @returns {Signal}
*/
- void stateChanged(const QString &);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1018,7 +1015,6 @@ signals:
* @param {boolean} focus
* @returns {Signal}
*/
- void focusChanged(bool);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1026,7 +1022,6 @@ signals:
* @param {boolean} activeFocus
* @returns {Signal}
*/
- void activeFocusChanged(bool);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1034,7 +1029,6 @@ signals:
* @param {boolean} activeFocusOnTab
* @returns {Signal}
*/
- void activeFocusOnTabChanged(bool);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1042,7 +1036,6 @@ signals:
* @param {object} parent
* @returns {Signal}
*/
- void parentChanged(QQuickItem *);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1050,7 +1043,6 @@ signals:
* @param {number} transformOrigin
* @returns {Signal}
*/
- void transformOriginChanged(TransformOrigin);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1058,7 +1050,6 @@ signals:
* @param {boolean} smooth
* @returns {Signal}
*/
- void smoothChanged(bool);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1066,7 +1057,6 @@ signals:
* @param {boolean} antialiasing
* @returns {Signal}
*/
- void antialiasingChanged(bool);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1074,7 +1064,6 @@ signals:
* @param {boolean} clip
* @returns {Signal}
*/
- void clipChanged(bool);
/**jsdoc
* Triggered when the value of the TODO property changes.
@@ -1082,107 +1071,90 @@ signals:
* @param {object} window
* @returns {Signal}
*/
- void windowChanged(QQuickWindow* window);
-
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void childrenChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void opacityChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void enabledChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void visibleChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void visibleChildrenChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void rotationChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void scaleChanged();
-
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void xChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void yChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void widthChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void heightChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void zChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void implicitWidthChanged();
/**jsdoc
* Triggered when the value of the TODO property changes.
* @function Stats.TODO
* @returns {Signal}
*/
- void implicitHeightChanged();
// QQuickItem functions.
@@ -1193,52 +1165,43 @@ signals:
* @param {Size} [targetSize=0,0]
* @returns {boolean}
*/
- Q_INVOKABLE bool grabToImage(const QJSValue &callback, const QSize &targetSize = QSize());
/**jsdoc
* @function Stats.contains
* @param {Vec2} point
* @returns {boolean}
*/
- Q_INVOKABLE virtual bool contains(const QPointF &point) const;
/**jsdoc
* @function Stats.mapFromItem
* @param {object} item
*/
- Q_INVOKABLE void mapFromItem(QQmlV4Function*) const;
/**jsdoc
* @function Stats.mapToItem
* @param {object} item
*/
- Q_INVOKABLE void mapToItem(QQmlV4Function*) const;
/**jsdoc
* @function Stats.mapFromGlobal
* @param {object} global
*/
- Q_INVOKABLE void mapFromGlobal(QQmlV4Function*) const;
/**jsdoc
* @function Stats.mapToGlobal
* @param {object} global
*/
- Q_INVOKABLE void mapToGlobal(QQmlV4Function*) const;
/**jsdoc
* @function Stats.forceActiveFocus
* @param {number} [reason=7]
*/
- Q_INVOKABLE void forceActiveFocus();
- Q_INVOKABLE void forceActiveFocus(Qt::FocusReason reason);
/**jsdoc
* @function Stats.nextItemInFocusChain
* @param {boolean} [forward=true]
* @returns {object}
*/
- Q_INVOKABLE QQuickItem *nextItemInFocusChain(bool forward = true);
/**jsdoc
* @function Stats.childAt
@@ -1246,7 +1209,6 @@ signals:
* @param {number} y
* @returns {object}
*/
- Q_INVOKABLE QQuickItem *childAt(qreal x, qreal y) const;
private:
int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process
From cad5b3fb153c69c06d75f2a82e84b1706eacd16b Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Mon, 14 May 2018 09:28:50 +1200
Subject: [PATCH 40/80] Expand AudioEffectOptions JSDoc stubs
---
libraries/audio/src/AudioEffectOptions.cpp | 24 ++++++++++++
libraries/audio/src/AudioEffectOptions.h | 44 +++++++++++-----------
2 files changed, 46 insertions(+), 22 deletions(-)
diff --git a/libraries/audio/src/AudioEffectOptions.cpp b/libraries/audio/src/AudioEffectOptions.cpp
index 9d3ce9299b..edb0ff52ae 100644
--- a/libraries/audio/src/AudioEffectOptions.cpp
+++ b/libraries/audio/src/AudioEffectOptions.cpp
@@ -58,6 +58,30 @@ static void setOption(QScriptValue arguments, const QString name, float defaultV
variable = arguments.property(name).isNumber() ? (float)arguments.property(name).toNumber() : defaultValue;
}
+/**jsdoc
+ * @typedef {object} AudioEffectOptions.ReverbOptions
+ * @property {number} bandwidth
+ * @property {number} preDelay
+ * @property {number} lateDelay
+ * @property {number} reverbTime
+ * @property {number} earlyDiffusion
+ * @property {number} lateDiffusion
+ * @property {number} roomSize
+ * @property {number} density
+ * @property {number} bassMult
+ * @property {number} bassFreq
+ * @property {number} highGain
+ * @property {number} highFreq
+ * @property {number} modRate
+ * @property {number} modDepth
+ * @property {number} earlyGain
+ * @property {number} lateGain
+ * @property {number} earlyMixLeft
+ * @property {number} earlyMixRight
+ * @property {number} lateMixLeft
+ * @property {number} lateMixRight
+ * @property {number} wetDryMix
+ */
AudioEffectOptions::AudioEffectOptions(QScriptValue arguments) {
setOption(arguments, BANDWIDTH_HANDLE, BANDWIDTH_DEFAULT, _bandwidth);
setOption(arguments, PRE_DELAY_HANDLE, PRE_DELAY_DEFAULT, _preDelay);
diff --git a/libraries/audio/src/AudioEffectOptions.h b/libraries/audio/src/AudioEffectOptions.h
index 18e019731e..1afd4e21be 100644
--- a/libraries/audio/src/AudioEffectOptions.h
+++ b/libraries/audio/src/AudioEffectOptions.h
@@ -17,34 +17,34 @@
/**jsdoc
* @class AudioEffectOptions
- * @param {object} [properties=null]
+ * @param {AudioEffectOptions.ReverbOptions} [reverbOptions=null]
*
* @hifi-interface
* @hifi-client-entity
* @hifi-server-entity
* @hifi-assignment-client
*
- * @property {number} bandwidth
- * @property {number} preDelay
- * @property {number} lateDelay
- * @property {number} reverbTime
- * @property {number} earlyDiffusion
- * @property {number} lateDiffusion
- * @property {number} roomSize
- * @property {number} density
- * @property {number} bassMult
- * @property {number} bassFreq
- * @property {number} highGain
- * @property {number} highFreq
- * @property {number} modRate
- * @property {number} modDepth
- * @property {number} earlyGain
- * @property {number} lateGain
- * @property {number} earlyMixLeft
- * @property {number} earlyMixRight
- * @property {number} lateMixLeft
- * @property {number} lateMixRight
- * @property {number} wetDryMix
+ * @property {number} bandwidth=10000
+ * @property {number} preDelay=20
+ * @property {number} lateDelay=0
+ * @property {number} reverbTime=2
+ * @property {number} earlyDiffusion=100
+ * @property {number} lateDiffusion=100
+ * @property {number} roomSize=50
+ * @property {number} density=100
+ * @property {number} bassMult=1.5
+ * @property {number} bassFreq=250
+ * @property {number} highGain=-6
+ * @property {number} highFreq=3000
+ * @property {number} modRate=2.3
+ * @property {number} modDepth=50
+ * @property {number} earlyGain=0
+ * @property {number} lateGain=0
+ * @property {number} earlyMixLeft=20
+ * @property {number} earlyMixRight=20
+ * @property {number} lateMixLeft=90
+ * @property {number} lateMixRight=90
+ * @property {number} wetDryMix=50
*/
class AudioEffectOptions : public QObject {
From 71355840b992d2b34c2d593e35588a9f3b71ef2d Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Mon, 14 May 2018 09:57:35 +1200
Subject: [PATCH 41/80] Expand OverlayWindow and OverlayWebWindow JSDoc stubs
---
libraries/ui/src/QmlWebWindowClass.h | 2 +-
libraries/ui/src/QmlWindowClass.cpp | 8 ++++++++
libraries/ui/src/QmlWindowClass.h | 21 +++++++++++++++++++--
3 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/libraries/ui/src/QmlWebWindowClass.h b/libraries/ui/src/QmlWebWindowClass.h
index 95ac2eac4a..c35a6bab87 100644
--- a/libraries/ui/src/QmlWebWindowClass.h
+++ b/libraries/ui/src/QmlWebWindowClass.h
@@ -14,7 +14,7 @@
/**jsdoc
* @class OverlayWebWindow
* @augments OverlayWindow
- * @param {object} [properties=null]
+ * @param {OverlayWindow.Properties} [properties=null]
*
* @hifi-interface
* @hifi-client-en
diff --git a/libraries/ui/src/QmlWindowClass.cpp b/libraries/ui/src/QmlWindowClass.cpp
index 02c9707d95..64fa27c8c6 100644
--- a/libraries/ui/src/QmlWindowClass.cpp
+++ b/libraries/ui/src/QmlWindowClass.cpp
@@ -87,6 +87,14 @@ QmlWindowClass::QmlWindowClass() {
}
+/**jsdoc
+ * @typedef {object} OverlayWindow.Properties
+ * @property {string} title
+ * @property {string} source
+ * @property {number} width
+ * @property {number} height
+ * @property {boolean} visible
+ */
void QmlWindowClass::initQml(QVariantMap properties) {
auto offscreenUi = DependencyManager::get();
_source = properties[SOURCE_PROPERTY].toString();
diff --git a/libraries/ui/src/QmlWindowClass.h b/libraries/ui/src/QmlWindowClass.h
index 34b4d2f7c0..2b01c028ea 100644
--- a/libraries/ui/src/QmlWindowClass.h
+++ b/libraries/ui/src/QmlWindowClass.h
@@ -21,7 +21,7 @@ class QScriptContext;
/**jsdoc
* @class OverlayWindow
- * @param {object} [properties=null]
+ * @param {OverlayWindow.Properties} [properties=null]
*
* @hifi-interface
* @hifi-client-en
@@ -45,7 +45,7 @@ public:
/**jsdoc
* @function OverlayWindow.initQml
- * @param {object} properties
+ * @param {OverlayWindow.Properties} properties
*/
Q_INVOKABLE virtual void initQml(QVariantMap properties);
@@ -220,8 +220,25 @@ signals:
void webEventReceived(const QVariant& message);
protected slots:
+
+ /**jsdoc
+ * @function OverlayWindow.hasMoved
+ * @param {Vec2} position
+ * @returns {Signal}
+ */
void hasMoved(QVector2D);
+
+ /**jsdoc
+ * @function OverlayWindow.hasClosed
+ * @returns {Signal}
+ */
void hasClosed();
+
+ /**jsdoc
+ * @function OverlayWindow.qmlToScript
+ * @param {object} message
+ * @returns {Signal}
+ */
void qmlToScript(const QVariant& message);
protected:
From c97d7c9d7324ed1bfc86d5be8ce6d098ba8ca8f7 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Mon, 14 May 2018 10:43:38 +1200
Subject: [PATCH 42/80] Expand and fix ToolbarProxy and ToolbarButtonProxy
JSDoc stubs
---
.../ui/src/ui/ToolbarScriptingInterface.h | 56 ++++++++++++++++++-
1 file changed, 54 insertions(+), 2 deletions(-)
diff --git a/libraries/ui/src/ui/ToolbarScriptingInterface.h b/libraries/ui/src/ui/ToolbarScriptingInterface.h
index 4b9bd79fb3..777eeba9dd 100644
--- a/libraries/ui/src/ui/ToolbarScriptingInterface.h
+++ b/libraries/ui/src/ui/ToolbarScriptingInterface.h
@@ -37,6 +37,32 @@ public:
*/
Q_INVOKABLE void editProperties(const QVariantMap& properties);
+
+ // QmlWrapper methods.
+
+ /**jsdoc
+ * @function ToolbarButtonProxy#writeProperty
+ * @parm {string} propertyName
+ * @param {object} propertyValue
+ */
+
+ /**jsdoc
+ * @function ToolbarButtonProxy#writeProperties
+ * @param {object} properties
+ */
+
+ /**jsdoc
+ * @function ToolbarButtonProxy#readProperty
+ * @param {string} propertyName
+ * @returns {object}
+ */
+
+ /**jsdoc
+ * @function ToolbarButtonProxy#readProperties
+ * @param {string[]} propertyList
+ * @returns {object}
+ */
+
signals:
/**jsdoc
@@ -65,16 +91,42 @@ public:
/**jsdoc
* @function ToolbarProxy#addButton
- * @property {object} properties
+ * @param {object} properties
* @returns {ToolbarButtonProxy}
*/
Q_INVOKABLE ToolbarButtonProxy* addButton(const QVariant& properties);
/**jsdoc
* @function ToolbarProxy#removeButton
- * @property {string} name
+ * @param {string} name
*/
Q_INVOKABLE void removeButton(const QVariant& name);
+
+
+ // QmlWrapper methods.
+
+ /**jsdoc
+ * @function ToolbarProxy#writeProperty
+ * @parm {string} propertyName
+ * @param {object} propertyValue
+ */
+
+ /**jsdoc
+ * @function ToolbarProxy#writeProperties
+ * @param {object} properties
+ */
+
+ /**jsdoc
+ * @function ToolbarProxy#readProperty
+ * @param {string} propertyName
+ * @returns {object}
+ */
+
+ /**jsdoc
+ * @function ToolbarProxy#readProperties
+ * @param {string[]} propertyList
+ * @returns {object}
+ */
};
Q_DECLARE_METATYPE(ToolbarProxy*);
From d0596f8205e492c2a98fff245a568719b98b2313 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Mon, 14 May 2018 10:43:55 +1200
Subject: [PATCH 43/80] Fix Wallet JSDoc stubs
---
interface/src/scripting/WalletScriptingInterface.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h
index 45661d939b..25955ca7a3 100644
--- a/interface/src/scripting/WalletScriptingInterface.h
+++ b/interface/src/scripting/WalletScriptingInterface.h
@@ -83,14 +83,14 @@ signals:
/**jsdoc
* @function Wallet.ownershipVerificationSuccess
- * @property {Uuid} entityID
+ * @param {Uuid} entityID
* @returns {Signal}
*/
void ownershipVerificationSuccess(const QUuid& entityID);
/**jsdoc
* @function Wallet.ownershipVerificationFailed
- * @property {Uuid} entityID
+ * @param {Uuid} entityID
* @returns {Signal}
*/
void ownershipVerificationFailed(const QUuid& entityID);
From 77021f3236c9ac0d707ff3d2711ab1a0a911f67a Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Mon, 14 May 2018 17:32:18 +1200
Subject: [PATCH 44/80] Fix up Stats JSDoc
---
interface/src/ui/Stats.h | 282 +++++++++++++++++++--------------------
1 file changed, 141 insertions(+), 141 deletions(-)
diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h
index ed6e3c9540..5c6a3db064 100644
--- a/interface/src/ui/Stats.h
+++ b/interface/src/ui/Stats.h
@@ -147,6 +147,7 @@ private: \
* @property {boolean} visible
*
* @property {string} state
+ * @property {object} anchors - Read-only.
* @property {number} baselineOffset
*
* @property {boolean} clip
@@ -163,6 +164,8 @@ private: \
* @property {boolean} antialiasing
* @property {number} implicitWidth
* @property {number} implicitHeight
+ *
+ * @property {object} layer - Read-only.
*/
// Properties from x onwards are QQuickItem properties.
@@ -989,173 +992,166 @@ signals:
// QQuickItem signals.
/**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @param {Rect} childrenRect
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @param {number} baselineOffset
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @param {string} state
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @param {boolean} focus
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @param {boolean} activeFocus
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @param {boolean} activeFocusOnTab
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
+ * Triggered when the parent item changes.
+ * @function Stats.parentChanged
* @param {object} parent
* @returns {Signal}
*/
/**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @param {number} transformOrigin
+ * Triggered when the value of the x property changes.
+ * @function Stats.xChanged
* @returns {Signal}
*/
/**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @param {boolean} smooth
+ * Triggered when the value of the y property changes.
+ * @function Stats.yChanged
* @returns {Signal}
*/
/**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @param {boolean} antialiasing
+ * Triggered when the value of the z property changes.
+ * @function Stats.zChanged
* @returns {Signal}
*/
/**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
+ * Triggered when the value of the width property changes.
+ * @function Stats.widthChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the height property changes.
+ * @function Stats.heightChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the opacity property changes.
+ * @function Stats.opacityChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the enabled property changes.
+ * @function Stats.enabledChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the visibleChanged property changes.
+ * @function Stats.visibleChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the list of visible children changes.
+ * @function Stats.visibleChildrenChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the state property changes.
+ * @function Stats.stateChanged
+ * @paramm {string} state
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the position and size of the rectangle containing the children changes.
+ * @function Stats.childrenRectChanged
+ * @param {Rect} childrenRect
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the baselineOffset property changes.
+ * @function Stats.baselineOffsetChanged
+ * @param {number} baselineOffset
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the clip property changes.
+ * @function Stats.clipChanged
* @param {boolean} clip
* @returns {Signal}
*/
/**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
+ * Triggered when the value of the focus property changes.
+ * @function Stats.focusChanged
+ * @param {boolean} focus
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the activeFocus property changes.
+ * @function Stats.activeFocusChanged
+ * @param {boolean} activeFocus
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the activeFocusOnTab property changes.
+ * @function Stats.activeFocusOnTabChanged
+ * @param {boolean} activeFocusOnTab
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the rotation property changes.
+ * @function Stats.rotationChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the scaleChanged property changes.
+ * @function Stats.scaleChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the transformOrigin property changes.
+ * @function Stats.transformOriginChanged
+ * @param {number} transformOrigin
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the smooth property changes.
+ * @function Stats.smoothChanged
+ * @param {boolean} smooth
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the antialiasing property changes.
+ * @function Stats.antialiasingChanged
+ * @param {boolean} antialiasing
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the implicitWidth property changes.
+ * @function Stats.implicitWidthChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * Triggered when the value of the implicitHeight property changes.
+ * @function Stats.implicitHeightChanged
+ * @returns {Signal}
+ */
+
+ /**jsdoc
+ * @function Stats.windowChanged
* @param {object} window
* @returns {Signal}
*/
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
- /**jsdoc
- * Triggered when the value of the TODO property changes.
- * @function Stats.TODO
- * @returns {Signal}
- */
-
// QQuickItem functions.
@@ -1210,6 +1206,10 @@ signals:
* @returns {object}
*/
+ /**jsdoc
+ * @function Stats.update
+ */
+
private:
int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process
bool _resetRecentMaxPacketsSoon{ true };
From 20fb9034f8bb1727d7df603cd14d812af4c6c5fd Mon Sep 17 00:00:00 2001
From: Thijs Wenker
Date: Mon, 14 May 2018 20:11:55 +0200
Subject: [PATCH 45/80] no magic numbers, except -1, 0, 1
---
.eslintrc.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.eslintrc.js b/.eslintrc.js
index ddcc03055a..804e2bc928 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -79,7 +79,7 @@ module.exports = {
"new-cap": ["error"],
"no-console": ["off"],
"no-floating-decimal": ["error"],
- // "no-magic-numbers": ["error", {"ignore": [0, 1], "ignoreArrayIndexes": true}],
+ "no-magic-numbers": ["error", {"ignore": [-1, 0, 1], "ignoreArrayIndexes": true}],
"no-multi-spaces": ["error"],
"no-multiple-empty-lines": ["error"],
"no-unused-vars": ["error", {"args": "none", "vars": "local"}],
From a1de44310f2f9ff89d1ac9abec84ebbd4faca329 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Tue, 15 May 2018 10:02:38 +1200
Subject: [PATCH 46/80] tabletInterface API JSDoc
---
.../ui/src/ui/TabletScriptingInterface.h | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/libraries/ui/src/ui/TabletScriptingInterface.h b/libraries/ui/src/ui/TabletScriptingInterface.h
index e74b846f02..f30c6de75e 100644
--- a/libraries/ui/src/ui/TabletScriptingInterface.h
+++ b/libraries/ui/src/ui/TabletScriptingInterface.h
@@ -44,6 +44,14 @@ class OffscreenQmlSurface;
* @hifi-interface
* @hifi-client-entity
*/
+/**jsdoc
+ * @namespace tabletInterface
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ *
+ * @deprecated This API is deprecated and will be removed. Use {@link Tablet} instead.
+ */
class TabletScriptingInterface : public QObject, public Dependency {
Q_OBJECT
public:
@@ -83,6 +91,13 @@ public:
* @param {string} name - Tablet name.
* @returns {TabletProxy} Tablet instance.
*/
+ /**jsdoc
+ * Creates or returns a new TabletProxy and returns it.
+ * @function tabletInterface.getTablet
+ * @param {string} name - Tablet name.
+ * @returns {TabletProxy} Tablet instance.
+ * @deprecated This function is deprecated and will be removed. Use {@link Tablet.getTablet} instead.
+ */
Q_INVOKABLE TabletProxy* getTablet(const QString& tabletId);
void preloadSounds();
@@ -91,6 +106,11 @@ public:
* @function Tablet.playSound
* @param {Tablet.AudioEvents} sound
*/
+ /**jsdoc
+ * @function tabletInterface.playSound
+ * @param {Tablet.AudioEvents} sound
+ * @deprecated This function is deprecated and will be removed. Use {@link Tablet.playSound} instead.
+ */
Q_INVOKABLE void playSound(TabletAudioEvents aEvent);
void setToolbarMode(bool toolbarMode);
@@ -108,6 +128,12 @@ signals:
* @function Tablet.tabletNotification
* @returns {Signal}
*/
+ /**jsdoc
+ * Triggered when a tablet message or dialog is created.
+ * @function tabletInterface.tabletNotification
+ * @returns {Signal}
+ * @deprecated This function is deprecated and will be removed. Use {@link Tablet.tabletNotification} instead.
+ */
void tabletNotification();
private:
From 50f76dd4df4db78e3644d6328e19405bfcb87184 Mon Sep 17 00:00:00 2001
From: Thijs Wenker
Date: Tue, 15 May 2018 00:11:34 +0200
Subject: [PATCH 47/80] added more missing globals
---
.eslintrc.js | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/.eslintrc.js b/.eslintrc.js
index 804e2bc928..04d4a820d8 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -12,7 +12,11 @@ module.exports = {
"Audio": false,
"AudioDevice": false,
"AudioEffectOptions": false,
+ "AudioScope": false,
+ "AudioStats": false,
"Avatar": false,
+ "AvatarBookmarks": false,
+ "AvatarInputs": false,
"AvatarList": false,
"AvatarManager": false,
"Camera": false,
@@ -21,25 +25,38 @@ module.exports = {
"ContextOverlay": false,
"Controller": false,
"DebugDraw": false,
+ "Desktop": false,
+ "DesktopPreviewProvider": false,
"DialogsManager": false,
"Entities": false,
"EntityViewer": false,
"FaceTracker": false,
"GlobalServices": false,
+ "GooglePoly": false,
+ "Graphics": false,
"HMD": false,
"LaserPointers": false,
"location": true,
+ "LocationBookmarks": false,
"LODManager": false,
"Mat4": false,
"Menu": false,
"Messages": false,
+ "Midi": false,
"ModelCache": false,
"module": false,
"MyAvatar": false,
+ "OffscreenFlags": false,
"Overlays": false,
"OverlayWebWindow": false,
+ "OverlayWindow": false,
"Paths": false,
+ "Picks": false,
+ "PickType": false,
+ "PointerEvent": false,
+ "Pointers": false,
"print": false,
+ "QmlFragment": false,
"Quat": false,
"Rates": false,
"RayPick": false,
@@ -50,17 +67,22 @@ module.exports = {
"Scene": false,
"Script": false,
"ScriptDiscoveryService": false,
+ "Selection": false,
"Settings": false,
+ "Snapshot": false,
"SoundCache": false,
+ "SpeechRecognizer": false,
"Stats": false,
+ "Steam": false,
"Tablet": false,
"TextureCache": false,
"Toolbars": false,
"UndoStack": false,
- "Users": false,
"UserActivityLogger": false,
+ "Users": false,
"Uuid": false,
"Vec3": false,
+ "Wallet": false,
"WebSocket": false,
"WebWindow": false,
"Window": false,
From 8ea3a733cad0e756bde226b6b44b3a6bd7b04cfe Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Tue, 15 May 2018 10:32:36 +1200
Subject: [PATCH 48/80] Resource API JSDoc stub
---
libraries/networking/src/ResourceCache.h | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h
index e2df582aa3..18840cd11e 100644
--- a/libraries/networking/src/ResourceCache.h
+++ b/libraries/networking/src/ResourceCache.h
@@ -86,7 +86,6 @@ private:
/// Wrapper to expose resources to JS/QML
class ScriptableResource : public QObject {
-
/**jsdoc
* @constructor Resource
*
@@ -98,12 +97,15 @@ class ScriptableResource : public QObject {
* @property {string} url - URL of this resource.
* @property {Resource.State} state - Current loading state.
*/
-
+ /**jsdoc
+ * @namespace Resource
+ * @variation 0
+ * @property {Resource.State} State
+ */
Q_OBJECT
Q_PROPERTY(QUrl url READ getURL)
Q_PROPERTY(int state READ getState NOTIFY stateChanged)
-
public:
/**jsdoc
@@ -115,7 +117,6 @@ public:
* @property {number} FINISHED - The resource has completely finished loading and is ready.
* @property {number} FAILED - Downloading the resource has failed.
*/
-
enum State {
QUEUED,
LOADING,
From 3fb6fd1afb28211012257a215bf538a469bda5f1 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Tue, 15 May 2018 11:22:47 +1200
Subject: [PATCH 49/80] Picks API JSDoc stubs
---
.../src/raypick/PickScriptingInterface.cpp | 22 +++
.../src/raypick/PickScriptingInterface.h | 140 +++++++++++++-----
2 files changed, 122 insertions(+), 40 deletions(-)
diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp
index 1bf6dd2f8e..654063bebc 100644
--- a/interface/src/raypick/PickScriptingInterface.cpp
+++ b/interface/src/raypick/PickScriptingInterface.cpp
@@ -31,6 +31,20 @@ unsigned int PickScriptingInterface::createPick(const PickQuery::PickType type,
}
}
+/**jsdoc
+ * A set of properties that can be passed to {@link Picks.createPick} to create a new Ray Pick.
+ * @typedef {object} Picks.RayPickProperties
+ * @property {boolean} [enabled=false] If this Pick should start enabled or not. Disabled Picks do not updated their pick results.
+ * @property {number} [filter=Picks.PICK_NOTHING] The filter for this Pick to use, constructed using filter flags combined using bitwise OR.
+ * @property {float} [maxDistance=0.0] The max distance at which this Pick will intersect. 0.0 = no max. < 0.0 is invalid.
+ * @property {string} [joint] Only for Joint or Mouse Ray Picks. If "Mouse", it will create a Ray Pick that follows the system mouse, in desktop or HMD.
+ * If "Avatar", it will create a Joint Ray Pick that follows your avatar's head. Otherwise, it will create a Joint Ray Pick that follows the given joint, if it
+ * exists on your current avatar.
+ * @property {Vec3} [posOffset=Vec3.ZERO] Only for Joint Ray Picks. A local joint position offset, in meters. x = upward, y = forward, z = lateral
+ * @property {Vec3} [dirOffset=Vec3.UP] Only for Joint Ray Picks. A local joint direction offset. x = upward, y = forward, z = lateral
+ * @property {Vec3} [position] Only for Static Ray Picks. The world-space origin of the ray.
+ * @property {Vec3} [direction=-Vec3.UP] Only for Static Ray Picks. The world-space direction of the ray.
+ */
unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) {
QVariantMap propMap = properties.toMap();
@@ -83,6 +97,14 @@ unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) {
return PickManager::INVALID_PICK_ID;
}
+/**jsdoc
+ * A set of properties that can be passed to {@link Picks.createPick} to create a new Ray Pick.
+ * @typedef {object} Picks.StylusPickProperties
+ * @property {number} [hand=-1] An integer. 0 == left, 1 == right. Invalid otherwise.
+ * @property {boolean} [enabled=false] If this Pick should start enabled or not. Disabled Picks do not updated their pick results.
+ * @property {number} [filter=Picks.PICK_NOTHING] The filter for this Pick to use, constructed using filter flags combined using bitwise OR.
+ * @property {float} [maxDistance=0.0] The max distance at which this Pick will intersect. 0.0 = no max. < 0.0 is invalid.
+ */
unsigned int PickScriptingInterface::createStylusPick(const QVariant& properties) {
QVariantMap propMap = properties.toMap();
diff --git a/interface/src/raypick/PickScriptingInterface.h b/interface/src/raypick/PickScriptingInterface.h
index 2568dd8457..4eb3fface2 100644
--- a/interface/src/raypick/PickScriptingInterface.h
+++ b/interface/src/raypick/PickScriptingInterface.h
@@ -22,19 +22,22 @@
* @hifi-interface
* @hifi-client-entity
*
- * @property PICK_NOTHING {number} A filter flag. Don't intersect with anything.
- * @property PICK_ENTITIES {number} A filter flag. Include entities when intersecting.
- * @property PICK_OVERLAYS {number} A filter flag. Include overlays when intersecting.
- * @property PICK_AVATARS {number} A filter flag. Include avatars when intersecting.
- * @property PICK_HUD {number} A filter flag. Include the HUD sphere when intersecting in HMD mode.
- * @property PICK_COARSE {number} A filter flag. Pick against coarse meshes, instead of exact meshes.
- * @property PICK_INCLUDE_INVISIBLE {number} A filter flag. Include invisible objects when intersecting.
- * @property PICK_INCLUDE_NONCOLLIDABLE {number} A filter flag. Include non-collidable objects when intersecting.
- * @property INTERSECTED_NONE {number} An intersection type. Intersected nothing with the given filter flags.
- * @property INTERSECTED_ENTITY {number} An intersection type. Intersected an entity.
- * @property INTERSECTED_OVERLAY {number} An intersection type. Intersected an overlay.
- * @property INTERSECTED_AVATAR {number} An intersection type. Intersected an avatar.
- * @property INTERSECTED_HUD {number} An intersection type. Intersected the HUD sphere.
+ * @property PICK_NOTHING {number} A filter flag. Don't intersect with anything. Read-only.
+ * @property PICK_ENTITIES {number} A filter flag. Include entities when intersecting. Read-only.
+ * @property PICK_OVERLAYS {number} A filter flag. Include overlays when intersecting. Read-only.
+ * @property PICK_AVATARS {number} A filter flag. Include avatars when intersecting. Read-only.
+ * @property PICK_HUD {number} A filter flag. Include the HUD sphere when intersecting in HMD mode. Read-only.
+ * @property PICK_COARSE {number} A filter flag. Pick against coarse meshes, instead of exact meshes. Read-only.
+ * @property PICK_INCLUDE_INVISIBLE {number} A filter flag. Include invisible objects when intersecting. Read-only.
+ * @property PICK_INCLUDE_NONCOLLIDABLE {number} A filter flag. Include non-collidable objects when intersecting.
+ * Read-only.
+ * @property PICK_ALL_INTERSECTIONS {number} Read-only.
+ * @property INTERSECTED_NONE {number} An intersection type. Intersected nothing with the given filter flags. Read-only.
+ * @property INTERSECTED_ENTITY {number} An intersection type. Intersected an entity. Read-only.
+ * @property INTERSECTED_OVERLAY {number} An intersection type. Intersected an overlay. Read-only.
+ * @property INTERSECTED_AVATAR {number} An intersection type. Intersected an avatar. Read-only.
+ * @property INTERSECTED_HUD {number} An intersection type. Intersected the HUD sphere. Read-only.
+ * @property {number} perFrameTimeBudget - The max number of usec to spend per frame updating Pick results. Read-only.
*/
class PickScriptingInterface : public QObject, public Dependency {
@@ -61,46 +64,31 @@ public:
void registerMetaTypes(QScriptEngine* engine);
- /**jsdoc
- * A set of properties that can be passed to {@link Picks.createPick} to create a new Pick.
- *
- * Different {@link Picks.PickType}s use different properties, and within one PickType, the properties you choose can lead to a wide range of behaviors. For example,
- * with PickType.Ray, depending on which optional parameters you pass, you could create a Static Ray Pick, a Mouse Ray Pick, or a Joint Ray Pick.
- *
- * @typedef {Object} Picks.PickProperties
- * @property {boolean} [enabled=false] If this Pick should start enabled or not. Disabled Picks do not updated their pick results.
- * @property {number} [filter=Picks.PICK_NOTHING] The filter for this Pick to use, constructed using filter flags combined using bitwise OR.
- * @property {float} [maxDistance=0.0] The max distance at which this Pick will intersect. 0.0 = no max. < 0.0 is invalid.
- * @property {string} [joint] Only for Joint or Mouse Ray Picks. If "Mouse", it will create a Ray Pick that follows the system mouse, in desktop or HMD.
- * If "Avatar", it will create a Joint Ray Pick that follows your avatar's head. Otherwise, it will create a Joint Ray Pick that follows the given joint, if it
- * exists on your current avatar.
- * @property {Vec3} [posOffset=Vec3.ZERO] Only for Joint Ray Picks. A local joint position offset, in meters. x = upward, y = forward, z = lateral
- * @property {Vec3} [dirOffset=Vec3.UP] Only for Joint Ray Picks. A local joint direction offset. x = upward, y = forward, z = lateral
- * @property {Vec3} [position] Only for Static Ray Picks. The world-space origin of the ray.
- * @property {Vec3} [direction=-Vec3.UP] Only for Static Ray Picks. The world-space direction of the ray.
- * @property {number} [hand=-1] Only for Stylus Picks. An integer. 0 == left, 1 == right. Invalid otherwise.
- */
-
/**jsdoc
* Adds a new Pick.
+ * Different {@link PickType}s use different properties, and within one PickType, the properties you choose can lead to a wide range of behaviors. For example,
+ * with PickType.Ray, depending on which optional parameters you pass, you could create a Static Ray Pick, a Mouse Ray Pick, or a Joint Ray Pick.
* @function Picks.createPick
- * @param {Picks.PickType} type A PickType that specifies the method of picking to use
- * @param {Picks.PickProperties} properties A PickProperties object, containing all the properties for initializing this Pick
+ * @param {PickType} type A PickType that specifies the method of picking to use
+ * @param {Picks.RayPickProperties|Picks.StylusPickProperties} properties A PickProperties object, containing all the properties for initializing this Pick
* @returns {number} The ID of the created Pick. Used for managing the Pick. 0 if invalid.
*/
Q_INVOKABLE unsigned int createPick(const PickQuery::PickType type, const QVariant& properties);
+
/**jsdoc
* Enables a Pick.
* @function Picks.enablePick
* @param {number} uid The ID of the Pick, as returned by {@link Picks.createPick}.
*/
Q_INVOKABLE void enablePick(unsigned int uid);
+
/**jsdoc
* Disables a Pick.
* @function Picks.disablePick
* @param {number} uid The ID of the Pick, as returned by {@link Picks.createPick}.
*/
Q_INVOKABLE void disablePick(unsigned int uid);
+
/**jsdoc
* Removes a Pick.
* @function Picks.removePick
@@ -140,7 +128,7 @@ public:
* Get the most recent pick result from this Pick. This will be updated as long as the Pick is enabled.
* @function Picks.getPrevPickResult
* @param {number} uid The ID of the Pick, as returned by {@link Picks.createPick}.
- * @returns {PickResult} The most recent intersection result. This will be slightly different for different PickTypes. See {@link Picks.RayPickResult} and {@link Picks.StylusPickResult}.
+ * @returns {Picks.RayPickResult|Picks.StylusPickResult} The most recent intersection result. This will be different for different PickTypes.
*/
Q_INVOKABLE QVariantMap getPrevPickResult(unsigned int uid);
@@ -151,6 +139,7 @@ public:
* @param {boolean} precisionPicking Whether or not to use precision picking
*/
Q_INVOKABLE void setPrecisionPicking(unsigned int uid, bool precisionPicking);
+
/**jsdoc
* Sets a list of Entity IDs, Overlay IDs, and/or Avatar IDs to ignore during intersection. Not used by Stylus Picks.
* @function Picks.setIgnoreItems
@@ -158,6 +147,7 @@ public:
* @param {Uuid[]} ignoreItems A list of IDs to ignore.
*/
Q_INVOKABLE void setIgnoreItems(unsigned int uid, const QScriptValue& ignoreItems);
+
/**jsdoc
* Sets a list of Entity IDs, Overlay IDs, and/or Avatar IDs to include during intersection, instead of intersecting with everything. Stylus
* Picks only intersect with objects in their include list.
@@ -174,6 +164,7 @@ public:
* @returns {boolean} True if the Pick is a Joint Ray Pick with joint == "_CONTROLLER_LEFTHAND" or "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", or a Stylus Pick with hand == 0.
*/
Q_INVOKABLE bool isLeftHand(unsigned int uid);
+
/**jsdoc
* Check if a Pick is associated with the right hand.
* @function Picks.isRightHand
@@ -181,6 +172,7 @@ public:
* @returns {boolean} True if the Pick is a Joint Ray Pick with joint == "_CONTROLLER_RIGHTHAND" or "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND", or a Stylus Pick with hand == 1.
*/
Q_INVOKABLE bool isRightHand(unsigned int uid);
+
/**jsdoc
* Check if a Pick is associated with the system mouse.
* @function Picks.isMouse
@@ -189,28 +181,96 @@ public:
*/
Q_INVOKABLE bool isMouse(unsigned int uid);
+ // FIXME: Move to other property definitions.
Q_PROPERTY(unsigned int perFrameTimeBudget READ getPerFrameTimeBudget WRITE setPerFrameTimeBudget)
- /**jsdoc
- * The max number of usec to spend per frame updating Pick results.
- * @typedef {number} Picks.perFrameTimeBudget
- */
+
unsigned int getPerFrameTimeBudget() const;
void setPerFrameTimeBudget(unsigned int numUsecs);
public slots:
+
+ /**jsdoc
+ * @function Picks.PICK_NOTHING
+ * @returns {number}
+ */
static constexpr unsigned int PICK_NOTHING() { return 0; }
+
+ /**jsdoc
+ * @function Picks.PICK_ENTITIES
+ * @returns {number}
+ */
static constexpr unsigned int PICK_ENTITIES() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ENTITIES); }
+
+ /**jsdoc
+ * @function Picks.PICK_OVERLAYS
+ * @returns {number}
+ */
static constexpr unsigned int PICK_OVERLAYS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_OVERLAYS); }
+
+ /**jsdoc
+ * @function Picks.PICK_AVATARS
+ * @returns {number}
+ */
static constexpr unsigned int PICK_AVATARS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_AVATARS); }
+
+ /**jsdoc
+ * @function Picks.PICK_HUD
+ * @returns {number}
+ */
static constexpr unsigned int PICK_HUD() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_HUD); }
+
+ /**jsdoc
+ * @function Picks.PICK_COARSE
+ * @returns {number}
+ */
static constexpr unsigned int PICK_COARSE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_COARSE); }
+
+ /**jsdoc
+ * @function Picks.PICK_INCLUDE_INVISIBLE
+ * @returns {number}
+ */
static constexpr unsigned int PICK_INCLUDE_INVISIBLE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_INCLUDE_INVISIBLE); }
+
+ /**jsdoc
+ * @function Picks.PICK_INCLUDE_NONCOLLIDABLE
+ * @returns {number}
+ */
static constexpr unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_INCLUDE_NONCOLLIDABLE); }
+
+ /**jsdoc
+ * @function Picks.PICK_ALL_INTERSECTIONS
+ * @returns {number}
+ */
static constexpr unsigned int PICK_ALL_INTERSECTIONS() { return PickFilter::getBitMask(PickFilter::FlagBit::PICK_ALL_INTERSECTIONS); }
+
+ /**jsdoc
+ * @function Picks.INTERSECTED_NONE
+ * @returns {number}
+ */
static constexpr unsigned int INTERSECTED_NONE() { return IntersectionType::NONE; }
+
+ /**jsdoc
+ * @function Picks.INTERSECTED_ENTITY
+ * @returns {number}
+ */
static constexpr unsigned int INTERSECTED_ENTITY() { return IntersectionType::ENTITY; }
+
+ /**jsdoc
+ * @function Picks.INTERSECTED_OVERLAY
+ * @returns {number}
+ */
static constexpr unsigned int INTERSECTED_OVERLAY() { return IntersectionType::OVERLAY; }
+
+ /**jsdoc
+ * @function Picks.INTERSECTED_AVATAR
+ * @returns {number}
+ */
static constexpr unsigned int INTERSECTED_AVATAR() { return IntersectionType::AVATAR; }
+
+ /**jsdoc
+ * @function Picks.INTERSECTED_HUD
+ * @returns {number}
+ */
static constexpr unsigned int INTERSECTED_HUD() { return IntersectionType::HUD; }
};
From 36752ee7012ae138694090bf64ef9bd94ed932ae Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Tue, 15 May 2018 11:23:29 +1200
Subject: [PATCH 50/80] PickType API JSDoc fix up
---
libraries/pointers/src/Pick.h | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/libraries/pointers/src/Pick.h b/libraries/pointers/src/Pick.h
index 68c89a59cb..caaeae6725 100644
--- a/libraries/pointers/src/Pick.h
+++ b/libraries/pointers/src/Pick.h
@@ -135,12 +135,13 @@ public:
PickQuery(const PickFilter& filter, const float maxDistance, const bool enabled);
/**jsdoc
- * @namespace
- * @augments Picks
- *
* Enum for different types of Picks and Pointers.
*
- * @typedef {enum} Picks.PickType
+ * @namespace PickType
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ *
* @property {number} Ray Ray Picks intersect a ray with the nearest object in front of them, along a given direction.
* @property {number} Stylus Stylus Picks provide "tapping" functionality on/into flat surfaces.
*/
From 9040e45be7d8f72d60c8dc9af78b7ff7f0d3d168 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Tue, 15 May 2018 11:43:49 +1200
Subject: [PATCH 51/80] RayPick API JSDoc stubs
---
.../src/raypick/RayPickScriptingInterface.h | 157 ++++++++++++++++++
1 file changed, 157 insertions(+)
diff --git a/interface/src/raypick/RayPickScriptingInterface.h b/interface/src/raypick/RayPickScriptingInterface.h
index 3795f191b3..ce692e2003 100644
--- a/interface/src/raypick/RayPickScriptingInterface.h
+++ b/interface/src/raypick/RayPickScriptingInterface.h
@@ -18,6 +18,30 @@
#include "PickScriptingInterface.h"
+/**jsdoc
+ * Synonym for {@link Picks} as used for ray picks.
+ *
+ * @namespace RayPick
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ *
+ * @property {number} PICK_NOTHING Read-only.
+ * @property {number} PICK_ENTITIES Read-only.
+ * @property {number} PICK_OVERLAYS Read-only.
+ * @property {number} PICK_AVATARS Read-only.
+ * @property {number} PICK_HUD Read-only.
+ * @property {number} PICK_COARSE Read-only.
+ * @property {number} PICK_INCLUDE_INVISIBLE Read-only.
+ * @property {number} PICK_INCLUDE_NONCOLLIDABLE Read-only.
+ * @property {number} PICK_ALL_INTERSECTIONS Read-only.
+ * @property {number} INTERSECTED_NONE Read-only.
+ * @property {number} INTERSECTED_ENTITY Read-only.
+ * @property {number} INTERSECTED_OVERLAY Read-only.
+ * @property {number} INTERSECTED_AVATAR Read-only.
+ * @property {number} INTERSECTED_HUD Read-only.
+ */
+
class RayPickScriptingInterface : public QObject, public Dependency {
Q_OBJECT
Q_PROPERTY(unsigned int PICK_NOTHING READ PICK_NOTHING CONSTANT)
@@ -37,34 +61,167 @@ class RayPickScriptingInterface : public QObject, public Dependency {
SINGLETON_DEPENDENCY
public:
+
+ /**jsdoc
+ * @function RayPick.createRayPick
+ * @param {Picks.RayPickProperties}
+ * @returns {number}
+ */
Q_INVOKABLE unsigned int createRayPick(const QVariant& properties);
+
+ /**jsdoc
+ * @function RayPick.enableRayPick
+ * @param {number} id
+ */
Q_INVOKABLE void enableRayPick(unsigned int uid);
+
+ /**jsdoc
+ * @function RayPick.disableRayPick
+ * @param {number} id
+ */
Q_INVOKABLE void disableRayPick(unsigned int uid);
+
+ /**jsdoc
+ * @function RayPick.removeRayPick
+ * @param {number} id
+ */
Q_INVOKABLE void removeRayPick(unsigned int uid);
+
+ /**jsdoc
+ * @function RayPick.getPrevRayPickResult
+ * @param {number} id
+ * @returns {Picks.RayPickResult}
+ */
Q_INVOKABLE QVariantMap getPrevRayPickResult(unsigned int uid);
+
+ /**jsdoc
+ * @function RayPick.setPrecisionPicking
+ * @param {number} id
+ * @param {boolean} precisionPicking
+ */
Q_INVOKABLE void setPrecisionPicking(unsigned int uid, bool precisionPicking);
+
+ /**jsdoc
+ * @function RayPick.setIgnoreItems
+ * @param {number} id
+ * @param {Uuid[]) ignoreEntities
+ */
Q_INVOKABLE void setIgnoreItems(unsigned int uid, const QScriptValue& ignoreEntities);
+
+ /**jsdoc
+ * @function RayPick.setIncludeItems
+ * @param {number} id
+ * @param {Uuid[]) includeEntities
+ */
Q_INVOKABLE void setIncludeItems(unsigned int uid, const QScriptValue& includeEntities);
+
+ /**jsdoc
+ * @function RayPick.isLeftHand
+ * @param {number} id
+ * @returns {boolean}
+ */
Q_INVOKABLE bool isLeftHand(unsigned int uid);
+
+ /**jsdoc
+ * @function RayPick.isRightHand
+ * @param {number} id
+ * @returns {boolean}
+ */
Q_INVOKABLE bool isRightHand(unsigned int uid);
+
+ /**jsdoc
+ * @function RayPick.isMouse
+ * @param {number} id
+ * @returns {boolean}
+ */
Q_INVOKABLE bool isMouse(unsigned int uid);
public slots:
+
+ /**jsdoc
+ * @function RayPick.PICK_NOTHING
+ * @returns {number}
+ */
static unsigned int PICK_NOTHING() { return PickScriptingInterface::PICK_NOTHING(); }
+
+ /**jsdoc
+ * @function RayPick.PICK_ENTITIES
+ * @returns {number}
+ */
static unsigned int PICK_ENTITIES() { return PickScriptingInterface::PICK_ENTITIES(); }
+
+ /**jsdoc
+ * @function RayPick.PICK_OVERLAYS
+ * @returns {number}
+ */
static unsigned int PICK_OVERLAYS() { return PickScriptingInterface::PICK_OVERLAYS(); }
+
+ /**jsdoc
+ * @function RayPick.PICK_AVATARS
+ * @returns {number}
+ */
static unsigned int PICK_AVATARS() { return PickScriptingInterface::PICK_AVATARS(); }
+
+ /**jsdoc
+ * @function RayPick.PICK_HUD
+ * @returns {number}
+ */
static unsigned int PICK_HUD() { return PickScriptingInterface::PICK_HUD(); }
+
+ /**jsdoc
+ * @function RayPick.PICK_COARSE
+ * @returns {number}
+ */
static unsigned int PICK_COARSE() { return PickScriptingInterface::PICK_COARSE(); }
+
+ /**jsdoc
+ * @function RayPick.PICK_INCLUDE_INVISIBLE
+ * @returns {number}
+ */
static unsigned int PICK_INCLUDE_INVISIBLE() { return PickScriptingInterface::PICK_INCLUDE_INVISIBLE(); }
+
+ /**jsdoc
+ * @function RayPick.PICK_INCLUDE_NONCOLLIDABLE
+ * @returns {number}
+ */
static unsigned int PICK_INCLUDE_NONCOLLIDABLE() { return PickScriptingInterface::PICK_INCLUDE_NONCOLLIDABLE(); }
+
+ /**jsdoc
+ * @function RayPick.PICK_ALL_INTERSECTIONS
+ * @returns {number}
+ */
static unsigned int PICK_ALL_INTERSECTIONS() { return PickScriptingInterface::PICK_ALL_INTERSECTIONS(); }
+
+ /**jsdoc
+ * @function RayPick.INTERSECTED_NONE
+ * @returns {number}
+ */
static unsigned int INTERSECTED_NONE() { return PickScriptingInterface::INTERSECTED_NONE(); }
+
+ /**jsdoc
+ * @function RayPick.INTERSECTED_ENTITY
+ * @returns {number}
+ */
static unsigned int INTERSECTED_ENTITY() { return PickScriptingInterface::INTERSECTED_ENTITY(); }
+
+ /**jsdoc
+ * @function RayPick.INTERSECTED_OVERLAY
+ * @returns {number}
+ */
static unsigned int INTERSECTED_OVERLAY() { return PickScriptingInterface::INTERSECTED_OVERLAY(); }
+
+ /**jsdoc
+ * @function RayPick.INTERSECTED_AVATAR
+ * @returns {number}
+ */
static unsigned int INTERSECTED_AVATAR() { return PickScriptingInterface::INTERSECTED_AVATAR(); }
+
+ /**jsdoc
+ * @function RayPick.INTERSECTED_HUD
+ * @returns {number}
+ */
static unsigned int INTERSECTED_HUD() { return PickScriptingInterface::INTERSECTED_HUD(); }
};
From 82befc88628738b9ebde348601b28d5d6789fb2f Mon Sep 17 00:00:00 2001
From: Thijs Wenker
Date: Tue, 15 May 2018 06:21:26 +0200
Subject: [PATCH 52/80] ignore 0.5 and 2 as magic-numbers
---
.eslintrc.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.eslintrc.js b/.eslintrc.js
index 04d4a820d8..7409893020 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -101,7 +101,7 @@ module.exports = {
"new-cap": ["error"],
"no-console": ["off"],
"no-floating-decimal": ["error"],
- "no-magic-numbers": ["error", {"ignore": [-1, 0, 1], "ignoreArrayIndexes": true}],
+ "no-magic-numbers": ["error", {"ignore": [0.5, -1, 0, 1, 2], "ignoreArrayIndexes": true}],
"no-multi-spaces": ["error"],
"no-multiple-empty-lines": ["error"],
"no-unused-vars": ["error", {"args": "none", "vars": "local"}],
From b20741baba03870f67cb36200f6ff5f1efadecf3 Mon Sep 17 00:00:00 2001
From: Thijs Wenker
Date: Tue, 15 May 2018 06:36:01 +0200
Subject: [PATCH 53/80] web-scripting globals
---
.eslintrc.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.eslintrc.js b/.eslintrc.js
index 7409893020..67921be395 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -28,8 +28,10 @@ module.exports = {
"Desktop": false,
"DesktopPreviewProvider": false,
"DialogsManager": false,
+ "document": false,
"Entities": false,
"EntityViewer": false,
+ "EventBridge": false,
"FaceTracker": false,
"GlobalServices": false,
"GooglePoly": false,
From 8e9799b80f0ea1056be26764bb308416d3347e3e Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Tue, 15 May 2018 16:36:42 +1200
Subject: [PATCH 54/80] Pointers API JSDoc fix up
---
.../src/raypick/PickScriptingInterface.cpp | 2 +-
.../src/raypick/PickScriptingInterface.h | 6 +-
.../src/raypick/PointerScriptingInterface.cpp | 48 ++++++++++++
.../src/raypick/PointerScriptingInterface.h | 73 +++++--------------
.../src/raypick/RayPickScriptingInterface.h | 2 +-
libraries/pointers/src/Pick.h | 13 ++++
6 files changed, 86 insertions(+), 58 deletions(-)
diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp
index 654063bebc..8da6e7c615 100644
--- a/interface/src/raypick/PickScriptingInterface.cpp
+++ b/interface/src/raypick/PickScriptingInterface.cpp
@@ -98,7 +98,7 @@ unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) {
}
/**jsdoc
- * A set of properties that can be passed to {@link Picks.createPick} to create a new Ray Pick.
+ * A set of properties that can be passed to {@link Picks.createPick} to create a new Stylus Pick.
* @typedef {object} Picks.StylusPickProperties
* @property {number} [hand=-1] An integer. 0 == left, 1 == right. Invalid otherwise.
* @property {boolean} [enabled=false] If this Pick should start enabled or not. Disabled Picks do not updated their pick results.
diff --git a/interface/src/raypick/PickScriptingInterface.h b/interface/src/raypick/PickScriptingInterface.h
index 4eb3fface2..a39aa3a4a1 100644
--- a/interface/src/raypick/PickScriptingInterface.h
+++ b/interface/src/raypick/PickScriptingInterface.h
@@ -99,7 +99,7 @@ public:
/**jsdoc
* An intersection result for a Ray Pick.
*
- * @typedef {Object} Picks.RayPickResult
+ * @typedef {Object} RayPickResult
* @property {number} type The intersection type.
* @property {boolean} intersects If there was a valid intersection (type != INTERSECTED_NONE)
* @property {Uuid} objectID The ID of the intersected object. Uuid.NULL for the HUD or invalid intersections.
@@ -113,7 +113,7 @@ public:
/**jsdoc
* An intersection result for a Stylus Pick.
*
- * @typedef {Object} Picks.StylusPickResult
+ * @typedef {Object} StylusPickResult
* @property {number} type The intersection type.
* @property {boolean} intersects If there was a valid intersection (type != INTERSECTED_NONE)
* @property {Uuid} objectID The ID of the intersected object. Uuid.NULL for the HUD or invalid intersections.
@@ -128,7 +128,7 @@ public:
* Get the most recent pick result from this Pick. This will be updated as long as the Pick is enabled.
* @function Picks.getPrevPickResult
* @param {number} uid The ID of the Pick, as returned by {@link Picks.createPick}.
- * @returns {Picks.RayPickResult|Picks.StylusPickResult} The most recent intersection result. This will be different for different PickTypes.
+ * @returns {RayPickResult|StylusPickResult} The most recent intersection result. This will be different for different PickTypes.
*/
Q_INVOKABLE QVariantMap getPrevPickResult(unsigned int uid);
diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp
index ac5a467e76..b7ac899c8d 100644
--- a/interface/src/raypick/PointerScriptingInterface.cpp
+++ b/interface/src/raypick/PointerScriptingInterface.cpp
@@ -42,6 +42,12 @@ unsigned int PointerScriptingInterface::createPointer(const PickQuery::PickType&
}
}
+/**jsdoc
+ * A set of properties that can be passed to {@link Pointers.createPointer} to create a new Pointer. Contains the relevant {@link Picks.PickProperties} to define the underlying Pick.
+ * @typedef {object} Pointers.StylusPointerProperties
+ * @property {boolean} [hover=false] If this pointer should generate hover events.
+ * @property {boolean} [enabled=false]
+ */
unsigned int PointerScriptingInterface::createStylus(const QVariant& properties) const {
QVariantMap propertyMap = properties.toMap();
@@ -58,6 +64,48 @@ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties)
return DependencyManager::get()->addPointer(std::make_shared(properties, StylusPointer::buildStylusOverlay(propertyMap), hover, enabled));
}
+/**jsdoc
+ * A set of properties used to define the visual aspect of a Ray Pointer in the case that the Pointer is not intersecting something. Same as a {@link Pointers.RayPointerRenderState},
+ * but with an additional distance field.
+ *
+ * @typedef {Object} Pointers.DefaultRayPointerRenderState
+ * @augments Pointers.RayPointerRenderState
+ * @property {number} distance The distance at which to render the end of this Ray Pointer, if one is defined.
+ */
+/**jsdoc
+ * A set of properties used to define the visual aspect of a Ray Pointer in the case that the Pointer is intersecting something.
+ *
+ * @typedef {Object} Pointers.RayPointerRenderState
+ * @property {string} name The name of this render state, used by {@link Pointers.setRenderState} and {@link Pointers.editRenderState}
+ * @property {Overlays.OverlayProperties} [start] All of the properties you would normally pass to {@link Overlays.addOverlay}, plus the type (as a type field).
+ * An overlay to represent the beginning of the Ray Pointer, if desired.
+ * @property {Overlays.OverlayProperties} [path] All of the properties you would normally pass to {@link Overlays.addOverlay}, plus the type (as a type field), which must be "line3d".
+ * An overlay to represent the path of the Ray Pointer, if desired.
+ * @property {Overlays.OverlayProperties} [end] All of the properties you would normally pass to {@link Overlays.addOverlay}, plus the type (as a type field).
+ * An overlay to represent the end of the Ray Pointer, if desired.
+ */
+/**jsdoc
+ * A trigger mechanism for Ray Pointers.
+ *
+ * @typedef {Object} Pointers.Trigger
+ * @property {Controller.Standard|Controller.Actions|function} action This can be a built-in Controller action, like Controller.Standard.LTClick, or a function that evaluates to >= 1.0 when you want to trigger button.
+ * @property {string} button Which button to trigger. "Primary", "Secondary", "Tertiary", and "Focus" are currently supported. Only "Primary" will trigger clicks on web surfaces. If "Focus" is triggered,
+ * it will try to set the entity or overlay focus to the object at which the Pointer is aimed. Buttons besides the first three will still trigger events, but event.button will be "None".
+ */
+/**jsdoc
+ * A set of properties that can be passed to {@link Pointers.createPointer} to create a new Pointer. Contains the relevant {@link Picks.PickProperties} to define the underlying Pick.
+ * @typedef {object} Pointers.LaserPointerProperties
+ * @property {boolean} [faceAvatar=false] Ray Pointers only. If true, the end of the Pointer will always rotate to face the avatar.
+ * @property {boolean} [centerEndY=true] Ray Pointers only. If false, the end of the Pointer will be moved up by half of its height.
+ * @property {boolean} [lockEnd=false] Ray Pointers only. If true, the end of the Pointer will lock on to the center of the object at which the laser is pointing.
+ * @property {boolean} [distanceScaleEnd=false] Ray Pointers only. If true, the dimensions of the end of the Pointer will scale linearly with distance.
+ * @property {boolean} [scaleWithAvatar=false] Ray Pointers only. If true, the width of the Pointer's path will scale linearly with your avatar's scale.
+ * @property {boolean} [enabled=false]
+ * @property {Pointers.RayPointerRenderState[]} [renderStates] Ray Pointers only. A list of different visual states to switch between.
+ * @property {Pointers.DefaultRayPointerRenderState[]} [defaultRenderStates] Ray Pointers only. A list of different visual states to use if there is no intersection.
+ * @property {boolean} [hover=false] If this Pointer should generate hover events.
+ * @property {Pointers.Trigger[]} [triggers] Ray Pointers only. A list of different triggers mechanisms that control this Pointer's click event generation.
+ */
unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& properties) const {
QVariantMap propertyMap = properties.toMap();
diff --git a/interface/src/raypick/PointerScriptingInterface.h b/interface/src/raypick/PointerScriptingInterface.h
index e7acfd4037..6ff98c8a84 100644
--- a/interface/src/raypick/PointerScriptingInterface.h
+++ b/interface/src/raypick/PointerScriptingInterface.h
@@ -33,59 +33,12 @@ public:
unsigned int createStylus(const QVariant& properties) const;
/**jsdoc
- * A set of properties that can be passed to {@link Pointers.createPointer} to create a new Pointer. Also contains the relevant {@link Picks.PickProperties} to define the underlying Pick.
- *
+ * Adds a new Pointer
* Different {@link PickType}s use different properties, and within one PickType, the properties you choose can lead to a wide range of behaviors. For example,
* with PickType.Ray, depending on which optional parameters you pass, you could create a Static Ray Pointer, a Mouse Ray Pointer, or a Joint Ray Pointer.
- *
- * @typedef {Object} Pointers.PointerProperties
- * @property {boolean} [hover=false] If this Pointer should generate hover events.
- * @property {boolean} [faceAvatar=false] Ray Pointers only. If true, the end of the Pointer will always rotate to face the avatar.
- * @property {boolean} [centerEndY=true] Ray Pointers only. If false, the end of the Pointer will be moved up by half of its height.
- * @property {boolean} [lockEnd=false] Ray Pointers only. If true, the end of the Pointer will lock on to the center of the object at which the laser is pointing.
- * @property {boolean} [distanceScaleEnd=false] Ray Pointers only. If true, the dimensions of the end of the Pointer will scale linearly with distance.
- * @property {boolean} [scaleWithAvatar=false] Ray Pointers only. If true, the width of the Pointer's path will scale linearly with your avatar's scale.
- * @property {Pointers.RayPointerRenderState[]} [renderStates] Ray Pointers only. A list of different visual states to switch between.
- * @property {Pointers.DefaultRayPointerRenderState[]} [defaultRenderStates] Ray Pointers only. A list of different visual states to use if there is no intersection.
- * @property {Pointers.Trigger[]} [triggers] Ray Pointers only. A list of different triggers mechanisms that control this Pointer's click event generation.
- */
-
- /**jsdoc
- * A set of properties used to define the visual aspect of a Ray Pointer in the case that the Pointer is intersecting something.
- *
- * @typedef {Object} Pointers.RayPointerRenderState
- * @property {string} name The name of this render state, used by {@link Pointers.setRenderState} and {@link Pointers.editRenderState}
- * @property {OverlayProperties} [start] All of the properties you would normally pass to {@Overlays.addOverlay}, plus the type (as a type field).
- * An overlay to represent the beginning of the Ray Pointer, if desired.
- * @property {OverlayProperties} [path] All of the properties you would normally pass to {@Overlays.addOverlay}, plus the type (as a type field), which must be "line3d".
- * An overlay to represent the path of the Ray Pointer, if desired.
- * @property {OverlayProperties} [end] All of the properties you would normally pass to {@Overlays.addOverlay}, plus the type (as a type field).
- * An overlay to represent the end of the Ray Pointer, if desired.
- */
-
- /**jsdoc
- * A set of properties used to define the visual aspect of a Ray Pointer in the case that the Pointer is not intersecting something. Same as a {@link Pointers.RayPointerRenderState},
- * but with an additional distance field.
- *
- * @typedef {Object} Pointers.DefaultRayPointerRenderState
- * @augments Pointers.RayPointerRenderState
- * @property {number} distance The distance at which to render the end of this Ray Pointer, if one is defined.
- */
-
- /**jsdoc
- * A trigger mechanism for Ray Pointers.
- *
- * @typedef {Object} Pointers.Trigger
- * @property {Controller.Action} action This can be a built-in Controller action, like Controller.Standard.LTClick, or a function that evaluates to >= 1.0 when you want to trigger button.
- * @property {string} button Which button to trigger. "Primary", "Secondary", "Tertiary", and "Focus" are currently supported. Only "Primary" will trigger clicks on web surfaces. If "Focus" is triggered,
- * it will try to set the entity or overlay focus to the object at which the Pointer is aimed. Buttons besides the first three will still trigger events, but event.button will be "None".
- */
-
- /**jsdoc
- * Adds a new Pointer
* @function Pointers.createPointer
- * @param {Picks.PickType} type A PickType that specifies the method of picking to use
- * @param {Pointers.PointerProperties} properties A PointerProperties object, containing all the properties for initializing this Pointer and the {@link Picks.PickProperties} for the Pick that
+ * @param {PickType} type A PickType that specifies the method of picking to use
+ * @param {Pointers.LaserPointerProperties|Pointers.StylusPointerProperties} properties A PointerProperties object, containing all the properties for initializing this Pointer and the {@link Picks.PickProperties} for the Pick that
* this Pointer will use to do its picking.
* @returns {number} The ID of the created Pointer. Used for managing the Pointer. 0 if invalid.
*
@@ -121,32 +74,37 @@ public:
* Pointers.setRenderState(pointer, "test");
*/
Q_INVOKABLE unsigned int createPointer(const PickQuery::PickType& type, const QVariant& properties);
+
/**jsdoc
* Enables a Pointer.
* @function Pointers.enablePointer
* @param {number} uid The ID of the Pointer, as returned by {@link Pointers.createPointer}.
*/
Q_INVOKABLE void enablePointer(unsigned int uid) const { DependencyManager::get()->enablePointer(uid); }
+
/**jsdoc
* Disables a Pointer.
* @function Pointers.disablePointer
* @param {number} uid The ID of the Pointer, as returned by {@link Pointers.createPointer}.
*/
Q_INVOKABLE void disablePointer(unsigned int uid) const { DependencyManager::get()->disablePointer(uid); }
+
/**jsdoc
* Removes a Pointer.
* @function Pointers.removePointer
* @param {number} uid The ID of the Pointer, as returned by {@link Pointers.createPointer}.
*/
Q_INVOKABLE void removePointer(unsigned int uid) const { DependencyManager::get()->removePointer(uid); }
+
/**jsdoc
* Edit some visual aspect of a Pointer. Currently only supported for Ray Pointers.
* @function Pointers.editRenderState
* @param {number} uid The ID of the Pointer, as returned by {@link Pointers.createPointer}.
* @param {string} renderState The name of the render state you want to edit.
- * @param {RenderState} properties The new properties for renderState. For Ray Pointers, a {@link Pointers.RayPointerRenderState}.
+ * @param {Pointers.RayPointerRenderState} properties The new properties for renderStates item.
*/
Q_INVOKABLE void editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const;
+
/**jsdoc
* Set the render state of a Pointer. For Ray Pointers, this means switching between their {@link Pointers.RayPointerRenderState}s, or "" to turn off rendering and hover/trigger events.
* For Stylus Pointers, there are three built-in options: "events on" (render and send events, the default), "events off" (render but don't send events), and "disabled" (don't render, don't send events).
@@ -156,14 +114,16 @@ public:
*/
Q_INVOKABLE void setRenderState(unsigned int uid, const QString& renderState) const { DependencyManager::get()->setRenderState(uid, renderState.toStdString()); }
+
/**jsdoc
* Get the most recent pick result from this Pointer. This will be updated as long as the Pointer is enabled, regardless of the render state.
* @function Pointers.getPrevPickResult
* @param {number} uid The ID of the Pointer, as returned by {@link Pointers.createPointer}.
- * @returns {PickResult} The most recent intersection result. This will be slightly different for different PickTypes. See {@link Picks.RayPickResult} and {@link Picks.StylusPickResult}.
+ * @returns {RayPickResult|StylusPickResult} The most recent intersection result. This will be slightly different for different PickTypes.
*/
Q_INVOKABLE QVariantMap getPrevPickResult(unsigned int uid) const;
+
/**jsdoc
* Sets whether or not to use precision picking.
* @function Pointers.setPrecisionPicking
@@ -171,6 +131,7 @@ public:
* @param {boolean} precisionPicking Whether or not to use precision picking
*/
Q_INVOKABLE void setPrecisionPicking(unsigned int uid, bool precisionPicking) const { DependencyManager::get()->setPrecisionPicking(uid, precisionPicking); }
+
/**jsdoc
* Sets the length of this Pointer. No effect on Stylus Pointers.
* @function Pointers.setLength
@@ -178,6 +139,7 @@ public:
* @param {float} length The desired length of the Pointer.
*/
Q_INVOKABLE void setLength(unsigned int uid, float length) const { DependencyManager::get()->setLength(uid, length); }
+
/**jsdoc
* Sets a list of Entity IDs, Overlay IDs, and/or Avatar IDs to ignore during intersection. Not used by Stylus Pointers.
* @function Pointers.setIgnoreItems
@@ -185,6 +147,7 @@ public:
* @param {Uuid[]} ignoreItems A list of IDs to ignore.
*/
Q_INVOKABLE void setIgnoreItems(unsigned int uid, const QScriptValue& ignoreEntities) const;
+
/**jsdoc
* Sets a list of Entity IDs, Overlay IDs, and/or Avatar IDs to include during intersection, instead of intersecting with everything. Stylus
* Pointers only intersect with objects in their include list.
@@ -194,17 +157,19 @@ public:
*/
Q_INVOKABLE void setIncludeItems(unsigned int uid, const QScriptValue& includeEntities) const;
+
/**jsdoc
* Lock a Pointer onto a specific object (overlay, entity, or avatar). Optionally, provide an offset in object-space, otherwise the Pointer will lock on to the center of the object.
* Not used by Stylus Pointers.
* @function Pointers.setLockEndUUID
* @param {number} uid The ID of the Pointer, as returned by {@link Pointers.createPointer}.
- * @param {QUuid} objectID The ID of the object to which to lock on.
+ * @param {Uuid} objectID The ID of the object to which to lock on.
* @param {boolean} isOverlay False for entities or avatars, true for overlays
* @param {Mat4} [offsetMat] The offset matrix to use if you do not want to lock on to the center of the object.
*/
Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay, offsetMat); }
+
/**jsdoc
* Check if a Pointer is associated with the left hand.
* @function Pointers.isLeftHand
@@ -212,6 +177,7 @@ public:
* @returns {boolean} True if the Pointer is a Joint Ray Pointer with joint == "_CONTROLLER_LEFTHAND" or "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", or a Stylus Pointer with hand == 0
*/
Q_INVOKABLE bool isLeftHand(unsigned int uid) { return DependencyManager::get()->isLeftHand(uid); }
+
/**jsdoc
* Check if a Pointer is associated with the right hand.
* @function Pointers.isRightHand
@@ -219,6 +185,7 @@ public:
* @returns {boolean} True if the Pointer is a Joint Ray Pointer with joint == "_CONTROLLER_RIGHTHAND" or "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND", or a Stylus Pointer with hand == 1
*/
Q_INVOKABLE bool isRightHand(unsigned int uid) { return DependencyManager::get()->isRightHand(uid); }
+
/**jsdoc
* Check if a Pointer is associated with the system mouse.
* @function Pointers.isMouse
diff --git a/interface/src/raypick/RayPickScriptingInterface.h b/interface/src/raypick/RayPickScriptingInterface.h
index ce692e2003..d5e224018e 100644
--- a/interface/src/raypick/RayPickScriptingInterface.h
+++ b/interface/src/raypick/RayPickScriptingInterface.h
@@ -90,7 +90,7 @@ public:
/**jsdoc
* @function RayPick.getPrevRayPickResult
* @param {number} id
- * @returns {Picks.RayPickResult}
+ * @returns {RayPickResult}
*/
Q_INVOKABLE QVariantMap getPrevRayPickResult(unsigned int uid);
diff --git a/libraries/pointers/src/Pick.h b/libraries/pointers/src/Pick.h
index caaeae6725..53606b154f 100644
--- a/libraries/pointers/src/Pick.h
+++ b/libraries/pointers/src/Pick.h
@@ -138,6 +138,7 @@ public:
* Enum for different types of Picks and Pointers.
*
* @namespace PickType
+ * @variation 0
*
* @hifi-interface
* @hifi-client-entity
@@ -145,6 +146,18 @@ public:
* @property {number} Ray Ray Picks intersect a ray with the nearest object in front of them, along a given direction.
* @property {number} Stylus Stylus Picks provide "tapping" functionality on/into flat surfaces.
*/
+ /**jsdoc
+ *
+ *
+ *
Value
Description
+ *
+ *
+ *
{@link PickType(0)|PickType.Ray}
+ *
{@link PickType(0)|PickType.Stylus}
+ *
+ *
+ * @typedef {number} PickType
+ */
enum PickType {
Ray = 0,
Stylus,
From b7a0ff523a692bdc54a2bc6dc895a0aaf2e74de7 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Tue, 15 May 2018 17:36:23 +1200
Subject: [PATCH 55/80] LaserPointers API JSDoc stubs
---
.../raypick/LaserPointerScriptingInterface.h | 98 +++++++++++++++++++
.../src/raypick/PointerScriptingInterface.h | 2 +-
2 files changed, 99 insertions(+), 1 deletion(-)
diff --git a/interface/src/raypick/LaserPointerScriptingInterface.h b/interface/src/raypick/LaserPointerScriptingInterface.h
index c2e6c8f113..5aaacd7960 100644
--- a/interface/src/raypick/LaserPointerScriptingInterface.h
+++ b/interface/src/raypick/LaserPointerScriptingInterface.h
@@ -20,24 +20,122 @@ class LaserPointerScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
+/**jsdoc
+ * Synonym for {@link Pointers} as used for laser pointers.
+ *
+ * @namespace LaserPointers
+ *
+ * @hifi-interface
+ * @hifi-client-entity
+ */
public:
+
+ /**jsdoc
+ * @function LaserPointers.createLaserPointer
+ * @param {Pointers.LaserPointerProperties} properties
+ * @returns {number}
+ */
Q_INVOKABLE unsigned int createLaserPointer(const QVariant& properties) const;
+
+ /**jsdoc
+ * @function LaserPointers.enableLaserPointer
+ * @param {number} id
+ */
Q_INVOKABLE void enableLaserPointer(unsigned int uid) const { DependencyManager::get()->enablePointer(uid); }
+
+ /**jsdoc
+ * @function LaserPointers.disableLaserPointer
+ * @param {number} id
+ */
Q_INVOKABLE void disableLaserPointer(unsigned int uid) const { DependencyManager::get()->disablePointer(uid); }
+
+ /**jsdoc
+ * @function LaserPointers.removeLaserPointer
+ * @param {number} id
+ */
Q_INVOKABLE void removeLaserPointer(unsigned int uid) const { DependencyManager::get()->removePointer(uid); }
+
+ /**jsdoc
+ * @function LaserPointers.editRenderState
+ * @param {number} id
+ * @param {string} renderState
+ * @param {Pointers.RayPointerRenderState} properties
+ */
Q_INVOKABLE void editRenderState(unsigned int uid, const QString& renderState, const QVariant& properties) const;
+
+ /**jsdoc
+ * @function LaserPointers.setRenderState
+ * @param {string} renderState
+ * @param {number} id
+ */
Q_INVOKABLE void setRenderState(unsigned int uid, const QString& renderState) const { DependencyManager::get()->setRenderState(uid, renderState.toStdString()); }
+
+ /**jsdoc
+ * @function LaserPointers.getPrevRayPickResult
+ * @param {number} id
+ * @returns {RayPickResult}
+ */
Q_INVOKABLE QVariantMap getPrevRayPickResult(unsigned int uid) const;
+
+ /**jsdoc
+ * @function LaserPointers.setPrecisionPicking
+ * @param {number} id
+ * @param {boolean} precisionPicking
+ */
Q_INVOKABLE void setPrecisionPicking(unsigned int uid, bool precisionPicking) const { DependencyManager::get()->setPrecisionPicking(uid, precisionPicking); }
+
+ /**jsdoc
+ * @function LaserPointers.setLaserLength
+ * @param {number} id
+ * @param {number} laserLength
+ */
Q_INVOKABLE void setLaserLength(unsigned int uid, float laserLength) const { DependencyManager::get()->setLength(uid, laserLength); }
+
+ /**jsdoc
+ * @function LaserPointers.setIgnoreItems
+ * @param {number} id
+ * @param {Uuid[]} ignoreItems
+ */
Q_INVOKABLE void setIgnoreItems(unsigned int uid, const QScriptValue& ignoreEntities) const;
+
+ /**jsdoc
+ * @function LaserPointers.setIncludeItems
+ * @param {number} id
+ * @param {Uuid[]} includeItems
+ */
Q_INVOKABLE void setIncludeItems(unsigned int uid, const QScriptValue& includeEntities) const;
+
+ /**jsdoc
+ * @function LaserPointers.setLockEndUUID
+ * @param {number} id
+ * @param {Uuid} itemID
+ * @param {boolean} isOverlay
+ * @param {Mat4} [offsetMat]
+ */
Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay, offsetMat); }
+
+ /**jsdoc
+ * @function LaserPointers.isLeftHand
+ * @param {number} id
+ * @returns {boolean}
+ */
Q_INVOKABLE bool isLeftHand(unsigned int uid) { return DependencyManager::get()->isLeftHand(uid); }
+
+ /**jsdoc
+ * @function LaserPointers.isRightHand
+ * @param {number} id
+ * @returns {boolean}
+ */
Q_INVOKABLE bool isRightHand(unsigned int uid) { return DependencyManager::get()->isRightHand(uid); }
+
+ /**jsdoc
+ * @function LaserPointers.isMouse
+ * @param {number} id
+ * @returns {boolean}
+ */
Q_INVOKABLE bool isMouse(unsigned int uid) { return DependencyManager::get()->isMouse(uid); }
};
diff --git a/interface/src/raypick/PointerScriptingInterface.h b/interface/src/raypick/PointerScriptingInterface.h
index 6ff98c8a84..49eb40504d 100644
--- a/interface/src/raypick/PointerScriptingInterface.h
+++ b/interface/src/raypick/PointerScriptingInterface.h
@@ -16,7 +16,7 @@
/**jsdoc
* The Pointers API lets you create and manage objects for repeatedly calculating intersections in different ways, as well as the visual representation of those objects.
- * Pointers can also be configured to automatically generate PointerEvents.
+ * Pointers can also be configured to automatically generate {@link PointerEvent}s on {@link Entities} and {@link Overlays}.
*
* @namespace Pointers
*
From 1ca6bd2f0bdc7ae704bc8ca50fa7f81379cf9fb7 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Tue, 15 May 2018 17:37:45 +1200
Subject: [PATCH 56/80] location getter/setter JSDoc
---
libraries/networking/src/AddressManager.h | 5 +++++
tools/jsdoc/plugins/hifi.js | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h
index 8e2553779b..7832b26c96 100644
--- a/libraries/networking/src/AddressManager.h
+++ b/libraries/networking/src/AddressManager.h
@@ -32,6 +32,11 @@ const QString GET_PLACE = "/api/v1/places/%1";
/**jsdoc
* The location API provides facilities related to your current location in the metaverse.
*
+ *
Getter/Setter
+ *
You can get and set your current metaverse address by directly reading a string value from and writing a string value to
+ * the location object. This is an alternative to using the location.href property or this object's
+ * functions.
+ *
* @namespace location
*
* @hifi-interface
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index d063d43990..21749c7fe2 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -114,8 +114,8 @@ exports.handlers = {
// Append an Available In: table at the end of the namespace description.
if (rows.length > 0) {
- var table = "
";
+ e.doclet.description = table + (e.doclet.description ? e.doclet.description : "");
}
}
}
From bed7752a1a0560b1535525adfa671392b2617f7f Mon Sep 17 00:00:00 2001
From: Olivier Prat
Date: Tue, 15 May 2018 12:27:04 +0200
Subject: [PATCH 57/80] Fixed bug with highlighting and TAA
---
libraries/render-utils/src/HighlightEffect.cpp | 9 +++++++--
libraries/render-utils/src/HighlightEffect.h | 6 +++---
libraries/render-utils/src/RenderDeferredTask.cpp | 9 ++++++---
libraries/render-utils/src/RenderDeferredTask.h | 2 +-
libraries/render/src/render/DrawStatus.cpp | 6 +++++-
libraries/render/src/render/DrawStatus.h | 5 +++--
6 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/libraries/render-utils/src/HighlightEffect.cpp b/libraries/render-utils/src/HighlightEffect.cpp
index d151da766b..3905d3a54c 100644
--- a/libraries/render-utils/src/HighlightEffect.cpp
+++ b/libraries/render-utils/src/HighlightEffect.cpp
@@ -169,6 +169,7 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
glm::mat4 projMat;
Transform viewMat;
+ const auto jitter = inputs.get2();
args->getViewFrustum().evalProjectionMatrix(projMat);
args->getViewFrustum().evalViewTransform(viewMat);
@@ -183,6 +184,7 @@ void DrawHighlightMask::run(const render::RenderContextPointer& renderContext, c
// Setup camera, projection and viewport for all items
batch.setViewportTransform(args->_viewport);
batch.setProjectionTransform(projMat);
+ batch.setProjectionJitter(jitter.x, jitter.y);
batch.setViewTransform(viewMat);
std::vector skinnedShapeKeys{};
@@ -356,6 +358,7 @@ void DebugHighlight::run(const render::RenderContextPointer& renderContext, cons
assert(renderContext->args);
assert(renderContext->args->hasViewFrustum());
RenderArgs* args = renderContext->args;
+ const auto jitter = input.get2();
gpu::doInBatch("DebugHighlight::run", args->_context, [&](gpu::Batch& batch) {
batch.setViewportTransform(args->_viewport);
@@ -368,6 +371,7 @@ void DebugHighlight::run(const render::RenderContextPointer& renderContext, cons
args->getViewFrustum().evalProjectionMatrix(projMat);
args->getViewFrustum().evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
+ batch.setProjectionJitter(jitter.x, jitter.y);
batch.setViewTransform(viewMat, true);
batch.setModelTransform(Transform());
@@ -480,6 +484,7 @@ void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, ren
const auto sceneFrameBuffer = inputs.getN(1);
const auto primaryFramebuffer = inputs.getN(2);
const auto deferredFrameTransform = inputs.getN(3);
+ const auto jitter = inputs.getN(4);
// Prepare the ShapePipeline
auto shapePlumber = std::make_shared();
@@ -515,7 +520,7 @@ void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, ren
stream << "HighlightMask" << i;
name = stream.str();
}
- const auto drawMaskInputs = DrawHighlightMask::Inputs(sortedBounds, highlightRessources).asVarying();
+ const auto drawMaskInputs = DrawHighlightMask::Inputs(sortedBounds, highlightRessources, jitter).asVarying();
const auto highlightedRect = task.addJob(name, drawMaskInputs, i, shapePlumber, sharedParameters);
if (i == 0) {
highlight0Rect = highlightedRect;
@@ -532,7 +537,7 @@ void DrawHighlightTask::build(JobModel& task, const render::Varying& inputs, ren
}
// Debug highlight
- const auto debugInputs = DebugHighlight::Inputs(highlightRessources, const_cast(highlight0Rect)).asVarying();
+ const auto debugInputs = DebugHighlight::Inputs(highlightRessources, const_cast(highlight0Rect), jitter).asVarying();
task.addJob("HighlightDebug", debugInputs);
}
diff --git a/libraries/render-utils/src/HighlightEffect.h b/libraries/render-utils/src/HighlightEffect.h
index 90a8e730ce..7c1db795fb 100644
--- a/libraries/render-utils/src/HighlightEffect.h
+++ b/libraries/render-utils/src/HighlightEffect.h
@@ -113,7 +113,7 @@ private:
class DrawHighlightMask {
public:
- using Inputs = render::VaryingSet2;
+ using Inputs = render::VaryingSet3;
using Outputs = glm::ivec4;
using JobModel = render::Job::ModelIO;
@@ -182,7 +182,7 @@ signals:
class DebugHighlight {
public:
- using Inputs = render::VaryingSet2;
+ using Inputs = render::VaryingSet3;
using Config = DebugHighlightConfig;
using JobModel = render::Job::ModelI;
@@ -205,7 +205,7 @@ private:
class DrawHighlightTask {
public:
- using Inputs = render::VaryingSet4;
+ using Inputs = render::VaryingSet5;
using Config = render::Task::Config;
using JobModel = render::Task::ModelI;
diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp
index bea298122e..ab1d831ead 100644
--- a/libraries/render-utils/src/RenderDeferredTask.cpp
+++ b/libraries/render-utils/src/RenderDeferredTask.cpp
@@ -178,7 +178,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
task.addJob("DrawHazeDeferred", drawHazeInputs);
// Render transparent objects forward in LightingBuffer
- const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel, lightClusters).asVarying();
+ const auto transparentsInputs = DrawDeferred::Inputs(transparents, lightingModel, lightClusters, jitter).asVarying();
task.addJob("DrawTransparentDeferred", transparentsInputs, shapePlumber);
// Light Cluster Grid Debuging job
@@ -192,7 +192,7 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
const auto selectionBaseName = "contextOverlayHighlightList";
const auto selectedItems = addSelectItemJobs(task, selectionBaseName, metas, opaques, transparents);
- const auto outlineInputs = DrawHighlightTask::Inputs(items.get0(), deferredFramebuffer, lightingFramebuffer, deferredFrameTransform).asVarying();
+ const auto outlineInputs = DrawHighlightTask::Inputs(items.get0(), deferredFramebuffer, lightingFramebuffer, deferredFrameTransform, jitter).asVarying();
task.addJob("DrawHighlight", outlineInputs);
task.addJob("HighlightRangeTimer", outlineRangeTimer);
@@ -277,7 +277,8 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
// Grab a texture map representing the different status icons and assign that to the drawStatsuJob
auto iconMapPath = PathUtils::resourcesPath() + "icons/statusIconAtlas.svg";
auto statusIconMap = DependencyManager::get()->getImageTexture(iconMapPath, image::TextureUsage::STRICT_TEXTURE);
- task.addJob("DrawStatus", opaques, DrawStatus(statusIconMap));
+ const auto drawStatusInputs = DrawStatus::Input(opaques, jitter).asVarying();
+ task.addJob("DrawStatus", drawStatusInputs, DrawStatus(statusIconMap));
}
task.addJob("DrawZoneStack", deferredFrameTransform);
@@ -315,6 +316,7 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
const auto& inItems = inputs.get0();
const auto& lightingModel = inputs.get1();
const auto& lightClusters = inputs.get2();
+ const auto jitter = inputs.get3();
auto deferredLightingEffect = DependencyManager::get();
RenderArgs* args = renderContext->args;
@@ -332,6 +334,7 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
args->getViewFrustum().evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
+ batch.setProjectionJitter(jitter.x, jitter.y);
batch.setViewTransform(viewMat);
// Setup lighting model for all items;
diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h
index b923ec0878..9917058790 100644
--- a/libraries/render-utils/src/RenderDeferredTask.h
+++ b/libraries/render-utils/src/RenderDeferredTask.h
@@ -41,7 +41,7 @@ protected:
class DrawDeferred {
public:
- using Inputs = render::VaryingSet3 ;
+ using Inputs = render::VaryingSet4;
using Config = DrawDeferredConfig;
using JobModel = render::Job::ModelI;
diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp
index 56802a3239..496b2000a9 100644
--- a/libraries/render/src/render/DrawStatus.cpp
+++ b/libraries/render/src/render/DrawStatus.cpp
@@ -104,7 +104,7 @@ void DrawStatus::configure(const Config& config) {
_showNetwork = config.showNetwork;
}
-void DrawStatus::run(const RenderContextPointer& renderContext, const ItemBounds& inItems) {
+void DrawStatus::run(const RenderContextPointer& renderContext, const Input& input) {
assert(renderContext->args);
assert(renderContext->args->hasViewFrustum());
RenderArgs* args = renderContext->args;
@@ -112,6 +112,9 @@ void DrawStatus::run(const RenderContextPointer& renderContext, const ItemBounds
const int NUM_STATUS_VEC4_PER_ITEM = 2;
const int VEC4_LENGTH = 4;
+ const auto& inItems = input.get0();
+ const auto jitter = input.get1();
+
// FIrst thing, we collect the bound and the status for all the items we want to render
int nbItems = 0;
{
@@ -171,6 +174,7 @@ void DrawStatus::run(const RenderContextPointer& renderContext, const ItemBounds
batch.setViewportTransform(args->_viewport);
batch.setProjectionTransform(projMat);
+ batch.setProjectionJitter(jitter.x, jitter.y);
batch.setViewTransform(viewMat, true);
batch.setModelTransform(Transform());
diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h
index 2e0adb4653..9e05471cd6 100644
--- a/libraries/render/src/render/DrawStatus.h
+++ b/libraries/render/src/render/DrawStatus.h
@@ -39,13 +39,14 @@ namespace render {
class DrawStatus {
public:
using Config = DrawStatusConfig;
- using JobModel = Job::ModelI;
+ using Input = VaryingSet2;
+ using JobModel = Job::ModelI;
DrawStatus() {}
DrawStatus(const gpu::TexturePointer statusIconMap) { setStatusIconMap(statusIconMap); }
void configure(const Config& config);
- void run(const RenderContextPointer& renderContext, const ItemBounds& inItems);
+ void run(const RenderContextPointer& renderContext, const Input& input);
const gpu::PipelinePointer getDrawItemBoundsPipeline();
const gpu::PipelinePointer getDrawItemStatusPipeline();
From d10b5a16f291b860a0c213f1ad0636cf0b94f55b Mon Sep 17 00:00:00 2001
From: Olivier Prat
Date: Tue, 15 May 2018 15:09:02 +0200
Subject: [PATCH 58/80] Turned off jitter with FXAA
---
.../render-utils/src/AntialiasingEffect.cpp | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp
index f77b4fc68b..249d2bbc47 100644
--- a/libraries/render-utils/src/AntialiasingEffect.cpp
+++ b/libraries/render-utils/src/AntialiasingEffect.cpp
@@ -482,16 +482,14 @@ JitterSample::SampleSequence::SampleSequence(){
}
void JitterSample::configure(const Config& config) {
- _freeze = config.freeze;
- if (config.stop || _freeze) {
+ _freeze = config.stop || config.freeze;
+ if (config.freeze) {
auto pausedIndex = config.getIndex();
if (_sampleSequence.currentIndex != pausedIndex) {
_sampleSequence.currentIndex = pausedIndex;
}
- } else {
- if (_sampleSequence.currentIndex < 0) {
- _sampleSequence.currentIndex = config.getIndex();
- }
+ } else if (config.stop) {
+ _sampleSequence.currentIndex = -1;
}
_scale = config.scale;
}
@@ -505,7 +503,12 @@ void JitterSample::run(const render::RenderContextPointer& renderContext, Output
current = -1;
}
}
- jitter = _sampleSequence.offsets[(current < 0 ? SEQUENCE_LENGTH : current)];
+
+ jitter.x = 0.0f;
+ jitter.y = 0.0f;
+ if (current >= 0) {
+ jitter = _sampleSequence.offsets[current];
+ }
}
From fdeb0e3305b4cfe002dd7d958b425a5f767dfcc8 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Wed, 16 May 2018 09:20:54 +1200
Subject: [PATCH 59/80] Avatar API JSDoc stubs
---
.../src/avatars/ScriptableAvatar.h | 130 +++++++++++++++++-
interface/src/avatar/MyAvatar.h | 6 +-
libraries/avatars/src/AvatarData.cpp | 2 +-
libraries/avatars/src/AvatarData.h | 22 +--
libraries/shared/src/RegisteredMetaTypes.cpp | 16 ++-
tools/jsdoc/plugins/hifi.js | 7 +-
6 files changed, 161 insertions(+), 22 deletions(-)
diff --git a/assignment-client/src/avatars/ScriptableAvatar.h b/assignment-client/src/avatars/ScriptableAvatar.h
index b1039b5ac0..d34ad2d21e 100644
--- a/assignment-client/src/avatars/ScriptableAvatar.h
+++ b/assignment-client/src/avatars/ScriptableAvatar.h
@@ -17,20 +17,144 @@
#include
#include
+/**jsdoc
+ * The Avatar API is used to manipulate scriptable avatars on the domain. This API is a subset of the
+ * {@link MyAvatar} API.
+ *
+ *
Note: In the examples, use "Avatar" instead of "MyAvatar".
+ *
+ * @namespace Avatar
+ *
+ * @hifi-assignment-client
+ *
+ * @property {Vec3} position
+ * @property {number} scale
+ * @property {number} density Read-only.
+ * @property {Vec3} handPosition
+ * @property {number} bodyYaw - The rotation left or right about an axis running from the head to the feet of the avatar.
+ * Yaw is sometimes called "heading".
+ * @property {number} bodyPitch - The rotation about an axis running from shoulder to shoulder of the avatar. Pitch is
+ * sometimes called "elevation".
+ * @property {number} bodyRoll - The rotation about an axis running from the chest to the back of the avatar. Roll is
+ * sometimes called "bank".
+ * @property {Quat} orientation
+ * @property {Quat} headOrientation - The orientation of the avatar's head.
+ * @property {number} headPitch - The rotation about an axis running from ear to ear of the avatar's head. Pitch is
+ * sometimes called "elevation".
+ * @property {number} headYaw - The rotation left or right about an axis running from the base to the crown of the avatar's
+ * head. Yaw is sometimes called "heading".
+ * @property {number} headRoll - The rotation about an axis running from the nose to the back of the avatar's head. Roll is
+ * sometimes called "bank".
+ * @property {Vec3} velocity
+ * @property {Vec3} angularVelocity
+ * @property {number} audioLoudness
+ * @property {number} audioAverageLoudness
+ * @property {string} displayName
+ * @property {string} sessionDisplayName - Sanitized, defaulted version displayName that is defined by the AvatarMixer
+ * rather than by Interface clients. The result is unique among all avatars present at the time.
+ * @property {boolean} lookAtSnappingEnabled
+ * @property {string} skeletonModelURL
+ * @property {AttachmentData[]} attachmentData
+ * @property {string[]} jointNames - The list of joints in the current avatar model. Read-only.
+ * @property {Uuid} sessionUUID Read-only.
+ * @property {Mat4} sensorToWorldMatrix Read-only.
+ * @property {Mat4} controllerLeftHandMatrix Read-only.
+ * @property {Mat4} controllerRightHandMatrix Read-only.
+ * @property {number} sensorToWorldScale Read-only.
+ *
+ * @borrows MyAvatar.getDomainMinScale as getDomainMinScale
+ * @borrows MyAvatar.getDomainMaxScale as getDomainMaxScale
+ * @borrows MyAvatar.canMeasureEyeHeight as canMeasureEyeHeight
+ * @borrows MyAvatar.getEyeHeight as getEyeHeight
+ * @borrows MyAvatar.getHeight as getHeight
+ * @borrows MyAvatar.setHandState as setHandState
+ * @borrows MyAvatar.getHandState as getHandState
+ * @borrows MyAvatar.setRawJointData as setRawJointData
+ * @borrows MyAvatar.setJointData as setJointData
+ * @borrows MyAvatar.setJointRotation as setJointRotation
+ * @borrows MyAvatar.setJointTranslation as setJointTranslation
+ * @borrows MyAvatar.clearJointData as clearJointData
+ * @borrows MyAvatar.isJointDataValid as isJointDataValid
+ * @borrows MyAvatar.getJointRotation as getJointRotation
+ * @borrows MyAvatar.getJointTranslation as getJointTranslation
+ * @borrows MyAvatar.getJointRotations as getJointRotations
+ * @borrows MyAvatar.getJointTranslations as getJointTranslations
+ * @borrows MyAvatar.setJointRotations as setJointRotations
+ * @borrows MyAvatar.setJointTranslations as setJointTranslations
+ * @borrows MyAvatar.clearJointsData as clearJointsData
+ * @borrows MyAvatar.getJointIndex as getJointIndex
+ * @borrows MyAvatar.getJointNames as getJointNames
+ * @borrows MyAvatar.setBlendshape as setBlendshape
+ * @borrows MyAvatar.getAttachmentsVariant as getAttachmentsVariant
+ * @borrows MyAvatar.setAttachmentsVariant as setAttachmentsVariant
+ * @borrows MyAvatar.updateAvatarEntity as updateAvatarEntity
+ * @borrows MyAvatar.clearAvatarEntity as clearAvatarEntity
+ * @borrows MyAvatar.setForceFaceTrackerConnected as setForceFaceTrackerConnected
+ * @borrows MyAvatar.getAttachmentData as getAttachmentData
+ * @borrows MyAvatar.setAttachmentData as setAttachmentData
+ * @borrows MyAvatar.attach as attach
+ * @borrows MyAvatar.detachOne as detachOne
+ * @borrows MyAvatar.detachAll as detachAll
+ * @borrows MyAvatar.getAvatarEntityData as getAvatarEntityData
+ * @borrows MyAvatar.setAvatarEntityData as setAvatarEntityData
+ * @borrows MyAvatar.getSensorToWorldMatrix as getSensorToWorldMatrix
+ * @borrows MyAvatar.getSensorToWorldScale as getSensorToWorldScale
+ * @borrows MyAvatar.getControllerLeftHandMatrix as getControllerLeftHandMatrix
+ * @borrows MyAvatar.getControllerRightHandMatrix as getControllerRightHandMatrix
+ * @borrows MyAvatar.getDataRate as getDataRate
+ * @borrows MyAvatar.getUpdateRate as getUpdateRate
+ * @borrows MyAvatar.displayNameChanged as displayNameChanged
+ * @borrows MyAvatar.sessionDisplayNameChanged as sessionDisplayNameChanged
+ * @borrows MyAvatar.skeletonModelURLChanged as skeletonModelURLChanged
+ * @borrows MyAvatar.lookAtSnappingChanged as lookAtSnappingChanged
+ * @borrows MyAvatar.sessionUUIDChanged as sessionUUIDChanged
+ * @borrows MyAvatar.sendAvatarDataPacket as sendAvatarDataPacket
+ * @borrows MyAvatar.sendIdentityPacket as sendIdentityPacket
+ * @borrows MyAvatar.setJointMappingsFromNetworkReply as setJointMappingsFromNetworkReply
+ * @borrows MyAvatar.setSessionUUID as setSessionUUID
+ * @borrows MyAvatar.getAbsoluteJointRotationInObjectFrame as getAbsoluteJointRotationInObjectFrame
+ * @borrows MyAvatar.getAbsoluteJointTranslationInObjectFrame as getAbsoluteJointTranslationInObjectFrame
+ * @borrows MyAvatar.setAbsoluteJointRotationInObjectFrame as setAbsoluteJointRotationInObjectFrame
+ * @borrows MyAvatar.setAbsoluteJointTranslationInObjectFrame as setAbsoluteJointTranslationInObjectFrame
+ * @borrows MyAvatar.getTargetScale as getTargetScale
+ * @borrows MyAvatar.resetLastSent as resetLastSent
+ */
+
class ScriptableAvatar : public AvatarData, public Dependency {
Q_OBJECT
public:
-
+
+ /**jsdoc
+ * @function Avatar.startAnimation
+ * @param {string} url
+ * @param {number} [fps=30]
+ * @param {number} [priority=1]
+ * @param {boolean} [loop=false]
+ * @param {boolean} [hold=false]
+ * @param {number} [firstFrame=0]
+ * @param {number} [lastFrame=3.403e+38]
+ * @param {string[]} [maskedJoints=[]]
+ */
/// Allows scripts to run animations.
Q_INVOKABLE void startAnimation(const QString& url, float fps = 30.0f, float priority = 1.0f, bool loop = false,
- bool hold = false, float firstFrame = 0.0f, float lastFrame = FLT_MAX, const QStringList& maskedJoints = QStringList());
+ bool hold = false, float firstFrame = 0.0f, float lastFrame = FLT_MAX,
+ const QStringList& maskedJoints = QStringList());
+
+ /**jsdoc
+ * @function Avatar.stopAnimation
+ */
Q_INVOKABLE void stopAnimation();
+
+ /**jsdoc
+ * @function Avatar.getAnimationDetails
+ * @returns {Avatar.AnimationDetails}
+ */
Q_INVOKABLE AnimationDetails getAnimationDetails();
+
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
virtual QByteArray toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking = false) override;
-
private slots:
void update(float deltatime);
diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h
index 154e2e4d09..fa6a675d99 100644
--- a/interface/src/avatar/MyAvatar.h
+++ b/interface/src/avatar/MyAvatar.h
@@ -137,9 +137,9 @@ class MyAvatar : public Avatar {
* @property {number} scale
* @property {number} density Read-only.
* @property {Vec3} handPosition
- * @property {number} bodyYaw - The rotation left or right about an axis running from the head to the feet of MyAvatar. Yaw
- * is sometimes called "heading".
- * @property {number} bodyPitch - The rotation about an axis running from shoulder to shoulder of MyAvatar. Pitch is
+ * @property {number} bodyYaw - The rotation left or right about an axis running from the head to the feet of the avatar.
+ * Yaw is sometimes called "heading".
+ * @property {number} bodyPitch - The rotation about an axis running from shoulder to shoulder of the avatar. Pitch is
* sometimes called "elevation".
* @property {number} bodyRoll - The rotation about an axis running from the chest to the back of the avatar. Roll is
* sometimes called "bank".
diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp
index db38999481..7a28686f8c 100644
--- a/libraries/avatars/src/AvatarData.cpp
+++ b/libraries/avatars/src/AvatarData.cpp
@@ -2363,7 +2363,7 @@ glm::vec3 AvatarData::getAbsoluteJointTranslationInObjectFrame(int index) const
}
/**jsdoc
- * @typedef MyAvatar.AttachmentData
+ * @typedef AttachmentData
* @property {string} modelUrl
* @property {string} jointName
* @property {Vec3} translation
diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h
index bbcdd3693d..62a14ec51e 100644
--- a/libraries/avatars/src/AvatarData.h
+++ b/libraries/avatars/src/AvatarData.h
@@ -351,7 +351,7 @@ public:
class AvatarData : public QObject, public SpatiallyNestable {
Q_OBJECT
- // The following properties have JSDoc in MyAvatar.h.
+ // The following properties have JSDoc in MyAvatar.h and ScriptableAvatar.h
Q_PROPERTY(glm::vec3 position READ getWorldPosition WRITE setPositionViaScript)
Q_PROPERTY(float scale READ getTargetScale WRITE setTargetScale)
Q_PROPERTY(float density READ getDensity)
@@ -502,7 +502,7 @@ public:
float getDomainLimitedScale() const;
/**jsdoc
- * returns the minimum scale allowed for this avatar in the current domain.
+ * Returns the minimum scale allowed for this avatar in the current domain.
* This value can change as the user changes avatars or when changing domains.
* @function MyAvatar.getDomainMinScale
* @returns {number} minimum scale allowed for this avatar in the current domain.
@@ -510,14 +510,14 @@ public:
Q_INVOKABLE float getDomainMinScale() const;
/**jsdoc
- * returns the maximum scale allowed for this avatar in the current domain.
+ * Returns the maximum scale allowed for this avatar in the current domain.
* This value can change as the user changes avatars or when changing domains.
* @function MyAvatar.getDomainMaxScale
* @returns {number} maximum scale allowed for this avatar in the current domain.
*/
Q_INVOKABLE float getDomainMaxScale() const;
- // returns eye height of avatar in meters, ignoreing avatar scale.
+ // Returns eye height of avatar in meters, ignoring avatar scale.
// if _targetScale is 1 then this will be identical to getEyeHeight;
virtual float getUnscaledEyeHeight() const { return DEFAULT_AVATAR_EYE_HEIGHT; }
@@ -775,7 +775,7 @@ public:
* Get the rotations of all joints in the current avatar. Each joint's rotation is relative to its parent joint.
* @function MyAvatar.getJointRotations
* @returns {Quat[]} The rotations of all joints relative to each's parent. The values are in the same order as the array
- * returned by {@link MyAvatar.getJointNames}.
+ * returned by {@link MyAvatar.getJointNames} or {@link Avatar.getJointNames}.
* @example
Report the rotations of all your avatar's joints.
* print(JSON.stringify(MyAvatar.getJointRotations()));
*/
@@ -796,7 +796,7 @@ public:
* the rotation of the elbow, the hand inverse kinematics position won't end up in the right place.
* @function MyAvatar.setJointRotations
* @param {Quat[]} jointRotations - The rotations for all joints in the avatar. The values are in the same order as the
- * array returned by {@link MyAvatar.getJointNames}.
+ * array returned by {@link MyAvatar.getJointNames} or {@link Avatar.getJointNames}.
* @example
Set your avatar to its default T-pose then rotate its right arm.
*
*
@@ -852,7 +852,7 @@ public:
/**jsdoc
* Get the joint index for a named joint. The joint index value is the position of the joint in the array returned by
- * {@link MyAvatar.getJointNames}.
+ * {@link MyAvatar.getJointNames} or {@link Avatar.getJointNames}.
* @function MyAvatar.getJointIndex
* @param {string} name - The name of the joint.
* @returns {number} The index of the joint.
@@ -952,7 +952,7 @@ public:
/**jsdoc
* Get information about all models currently attached to your avatar.
* @function MyAvatar.getAttachmentData
- * @returns {MyAvatar.AttachmentData[]} Information about all models attached to your avatar.
+ * @returns {AttachmentData[]} Information about all models attached to your avatar.
* @example
Report the URLs of all current attachments.
* var attachments = MyAvatar.getaAttachmentData();
* for (var i = 0; i < attachments.length; i++) {
@@ -963,10 +963,10 @@ public:
/**jsdoc
* Set all models currently attached to your avatar. For example, if you retrieve attachment data using
- * {@link MyAvatar.getAttachmentData}, make changes to it, and then want to update your avatar's attachments per the
+ * {@link MyAvatar.getAttachmentData} or {@link Avatar.getAttachmentData}, make changes to it, and then want to update your avatar's attachments per the
* changed data. You can also remove all attachments by using setting attachmentData to null.
* @function MyAvatar.setAttachmentData
- * @param {MyAvatar.AttachmentData[]} attachmentData - The attachment data defining the models to have attached to your avatar. Use
+ * @param {AttachmentData[]} attachmentData - The attachment data defining the models to have attached to your avatar. Use
* null to remove all attachments.
* @example
Remove a hat attachment if your avatar is wearing it.
* var hatURL = "https://s3.amazonaws.com/hifi-public/tony/cowboy-hat.fbx";
@@ -989,7 +989,7 @@ public:
* Nor can you use this function to attach an entity (such as a sphere or a box) to your avatar.
* @function MyAvatar.attach
* @param {string} modelURL - The URL of the model to attach. Models can be .FBX or .OBJ format.
- * @param {string} [jointName=""] - The name of the avatar joint (see {@link MyAvatar.getJointNames}) to attach the model
+ * @param {string} [jointName=""] - The name of the avatar joint (see {@link MyAvatar.getJointNames} or {@link Avatar.getJointNames}) to attach the model
* to.
* @param {Vec3} [translation=Vec3.ZERO] - The offset to apply to the model relative to the joint position.
* @param {Quat} [rotation=Quat.IDENTITY] - The rotation to apply to the model relative to the joint orientation.
diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp
index a3d312b9c1..ed2a1d67eb 100644
--- a/libraries/shared/src/RegisteredMetaTypes.cpp
+++ b/libraries/shared/src/RegisteredMetaTypes.cpp
@@ -852,7 +852,21 @@ AnimationDetails::AnimationDetails(QString role, QUrl url, float fps, float prio
running(running), currentFrame(currentFrame), allowTranslation(allowTranslation) {
}
-
+/**jsdoc
+ * @typedef {object} Avatar.AnimationDetails
+ * @property {string} role
+ * @property {string} url
+ * @property {number} fps
+ * @property {number} priority
+ * @property {boolean} loop
+ * @property {boolean} hold
+ * @property {boolean} startAutomatically
+ * @property {number} firstFrame
+ * @property {number} lastFrame
+ * @property {boolean} running
+ * @property {number} currentFrame
+ * @property {boolean} allowTranslation
+ */
QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& details) {
QScriptValue obj = engine->newObject();
obj.setProperty("role", details.role);
diff --git a/tools/jsdoc/plugins/hifi.js b/tools/jsdoc/plugins/hifi.js
index 21749c7fe2..4378c2b4cb 100644
--- a/tools/jsdoc/plugins/hifi.js
+++ b/tools/jsdoc/plugins/hifi.js
@@ -21,6 +21,7 @@ exports.handlers = {
// directories to scan for jsdoc comments
var dirList = [
'../../assignment-client/src',
+ '../../assignment-client/src/avatars',
'../../assignment-client/src/entities',
'../../assignment-client/src/octree',
'../../interface/src',
@@ -31,10 +32,10 @@ exports.handlers = {
'../../interface/src/devices',
'../../interface/src/java',
'../../interface/src/networking',
- '../../interface/src/ui/',
- '../../interface/src/scripting',
- '../../interface/src/ui/overlays',
'../../interface/src/raypick',
+ '../../interface/src/scripting',
+ '../../interface/src/ui/',
+ '../../interface/src/ui/overlays',
'../../libraries/animation/src',
'../../libraries/audio-client/src',
'../../libraries/audio/src',
From 4a3001be1894545ca4c52fb278fe5bab34e7fef4 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Tue, 15 May 2018 18:21:37 -0300
Subject: [PATCH 60/80] Fix clipping on the right edge of login italic text
views
---
.../hifiinterface/fragment/LoginFragment.java | 42 ++++++++++++++++++-
android/app/src/main/res/values/strings.xml | 6 +--
2 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java
index 7c1a7f6dc9..c2567d77a7 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java
@@ -7,6 +7,8 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -53,6 +55,44 @@ public class LoginFragment extends Fragment {
mLoginButton = rootView.findViewById(R.id.loginButton);
mForgotPassword = rootView.findViewById(R.id.forgotPassword);
+ mUsername.addTextChangedListener(new TextWatcher() {
+ boolean ignoreNextChange = false;
+ boolean hadBlankSpace = false;
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
+ hadBlankSpace = charSequence.length() > 0 && charSequence.charAt(charSequence.length()-1) == ' ';
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ if (!ignoreNextChange) {
+ ignoreNextChange = true;
+ boolean spaceFound=false;
+ for (int i=0; i< editable.length(); i++) {
+ if (editable.charAt(i) == ' ') {
+ spaceFound=true;
+ editable.delete(i, i+1);
+ i--;
+ }
+ }
+
+ if (hadBlankSpace && !spaceFound && editable.length() > 0) {
+ editable.delete(editable.length()-1, editable.length());
+ }
+
+ editable.append(' ');
+ ignoreNextChange = false;
+ }
+
+ }
+ });
+
+
mLoginButton.setOnClickListener(view -> login());
mForgotPassword.setOnClickListener(view -> forgotPassword());
@@ -93,7 +133,7 @@ public class LoginFragment extends Fragment {
}
public void login() {
- String username = mUsername.getText().toString();
+ String username = mUsername.getText().toString().trim();
String password = mPassword.getText().toString();
hideKeyboard();
if (username.isEmpty() || password.isEmpty()) {
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
index a34b480c3c..9646fe0a7e 100644
--- a/android/app/src/main/res/values/strings.xml
+++ b/android/app/src/main/res/values/strings.xml
@@ -9,11 +9,11 @@
POPULARBOOKMARKSType a domain url
- Username or email
- Password
+ Username or email\u00A0
+ Password\u00A0LoginLogout
- Forgot password?
+ Forgot password?\u00A0Username or password incorrect.Logging into High FidelitySearch for a place by name\u00A0
From f629022b8c51b22146c11b4df23a09bd78f62f7a Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Wed, 16 May 2018 10:16:13 +1200
Subject: [PATCH 61/80] AvatarList API JSDoc stubs
---
interface/src/avatar/AvatarManager.h | 15 ++++++++++++
libraries/avatars/src/AvatarHashMap.h | 35 ++++++++++++++++++---------
2 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h
index 7f5aa00466..6a3d0355f6 100644
--- a/interface/src/avatar/AvatarManager.h
+++ b/interface/src/avatar/AvatarManager.h
@@ -29,10 +29,25 @@
/**jsdoc
* The AvatarManager API has properties and methods which manage Avatars within the same domain.
+ *
+ *
Note: This API is also provided to Interface and client entity scripts as the synonym,
+ * AvatarList. For assignment client scripts, see the separate {@link AvatarList} API.
+ *
* @namespace AvatarManager
*
* @hifi-interface
* @hifi-client-entity
+ *
+ * @borrows AvatarList.getAvatarIdentifiers as getAvatarIdentifiers
+ * @borrows AvatarList.getAvatarsInRange as getAvatarsInRange
+ * @borrows AvatarList.avatarAddedEvent as avatarAddedEvent
+ * @borrows AvatarList.avatarRemovedEvent as avatarRemovedEvent
+ * @borrows AvatarList.avatarSessionChangedEvent as avatarSessionChangedEvent
+ * @borrows AvatarList.isAvatarInRange as isAvatarInRange
+ * @borrows AvatarList.sessionUUIDChanged as sessionUUIDChanged
+ * @borrows AvatarList.processAvatarDataPacket as processAvatarDataPacket
+ * @borrows AvatarList.processAvatarIdentityPacket as processAvatarIdentityPacket
+ * @borrows AvatarList.processKillAvatar as processKillAvatar
*/
class AvatarManager : public AvatarHashMap {
diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h
index dc3f40c5d3..6747025de0 100644
--- a/libraries/avatars/src/AvatarHashMap.h
+++ b/libraries/avatars/src/AvatarHashMap.h
@@ -30,6 +30,15 @@
#include "AvatarData.h"
+/**jsdoc
+ * Note: An AvatarList API is also provided for Interface and client entity scripts: it is a
+ * synonym for the {@link AvatarManager} API.
+ *
+ * @namespace AvatarList
+ *
+ * @hifi-assignment-client
+ */
+
class AvatarHashMap : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
@@ -42,20 +51,24 @@ public:
// Currently, your own avatar will be included as the null avatar id.
/**jsdoc
- * @function AvatarManager.getAvatarIdentifiers
+ * @function AvatarList.getAvatarIdentifiers
* @returns {Uuid[]}
*/
Q_INVOKABLE QVector getAvatarIdentifiers();
/**jsdoc
- * @function AvatarManager.getAvatarsInRange
+ * @function AvatarList.getAvatarsInRange
* @param {Vec3} position
* @param {number} range
* @returns {Uuid[]}
*/
Q_INVOKABLE QVector getAvatarsInRange(const glm::vec3& position, float rangeMeters) const;
- // No JSDod because it's documwented in AvatarManager.
+ /**jsdoc
+ * @function AvatarList.getAvatar
+ * @param {Uuid} avatarID
+ * @returns {AvatarData}
+ */
// Null/Default-constructed QUuids will return MyAvatar
Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); }
@@ -65,21 +78,21 @@ public:
signals:
/**jsdoc
- * @function AvatarManager.avatarAddedEvent
+ * @function AvatarList.avatarAddedEvent
* @param {Uuid} sessionUUID
* @returns {Signal}
*/
void avatarAddedEvent(const QUuid& sessionUUID);
/**jsdoc
- * @function AvatarManager.avatarRemovedEvent
+ * @function AvatarList.avatarRemovedEvent
* @param {Uuid} sessionUUID
* @returns {Signal}
*/
void avatarRemovedEvent(const QUuid& sessionUUID);
/**jsdoc
- * @function AvatarManager.avatarSessionChangedEvent
+ * @function AvatarList.avatarSessionChangedEvent
* @param {Uuid} sessionUUID
* @param {Uuid} oldSessionUUID
* @returns {Signal}
@@ -89,7 +102,7 @@ signals:
public slots:
/**jsdoc
- * @function AvatarManager.isAvatarInRange
+ * @function AvatarList.isAvatarInRange
* @param {string} position
* @param {string} range
* @returns {boolean}
@@ -99,28 +112,28 @@ public slots:
protected slots:
/**jsdoc
- * @function AvatarManager.sessionUUIDChanged
+ * @function AvatarList.sessionUUIDChanged
* @param {Uuid} sessionUUID
* @param {Uuid} oldSessionUUID
*/
void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
/**jsdoc
- * @function AvatarManager.processAvatarDataPacket
+ * @function AvatarList.processAvatarDataPacket
* @param {} message
* @param {} sendingNode
*/
void processAvatarDataPacket(QSharedPointer message, SharedNodePointer sendingNode);
/**jsdoc
- * @function AvatarManager.processAvatarIdentityPacket
+ * @function AvatarList.processAvatarIdentityPacket
* @param {} message
* @param {} sendingNode
*/
void processAvatarIdentityPacket(QSharedPointer message, SharedNodePointer sendingNode);
/**jsdoc
- * @function AvatarManager.processKillAvatar
+ * @function AvatarList.processKillAvatar
* @param {} message
* @param {} sendingNode
*/
From 179801dab6fe1802163491b63624fad688e7aaaa Mon Sep 17 00:00:00 2001
From: samcake
Date: Tue, 15 May 2018 17:22:28 -0700
Subject: [PATCH 62/80] FIxing the transparent ambient lighting bug
---
.../render-utils/src/DeferredBufferWrite.slh | 7 ++--
.../render-utils/src/DeferredGlobalLight.slh | 6 +--
.../src/DeferredLightingEffect.cpp | 39 +++++++++++--------
.../render-utils/src/DeferredLightingEffect.h | 4 +-
libraries/render-utils/src/GeometryCache.cpp | 4 +-
libraries/render-utils/src/Haze.slf | 2 +-
libraries/render-utils/src/LightClusters.cpp | 2 +-
libraries/render-utils/src/LightingModel.cpp | 9 +++++
libraries/render-utils/src/LightingModel.h | 11 +++++-
libraries/render-utils/src/LightingModel.slh | 5 +++
.../render-utils/src/RenderDeferredTask.cpp | 29 ++++++++++----
.../render-utils/src/RenderForwardTask.cpp | 2 +-
libraries/render/src/render/ShapePipeline.cpp | 6 +--
libraries/render/src/render/ShapePipeline.h | 5 ++-
.../utilities/render/deferredLighting.qml | 3 +-
15 files changed, 90 insertions(+), 44 deletions(-)
diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh
index 49db49af2a..ae8d6fa277 100644
--- a/libraries/render-utils/src/DeferredBufferWrite.slh
+++ b/libraries/render-utils/src/DeferredBufferWrite.slh
@@ -27,6 +27,7 @@ float evalOpaqueFinalAlpha(float alpha, float mapAlpha) {
}
<@include DefaultMaterials.slh@>
+<@include LightingModel.slh@>
void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 emissive, float occlusion, float scattering) {
if (alpha != 1.0) {
@@ -36,7 +37,7 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(((scattering > 0.0) ? vec3(scattering) : emissive), occlusion);
- _fragColor3 = vec4(emissive, 1.0);
+ _fragColor3 = vec4(isEmissiveEnabled() * emissive, 1.0);
}
void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 fresnel, vec3 lightmap) {
@@ -46,9 +47,9 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float r
_fragColor0 = vec4(albedo, packLightmappedMetallic(metallic));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
- _fragColor2 = vec4(lightmap, 1.0);
+ _fragColor2 = vec4(isLightmapEnabled() * lightmap, 1.0);
- _fragColor3 = vec4(lightmap * albedo, 1.0);
+ _fragColor3 = vec4(isLightmapEnabled() * lightmap * albedo, 1.0);
}
void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) {
diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh
index f6c1d290a7..bb712bf9d2 100644
--- a/libraries/render-utils/src/DeferredGlobalLight.slh
+++ b/libraries/render-utils/src/DeferredGlobalLight.slh
@@ -140,7 +140,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
color += directionalSpecular;
// Attenuate the light if haze effect selected
- if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
+ if ((isHazeEnabled() > 0) && (hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
}
@@ -234,7 +234,7 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
color += (ambientSpecular + directionalSpecular) / opacity;
// Haze
- if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
+ if ((isHazeEnabled() > 0) && (hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 colorV4 = computeHazeColor(
vec4(color, 1.0), // fragment original color
positionES, // fragment position in eye coordinates
@@ -272,7 +272,7 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
color += (ambientSpecular + directionalSpecular) / opacity;
// Haze
- if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
+ if ((isHazeEnabled() > 0) && (hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
vec4 colorV4 = computeHazeColor(
vec4(color, 1.0), // fragment original color
positionES, // fragment position in eye coordinates
diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp
index 956b6c4a58..3074bb2e7f 100644
--- a/libraries/render-utils/src/DeferredLightingEffect.cpp
+++ b/libraries/render-utils/src/DeferredLightingEffect.cpp
@@ -61,20 +61,22 @@ enum DeferredShader_MapSlot {
DEFERRED_BUFFER_EMISSIVE_UNIT = 2,
DEFERRED_BUFFER_DEPTH_UNIT = 3,
DEFERRED_BUFFER_OBSCURANCE_UNIT = 4,
- SHADOW_MAP_UNIT = 5,
- SKYBOX_MAP_UNIT = SHADOW_MAP_UNIT + SHADOW_CASCADE_MAX_COUNT,
- DEFERRED_BUFFER_LINEAR_DEPTH_UNIT,
- DEFERRED_BUFFER_CURVATURE_UNIT,
- DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT,
- SCATTERING_LUT_UNIT,
- SCATTERING_SPECULAR_UNIT,
+ DEFERRED_BUFFER_LINEAR_DEPTH_UNIT = 5,
+ DEFERRED_BUFFER_CURVATURE_UNIT = 6,
+ DEFERRED_BUFFER_DIFFUSED_CURVATURE_UNIT = 7,
+ SCATTERING_LUT_UNIT = 8,
+ SCATTERING_SPECULAR_UNIT = 9,
+ SKYBOX_MAP_UNIT = render::ShapePipeline::Slot::LIGHT_AMBIENT_MAP, // unit = 10
+ SHADOW_MAP_UNIT = 11,
+ nextAvailableUnit = SHADOW_MAP_UNIT + SHADOW_CASCADE_MAX_COUNT
};
enum DeferredShader_BufferSlot {
DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT = 0,
CAMERA_CORRECTION_BUFFER_SLOT,
SCATTERING_PARAMETERS_BUFFER_SLOT,
LIGHTING_MODEL_BUFFER_SLOT = render::ShapePipeline::Slot::LIGHTING_MODEL,
- LIGHT_GPU_SLOT = render::ShapePipeline::Slot::LIGHT,
+ KEY_LIGHT_SLOT = render::ShapePipeline::Slot::KEY_LIGHT,
+ LIGHT_ARRAY_SLOT = render::ShapePipeline::Slot::LIGHT_ARRAY_BUFFER,
LIGHT_AMBIENT_SLOT = render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER,
HAZE_MODEL_BUFFER_SLOT = render::ShapePipeline::Slot::HAZE_MODEL,
LIGHT_INDEX_GPU_SLOT,
@@ -149,17 +151,20 @@ void DeferredLightingEffect::unsetKeyLightBatch(gpu::Batch& batch, int lightBuff
}
void DeferredLightingEffect::setupLocalLightsBatch(gpu::Batch& batch,
- int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit,
+ int lightArrayBufferUnit, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit,
const LightClustersPointer& lightClusters) {
// Bind the global list of lights and the visible lights this frame
- batch.setUniformBuffer(_localLightLocations->lightBufferUnit, lightClusters->_lightStage->getLightArrayBuffer());
+ batch.setUniformBuffer(lightArrayBufferUnit, lightClusters->_lightStage->getLightArrayBuffer());
batch.setUniformBuffer(frustumGridBufferUnit, lightClusters->_frustumGridBuffer);
batch.setUniformBuffer(clusterGridBufferUnit, lightClusters->_clusterGridBuffer);
batch.setUniformBuffer(clusterContentBufferUnit, lightClusters->_clusterContentBuffer);
}
-void DeferredLightingEffect::unsetLocalLightsBatch(gpu::Batch& batch, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit) {
+void DeferredLightingEffect::unsetLocalLightsBatch(gpu::Batch& batch, int lightArrayBufferUnit, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit) {
+ if (lightArrayBufferUnit >= 0) {
+ batch.setUniformBuffer(lightArrayBufferUnit, nullptr);
+ }
if (clusterGridBufferUnit >= 0) {
batch.setUniformBuffer(clusterGridBufferUnit, nullptr);
}
@@ -194,7 +199,8 @@ static gpu::ShaderPointer makeLightProgram(const gpu::ShaderPointer& vertShader,
slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), LIGHTING_MODEL_BUFFER_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), HAZE_MODEL_BUFFER_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("subsurfaceScatteringParametersBuffer"), SCATTERING_PARAMETERS_BUFFER_SLOT));
- slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT));
+ slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), KEY_LIGHT_SLOT));
+ slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_ARRAY_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), LIGHT_AMBIENT_SLOT));
slotBindings.insert(gpu::Shader::Binding(std::string("lightIndexBuffer"), LIGHT_INDEX_GPU_SLOT));
@@ -592,7 +598,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
batch._glUniform4fv(locations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
// Setup the global lighting
- deferredLightingEffect->setupKeyLightBatch(args, batch, locations->keyLightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
+ deferredLightingEffect->setupKeyLightBatch(args, batch, KEY_LIGHT_SLOT, LIGHT_AMBIENT_SLOT, SKYBOX_MAP_UNIT);
// Haze
if (haze) {
@@ -601,7 +607,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
batch.draw(gpu::TRIANGLE_STRIP, 4);
- deferredLightingEffect->unsetKeyLightBatch(batch, locations->keyLightBufferUnit, locations->ambientBufferUnit, SKYBOX_MAP_UNIT);
+ deferredLightingEffect->unsetKeyLightBatch(batch, KEY_LIGHT_SLOT, LIGHT_AMBIENT_SLOT, SKYBOX_MAP_UNIT);
for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) {
batch.setResourceTexture(SHADOW_MAP_UNIT+i, nullptr);
@@ -656,8 +662,9 @@ void RenderDeferredLocals::run(const render::RenderContextPointer& renderContext
auto& lightIndices = lightClusters->_visibleLightIndices;
if (!lightIndices.empty() && lightIndices[0] > 0) {
- deferredLightingEffect->setupLocalLightsBatch(batch, LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT,
- lightClusters);
+ deferredLightingEffect->setupLocalLightsBatch(batch,
+ LIGHT_ARRAY_SLOT, LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT, LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT, LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT,
+ lightClusters);
// Local light pipeline
batch.setPipeline(deferredLightingEffect->_localLight);
diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h
index ce7ecacbbe..3b77b8137e 100644
--- a/libraries/render-utils/src/DeferredLightingEffect.h
+++ b/libraries/render-utils/src/DeferredLightingEffect.h
@@ -51,8 +51,8 @@ public:
void setupKeyLightBatch(const RenderArgs* args, gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit);
void unsetKeyLightBatch(gpu::Batch& batch, int lightBufferUnit, int ambientBufferUnit, int skyboxCubemapUnit);
- void setupLocalLightsBatch(gpu::Batch& batch, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit, const LightClustersPointer& lightClusters);
- void unsetLocalLightsBatch(gpu::Batch& batch, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit);
+ void setupLocalLightsBatch(gpu::Batch& batch, int lightArrayBufferUnit, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit, const LightClustersPointer& lightClusters);
+ void unsetLocalLightsBatch(gpu::Batch& batch, int lightArrayBufferUnit, int clusterGridBufferUnit, int clusterContentBufferUnit, int frustumGridBufferUnit);
void setShadowMapEnabled(bool enable) { _shadowMapEnabled = enable; };
void setAmbientOcclusionEnabled(bool enable) { _ambientOcclusionEnabled = enable; }
diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp
index 8be142d939..0d8561ad21 100644
--- a/libraries/render-utils/src/GeometryCache.cpp
+++ b/libraries/render-utils/src/GeometryCache.cpp
@@ -2264,7 +2264,7 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), render::ShapePipeline::Slot::LIGHTING_MODEL));
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), render::ShapePipeline::Slot::KEY_LIGHT));
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER));
- slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), render::ShapePipeline::Slot::MAP::LIGHT_AMBIENT));
+ slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), render::ShapePipeline::Slot::MAP::LIGHT_AMBIENT_MAP));
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
gpu::Shader::makeProgram(*_transparentShader, slotBindings);
gpu::Shader::makeProgram(*_unlitShader, slotBindings);
@@ -2284,7 +2284,7 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), render::ShapePipeline::Slot::LIGHTING_MODEL));
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), render::ShapePipeline::Slot::KEY_LIGHT));
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER));
- slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), render::ShapePipeline::Slot::MAP::LIGHT_AMBIENT));
+ slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), render::ShapePipeline::Slot::MAP::LIGHT_AMBIENT_MAP));
slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), render::ShapePipeline::Slot::MAP::FADE_MASK));
gpu::Shader::makeProgram(*_simpleFadeShader, slotBindings);
gpu::Shader::makeProgram(*_unlitFadeShader, slotBindings);
diff --git a/libraries/render-utils/src/Haze.slf b/libraries/render-utils/src/Haze.slf
index b9f23fd932..dc4f04b144 100644
--- a/libraries/render-utils/src/Haze.slf
+++ b/libraries/render-utils/src/Haze.slf
@@ -42,7 +42,7 @@ in vec2 varTexCoord0;
out vec4 outFragColor;
void main(void) {
- if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) != HAZE_MODE_IS_ACTIVE) {
+ if ((isHazeEnabled() == 0) || (hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) != HAZE_MODE_IS_ACTIVE) {
discard;
}
diff --git a/libraries/render-utils/src/LightClusters.cpp b/libraries/render-utils/src/LightClusters.cpp
index ea02edb601..36d3fe9e49 100644
--- a/libraries/render-utils/src/LightClusters.cpp
+++ b/libraries/render-utils/src/LightClusters.cpp
@@ -39,7 +39,7 @@ enum LightClusterGridShader_MapSlot {
enum LightClusterGridShader_BufferSlot {
DEFERRED_FRAME_TRANSFORM_BUFFER_SLOT = 0,
CAMERA_CORRECTION_BUFFER_SLOT = 1,
- LIGHT_GPU_SLOT = render::ShapePipeline::Slot::LIGHT,
+ LIGHT_GPU_SLOT = render::ShapePipeline::Slot::LIGHT_ARRAY_BUFFER,
LIGHT_INDEX_GPU_SLOT = 7,
LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT = 8,
LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT = 9,
diff --git a/libraries/render-utils/src/LightingModel.cpp b/libraries/render-utils/src/LightingModel.cpp
index 30801ac69e..23d4c66fd5 100644
--- a/libraries/render-utils/src/LightingModel.cpp
+++ b/libraries/render-utils/src/LightingModel.cpp
@@ -49,6 +49,14 @@ void LightingModel::setBackground(bool enable) {
bool LightingModel::isBackgroundEnabled() const {
return (bool)_parametersBuffer.get().enableBackground;
}
+void LightingModel::setHaze(bool enable) {
+ if (enable != isHazeEnabled()) {
+ _parametersBuffer.edit().enableHaze = (float)enable;
+ }
+}
+bool LightingModel::isHazeEnabled() const {
+ return (bool)_parametersBuffer.get().enableHaze;
+}
void LightingModel::setObscurance(bool enable) {
if (enable != isObscuranceEnabled()) {
_parametersBuffer.edit().enableObscurance = (float)enable;
@@ -160,6 +168,7 @@ void MakeLightingModel::configure(const Config& config) {
_lightingModel->setEmissive(config.enableEmissive);
_lightingModel->setLightmap(config.enableLightmap);
_lightingModel->setBackground(config.enableBackground);
+ _lightingModel->setHaze(config.enableHaze);
_lightingModel->setObscurance(config.enableObscurance);
diff --git a/libraries/render-utils/src/LightingModel.h b/libraries/render-utils/src/LightingModel.h
index e058b10921..c71917603c 100644
--- a/libraries/render-utils/src/LightingModel.h
+++ b/libraries/render-utils/src/LightingModel.h
@@ -36,6 +36,9 @@ public:
void setBackground(bool enable);
bool isBackgroundEnabled() const;
+ void setHaze(bool enable);
+ bool isHazeEnabled() const;
+
void setObscurance(bool enable);
bool isObscuranceEnabled() const;
@@ -86,7 +89,6 @@ protected:
float enableSpecular{ 1.0f };
float enableAlbedo{ 1.0f };
-
float enableAmbientLight{ 1.0f };
float enableDirectionalLight{ 1.0f };
float enablePointLight{ 1.0f };
@@ -99,6 +101,11 @@ protected:
float enableMaterialTexturing { 1.0f };
float enableWireframe { 0.0f }; // false by default
+ float enableHaze{ 1.0f };
+ float spare1; // Needed for having the LightingModel class aligned on a 4 scalar boundary for gpu
+ float spare2;
+ float spare3;
+
Parameters() {}
};
UniformBufferView _parametersBuffer;
@@ -116,6 +123,7 @@ class MakeLightingModelConfig : public render::Job::Config {
Q_PROPERTY(bool enableEmissive MEMBER enableEmissive NOTIFY dirty)
Q_PROPERTY(bool enableLightmap MEMBER enableLightmap NOTIFY dirty)
Q_PROPERTY(bool enableBackground MEMBER enableBackground NOTIFY dirty)
+ Q_PROPERTY(bool enableHaze MEMBER enableHaze NOTIFY dirty)
Q_PROPERTY(bool enableObscurance MEMBER enableObscurance NOTIFY dirty)
@@ -158,6 +166,7 @@ public:
bool showLightContour { false }; // false by default
bool enableWireframe { false }; // false by default
+ bool enableHaze{ true };
signals:
void dirty();
diff --git a/libraries/render-utils/src/LightingModel.slh b/libraries/render-utils/src/LightingModel.slh
index 6a5982f1e8..309a4899a2 100644
--- a/libraries/render-utils/src/LightingModel.slh
+++ b/libraries/render-utils/src/LightingModel.slh
@@ -18,6 +18,7 @@ struct LightingModel {
PRECISIONQ vec4 _ScatteringDiffuseSpecularAlbedo;
PRECISIONQ vec4 _AmbientDirectionalPointSpot;
PRECISIONQ vec4 _ShowContourObscuranceWireframe;
+ PRECISIONQ vec4 _Haze_spareyzw;
};
uniform lightingModelBuffer{
@@ -74,6 +75,10 @@ float isWireframeEnabled() {
return lightingModel._ShowContourObscuranceWireframe.z;
}
+float isHazeEnabled() {
+ return lightingModel._Haze_spareyzw.x;
+}
+
<@endfunc@>
<$declareLightingModel()$>
diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp
index ab1d831ead..3ea56f8542 100644
--- a/libraries/render-utils/src/RenderDeferredTask.cpp
+++ b/libraries/render-utils/src/RenderDeferredTask.cpp
@@ -340,11 +340,18 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
// Setup lighting model for all items;
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
- deferredLightingEffect->setupLocalLightsBatch(batch,
- render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
- render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
- render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT,
- lightClusters);
+ // Set the light
+ deferredLightingEffect->setupKeyLightBatch(args, batch,
+ render::ShapePipeline::Slot::KEY_LIGHT,
+ render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER,
+ render::ShapePipeline::Slot::LIGHT_AMBIENT_MAP);
+
+ deferredLightingEffect->setupLocalLightsBatch(batch,
+ render::ShapePipeline::Slot::LIGHT_ARRAY_BUFFER,
+ render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
+ render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
+ render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT,
+ lightClusters);
// Setup haze if current zone has haze
auto hazeStage = args->_scene->getStage();
@@ -370,9 +377,15 @@ void DrawDeferred::run(const RenderContextPointer& renderContext, const Inputs&
args->_globalShapeKey = 0;
deferredLightingEffect->unsetLocalLightsBatch(batch,
- render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
- render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
- render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT);
+ render::ShapePipeline::Slot::LIGHT_ARRAY_BUFFER,
+ render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_GRID_SLOT,
+ render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_CLUSTER_CONTENT_SLOT,
+ render::ShapePipeline::Slot::LIGHT_CLUSTER_GRID_FRUSTUM_GRID_SLOT);
+
+ deferredLightingEffect->unsetKeyLightBatch(batch,
+ render::ShapePipeline::Slot::KEY_LIGHT,
+ render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER,
+ render::ShapePipeline::Slot::LIGHT_AMBIENT_MAP);
});
config->setNumDrawn((int)inItems.size());
diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp
index 63370109e0..294d8e12f4 100755
--- a/libraries/render-utils/src/RenderForwardTask.cpp
+++ b/libraries/render-utils/src/RenderForwardTask.cpp
@@ -175,7 +175,7 @@ void PrepareForward::run(const RenderContextPointer& renderContext, const Inputs
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER, keyAmbiLight->getAmbientSchemaBuffer());
if (keyAmbiLight->getAmbientMap()) {
- batch.setResourceTexture(render::ShapePipeline::Slot::LIGHT_AMBIENT, keyAmbiLight->getAmbientMap());
+ batch.setResourceTexture(render::ShapePipeline::Slot::LIGHT_AMBIENT_MAP, keyAmbiLight->getAmbientMap());
}
}
});
diff --git a/libraries/render/src/render/ShapePipeline.cpp b/libraries/render/src/render/ShapePipeline.cpp
index 35cc66315b..7788b14795 100644
--- a/libraries/render/src/render/ShapePipeline.cpp
+++ b/libraries/render/src/render/ShapePipeline.cpp
@@ -89,9 +89,9 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
slotBindings.insert(gpu::Shader::Binding(std::string("occlusionMap"), Slot::MAP::OCCLUSION));
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringMap"), Slot::MAP::SCATTERING));
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), Slot::BUFFER::KEY_LIGHT));
- slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::BUFFER::LIGHT));
+ slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), Slot::BUFFER::LIGHT_ARRAY_BUFFER));
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), Slot::BUFFER::LIGHT_AMBIENT_BUFFER));
- slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT));
+ slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), Slot::MAP::LIGHT_AMBIENT_MAP));
slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), Slot::MAP::FADE_MASK));
slotBindings.insert(gpu::Shader::Binding(std::string("fadeParametersBuffer"), Slot::BUFFER::FADE_PARAMETERS));
slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), Slot::BUFFER::HAZE_MODEL));
@@ -123,7 +123,7 @@ void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& p
locations->lightAmbientMapUnit = program->getTextures().findLocation("skyboxMap");
locations->fadeMaskTextureUnit = program->getTextures().findLocation("fadeMaskMap");
locations->fadeParameterBufferUnit = program->getUniformBuffers().findLocation("fadeParametersBuffer");
- locations->hazeParameterBufferUnit = program->getUniformBuffers().findLocation("hazeParametersBuffer");
+ locations->hazeParameterBufferUnit = program->getUniformBuffers().findLocation("hazeBuffer");
if (key.isTranslucent()) {
locations->lightClusterGridBufferUnit = program->getUniformBuffers().findLocation("clusterGridBuffer");
locations->lightClusterContentBufferUnit = program->getUniformBuffers().findLocation("clusterContentBuffer");
diff --git a/libraries/render/src/render/ShapePipeline.h b/libraries/render/src/render/ShapePipeline.h
index a6bfb4a234..7d87d98deb 100644
--- a/libraries/render/src/render/ShapePipeline.h
+++ b/libraries/render/src/render/ShapePipeline.h
@@ -236,7 +236,7 @@ public:
TEXMAPARRAY,
LIGHTING_MODEL,
KEY_LIGHT,
- LIGHT,
+ LIGHT_ARRAY_BUFFER,
LIGHT_AMBIENT_BUFFER,
HAZE_MODEL,
FADE_PARAMETERS,
@@ -254,8 +254,9 @@ public:
ROUGHNESS,
OCCLUSION,
SCATTERING,
- LIGHT_AMBIENT,
FADE_MASK,
+
+ LIGHT_AMBIENT_MAP = 10,
};
};
diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml
index 189d23c44f..b2d917475e 100644
--- a/scripts/developer/utilities/render/deferredLighting.qml
+++ b/scripts/developer/utilities/render/deferredLighting.qml
@@ -45,7 +45,8 @@ Rectangle {
"Unlit:LightingModel:enableUnlit",
"Emissive:LightingModel:enableEmissive",
"Lightmap:LightingModel:enableLightmap",
- "Background:LightingModel:enableBackground",
+ "Background:LightingModel:enableBackground",
+ "Haze:LightingModel:enableHaze",
"ssao:AmbientOcclusion:enabled",
"Textures:LightingModel:enableMaterialTexturing"
]
From fe5da244837f45d8301bd9d33e5b9aa633d8fda1 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Wed, 16 May 2018 15:12:42 -0300
Subject: [PATCH 63/80] Fix spaces
---
.../main/java/io/highfidelity/hifiinterface/HifiUtils.java | 2 +-
.../java/io/highfidelity/hifiinterface/MainActivity.java | 2 +-
.../highfidelity/hifiinterface/fragment/LoginFragment.java | 6 +++---
android/app/src/main/res/layout/fragment_home.xml | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java
index 94378529f0..f92cd0a385 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/HifiUtils.java
@@ -45,7 +45,7 @@ public class HifiUtils {
}
public String absoluteHifiAssetUrl(String urlString, String baseUrl) {
- urlString = urlString.trim();
+ urlString = urlString.trim();
if (!urlString.isEmpty()) {
URI uri;
try {
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
index 1ecd1e193c..c70c20a924 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
@@ -251,7 +251,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
*/
private void updateProfilePicture(String username) {
mProfilePicture.setImageResource(PROFILE_PICTURE_PLACEHOLDER);
- new DownloadProfileImageTask(url -> { if (url!=null && !url.isEmpty()) {
+ new DownloadProfileImageTask(url -> { if (url != null && !url.isEmpty()) {
Picasso.get().load(url).into(mProfilePicture, new RoundProfilePictureCallback());
} } ).execute(username);
}
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java
index c2567d77a7..f29c237ed7 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/LoginFragment.java
@@ -72,11 +72,11 @@ public class LoginFragment extends Fragment {
public void afterTextChanged(Editable editable) {
if (!ignoreNextChange) {
ignoreNextChange = true;
- boolean spaceFound=false;
- for (int i=0; i< editable.length(); i++) {
+ boolean spaceFound = false;
+ for (int i = 0; i < editable.length(); i++) {
if (editable.charAt(i) == ' ') {
spaceFound=true;
- editable.delete(i, i+1);
+ editable.delete(i, i + 1);
i--;
}
}
diff --git a/android/app/src/main/res/layout/fragment_home.xml b/android/app/src/main/res/layout/fragment_home.xml
index a5eea62bb6..cb39b8f69e 100644
--- a/android/app/src/main/res/layout/fragment_home.xml
+++ b/android/app/src/main/res/layout/fragment_home.xml
@@ -6,7 +6,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
- android:background="@color/colorPrimary"
+ android:background="@color/colorPrimary"
tools:context="io.highfidelity.hifiinterface.MainActivity"
tools:showIn="@layout/activity_home">
From 21e069c90c1ce459abd08f91259221eb449a42a6 Mon Sep 17 00:00:00 2001
From: samcake
Date: Wed, 16 May 2018 13:09:55 -0700
Subject: [PATCH 64/80] Adding a toggle button to the developer/Render menu to
be able to disable taa and fall back to Fxaa
---
interface/src/Menu.cpp | 20 ++++++++++++++++++
interface/src/Menu.h | 1 +
.../render-utils/src/AntialiasingEffect.h | 8 +++++--
.../utilities/render/antialiasing.qml | 21 ++++++++++---------
4 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp
index 4384635147..310e873212 100644
--- a/interface/src/Menu.cpp
+++ b/interface/src/Menu.cpp
@@ -47,6 +47,7 @@
#include "AmbientOcclusionEffect.h"
#include "RenderShadowTask.h"
+#include "AntialiasingEffect.h"
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
#include "SpeechRecognizer.h"
@@ -380,6 +381,25 @@ Menu::Menu() {
// Developer > Render >>>
MenuWrapper* renderOptionsMenu = developerMenu->addMenu("Render");
+
+ action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::AntiAliasing, 0, true);
+ connect(action, &QAction::triggered, [action] {
+ auto renderConfig = qApp->getRenderEngine()->getConfiguration();
+ if (renderConfig) {
+ auto mainViewJitterCamConfig = renderConfig->getConfig("RenderMainView.JitterCam");
+ auto mainViewAntialiasingConfig = renderConfig->getConfig("RenderMainView.Antialiasing");
+ if (mainViewJitterCamConfig && mainViewAntialiasingConfig) {
+ if (action->isChecked()) {
+ mainViewJitterCamConfig->play();
+ mainViewAntialiasingConfig->debugFXAAX = 1.0;
+ } else {
+ mainViewJitterCamConfig->none();
+ mainViewAntialiasingConfig->debugFXAAX = 0.0;
+ }
+ }
+ }
+ });
+
action = addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Shadows, 0, true);
connect(action, &QAction::triggered, [action] {
auto renderConfig = qApp->getRenderEngine()->getConfiguration();
diff --git a/interface/src/Menu.h b/interface/src/Menu.h
index bba70a6a89..92885f0801 100644
--- a/interface/src/Menu.h
+++ b/interface/src/Menu.h
@@ -210,6 +210,7 @@ namespace MenuOption {
const QString DesktopTabletToToolbar = "Desktop Tablet Becomes Toolbar";
const QString HMDTabletToToolbar = "HMD Tablet Becomes Toolbar";
const QString Shadows = "Shadows";
+ const QString AntiAliasing = "Temporal Antialiasing (FXAA if disabled)";
const QString AmbientOcclusion = "Ambient Occlusion";
}
diff --git a/libraries/render-utils/src/AntialiasingEffect.h b/libraries/render-utils/src/AntialiasingEffect.h
index a89666f58b..175f7b41e4 100644
--- a/libraries/render-utils/src/AntialiasingEffect.h
+++ b/libraries/render-utils/src/AntialiasingEffect.h
@@ -62,7 +62,7 @@ public:
};
using Config = JitterSampleConfig;
- using Output = glm::vec2;
+ using Output = glm::vec2;
using JobModel = render::Job::ModelO;
void configure(const Config& config);
@@ -95,7 +95,7 @@ class AntialiasingConfig : public render::Job::Config {
Q_PROPERTY(bool debug MEMBER debug NOTIFY dirty)
Q_PROPERTY(float debugX MEMBER debugX NOTIFY dirty)
- Q_PROPERTY(float debugFXAAX MEMBER debugFXAAX NOTIFY dirty)
+ Q_PROPERTY(bool fxaaOnOff READ debugFXAA WRITE setDebugFXAA NOTIFY dirty)
Q_PROPERTY(float debugShowVelocityThreshold MEMBER debugShowVelocityThreshold NOTIFY dirty)
Q_PROPERTY(bool showCursorPixel MEMBER showCursorPixel NOTIFY dirty)
Q_PROPERTY(glm::vec2 debugCursorTexcoord MEMBER debugCursorTexcoord NOTIFY dirty)
@@ -106,6 +106,10 @@ class AntialiasingConfig : public render::Job::Config {
public:
AntialiasingConfig() : render::Job::Config(true) {}
+ void setDebugFXAA(bool debug) { debugFXAAX = (debug ? 0.0f : 1.0f); emit dirty();}
+ bool debugFXAA() const { return (debugFXAAX == 0.0f ? true : false); }
+
+
float blend{ 0.25f };
float sharpen{ 0.05f };
diff --git a/scripts/developer/utilities/render/antialiasing.qml b/scripts/developer/utilities/render/antialiasing.qml
index 8bdd5c6a0d..1a8f9dac2d 100644
--- a/scripts/developer/utilities/render/antialiasing.qml
+++ b/scripts/developer/utilities/render/antialiasing.qml
@@ -38,21 +38,22 @@ Rectangle {
id: fxaaOnOff
property bool debugFXAA: false
HifiControls.Button {
- text: {
- if (fxaaOnOff.debugFXAA) {
- return "FXAA"
- } else {
- return "TAA"
- }
+ function getTheText() {
+ if (Render.getConfig("RenderMainView.Antialiasing").fxaaOnOff) {
+ return "FXAA"
+ } else {
+ return "TAA"
+ }
}
+ text: getTheText()
onClicked: {
- fxaaOnOff.debugFXAA = !fxaaOnOff.debugFXAA
- if (fxaaOnOff.debugFXAA) {
+ var onOff = !Render.getConfig("RenderMainView.Antialiasing").fxaaOnOff;
+ if (onOff) {
Render.getConfig("RenderMainView.JitterCam").none();
- Render.getConfig("RenderMainView.Antialiasing").debugFXAAX = 0;
+ Render.getConfig("RenderMainView.Antialiasing").fxaaOnOff = true;
} else {
Render.getConfig("RenderMainView.JitterCam").play();
- Render.getConfig("RenderMainView.Antialiasing").debugFXAAX = 1.0;
+ Render.getConfig("RenderMainView.Antialiasing").fxaaOnOff = false;
}
}
From 5370cb7725b7f5427058b49e6aaf2bc64f036a27 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Wed, 16 May 2018 18:15:31 -0300
Subject: [PATCH 65/80] Change login option UI
---
.../hifiinterface/MainActivity.java | 24 +++++----
.../main/res/drawable/hifi_logo_header.xml | 14 +++++
.../app/src/main/res/layout/activity_main.xml | 9 ----
.../src/main/res/layout/fragment_login.xml | 8 +--
.../src/main/res/layout/navigation_header.xml | 51 +++++++++++++++----
5 files changed, 75 insertions(+), 31 deletions(-)
create mode 100644 android/app/src/main/res/drawable/hifi_logo_header.xml
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
index c70c20a924..54161f60c6 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java
@@ -53,6 +53,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private NavigationView mNavigationView;
private ImageView mProfilePicture;
private TextView mDisplayName;
+ private View mLoginPanel;
+ private View mProfilePanel;
+ private TextView mLogoutOption;
private boolean backToScene;
@@ -63,6 +66,12 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
mNavigationView = findViewById(R.id.nav_view);
mNavigationView.setNavigationItemSelectedListener(this);
+
+ mLoginPanel = mNavigationView.getHeaderView(0).findViewById(R.id.loginPanel);
+ mProfilePanel = mNavigationView.getHeaderView(0).findViewById(R.id.profilePanel);
+
+ mLogoutOption = mNavigationView.findViewById(R.id.logout);
+
mDisplayName = mNavigationView.getHeaderView(0).findViewById(R.id.displayName);
mProfilePicture = mNavigationView.getHeaderView(0).findViewById(R.id.profilePicture);
@@ -113,7 +122,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private void loadHomeFragment() {
Fragment fragment = HomeFragment.newInstance();
-
loadFragment(fragment, getString(R.string.home), false);
}
@@ -143,17 +151,16 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private void updateLoginMenu() {
- TextView loginOption = findViewById(R.id.login);
- TextView logoutOption = findViewById(R.id.logout);
if (nativeIsLoggedIn()) {
- loginOption.setVisibility(View.GONE);
- logoutOption.setVisibility(View.VISIBLE);
+ mLoginPanel.setVisibility(View.GONE);
+ mProfilePanel.setVisibility(View.VISIBLE);
+ mLogoutOption.setVisibility(View.VISIBLE);
updateProfileHeader();
} else {
- loginOption.setVisibility(View.VISIBLE);
- logoutOption.setVisibility(View.GONE);
+ mLoginPanel.setVisibility(View.VISIBLE);
+ mProfilePanel.setVisibility(View.GONE);
+ mLogoutOption.setVisibility(View.GONE);
mDisplayName.setText("");
- mNavigationView.getHeaderView(0).setVisibility(View.INVISIBLE);
}
}
@@ -163,7 +170,6 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
private void updateProfileHeader(String username) {
if (!username.isEmpty()) {
mDisplayName.setText(username);
- mNavigationView.getHeaderView(0).setVisibility(View.VISIBLE);
updateProfilePicture(username);
}
}
diff --git a/android/app/src/main/res/drawable/hifi_logo_header.xml b/android/app/src/main/res/drawable/hifi_logo_header.xml
new file mode 100644
index 0000000000..017e636184
--- /dev/null
+++ b/android/app/src/main/res/drawable/hifi_logo_header.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/main/res/layout/activity_main.xml b/android/app/src/main/res/layout/activity_main.xml
index aaf6b43adb..f14bb66586 100644
--- a/android/app/src/main/res/layout/activity_main.xml
+++ b/android/app/src/main/res/layout/activity_main.xml
@@ -46,15 +46,6 @@
android:clickable="true"
android:orientation="vertical"
android:padding="@dimen/activity_horizontal_margin">
-
@@ -68,7 +68,7 @@
android:textStyle="italic"
android:textColor="@color/editTextColor"
android:textColorHint="@color/editTextColor"
- android:gravity="right"
+ android:gravity="right|center_vertical"
app:layout_constraintTop_toBottomOf="@id/username"
android:hint="@string/password"
android:layout_marginTop="13dp"
@@ -103,8 +103,8 @@
android:textStyle="italic"
android:paddingRight="10dp"
app:layout_constraintLeft_toLeftOf="@id/password"
- app:layout_constraintTop_toBottomOf="@id/password"
- android:layout_marginTop="11dp"
+ app:layout_constraintTop_toTopOf="@id/loginButton"
+ app:layout_constraintRight_toLeftOf="@id/loginButton"
android:textColor="@color/colorButton1"/>
diff --git a/android/app/src/main/res/layout/navigation_header.xml b/android/app/src/main/res/layout/navigation_header.xml
index b61e701f48..40ab589253 100644
--- a/android/app/src/main/res/layout/navigation_header.xml
+++ b/android/app/src/main/res/layout/navigation_header.xml
@@ -2,18 +2,52 @@
+ android:layout_height="176dp"
+ android:minHeight="176dp">
+
+
+
+
+
+
+ android:layout_gravity="center_vertical|left" />
-
+ android:layout_gravity="center_vertical"/>
+
\ No newline at end of file
From ade1d6c0567abed81bff1802a491cd2400adc9ab Mon Sep 17 00:00:00 2001
From: samcake
Date: Wed, 16 May 2018 15:37:13 -0700
Subject: [PATCH 66/80] use the correct call to toggle the debugFXAA on the
AaConfig
---
interface/src/Menu.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp
index 310e873212..c3ca5feeee 100644
--- a/interface/src/Menu.cpp
+++ b/interface/src/Menu.cpp
@@ -391,10 +391,10 @@ Menu::Menu() {
if (mainViewJitterCamConfig && mainViewAntialiasingConfig) {
if (action->isChecked()) {
mainViewJitterCamConfig->play();
- mainViewAntialiasingConfig->debugFXAAX = 1.0;
+ mainViewAntialiasingConfig->setDebugFXAA(false);
} else {
mainViewJitterCamConfig->none();
- mainViewAntialiasingConfig->debugFXAAX = 0.0;
+ mainViewAntialiasingConfig->setDebugFXAA(true);
}
}
}
From 65a9b98b97f72112892b6d0f4102d38eb9b08b0e Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Wed, 16 May 2018 20:07:10 -0300
Subject: [PATCH 67/80] Use android.os.Vibrator to perform haptic feedback in
Android
---
.../io/highfidelity/hifiinterface/InterfaceActivity.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
index d20fc84020..4d1e13becf 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
@@ -15,6 +15,7 @@ import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Vibrator;
import android.view.HapticFeedbackConstants;
import android.view.WindowManager;
import android.util.Log;
@@ -34,6 +35,7 @@ public class InterfaceActivity extends QtActivity {
public static final String DOMAIN_URL = "url";
private static final String TAG = "Interface";
+ private Vibrator mVibrator;
//public static native void handleHifiURL(String hifiURLString);
private native long nativeOnCreate(InterfaceActivity instance, AssetManager assetManager);
@@ -105,7 +107,7 @@ public class InterfaceActivity extends QtActivity {
}
});
startActivity(new Intent(this, SplashActivity.class));
-
+ mVibrator = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);
}
@Override
@@ -216,7 +218,7 @@ public class InterfaceActivity extends QtActivity {
switch (feedbackConstant) {
case "CONTEXT_CLICK":
default:
- findViewById(android.R.id.content).performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ mVibrator.vibrate(50);
break;
}
}
From 145d73aa762eb322da4451431d06c13a88abb3b2 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Thu, 17 May 2018 19:18:00 +1200
Subject: [PATCH 68/80] OverlayWebWindow JSDoc fixes
---
libraries/ui/src/QmlWebWindowClass.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libraries/ui/src/QmlWebWindowClass.h b/libraries/ui/src/QmlWebWindowClass.h
index c35a6bab87..550be0a63d 100644
--- a/libraries/ui/src/QmlWebWindowClass.h
+++ b/libraries/ui/src/QmlWebWindowClass.h
@@ -17,7 +17,7 @@
* @param {OverlayWindow.Properties} [properties=null]
*
* @hifi-interface
- * @hifi-client-en
+ * @hifi-client-entity
*
* @property {string} url - Read-only.
*/
@@ -44,14 +44,14 @@ public slots:
void setURL(const QString& url);
/**jsdoc
- * @function OverlayWebWindow.getURL
+ * @function OverlayWebWindow.setScriptURL
* @param {string} script
*/
void setScriptURL(const QString& script);
signals:
/**jsdoc
- * @function OverlayWebWindow.getURL
+ * @function OverlayWebWindow.urlChanged
* @returns {Signal}
*/
void urlChanged();
From d20cd6ad44c15f185f3c427d6e3e82fafa207e7d Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Thu, 17 May 2018 20:25:25 +1200
Subject: [PATCH 69/80] Add missing JSDoc of parameter in
takeSecondaryCamera360Snapshot()
---
interface/src/scripting/WindowScriptingInterface.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h
index 27e00442bc..0209e49225 100644
--- a/interface/src/scripting/WindowScriptingInterface.h
+++ b/interface/src/scripting/WindowScriptingInterface.h
@@ -374,6 +374,8 @@ public slots:
* Takes a 360 snapshot given a position of the secondary camera (which does not need to have been previously set up).
* @function Window.takeSecondaryCameraSnapshot
* @param {vec3} [cameraPosition] - The (x, y, z) position of the camera for the 360 snapshot
+ * @param {boolean} [cubemapOutputFormat=false] - If true then the snapshot is saved as a cube map image,
+ * otherwise is saved as an equirectangular image.
* @param {string} [filename=""] - If this parameter is not given, the image will be saved as 'hifi-snap-by--YYYY-MM-DD_HH-MM-SS'.
* If this parameter is "" then the image will be saved as ".jpg".
* Otherwise, the image will be saved to this filename, with an appended ".jpg".
From 8741c5e6a48d1554e3db7093898407e6ad0a2962 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Thu, 17 May 2018 11:37:13 -0300
Subject: [PATCH 70/80] Make haptic pulse duration configurable in
VirtualPadDevice
---
android/app/src/main/cpp/native.cpp | 6 +++---
.../io/highfidelity/hifiinterface/InterfaceActivity.java | 9 +++------
interface/src/AndroidHelper.cpp | 4 ++--
interface/src/AndroidHelper.h | 4 ++--
interface/src/Application.cpp | 4 ++--
.../src/input-plugins/TouchscreenVirtualPadDevice.cpp | 2 +-
libraries/ui/src/VirtualPadManager.cpp | 4 ++--
libraries/ui/src/VirtualPadManager.h | 4 ++--
scripts/system/+android/modes.js | 2 +-
9 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/android/app/src/main/cpp/native.cpp b/android/app/src/main/cpp/native.cpp
index ca0312db0e..5822eb77a4 100644
--- a/android/app/src/main/cpp/native.cpp
+++ b/android/app/src/main/cpp/native.cpp
@@ -158,9 +158,9 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeOnCrea
__interfaceActivity.callMethod("openAndroidActivity", "(Ljava/lang/String;Z)V", string.object(), jBackToScene);
});
- QObject::connect(&AndroidHelper::instance(), &AndroidHelper::hapticFeedbackRequested, [](const QString &c) {
- QAndroidJniObject string = QAndroidJniObject::fromString(c);
- __interfaceActivity.callMethod("performHapticFeedback", "(Ljava/lang/String;)V", string.object());
+ QObject::connect(&AndroidHelper::instance(), &AndroidHelper::hapticFeedbackRequested, [](int duration) {
+ jint iDuration = (jint) duration;
+ __interfaceActivity.callMethod("performHapticFeedback", "(I)V", iDuration);
});
}
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
index 4d1e13becf..acd6a60eb7 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
@@ -214,12 +214,9 @@ public class InterfaceActivity extends QtActivity {
super.isLoading = false;
}
- public void performHapticFeedback(String feedbackConstant) {
- switch (feedbackConstant) {
- case "CONTEXT_CLICK":
- default:
- mVibrator.vibrate(50);
- break;
+ public void performHapticFeedback(int duration) {
+ if (duration > 0) {
+ mVibrator.vibrate(duration);
}
}
diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp
index 9d31ff49fa..246fb06941 100644
--- a/interface/src/AndroidHelper.cpp
+++ b/interface/src/AndroidHelper.cpp
@@ -45,8 +45,8 @@ void AndroidHelper::notifyLoadComplete() {
emit qtAppLoadComplete();
}
-void AndroidHelper::performHapticFeedback(const QString& feedbackConstant) {
- emit hapticFeedbackRequested(feedbackConstant);
+void AndroidHelper::notifyEnterForeground() {
+ emit enterForeground();
}
void AndroidHelper::showLoginDialog() {
diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h
index 2a281f605b..13ce981fd8 100644
--- a/interface/src/AndroidHelper.h
+++ b/interface/src/AndroidHelper.h
@@ -27,7 +27,7 @@ public:
void requestActivity(const QString &activityName, const bool backToScene);
void notifyLoadComplete();
- void performHapticFeedback(const QString& feedbackConstant);
+ void performHapticFeedback(int duration);
QSharedPointer getAccountManager() { return _accountManager; }
AndroidHelper(AndroidHelper const&) = delete;
@@ -40,7 +40,7 @@ signals:
void androidActivityRequested(const QString &activityName, const bool backToScene);
void qtAppLoadComplete();
- void hapticFeedbackRequested(const QString &feedbackConstant);
+ void hapticFeedbackRequested(int duration);
private:
AndroidHelper();
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 3bc0d14c94..6086b9bfd8 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -2867,8 +2867,8 @@ void Application::initializeUi() {
#if defined(Q_OS_ANDROID)
auto& virtualPadManager = VirtualPad::Manager::instance();
connect(&virtualPadManager, &VirtualPad::Manager::hapticFeedbackRequested,
- this, []() {
- AndroidHelper::instance().performHapticFeedback("CONTEXT_CLICK");
+ this, [](int duration) {
+ AndroidHelper::instance().performHapticFeedback(duration);
});
#endif
}
diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp
index a8e509b7ce..ba802ced15 100644
--- a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp
+++ b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp
@@ -189,7 +189,7 @@ void TouchscreenVirtualPadDevice::InputDevice::update(float deltaTime, const con
bool TouchscreenVirtualPadDevice::InputDevice::triggerHapticPulse(float strength, float duration, controller::Hand hand) {
auto& virtualPadManager = VirtualPad::Manager::instance();
- virtualPadManager.requestHapticFeedback();
+ virtualPadManager.requestHapticFeedback((int) duration);
return true;
}
diff --git a/libraries/ui/src/VirtualPadManager.cpp b/libraries/ui/src/VirtualPadManager.cpp
index e62a439ab8..ef2b8670cc 100644
--- a/libraries/ui/src/VirtualPadManager.cpp
+++ b/libraries/ui/src/VirtualPadManager.cpp
@@ -84,8 +84,8 @@ namespace VirtualPad {
_jumpButtonPosition = point;
}
- void Manager::requestHapticFeedback() {
- emit hapticFeedbackRequested();
+ void Manager::requestHapticFeedback(int duration) {
+ emit hapticFeedbackRequested(duration);
}
Instance* Manager::getLeftVirtualPad() {
diff --git a/libraries/ui/src/VirtualPadManager.h b/libraries/ui/src/VirtualPadManager.h
index 6391d731f8..3c3aa9ec9f 100644
--- a/libraries/ui/src/VirtualPadManager.h
+++ b/libraries/ui/src/VirtualPadManager.h
@@ -46,7 +46,7 @@ namespace VirtualPad {
void setExtraBottomMargin(int margin);
glm::vec2 getJumpButtonPosition();
void setJumpButtonPosition(glm::vec2 point);
- void requestHapticFeedback();
+ void requestHapticFeedback(int duration);
static const float DPI;
static const float BASE_DIAMETER_PIXELS;
@@ -58,7 +58,7 @@ namespace VirtualPad {
static const float JUMP_BTN_RIGHT_MARGIN_PIXELS;
signals:
- void hapticFeedbackRequested();
+ void hapticFeedbackRequested(int duration);
private:
Instance _leftVPadInstance;
diff --git a/scripts/system/+android/modes.js b/scripts/system/+android/modes.js
index 9e952e3cb6..f0dfb64677 100644
--- a/scripts/system/+android/modes.js
+++ b/scripts/system/+android/modes.js
@@ -69,7 +69,7 @@ function shutdown() {
}
function modeButtonPressed() {
- Controller.triggerHapticPulse(Controller.findDevice("TouchscreenVirtualPad"), 0.1, 1.0, 0);
+ Controller.triggerHapticPulseOnDevice(Controller.findDevice("TouchscreenVirtualPad"), 0.1, 40.0, 0);
}
function modeButtonClicked() {
From 96da032b161a69e9665a722bad01649a3d38ae17 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Thu, 17 May 2018 11:49:44 -0300
Subject: [PATCH 71/80] Add missing js to haptic feedback change
---
scripts/system/+android/actionbar.js | 2 +-
scripts/system/+android/audio.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/system/+android/actionbar.js b/scripts/system/+android/actionbar.js
index 8c476933ef..e7e2459e69 100644
--- a/scripts/system/+android/actionbar.js
+++ b/scripts/system/+android/actionbar.js
@@ -39,7 +39,7 @@ function init() {
}
function onBackPressed() {
- Controller.triggerHapticPulse(Controller.findDevice("TouchscreenVirtualPad"), 0.1, 1.0, 0);
+ Controller.triggerHapticPulseOnDevice(Controller.findDevice("TouchscreenVirtualPad"), 0.1, 40.0, 0);
}
function onBackClicked() {
diff --git a/scripts/system/+android/audio.js b/scripts/system/+android/audio.js
index 6e0f0f7b03..34dd52604a 100644
--- a/scripts/system/+android/audio.js
+++ b/scripts/system/+android/audio.js
@@ -49,7 +49,7 @@ function onMuteClicked() {
}
function onMutePressed() {
- Controller.triggerHapticPulse(Controller.findDevice("TouchscreenVirtualPad"), 0.1, 1.0, 0);
+ Controller.triggerHapticPulseOnDevice(Controller.findDevice("TouchscreenVirtualPad"), 0.1, 40.0, 0);
}
function onMuteToggled() {
From 5a73da6fdfa35efcecd86679b0d1e960aa8ceee5 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Thu, 17 May 2018 14:05:49 -0300
Subject: [PATCH 72/80] Bugfix: stop audio when app starts
---
android/app/src/main/cpp/native.cpp | 10 ++++++++
.../hifiinterface/InterfaceActivity.java | 8 ++++++-
interface/src/AndroidHelper.cpp | 8 +++++++
interface/src/AndroidHelper.h | 4 ++++
interface/src/Application.cpp | 3 ++-
interface/src/Application_jni.cpp | 24 -------------------
6 files changed, 31 insertions(+), 26 deletions(-)
delete mode 100644 interface/src/Application_jni.cpp
diff --git a/android/app/src/main/cpp/native.cpp b/android/app/src/main/cpp/native.cpp
index 5822eb77a4..3179534b34 100644
--- a/android/app/src/main/cpp/native.cpp
+++ b/android/app/src/main/cpp/native.cpp
@@ -278,4 +278,14 @@ Java_io_highfidelity_hifiinterface_MainActivity_nativeGetDisplayName(JNIEnv *env
return env->NewStringUTF(username.toLatin1().data());
}
+JNIEXPORT void JNICALL
+Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeEnterBackground(JNIEnv *env, jobject obj) {
+ AndroidHelper::instance().notifyEnterBackground();
+}
+
+JNIEXPORT void JNICALL
+Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeEnterForeground(JNIEnv *env, jobject obj) {
+ AndroidHelper::instance().notifyEnterForeground();
+}
+
}
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
index acd6a60eb7..00b50ccee0 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
@@ -15,6 +15,7 @@ import android.content.Intent;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.os.Vibrator;
import android.view.HapticFeedbackConstants;
import android.view.WindowManager;
@@ -113,7 +114,9 @@ public class InterfaceActivity extends QtActivity {
@Override
protected void onPause() {
super.onPause();
- nativeEnterBackground();
+ if (!isLoading) {
+ nativeEnterBackground();
+ }
//gvrApi.pauseTracking();
}
@@ -212,6 +215,9 @@ public class InterfaceActivity extends QtActivity {
public void onAppLoadedComplete() {
super.isLoading = false;
+ new Handler(getMainLooper()).postDelayed(() -> {
+ nativeEnterBackground();
+ }, 2000);
}
public void performHapticFeedback(int duration) {
diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp
index 246fb06941..ef7319e63f 100644
--- a/interface/src/AndroidHelper.cpp
+++ b/interface/src/AndroidHelper.cpp
@@ -49,6 +49,14 @@ void AndroidHelper::notifyEnterForeground() {
emit enterForeground();
}
+void AndroidHelper::notifyEnterBackground() {
+ emit enterBackground();
+}
+
+void AndroidHelper::performHapticFeedback(int duration) {
+ emit hapticFeedbackRequested(duration);
+}
+
void AndroidHelper::showLoginDialog() {
emit androidActivityRequested("Login", true);
}
diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h
index 13ce981fd8..007c0db4a5 100644
--- a/interface/src/AndroidHelper.h
+++ b/interface/src/AndroidHelper.h
@@ -26,6 +26,8 @@ public:
void init();
void requestActivity(const QString &activityName, const bool backToScene);
void notifyLoadComplete();
+ void notifyEnterForeground();
+ void notifyEnterBackground();
void performHapticFeedback(int duration);
@@ -39,6 +41,8 @@ public slots:
signals:
void androidActivityRequested(const QString &activityName, const bool backToScene);
void qtAppLoadComplete();
+ void enterForeground();
+ void enterBackground();
void hapticFeedbackRequested(int duration);
diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp
index 6086b9bfd8..9679fc1e8b 100644
--- a/interface/src/Application.cpp
+++ b/interface/src/Application.cpp
@@ -2265,6 +2265,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
#if defined(Q_OS_ANDROID)
AndroidHelper::instance().init();
+ connect(&AndroidHelper::instance(), &AndroidHelper::enterBackground, this, &Application::enterBackground);
+ connect(&AndroidHelper::instance(), &AndroidHelper::enterForeground, this, &Application::enterForeground);
AndroidHelper::instance().notifyLoadComplete();
#endif
}
@@ -8290,5 +8292,4 @@ void Application::enterForeground() {
}
#endif
-#include "Application_jni.cpp"
#include "Application.moc"
diff --git a/interface/src/Application_jni.cpp b/interface/src/Application_jni.cpp
deleted file mode 100644
index 5e9f1ac29e..0000000000
--- a/interface/src/Application_jni.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#if defined(Q_OS_ANDROID)
-
-#include
-#include "AndroidHelper.h"
-
-extern "C" {
-
-JNIEXPORT void
-Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeEnterBackground(JNIEnv *env, jobject obj) {
- if (qApp) {
- qApp->enterBackground();
- }
-}
-
-JNIEXPORT void
-Java_io_highfidelity_hifiinterface_InterfaceActivity_nativeEnterForeground(JNIEnv *env, jobject obj) {
- if (qApp) {
- qApp->enterForeground();
- }
-}
-
-
-}
-#endif
\ No newline at end of file
From e10b71650766d0e423b0f0ebcfbaa88a6fa9f5e1 Mon Sep 17 00:00:00 2001
From: Gabriel Calero
Date: Thu, 17 May 2018 14:26:36 -0300
Subject: [PATCH 73/80] Revert audio fix
---
.../io/highfidelity/hifiinterface/InterfaceActivity.java | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
index 00b50ccee0..2165339918 100644
--- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
+++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java
@@ -114,9 +114,7 @@ public class InterfaceActivity extends QtActivity {
@Override
protected void onPause() {
super.onPause();
- if (!isLoading) {
- nativeEnterBackground();
- }
+ nativeEnterBackground();
//gvrApi.pauseTracking();
}
@@ -215,9 +213,6 @@ public class InterfaceActivity extends QtActivity {
public void onAppLoadedComplete() {
super.isLoading = false;
- new Handler(getMainLooper()).postDelayed(() -> {
- nativeEnterBackground();
- }, 2000);
}
public void performHapticFeedback(int duration) {
From 2669a39e0fe74e8c5806528d4febc70dc027eef0 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Fri, 18 May 2018 07:32:25 +1200
Subject: [PATCH 74/80] Deprecate Agent API items that shouldn't be exposed in
the API
---
assignment-client/src/Agent.h | 1 +
libraries/networking/src/ThreadedAssignment.h | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h
index 00ef034ad5..0fc3fbe1f9 100644
--- a/assignment-client/src/Agent.h
+++ b/assignment-client/src/Agent.h
@@ -75,6 +75,7 @@ public:
public slots:
/**jsdoc
* @function Agent.run
+ * @deprecated This function is being removed from the API.
*/
void run() override;
diff --git a/libraries/networking/src/ThreadedAssignment.h b/libraries/networking/src/ThreadedAssignment.h
index d19617357b..9372cfa667 100644
--- a/libraries/networking/src/ThreadedAssignment.h
+++ b/libraries/networking/src/ThreadedAssignment.h
@@ -35,16 +35,19 @@ public slots:
/**jsdoc
* @function Agent.stop
+ * @deprecated This function is being removed from the API.
*/
Q_INVOKABLE virtual void stop() { setFinished(true); }
/**jsdoc
* @function Agent.sendStatsPacket
+ * @deprecated This function is being removed from the API.
*/
virtual void sendStatsPacket();
/**jsdoc
* @function Agent.clearQueuedCheckIns
+ * @deprecated This function is being removed from the API.
*/
void clearQueuedCheckIns() { _numQueuedCheckIns = 0; }
@@ -52,6 +55,7 @@ signals:
/**jsdoc
* @function Agent.finished
* @returns {Signal}
+ * @deprecated This function is being removed from the API.
*/
void finished();
@@ -66,6 +70,7 @@ protected:
protected slots:
/**jsdoc
* @function Agent.domainSettingsRequestFailed
+ * @deprecated This function is being removed from the API.
*/
void domainSettingsRequestFailed();
From 33ba559bb471fc3fdcf447009f260475525c1019 Mon Sep 17 00:00:00 2001
From: David Rowe
Date: Fri, 18 May 2018 08:02:02 +1200
Subject: [PATCH 75/80] Show all OverlayWebWindows properties and functions
together
---
libraries/ui/src/QmlWebWindowClass.h | 32 +++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/libraries/ui/src/QmlWebWindowClass.h b/libraries/ui/src/QmlWebWindowClass.h
index 550be0a63d..8cf77e4286 100644
--- a/libraries/ui/src/QmlWebWindowClass.h
+++ b/libraries/ui/src/QmlWebWindowClass.h
@@ -13,13 +13,43 @@
/**jsdoc
* @class OverlayWebWindow
- * @augments OverlayWindow
* @param {OverlayWindow.Properties} [properties=null]
*
* @hifi-interface
* @hifi-client-entity
*
* @property {string} url - Read-only.
+ * @property {Vec2} position
+ * @property {Vec2} size
+ * @property {boolean} visible
+ *
+ * @borrows OverlayWindow.initQml as initQml
+ * @borrows OverlayWindow.isVisible as isVisible
+ * @borrows OverlayWindow.setVisible as setVisible
+ * @borrows OverlayWindow.getPosition as getPosition
+ * @borrows OverlayWindow.setPosition as setPosition
+ * @borrows OverlayWindow.getSize as getSize
+ * @borrows OverlayWindow.setSize as setSize
+ * @borrows OverlayWindow.setTitle as setTitle
+ * @borrows OverlayWindow.raise as raise
+ * @borrows OverlayWindow.close as close
+ * @borrows OverlayWindow.getEventBridge as getEventBridge
+ * @borrows OverlayWindow.sendToQml as sendToQml
+ * @borrows OverlayWindow.clearDebugWindow as clearDebugWindow
+ * @borrows OverlayWindow.emitScriptEvent as emitScriptEvent
+ * @borrows OverlayWindow.emitWebEvent as emitWebEvent
+ * @borrows OverlayWindow.visibleChanged as visibleChanged
+ * @borrows OverlayWindow.positionChanged as positionChanged
+ * @borrows OverlayWindow.sizeChanged as sizeChanged
+ * @borrows OverlayWindow.moved as moved
+ * @borrows OverlayWindow.resized as resized
+ * @borrows OverlayWindow.closed as closed
+ * @borrows OverlayWindow.fromQml as fromQml
+ * @borrows OverlayWindow.scriptEventReceived as scriptEventReceived
+ * @borrows OverlayWindow.webEventReceived as webEventReceived
+ * @borrows OverlayWindow.hasMoved as hasMoved
+ * @borrows OverlayWindow.hasClosed as hasClosed
+ * @borrows OverlayWindow.qmlToScript as qmlToScript
*/
// FIXME refactor this class to be a QQuickItem derived type and eliminate the needless wrapping
From a0462451be0c61a33731c5239ef82e4e741595eb Mon Sep 17 00:00:00 2001
From: NissimHadar
Date: Fri, 18 May 2018 09:09:29 -0700
Subject: [PATCH 76/80] Updated auto-tester
---
tools/auto-tester/src/Test.cpp | 123 +++++++++++++++++++++------------
tools/auto-tester/src/Test.h | 10 ++-
2 files changed, 87 insertions(+), 46 deletions(-)
diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp
index 078a66aa6a..253f30a3b1 100644
--- a/tools/auto-tester/src/Test.cpp
+++ b/tools/auto-tester/src/Test.cpp
@@ -63,7 +63,7 @@ bool Test::compareImageLists(bool isInteractiveMode, QProgressBar* progressBar)
// Loop over both lists and compare each pair of images
// Quit loop if user has aborted due to a failed test.
- const double THRESHOLD { 0.999 };
+ const double THRESHOLD { 0.99 };
bool success{ true };
bool keepOn{ true };
for (int i = 0; keepOn && i < expectedImagesFullFilenames.length(); ++i) {
@@ -177,9 +177,12 @@ void Test::appendTestResultsToFile(const QString& testResultsFolderPath, TestFai
void Test::startTestsEvaluation(const QString& testFolder) {
// Get list of JPEG images in folder, sorted by name
QString previousSelection = snapshotDirectory;
-
- snapshotDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images",
- previousSelection, QFileDialog::ShowDirsOnly);
+ QString parent = previousSelection.left(previousSelection.lastIndexOf('/'));
+ if (!parent.isNull() && parent.right(1) != "/") {
+ parent += "/";
+ }
+ snapshotDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", parent,
+ QFileDialog::ShowDirsOnly);
// If user cancelled then restore previous selection and return
if (snapshotDirectory == "") {
@@ -195,12 +198,12 @@ void Test::startTestsEvaluation(const QString& testFolder) {
// Before any processing - all images are converted to PNGs, as this is the format stored on GitHub
QStringList sortedSnapshotFilenames = createListOfAll_imagesInDirectory("jpg", snapshotDirectory);
foreach(QString filename, sortedSnapshotFilenames) {
- QStringList stringParts = filename.split(".");
- copyJPGtoPNG(snapshotDirectory + "/" + stringParts[0] + ".jpg",
- snapshotDirectory + "/" + stringParts[0] + ".png"
+ QString filenameWithoutExtension = filename.left(filename.length() - 4);
+ copyJPGtoPNG(snapshotDirectory + "/" + filenameWithoutExtension + ".jpg",
+ snapshotDirectory + "/" + filenameWithoutExtension + ".png"
);
- QFile::remove(snapshotDirectory + "/" + stringParts[0] + ".jpg");
+ QFile::remove(snapshotDirectory + "/" + filenameWithoutExtension + ".jpg");
}
// Create two lists. The first is the test results, the second is the expected images
@@ -226,13 +229,13 @@ void Test::startTestsEvaluation(const QString& testFolder) {
QString expectedImageFilenameTail = currentFilename.left(currentFilename.length() - 4).right(NUM_DIGITS);
QString expectedImageStoredFilename = EXPECTED_IMAGE_PREFIX + expectedImageFilenameTail + ".png";
- QString imageURLString("https://raw.githubusercontent.com/" + githubUser + "/hifi_tests/" + gitHubBranch + "/" +
+ QString imageURLString("https://raw.githubusercontent.com/" + GIT_HUB_USER + "/hifi_tests/" + GIT_HUB_BRANCH + "/" +
expectedImagePartialSourceDirectory + "/" + expectedImageStoredFilename);
expectedImagesURLs << imageURLString;
// The image retrieved from GitHub needs a unique name
- QString expectedImageFilename = currentFilename.replace("/", "_").replace(".", "_EI.");
+ QString expectedImageFilename = currentFilename.replace("/", "_").replace(".png", "_EI.png");
expectedImagesFilenames << expectedImageFilename;
expectedImagesFullFilenames << snapshotDirectory + "/" + expectedImageFilename;
@@ -294,8 +297,10 @@ QString Test::extractPathFromTestsDown(const QString& fullPath) {
void Test::importTest(QTextStream& textStream, const QString& testPathname) {
QString partialPath = extractPathFromTestsDown(testPathname);
- textStream << "Script.include(\"" << "https://github.com/" << githubUser
- << "/hifi_tests/blob/" << gitHubBranch << partialPath + "?raw=true\");" << endl;
+ textStream << "Script.include(\""
+ << "https://github.com/" << GIT_HUB_USER << "/hifi_tests/blob/" << GIT_HUB_BRANCH
+ << partialPath + "?raw=true\");"
+ << endl;
}
// Creates a single script in a user-selected folder.
@@ -303,10 +308,14 @@ void Test::importTest(QTextStream& textStream, const QString& testPathname) {
void Test::createRecursiveScript() {
// Select folder to start recursing from
QString previousSelection = testDirectory;
+ QString parent = previousSelection.left(previousSelection.lastIndexOf('/'));
+ if (!parent.isNull() && parent.right(1) != "/") {
+ parent += "/";
+ }
testDirectory =
- QFileDialog::getExistingDirectory(nullptr, "Please select folder that will contain the top level test script",
- previousSelection, QFileDialog::ShowDirsOnly);
+ QFileDialog::getExistingDirectory(nullptr, "Please select folder that will contain the top level test script", parent,
+ QFileDialog::ShowDirsOnly);
// If user cancelled then restore previous selection and return
if (testDirectory == "") {
@@ -321,10 +330,13 @@ void Test::createRecursiveScript() {
void Test::createAllRecursiveScripts() {
// Select folder to start recursing from
QString previousSelection = testDirectory;
+ QString parent = previousSelection.left(previousSelection.lastIndexOf('/'));
+ if (!parent.isNull() && parent.right(1) != "/") {
+ parent += "/";
+ }
testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the root folder for the recursive scripts",
- previousSelection,
- QFileDialog::ShowDirsOnly);
+ parent, QFileDialog::ShowDirsOnly);
// If user cancelled then restore previous selection and return
if (testDirectory == "") {
@@ -383,8 +395,8 @@ void Test::createRecursiveScript(const QString& topLevelDirectory, bool interact
const QString DATE_TIME_FORMAT("MMM d yyyy, h:mm");
textStream << "// This is an automatically generated file, created by auto-tester on " << QDateTime::currentDateTime().toString(DATE_TIME_FORMAT) << endl << endl;
- textStream << "var autoTester = Script.require(\"https://github.com/" + githubUser + "/hifi_tests/blob/"
- + gitHubBranch + "/tests/utils/autoTester.js?raw=true\");" << endl << endl;
+ textStream << "var autoTester = Script.require(\"https://github.com/" + GIT_HUB_USER + "/hifi_tests/blob/"
+ + GIT_HUB_BRANCH + "/tests/utils/autoTester.js?raw=true\");" << endl << endl;
textStream << "autoTester.enableRecursive();" << endl;
textStream << "autoTester.enableAuto();" << endl << endl;
@@ -441,9 +453,12 @@ void Test::createTest() {
// Rename files sequentially, as ExpectedResult_00000.jpeg, ExpectedResult_00001.jpg and so on
// Any existing expected result images will be deleted
QString previousSelection = snapshotDirectory;
+ QString parent = previousSelection.left(previousSelection.lastIndexOf('/'));
+ if (!parent.isNull() && parent.right(1) != "/") {
+ parent += "/";
+ }
- snapshotDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images",
- previousSelection,
+ snapshotDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", parent,
QFileDialog::ShowDirsOnly);
// If user cancelled then restore previous selection and return
@@ -453,9 +468,13 @@ void Test::createTest() {
}
previousSelection = testDirectory;
+ parent = previousSelection.left(previousSelection.lastIndexOf('/'));
+ if (!parent.isNull() && parent.right(1) != "/") {
+ parent += "/";
+ }
- QString testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder to save the test images",
- previousSelection, QFileDialog::ShowDirsOnly);
+ testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder to save the test images", parent,
+ QFileDialog::ShowDirsOnly);
// If user cancelled then restore previous selection and return
if (testDirectory == "") {
@@ -562,8 +581,12 @@ ExtractedText Test::getTestScriptLines(QString testFileName) {
void Test::createMDFile() {
// Folder selection
QString previousSelection = testDirectory;
+ QString parent = previousSelection.left(previousSelection.lastIndexOf('/'));
+ if (!parent.isNull() && parent.right(1) != "/") {
+ parent += "/";
+ }
- testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test", previousSelection,
+ testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test", parent,
QFileDialog::ShowDirsOnly);
// If user cancelled then restore previous selection and return
@@ -580,9 +603,13 @@ void Test::createMDFile() {
void Test::createAllMDFiles() {
// Select folder to start recursing from
QString previousSelection = testDirectory;
+ QString parent = previousSelection.left(previousSelection.lastIndexOf('/'));
+ if (!parent.isNull() && parent.right(1) != "/") {
+ parent += "/";
+ }
- testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the root folder for the MD files",
- previousSelection, QFileDialog::ShowDirsOnly);
+ testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the root folder for the MD files", parent,
+ QFileDialog::ShowDirsOnly);
// If user cancelled then restore previous selection and return
if (testDirectory == "") {
@@ -650,7 +677,7 @@ void Test::createMDFile(const QString& testDirectory) {
stream << "- In an empty region of a domain with editing rights." << "\n\n";
stream << "## Steps\n";
- stream << "Press space bar to advance step by step\n\n";
+ stream << "Press '" + ADVANCE_KEY + "' key to advance step by step\n\n"; // note apostrophes surrounding 'ADVANCE_KEY'
int snapShotIndex { 0 };
for (size_t i = 0; i < testScriptLines.stepList.size(); ++i) {
@@ -667,9 +694,13 @@ void Test::createMDFile(const QString& testDirectory) {
void Test::createTestsOutline() {
QString previousSelection = testDirectory;
+ QString parent = previousSelection.left(previousSelection.lastIndexOf('/'));
+ if (!parent.isNull() && parent.right(1) != "/") {
+ parent += "/";
+ }
- testDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select the tests root folder", previousSelection,
- QFileDialog::ShowDirsOnly);
+ testDirectory =
+ QFileDialog::getExistingDirectory(nullptr, "Please select the tests root folder", parent, QFileDialog::ShowDirsOnly);
// If user cancelled then restore previous selection and return
if (testDirectory == "") {
@@ -725,13 +756,20 @@ void Test::createTestsOutline() {
QString url = "./" + partialPath;
stream << prefix << "[" << directoryName << "](" << url << "?raw=true" << ")";
+
+ // note that md files may be named 'test.md' or 'testStory.md'
QFileInfo fileInfo1(directory + "/test.md");
if (fileInfo1.exists()) {
stream << " [(test description)](" << url << "/test.md)";
}
- QFileInfo fileInfo2(directory + "/" + TEST_FILENAME);
+ QFileInfo fileInfo2(directory + "/testStory.md");
if (fileInfo2.exists()) {
+ stream << " [(test description)](" << url << "/testStory.md)";
+ }
+
+ QFileInfo fileInfo3(directory + "/" + TEST_FILENAME);
+ if (fileInfo3.exists()) {
stream << " (*)";
}
stream << "\n";
@@ -764,30 +802,27 @@ QStringList Test::createListOfAll_imagesInDirectory(const QString& imageFormat,
}
// Snapshots are files in the following format:
-// Filename contains no periods (excluding period before exception
-// Filename (i.e. without extension) contains _tests_ (this is based on all test scripts being within the tests folder
-// Last 5 characters in filename are digits
-// Extension is jpg
+// Filename (i.e. without extension) contains tests (this is based on all test scripts being within the tests folder)
+// Last 5 characters in filename are digits (after removing the extension)
+// Extension is 'imageFormat'
bool Test::isInSnapshotFilenameFormat(const QString& imageFormat, const QString& filename) {
- QStringList filenameParts = filename.split(".");
-
- bool filnameHasNoPeriods = (filenameParts.size() == 2);
- bool contains_tests = filenameParts[0].contains("_tests_");
+ bool contains_tests = filename.contains("tests" + PATH_SEPARATOR);
+ QString filenameWithoutExtension = filename.left(filename.lastIndexOf('.'));
bool last5CharactersAreDigits;
- filenameParts[0].right(5).toInt(&last5CharactersAreDigits, 10);
+ filenameWithoutExtension.right(5).toInt(&last5CharactersAreDigits, 10);
- bool extensionIsIMAGE_FORMAT = (filenameParts[1] == imageFormat);
+ bool extensionIsIMAGE_FORMAT = (filename.right(imageFormat.length()) == imageFormat);
- return (filnameHasNoPeriods && contains_tests && last5CharactersAreDigits && extensionIsIMAGE_FORMAT);
+ return (contains_tests && last5CharactersAreDigits && extensionIsIMAGE_FORMAT);
}
// For a file named "D_GitHub_hifi-tests_tests_content_entity_zone_create_0.jpg", the test directory is
// D:/GitHub/hifi-tests/tests/content/entity/zone/create
// This method assumes the filename is in the correct format
QString Test::getExpectedImageDestinationDirectory(const QString& filename) {
- QString filenameWithoutExtension = filename.split(".")[0];
- QStringList filenameParts = filenameWithoutExtension.split("_");
+ QString filenameWithoutExtension = filename.left(filename.length() - 4);
+ QStringList filenameParts = filenameWithoutExtension.split(PATH_SEPARATOR);
QString result = filenameParts[0] + ":";
@@ -803,8 +838,8 @@ QString Test::getExpectedImageDestinationDirectory(const QString& filename) {
// This is used to create the full URL
// This method assumes the filename is in the correct format
QString Test::getExpectedImagePartialSourceDirectory(const QString& filename) {
- QString filenameWithoutExtension = filename.split(".")[0];
- QStringList filenameParts = filenameWithoutExtension.split("_");
+ QString filenameWithoutExtension = filename.left(filename.length() - 4);
+ QStringList filenameParts = filenameWithoutExtension.split(PATH_SEPARATOR);
// Note that the bottom-most "tests" folder is assumed to be the root
// This is required because the tests folder is named hifi_tests
diff --git a/tools/auto-tester/src/Test.h b/tools/auto-tester/src/Test.h
index 0fb957d309..2fedc66959 100644
--- a/tools/auto-tester/src/Test.h
+++ b/tools/auto-tester/src/Test.h
@@ -100,11 +100,17 @@ private:
QStringList resultImagesFullFilenames;
// Used for accessing GitHub
- const QString githubUser{ "highfidelity" };
- const QString gitHubBranch { "master" };
+ const QString GIT_HUB_USER{ "highfidelity" };
+ const QString GIT_HUB_BRANCH { "master" };
const QString DATETIME_FORMAT { "yyyy-MM-dd_hh-mm-ss" };
ExtractedText getTestScriptLines(QString testFileName);
+
+ // NOTE: these need to match the appropriate var's in autoTester.js
+ // var advanceKey = "n";
+ // var pathSeparator = ".";
+ const QString ADVANCE_KEY{ "n" };
+ const QString PATH_SEPARATOR{ "." };
};
#endif // hifi_test_h
\ No newline at end of file
From fb81cf927a29547628f4aa97c4df10d64310b262 Mon Sep 17 00:00:00 2001
From: Brad Davis
Date: Thu, 10 May 2018 12:08:20 -0700
Subject: [PATCH 77/80] Faster texture transfers
---
.../gpu-gl-common/src/gpu/gl/GLBackend.cpp | 50 +-
.../gpu-gl-common/src/gpu/gl/GLBackend.h | 4 +-
libraries/gpu-gl-common/src/gpu/gl/GLShared.h | 2 +
.../gpu-gl-common/src/gpu/gl/GLTexture.cpp | 565 ++----------------
.../gpu-gl-common/src/gpu/gl/GLTexture.h | 180 +++---
.../src/gpu/gl/GLTextureTransfer.cpp | 502 ++++++++++++++++
libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 6 +-
.../src/gpu/gl41/GL41BackendTexture.cpp | 24 +-
libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 6 +-
.../src/gpu/gl45/GL45BackendTexture.cpp | 8 +-
.../gpu/gl45/GL45BackendVariableTexture.cpp | 24 +-
libraries/gpu-gles/src/gpu/gles/GLESBackend.h | 6 +-
.../src/gpu/gles/GLESBackendTexture.cpp | 21 +-
tests/gpu/src/TextureTest.cpp | 279 +++++----
tests/gpu/src/TextureTest.h | 5 +-
15 files changed, 866 insertions(+), 816 deletions(-)
create mode 100644 libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp
diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp
index 501e59f38e..f484de57f1 100644
--- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp
+++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp
@@ -44,9 +44,9 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::gl::GLBackend::do_setModelTransform),
(&::gpu::gl::GLBackend::do_setViewTransform),
- (&::gpu::gl::GLBackend::do_setProjectionTransform),
- (&::gpu::gl::GLBackend::do_setProjectionJitter),
- (&::gpu::gl::GLBackend::do_setViewportTransform),
+ (&::gpu::gl::GLBackend::do_setProjectionTransform),
+ (&::gpu::gl::GLBackend::do_setProjectionJitter),
+ (&::gpu::gl::GLBackend::do_setViewportTransform),
(&::gpu::gl::GLBackend::do_setDepthRangeTransform),
(&::gpu::gl::GLBackend::do_setPipeline),
@@ -118,12 +118,6 @@ void GLBackend::init() {
#if !defined(USE_GLES)
qCDebug(gpugllogging, "V-Sync is %s\n", (::gl::getSwapInterval() > 0 ? "ON" : "OFF"));
#endif
-#if THREADED_TEXTURE_BUFFERING
- // This has to happen on the main thread in order to give the thread
- // pool a reasonable parent object
- GLVariableAllocationSupport::TransferJob::startBufferingThread();
-#endif
-
});
}
@@ -136,6 +130,7 @@ GLBackend::GLBackend() {
GLBackend::~GLBackend() {
killInput();
killTransform();
+ killTextureManagementStage();
}
void GLBackend::renderPassTransfer(const Batch& batch) {
@@ -167,18 +162,18 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
case Batch::COMMAND_drawIndexedInstanced:
case Batch::COMMAND_multiDrawIndirect:
case Batch::COMMAND_multiDrawIndexedIndirect:
- {
- Vec2u outputSize{ 1,1 };
+ {
+ Vec2u outputSize{ 1,1 };
- if (_output._framebuffer) {
- outputSize.x = _output._framebuffer->getWidth();
- outputSize.y = _output._framebuffer->getHeight();
- } else if (glm::dot(_transform._projectionJitter, _transform._projectionJitter)>0.0f) {
- qCWarning(gpugllogging) << "Jittering needs to have a frame buffer to be set";
- }
+ if (_output._framebuffer) {
+ outputSize.x = _output._framebuffer->getWidth();
+ outputSize.y = _output._framebuffer->getHeight();
+ } else if (glm::dot(_transform._projectionJitter, _transform._projectionJitter)>0.0f) {
+ qCWarning(gpugllogging) << "Jittering needs to have a frame buffer to be set";
+ }
- _transform.preUpdate(_commandIndex, _stereo, outputSize);
- }
+ _transform.preUpdate(_commandIndex, _stereo, outputSize);
+ }
break;
case Batch::COMMAND_disableContextStereo:
@@ -191,10 +186,10 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
case Batch::COMMAND_setViewportTransform:
case Batch::COMMAND_setViewTransform:
- case Batch::COMMAND_setProjectionTransform:
- case Batch::COMMAND_setProjectionJitter:
- {
- CommandCall call = _commandCalls[(*command)];
+ case Batch::COMMAND_setProjectionTransform:
+ case Batch::COMMAND_setProjectionJitter:
+ {
+ CommandCall call = _commandCalls[(*command)];
(this->*(call))(batch, *offset);
break;
}
@@ -268,8 +263,8 @@ void GLBackend::render(const Batch& batch) {
if (!batch.isStereoEnabled()) {
_stereo._enable = false;
}
- // Reset jitter
- _transform._projectionJitter = Vec2(0.0f, 0.0f);
+ // Reset jitter
+ _transform._projectionJitter = Vec2(0.0f, 0.0f);
{
PROFILE_RANGE(render_gpu_gl_detail, "Transfer");
@@ -729,9 +724,8 @@ void GLBackend::recycle() const {
glDeleteQueries((GLsizei)ids.size(), ids.data());
}
}
-
- GLVariableAllocationSupport::manageMemory();
- GLVariableAllocationSupport::_frameTexturesCreated = 0;
+
+ _textureManagement._transferEngine->manageMemory();
Texture::KtxStorage::releaseOpenKtxFiles();
}
diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h
index 314bbee387..32c75d0363 100644
--- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h
+++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h
@@ -491,8 +491,10 @@ protected:
struct TextureManagementStageState {
bool _sparseCapable { false };
+ GLTextureTransferEnginePointer _transferEngine;
} _textureManagement;
- virtual void initTextureManagementStage() {}
+ virtual void initTextureManagementStage();
+ virtual void killTextureManagementStage();
typedef void (GLBackend::*CommandCall)(const Batch&, size_t);
static CommandCall _commandCalls[Batch::NUM_COMMANDS];
diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLShared.h b/libraries/gpu-gl-common/src/gpu/gl/GLShared.h
index ccdf0a5c41..f67439f96a 100644
--- a/libraries/gpu-gl-common/src/gpu/gl/GLShared.h
+++ b/libraries/gpu-gl-common/src/gpu/gl/GLShared.h
@@ -137,6 +137,8 @@ class GLQuery;
class GLState;
class GLShader;
class GLTexture;
+class GLTextureTransferEngine;
+using GLTextureTransferEnginePointer = std::shared_ptr;
struct ShaderObject;
} } // namespace gpu::gl
diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp
index 943b8148ef..394b44166f 100644
--- a/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp
+++ b/libraries/gpu-gl-common/src/gpu/gl/GLTexture.cpp
@@ -48,6 +48,14 @@ const GLFilterMode GLTexture::FILTER_MODES[Sampler::NUM_FILTERS] = {
{ GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR } //FILTER_ANISOTROPIC,
};
+static constexpr size_t MAX_PIXEL_BYTE_SIZE{ 4 };
+static constexpr size_t MAX_TRANSFER_DIMENSION{ 1024 };
+
+const uvec3 GLVariableAllocationSupport::MAX_TRANSFER_DIMENSIONS{ MAX_TRANSFER_DIMENSION, MAX_TRANSFER_DIMENSION, 1 };
+const uvec3 GLVariableAllocationSupport::INITIAL_MIP_TRANSFER_DIMENSIONS{ 64, 64, 1 };
+const size_t GLVariableAllocationSupport::MAX_TRANSFER_SIZE = MAX_TRANSFER_DIMENSION * MAX_TRANSFER_DIMENSION * MAX_PIXEL_BYTE_SIZE;
+const size_t GLVariableAllocationSupport::MAX_BUFFER_SIZE = MAX_TRANSFER_SIZE;
+
GLenum GLTexture::getGLTextureType(const Texture& texture) {
switch (texture.getType()) {
case Texture::TEX_2D:
@@ -131,7 +139,6 @@ Size GLTexture::copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, u
return 0;
}
-
GLExternalTexture::GLExternalTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id)
: Parent(backend, texture, id) {
Backend::textureExternalCount.increment();
@@ -151,65 +158,58 @@ GLExternalTexture::~GLExternalTexture() {
Backend::textureExternalCount.decrement();
}
-
-// Variable sized textures
-using MemoryPressureState = GLVariableAllocationSupport::MemoryPressureState;
-using WorkQueue = GLVariableAllocationSupport::WorkQueue;
-using TransferJobPointer = GLVariableAllocationSupport::TransferJobPointer;
-
-std::list GLVariableAllocationSupport::_memoryManagedTextures;
-MemoryPressureState GLVariableAllocationSupport::_memoryPressureState { MemoryPressureState::Idle };
-std::atomic GLVariableAllocationSupport::_memoryPressureStateStale { false };
-const uvec3 GLVariableAllocationSupport::INITIAL_MIP_TRANSFER_DIMENSIONS { 64, 64, 1 };
-WorkQueue GLVariableAllocationSupport::_transferQueue;
-WorkQueue GLVariableAllocationSupport::_promoteQueue;
-WorkQueue GLVariableAllocationSupport::_demoteQueue;
-size_t GLVariableAllocationSupport::_frameTexturesCreated { 0 };
-
-#define OVERSUBSCRIBED_PRESSURE_VALUE 0.95f
-#define UNDERSUBSCRIBED_PRESSURE_VALUE 0.85f
-#define DEFAULT_ALLOWED_TEXTURE_MEMORY_MB ((size_t)1024)
-
-static const size_t DEFAULT_ALLOWED_TEXTURE_MEMORY = MB_TO_BYTES(DEFAULT_ALLOWED_TEXTURE_MEMORY_MB);
-
-using TransferJob = GLVariableAllocationSupport::TransferJob;
-
-const uvec3 GLVariableAllocationSupport::MAX_TRANSFER_DIMENSIONS { 1024, 1024, 1 };
-const size_t GLVariableAllocationSupport::MAX_TRANSFER_SIZE = GLVariableAllocationSupport::MAX_TRANSFER_DIMENSIONS.x * GLVariableAllocationSupport::MAX_TRANSFER_DIMENSIONS.y * 4;
-
-#if THREADED_TEXTURE_BUFFERING
-
-TexturePointer GLVariableAllocationSupport::_currentTransferTexture;
-TransferJobPointer GLVariableAllocationSupport::_currentTransferJob;
-QThreadPool* TransferJob::_bufferThreadPool { nullptr };
-
-void TransferJob::startBufferingThread() {
- static std::once_flag once;
- std::call_once(once, [&] {
- _bufferThreadPool = new QThreadPool(qApp);
- _bufferThreadPool->setMaxThreadCount(1);
- });
+GLVariableAllocationSupport::GLVariableAllocationSupport() {
}
-#endif
+GLVariableAllocationSupport::~GLVariableAllocationSupport() {
+}
-TransferJob::TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t targetMip, uint8_t face, uint32_t lines, uint32_t lineOffset)
- : _parent(parent) {
+void GLVariableAllocationSupport::incrementPopulatedSize(Size delta) const {
+ _populatedSize += delta;
+ // Keep the 2 code paths to be able to debug
+ if (_size < _populatedSize) {
+ Backend::textureResourcePopulatedGPUMemSize.update(0, delta);
+ } else {
+ Backend::textureResourcePopulatedGPUMemSize.update(0, delta);
+ }
+}
- auto transferDimensions = _parent._gpuObject.evalMipDimensions(sourceMip);
+void GLVariableAllocationSupport::decrementPopulatedSize(Size delta) const {
+ _populatedSize -= delta;
+ // Keep the 2 code paths to be able to debug
+ if (_size < _populatedSize) {
+ Backend::textureResourcePopulatedGPUMemSize.update(delta, 0);
+ } else {
+ Backend::textureResourcePopulatedGPUMemSize.update(delta, 0);
+ }
+}
+
+void GLVariableAllocationSupport::sanityCheck() const {
+ if (_populatedMip < _allocatedMip) {
+ qCWarning(gpugllogging) << "Invalid mip levels";
+ }
+}
+
+TransferJob::TransferJob(const Texture& texture,
+ uint16_t sourceMip,
+ uint16_t targetMip,
+ uint8_t face,
+ uint32_t lines,
+ uint32_t lineOffset) {
+ auto transferDimensions = texture.evalMipDimensions(sourceMip);
GLenum format;
GLenum internalFormat;
GLenum type;
- GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(_parent._gpuObject.getTexelFormat(), _parent._gpuObject.getStoredMipFormat());
+ GLTexelFormat texelFormat = GLTexelFormat::evalGLTexelFormat(texture.getTexelFormat(), texture.getStoredMipFormat());
format = texelFormat.format;
internalFormat = texelFormat.internalFormat;
type = texelFormat.type;
- _transferSize = _parent._gpuObject.getStoredMipFaceSize(sourceMip, face);
+ _transferSize = texture.getStoredMipFaceSize(sourceMip, face);
// If we're copying a subsection of the mip, do additional calculations to find the size and offset of the segment
if (0 != lines) {
transferDimensions.y = lines;
- auto dimensions = _parent._gpuObject.evalMipDimensions(sourceMip);
+ auto dimensions = texture.evalMipDimensions(sourceMip);
auto bytesPerLine = (uint32_t)_transferSize / dimensions.y;
_transferOffset = bytesPerLine * lineOffset;
_transferSize = bytesPerLine * lines;
@@ -222,481 +222,34 @@ TransferJob::TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t t
}
// Buffering can invoke disk IO, so it should be off of the main and render threads
- _bufferingLambda = [=] {
- auto mipStorage = _parent._gpuObject.accessStoredMipFace(sourceMip, face);
+ _bufferingLambda = [=](const TexturePointer& texture) {
+ auto mipStorage = texture->accessStoredMipFace(sourceMip, face);
if (mipStorage) {
_mipData = mipStorage->createView(_transferSize, _transferOffset);
} else {
- qCWarning(gpugllogging) << "Buffering failed because mip could not be retrieved from texture " << _parent._source.c_str() ;
+ qCWarning(gpugllogging) << "Buffering failed because mip could not be retrieved from texture "
+ << texture->source().c_str();
}
};
- _transferLambda = [=] {
+ _transferLambda = [=](const TexturePointer& texture) {
if (_mipData) {
- _parent.copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, internalFormat, format, type, _mipData->size(), _mipData->readData());
+ auto gltexture = Backend::getGPUObject(*texture);
+ ;
+ gltexture->copyMipFaceLinesFromTexture(targetMip, face, transferDimensions, lineOffset, internalFormat, format,
+ type, _mipData->size(), _mipData->readData());
_mipData.reset();
} else {
- qCWarning(gpugllogging) << "Transfer failed because mip could not be retrieved from texture " << _parent._source.c_str();
+ qCWarning(gpugllogging) << "Transfer failed because mip could not be retrieved from texture "
+ << texture->source().c_str();
}
};
}
-TransferJob::TransferJob(const GLTexture& parent, std::function transferLambda)
- : _parent(parent), _bufferingRequired(false), _transferLambda(transferLambda) {
-}
+TransferJob::TransferJob(const std::function& transferLambda) :
+ _bufferingRequired(false), _transferLambda([=](const TexturePointer&) { transferLambda(); }) {}
TransferJob::~TransferJob() {
Backend::texturePendingGPUTransferMemSize.update(_transferSize, 0);
}
-bool TransferJob::tryTransfer() {
-#if THREADED_TEXTURE_BUFFERING
- // Are we ready to transfer
- if (!bufferingCompleted()) {
- startBuffering();
- return false;
- }
-#else
- if (_bufferingRequired) {
- _bufferingLambda();
- }
-#endif
- _transferLambda();
- return true;
-}
-
-#if THREADED_TEXTURE_BUFFERING
-bool TransferJob::bufferingRequired() const {
- if (!_bufferingRequired) {
- return false;
- }
-
- // The default state of a QFuture is with status Canceled | Started | Finished,
- // so we have to check isCancelled before we check the actual state
- if (_bufferingStatus.isCanceled()) {
- return true;
- }
-
- return !_bufferingStatus.isStarted();
-}
-
-bool TransferJob::bufferingCompleted() const {
- if (!_bufferingRequired) {
- return true;
- }
-
- // The default state of a QFuture is with status Canceled | Started | Finished,
- // so we have to check isCancelled before we check the actual state
- if (_bufferingStatus.isCanceled()) {
- return false;
- }
-
- return _bufferingStatus.isFinished();
-}
-
-void TransferJob::startBuffering() {
- if (bufferingRequired()) {
- assert(_bufferingStatus.isCanceled());
- _bufferingStatus = QtConcurrent::run(_bufferThreadPool, [=] {
- _bufferingLambda();
- });
- assert(!_bufferingStatus.isCanceled());
- assert(_bufferingStatus.isStarted());
- }
-}
-#endif
-
-GLVariableAllocationSupport::GLVariableAllocationSupport() {
- _memoryPressureStateStale = true;
-}
-
-GLVariableAllocationSupport::~GLVariableAllocationSupport() {
- _memoryPressureStateStale = true;
-}
-
-void GLVariableAllocationSupport::addMemoryManagedTexture(const TexturePointer& texturePointer) {
- _memoryManagedTextures.push_back(texturePointer);
- if (MemoryPressureState::Idle != _memoryPressureState) {
- addToWorkQueue(texturePointer);
- }
-}
-
-void GLVariableAllocationSupport::addToWorkQueue(const TexturePointer& texturePointer) {
- GLTexture* gltexture = Backend::getGPUObject(*texturePointer);
- GLVariableAllocationSupport* vargltexture = dynamic_cast(gltexture);
- switch (_memoryPressureState) {
- case MemoryPressureState::Oversubscribed:
- if (vargltexture->canDemote()) {
- // Demote largest first
- _demoteQueue.push({ texturePointer, (float)gltexture->size() });
- }
- break;
-
- case MemoryPressureState::Undersubscribed:
- if (vargltexture->canPromote()) {
- // Promote smallest first
- _promoteQueue.push({ texturePointer, 1.0f / (float)gltexture->size() });
- }
- break;
-
- case MemoryPressureState::Transfer:
- if (vargltexture->hasPendingTransfers()) {
- // Transfer priority given to smaller mips first
- _transferQueue.push({ texturePointer, 1.0f / (float)gltexture->_gpuObject.evalMipSize(vargltexture->_populatedMip) });
- }
- break;
-
- case MemoryPressureState::Idle:
- Q_UNREACHABLE();
- break;
- }
-}
-
-WorkQueue& GLVariableAllocationSupport::getActiveWorkQueue() {
- static WorkQueue empty;
- switch (_memoryPressureState) {
- case MemoryPressureState::Oversubscribed:
- return _demoteQueue;
-
- case MemoryPressureState::Undersubscribed:
- return _promoteQueue;
-
- case MemoryPressureState::Transfer:
- return _transferQueue;
-
- case MemoryPressureState::Idle:
- Q_UNREACHABLE();
- break;
- }
- return empty;
-}
-
-// FIXME hack for stats display
-QString getTextureMemoryPressureModeString() {
- switch (GLVariableAllocationSupport::_memoryPressureState) {
- case MemoryPressureState::Oversubscribed:
- return "Oversubscribed";
-
- case MemoryPressureState::Undersubscribed:
- return "Undersubscribed";
-
- case MemoryPressureState::Transfer:
- return "Transfer";
-
- case MemoryPressureState::Idle:
- return "Idle";
- }
- Q_UNREACHABLE();
- return "Unknown";
-}
-
-void GLVariableAllocationSupport::updateMemoryPressure() {
- static size_t lastAllowedMemoryAllocation = gpu::Texture::getAllowedGPUMemoryUsage();
-
- size_t allowedMemoryAllocation = gpu::Texture::getAllowedGPUMemoryUsage();
- if (0 == allowedMemoryAllocation) {
- allowedMemoryAllocation = DEFAULT_ALLOWED_TEXTURE_MEMORY;
- }
-
- // If the user explicitly changed the allowed memory usage, we need to mark ourselves stale
- // so that we react
- if (allowedMemoryAllocation != lastAllowedMemoryAllocation) {
- _memoryPressureStateStale = true;
- lastAllowedMemoryAllocation = allowedMemoryAllocation;
- }
-
- if (!_memoryPressureStateStale.exchange(false)) {
- return;
- }
-
- PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
-
- // Clear any defunct textures (weak pointers that no longer have a valid texture)
- _memoryManagedTextures.remove_if([&](const TextureWeakPointer& weakPointer) {
- return weakPointer.expired();
- });
-
- // Convert weak pointers to strong. This new list may still contain nulls if a texture was
- // deleted on another thread between the previous line and this one
- std::vector strongTextures; {
- strongTextures.reserve(_memoryManagedTextures.size());
- std::transform(
- _memoryManagedTextures.begin(), _memoryManagedTextures.end(),
- std::back_inserter(strongTextures),
- [](const TextureWeakPointer& p) { return p.lock(); });
- }
-
- size_t totalVariableMemoryAllocation = 0;
- size_t idealMemoryAllocation = 0;
- bool canDemote = false;
- bool canPromote = false;
- bool hasTransfers = false;
- for (const auto& texture : strongTextures) {
- // Race conditions can still leave nulls in the list, so we need to check
- if (!texture) {
- continue;
- }
- GLTexture* gltexture = Backend::getGPUObject(*texture);
- GLVariableAllocationSupport* vartexture = dynamic_cast(gltexture);
- // Track how much the texture thinks it should be using
- idealMemoryAllocation += texture->evalTotalSize();
- // Track how much we're actually using
- totalVariableMemoryAllocation += gltexture->size();
- canDemote |= vartexture->canDemote();
- canPromote |= vartexture->canPromote();
- hasTransfers |= vartexture->hasPendingTransfers();
- }
-
- size_t unallocated = idealMemoryAllocation - totalVariableMemoryAllocation;
- float pressure = (float)totalVariableMemoryAllocation / (float)allowedMemoryAllocation;
-
- auto newState = MemoryPressureState::Idle;
- if (pressure < UNDERSUBSCRIBED_PRESSURE_VALUE && (unallocated != 0 && canPromote)) {
- newState = MemoryPressureState::Undersubscribed;
- } else if (pressure > OVERSUBSCRIBED_PRESSURE_VALUE && canDemote) {
- newState = MemoryPressureState::Oversubscribed;
- } else if (hasTransfers) {
- newState = MemoryPressureState::Transfer;
- }
-
- if (newState != _memoryPressureState) {
- _memoryPressureState = newState;
- // Clear the existing queue
- _transferQueue = WorkQueue();
- _promoteQueue = WorkQueue();
- _demoteQueue = WorkQueue();
-
- // Populate the existing textures into the queue
- if (_memoryPressureState != MemoryPressureState::Idle) {
- for (const auto& texture : strongTextures) {
- // Race conditions can still leave nulls in the list, so we need to check
- if (!texture) {
- continue;
- }
- addToWorkQueue(texture);
- }
- }
- }
-}
-
-TexturePointer GLVariableAllocationSupport::getNextWorkQueueItem(WorkQueue& workQueue) {
- while (!workQueue.empty()) {
- auto workTarget = workQueue.top();
-
- auto texture = workTarget.first.lock();
- if (!texture) {
- workQueue.pop();
- continue;
- }
-
- // Check whether the resulting texture can actually have work performed
- GLTexture* gltexture = Backend::getGPUObject(*texture);
- GLVariableAllocationSupport* vartexture = dynamic_cast(gltexture);
- switch (_memoryPressureState) {
- case MemoryPressureState::Oversubscribed:
- if (vartexture->canDemote()) {
- return texture;
- }
- break;
-
- case MemoryPressureState::Undersubscribed:
- if (vartexture->canPromote()) {
- return texture;
- }
- break;
-
- case MemoryPressureState::Transfer:
- if (vartexture->hasPendingTransfers()) {
- return texture;
- }
- break;
-
- case MemoryPressureState::Idle:
- Q_UNREACHABLE();
- break;
- }
-
- // If we got here, then the texture has no work to do in the current state,
- // so pop it off the queue and continue
- workQueue.pop();
- }
-
- return TexturePointer();
-}
-
-void GLVariableAllocationSupport::processWorkQueue(WorkQueue& workQueue) {
- if (workQueue.empty()) {
- return;
- }
-
- // Get the front of the work queue to perform work
- auto texture = getNextWorkQueueItem(workQueue);
- if (!texture) {
- return;
- }
-
- // Grab the first item off the demote queue
- PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
-
- GLTexture* gltexture = Backend::getGPUObject(*texture);
- GLVariableAllocationSupport* vartexture = dynamic_cast(gltexture);
- switch (_memoryPressureState) {
- case MemoryPressureState::Oversubscribed:
- vartexture->demote();
- workQueue.pop();
- addToWorkQueue(texture);
- _memoryPressureStateStale = true;
- break;
-
- case MemoryPressureState::Undersubscribed:
- vartexture->promote();
- workQueue.pop();
- addToWorkQueue(texture);
- _memoryPressureStateStale = true;
- break;
-
- case MemoryPressureState::Transfer:
- if (vartexture->executeNextTransfer(texture)) {
- workQueue.pop();
- addToWorkQueue(texture);
-
-#if THREADED_TEXTURE_BUFFERING
- // Eagerly start the next buffering job if possible
- texture = getNextWorkQueueItem(workQueue);
- if (texture) {
- gltexture = Backend::getGPUObject(*texture);
- vartexture = dynamic_cast(gltexture);
- vartexture->executeNextBuffer(texture);
- }
-#endif
- }
- break;
-
- case MemoryPressureState::Idle:
- Q_UNREACHABLE();
- break;
- }
-}
-
-void GLVariableAllocationSupport::processWorkQueues() {
- if (MemoryPressureState::Idle == _memoryPressureState) {
- return;
- }
-
- auto& workQueue = getActiveWorkQueue();
- // Do work on the front of the queue
- processWorkQueue(workQueue);
-
- if (workQueue.empty()) {
- _memoryPressureState = MemoryPressureState::Idle;
- _memoryPressureStateStale = true;
- }
-}
-
-void GLVariableAllocationSupport::manageMemory() {
- PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
- updateMemoryPressure();
- processWorkQueues();
-}
-
-bool GLVariableAllocationSupport::executeNextTransfer(const TexturePointer& currentTexture) {
-#if THREADED_TEXTURE_BUFFERING
- // If a transfer job is active on the buffering thread, but has not completed it's buffering lambda,
- // then we need to exit early, since we don't want to have the transfer job leave scope while it's
- // being used in another thread -- See https://highfidelity.fogbugz.com/f/cases/4626
- if (_currentTransferJob && !_currentTransferJob->bufferingCompleted()) {
- return false;
- }
-#endif
-
- if (_populatedMip <= _allocatedMip) {
-#if THREADED_TEXTURE_BUFFERING
- _currentTransferJob.reset();
- _currentTransferTexture.reset();
-#endif
- return true;
- }
-
- // If the transfer queue is empty, rebuild it
- if (_pendingTransfers.empty()) {
- populateTransferQueue();
- }
-
- bool result = false;
- if (!_pendingTransfers.empty()) {
-#if THREADED_TEXTURE_BUFFERING
- // If there is a current transfer, but it's not the top of the pending transfer queue, then it's an orphan, so we want to abandon it.
- if (_currentTransferJob && _currentTransferJob != _pendingTransfers.front()) {
- _currentTransferJob.reset();
- }
-
- if (!_currentTransferJob) {
- // Keeping hold of a strong pointer to the transfer job ensures that if the pending transfer queue is rebuilt, the transfer job
- // doesn't leave scope, causing a crash in the buffering thread
- _currentTransferJob = _pendingTransfers.front();
-
- // Keeping hold of a strong pointer during the transfer ensures that the transfer thread cannot try to access a destroyed texture
- _currentTransferTexture = currentTexture;
- }
-
- // transfer jobs use asynchronous buffering of the texture data because it may involve disk IO, so we execute a try here to determine if the buffering
- // is complete
- if (_currentTransferJob->tryTransfer()) {
- _pendingTransfers.pop();
- // Once a given job is finished, release the shared pointers keeping them alive
- _currentTransferTexture.reset();
- _currentTransferJob.reset();
- result = true;
- }
-#else
- if (_pendingTransfers.front()->tryTransfer()) {
- _pendingTransfers.pop();
- result = true;
- }
-#endif
- }
- return result;
-}
-
-#if THREADED_TEXTURE_BUFFERING
-void GLVariableAllocationSupport::executeNextBuffer(const TexturePointer& currentTexture) {
- if (_currentTransferJob && !_currentTransferJob->bufferingCompleted()) {
- return;
- }
-
- // If the transfer queue is empty, rebuild it
- if (_pendingTransfers.empty()) {
- populateTransferQueue();
- }
-
- if (!_pendingTransfers.empty()) {
- if (!_currentTransferJob) {
- _currentTransferJob = _pendingTransfers.front();
- _currentTransferTexture = currentTexture;
- }
-
- _currentTransferJob->startBuffering();
- }
-}
-#endif
-
-void GLVariableAllocationSupport::incrementPopulatedSize(Size delta) const {
- _populatedSize += delta;
- // Keep the 2 code paths to be able to debug
- if (_size < _populatedSize) {
- Backend::textureResourcePopulatedGPUMemSize.update(0, delta);
- } else {
- Backend::textureResourcePopulatedGPUMemSize.update(0, delta);
- }
-}
-void GLVariableAllocationSupport::decrementPopulatedSize(Size delta) const {
- _populatedSize -= delta;
- // Keep the 2 code paths to be able to debug
- if (_size < _populatedSize) {
- Backend::textureResourcePopulatedGPUMemSize.update(delta, 0);
- } else {
- Backend::textureResourcePopulatedGPUMemSize.update(delta, 0);
- }
-}
-
-
diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTexture.h b/libraries/gpu-gl-common/src/gpu/gl/GLTexture.h
index c2483eb2a1..5ace804683 100644
--- a/libraries/gpu-gl-common/src/gpu/gl/GLTexture.h
+++ b/libraries/gpu-gl-common/src/gpu/gl/GLTexture.h
@@ -16,8 +16,6 @@
#include "GLTexelFormat.h"
#include
-#define THREADED_TEXTURE_BUFFERING 1
-
namespace gpu { namespace gl {
struct GLFilterMode {
@@ -25,107 +23,92 @@ struct GLFilterMode {
GLint magFilter;
};
+class GLTextureTransferEngine {
+public:
+ using Pointer = std::shared_ptr;
+ /// Called once per frame to perform any require memory management or transfer work
+ virtual void manageMemory() = 0;
+ virtual void shutdown() = 0;
+
+ /// Called whenever a client wants to create a new texture. This allows the transfer engine to
+ /// potentially limit the number of GL textures created per frame
+ bool allowCreate() const { return _frameTexturesCreated < MAX_RESOURCE_TEXTURES_PER_FRAME; }
+ /// Called whenever a client creates a new resource texture that should use managed memory
+ /// and incremental transfer
+ void addMemoryManagedTexture(const TexturePointer& texturePointer);
+
+protected:
+ // Fetch all the currently active textures as strong pointers, while clearing the
+ // empty weak pointers out of _registeredTextures
+ std::vector getAllTextures();
+ void resetFrameTextureCreated() { _frameTexturesCreated = 0; }
+
+private:
+ static const size_t MAX_RESOURCE_TEXTURES_PER_FRAME{ 2 };
+ size_t _frameTexturesCreated{ 0 };
+ std::list _registeredTextures;
+};
+
+/**
+ A transfer job encapsulates an individual piece of work required to upload texture data to the GPU.
+ The work can be broken down into two parts, expressed as lambdas. The buffering lambda is repsonsible
+ for putting the data to be uploaded into a CPU memory buffer. The transfer lambda is repsonsible for
+ uploading the data from the CPU memory buffer to the GPU using OpenGL calls. Ideally the buffering lambda
+ will be executed on a seprate thread from the OpenGL work to ensure that disk IO operations do not block
+ OpenGL calls
+
+ Additionally, a TransferJob can encapsulate some kind of post-upload work that changes the state of the
+ GLTexture derived object wrapping the actual texture ID, such as changing the _populateMip value once
+ a given mip level has been compeltely uploaded
+ */
+class TransferJob {
+public:
+ using Pointer = std::shared_ptr;
+ using Queue = std::queue;
+ using Lambda = std::function;
+private:
+ Texture::PixelsPointer _mipData;
+ size_t _transferOffset{ 0 };
+ size_t _transferSize{ 0 };
+ bool _bufferingRequired{ true };
+ Lambda _transferLambda{ [](const TexturePointer&) {} };
+ Lambda _bufferingLambda{ [](const TexturePointer&) {} };
+public:
+ TransferJob(const TransferJob& other) = delete;
+ TransferJob(const std::function& transferLambda);
+ TransferJob(const Texture& texture, uint16_t sourceMip, uint16_t targetMip, uint8_t face, uint32_t lines = 0, uint32_t lineOffset = 0);
+ ~TransferJob();
+ const size_t& size() const { return _transferSize; }
+ bool bufferingRequired() const { return _bufferingRequired; }
+ void buffer(const TexturePointer& texture) { _bufferingLambda(texture); }
+ void transfer(const TexturePointer& texture) { _transferLambda(texture); }
+};
+
+using TransferJobPointer = std::shared_ptr;
+using TransferQueue = std::queue;
+
class GLVariableAllocationSupport {
friend class GLBackend;
public:
GLVariableAllocationSupport();
virtual ~GLVariableAllocationSupport();
+ virtual void populateTransferQueue(TransferQueue& pendingTransfers) = 0;
- enum class MemoryPressureState {
- Idle,
- Transfer,
- Oversubscribed,
- Undersubscribed,
- };
-
- using QueuePair = std::pair;
- struct QueuePairLess {
- bool operator()(const QueuePair& a, const QueuePair& b) {
- return a.second < b.second;
- }
- };
- using WorkQueue = std::priority_queue, QueuePairLess>;
-
- class TransferJob {
- using VoidLambda = std::function;
- using VoidLambdaQueue = std::queue;
- const GLTexture& _parent;
- Texture::PixelsPointer _mipData;
- size_t _transferOffset { 0 };
- size_t _transferSize { 0 };
-
- bool _bufferingRequired { true };
- VoidLambda _transferLambda;
- VoidLambda _bufferingLambda;
-
-#if THREADED_TEXTURE_BUFFERING
- // Indicates if a transfer from backing storage to interal storage has started
- QFuture _bufferingStatus;
- static QThreadPool* _bufferThreadPool;
-#endif
-
- public:
- TransferJob(const TransferJob& other) = delete;
- TransferJob(const GLTexture& parent, std::function transferLambda);
- TransferJob(const GLTexture& parent, uint16_t sourceMip, uint16_t targetMip, uint8_t face, uint32_t lines = 0, uint32_t lineOffset = 0);
- ~TransferJob();
- bool tryTransfer();
-
-#if THREADED_TEXTURE_BUFFERING
- void startBuffering();
- bool bufferingRequired() const;
- bool bufferingCompleted() const;
- static void startBufferingThread();
-#endif
-
- private:
- void transfer();
- };
-
- using TransferJobPointer = std::shared_ptr;
- using TransferQueue = std::queue;
- static MemoryPressureState _memoryPressureState;
-
-public:
- static void addMemoryManagedTexture(const TexturePointer& texturePointer);
-
-protected:
- static size_t _frameTexturesCreated;
- static std::atomic _memoryPressureStateStale;
- static std::list _memoryManagedTextures;
- static WorkQueue _transferQueue;
- static WorkQueue _promoteQueue;
- static WorkQueue _demoteQueue;
-#if THREADED_TEXTURE_BUFFERING
- static TexturePointer _currentTransferTexture;
- static TransferJobPointer _currentTransferJob;
-#endif
- static const uvec3 INITIAL_MIP_TRANSFER_DIMENSIONS;
- static const uvec3 MAX_TRANSFER_DIMENSIONS;
- static const size_t MAX_TRANSFER_SIZE;
-
-
- static void updateMemoryPressure();
- static void processWorkQueues();
- static void processWorkQueue(WorkQueue& workQueue);
- static TexturePointer getNextWorkQueueItem(WorkQueue& workQueue);
- static void addToWorkQueue(const TexturePointer& texture);
- static WorkQueue& getActiveWorkQueue();
-
- static void manageMemory();
-
- //bool canPromoteNoAllocate() const { return _allocatedMip < _populatedMip; }
+ void sanityCheck() const;
bool canPromote() const { return _allocatedMip > _minAllocatedMip; }
bool canDemote() const { return _allocatedMip < _maxAllocatedMip; }
bool hasPendingTransfers() const { return _populatedMip > _allocatedMip; }
-#if THREADED_TEXTURE_BUFFERING
- void executeNextBuffer(const TexturePointer& currentTexture);
-#endif
- bool executeNextTransfer(const TexturePointer& currentTexture);
- virtual void populateTransferQueue() = 0;
- virtual void promote() = 0;
- virtual void demote() = 0;
+
+ virtual size_t promote() = 0;
+ virtual size_t demote() = 0;
+
+ static const uvec3 MAX_TRANSFER_DIMENSIONS;
+ static const uvec3 INITIAL_MIP_TRANSFER_DIMENSIONS;
+ static const size_t MAX_TRANSFER_SIZE;
+ static const size_t MAX_BUFFER_SIZE;
+
+protected:
// THe amount of memory currently allocated
Size _size { 0 };
@@ -148,10 +131,6 @@ protected:
// The lowest (highest resolution) mip that we will support, relative to the number
// of mips in the gpu::Texture object
uint16 _minAllocatedMip { 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
- TransferQueue _pendingTransfers;
};
class GLTexture : public GLObject {
@@ -172,6 +151,9 @@ public:
static const std::vector& getFaceTargets(GLenum textureType);
static uint8_t getFaceCount(GLenum textureType);
static GLenum getGLTextureType(const Texture& texture);
+ virtual Size size() const = 0;
+ virtual Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const = 0;
+ virtual Size copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const final;
static const uint8_t TEXTURE_2D_NUM_FACES = 1;
static const uint8_t TEXTURE_CUBE_NUM_FACES = 6;
@@ -180,12 +162,9 @@ public:
static const GLenum WRAP_MODES[Sampler::NUM_WRAP_MODES];
protected:
- virtual Size size() const = 0;
virtual void generateMips() const = 0;
virtual void syncSampler() const = 0;
- virtual Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const = 0;
- virtual Size copyMipFaceFromTexture(uint16_t sourceMip, uint16_t targetMip, uint8_t face) const final;
virtual void copyTextureMipsInGPUMem(GLuint srcId, GLuint destId, uint16_t srcMipOffset, uint16_t destMipOffset, uint16_t populatedMips) {} // Only relevant for Variable Allocation textures
GLTexture(const std::weak_ptr& backend, const Texture& texture, GLuint id);
@@ -205,7 +184,6 @@ protected:
Size size() const override { return 0; }
};
-
} }
#endif
diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp
new file mode 100644
index 0000000000..ae0a68e1e9
--- /dev/null
+++ b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp
@@ -0,0 +1,502 @@
+//
+// Created by Bradley Austin Davis on 2016/05/15
+// Copyright 2013-2016 High Fidelity, Inc.
+//
+// Distributed under the Apache License, Version 2.0.
+// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
+//
+
+#include "GLTexture.h"
+
+#include
+#include
+
+#include "GLBackend.h"
+
+#define OVERSUBSCRIBED_PRESSURE_VALUE 0.95f
+#define UNDERSUBSCRIBED_PRESSURE_VALUE 0.85f
+#define DEFAULT_ALLOWED_TEXTURE_MEMORY_MB ((size_t)1024)
+#define MAX_RESOURCE_TEXTURES_PER_FRAME 2
+#define NO_BUFFER_WORK_SLEEP_TIME_MS 2
+#define THREADED_TEXTURE_BUFFERING 1
+
+static const size_t DEFAULT_ALLOWED_TEXTURE_MEMORY = MB_TO_BYTES(DEFAULT_ALLOWED_TEXTURE_MEMORY_MB);
+
+namespace gpu { namespace gl {
+
+enum class MemoryPressureState
+{
+ Idle,
+ Transfer,
+ Undersubscribed,
+};
+
+static MemoryPressureState _memoryPressureState{ MemoryPressureState::Idle };
+
+template
+struct LessPairSecond {
+ bool operator()(const T& a, const T& b) { return a.second < b.second; }
+};
+
+using QueuePair = std::pair;
+// Contains a priority sorted list of textures on which work is to be done over many frames
+// Uses a weak pointer to the texture to avoid keeping it in scope if the client stops using it
+using WorkQueue = std::priority_queue, LessPairSecond>;
+
+
+using ImmediateQueuePair = std::pair;
+// Contains a priority sorted list of textures on which work is to be done in the current frame
+using ImmediateWorkQueue = std::priority_queue, LessPairSecond>;
+
+// A map of weak texture pointers to queues of work to be done to transfer their data from the backing store to the GPU
+using TransferMap = std::map>;
+
+class GLTextureTransferEngineDefault : public GLTextureTransferEngine {
+ using Parent = GLTextureTransferEngine;
+public:
+ // Called once per frame by the GLBackend to manage texture memory
+ // Will deallocate textures if oversubscribed,
+ void manageMemory() override;
+ void shutdown() override;
+
+protected:
+ class TextureBufferThread : public QThread {
+ public:
+ TextureBufferThread(GLTextureTransferEngineDefault& parent) : _parent(parent) { start(); }
+
+ protected:
+ void run() override {
+ while (!_parent._shutdown) {
+ if (!_parent.processActiveBufferQueue()) {
+ QThread::msleep(NO_BUFFER_WORK_SLEEP_TIME_MS);
+ }
+ }
+ }
+
+ GLTextureTransferEngineDefault& _parent;
+ };
+
+ using ActiveTransferJob = std::pair;
+ using ActiveTransferQueue = std::list;
+
+ void populateActiveBufferQueue();
+ bool processActiveBufferQueue();
+ void processTransferQueues();
+ void populateTransferQueue(const TexturePointer& texturePointer);
+ //void addToWorkQueue(const TexturePointer& texturePointer);
+ void updateMemoryPressure();
+
+ void processDemotes(size_t relief, const std::vector& strongTextures);
+ void processPromotes();
+
+private:
+ std::atomic _shutdown{ false };
+ // Contains a priority sorted list of weak texture pointers that have been determined to be eligible for additional allocation
+ // While the memory state is 'undersubscribed', items will be removed from this list and processed, allocating additional memory
+ // per frame
+ WorkQueue _promoteQueue;
+ // This queue contains jobs that will buffer data from the texture backing store (ideally a memory mapped KTX file)
+ // to a CPU memory buffer. This queue is populated on the main GPU thread, and drained on a dedicated thread.
+ // When an item on the _activeBufferQueue is completed it is put into the _activeTransferQueue
+ ActiveTransferQueue _activeBufferQueue;
+ // This queue contains jobs that will upload data from a CPU buffer into a GPU. This queue is populated on the background
+ // thread that process the _activeBufferQueue and drained on the main GPU thread
+ ActiveTransferQueue _activeTransferQueue;
+ // Mutex protecting the _activeTransferQueue & _activeBufferQueue since they are each accessed both from the main GPU thread
+ // and the buffering thread
+ Mutex _bufferMutex;
+ // The buffering thread which drains the _activeBufferQueue and populates the _activeTransferQueue
+ TextureBufferThread* _transferThread{ nullptr };
+ // The amount of buffering work currently represented by the _activeBufferQueue
+ size_t _queuedBufferSize{ 0 };
+ // This contains a map of all textures to queues of pending transfer jobs. While in the transfer state, this map is used to
+ // populate the _activeBufferQueue up to the limit specified in GLVariableAllocationTexture::MAX_BUFFER_SIZE
+ TransferMap _pendingTransfersMap;
+};
+
+}} // namespace gpu::gl
+
+using namespace gpu;
+using namespace gpu::gl;
+
+void GLBackend::initTextureManagementStage() {
+ _textureManagement._transferEngine = std::make_shared();
+}
+
+void GLBackend::killTextureManagementStage() {
+ _textureManagement._transferEngine->shutdown();
+ _textureManagement._transferEngine.reset();
+}
+
+std::vector GLTextureTransferEngine::getAllTextures() {
+ std::vector result;
+ result.reserve(_registeredTextures.size());
+ std::remove_if(_registeredTextures.begin(), _registeredTextures.end(), [&](const std::weak_ptr& weak)->bool {
+ auto strong = weak.lock();
+ bool strongResult = strong.operator bool();
+ if (strongResult) {
+ result.push_back(strong);
+ }
+ return strongResult;
+ });
+ return result;
+}
+
+void GLTextureTransferEngine::addMemoryManagedTexture(const TexturePointer& texturePointer) {
+ ++_frameTexturesCreated;
+ _registeredTextures.push_back(texturePointer);
+}
+
+void GLTextureTransferEngineDefault::shutdown() {
+ _shutdown = true;
+#if THREADED_TEXTURE_BUFFERING
+ if (_transferThread) {
+ _transferThread->wait();
+ delete _transferThread;
+ _transferThread = nullptr;
+ }
+#endif
+}
+
+
+void GLTextureTransferEngineDefault::manageMemory() {
+ PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
+ // reset the count used to limit the number of textures created per frame
+ resetFrameTextureCreated();
+ // Determine the current memory management state. It will be either idle (no work to do),
+ // undersubscribed (need to do more allocation) or transfer (need to upload content from the
+ // backing store to the GPU
+ updateMemoryPressure();
+ if (MemoryPressureState::Undersubscribed == _memoryPressureState) {
+ // If we're undersubscribed, we need to process some of the textures that can have additional allocation
+ processPromotes();
+ } else if (MemoryPressureState::Transfer == _memoryPressureState) {
+ // If we're in transfer mode we need to manage the buffering and upload queues
+ processTransferQueues();
+ }
+}
+
+// Each frame we will check if our memory pressure state has changed.
+void GLTextureTransferEngineDefault::updateMemoryPressure() {
+ PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
+
+ size_t allowedMemoryAllocation = gpu::Texture::getAllowedGPUMemoryUsage();
+ if (0 == allowedMemoryAllocation) {
+ allowedMemoryAllocation = DEFAULT_ALLOWED_TEXTURE_MEMORY;
+ }
+
+ // Clear any defunct textures (weak pointers that no longer have a valid texture)
+ auto strongTextures = getAllTextures();
+
+ size_t totalVariableMemoryAllocation = 0;
+ size_t idealMemoryAllocation = 0;
+ bool canDemote = false;
+ bool canPromote = false;
+ bool hasTransfers = false;
+ for (const auto& texture : strongTextures) {
+ GLTexture* gltexture = Backend::getGPUObject(*texture);
+ GLVariableAllocationSupport* vartexture = dynamic_cast(gltexture);
+ vartexture->sanityCheck();
+
+ // Track how much the texture thinks it should be using
+ idealMemoryAllocation += texture->evalTotalSize();
+ // Track how much we're actually using
+ totalVariableMemoryAllocation += gltexture->size();
+ if (vartexture->canDemote()) {
+ canDemote |= true;
+ }
+ if (vartexture->canPromote()) {
+ canPromote |= true;
+ }
+ if (vartexture->hasPendingTransfers()) {
+ hasTransfers |= true;
+ }
+ }
+
+ size_t unallocated = idealMemoryAllocation - totalVariableMemoryAllocation;
+ float pressure = (float)totalVariableMemoryAllocation / (float)allowedMemoryAllocation;
+
+ // If we're oversubscribed we need to demote textures IMMEDIATELY
+ if (pressure > OVERSUBSCRIBED_PRESSURE_VALUE && canDemote) {
+ auto overPressure = pressure - OVERSUBSCRIBED_PRESSURE_VALUE;
+ size_t relief = (size_t)(overPressure * totalVariableMemoryAllocation);
+ processDemotes(relief, strongTextures);
+ return;
+ }
+
+
+ auto newState = MemoryPressureState::Idle;
+ if (pressure < UNDERSUBSCRIBED_PRESSURE_VALUE && (unallocated != 0 && canPromote)) {
+ newState = MemoryPressureState::Undersubscribed;
+ } else if (hasTransfers) {
+ newState = MemoryPressureState::Transfer;
+ } else {
+ Lock lock(_bufferMutex);
+ if (!_activeBufferQueue.empty() || !_activeTransferQueue.empty() || !_pendingTransfersMap.empty()) {
+ newState = MemoryPressureState::Transfer;
+ }
+ }
+
+ // If we've changed state then we have to populate the appropriate structure with the work to be done
+ if (newState != _memoryPressureState) {
+ _memoryPressureState = newState;
+ _promoteQueue = WorkQueue();
+ _pendingTransfersMap.clear();
+
+ if (MemoryPressureState::Idle == _memoryPressureState) {
+ return;
+ }
+
+ // For each texture, if it's eligible for work in the current state, put it into the appropriate structure
+ for (const auto& texture : strongTextures) {
+ GLTexture* gltexture = Backend::getGPUObject(*texture);
+ GLVariableAllocationSupport* vargltexture = dynamic_cast(gltexture);
+ if (MemoryPressureState::Undersubscribed == _memoryPressureState && vargltexture->canPromote()) {
+ // Promote smallest first
+ _promoteQueue.push({ texture, 1.0f / (float)gltexture->size() });
+ } else if (MemoryPressureState::Transfer == _memoryPressureState && vargltexture->hasPendingTransfers()) {
+ populateTransferQueue(texture);
+ }
+ }
+ }
+}
+
+// Manage the _activeBufferQueue and _activeTransferQueue queues
+void GLTextureTransferEngineDefault::processTransferQueues() {
+#if THREADED_TEXTURE_BUFFERING
+ if (!_transferThread) {
+ _transferThread = new TextureBufferThread(*this);
+ }
+#endif
+
+
+ // From the pendingTransferMap, queue jobs into the _activeBufferQueue
+ // Doing so will lock the weak texture pointer so that it can't be destroyed
+ // while the background thread is working.
+ //
+ // This will queue jobs until _queuedBufferSize can't be increased without exceeding
+ // GLVariableAllocationTexture::MAX_BUFFER_SIZE or there is no more work to be done
+ populateActiveBufferQueue();
+#if !THREADED_TEXTURE_BUFFERING
+ processActiveBufferQueue();
+#endif
+
+ // Take any tasks which have completed buffering and process them, uploading the buffered
+ // data to the GPU. Drains the _activeTransferQueue
+ {
+ ActiveTransferQueue activeTransferQueue;
+ {
+ Lock lock(_bufferMutex);
+ activeTransferQueue.swap(_activeTransferQueue);
+ }
+
+ while (!activeTransferQueue.empty()) {
+ const auto& activeTransferJob = activeTransferQueue.front();
+ const auto& texturePointer = activeTransferJob.first;
+ const auto& tranferJob = activeTransferJob.second;
+ tranferJob->transfer(texturePointer);
+ // The pop_front MUST be the last call since all of these varaibles in scope are
+ // references that will be invalid after the pop
+ activeTransferQueue.pop_front();
+ }
+ }
+
+ // If we have no more work in any of the structures, reset the memory state to idle to
+ // force reconstruction of the _pendingTransfersMap if necessary
+ {
+ Lock lock(_bufferMutex);
+ if (_activeTransferQueue.empty() && _activeBufferQueue.empty() && _pendingTransfersMap.empty()) {
+ _memoryPressureState = MemoryPressureState::Idle;
+ }
+ }
+}
+
+void GLTextureTransferEngineDefault::populateActiveBufferQueue() {
+ size_t queuedBufferSize = _queuedBufferSize;
+ static const auto& MAX_BUFFER_SIZE = GLVariableAllocationSupport::MAX_BUFFER_SIZE;
+ Q_ASSERT(queuedBufferSize <= MAX_BUFFER_SIZE);
+ size_t availableBufferSize = MAX_BUFFER_SIZE - queuedBufferSize;
+
+ // Queue up buffering jobs
+ ActiveTransferQueue newBufferJobs;
+ ActiveTransferQueue newTransferJobs;
+ size_t newTransferSize{ 0 };
+
+ for (auto itr = _pendingTransfersMap.begin(); itr != _pendingTransfersMap.end(); ) {
+ const auto& weakTexture = itr->first;
+ const auto texture = weakTexture.lock();
+
+ // Texture no longer exists, remove from the transfer map and move on
+ if (!texture) {
+ itr = _pendingTransfersMap.erase(itr);
+ continue;
+ }
+
+ GLTexture* gltexture = Backend::getGPUObject(*texture);
+ GLVariableAllocationSupport* vargltexture = dynamic_cast(gltexture);
+
+ auto& textureTransferQueue = itr->second;
+ // Can't find any pending transfers, so move on
+ if (textureTransferQueue.empty()) {
+ if (vargltexture->hasPendingTransfers()) {
+ qWarning(gpugllogging) << "Texture has no transfer jobs, but has pending transfers";
+ }
+ itr = _pendingTransfersMap.erase(itr);
+ continue;
+ }
+
+ const auto& transferJob = textureTransferQueue.front();
+ if (!transferJob->bufferingRequired()) {
+ newTransferJobs.emplace_back(texture, transferJob);
+ } else {
+ const auto& transferSize = transferJob->size();
+ // If there's not enough space for the buffering, then break out of the loop
+ if (transferSize > availableBufferSize) {
+ break;
+ }
+ availableBufferSize -= transferSize;
+ Q_ASSERT(availableBufferSize <= MAX_BUFFER_SIZE);
+ Q_ASSERT(newTransferSize <= MAX_BUFFER_SIZE);
+ newTransferSize += transferSize;
+ Q_ASSERT(newTransferSize <= MAX_BUFFER_SIZE);
+ newBufferJobs.emplace_back(texture, transferJob);
+ }
+ textureTransferQueue.pop();
+ ++itr;
+ }
+
+ {
+ Lock lock(_bufferMutex);
+ _activeBufferQueue.splice(_activeBufferQueue.end(), newBufferJobs);
+ Q_ASSERT(_queuedBufferSize <= MAX_BUFFER_SIZE);
+ _queuedBufferSize += newTransferSize;
+ Q_ASSERT(_queuedBufferSize <= MAX_BUFFER_SIZE);
+ _activeTransferQueue.splice(_activeTransferQueue.end(), newTransferJobs);
+ }
+}
+
+bool GLTextureTransferEngineDefault::processActiveBufferQueue() {
+ ActiveTransferQueue activeBufferQueue;
+ {
+ Lock lock(_bufferMutex);
+ _activeBufferQueue.swap(activeBufferQueue);
+ }
+
+ if (activeBufferQueue.empty()) {
+ return false;
+ }
+
+ for (const auto& activeJob : activeBufferQueue) {
+ const auto& texture = activeJob.first;
+ const auto& transferJob = activeJob.second;
+ const auto& transferSize = transferJob->size();
+ transferJob->buffer(texture);
+ Q_ASSERT(_queuedBufferSize >= transferSize);
+ _queuedBufferSize -= transferSize;
+ }
+
+ {
+ Lock lock(_bufferMutex);
+ _activeTransferQueue.splice(_activeTransferQueue.end(), activeBufferQueue);
+ }
+
+ return true;
+}
+
+void GLTextureTransferEngineDefault::populateTransferQueue(const TexturePointer& texturePointer) {
+ TextureWeakPointer weakTexture = texturePointer;
+ GLTexture* gltexture = Backend::getGPUObject(*texturePointer);
+ GLVariableAllocationSupport* vargltexture = dynamic_cast(gltexture);
+ TransferJob::Queue pendingTransfers;
+ PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
+ vargltexture->populateTransferQueue(pendingTransfers);
+ if (!pendingTransfers.empty()) {
+ _pendingTransfersMap[weakTexture] = pendingTransfers;
+ }
+}
+
+// From the queue of textures to be promited
+void GLTextureTransferEngineDefault::processPromotes() {
+ // FIXME use max allocated memory per frame instead of promotion count
+ static const size_t MAX_ALLOCATED_BYTES_PER_FRAME = GLVariableAllocationSupport::MAX_BUFFER_SIZE;
+ static const size_t MAX_ALLOCATIONS_PER_FRAME = 8;
+ size_t allocatedBytes{ 0 };
+ size_t allocations{ 0 };
+
+ while (!_promoteQueue.empty()) {
+ // Grab the first item off the demote queue
+ PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
+ auto entry = _promoteQueue.top();
+ _promoteQueue.pop();
+ auto texture = entry.first.lock();
+ if (!texture) {
+ continue;
+ }
+
+ GLTexture* gltexture = Backend::getGPUObject(*texture);
+ GLVariableAllocationSupport* vartexture = dynamic_cast(gltexture);
+ auto originalSize = gltexture->size();
+ vartexture->promote();
+ auto allocationDelta = gltexture->size() - originalSize;
+ if (vartexture->canPromote()) {
+ // Promote smallest first
+ _promoteQueue.push({ texture, 1.0f / (float)gltexture->size() });
+ }
+ allocatedBytes += allocationDelta;
+ if (++allocations >= MAX_ALLOCATIONS_PER_FRAME) {
+ break;
+ }
+ if (allocatedBytes >= MAX_ALLOCATED_BYTES_PER_FRAME) {
+ break;
+ }
+ }
+
+ // Get the front of the work queue to perform work
+ if (_promoteQueue.empty()) {
+ // Force rebuild of work queue
+ _memoryPressureState = MemoryPressureState::Idle;
+ }
+}
+
+void GLTextureTransferEngineDefault::processDemotes(size_t reliefRequired, const std::vector& strongTextures) {
+ // Demote largest first
+ ImmediateWorkQueue demoteQueue;
+ for (const auto& texture : strongTextures) {
+ GLTexture* gltexture = Backend::getGPUObject(*texture);
+ GLVariableAllocationSupport* vargltexture = dynamic_cast(gltexture);
+ if (vargltexture->canDemote()) {
+ demoteQueue.push({ texture, (float)gltexture->size() });
+ }
+ }
+
+ size_t relieved = 0;
+ while (!demoteQueue.empty() && relieved < reliefRequired) {
+ {
+ const auto& target = demoteQueue.top();
+ const auto& texture = target.first;
+ GLTexture* gltexture = Backend::getGPUObject(*texture);
+ auto oldSize = gltexture->size();
+ GLVariableAllocationSupport* vargltexture = dynamic_cast(gltexture);
+ vargltexture->demote();
+ auto newSize = gltexture->size();
+ relieved += (oldSize - newSize);
+ }
+ demoteQueue.pop();
+ }
+}
+
+// FIXME hack for stats display
+QString getTextureMemoryPressureModeString() {
+ switch (_memoryPressureState) {
+ case MemoryPressureState::Undersubscribed:
+ return "Undersubscribed";
+
+ case MemoryPressureState::Transfer:
+ return "Transfer";
+
+ case MemoryPressureState::Idle:
+ return "Idle";
+ }
+ Q_UNREACHABLE();
+ return "Unknown";
+}
diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h
index f3b452b1f9..23dcac0d8d 100644
--- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h
+++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h
@@ -114,9 +114,9 @@ public:
void allocateStorage(uint16 allocatedMip);
void syncSampler() const override;
- void promote() override;
- void demote() override;
- void populateTransferQueue() override;
+ size_t promote() override;
+ size_t demote() override;
+ void populateTransferQueue(TransferQueue& pendingTransfers) override;
Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override;
Size copyMipsFromTexture();
diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp
index 0298b8b892..624cb4f656 100644
--- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp
+++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp
@@ -72,7 +72,7 @@ GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) {
case TextureUsageType::RESOURCE:
qCDebug(gpugllogging) << "variable / Strict texture " << texture.source().c_str();
object = new GL41ResourceTexture(shared_from_this(), texture);
- GLVariableAllocationSupport::addMemoryManagedTexture(texturePointer);
+ _textureManagement._transferEngine->addMemoryManagedTexture(texturePointer);
break;
default:
@@ -86,7 +86,6 @@ GLTexture* GL41Backend::syncGPUObject(const TexturePointer& texturePointer) {
auto minAvailableMip = texture.minAvailableMipLevel();
if (minAvailableMip < varTex->_minAllocatedMip) {
varTex->_minAllocatedMip = minAvailableMip;
- GL41VariableAllocationTexture::_memoryPressureStateStale = true;
}
}
}
@@ -299,9 +298,7 @@ GL41VariableAllocationTexture::GL41VariableAllocationTexture(const std::weak_ptr
uint16_t allocatedMip = std::max(_minAllocatedMip, targetMip);
allocateStorage(allocatedMip);
- _memoryPressureStateStale = true;
copyMipsFromTexture();
-
syncSampler();
}
@@ -496,7 +493,7 @@ void GL41VariableAllocationTexture::copyTextureMipsInGPUMem(GLuint srcId, GLuint
});
}
-void GL41VariableAllocationTexture::promote() {
+size_t GL41VariableAllocationTexture::promote() {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
Q_ASSERT(_allocatedMip > 0);
@@ -524,12 +521,11 @@ void GL41VariableAllocationTexture::promote() {
// update the memory usage
Backend::textureResourceGPUMemSize.update(oldSize, 0);
+ return (_size - oldSize);
// no change to Backend::textureResourcePopulatedGPUMemSize
-
- populateTransferQueue();
}
-void GL41VariableAllocationTexture::demote() {
+size_t GL41VariableAllocationTexture::demote() {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
Q_ASSERT(_allocatedMip < _maxAllocatedMip);
auto oldId = _id;
@@ -563,16 +559,16 @@ void GL41VariableAllocationTexture::demote() {
}
decrementPopulatedSize(amountUnpopulated);
}
- populateTransferQueue();
+
+ return oldSize - _size;
}
-void GL41VariableAllocationTexture::populateTransferQueue() {
+void GL41VariableAllocationTexture::populateTransferQueue(TransferQueue& pendingTransfers) {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
if (_populatedMip <= _allocatedMip) {
return;
}
- _pendingTransfers = TransferQueue();
const uint8_t maxFace = GLTexture::getFaceCount(_target);
uint16_t sourceMip = _populatedMip;
@@ -588,7 +584,7 @@ void GL41VariableAllocationTexture::populateTransferQueue() {
// If the mip is less than the max transfer size, then just do it in one transfer
if (glm::all(glm::lessThanEqual(mipDimensions, MAX_TRANSFER_DIMENSIONS))) {
// Can the mip be transferred in one go
- _pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face));
+ pendingTransfers.emplace(new TransferJob(_gpuObject, sourceMip, targetMip, face));
continue;
}
@@ -605,13 +601,13 @@ void GL41VariableAllocationTexture::populateTransferQueue() {
uint32_t lineOffset = 0;
while (lineOffset < lines) {
uint32_t linesToCopy = std::min(lines - lineOffset, linesPerTransfer);
- _pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face, linesToCopy, lineOffset));
+ pendingTransfers.emplace(new TransferJob(_gpuObject, sourceMip, targetMip, face, linesToCopy, lineOffset));
lineOffset += linesToCopy;
}
}
// queue up the sampler and populated mip change for after the transfer has completed
- _pendingTransfers.emplace(new TransferJob(*this, [=] {
+ pendingTransfers.emplace(new TransferJob([=] {
_populatedMip = sourceMip;
syncSampler();
}));
diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h
index 616b6d1075..0db9271f57 100644
--- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h
+++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h
@@ -187,9 +187,9 @@ public:
GL45ResourceTexture(const std::weak_ptr& backend, const Texture& texture);
void syncSampler() const override;
- void promote() override;
- void demote() override;
- void populateTransferQueue() override;
+ size_t promote() override;
+ size_t demote() override;
+ void populateTransferQueue(TransferQueue& pendingTransfers) override;
void allocateStorage(uint16 mip);
diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp
index 6b3c99ccc3..b0ae1296e9 100644
--- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp
+++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp
@@ -28,7 +28,6 @@ using namespace gpu;
using namespace gpu::gl;
using namespace gpu::gl45;
-#define MAX_RESOURCE_TEXTURES_PER_FRAME 2
#define FORCE_STRICT_TEXTURE 0
#define ENABLE_SPARSE_TEXTURE 0
@@ -82,7 +81,8 @@ GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) {
#if !FORCE_STRICT_TEXTURE
case TextureUsageType::RESOURCE: {
- if (GL45VariableAllocationTexture::_frameTexturesCreated < MAX_RESOURCE_TEXTURES_PER_FRAME) {
+ auto& transferEngine = _textureManagement._transferEngine;
+ if (transferEngine->allowCreate()) {
#if ENABLE_SPARSE_TEXTURE
if (isTextureManagementSparseEnabled() && GL45Texture::isSparseEligible(texture)) {
object = new GL45SparseResourceTexture(shared_from_this(), texture);
@@ -92,7 +92,7 @@ GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) {
#else
object = new GL45ResourceTexture(shared_from_this(), texture);
#endif
- GLVariableAllocationSupport::addMemoryManagedTexture(texturePointer);
+ transferEngine->addMemoryManagedTexture(texturePointer);
} else {
auto fallback = texturePointer->getFallbackTexture();
if (fallback) {
@@ -114,7 +114,6 @@ GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) {
auto minAvailableMip = texture.minAvailableMipLevel();
if (minAvailableMip < varTex->_minAllocatedMip) {
varTex->_minAllocatedMip = minAvailableMip;
- GL45VariableAllocationTexture::_memoryPressureStateStale = true;
}
}
}
@@ -124,6 +123,7 @@ GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) {
}
void GL45Backend::initTextureManagementStage() {
+ GLBackend::initTextureManagementStage();
// enable the Sparse Texture on gl45
_textureManagement._sparseCapable = true;
diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp
index 08d077605d..fe74336b2a 100644
--- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp
+++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp
@@ -31,7 +31,6 @@ using GL45Texture = GL45Backend::GL45Texture;
using GL45VariableAllocationTexture = GL45Backend::GL45VariableAllocationTexture;
GL45VariableAllocationTexture::GL45VariableAllocationTexture(const std::weak_ptr& backend, const Texture& texture) : GL45Texture(backend, texture) {
- ++_frameTexturesCreated;
Backend::textureResourceCount.increment();
}
@@ -104,7 +103,6 @@ GL45ResourceTexture::GL45ResourceTexture(const std::weak_ptr& backend
uint16_t allocatedMip = std::max(_minAllocatedMip, targetMip);
allocateStorage(allocatedMip);
- _memoryPressureStateStale = true;
copyMipsFromTexture();
syncSampler();
}
@@ -148,7 +146,7 @@ void GL45ResourceTexture::syncSampler() const {
#endif
}
-void GL45ResourceTexture::promote() {
+size_t GL45ResourceTexture::promote() {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
Q_ASSERT(_allocatedMip > 0);
@@ -191,11 +189,10 @@ void GL45ResourceTexture::promote() {
// update the memory usage
Backend::textureResourceGPUMemSize.update(oldSize, 0);
// no change to Backend::textureResourcePopulatedGPUMemSize
-
- populateTransferQueue();
+ return (_size - oldSize);
}
-void GL45ResourceTexture::demote() {
+size_t GL45ResourceTexture::demote() {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
Q_ASSERT(_allocatedMip < _maxAllocatedMip);
auto oldId = _id;
@@ -242,16 +239,16 @@ void GL45ResourceTexture::demote() {
}
decrementPopulatedSize(amountUnpopulated);
}
-
- populateTransferQueue();
+ return (oldSize - _size);
}
-void GL45ResourceTexture::populateTransferQueue() {
+void GL45ResourceTexture::populateTransferQueue(TransferQueue& pendingTransfers) {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
+ sanityCheck();
+
if (_populatedMip <= _allocatedMip) {
return;
}
- _pendingTransfers = TransferQueue();
const uint8_t maxFace = GLTexture::getFaceCount(_target);
uint16_t sourceMip = _populatedMip;
@@ -267,7 +264,7 @@ void GL45ResourceTexture::populateTransferQueue() {
// If the mip is less than the max transfer size, then just do it in one transfer
if (glm::all(glm::lessThanEqual(mipDimensions, MAX_TRANSFER_DIMENSIONS))) {
// Can the mip be transferred in one go
- _pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face));
+ pendingTransfers.emplace(new TransferJob(_gpuObject, sourceMip, targetMip, face));
continue;
}
@@ -284,14 +281,15 @@ void GL45ResourceTexture::populateTransferQueue() {
uint32_t lineOffset = 0;
while (lineOffset < lines) {
uint32_t linesToCopy = std::min(lines - lineOffset, linesPerTransfer);
- _pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face, linesToCopy, lineOffset));
+ pendingTransfers.emplace(new TransferJob(_gpuObject, sourceMip, targetMip, face, linesToCopy, lineOffset));
lineOffset += linesToCopy;
}
}
// queue up the sampler and populated mip change for after the transfer has completed
- _pendingTransfers.emplace(new TransferJob(*this, [=] {
+ pendingTransfers.emplace(new TransferJob([=] {
_populatedMip = sourceMip;
+ sanityCheck();
syncSampler();
}));
} while (sourceMip != _allocatedMip);
diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h
index 47a123718a..cb8e4abb29 100644
--- a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h
+++ b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h
@@ -105,9 +105,9 @@ public:
void allocateStorage(uint16 allocatedMip);
void syncSampler() const override;
- void promote() override;
- void demote() override;
- void populateTransferQueue() override;
+ size_t promote() override;
+ size_t demote() override;
+ void populateTransferQueue(TransferJob::Queue& queue) override;
Size copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const override;
Size copyMipsFromTexture();
diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp
index 2009dc5dc9..2ffa421bc8 100644
--- a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp
+++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp
@@ -90,7 +90,6 @@ GLTexture* GLESBackend::syncGPUObject(const TexturePointer& texturePointer) {
auto minAvailableMip = texture.minAvailableMipLevel();
if (minAvailableMip < varTex->_minAllocatedMip) {
varTex->_minAllocatedMip = minAvailableMip;
- GLESVariableAllocationTexture::_memoryPressureStateStale = true;
}
}
}
@@ -361,7 +360,6 @@ GLESVariableAllocationTexture::GLESVariableAllocationTexture(const std::weak_ptr
uint16_t allocatedMip = std::max(_minAllocatedMip, targetMip);
allocateStorage(allocatedMip);
- _memoryPressureStateStale = true;
copyMipsFromTexture();
syncSampler();
@@ -559,7 +557,7 @@ void GLESVariableAllocationTexture::copyTextureMipsInGPUMem(GLuint srcId, GLuint
});
}
-void GLESVariableAllocationTexture::promote() {
+size_t GLESVariableAllocationTexture::promote() {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
Q_ASSERT(_allocatedMip > 0);
@@ -587,12 +585,11 @@ void GLESVariableAllocationTexture::promote() {
// update the memory usage
Backend::textureResourceGPUMemSize.update(oldSize, 0);
- // no change to Backend::textureResourcePopulatedGPUMemSize
- populateTransferQueue();
+ return _size - oldSize;
}
-void GLESVariableAllocationTexture::demote() {
+size_t GLESVariableAllocationTexture::demote() {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
Q_ASSERT(_allocatedMip < _maxAllocatedMip);
auto oldId = _id;
@@ -626,16 +623,16 @@ void GLESVariableAllocationTexture::demote() {
}
decrementPopulatedSize(amountUnpopulated);
}
- populateTransferQueue();
+
+ return oldSize - _size;
}
-void GLESVariableAllocationTexture::populateTransferQueue() {
+void GLESVariableAllocationTexture::populateTransferQueue(TransferJob::Queue& queue) {
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
if (_populatedMip <= _allocatedMip) {
return;
}
- _pendingTransfers = TransferQueue();
const uint8_t maxFace = GLTexture::getFaceCount(_target);
uint16_t sourceMip = _populatedMip;
@@ -651,7 +648,7 @@ void GLESVariableAllocationTexture::populateTransferQueue() {
// If the mip is less than the max transfer size, then just do it in one transfer
if (glm::all(glm::lessThanEqual(mipDimensions, MAX_TRANSFER_DIMENSIONS))) {
// Can the mip be transferred in one go
- _pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face));
+ queue.emplace(new TransferJob(_gpuObject, sourceMip, targetMip, face));
continue;
}
@@ -668,13 +665,13 @@ void GLESVariableAllocationTexture::populateTransferQueue() {
uint32_t lineOffset = 0;
while (lineOffset < lines) {
uint32_t linesToCopy = std::min(lines - lineOffset, linesPerTransfer);
- _pendingTransfers.emplace(new TransferJob(*this, sourceMip, targetMip, face, linesToCopy, lineOffset));
+ queue.emplace(new TransferJob(_gpuObject, sourceMip, targetMip, face, linesToCopy, lineOffset));
lineOffset += linesToCopy;
}
}
// queue up the sampler and populated mip change for after the transfer has completed
- _pendingTransfers.emplace(new TransferJob(*this, [=] {
+ queue.emplace(new TransferJob([=] {
_populatedMip = sourceMip;
syncSampler();
}));
diff --git a/tests/gpu/src/TextureTest.cpp b/tests/gpu/src/TextureTest.cpp
index 18361af791..c9229fb826 100644
--- a/tests/gpu/src/TextureTest.cpp
+++ b/tests/gpu/src/TextureTest.cpp
@@ -25,13 +25,14 @@
QTEST_MAIN(TextureTest)
-#define LOAD_TEXTURE_COUNT 40
+#define LOAD_TEXTURE_COUNT 100
+#define FAIL_AFTER_SECONDS 30
static const QString TEST_DATA("https://hifi-public.s3.amazonaws.com/austin/test_data/test_ktx.zip");
static const QString TEST_DIR_NAME("{630b8f02-52af-4cdf-a896-24e472b94b28}");
+static const QString KTX_TEST_DIR_ENV("HIFI_KTX_TEST_DIR");
std::string vertexShaderSource = R"SHADER(
-#line 14
layout(location = 0) out vec2 outTexCoord0;
const vec4 VERTICES[] = vec4[](
@@ -50,8 +51,6 @@ void main() {
)SHADER";
std::string fragmentShaderSource = R"SHADER(
-#line 28
-
uniform sampler2D tex;
layout(location = 0) in vec2 inTexCoord0;
@@ -87,21 +86,29 @@ void TextureTest::initTestCase() {
gpu::Context::init();
_gpuContext = std::make_shared();
- _resourcesPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + TEST_DIR_NAME;
- if (!QFileInfo(_resourcesPath).exists()) {
- QDir(_resourcesPath).mkpath(".");
- FileDownloader(TEST_DATA,
- [&](const QByteArray& data) {
- QTemporaryFile zipFile;
- if (zipFile.open()) {
- zipFile.write(data);
- zipFile.close();
- }
- JlCompress::extractDir(zipFile.fileName(), _resourcesPath);
- })
- .waitForDownload();
+
+ if (QProcessEnvironment::systemEnvironment().contains(KTX_TEST_DIR_ENV)) {
+ // For local testing with larger data sets
+ _resourcesPath = QProcessEnvironment::systemEnvironment().value(KTX_TEST_DIR_ENV);
+ } else {
+ _resourcesPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/" + TEST_DIR_NAME;
+ if (!QFileInfo(_resourcesPath).exists()) {
+ QDir(_resourcesPath).mkpath(".");
+ FileDownloader(TEST_DATA,
+ [&](const QByteArray& data) {
+ QTemporaryFile zipFile;
+ if (zipFile.open()) {
+ zipFile.write(data);
+ zipFile.close();
+ }
+ JlCompress::extractDir(zipFile.fileName(), _resourcesPath);
+ })
+ .waitForDownload();
+ }
}
+ QVERIFY(!_resourcesPath.isEmpty());
+
_canvas.makeCurrent();
{
auto VS = gpu::Shader::createVertex(vertexShaderSource);
@@ -130,15 +137,7 @@ void TextureTest::initTestCase() {
}
}
- // Load the test textures
- {
- size_t newTextureCount = std::min(_textureFiles.size(), LOAD_TEXTURE_COUNT);
- for (size_t i = 0; i < newTextureCount; ++i) {
- const auto& textureFile = _textureFiles[i];
- auto texture = gpu::Texture::unserialize(textureFile);
- _textures.push_back(texture);
- }
- }
+ QVERIFY(!_textureFiles.empty());
}
void TextureTest::cleanupTestCase() {
@@ -148,6 +147,18 @@ void TextureTest::cleanupTestCase() {
_gpuContext.reset();
}
+std::vector TextureTest::loadTestTextures() const {
+ // Load the test textures
+ std::vector result;
+ size_t newTextureCount = std::min(_textureFiles.size(), LOAD_TEXTURE_COUNT);
+ for (size_t i = 0; i < newTextureCount; ++i) {
+ const auto& textureFile = _textureFiles[i];
+ auto texture = gpu::Texture::unserialize(textureFile);
+ result.push_back(texture);
+ }
+ return result;
+}
+
void TextureTest::beginFrame() {
_gpuContext->recycle();
_gpuContext->beginFrame();
@@ -169,116 +180,130 @@ void TextureTest::endFrame() {
QThread::msleep(10);
}
+
void TextureTest::renderFrame(const std::function& renderLambda) {
beginFrame();
gpu::doInBatch("Test::body", _gpuContext, renderLambda);
endFrame();
+ ++_frameCount;
}
+extern QString getTextureMemoryPressureModeString();
void TextureTest::testTextureLoading() {
- QVERIFY(_textures.size() > 0);
- auto renderTexturesLamdba = [this](gpu::Batch& batch) {
- batch.setPipeline(_pipeline);
- for (const auto& texture : _textures) {
- batch.setResourceTexture(0, texture);
- batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
+ QBENCHMARK{
+ _frameCount = 0;
+ auto textures = loadTestTextures();
+ QVERIFY(textures.size() > 0);
+ auto renderTexturesLamdba = [&](gpu::Batch& batch) {
+ batch.setPipeline(_pipeline);
+ for (const auto& texture : textures) {
+ batch.setResourceTexture(0, texture);
+ batch.draw(gpu::TRIANGLE_STRIP, 4, 0);
+ }
+ };
+
+ size_t expectedAllocation = 0;
+ for (const auto& texture : textures) {
+ expectedAllocation += texture->evalTotalSize();
}
- };
+ QVERIFY(textures.size() > 0);
- size_t expectedAllocation = 0;
- for (const auto& texture : _textures) {
- expectedAllocation += texture->evalTotalSize();
+ auto reportLambda = [=] {
+ qDebug() << "Allowed " << gpu::Texture::getAllowedGPUMemoryUsage();
+ qDebug() << "Allocated " << gpu::Context::getTextureResourceGPUMemSize();
+ qDebug() << "Populated " << gpu::Context::getTextureResourcePopulatedGPUMemSize();
+ qDebug() << "Pending " << gpu::Context::getTexturePendingGPUTransferMemSize();
+ qDebug() << "State " << getTextureMemoryPressureModeString();
+ };
+
+ auto allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
+ auto populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
+
+ // Cycle frames we're fully allocated
+ // We need to use the texture rendering lambda
+ auto lastReport = usecTimestampNow();
+ auto start = usecTimestampNow();
+ qDebug() << "Awaiting texture allocation";
+ while (expectedAllocation != allocatedMemory) {
+ doEvery(lastReport, 4, reportLambda);
+ failAfter(start, FAIL_AFTER_SECONDS, "Failed to allocate texture memory");
+ renderFrame(renderTexturesLamdba);
+ allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
+ populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
+ }
+ reportLambda();
+ QCOMPARE(allocatedMemory, expectedAllocation);
+
+ // Restart the timer
+ start = usecTimestampNow();
+ // Cycle frames we're fully populated
+ qDebug() << "Awaiting texture population";
+ while (allocatedMemory != populatedMemory || 0 != gpu::Context::getTexturePendingGPUTransferMemSize()) {
+ doEvery(lastReport, 4, reportLambda);
+ failAfter(start, FAIL_AFTER_SECONDS, "Failed to populate texture memory");
+ renderFrame();
+ allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
+ populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
+ }
+ reportLambda();
+ QCOMPARE(populatedMemory, allocatedMemory);
+ // FIXME workaround a race condition in the difference between populated size and the actual _populatedMip value in the texture
+ for (size_t i = 0; i < textures.size(); ++i) {
+ renderFrame();
+ }
+
+ // Test on-demand deallocation of memory
+ auto maxMemory = allocatedMemory / 2;
+ gpu::Texture::setAllowedGPUMemoryUsage(maxMemory);
+
+ // Restart the timer
+ start = usecTimestampNow();
+ // Cycle frames until the allocated memory is below the max memory
+ qDebug() << "Awaiting texture deallocation";
+ while (allocatedMemory > maxMemory || allocatedMemory != populatedMemory) {
+ doEvery(lastReport, 4, reportLambda);
+ failAfter(start, FAIL_AFTER_SECONDS, "Failed to deallocate texture memory");
+ renderFrame(renderTexturesLamdba);
+ allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
+ populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
+ }
+ reportLambda();
+
+ // Verify that the allocation is now below the target
+ QVERIFY(allocatedMemory <= maxMemory);
+ // Verify that populated memory is the same as allocated memory
+ QCOMPARE(populatedMemory, allocatedMemory);
+
+ // Restart the timer
+ start = usecTimestampNow();
+ // Reset the max memory to automatic
+ gpu::Texture::setAllowedGPUMemoryUsage(0);
+ // Cycle frames we're fully populated
+ qDebug() << "Awaiting texture reallocation and repopulation";
+ while (allocatedMemory != expectedAllocation || allocatedMemory != populatedMemory) {
+ doEvery(lastReport, 4, reportLambda);
+ failAfter(start, FAIL_AFTER_SECONDS, "Failed to populate texture memory");
+ renderFrame();
+ allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
+ populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
+ }
+ reportLambda();
+ QCOMPARE(allocatedMemory, expectedAllocation);
+ QCOMPARE(populatedMemory, allocatedMemory);
+
+ textures.clear();
+ // Cycle frames we're fully populated
+ qDebug() << "Awaiting texture deallocation";
+ while (allocatedMemory != 0) {
+ failAfter(start, FAIL_AFTER_SECONDS, "Failed to clear texture memory");
+ renderFrame();
+ allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
+ populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
+ }
+ reportLambda();
+ QCOMPARE(allocatedMemory, 0);
+ QCOMPARE(populatedMemory, 0);
+ qDebug() << "Test took " << _frameCount << "frame";
}
- QVERIFY(_textures.size() > 0);
-
- auto reportLambda = [=] {
- qDebug() << "Allowed " << gpu::Texture::getAllowedGPUMemoryUsage();
- qDebug() << "Allocated " << gpu::Context::getTextureResourceGPUMemSize();
- qDebug() << "Populated " << gpu::Context::getTextureResourcePopulatedGPUMemSize();
- qDebug() << "Pending " << gpu::Context::getTexturePendingGPUTransferMemSize();
- };
-
- auto allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
- auto populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
-
- // Cycle frames we're fully allocated
- // We need to use the texture rendering lambda
- auto lastReport = usecTimestampNow();
- auto start = usecTimestampNow();
- while (expectedAllocation != allocatedMemory) {
- doEvery(lastReport, 4, reportLambda);
- failAfter(start, 10, "Failed to allocate texture memory after 10 seconds");
- renderFrame(renderTexturesLamdba);
- allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
- populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
- }
- QCOMPARE(allocatedMemory, expectedAllocation);
-
- // Restart the timer
- start = usecTimestampNow();
- // Cycle frames we're fully populated
- while (allocatedMemory != populatedMemory || 0 != gpu::Context::getTexturePendingGPUTransferMemSize()) {
- doEvery(lastReport, 4, reportLambda);
- failAfter(start, 10, "Failed to populate texture memory after 10 seconds");
- renderFrame();
- allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
- populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
- }
- reportLambda();
- QCOMPARE(populatedMemory, allocatedMemory);
-
- // FIXME workaround a race condition in the difference between populated size and the actual _populatedMip value in the texture
- for (size_t i = 0; i < _textures.size(); ++i) {
- renderFrame();
- }
-
- // Test on-demand deallocation of memory
- auto maxMemory = allocatedMemory / 2;
- gpu::Texture::setAllowedGPUMemoryUsage(maxMemory);
-
- // Restart the timer
- start = usecTimestampNow();
- // Cycle frames until the allocated memory is below the max memory
- while (allocatedMemory > maxMemory || allocatedMemory != populatedMemory) {
- doEvery(lastReport, 4, reportLambda);
- failAfter(start, 10, "Failed to deallocate texture memory after 10 seconds");
- renderFrame(renderTexturesLamdba);
- allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
- populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
- }
- reportLambda();
-
- // Verify that the allocation is now below the target
- QVERIFY(allocatedMemory <= maxMemory);
- // Verify that populated memory is the same as allocated memory
- QCOMPARE(populatedMemory, allocatedMemory);
-
- // Restart the timer
- start = usecTimestampNow();
- // Reset the max memory to automatic
- gpu::Texture::setAllowedGPUMemoryUsage(0);
- // Cycle frames we're fully populated
- while (allocatedMemory != expectedAllocation || allocatedMemory != populatedMemory) {
- doEvery(lastReport, 4, reportLambda);
- failAfter(start, 10, "Failed to populate texture memory after 10 seconds");
- renderFrame();
- allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
- populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
- }
- reportLambda();
- QCOMPARE(allocatedMemory, expectedAllocation);
- QCOMPARE(populatedMemory, allocatedMemory);
-
- _textures.clear();
- // Cycle frames we're fully populated
- while (allocatedMemory != 0) {
- failAfter(start, 10, "Failed to clear texture memory after 10 seconds");
- renderFrame();
- allocatedMemory = gpu::Context::getTextureResourceGPUMemSize();
- populatedMemory = gpu::Context::getTextureResourcePopulatedGPUMemSize();
- }
- QCOMPARE(allocatedMemory, 0);
- QCOMPARE(populatedMemory, 0);
qDebug() << "Done";
-
}
diff --git a/tests/gpu/src/TextureTest.h b/tests/gpu/src/TextureTest.h
index 91f8a358ea..2175300406 100644
--- a/tests/gpu/src/TextureTest.h
+++ b/tests/gpu/src/TextureTest.h
@@ -21,12 +21,15 @@ private:
void beginFrame();
void endFrame();
void renderFrame(const std::function& = [](gpu::Batch&) {});
+ std::vector loadTestTextures() const;
+
private slots:
void initTestCase();
void cleanupTestCase();
void testTextureLoading();
+
private:
QString _resourcesPath;
OffscreenGLCanvas _canvas;
@@ -36,5 +39,5 @@ private:
gpu::TexturePointer _colorBuffer, _depthBuffer;
const glm::uvec2 _size{ 640, 480 };
std::vector _textureFiles;
- std::vector _textures;
+ size_t _frameCount { 0 };
};
From ae07036f20bffcb8d4d1d59d1cc979e66394fffe Mon Sep 17 00:00:00 2001
From: Brad Davis
Date: Thu, 17 May 2018 14:29:06 -0700
Subject: [PATCH 78/80] Add ideal resource texture memory stat
---
interface/resources/qml/Stats.qml | 6 ++++--
interface/src/ui/Stats.cpp | 1 +
interface/src/ui/Stats.h | 9 +++++++++
libraries/gpu/src/gpu/Context.cpp | 5 +++++
libraries/gpu/src/gpu/Context.h | 2 ++
5 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml
index d961285a46..2406fa048d 100644
--- a/interface/resources/qml/Stats.qml
+++ b/interface/resources/qml/Stats.qml
@@ -281,10 +281,12 @@ Item {
text: " Pressure State: " + root.gpuTextureMemoryPressureState;
}
StatText {
- text: " Resource Allocated / Populated / Pending: ";
+ property bool showIdeal: (root.gpuTextureResourceIdealMemory != root.gpuTextureResourceMemory);
+ text: " Resource Allocated " + (showIdeal ? "(Ideal)" : "") + " / Populated / Pending: ";
}
StatText {
- text: " " + root.gpuTextureResourceMemory + " / " + root.gpuTextureResourcePopulatedMemory + " / " + root.texturePendingTransfers + " MB";
+ property bool showIdeal: (root.gpuTextureResourceIdealMemory != root.gpuTextureResourceMemory);
+ text: " " + root.gpuTextureResourceMemory + (showIdeal ? ("(" + root.gpuTextureResourceIdealMemory + ")") : "") + " / " + root.gpuTextureResourcePopulatedMemory + " / " + root.texturePendingTransfers + " MB";
}
StatText {
text: " Resident Memory: " + root.gpuTextureResidentMemory + " MB";
diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp
index d54faf8b28..9d86745341 100644
--- a/interface/src/ui/Stats.cpp
+++ b/interface/src/ui/Stats.cpp
@@ -354,6 +354,7 @@ void Stats::updateStats(bool force) {
STAT_UPDATE(gpuTextureResidentMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResidentGPUMemSize()));
STAT_UPDATE(gpuTextureFramebufferMemory, (int)BYTES_TO_MB(gpu::Context::getTextureFramebufferGPUMemSize()));
STAT_UPDATE(gpuTextureResourceMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResourceGPUMemSize()));
+ STAT_UPDATE(gpuTextureResourceIdealMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResourceIdealGPUMemSize()));
STAT_UPDATE(gpuTextureResourcePopulatedMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResourcePopulatedGPUMemSize()));
STAT_UPDATE(gpuTextureExternalMemory, (int)BYTES_TO_MB(gpu::Context::getTextureExternalGPUMemSize()));
#if !defined(Q_OS_ANDROID)
diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h
index 5c6a3db064..36e923261d 100644
--- a/interface/src/ui/Stats.h
+++ b/interface/src/ui/Stats.h
@@ -126,6 +126,7 @@ private: \
* @property {number} gpuTextureResidentMemory - Read-only.
* @property {number} gpuTextureFramebufferMemory - Read-only.
* @property {number} gpuTextureResourceMemory - Read-only.
+ * @property {number} gpuTextureResourceIdealMemory - Read-only.
* @property {number} gpuTextureResourcePopulatedMemory - Read-only.
* @property {number} gpuTextureExternalMemory - Read-only.
* @property {string} gpuTextureMemoryPressureState - Read-only.
@@ -270,6 +271,7 @@ class Stats : public QQuickItem {
STATS_PROPERTY(int, gpuTextureResidentMemory, 0)
STATS_PROPERTY(int, gpuTextureFramebufferMemory, 0)
STATS_PROPERTY(int, gpuTextureResourceMemory, 0)
+ STATS_PROPERTY(int, gpuTextureResourceIdealMemory, 0)
STATS_PROPERTY(int, gpuTextureResourcePopulatedMemory, 0)
STATS_PROPERTY(int, gpuTextureExternalMemory, 0)
STATS_PROPERTY(QString, gpuTextureMemoryPressureState, QString())
@@ -918,6 +920,13 @@ signals:
*/
void gpuTextureResourceMemoryChanged();
+ /**jsdoc
+ * Triggered when the value of the gpuTextureResourceIdealMemory property changes.
+ * @function Stats.gpuTextureResourceIdealMemoryChanged
+ * @returns {Signal}
+ */
+ void gpuTextureResourceIdealMemoryChanged();
+
/**jsdoc
* Triggered when the value of the gpuTextureResourcePopulatedMemory property changes.
* @function Stats.gpuTextureResourcePopulatedMemoryChanged
diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp
index 75c80a0164..ad2be7af5e 100644
--- a/libraries/gpu/src/gpu/Context.cpp
+++ b/libraries/gpu/src/gpu/Context.cpp
@@ -270,6 +270,7 @@ ContextMetricCount Backend::texturePendingGPUTransferCount;
ContextMetricSize Backend::texturePendingGPUTransferMemSize;
ContextMetricSize Backend::textureResourcePopulatedGPUMemSize;
+ContextMetricSize Backend::textureResourceIdealGPUMemSize;
Size Context::getFreeGPUMemSize() {
return Backend::freeGPUMemSize.getValue();
@@ -329,3 +330,7 @@ Size Context::getTexturePendingGPUTransferMemSize() {
Size Context::getTextureResourcePopulatedGPUMemSize() {
return Backend::textureResourcePopulatedGPUMemSize.getValue();
}
+
+Size Context::getTextureResourceIdealGPUMemSize() {
+ return Backend::textureResourceIdealGPUMemSize.getValue();
+}
diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h
index 8c5a4d493e..23c7edaff4 100644
--- a/libraries/gpu/src/gpu/Context.h
+++ b/libraries/gpu/src/gpu/Context.h
@@ -113,6 +113,7 @@ public:
static ContextMetricCount texturePendingGPUTransferCount;
static ContextMetricSize texturePendingGPUTransferMemSize;
static ContextMetricSize textureResourcePopulatedGPUMemSize;
+ static ContextMetricSize textureResourceIdealGPUMemSize;
protected:
@@ -243,6 +244,7 @@ public:
static Size getTexturePendingGPUTransferMemSize();
static Size getTextureResourcePopulatedGPUMemSize();
+ static Size getTextureResourceIdealGPUMemSize();
protected:
Context(const Context& context);
From 91f1d93d4e94598c87e4f82471e7d6b8309e4dfd Mon Sep 17 00:00:00 2001
From: Brad Davis
Date: Thu, 17 May 2018 14:32:14 -0700
Subject: [PATCH 79/80] Fix flicker while transferring texture data
---
.../src/gpu/gl/GLTextureTransfer.cpp | 34 +++++++++----------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp
index ae0a68e1e9..56da8927a4 100644
--- a/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp
+++ b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp
@@ -108,7 +108,7 @@ private:
// The buffering thread which drains the _activeBufferQueue and populates the _activeTransferQueue
TextureBufferThread* _transferThread{ nullptr };
// The amount of buffering work currently represented by the _activeBufferQueue
- size_t _queuedBufferSize{ 0 };
+ std::atomic _queuedBufferSize{ 0 };
// This contains a map of all textures to queues of pending transfer jobs. While in the transfer state, this map is used to
// populate the _activeBufferQueue up to the limit specified in GLVariableAllocationTexture::MAX_BUFFER_SIZE
TransferMap _pendingTransfersMap;
@@ -213,6 +213,7 @@ void GLTextureTransferEngineDefault::updateMemoryPressure() {
}
}
+ Backend::textureResourceIdealGPUMemSize.set(idealMemoryAllocation);
size_t unallocated = idealMemoryAllocation - totalVariableMemoryAllocation;
float pressure = (float)totalVariableMemoryAllocation / (float)allowedMemoryAllocation;
@@ -319,7 +320,6 @@ void GLTextureTransferEngineDefault::populateActiveBufferQueue() {
// Queue up buffering jobs
ActiveTransferQueue newBufferJobs;
- ActiveTransferQueue newTransferJobs;
size_t newTransferSize{ 0 };
for (auto itr = _pendingTransfersMap.begin(); itr != _pendingTransfersMap.end(); ) {
@@ -346,21 +346,17 @@ void GLTextureTransferEngineDefault::populateActiveBufferQueue() {
}
const auto& transferJob = textureTransferQueue.front();
- if (!transferJob->bufferingRequired()) {
- newTransferJobs.emplace_back(texture, transferJob);
- } else {
- const auto& transferSize = transferJob->size();
- // If there's not enough space for the buffering, then break out of the loop
- if (transferSize > availableBufferSize) {
- break;
- }
- availableBufferSize -= transferSize;
- Q_ASSERT(availableBufferSize <= MAX_BUFFER_SIZE);
- Q_ASSERT(newTransferSize <= MAX_BUFFER_SIZE);
- newTransferSize += transferSize;
- Q_ASSERT(newTransferSize <= MAX_BUFFER_SIZE);
- newBufferJobs.emplace_back(texture, transferJob);
+ const auto& transferSize = transferJob->size();
+ // If there's not enough space for the buffering, then break out of the loop
+ if (transferSize > availableBufferSize) {
+ break;
}
+ availableBufferSize -= transferSize;
+ Q_ASSERT(availableBufferSize <= MAX_BUFFER_SIZE);
+ Q_ASSERT(newTransferSize <= MAX_BUFFER_SIZE);
+ newTransferSize += transferSize;
+ Q_ASSERT(newTransferSize <= MAX_BUFFER_SIZE);
+ newBufferJobs.emplace_back(texture, transferJob);
textureTransferQueue.pop();
++itr;
}
@@ -371,7 +367,6 @@ void GLTextureTransferEngineDefault::populateActiveBufferQueue() {
Q_ASSERT(_queuedBufferSize <= MAX_BUFFER_SIZE);
_queuedBufferSize += newTransferSize;
Q_ASSERT(_queuedBufferSize <= MAX_BUFFER_SIZE);
- _activeTransferQueue.splice(_activeTransferQueue.end(), newTransferJobs);
}
}
@@ -389,6 +384,11 @@ bool GLTextureTransferEngineDefault::processActiveBufferQueue() {
for (const auto& activeJob : activeBufferQueue) {
const auto& texture = activeJob.first;
const auto& transferJob = activeJob.second;
+ // Some jobs don't require buffering, but they pass through this queue to ensure that we don't re-order
+ // the buffering & transfer operations. All jobs in the queue must be processed in order.
+ if (!transferJob->bufferingRequired()) {
+ continue;
+ }
const auto& transferSize = transferJob->size();
transferJob->buffer(texture);
Q_ASSERT(_queuedBufferSize >= transferSize);
From 3356486f277169db83eecb9cdda223695c756b75 Mon Sep 17 00:00:00 2001
From: Brad Davis
Date: Thu, 17 May 2018 14:33:46 -0700
Subject: [PATCH 80/80] Fix populated texture size tracking
---
.../gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp | 6 +++---
.../gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp | 2 +-
.../gpu/gl45/GL45BackendVariableTexture.cpp | 18 +++++++++---------
.../src/gpu/gles/GLESBackendTexture.cpp | 6 +++---
4 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp
index 624cb4f656..00f7ae284f 100644
--- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp
+++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendTexture.cpp
@@ -338,8 +338,7 @@ Size GL41VariableAllocationTexture::copyMipsFromTexture() {
amount += copyMipFaceFromTexture(sourceMip, targetMip, face);
}
}
-
-
+ incrementPopulatedSize(amount);
return amount;
}
@@ -348,7 +347,6 @@ Size GL41VariableAllocationTexture::copyMipFaceLinesFromTexture(uint16_t mip, ui
withPreservedTexture([&] {
amountCopied = Parent::copyMipFaceLinesFromTexture(mip, face, size, yOffset, internalFormat, format, type, sourceSize, sourcePointer);
});
- incrementPopulatedSize(amountCopied);
return amountCopied;
}
@@ -609,6 +607,8 @@ void GL41VariableAllocationTexture::populateTransferQueue(TransferQueue& pending
// queue up the sampler and populated mip change for after the transfer has completed
pendingTransfers.emplace(new TransferJob([=] {
_populatedMip = sourceMip;
+ incrementPopulatedSize(_gpuObject.evalMipSize(sourceMip));
+ sanityCheck();
syncSampler();
}));
} while (sourceMip != _allocatedMip);
diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp
index b0ae1296e9..558f221705 100644
--- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp
+++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp
@@ -123,7 +123,7 @@ GLTexture* GL45Backend::syncGPUObject(const TexturePointer& texturePointer) {
}
void GL45Backend::initTextureManagementStage() {
- GLBackend::initTextureManagementStage();
+ GLBackend::initTextureManagementStage();
// enable the Sparse Texture on gl45
_textureManagement._sparseCapable = true;
diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp
index fe74336b2a..713b99fc77 100644
--- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp
+++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendVariableTexture.cpp
@@ -54,7 +54,6 @@ const GL45Texture::Bindless& GL45VariableAllocationTexture::getBindless() const
Size GL45VariableAllocationTexture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const {
Size amountCopied = 0;
amountCopied = Parent::copyMipFaceLinesFromTexture(mip, face, size, yOffset, internalFormat, format, type, sourceSize, sourcePointer);
- incrementPopulatedSize(amountCopied);
return amountCopied;
}
@@ -81,7 +80,6 @@ void GL45VariableAllocationTexture::copyTextureMipsInGPUMem(GLuint srcId, GLuint
copyTexGPUMem(_gpuObject, _target, srcId, destId, numMips, srcMipOffset, destMipOffset, populatedMips);
}
-
// Managed size resource textures
using GL45ResourceTexture = GL45Backend::GL45ResourceTexture;
@@ -132,6 +130,7 @@ Size GL45ResourceTexture::copyMipsFromTexture() {
amount += copyMipFaceFromTexture(sourceMip, targetMip, face);
}
}
+ incrementPopulatedSize(amount);
return amount;
}
@@ -139,7 +138,7 @@ void GL45ResourceTexture::syncSampler() const {
Parent::syncSampler();
#if GPU_BINDLESS_TEXTURES
if (!isBindless()) {
- glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, _populatedMip - _allocatedMip);
+ glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, _populatedMip - _allocatedMip);
}
#else
glTextureParameteri(_id, GL_TEXTURE_BASE_LEVEL, _populatedMip - _allocatedMip);
@@ -169,7 +168,7 @@ size_t GL45ResourceTexture::promote() {
// allocate storage for new level
allocateStorage(targetAllocatedMip);
-
+
// copy pre-existing mips
copyTextureMipsInGPUMem(oldId, _id, oldAllocatedMip, _allocatedMip, _populatedMip);
@@ -230,14 +229,14 @@ size_t GL45ResourceTexture::demote() {
// update the memory usage
Backend::textureResourceGPUMemSize.update(oldSize, 0);
- // Demoting unpopulate the memory delta
+ // Demoting unpopulate the memory delta
if (oldPopulatedMip != _populatedMip) {
auto numPopulatedDemoted = _populatedMip - oldPopulatedMip;
Size amountUnpopulated = 0;
for (int i = 0; i < numPopulatedDemoted; i++) {
- amountUnpopulated += _gpuObject.evalMipSize(oldPopulatedMip + i);
+ amountUnpopulated += _gpuObject.evalMipSize(oldPopulatedMip + i);
}
- decrementPopulatedSize(amountUnpopulated);
+ decrementPopulatedSize(amountUnpopulated);
}
return (oldSize - _size);
}
@@ -268,12 +267,12 @@ void GL45ResourceTexture::populateTransferQueue(TransferQueue& pendingTransfers)
continue;
}
- // break down the transfers into chunks so that no single transfer is
+ // break down the transfers into chunks so that no single transfer is
// consuming more than X bandwidth
// For compressed format, regions must be a multiple of the 4x4 tiles, so enforce 4 lines as the minimum block
auto mipSize = _gpuObject.getStoredMipFaceSize(sourceMip, face);
const auto lines = mipDimensions.y;
- const uint32_t BLOCK_NUM_LINES { 4 };
+ const uint32_t BLOCK_NUM_LINES{ 4 };
const auto numBlocks = (lines + (BLOCK_NUM_LINES - 1)) / BLOCK_NUM_LINES;
auto bytesPerBlock = mipSize / numBlocks;
Q_ASSERT(0 == (mipSize % lines));
@@ -289,6 +288,7 @@ void GL45ResourceTexture::populateTransferQueue(TransferQueue& pendingTransfers)
// queue up the sampler and populated mip change for after the transfer has completed
pendingTransfers.emplace(new TransferJob([=] {
_populatedMip = sourceMip;
+ incrementPopulatedSize(_gpuObject.evalMipSize(sourceMip));
sanityCheck();
syncSampler();
}));
diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp
index 2ffa421bc8..7419221889 100644
--- a/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp
+++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendTexture.cpp
@@ -401,8 +401,7 @@ Size GLESVariableAllocationTexture::copyMipsFromTexture() {
amount += copyMipFaceFromTexture(sourceMip, targetMip, face);
}
}
-
-
+ incrementPopulatedSize(amount);
return amount;
}
@@ -411,7 +410,6 @@ Size GLESVariableAllocationTexture::copyMipFaceLinesFromTexture(uint16_t mip, ui
withPreservedTexture([&] {
amountCopied = Parent::copyMipFaceLinesFromTexture(mip, face, size, yOffset, internalFormat, format, type, sourceSize, sourcePointer);
});
- incrementPopulatedSize(amountCopied);
return amountCopied;
}
@@ -673,6 +671,8 @@ void GLESVariableAllocationTexture::populateTransferQueue(TransferJob::Queue& qu
// queue up the sampler and populated mip change for after the transfer has completed
queue.emplace(new TransferJob([=] {
_populatedMip = sourceMip;
+ incrementPopulatedSize(_gpuObject.evalMipSize(sourceMip));
+ sanityCheck();
syncSampler();
}));
} while (sourceMip != _allocatedMip);