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/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index aeba720..53b0dc4 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -990,6 +990,26 @@
}
}
+ // If possible, attempt to use the cursor overlay on each display.
+ for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
+ sp<const DisplayDevice> hw(mDisplays[dpy]);
+ const int32_t id = hw->getHwcDisplayId();
+ if (id >= 0) {
+ const Vector< sp<Layer> >& currentLayers(
+ hw->getVisibleLayersSortedByZ());
+ const size_t count = currentLayers.size();
+ HWComposer::LayerListIterator cur = hwc.begin(id);
+ const HWComposer::LayerListIterator end = hwc.end(id);
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
+ const sp<Layer>& layer(currentLayers[i]);
+ if (layer->isPotentialCursor()) {
+ cur->setIsCursorLayerHint();
+ break;
+ }
+ }
+ }
+ }
+
status_t err = hwc.prepare();
ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
@@ -1364,6 +1384,34 @@
}
commitTransaction();
+
+ updateCursorAsync();
+}
+
+void SurfaceFlinger::updateCursorAsync()
+{
+ HWComposer& hwc(getHwComposer());
+ for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
+ sp<const DisplayDevice> hw(mDisplays[dpy]);
+ const int32_t id = hw->getHwcDisplayId();
+ if (id < 0) {
+ continue;
+ }
+ const Vector< sp<Layer> >& currentLayers(
+ hw->getVisibleLayersSortedByZ());
+ const size_t count = currentLayers.size();
+ HWComposer::LayerListIterator cur = hwc.begin(id);
+ const HWComposer::LayerListIterator end = hwc.end(id);
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
+ if (cur->getCompositionType() != HWC_CURSOR_OVERLAY) {
+ continue;
+ }
+ const sp<Layer>& layer(currentLayers[i]);
+ Rect cursorPos = layer->getPosition(hw);
+ hwc.setCursorPositionAsync(id, cursorPos);
+ break;
+ }
+ }
}
void SurfaceFlinger::commitTransaction()
@@ -1695,6 +1743,7 @@
const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
if (!clip.isEmpty()) {
switch (cur->getCompositionType()) {
+ case HWC_CURSOR_OVERLAY:
case HWC_OVERLAY: {
const Layer::State& state(layer->getDrawingState());
if ((cur->getHints() & HWC_HINT_CLEAR_FB)