surfaceflinger: cache HWC client targets and buffers
Remember HWC client targets and buffers, and make sure we send each
unique slot/handle pair only once. This allows the composer to
clone/register/retain each buffer only once.
Test: builds and boots
Change-Id: Ib485189043a9c132031e82d4d7380ace3bf9453d
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 7914770..e86a071 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -444,7 +444,7 @@
}
}
-status_t HWComposer::setClientTarget(int32_t displayId,
+status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot,
const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
android_dataspace_t dataspace) {
if (!isValidDisplay(displayId)) {
@@ -457,7 +457,8 @@
if ((target != nullptr) && target->getNativeBuffer()) {
handle = target->getNativeBuffer()->handle;
}
- auto error = hwcDisplay->setClientTarget(handle, acquireFence, dataspace);
+ auto error = hwcDisplay->setClientTarget(slot, handle,
+ acquireFence, dataspace);
if (error != HWC2::Error::None) {
ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
to_string(error).c_str(), static_cast<int32_t>(error));
@@ -894,5 +895,36 @@
*this = DisplayData();
}
+void HWComposerBufferCache::clear()
+{
+ mBuffers.clear();
+}
+
+void HWComposerBufferCache::getHwcBuffer(int slot,
+ const sp<GraphicBuffer>& buffer,
+ uint32_t* outSlot, sp<GraphicBuffer>* outBuffer)
+{
+ if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0) {
+ // default to slot 0
+ slot = 0;
+ }
+
+ if (static_cast<size_t>(slot) >= mBuffers.size()) {
+ mBuffers.resize(slot + 1);
+ }
+
+ *outSlot = slot;
+
+ if (mBuffers[slot] == buffer) {
+ // already cached in HWC, skip sending the buffer
+ *outBuffer = nullptr;
+ } else {
+ *outBuffer = buffer;
+
+ // update cache
+ mBuffers[slot] = buffer;
+ }
+}
+
// ---------------------------------------------------------------------------
}; // namespace android