drm_hwcomposer: ground work for squashing
This patch rearranges things to make squashing possible.
The high-level changes:
- A new Plan phase that happens in QueueComposition. This is where the
overlay allocation is moved to. It's also the only safe time that
the composition can try to plan squashing. This is because squashing
depends on the exact ordering of compositions.
- GLWorker now renders regions rather than layers. A region in this case is
a clipping rectange and set of layers that are to be rendered in that
rectangle. This is always what GLWorker did in the end, but now the work
to seperate layers into regions is done externally. This was changed
because the output of SquashState is a list of stable regions that need to
be put through GLWorker
The Plan methods of the Compositions are responsible for updating per-display
SquashState and for allocation regions/layers to squashing, pre-composition, or
hardware overlay. Because of the drastic changes to how composition planning
works, it was necessary to bundle it with the GLWorker change.
This change also includes plenty of other refactorings that were deemed to
be too painful to try and seperate into another change.
Change-Id: Ie7bfe077067e936a0862a07cbe87b525eab8d4f8
diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h
index 89d5b67..22e1efc 100644
--- a/drmdisplaycompositor.h
+++ b/drmdisplaycompositor.h
@@ -21,10 +21,13 @@
#include "drmcomposition.h"
#include "drmcompositorworker.h"
#include "drmframebuffer.h"
+#include "seperate_rects.h"
#include <pthread.h>
+#include <memory>
#include <queue>
#include <sstream>
+#include <tuple>
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
@@ -35,6 +38,45 @@
class GLWorkerCompositor;
+class SquashState {
+ public:
+ static const unsigned kHistoryLength = 6;
+ static const unsigned kMaxLayers = 64;
+
+ struct Region {
+ DrmHwcRect<int> rect;
+ std::bitset<kMaxLayers> layer_refs;
+ std::bitset<kHistoryLength> change_history;
+ bool squashed = false;
+ };
+
+ bool is_stable(int region_index) const {
+ return valid_history_ >= kHistoryLength &&
+ regions_[region_index].change_history.none();
+ }
+
+ const std::vector<Region> ®ions() const {
+ return regions_;
+ }
+
+ void Init(DrmHwcLayer *layers, size_t num_layers);
+ void GenerateHistory(DrmHwcLayer *layers,
+ std::vector<bool> &changed_regions) const;
+ void StableRegionsWithMarginalHistory(
+ const std::vector<bool> &changed_regions,
+ std::vector<bool> &stable_regions) const;
+ void RecordHistory(DrmHwcLayer *layers,
+ const std::vector<bool> &changed_regions);
+ void RecordSquashed(const std::vector<bool> &squashed_regions);
+
+ private:
+ size_t generation_number_ = 0;
+ unsigned valid_history_ = 0;
+ std::vector<buffer_handle_t> last_handles_;
+
+ std::vector<Region> regions_;
+};
+
class DrmDisplayCompositor {
public:
DrmDisplayCompositor();
@@ -42,12 +84,19 @@
int Init(DrmResources *drm, int display);
+ std::unique_ptr<DrmDisplayComposition> CreateComposition() const;
int QueueComposition(std::unique_ptr<DrmDisplayComposition> composition);
int Composite();
void Dump(std::ostringstream *out) const;
+ std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();
+
bool HaveQueuedComposites() const;
+ SquashState *squash_state() {
+ return NULL;
+ }
+
private:
DrmDisplayCompositor(const DrmDisplayCompositor &) = delete;
@@ -56,6 +105,8 @@
static const int kAcquireWaitTries = 5;
static const int kAcquireWaitTimeoutMs = 100;
+ int PrepareFramebuffer(DrmFramebuffer &fb,
+ DrmDisplayComposition *display_comp);
int ApplyPreComposite(DrmDisplayComposition *display_comp);
int ApplyFrame(DrmDisplayComposition *display_comp);
int ApplyDpms(DrmDisplayComposition *display_comp);