Switch SurfaceFlinger to HWC 2.0
Enables SurfaceFlinger to speak to version 2.0 of the Hardware Composer
HAL instead of version 1.x (also removing support for the framebuffer
HAL). By default, however, this functionality is disabled. In order to
enable it, USE_HWC2 must be set to true in Android.mk.
Change-Id: I4589e02ac2165236b10ff2f7cb772f87e0d3daab
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index a6bc158..29e0766 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -15,6 +15,10 @@
** limitations under the License.
*/
+// #define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "FramebufferSurface"
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -56,16 +60,35 @@
ConsumerBase(consumer),
mDisplayType(disp),
mCurrentBufferSlot(-1),
+#ifdef USE_HWC2
+ mCurrentBuffer(),
+ mCurrentFence(Fence::NO_FENCE),
+ mHwc(hwc),
+ mHasPendingRelease(false),
+ mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
+ mPreviousBuffer()
+#else
mCurrentBuffer(0),
mHwc(hwc)
+#endif
{
+#ifdef USE_HWC2
+ ALOGV("Creating for display %d", disp);
+#endif
+
mName = "FramebufferSurface";
mConsumer->setConsumerName(mName);
mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_COMPOSER);
+#ifdef USE_HWC2
+ const auto& activeConfig = mHwc.getActiveConfig(disp);
+ mConsumer->setDefaultBufferSize(activeConfig->getWidth(),
+ activeConfig->getHeight());
+#else
mConsumer->setDefaultBufferFormat(mHwc.getFormat(disp));
- mConsumer->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp));
+ mConsumer->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp));
+#endif
mConsumer->setMaxAcquiredBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS - 1);
}
@@ -78,13 +101,35 @@
}
status_t FramebufferSurface::advanceFrame() {
+#ifdef USE_HWC2
+ sp<GraphicBuffer> buf;
+ sp<Fence> acquireFence(Fence::NO_FENCE);
+ android_dataspace_t dataspace = HAL_DATASPACE_UNKNOWN;
+ status_t result = nextBuffer(buf, acquireFence, dataspace);
+ if (result != NO_ERROR) {
+ ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
+ strerror(-result), result);
+ return result;
+ }
+ result = mHwc.setClientTarget(mDisplayType, acquireFence, buf, dataspace);
+ if (result != NO_ERROR) {
+ ALOGE("error posting framebuffer: %d", result);
+ }
+ return result;
+#else
// Once we remove FB HAL support, we can call nextBuffer() from here
// instead of using onFrameAvailable(). No real benefit, except it'll be
// more like VirtualDisplaySurface.
return NO_ERROR;
+#endif
}
+#ifdef USE_HWC2
+status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer,
+ sp<Fence>& outFence, android_dataspace_t& outDataspace) {
+#else
status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
+#endif
Mutex::Autolock lock(mMutex);
BufferItem item;
@@ -107,6 +152,11 @@
// had released the old buffer first.
if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
item.mSlot != mCurrentBufferSlot) {
+#ifdef USE_HWC2
+ mHasPendingRelease = true;
+ mPreviousBufferSlot = mCurrentBufferSlot;
+ mPreviousBuffer = mCurrentBuffer;
+#else
// Release the previous buffer.
err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer,
EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
@@ -114,14 +164,23 @@
ALOGE("error releasing buffer: %s (%d)", strerror(-err), err);
return err;
}
+#endif
}
mCurrentBufferSlot = item.mSlot;
mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
+#ifdef USE_HWC2
+ mCurrentFence = item.mFence;
+#endif
+
outFence = item.mFence;
outBuffer = mCurrentBuffer;
+#ifdef USE_HWC2
+ outDataspace = item.mDataSpace;
+#endif
return NO_ERROR;
}
+#ifndef USE_HWC2
// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
sp<GraphicBuffer> buf;
@@ -137,6 +196,7 @@
ALOGE("error posting framebuffer: %d", err);
}
}
+#endif
void FramebufferSurface::freeBufferLocked(int slotIndex) {
ConsumerBase::freeBufferLocked(slotIndex);
@@ -146,6 +206,24 @@
}
void FramebufferSurface::onFrameCommitted() {
+#ifdef USE_HWC2
+ if (mHasPendingRelease) {
+ sp<Fence> fence = mHwc.getRetireFence(mDisplayType);
+ if (fence->isValid()) {
+ status_t result = addReleaseFence(mPreviousBufferSlot,
+ mPreviousBuffer, fence);
+ ALOGE_IF(result != NO_ERROR, "onFrameCommitted: failed to add the"
+ " fence: %s (%d)", strerror(-result), result);
+ }
+ status_t result = releaseBufferLocked(mPreviousBufferSlot,
+ mPreviousBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+ ALOGE_IF(result != NO_ERROR, "onFrameCommitted: error releasing buffer:"
+ " %s (%d)", strerror(-result), result);
+
+ mPreviousBuffer.clear();
+ mHasPendingRelease = false;
+ }
+#else
sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType);
if (fence->isValid() &&
mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
@@ -154,12 +232,15 @@
ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
strerror(-err), err);
}
+#endif
}
+#ifndef USE_HWC2
status_t FramebufferSurface::compositionComplete()
{
return mHwc.fbCompositionComplete();
}
+#endif
void FramebufferSurface::dumpAsString(String8& result) const {
ConsumerBase::dump(result);
@@ -167,10 +248,18 @@
void FramebufferSurface::dumpLocked(String8& result, const char* prefix) const
{
+#ifndef USE_HWC2
mHwc.fbDump(result);
+#endif
ConsumerBase::dumpLocked(result, prefix);
}
+#ifdef USE_HWC2
+const sp<Fence>& FramebufferSurface::getClientTargetAcquireFence() const {
+ return mCurrentFence;
+}
+#endif
+
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------