getting closer to final main composition loop
Change-Id: Icd63782366ffd11d9ea00c925ae5783ed7440cdb
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c344870..198beeb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -82,6 +82,7 @@
mTransactionFlags(0),
mTransationPending(false),
mLayersRemoved(false),
+ mRepaintEverything(0),
mBootTime(systemTime()),
mVisibleRegionsDirty(false),
mHwWorkListDirty(false),
@@ -577,7 +578,7 @@
void SurfaceFlinger::handleMessageRefresh() {
handleRefresh();
- if (mVisibleRegionsDirty) {
+ if (CC_UNLIKELY(mVisibleRegionsDirty)) {
mVisibleRegionsDirty = false;
invalidateHwcGeometry();
@@ -586,9 +587,8 @@
*/
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
- // TODO: iterate through all displays
- {
- DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
+ for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
+ DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
Region opaqueRegion;
Region dirtyRegion;
@@ -612,45 +612,70 @@
}
}
- const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
+ HWComposer& hwc(getHwComposer());
+ if (hwc.initCheck() == NO_ERROR) {
+ // build the h/w work list
+ const bool workListsDirty = mHwWorkListDirty;
+ mHwWorkListDirty = false;
+ for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
+ DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
+ const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
+ const size_t count = currentLayers.size();
- // TODO: iterate through all displays
- for (int dpy=0 ; dpy<1 ; dpy++) {
- DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
- if (hw.dirtyRegion.isEmpty()) {
- continue;
+ hwc.createWorkList(count); // FIXME: the worklist should include enough space for all layer of all displays
+
+ HWComposer::LayerListIterator cur = hwc.begin();
+ const HWComposer::LayerListIterator end = hwc.end();
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+
+ if (CC_UNLIKELY(workListsDirty)) {
+ layer->setGeometry(hw, *cur);
+ if (mDebugDisableHWC || mDebugRegion) {
+ cur->setSkip(true);
+ }
+ }
+
+ /*
+ * update the per-frame h/w composer data for each layer
+ * and build the transparent region of the FB
+ */
+ layer->setPerFrameData(*cur);
+ }
}
+ status_t err = hwc.prepare();
+ ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
+ }
+
+ const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
+ for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
+ DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
// transform the dirty region into this screen's coordinate space
const Transform& planeTransform(hw.getTransform());
Region dirtyRegion;
if (repaintEverything) {
+ dirtyRegion.set(hw.bounds());
+ } else {
dirtyRegion = planeTransform.transform(hw.dirtyRegion);
dirtyRegion.andSelf(hw.bounds());
- } else {
- dirtyRegion.set(hw.bounds());
}
hw.dirtyRegion.clear();
- // build the h/w work list
- if (CC_UNLIKELY(mHwWorkListDirty)) {
- handleWorkList(hw);
+ if (!dirtyRegion.isEmpty()) {
+ if (hw.canDraw()) {
+ // repaint the framebuffer (if needed)
+ handleRepaint(hw, dirtyRegion);
+ }
}
-
- if (CC_LIKELY(hw.canDraw())) {
- // repaint the framebuffer (if needed)
- handleRepaint(hw, dirtyRegion);
- // inform the h/w that we're done compositing
- hw.compositionComplete();
- postFramebuffer();
- } else {
- // pretend we did the post
- hw.compositionComplete();
- }
+ // inform the h/w that we're done compositing
+ hw.compositionComplete();
}
+ postFramebuffer();
-#if 0
+
+#if 1
// render to the external display if we have one
EGLSurface externalDisplaySurface = getExternalDisplaySurface();
if (externalDisplaySurface != EGL_NO_SURFACE) {
@@ -670,6 +695,7 @@
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
+ DisplayHardware& hw(const_cast<DisplayDevice&>(getDisplayHardware(0)));
const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
@@ -695,45 +721,51 @@
void SurfaceFlinger::postFramebuffer()
{
ATRACE_CALL();
- // mSwapRegion can be empty here is some cases, for instance if a hidden
- // or fully transparent window is updating.
- // in that case, we need to flip anyways to not risk a deadlock with
- // h/w composer.
- const DisplayHardware& hw(getDefaultDisplayHardware());
- HWComposer& hwc(getHwComposer());
- const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
- size_t numLayers = layers.size();
const nsecs_t now = systemTime();
mDebugInSwapBuffers = now;
- if (hwc.initCheck() == NO_ERROR) {
- HWComposer::LayerListIterator cur = hwc.begin();
- const HWComposer::LayerListIterator end = hwc.end();
- for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
- if (cur->getCompositionType() == HWC_OVERLAY) {
- layers[i]->setAcquireFence(*cur);
- } else {
- cur->setAcquireFenceFd(-1);
+ HWComposer& hwc(getHwComposer());
+
+ for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
+ DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
+ if (hwc.initCheck() == NO_ERROR) {
+ const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
+ const size_t count = currentLayers.size();
+ HWComposer::LayerListIterator cur = hwc.begin();
+ const HWComposer::LayerListIterator end = hwc.end();
+ for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
+ const sp<LayerBase>& layer(currentLayers[i]);
+ layer->setAcquireFence(*cur);
}
}
+ hw.flip(hw.swapRegion);
+ hw.swapRegion.clear();
}
- hw.flip(hw.swapRegion);
- hw.swapRegion.clear();
-
if (hwc.initCheck() == NO_ERROR) {
- hwc.commit(mEGLDisplay, hw.getEGLSurface());
- HWComposer::LayerListIterator cur = hwc.begin();
- const HWComposer::LayerListIterator end = hwc.end();
- for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
- layers[i]->onLayerDisplayed(&*cur);
+ // FIXME: eventually commit() won't take arguments
+ hwc.commit(mEGLDisplay, getDefaultDisplayHardware().getEGLSurface());
+ }
+
+ for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
+ DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
+ const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
+ const size_t count = currentLayers.size();
+ if (hwc.initCheck() == NO_ERROR) {
+ HWComposer::LayerListIterator cur = hwc.begin();
+ const HWComposer::LayerListIterator end = hwc.end();
+ for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
+ currentLayers[i]->onLayerDisplayed(&*cur);
+ }
+ } else {
+ eglSwapBuffers(mEGLDisplay, hw.getEGLSurface());
+ for (size_t i = 0; i < count; i++) {
+ currentLayers[i]->onLayerDisplayed(NULL);
+ }
}
- } else {
- eglSwapBuffers(mEGLDisplay, hw.getEGLSurface());
- for (size_t i = 0; i < numLayers; i++) {
- layers[i]->onLayerDisplayed(NULL);
- }
+
+ // FIXME: we need to call eglSwapBuffers() on displays that have GL composition
}
mLastSwapBufferTime = systemTime() - now;
@@ -1028,27 +1060,6 @@
}
}
-
-void SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
-{
- mHwWorkListDirty = false;
- HWComposer& hwc(getHwComposer());
- if (hwc.initCheck() == NO_ERROR) {
- const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
- const size_t count = currentLayers.size();
- hwc.createWorkList(count);
-
- HWComposer::LayerListIterator cur = hwc.begin();
- const HWComposer::LayerListIterator end = hwc.end();
- for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
- currentLayers[i]->setGeometry(hw, *cur);
- if (mDebugDisableHWC || mDebugRegion) {
- cur->setSkip(true);
- }
- }
- }
-}
-
void SurfaceFlinger::handleRepaint(const DisplayHardware& hw,
const Region& inDirtyRegion)
{
@@ -1063,10 +1074,6 @@
debugFlashRegions(hw, dirtyRegion);
}
- // set the frame buffer
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
uint32_t flags = hw.getFlags();
if (flags & DisplayHardware::SWAP_RECTANGLE) {
// we can redraw only what's dirty, but since SWAP_RECTANGLE only
@@ -1087,57 +1094,29 @@
}
}
- setupHardwareComposer(hw);
composeSurfaces(hw, dirtyRegion);
// update the swap region and clear the dirty region
hw.swapRegion.orSelf(dirtyRegion);
}
-void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw)
-{
- HWComposer& hwc(getHwComposer());
- HWComposer::LayerListIterator cur = hwc.begin();
- const HWComposer::LayerListIterator end = hwc.end();
- if (cur == end) {
- return;
- }
-
- const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
- size_t count = layers.size();
-
- ALOGE_IF(hwc.getNumLayers() != count,
- "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
- hwc.getNumLayers(), count);
-
- // just to be extra-safe, use the smallest count
- if (hwc.initCheck() == NO_ERROR) {
- count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
- }
-
- /*
- * update the per-frame h/w composer data for each layer
- * and build the transparent region of the FB
- */
- for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
- const sp<LayerBase>& layer(layers[i]);
- layer->setPerFrameData(*cur);
- }
- status_t err = hwc.prepare();
- ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
-}
-
void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty)
{
HWComposer& hwc(getHwComposer());
HWComposer::LayerListIterator cur = hwc.begin();
const HWComposer::LayerListIterator end = hwc.end();
- const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
+ const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); // FIXME: this should be per display
if (cur==end || fbLayerCount) {
- // Never touch the framebuffer if we don't have any framebuffer layers
- if (hwc.getLayerCount(HWC_OVERLAY)) {
+ DisplayHardware::makeCurrent(hw, mEGLContext);
+
+ // set the frame buffer
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ // Never touch the framebuffer if we don't have any framebuffer layers
+ if (hwc.getLayerCount(HWC_OVERLAY)) { // FIXME: this should be per display
// when using overlays, we assume a fully transparent framebuffer
// NOTE: we could reduce how much we need to clear, for instance
// remove where there are opaque FB layers. however, on some