diff options
| author | Mathias Agopian <mathias@google.com> | 2010-11-01 23:32:18 -0700 |
|---|---|---|
| committer | Mathias Agopian <mathias@google.com> | 2010-12-03 17:35:07 -0800 |
| commit | 025005f562f695c3b1785745c2e5c184fc3a2330 (patch) | |
| tree | 850177ccb405a2234b885b41624c0253b02db128 /services/surfaceflinger/SurfaceFlinger.cpp | |
| parent | 48e723a0ee9b625825d23642f843b91fa276ab7c (diff) | |
| download | frameworks_base-025005f562f695c3b1785745c2e5c184fc3a2330.zip frameworks_base-025005f562f695c3b1785745c2e5c184fc3a2330.tar.gz frameworks_base-025005f562f695c3b1785745c2e5c184fc3a2330.tar.bz2 | |
[3171580] SurfaceFlinger Bypass mode. (DO NOT MERGE)
This is a poor's man precursor to the h/w composer HAL.
Basically we detect when a window is full screen and in
that case we bypass surfaceflinger's composition step, which
yields to much improved performance.
Change-Id: Ie03796ae81a1c951949b771c9323044b980cb347
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 68 |
1 files changed, 65 insertions, 3 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a9b3965..5e9e06c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -61,6 +61,10 @@ #define AID_GRAPHICS 1003 #endif +#ifdef USE_COMPOSITION_BYPASS +#warning "using COMPOSITION_BYPASS" +#endif + #define DISPLAY_COUNT 1 namespace android { @@ -373,8 +377,15 @@ bool SurfaceFlinger::threadLoop() const DisplayHardware& hw(graphicPlane(0).displayHardware()); if (LIKELY(hw.canDraw() && !isFrozen())) { - // repaint the framebuffer (if needed) +#ifdef USE_COMPOSITION_BYPASS + if (handleBypassLayer()) { + unlockClients(); + return true; + } +#endif + + // repaint the framebuffer (if needed) const int index = hw.getCurrentBufferIndex(); GraphicLog& logger(GraphicLog::getInstance()); @@ -401,6 +412,20 @@ bool SurfaceFlinger::threadLoop() return true; } +bool SurfaceFlinger::handleBypassLayer() +{ + sp<Layer> bypassLayer(mBypassLayer.promote()); + if (bypassLayer != 0) { + sp<GraphicBuffer> buffer(bypassLayer->getBypassBuffer()); + if (buffer!=0 && (buffer->usage & GRALLOC_USAGE_HW_FB)) { + const DisplayHardware& hw(graphicPlane(0).displayHardware()); + hw.postBypassBuffer(buffer->handle); + return true; + } + } + return false; +} + void SurfaceFlinger::postFramebuffer() { if (!mInvalidRegion.isEmpty()) { @@ -696,6 +721,28 @@ void SurfaceFlinger::commitTransaction() mTransactionCV.broadcast(); } +void SurfaceFlinger::setBypassLayer(const sp<LayerBase>& layer) +{ + // if this layer is already the bypass layer, do nothing + sp<Layer> cur(mBypassLayer.promote()); + if (mBypassLayer == layer) + return; + + // clear the current bypass layer + mBypassLayer.clear(); + if (cur != 0) { + cur->setBypass(false); + cur.clear(); + } + + // set new bypass layer + if (layer != 0) { + if (layer->setBypass(true)) { + mBypassLayer = static_cast<Layer*>(layer.get()); + } + } +} + void SurfaceFlinger::handlePageFlip() { bool visibleRegions = mVisibleRegionsDirty; @@ -721,6 +768,21 @@ void SurfaceFlinger::handlePageFlip() mVisibleLayersSortedByZ.add(currentLayers[i]); } +#ifdef USE_COMPOSITION_BYPASS + sp<LayerBase> bypassLayer; + const size_t numVisibleLayers = mVisibleLayersSortedByZ.size(); + if (numVisibleLayers == 1) { + const sp<LayerBase>& candidate(mVisibleLayersSortedByZ[0]); + const Region& visibleRegion(candidate->visibleRegionScreen); + const Region reminder(screenRegion.subtract(visibleRegion)); + if (reminder.isEmpty()) { + // fullscreen candidate! + bypassLayer = candidate; + } + } + setBypassLayer(bypassLayer); +#endif + mWormholeRegion = screenRegion.subtract(opaqueRegion); mVisibleRegionsDirty = false; } @@ -1416,9 +1478,9 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) mWormholeRegion.dump(result, "WormholeRegion"); const DisplayHardware& hw(graphicPlane(0).displayHardware()); snprintf(buffer, SIZE, - " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n", + " display frozen: %s, freezeCount=%d, orientation=%d, bypass=%p, canDraw=%d\n", mFreezeDisplay?"yes":"no", mFreezeCount, - mCurrentState.orientation, hw.canDraw()); + mCurrentState.orientation, mBypassLayer.unsafe_get(), hw.canDraw()); result.append(buffer); snprintf(buffer, SIZE, " last eglSwapBuffers() time: %f us\n" |
