diff options
author | Jesse Hall <jessehall@google.com> | 2012-06-29 15:21:18 -0700 |
---|---|---|
committer | Jesse Hall <jessehall@google.com> | 2012-06-30 21:38:51 -0700 |
commit | dc5b485f74edf2d2f31c62054eb6c180421a3ade (patch) | |
tree | f33c9322cadc2895f0e0f28c1968d796c423c8c6 /services/surfaceflinger | |
parent | b42b1ac1587aebda5e2f334d95b620271fafba4e (diff) | |
download | frameworks_native-dc5b485f74edf2d2f31c62054eb6c180421a3ade.zip frameworks_native-dc5b485f74edf2d2f31c62054eb6c180421a3ade.tar.gz frameworks_native-dc5b485f74edf2d2f31c62054eb6c180421a3ade.tar.bz2 |
Pass fence to HWC on first use of buffer
Also do a CPU-wait on the fence before using it for GL composition.
Change-Id: I0f645a42a44803276cae11b904e5a26d65871562
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 25 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 1 |
4 files changed, 36 insertions, 0 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 7c09ab2..4ed692f 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -350,6 +350,12 @@ public: // not supported on VERSION_03 return -1; } + virtual void setAcquireFenceFd(int fenceFd) { + if (fenceFd != -1) { + ALOGE("HWC 0.x can't handle acquire fences"); + close(fenceFd); + } + } virtual void setDefaultState() { getLayer()->compositionType = HWC_FRAMEBUFFER; @@ -416,6 +422,9 @@ public: getLayer()->releaseFenceFd = -1; return fd; } + virtual void setAcquireFenceFd(int fenceFd) { + getLayer()->acquireFenceFd = fenceFd; + } virtual void setDefaultState() { getLayer()->compositionType = HWC_FRAMEBUFFER; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index cb4c2db..a662b25 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -109,6 +109,7 @@ public: virtual void setCrop(const Rect& crop) = 0; virtual void setVisibleRegionScreen(const Region& reg) = 0; virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0; + virtual void setAcquireFenceFd(int fenceFd) = 0; }; /* diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6aba16a..5b9327d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -60,6 +60,7 @@ Layer::Layer(SurfaceFlinger* flinger, mCurrentOpacity(true), mRefreshPending(false), mFrameLatencyNeeded(false), + mNeedHwcFence(false), mFrameLatencyOffset(0), mFormat(PIXEL_FORMAT_NONE), mGLExtensions(GLExtensions::getInstance()), @@ -299,6 +300,20 @@ void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) { // NOTE: buffer can be NULL if the client never drew into this // layer yet, or if we ran out of memory layer.setBuffer(buffer); + + if (mNeedHwcFence) { + sp<Fence> fence = mSurfaceTexture->getCurrentFence(); + if (fence.get()) { + int fenceFd = fence->dup(); + if (fenceFd == -1) { + ALOGW("failed to dup layer fence, skipping sync: %d", errno); + } + layer.setAcquireFenceFd(fenceFd); + } + mNeedHwcFence = false; + } else { + layer.setAcquireFenceFd(-1); + } } void Layer::onDraw(const DisplayHardware& hw, const Region& clip) const @@ -333,6 +348,15 @@ void Layer::onDraw(const DisplayHardware& hw, const Region& clip) const return; } + // TODO: replace this with a server-side wait + sp<Fence> fence = mSurfaceTexture->getCurrentFence(); + if (fence.get()) { + status_t err = fence->wait(Fence::TIMEOUT_NEVER); + ALOGW_IF(err != OK, "Layer::onDraw: failed waiting for fence: %d", err); + // Go ahead and draw the buffer anyway; no matter what we do the screen + // is probably going to have something visibly wrong. + } + if (!isProtected()) { // TODO: we could be more subtle with isFixedSize() const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize(); @@ -627,6 +651,7 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) mRefreshPending = true; mFrameLatencyNeeded = true; + mNeedHwcFence = true; if (oldActiveBuffer == NULL) { // the first time we receive a buffer, we need to trigger a // geometry invalidation. diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index d47f2e8..29515f0 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -120,6 +120,7 @@ private: bool mCurrentOpacity; bool mRefreshPending; bool mFrameLatencyNeeded; + bool mNeedHwcFence; int mFrameLatencyOffset; struct Statistics { |