diff options
author | 2024-09-17 11:45:38 -0700 | |
---|---|---|
committer | 2024-09-17 21:15:58 +0000 | |
commit | b96661ff006d9b0635de11f8be510e19f68d532f (patch) | |
tree | 0e457551c41d4e7aa808c7b428ff8876c720dcaa /libs/gui/BufferQueueProducer.cpp | |
parent | dec962bc0aeb487e19dddcd6d769a65248bd9a2e (diff) |
BufferQueueProducer: queueBuffer() CPU throttling only in async mode
BufferQueueProducer throttles an EGL client in queueBuffer() until
the GPU has finished the previous frame. This behavior was intended
to solve some issues with "swap interval 0" (aka async mode) but
was performed all the time.
In turn, is prevented a "well behaved" applications from throttling
itself, because it would be throttled by BufferQueueProduced
before it could get a chance to do so. From the app perspective,
eglSwapBuffers() would block.
Here we perform the throttling only in async mode, as was the
original intention. Applications that don't pace themselves,
will still be blocked in dequeueBuffer() eventually, albeit,
not necessarily in eglSwapBuffers().
Fix: 359252619
Test: manually tested on pixel8 using AGI and filament sample app
Flag: com.android.graphics.libgui.flags.bq_producer_throttles_only_async_mode
Change-Id: Ie73848fbf609061bb6feceba5b5c5ad86ec8e07c
Diffstat (limited to 'libs/gui/BufferQueueProducer.cpp')
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index a4d105d320..da74e9cde6 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -45,7 +45,10 @@ #include <system/window.h> +#include <com_android_graphics_libgui_flags.h> + namespace android { +using namespace com::android::graphics::libgui; // Macros for include BufferQueueCore information in log messages #define BQ_LOGV(x, ...) \ @@ -924,6 +927,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, uint64_t currentFrameNumber = 0; BufferItem item; int connectedApi; + bool enableEglCpuThrottling = true; sp<Fence> lastQueuedFence; { // Autolock scope @@ -1097,6 +1101,9 @@ status_t BufferQueueProducer::queueBuffer(int slot, VALIDATE_CONSISTENCY(); connectedApi = mCore->mConnectedApi; + if (flags::bq_producer_throttles_only_async_mode()) { + enableEglCpuThrottling = mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock; + } lastQueuedFence = std::move(mLastQueueBufferFence); mLastQueueBufferFence = std::move(acquireFence); @@ -1142,7 +1149,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, } // Wait without lock held - if (connectedApi == NATIVE_WINDOW_API_EGL) { + if (connectedApi == NATIVE_WINDOW_API_EGL && enableEglCpuThrottling) { // Waiting here allows for two full buffers to be queued but not a // third. In the event that frames take varying time, this makes a // small trade-off in favor of latency rather than throughput. |