drm_hwcomposer: add scene flattening
Flattening of a scene is triggered if it doesn't change for a while.
As of now there is a separate thread which triggers flattening if the
scene did not change in last 60 vsyncs.
There are two options for flattening a scene:
* Serial, by using a writeback connector attached to the same crtc as
the one driving the display. This happens only if possible_clones
mask reports that the display encoder and writeback encoder could
work simultaneously.
The steps for achieving this are:
1. Build a commit that enables writeback connector, we don't need to
build a commit that contains the entire active_composition, just
set the writeback specific properties a let the kernel duplicate
the rest of the state.
2. Commit and wait for writeback_fence to fire.
3. Setup a composition with just one plane enabled.
4. Apply the composition if a new one has not been applied meanwhile.
* Concurrent, by comitting the scene to a new unused crtc (state !=
DRM_MODE_CONNECTED) and getting the result back through a writeback
connector.
The steps for achieving this are:
1. Copy layers from active composition.
2. Plan layers of copy on the unused crtc. This is realized by using a
newly created DrmDisplayCompositor object.
3. Commit copy to the unsed crtc and get the result as a drmhwclayer.
4. Setup a composition with just one plane enabled. Re-importing the
buffers might be needed since we might have been using a different
dri node.
5. Apply the composition if a new one has not been applied while doing
the flattening
Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
diff --git a/resourcemanager.cpp b/resourcemanager.cpp
index 80a67b7..9566fda 100644
--- a/resourcemanager.cpp
+++ b/resourcemanager.cpp
@@ -72,6 +72,24 @@
return ret;
}
+DrmConnector *ResourceManager::AvailableWritebackConnector(int display) {
+ DrmDevice *drm_device = GetDrmDevice(display);
+ DrmConnector *writeback_conn = NULL;
+ if (drm_device) {
+ writeback_conn = drm_device->AvailableWritebackConnector(display);
+ if (writeback_conn)
+ return writeback_conn;
+ }
+ for (auto &drm : drms_) {
+ if (drm.get() == drm_device)
+ continue;
+ writeback_conn = drm->AvailableWritebackConnector(display);
+ if (writeback_conn)
+ return writeback_conn;
+ }
+ return writeback_conn;
+}
+
DrmDevice *ResourceManager::GetDrmDevice(int display) {
for (auto &drm : drms_) {
if (drm->HandlesDisplay(display))