From 52bbb1ae239c8a4d05543a23fa8c08467d09c3b2 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 31 Jul 2012 19:01:53 -0700 Subject: [PATCH] getting closer to final main composition loop Change-Id: Icd63782366ffd11d9ea00c925ae5783ed7440cdb --- services/surfaceflinger/DisplayHardware.cpp | 8 + services/surfaceflinger/DisplayHardware.h | 2 + services/surfaceflinger/Layer.cpp | 2 +- services/surfaceflinger/SurfaceFlinger.cpp | 215 +++++++++----------- services/surfaceflinger/SurfaceFlinger.h | 2 - 5 files changed, 108 insertions(+), 121 deletions(-) diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp index 7e4aa83e4..b468aaefc 100644 --- a/services/surfaceflinger/DisplayHardware.cpp +++ b/services/surfaceflinger/DisplayHardware.cpp @@ -310,6 +310,14 @@ void DisplayHardware::dump(String8& res) const } } +void DisplayHardware::makeCurrent(const DisplayHardware& hw, EGLContext ctx) { + EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); + if (sur != hw.mSurface) { + EGLDisplay dpy = eglGetCurrentDisplay(); + eglMakeCurrent(dpy, hw.mSurface, hw.mSurface, ctx); + } +} + // ---------------------------------------------------------------------------- void DisplayHardware::setVisibleLayersSortedByZ(const Vector< sp >& layers) { diff --git a/services/surfaceflinger/DisplayHardware.h b/services/surfaceflinger/DisplayHardware.h index 80d20cb9b..a638dc0a7 100644 --- a/services/surfaceflinger/DisplayHardware.h +++ b/services/surfaceflinger/DisplayHardware.h @@ -107,6 +107,8 @@ public: } inline Rect bounds() const { return getBounds(); } + static void makeCurrent(const DisplayHardware& hw, EGLContext ctx); + private: void init(EGLConfig config); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6617ea28d..815a6f94a 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -294,7 +294,7 @@ void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) { void Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) { int fenceFd = -1; - if (mNeedHwcFence) { + if (mNeedHwcFence && (layer.getCompositionType() == HWC_OVERLAY)) { sp fence = mSurfaceTexture->getCurrentFence(); if (fence.get()) { fenceFd = fence->dup(); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index c344870e2..198beeb34 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -82,6 +82,7 @@ SurfaceFlinger::SurfaceFlinger() mTransactionFlags(0), mTransationPending(false), mLayersRemoved(false), + mRepaintEverything(0), mBootTime(systemTime()), mVisibleRegionsDirty(false), mHwWorkListDirty(false), @@ -577,7 +578,7 @@ void SurfaceFlinger::handleMessageInvalidate() { void SurfaceFlinger::handleMessageRefresh() { handleRefresh(); - if (mVisibleRegionsDirty) { + if (CC_UNLIKELY(mVisibleRegionsDirty)) { mVisibleRegionsDirty = false; invalidateHwcGeometry(); @@ -586,9 +587,8 @@ void SurfaceFlinger::handleMessageRefresh() { */ const LayerVector& currentLayers(mDrawingState.layersSortedByZ); - // TODO: iterate through all displays - { - DisplayHardware& hw(const_cast(getDisplayHardware(0))); + for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays + DisplayHardware& hw(const_cast(getDisplayHardware(dpy))); Region opaqueRegion; Region dirtyRegion; @@ -612,45 +612,70 @@ void SurfaceFlinger::handleMessageRefresh() { } } - 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(getDisplayHardware(dpy))); + const Vector< sp >& 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(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& 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(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 (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(); + if (!dirtyRegion.isEmpty()) { + if (hw.canDraw()) { + // repaint the framebuffer (if needed) + handleRepaint(hw, dirtyRegion); + } } + // 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 @@ void SurfaceFlinger::handleMessageRefresh() { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + DisplayHardware& hw(const_cast(getDisplayHardware(0))); const Vector< sp >& layers( hw.getVisibleLayersSortedByZ() ); const size_t count = layers.size(); for (size_t i=0 ; i