summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kevin DuBois <kevindubois@google.com> 2019-04-29 10:09:43 -0700
committer Kevin DuBois <kevindubois@google.com> 2019-05-02 15:51:44 -0700
commit4efd1f505ce5587bba57e79dfb54eb1daff59eec (patch)
tree6f2ed1bdc6fd2715239755d6068c21b779a39814
parent501604c5fa4f485ae96470e6e2ba71a8c98b9c8f (diff)
sf: reuse luma sampling buffer when available
Reuse the luma sampling buffer when available, saving a frequent buffer reallocation. Depending on driver refcounting behavior, this could have resulted in the buffer free on the SF main thread (and typically did on referenced device, costing about ~500us @10hz). Test: verify luma sampling work reduces from ~2ms -> 1.5ms Test: RegionSamplingTest in libgui Fixes: 131416627 Change-Id: I8e6d57ae25bd37ceec828c82796f0f4f8f45636e
-rw-r--r--services/surfaceflinger/RegionSamplingThread.cpp19
-rw-r--r--services/surfaceflinger/RegionSamplingThread.h4
2 files changed, 18 insertions, 5 deletions
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 252ff0d611..0d142675db 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -377,10 +377,15 @@ void RegionSamplingThread::captureSample() {
mFlinger.traverseLayersInDisplay(device, filterVisitor);
};
- const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER;
- sp<GraphicBuffer> buffer =
- new GraphicBuffer(sampledArea.getWidth(), sampledArea.getHeight(),
- PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
+ sp<GraphicBuffer> buffer = nullptr;
+ if (mCachedBuffer && mCachedBuffer->getWidth() == sampledArea.getWidth() &&
+ mCachedBuffer->getHeight() == sampledArea.getHeight()) {
+ buffer = mCachedBuffer;
+ } else {
+ const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER;
+ buffer = new GraphicBuffer(sampledArea.getWidth(), sampledArea.getHeight(),
+ PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread");
+ }
// When calling into SF, we post a message into the SF message queue (so the
// screen capture runs on the main thread). This message blocks until the
@@ -415,6 +420,12 @@ void RegionSamplingThread::captureSample() {
for (size_t d = 0; d < activeDescriptors.size(); ++d) {
activeDescriptors[d].listener->onSampleCollected(lumas[d]);
}
+
+ // Extend the lifetime of mCachedBuffer from the previous frame to here to ensure that:
+ // 1) The region sampling thread is the last owner of the buffer, and the freeing of the buffer
+ // happens in this thread, as opposed to the main thread.
+ // 2) The listener(s) receive their notifications prior to freeing the buffer.
+ mCachedBuffer = buffer;
ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::noWorkNeeded));
}
diff --git a/services/surfaceflinger/RegionSamplingThread.h b/services/surfaceflinger/RegionSamplingThread.h
index 979642912b..72b20420ef 100644
--- a/services/surfaceflinger/RegionSamplingThread.h
+++ b/services/surfaceflinger/RegionSamplingThread.h
@@ -24,13 +24,13 @@
#include <android-base/thread_annotations.h>
#include <binder/IBinder.h>
+#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
#include <utils/StrongPointer.h>
#include "Scheduler/IdleTimer.h"
namespace android {
-class GraphicBuffer;
class IRegionSamplingListener;
class Layer;
class Scheduler;
@@ -121,6 +121,8 @@ private:
std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mMutex);
std::chrono::nanoseconds lastSampleTime GUARDED_BY(mMutex);
bool mDiscardedFrames GUARDED_BY(mMutex) = false;
+
+ sp<GraphicBuffer> mCachedBuffer GUARDED_BY(mMutex) = nullptr;
};
} // namespace android