Turn on support for async cursor update in surfaceflinger.

If available, surfaceflinger will use the hwc setCursorPositionAsync()
api to change the position of supported cursor layers outside of
the usual prepare/set loop.

Change-Id: Ib3fc5c0c390b3489ddbba202379840a1d2748917
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 4861e34..bbb5cfe 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -79,7 +79,8 @@
         mSecure(false),
         mProtectedByApp(false),
         mHasSurface(false),
-        mClientRef(client)
+        mClientRef(client),
+        mPotentialCursor(false)
 {
     mCurrentCrop.makeInvalid();
     mFlinger->getRenderEngine().genTextures(1, &mTextureName);
@@ -200,6 +201,7 @@
 
     mFormat = format;
 
+    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
     mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
     mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
     mCurrentOpacity = getOpacityForFormat(format);
@@ -441,7 +443,7 @@
     // TODO: there is a possible optimization here: we only need to set the
     // acquire fence the first time a new buffer is acquired on EACH display.
 
-    if (layer.getCompositionType() == HWC_OVERLAY) {
+    if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) {
         sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence();
         if (fence->isValid()) {
             fenceFd = fence->dup();
@@ -453,6 +455,26 @@
     layer.setAcquireFenceFd(fenceFd);
 }
 
+Rect Layer::getPosition(
+    const sp<const DisplayDevice>& hw)
+{
+    // this gives us only the "orientation" component of the transform
+    const State& s(getCurrentState());
+
+    // apply the layer's transform, followed by the display's global transform
+    // here we're guaranteed that the layer's transform preserves rects
+    Rect win(s.active.w, s.active.h);
+    if (!s.active.crop.isEmpty()) {
+        win.intersect(s.active.crop, &win);
+    }
+    // subtract the transparent region and snap to the bounds
+    Rect bounds = reduce(win, s.activeTransparentRegion);
+    Rect frame(s.transform.transform(bounds));
+    frame.intersect(hw->getViewport(), &frame);
+    const Transform& tr(hw->getTransform());
+    return Rect(tr.transform(frame));
+}
+
 // ---------------------------------------------------------------------------
 // drawing...
 // ---------------------------------------------------------------------------
@@ -1187,6 +1209,9 @@
         // need a hardware-protected path to external video sink
         usage |= GraphicBuffer::USAGE_PROTECTED;
     }
+    if (mPotentialCursor) {
+        usage |= GraphicBuffer::USAGE_CURSOR;
+    }
     usage |= GraphicBuffer::USAGE_HW_COMPOSER;
     return usage;
 }