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/drmdisplaycompositor.h b/drmdisplaycompositor.h
index bc13d4c..7d46416 100644
--- a/drmdisplaycompositor.h
+++ b/drmdisplaycompositor.h
@@ -21,6 +21,7 @@
#include "drmdisplaycomposition.h"
#include "drmframebuffer.h"
#include "resourcemanager.h"
+#include "vsyncworker.h"
#include <pthread.h>
#include <memory>
@@ -34,6 +35,10 @@
// squash a frame that the hw can't display with hw overlays.
#define DRM_DISPLAY_BUFFERS 3
+// If a scene is still for this number of vblanks flatten it to reduce power
+// consumption.
+#define FLATTEN_COUNTDOWN_INIT 60
+
namespace android {
class DrmDisplayCompositor {
@@ -44,10 +49,12 @@
int Init(ResourceManager *resource_manager, int display);
std::unique_ptr<DrmDisplayComposition> CreateComposition() const;
+ std::unique_ptr<DrmDisplayComposition> CreateInitializedComposition() const;
int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition);
int TestComposition(DrmDisplayComposition *composition);
int Composite();
void Dump(std::ostringstream *out) const;
+ void Vsync(int display, int64_t timestamp);
std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();
@@ -66,16 +73,26 @@
static const int kAcquireWaitTries = 5;
static const int kAcquireWaitTimeoutMs = 100;
- int PrepareFramebuffer(DrmFramebuffer &fb,
- DrmDisplayComposition *display_comp);
- int PrepareFrame(DrmDisplayComposition *display_comp);
- int CommitFrame(DrmDisplayComposition *display_comp, bool test_only);
+ int CommitFrame(DrmDisplayComposition *display_comp, bool test_only,
+ DrmConnector *writeback_conn = NULL,
+ DrmHwcBuffer *writeback_buffer = NULL);
+ int SetupWritebackCommit(drmModeAtomicReqPtr pset, uint32_t crtc_id,
+ DrmConnector *writeback_conn,
+ DrmHwcBuffer *writeback_buffer);
int ApplyDpms(DrmDisplayComposition *display_comp);
int DisablePlanes(DrmDisplayComposition *display_comp);
void ClearDisplay();
void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition,
- int status);
+ int status, bool writeback = false);
+ int FlattenActiveComposition();
+ int FlattenSerial(DrmConnector *writeback_conn);
+ int FlattenConcurrent(DrmConnector *writeback_conn);
+ int FlattenOnDisplay(std::unique_ptr<DrmDisplayComposition> &src,
+ DrmConnector *writeback_conn, DrmMode &src_mode,
+ DrmHwcLayer *writeback_layer);
+
+ bool CountdownExpired() const;
std::tuple<int, uint32_t> CreateModeBlob(const DrmMode &mode);
@@ -100,6 +117,10 @@
// we need to reset them on every Dump() call.
mutable uint64_t dump_frames_composited_;
mutable uint64_t dump_last_timestamp_ns_;
+ VSyncWorker vsync_worker_;
+ int64_t flatten_countdown_;
+ std::unique_ptr<Planner> planner_;
+ int writeback_fence_;
};
}