liboverlay: Refactor, bug-fixes, upgrade.

* Fix memory leak during copying pipe objects.
* Remove unused / unnecessary code.
* setMemoryId API is merged with queueBuffer.
* setParameter API is setTransform now.
* Rotator upgraded to:
  --Allow different rotator hardware types.
  --Remove dependency on MDP code.
  --Allocate memory only during first playback,
  close when the associated pipe is closed.
* Have single commit implementation.
* Include new format types.
* Remove WAIT and CHANNEL enums and usage. Replace BypassPipe with
  GenericPipe. Client expected to set alignments and parameters.
  Add transform combination enums.
* Allow APIs to be called in any order. Do transform calcs in commit.
  Move ext type setter and getter functions.
* Add calculations for 180 transform.
* Add secure session support in rotator
* Implement all rotations in terms of H flip, V flip and 90 rotation.

Change-Id: I34a9a2a0f1255b3467a0abbaa254d0b584e901ce
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
new file mode 100644
index 0000000..bae35c8
--- /dev/null
+++ b/libhwcomposer/hwc_video.cpp
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "hwc_video.h"
+
+namespace qhwc {
+
+#define FINAL_TRANSFORM_MASK 0x000F
+#define VIDEO_DEBUG 0
+
+//Static Members
+ovutils::eOverlayState VideoOverlay::sState = ovutils::OV_CLOSED;
+int VideoOverlay::sYuvCount = 0;
+int VideoOverlay::sYuvLayerIndex = -1;
+bool VideoOverlay::sIsModeOn = false;
+bool VideoOverlay::sIsLayerSkip = false;
+
+//Cache stats, figure out the state, config overlay
+bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_layer_list_t *list) {
+    sIsModeOn = false;
+    chooseState(ctx);
+    //if the state chosen above is CLOSED, skip this block.
+    if(sState != ovutils::OV_CLOSED) {
+        if(configure(ctx, &list->hwLayers[sYuvLayerIndex])) {
+            markFlags(&list->hwLayers[sYuvLayerIndex]);
+        }
+    }
+
+    ALOGD_IF(VIDEO_DEBUG, "%s: stats: yuvCount = %d, yuvIndex = %d,"
+            "IsModeOn = %d, IsSkipLayer = %d", __FUNCTION__, sYuvCount,
+            sYuvLayerIndex, sIsModeOn, sIsLayerSkip);
+
+    return sIsModeOn;
+}
+
+void VideoOverlay::chooseState(hwc_context_t *ctx) {
+    ALOGD_IF(VIDEO_DEBUG, "%s: old state = %s", __FUNCTION__,
+            ovutils::getStateString(sState));
+
+    ovutils::eOverlayState newState = ovutils::OV_CLOSED;
+    //TODO check if device supports overlay and hdmi
+
+    //Support 1 video layer
+    if(sYuvCount == 1) {
+        if(sIsLayerSkip && ctx->hdmiEnabled) { //Skip on primary, display on ext.
+            //TODO
+            //VIDEO_ON_TV_ONLY
+        } else if(sIsLayerSkip) { //skip on primary, no ext
+            newState = ovutils::OV_CLOSED;
+        } else if(ctx->hdmiEnabled) { //display on both
+            newState = ovutils::OV_2D_VIDEO_ON_PANEL_TV;
+        } else { //display on primary only
+            newState = ovutils::OV_2D_VIDEO_ON_PANEL;
+        }
+    }
+    sState = newState;
+    ALOGD_IF(VIDEO_DEBUG, "%s: new chosen state = %s", __FUNCTION__,
+            ovutils::getStateString(sState));
+}
+
+void VideoOverlay::markFlags(hwc_layer_t *layer) {
+    switch(sState) {
+        case ovutils::OV_2D_VIDEO_ON_PANEL:
+        case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
+            layer->compositionType = HWC_OVERLAY;
+            layer->hints |= HWC_HINT_CLEAR_FB;
+            break;
+        //TODO
+        //case ovutils::OV_2D_VIDEO_ON_TV:
+            //just break, dont update flags.
+        default:
+            break;
+    }
+}
+
+bool VideoOverlay::configure(hwc_context_t *ctx, hwc_layer_t *layer)
+{
+    if (LIKELY(ctx->mOverlay)) {
+
+        overlay::Overlay& ov = *(ctx->mOverlay);
+        // Set overlay state
+        ov.setState(sState);
+
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
+
+        //TODO change this based on state.
+        ovutils::eDest dest = ovutils::OV_PIPE_ALL;
+
+        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
+        if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
+            ovutils::setMdpFlags(mdpFlags,
+                                 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
+        }
+
+        ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
+        if (ctx->numHwLayers == 1) {
+            isFgFlag = ovutils::IS_FG_SET;
+        }
+
+        ovutils::PipeArgs parg(mdpFlags,
+                               info,
+                               ovutils::ZORDER_0,
+                               isFgFlag,
+                               ovutils::ROT_FLAG_DISABLED);
+        ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
+        ov.setSource(pargs, dest);
+
+        hwc_rect_t sourceCrop = layer->sourceCrop;
+        // x,y,w,h
+        ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
+                           sourceCrop.right - sourceCrop.left,
+                           sourceCrop.bottom - sourceCrop.top);
+        //Only for External
+        ov.setCrop(dcrop, ovutils::OV_PIPE1);
+
+        // FIXME: Use source orientation for TV when source is portrait
+        //Only for External
+        ov.setTransform(0, dest);
+
+        ovutils::Dim dpos;
+        hwc_rect_t displayFrame = layer->displayFrame;
+        dpos.x = displayFrame.left;
+        dpos.y = displayFrame.top;
+        dpos.w = (displayFrame.right - displayFrame.left);
+        dpos.h = (displayFrame.bottom - displayFrame.top);
+
+        //Only for External
+        ov.setPosition(dpos, ovutils::OV_PIPE1);
+
+        //Calculate the rect for primary based on whether the supplied position
+        //is within or outside bounds.
+        const int fbWidth =
+            ovutils::FrameBufferInfo::getInstance()->getWidth();
+        const int fbHeight =
+            ovutils::FrameBufferInfo::getInstance()->getHeight();
+
+        if( displayFrame.left < 0 ||
+            displayFrame.top < 0 ||
+            displayFrame.right > fbWidth ||
+            displayFrame.bottom > fbHeight) {
+
+            calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight);
+
+            //Update calculated width and height
+            dcrop.w = sourceCrop.right - sourceCrop.left;
+            dcrop.h = sourceCrop.bottom - sourceCrop.top;
+
+            dpos.w = displayFrame.right - displayFrame.left;
+            dpos.h = displayFrame.bottom - displayFrame.top;
+        }
+
+        //Only for Primary
+        ov.setCrop(dcrop, ovutils::OV_PIPE0);
+
+        int transform = layer->transform & FINAL_TRANSFORM_MASK;
+        ovutils::eTransform orient =
+            static_cast<ovutils::eTransform>(transform);
+        ov.setTransform(orient, ovutils::OV_PIPE0);
+
+        ov.setPosition(dpos, ovutils::OV_PIPE0);
+
+        //Both prim and external
+        if (!ov.commit(dest)) {
+            ALOGE("%s: commit fails", __FUNCTION__);
+            return false;
+        }
+
+        sIsModeOn = true;
+    }
+    return sIsModeOn;
+}
+
+bool VideoOverlay::draw(hwc_context_t *ctx, hwc_layer_list_t *list)
+{
+    if(!sIsModeOn || sYuvLayerIndex == -1) {
+        return true;
+    }
+
+    private_handle_t *hnd =
+            (private_handle_t *)list->hwLayers[sYuvLayerIndex].handle;
+
+    // Lock this buffer for read.
+    ctx->qbuf->lockAndAdd(hnd);
+    bool ret = true;
+    overlay::Overlay& ov = *(ctx->mOverlay);
+    ovutils::eOverlayState state = ov.getState();
+
+    switch (state) {
+        case ovutils::OV_2D_VIDEO_ON_PANEL_TV:
+        case ovutils::OV_3D_VIDEO_ON_2D_PANEL_2D_TV:
+            // Play external
+            if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) {
+                ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
+                ret = false;
+            }
+
+            // Play primary
+            if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) {
+                ALOGE("%s: queueBuffer failed for primary", __FUNCTION__);
+                ret = false;
+            }
+
+            // Wait for external vsync to be done
+            if (!ov.waitForVsync(ovutils::OV_PIPE1)) {
+                ALOGE("%s: waitForVsync failed for external", __FUNCTION__);
+                ret = false;
+            }
+            break;
+        default:
+            // In most cases, displaying only to one (primary or external)
+            // so use OV_PIPE_ALL since overlay will ignore NullPipes
+            if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE_ALL)) {
+                ALOGE("%s: queueBuffer failed", __FUNCTION__);
+                ret = false;
+            }
+            break;
+    }
+
+    return ret;
+}
+
+
+}; //namespace qhwc