hwc: Clean up ExternalDisplay class

1. Remove hwc_context_t from libexternal since this is a construct
   that should only be used in libhwcomposer.
2. Clean up redundant code by creating utility functions to
   a. open a sysfs node in a given mode
   b. improving EDID mode storage/manipulation
   c. creating/destroying composition objects
3. Add utility functions to
   a. get the connected state of the external display
   b. determine which interface the external display is connected to
      (primary or external)
   c. activate the hdmi interface by setting the resolution via an
      ioctl
   d. update/reset external display information when a device
      connected/disconnected

Change-Id: Iba34c9e43b39ccb9c9436deb726587bd1b26b779
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index c535c5e..821bfa9 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -38,24 +38,6 @@
 #define HWC_UEVENT_SWITCH_STR  "change@/devices/virtual/switch/"
 #define HWC_UEVENT_THREAD_NAME "hwcUeventThread"
 
-static void setup(hwc_context_t* ctx, int dpy)
-{
-    ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx, dpy);
-    ctx->mMDPComp[dpy] =  MDPComp::getObject(ctx, dpy);
-}
-
-static void clear(hwc_context_t* ctx, int dpy)
-{
-    if(ctx->mFBUpdate[dpy]) {
-        delete ctx->mFBUpdate[dpy];
-        ctx->mFBUpdate[dpy] = NULL;
-    }
-    if(ctx->mMDPComp[dpy]) {
-        delete ctx->mMDPComp[dpy];
-        ctx->mMDPComp[dpy] = NULL;
-    }
-}
-
 /* Parse uevent data for devices which we are interested */
 static int getConnectedDisplay(const char* strUdata)
 {
@@ -126,13 +108,9 @@
             }
 
             Locker::Autolock _l(ctx->mDrawLock);
-            clear(ctx, dpy);
-            ctx->dpyAttr[dpy].connected = false;
-            ctx->dpyAttr[dpy].isActive = false;
-            /* If disconnect comes before any composition cycle */
-            ctx->dpyAttr[dpy].isConfiguring = false;
-
+            destroyCompositionResources(ctx, dpy);
             ctx->mExtDisplay->teardown();
+            resetDisplayInfo(ctx, dpy);
 
             /* We need to send hotplug to SF only when we are disconnecting
              * HDMI */
@@ -186,9 +164,11 @@
                 ctx->mWfdSyncLock.unlock();
             }
             ctx->mExtDisplay->configure();
+            ctx->mExtDisplay->activateDisplay();
 
             Locker::Autolock _l(ctx->mDrawLock);
-            setup(ctx, dpy);
+            updateDisplayInfo(ctx, dpy);
+            initCompositionResources(ctx, dpy);
             ctx->dpyAttr[dpy].isPause = false;
             ctx->dpyAttr[dpy].connected = true;
             ctx->dpyAttr[dpy].isConfiguring = true;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index a11baa9..a477fc0 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -112,6 +112,47 @@
     }
 }
 
+// Initialize external display attributes based on
+// external display class state
+void updateDisplayInfo(hwc_context_t* ctx, int dpy) {
+    ctx->dpyAttr[dpy].fd = ctx->mExtDisplay->getFd();
+    ctx->dpyAttr[dpy].xres = ctx->mExtDisplay->getWidth();
+    ctx->dpyAttr[dpy].yres = ctx->mExtDisplay->getHeight();
+    ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mExtDisplay->getMDPScalingMode();
+    ctx->dpyAttr[dpy].vsync_period = ctx->mExtDisplay->getVsyncPeriod();
+    ctx->mViewFrame[dpy].left = 0;
+    ctx->mViewFrame[dpy].top = 0;
+    ctx->mViewFrame[dpy].right = ctx->dpyAttr[dpy].xres;
+    ctx->mViewFrame[dpy].bottom = ctx->dpyAttr[dpy].yres;
+}
+
+// Reset external display attributes and list stats structures
+void resetDisplayInfo(hwc_context_t* ctx, int dpy) {
+    memset(&(ctx->dpyAttr[dpy]), 0, sizeof(ctx->dpyAttr[dpy]));
+    memset(&(ctx->listStats[dpy]), 0, sizeof(ctx->listStats[dpy]));
+    // We reset the fd to -1 here but External display class is responsible
+    // for it when the display is disconnected. This is handled as part of
+    // EXTERNAL_OFFLINE event.
+    ctx->dpyAttr[dpy].fd = -1;
+}
+
+// Initialize composition resources
+void initCompositionResources(hwc_context_t* ctx, int dpy) {
+    ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx, dpy);
+    ctx->mMDPComp[dpy] = MDPComp::getObject(ctx, dpy);
+}
+
+void destroyCompositionResources(hwc_context_t* ctx, int dpy) {
+    if(ctx->mFBUpdate[dpy]) {
+        delete ctx->mFBUpdate[dpy];
+        ctx->mFBUpdate[dpy] = NULL;
+    }
+    if(ctx->mMDPComp[dpy]) {
+        delete ctx->mMDPComp[dpy];
+        ctx->mMDPComp[dpy] = NULL;
+    }
+}
+
 static int openFramebufferDevice(hwc_context_t *ctx)
 {
     struct fb_fix_screeninfo finfo;
@@ -202,11 +243,8 @@
     ctx->mOverlay = overlay::Overlay::getInstance();
     ctx->mRotMgr = RotMgr::getInstance();
 
-    //Is created and destroyed only once for primary
-    //For external it could get created and destroyed multiple times depending
-    //on what external we connect to.
-    ctx->mFBUpdate[HWC_DISPLAY_PRIMARY] =
-        IFBUpdate::getObject(ctx, HWC_DISPLAY_PRIMARY);
+    // Initialize composition objects for the primary display
+    initCompositionResources(ctx, HWC_DISPLAY_PRIMARY);
 
     // Check if the target supports copybit compostion (dyn/mdp) to
     // decide if we need to open the copybit module.
@@ -222,7 +260,12 @@
                                                          HWC_DISPLAY_PRIMARY);
     }
 
-    ctx->mExtDisplay = new ExternalDisplay(ctx);
+    ctx->mExtDisplay = new ExternalDisplay();
+    // Send the primary resolution to the external display class
+    // to be used for MDP scaling functionality
+    uint32_t priW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+    uint32_t priH = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+    ctx->mExtDisplay->setPrimaryAttributes(priW, priH);
     ctx->mHWCVirtual = new HWCVirtualVDS();
     ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
     ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
@@ -232,8 +275,6 @@
     ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].mMDPScalingMode = false;
     ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].mMDPScalingMode = false;
 
-    ctx->mMDPComp[HWC_DISPLAY_PRIMARY] =
-         MDPComp::getObject(ctx, HWC_DISPLAY_PRIMARY);
     ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
     //Initialize the primary display viewFrame info
     ctx->mViewFrame[HWC_DISPLAY_PRIMARY].left = 0;
@@ -282,13 +323,6 @@
     ctx->deviceOrientation = 0;
     ctx->mBufferMirrorMode = false;
 
-    // Read the system property to determine if downscale feature is enabled.
-    ctx->mMDPDownscaleEnabled = false;
-    if(property_get("sys.hwc.mdp_downscale_enabled", value, "false")
-            && !strcmp(value, "true")) {
-        ctx->mMDPDownscaleEnabled = true;
-    }
-
     ctx->enableABC = false;
     property_get("debug.sf.hwc.canUseABC", value, "0");
     ctx->enableABC  = atoi(value) ? true : false;
@@ -338,14 +372,8 @@
     }
 
     for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
-        if(ctx->mFBUpdate[i]) {
-            delete ctx->mFBUpdate[i];
-            ctx->mFBUpdate[i] = NULL;
-        }
-        if(ctx->mMDPComp[i]) {
-            delete ctx->mMDPComp[i];
-            ctx->mMDPComp[i] = NULL;
-        }
+        destroyCompositionResources(ctx, i);
+
         if(ctx->mHwcDebug[i]) {
             delete ctx->mHwcDebug[i];
             ctx->mHwcDebug[i] = NULL;
@@ -445,8 +473,8 @@
     float xRatio = 1.0;
     float yRatio = 1.0;
 
-    int fbWidth = ctx->dpyAttr[dpy].xres;
-    int fbHeight = ctx->dpyAttr[dpy].yres;
+    uint32_t fbWidth = ctx->dpyAttr[dpy].xres;
+    uint32_t fbHeight = ctx->dpyAttr[dpy].yres;
     if(ctx->dpyAttr[dpy].mMDPScalingMode) {
         // if MDP scaling mode is enabled for external, need to query
         // the actual width and height, as that is the physical w & h
@@ -580,7 +608,7 @@
                  outPos.w, outPos.h);
     }
     if(ctx->dpyAttr[dpy].mMDPScalingMode) {
-        int extW = 0, extH = 0;
+        uint32_t extW = 0, extH = 0;
         if(dpy == HWC_DISPLAY_EXTERNAL) {
             ctx->mExtDisplay->getAttributes(extW, extH);
         } else if(dpy == HWC_DISPLAY_VIRTUAL) {
@@ -661,7 +689,7 @@
                 }
             }
             if(ctx->dpyAttr[dpy].mMDPScalingMode) {
-                int extW = 0, extH = 0;
+                uint32_t extW = 0, extH = 0;
                 // if MDP scaling mode is enabled, map the co-ordinates to new
                 // domain(downscaled)
                 float fbWidth  = (float)ctx->dpyAttr[dpy].xres;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index f7885b8..041ca74 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -284,6 +284,10 @@
 bool isAbcInUse(hwc_context_t *ctx);
 
 void dumpBuffer(private_handle_t *ohnd, char *bufferName);
+void updateDisplayInfo(hwc_context_t* ctx, int dpy);
+void resetDisplayInfo(hwc_context_t* ctx, int dpy);
+void initCompositionResources(hwc_context_t* ctx, int dpy);
+void destroyCompositionResources(hwc_context_t* ctx, int dpy);
 
 //Helper function to dump logs
 void dumpsys_log(android::String8& buf, const char* fmt, ...);
@@ -584,9 +588,6 @@
     bool mPanelResetStatus;
     // number of active Displays
     int numActiveDisplays;
-    // Downscale feature switch, set via system property
-    // sys.hwc.mdp_downscale_enabled
-    bool mMDPDownscaleEnabled;
     struct gpu_hint_info mGPUHintInfo;
     //App Buffer Composition
     bool enableABC;
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index 146d671..415a5e7 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -41,9 +41,7 @@
 void HWCVirtualVDS::init(hwc_context_t *ctx) {
     const int dpy = HWC_DISPLAY_VIRTUAL;
     mScalingWidth = 0, mScalingHeight = 0;
-    ctx->mFBUpdate[dpy] =
-            IFBUpdate::getObject(ctx, dpy);
-    ctx->mMDPComp[dpy] =  MDPComp::getObject(ctx, dpy);
+    initCompositionResources(ctx, dpy);
 
     if(ctx->mFBUpdate[dpy])
         ctx->mFBUpdate[dpy]->reset();
@@ -60,14 +58,8 @@
         ctx->dpyAttr[dpy].connected = false;
         ctx->dpyAttr[dpy].isPause = false;
 
-        if(ctx->mFBUpdate[dpy]) {
-            delete ctx->mFBUpdate[dpy];
-            ctx->mFBUpdate[dpy] = NULL;
-        }
-        if(ctx->mMDPComp[dpy]) {
-            delete ctx->mMDPComp[dpy];
-            ctx->mMDPComp[dpy] = NULL;
-        }
+        destroyCompositionResources(ctx, dpy);
+
         // signal synclock to indicate successful wfd teardown
         ctx->mWfdSyncLock.lock();
         ctx->mWfdSyncLock.signal();