From f1d4a2087c9adc9d5f6e5e831f835af28d2ee7a3 Mon Sep 17 00:00:00 2001 From: chaochen Date: Mon, 15 Jun 2015 17:24:49 -0700 Subject: [PATCH 1/3] Fix flickering and allow user to set/get refresh frequency of this GVRTextViewSceneObject. Fix flickering while more than a certain number of GVRTextViewSceneObject within a Scene. Actually the problem is caused by the limitation of SurfaceTexture's performance. If we are trying to refresh many SurfaceTextures within a frame, then it will cause latency issue which finally turns out to be the flickering. The patch is something like a load balancer so that we distribute the refresh() calls into interval frames instead of calling them within one frame. And only if the textview is changed, we trigger the refresh(). The default interval is 30 and I changed it to 20, and allow user to set the frequency of 3 levels based on their needs. --- .../scene_objects/GVRTextViewSceneObject.java | 84 ++++++++++++++++++- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java b/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java index 47d510104..d24eb626e 100644 --- a/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java +++ b/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java @@ -39,7 +39,32 @@ import android.widget.TextView; public class GVRTextViewSceneObject extends GVRSceneObject { - private static final int REFRESH_INTERVAL = 30; // frames + private static final int HIGH_REFRESH_INTERVAL = 10; // frames + private static final int MEDIUM_REFRESH_INTERVAL = 20; + private static final int LOW_REFRESH_INTERVAL = 30; + + /** + * The refresh frequency of this sceneobject. + */ + public static enum IntervalFrequency { + /* + * Frequency HIGH, means do refresh every 10 frames + */ + HIGH, + /* + * Frequency MEDIUM, means do refresh every 20 frames + */ + MEDIUM, + /* + * Frequency MEDIUM, means do refresh every 20 frames + */ + LOW + } + + private static int sReferenceCounter = 0; + private boolean mFirstFrame; + private boolean mIsChanged; + private int mRefreshInterval = MEDIUM_REFRESH_INTERVAL; private static final int DEFAULT_WIDTH = 2000; private static final int DEFAULT_HEIGHT = 1000; @@ -103,6 +128,9 @@ public GVRTextViewSceneObject(GVRContext gvrContext, GVRMesh mesh, mSurface = new Surface(mSurfaceTexture); mSurfaceTexture.setDefaultBufferSize(mTextViewContainer.getWidth(), mTextViewContainer.getHeight()); + sReferenceCounter++; + mCount = sReferenceCounter; + mFirstFrame = true; } /** @@ -231,6 +259,7 @@ public GVRTextViewSceneObject(GVRContext gvrContext, GVRActivity gvrActivity) { */ public void setTextSize(float size) { mTextView.setTextSize(size); + mIsChanged = true; } /** @@ -251,6 +280,7 @@ public float getTextSize() { */ public void setTextColor(int color) { mTextView.setTextColor(color); + mIsChanged = true; } /** @@ -261,6 +291,7 @@ public void setTextColor(int color) { */ public void setText(CharSequence text) { mTextView.setText(text); + mIsChanged = true; } /** @@ -293,6 +324,7 @@ public String getTextString() { */ public void setBackgroundColor(int color) { mTextViewContainer.setBackgroundColor(color); + mIsChanged = true; } /** @@ -304,6 +336,7 @@ public void setBackgroundColor(int color) { */ public void setBackGround(Drawable drawable) { mTextViewContainer.setBackground(drawable); + mIsChanged = true; } /** @@ -324,6 +357,7 @@ public Drawable getBackGround() { */ public void setGravity(int gravity) { mTextView.setGravity(gravity); + mIsChanged = true; } /** @@ -335,12 +369,56 @@ public int getGravity() { return mTextView.getGravity(); } + /** + * Set the refresh frequency of this scene object. + * + * @param frequency + * The refresh frequency of this TextViewSceneObject. + */ + public void setRefreshFrequency(IntervalFrequency frequency) { + switch (frequency) { + case HIGH: + mRefreshInterval = HIGH_REFRESH_INTERVAL; + break; + case MEDIUM: + mRefreshInterval = MEDIUM_REFRESH_INTERVAL; + break; + case LOW: + mRefreshInterval = LOW_REFRESH_INTERVAL; + break; + default: + break; + } + } + + /** + * Get the refresh frequency of this scene object. + * + * @return The refresh frequency of this TextViewSceneObject. + */ + + public IntervalFrequency getRefreshFrequency() { + switch (mRefreshInterval) { + case 10: + return IntervalFrequency.HIGH; + case 20: + return IntervalFrequency.MEDIUM; + default: + return IntervalFrequency.LOW; + } + } + private final GVRDrawFrameListener mFrameListener = new GVRDrawFrameListener() { @Override public void onDrawFrame(float frameTime) { - if (++mCount > REFRESH_INTERVAL) { + if (mFirstFrame || (++mCount % mRefreshInterval == 0 && mIsChanged)) { refresh(); - mCount = 0; + if (!mFirstFrame) { + mCount = 0; + } else { + mFirstFrame = false; + } + mIsChanged = false; } } }; From 40bf786e89707aae9066c502d1da659f030dd62b Mon Sep 17 00:00:00 2001 From: chaochen Date: Wed, 17 Jun 2015 15:25:07 -0700 Subject: [PATCH 2/3] Fix typo on GVRTextViewSceneObject and modify textview sample a little bit. --- .../scene_objects/GVRTextViewSceneObject.java | 4 +- .../gvrtextviewsample/SampleViewManager.java | 47 +++++++++++++------ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java b/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java index d24eb626e..6f57283ea 100644 --- a/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java +++ b/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java @@ -56,12 +56,12 @@ public static enum IntervalFrequency { */ MEDIUM, /* - * Frequency MEDIUM, means do refresh every 20 frames + * Frequency MEDIUM, means do refresh every 30 frames */ LOW } - private static int sReferenceCounter = 0; + private static int sReferenceCounter = 0;// This is for load balancing. private boolean mFirstFrame; private boolean mIsChanged; private int mRefreshInterval = MEDIUM_REFRESH_INTERVAL; diff --git a/GVRf/Sample/gvrtextviewsample/src/org/gearvrf/gvrtextviewsample/SampleViewManager.java b/GVRf/Sample/gvrtextviewsample/src/org/gearvrf/gvrtextviewsample/SampleViewManager.java index baaea196e..f2d9f68e6 100755 --- a/GVRf/Sample/gvrtextviewsample/src/org/gearvrf/gvrtextviewsample/SampleViewManager.java +++ b/GVRf/Sample/gvrtextviewsample/src/org/gearvrf/gvrtextviewsample/SampleViewManager.java @@ -15,9 +15,13 @@ package org.gearvrf.gvrtextviewsample; +import java.util.ArrayList; +import java.util.Random; + import org.gearvrf.GVRContext; import org.gearvrf.GVRScript; import org.gearvrf.scene_objects.GVRTextViewSceneObject; +import org.gearvrf.scene_objects.GVRTextViewSceneObject.IntervalFrequency; import android.graphics.Color; import android.widget.LinearLayout; @@ -32,8 +36,14 @@ public class SampleViewManager extends GVRScript { "veryverygood", "veryverygood", "veryveryverygood" }; private final int[] colors = new int[] { Color.RED, Color.YELLOW, Color.GREEN, Color.WHITE, Color.MAGENTA }; + private final IntervalFrequency[] frequencies = new IntervalFrequency[] { + IntervalFrequency.HIGH, IntervalFrequency.MEDIUM, + IntervalFrequency.LOW }; private float textSize; private int counter = 0; + Random random = new Random(); + + ArrayList textviews = new ArrayList(); SampleViewManager(SampleActivity activity) { mActivity = activity; @@ -41,26 +51,35 @@ public class SampleViewManager extends GVRScript { @Override public void onInit(GVRContext gvrContext) { - sceneObject = new GVRTextViewSceneObject(gvrContext, mActivity); - textSize = sceneObject.getTextSize(); - - // set the scene object position - sceneObject.getTransform().setPosition(0.0f, 0.0f, -2.0f); + for (int i = 0; i < 5; i++) { + sceneObject = new GVRTextViewSceneObject(gvrContext, mActivity); + textSize = sceneObject.getTextSize(); - // add the scene object to the scene graph - gvrContext.getNextMainScene().addSceneObject(sceneObject); + // set the scene object position + float x = i * 2.0f;// i * 2.0f - 4.0f; + sceneObject.getTransform().setPosition(x - 4.0f, 0.0f, -2.0f); + sceneObject.setText(strings[i]); + sceneObject.setTextColor(colors[i]); + sceneObject.setTextSize(textSize * (i + 1) / 2); + sceneObject.setRefreshFrequency(frequencies[i % 3]); + // add the scene object to the scene graph + gvrContext.getNextMainScene().addSceneObject(sceneObject); + sceneObject.getTransform().setPositionZ(-3.0f); + textviews.add(sceneObject); + } } @Override public void onStep() { counter++; - if (counter % 50 == 0) { - int currentState = (counter / 50) % 5; - - sceneObject.setText(strings[currentState]); - sceneObject.setTextColor(colors[currentState]); - sceneObject.setTextSize(textSize * (currentState + 1) / 2); + if(counter % 10 == 0){ + int viewIndex = random.nextInt(5); + sceneObject = textviews.get(viewIndex); + int colorIndex = random.nextInt(5); + sceneObject.setTextColor(colors[colorIndex]); +// int contentIndex = random.nextInt(5); +// sceneObject.setText(strings[contentIndex]); } } -} +} \ No newline at end of file From c1cdc1d518f6c4be586fdfbdbd341632696cae30 Mon Sep 17 00:00:00 2001 From: chaochen Date: Wed, 17 Jun 2015 16:38:45 -0700 Subject: [PATCH 3/3] More fix on wording. --- .../scene_objects/GVRTextViewSceneObject.java | 14 +++++++------- .../gvrtextviewsample/SampleViewManager.java | 4 ---- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java b/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java index 6f57283ea..1215beab6 100644 --- a/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java +++ b/GVRf/Framework/src/org/gearvrf/scene_objects/GVRTextViewSceneObject.java @@ -48,15 +48,15 @@ public class GVRTextViewSceneObject extends GVRSceneObject { */ public static enum IntervalFrequency { /* - * Frequency HIGH, means do refresh every 10 frames + * Frequency HIGH, means will do refresh every 10 frames */ HIGH, /* - * Frequency MEDIUM, means do refresh every 20 frames + * Frequency MEDIUM, means will do refresh every 20 frames */ MEDIUM, /* - * Frequency MEDIUM, means do refresh every 30 frames + * Frequency LOW, means will do refresh every 30 frames */ LOW } @@ -399,12 +399,12 @@ public void setRefreshFrequency(IntervalFrequency frequency) { public IntervalFrequency getRefreshFrequency() { switch (mRefreshInterval) { - case 10: + case HIGH_REFRESH_INTERVAL: return IntervalFrequency.HIGH; - case 20: - return IntervalFrequency.MEDIUM; - default: + case LOW_REFRESH_INTERVAL: return IntervalFrequency.LOW; + default: + return IntervalFrequency.MEDIUM; } } diff --git a/GVRf/Sample/gvrtextviewsample/src/org/gearvrf/gvrtextviewsample/SampleViewManager.java b/GVRf/Sample/gvrtextviewsample/src/org/gearvrf/gvrtextviewsample/SampleViewManager.java index f2d9f68e6..d42c6d005 100755 --- a/GVRf/Sample/gvrtextviewsample/src/org/gearvrf/gvrtextviewsample/SampleViewManager.java +++ b/GVRf/Sample/gvrtextviewsample/src/org/gearvrf/gvrtextviewsample/SampleViewManager.java @@ -29,9 +29,7 @@ public class SampleViewManager extends GVRScript { GVRTextViewSceneObject sceneObject; - LinearLayout mTextView; SampleActivity mActivity; - boolean init = false; private final String[] strings = new String[] { "good", "verygood", "veryverygood", "veryverygood", "veryveryverygood" }; private final int[] colors = new int[] { Color.RED, Color.YELLOW, @@ -77,8 +75,6 @@ public void onStep() { sceneObject = textviews.get(viewIndex); int colorIndex = random.nextInt(5); sceneObject.setTextColor(colors[colorIndex]); -// int contentIndex = random.nextInt(5); -// sceneObject.setText(strings[contentIndex]); } }