Set the swap interval of virtual display surfaces to 0
This prevents slow/malicious virtual display consumers from
backpressuring SurfaceFlinger and preventing it from updating other
displays.
Bug: 10193714
Change-Id: I3e877d97202628d2d9abea24b66576f38299c14d
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index c67f4d8..0e3c7c6 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -63,7 +63,6 @@
mDisplaySurface(displaySurface),
mDisplay(EGL_NO_DISPLAY),
mSurface(EGL_NO_SURFACE),
- mContext(EGL_NO_CONTEXT),
mDisplayWidth(), mDisplayHeight(), mFormat(),
mFlags(),
mPageFlipCount(),
@@ -79,6 +78,16 @@
int format;
window->query(window, NATIVE_WINDOW_FORMAT, &format);
+ // Make sure that composition can never be stalled by a virtual display
+ // consumer that isn't processing buffers fast enough. We have to do this
+ // in two places:
+ // * Here, in case the display is composed entirely by HWC.
+ // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
+ // window's swap interval in eglMakeCurrent, so they'll override the
+ // interval we set here.
+ if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
+ window->setSwapInterval(window, 0);
+
/*
* Create our display's surface
*/
@@ -253,6 +262,8 @@
if (sur != mSurface) {
result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
if (result == EGL_TRUE) {
+ if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
+ eglSwapInterval(dpy, 0);
setViewportAndProjection();
}
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 748be1a..86fbc87 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -170,7 +170,6 @@
EGLDisplay mDisplay;
EGLSurface mSurface;
- EGLContext mContext;
int mDisplayWidth;
int mDisplayHeight;
PixelFormat mFormat;