summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2012-06-29 15:21:18 -0700
committerJesse Hall <jessehall@google.com>2012-06-30 21:38:51 -0700
commitdc5b485f74edf2d2f31c62054eb6c180421a3ade (patch)
treef33c9322cadc2895f0e0f28c1968d796c423c8c6 /services/surfaceflinger
parentb42b1ac1587aebda5e2f334d95b620271fafba4e (diff)
downloadframeworks_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.cpp9
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h1
-rw-r--r--services/surfaceflinger/Layer.cpp25
-rw-r--r--services/surfaceflinger/Layer.h1
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 {