[sf] Implement addSamplingListener
Implements ISurfaceComposer::addSamplingListener, which allows a client
to receive streaming median luma updates for a given region of the
screen.
Bug: 119639245
Test: Manual using SamplingDemo in libgui
Test: Automated libgui_test in Ic85a97f475a3414a79d3719bbd0b2b648bbccfb0
Change-Id: Ic52359aeab884e734a806372be0eb4e327c45298
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8530309..6d10986 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -401,6 +401,9 @@
property_get("debug.sf.use_smart_90_for_video", value, "0");
mUseSmart90ForVideo = atoi(value);
+ property_get("debug.sf.luma_sampling", value, "1");
+ mLumaSampling = atoi(value);
+
const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
mVsyncModulator.setPhaseOffsets(early, gl, late);
@@ -1308,17 +1311,20 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::addRegionSamplingListener(
- const Rect& /*samplingArea*/, const sp<IBinder>& /*stopLayerHandle*/,
- const sp<IRegionSamplingListener>& /*listener*/) {
+status_t SurfaceFlinger::addRegionSamplingListener(const Rect& samplingArea,
+ const sp<IBinder>& stopLayerHandle,
+ const sp<IRegionSamplingListener>& listener) {
+ if (!listener) {
+ return BAD_VALUE;
+ }
+ mRegionSamplingThread->addListener(samplingArea, stopLayerHandle, listener);
return NO_ERROR;
}
-status_t SurfaceFlinger::removeRegionSamplingListener(
- const sp<IRegionSamplingListener>& /*listener*/) {
+status_t SurfaceFlinger::removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) {
+ mRegionSamplingThread->removeListener(listener);
return NO_ERROR;
}
-
// ----------------------------------------------------------------------------
sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
@@ -2172,6 +2178,10 @@
mTransactionCompletedThread.addPresentFence(mPreviousPresentFence);
mTransactionCompletedThread.sendCallbacks();
+ if (mLumaSampling) {
+ mRegionSamplingThread->sampleNow();
+ }
+
ASSERT_ON_STACK_GUARD();
}
#pragma clang optimize on // b/119477596
@@ -5475,6 +5485,13 @@
static_cast<android_pixel_format>(reqPixelFormat), 1,
usage, "screenshot");
+ return captureScreenCore(renderArea, traverseLayers, *outBuffer, useIdentityTransform);
+}
+
+status_t SurfaceFlinger::captureScreenCore(RenderArea& renderArea,
+ TraverseLayersFunction traverseLayers,
+ const sp<GraphicBuffer>& buffer,
+ bool useIdentityTransform) {
// This mutex protects syncFd and captureResult for communication of the return values from the
// main thread back to this Binder thread
std::mutex captureMutex;
@@ -5502,7 +5519,7 @@
{
Mutex::Autolock _l(mStateLock);
renderArea.render([&] {
- result = captureScreenImplLocked(renderArea, traverseLayers, (*outBuffer).get(),
+ result = captureScreenImplLocked(renderArea, traverseLayers, buffer.get(),
useIdentityTransform, forSystem, &fd);
});
}