Merge \\\\"gfx: change VSYNC from 60fps to 30fps\\\\" into cw-e-dev am: 2b28f717ce am: 0de801ec62 am: b87fdd911a
am: ca936c659d

Change-Id: I6f64381526dcfd9053aa49de3097b556f41c3479
diff --git a/merrifield/common/devices/PhysicalDevice.cpp b/merrifield/common/devices/PhysicalDevice.cpp
index 601b63e..f4072a7 100644
--- a/merrifield/common/devices/PhysicalDevice.cpp
+++ b/merrifield/common/devices/PhysicalDevice.cpp
@@ -17,6 +17,7 @@
 #include <Hwcomposer.h>
 #include <Drm.h>
 #include <PhysicalDevice.h>
+#include <cutils/properties.h>
 
 namespace android {
 namespace intel {
@@ -32,7 +33,8 @@
       mConnected(false),
       mBlank(false),
       mDisplayState(DEVICE_DISPLAY_ON),
-      mInitialized(false)
+      mInitialized(false),
+      mFpsDivider(1)
 {
     CTRACE();
 
@@ -341,7 +343,8 @@
         // don't bail out as it is not a fatal error
     }
     // use active fb dimension as config width/height
-    DisplayConfig *config = new DisplayConfig(mode.vrefresh,
+    // add display config vfresh/mFpsDivider to lower FPS
+    DisplayConfig *config = new DisplayConfig(mode.vrefresh/mFpsDivider,
                                               mode.hdisplay,
                                               mode.vdisplay,
                                               dpiX, dpiY);
@@ -395,6 +398,16 @@
 bool PhysicalDevice::initialize()
 {
     CTRACE();
+    char prop[PROPERTY_VALUE_MAX];
+    char *retptr;
+
+    if (property_get("hwc.fps_divider", prop, "1") > 0) {
+        uint32_t divider = strtoul(prop, &retptr, 10);
+        if (*retptr == '\0' && divider > 1 && divider < 60) {
+            mFpsDivider = divider;
+            ALOGI("%s display, setting HWC FPS divider to %d", mName, mFpsDivider);
+        }
+    }
 
     if (mType != DEVICE_PRIMARY && mType != DEVICE_EXTERNAL) {
         ETRACE("invalid device type");
@@ -509,6 +522,11 @@
         mLayerList->dump(d);
 }
 
+uint32_t PhysicalDevice::getFpsDivider()
+{
+    return mFpsDivider;
+}
+
 bool PhysicalDevice::setPowerMode(int mode)
 {
     // TODO: set proper power modes for HWC 1.4
diff --git a/merrifield/common/devices/VirtualDevice.cpp b/merrifield/common/devices/VirtualDevice.cpp
index 965c633..4e9ad83 100755
--- a/merrifield/common/devices/VirtualDevice.cpp
+++ b/merrifield/common/devices/VirtualDevice.cpp
@@ -653,7 +653,8 @@
       mLastConnectionStatus(false),
       mCachedBufferCapcity(16),
       mDecWidth(0),
-      mDecHeight(0)
+      mDecHeight(0),
+      mFpsDivider(1)
 {
     CTRACE();
 #ifdef INTEL_WIDI
@@ -2218,6 +2219,17 @@
 {
     mRgbLayer = -1;
     mYuvLayer = -1;
+    char prop[PROPERTY_VALUE_MAX];
+    char *retptr;
+
+    if (property_get("hwc.fps_divider", prop, "1") > 0) {
+        uint32_t divider = strtoul(prop, &retptr, 10);
+        if (*retptr == '\0' && divider > 1 && divider < 60) {
+            mFpsDivider = divider;
+            ALOGI("Virtual display, setting HWC FPS divider to %d", mFpsDivider);
+        }
+    }
+
 #ifdef INTEL_WIDI
     // Add initialization codes here. If init fails, invoke DEINIT_AND_RETURN_FALSE();
     mNextConfig.typeChangeListener = NULL;
@@ -2308,6 +2320,11 @@
 {
 }
 
+uint32_t VirtualDevice::getFpsDivider()
+{
+    return mFpsDivider;
+}
+
 void VirtualDevice::deinitialize()
 {
     VAStatus va_status;
diff --git a/merrifield/common/observers/SoftVsyncObserver.cpp b/merrifield/common/observers/SoftVsyncObserver.cpp
index 20a6bdf..27e78dd 100644
--- a/merrifield/common/observers/SoftVsyncObserver.cpp
+++ b/merrifield/common/observers/SoftVsyncObserver.cpp
@@ -53,7 +53,7 @@
 
     mExitThread = false;
     mEnabled = false;
-    mRefreshRate = 60;
+    mRefreshRate = 60/mDisplayDevice.getFpsDivider();
     mDevice = mDisplayDevice.getType();
     mThread = new VsyncEventPollThread(this);
     if (!mThread.get()) {
@@ -122,7 +122,7 @@
     }
 
 
-    const nsecs_t period = mRefreshPeriod;
+    const nsecs_t period = mRefreshPeriod * mDisplayDevice.getFpsDivider();
     const nsecs_t now = systemTime(CLOCK_MONOTONIC);
     nsecs_t next_vsync = mNextFakeVSync;
     nsecs_t sleep = next_vsync - now;
diff --git a/merrifield/common/observers/VsyncEventObserver.cpp b/merrifield/common/observers/VsyncEventObserver.cpp
index b7a6fa3..f25adb2 100644
--- a/merrifield/common/observers/VsyncEventObserver.cpp
+++ b/merrifield/common/observers/VsyncEventObserver.cpp
@@ -28,7 +28,8 @@
       mDevice(IDisplayDevice::DEVICE_COUNT),
       mEnabled(false),
       mExitThread(false),
-      mInitialized(false)
+      mInitialized(false),
+      mFpsCounter(0)
 {
     CTRACE();
 }
@@ -126,8 +127,9 @@
             return true;
         }
 
-        // notify device
-        mDisplayDevice.onVsync(timestamp);
+        // send vsync event notification every hwc.fps_divider
+        if ((mFpsCounter++) % mDisplayDevice.getFpsDivider() == 0)
+            mDisplayDevice.onVsync(timestamp);
     }
 
     return true;
diff --git a/merrifield/common/observers/VsyncEventObserver.h b/merrifield/common/observers/VsyncEventObserver.h
index 36cb99f..e5f10b7 100644
--- a/merrifield/common/observers/VsyncEventObserver.h
+++ b/merrifield/common/observers/VsyncEventObserver.h
@@ -43,6 +43,7 @@
     bool mEnabled;
     bool mExitThread;
     bool mInitialized;
+    unsigned int mFpsCounter;
 
 private:
     DECLARE_THREAD(VsyncEventPollThread, VsyncEventObserver);
diff --git a/merrifield/include/IDisplayDevice.h b/merrifield/include/IDisplayDevice.h
index ad99a2f..9c9a04c 100644
--- a/merrifield/include/IDisplayDevice.h
+++ b/merrifield/include/IDisplayDevice.h
@@ -97,6 +97,7 @@
     virtual int getType() const = 0;
     virtual void onVsync(int64_t timestamp) = 0;
     virtual void dump(Dump& d) = 0;
+    virtual uint32_t getFpsDivider() = 0;
 };
 
 }
diff --git a/merrifield/include/PhysicalDevice.h b/merrifield/include/PhysicalDevice.h
index 9bbb90d..9a1fd52 100644
--- a/merrifield/include/PhysicalDevice.h
+++ b/merrifield/include/PhysicalDevice.h
@@ -76,6 +76,7 @@
     virtual bool isConnected() const;
     virtual const char* getName() const;
     virtual int getType() const;
+    virtual uint32_t getFpsDivider();
 
     //events
     virtual void onVsync(int64_t timestamp);
@@ -115,6 +116,7 @@
     // DPMS on (1) or off (0)
     int mDisplayState;
     bool mInitialized;
+    uint32_t mFpsDivider;
 };
 
 
diff --git a/merrifield/include/VirtualDevice.h b/merrifield/include/VirtualDevice.h
index a2ae7d4..5b1ae63 100755
--- a/merrifield/include/VirtualDevice.h
+++ b/merrifield/include/VirtualDevice.h
@@ -199,6 +199,7 @@
     virtual int getType() const;
     virtual void onVsync(int64_t timestamp);
     virtual void dump(Dump& d);
+    virtual uint32_t getFpsDivider();
 #ifdef INTEL_WIDI
     // IFrameServer methods
     virtual android::status_t start(sp<IFrameTypeChangeListener> frameTypeChangeListener);
@@ -224,6 +225,7 @@
     uint32_t mDecWidth;
     uint32_t mDecHeight;
     bool mIsForceCloneMode;
+    uint32_t mFpsDivider;
 };
 
 }