#ifndef ANDROID_DRM_DISPLAY_COMPOSITOR_H_
#define ANDROID_DRM_DISPLAY_COMPOSITOR_H_
-#include "drm_hwcomposer.h"
-#include "drmcomposition.h"
-#include "drmcompositorworker.h"
+#include "drmhwcomposer.h"
+#include "drmdisplaycomposition.h"
#include "drmframebuffer.h"
-#include "seperate_rects.h"
+#include "separate_rects.h"
#include <pthread.h>
#include <memory>
-#include <queue>
#include <sstream>
#include <tuple>
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
-#define DRM_DISPLAY_BUFFERS 2
+// One for the front, one for the back, and one for cases where we need to
+// squash a frame that the hw can't display with hw overlays.
+#define DRM_DISPLAY_BUFFERS 3
namespace android {
class SquashState {
public:
- static const unsigned kHistoryLength = 6;
+ static const unsigned kHistoryLength = 6; // TODO: make this number not magic
static const unsigned kMaxLayers = 64;
struct Region {
}
void Init(DrmHwcLayer *layers, size_t num_layers);
- void GenerateHistory(DrmHwcLayer *layers,
+ void GenerateHistory(DrmHwcLayer *layers, size_t num_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,
+ void RecordHistory(DrmHwcLayer *layers, size_t num_layers,
const std::vector<bool> &changed_regions);
- void RecordSquashed(const std::vector<bool> &squashed_regions);
+ bool RecordAndCompareSquashed(const std::vector<bool> &squashed_regions);
void Dump(std::ostringstream *out) const;
int Init(DrmResources *drm, int display);
std::unique_ptr<DrmDisplayComposition> CreateComposition() const;
- int QueueComposition(std::unique_ptr<DrmDisplayComposition> composition);
+ int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition);
int Composite();
+ int SquashAll();
void Dump(std::ostringstream *out) const;
std::tuple<uint32_t, uint32_t, int> GetActiveModeResolution();
- bool HaveQueuedComposites() const;
-
SquashState *squash_state() {
- return NULL;
+ return &squash_state_;
}
+ bool uses_GL() {
+ return !!pre_compositor_;
+ }
private:
+ struct ModeState {
+ bool needs_modeset = false;
+ DrmMode mode;
+ uint32_t blob_id = 0;
+ uint32_t old_blob_id = 0;
+ };
+
DrmDisplayCompositor(const DrmDisplayCompositor &) = delete;
// We'll wait for acquire fences to fire for kAcquireWaitTimeoutMs,
int PrepareFramebuffer(DrmFramebuffer &fb,
DrmDisplayComposition *display_comp);
+ int ApplySquash(DrmDisplayComposition *display_comp);
int ApplyPreComposite(DrmDisplayComposition *display_comp);
- int ApplyFrame(DrmDisplayComposition *display_comp);
+ int PrepareFrame(DrmDisplayComposition *display_comp);
+ int CommitFrame(DrmDisplayComposition *display_comp, bool test_only);
+ int SquashFrame(DrmDisplayComposition *src, DrmDisplayComposition *dst);
int ApplyDpms(DrmDisplayComposition *display_comp);
int DisablePlanes(DrmDisplayComposition *display_comp);
+ void ClearDisplay();
+ void ApplyFrame(std::unique_ptr<DrmDisplayComposition> composition,
+ int status);
+
+ std::tuple<int, uint32_t> CreateModeBlob(const DrmMode &mode);
+
DrmResources *drm_;
int display_;
- DrmCompositorWorker worker_;
-
- std::queue<std::unique_ptr<DrmDisplayComposition>> composite_queue_;
std::unique_ptr<DrmDisplayComposition> active_composition_;
bool initialized_;
bool active_;
+ bool use_hw_overlays_;
- DrmMode next_mode_;
- bool needs_modeset_;
+ ModeState mode_;
int framebuffer_index_;
DrmFramebuffer framebuffers_[DRM_DISPLAY_BUFFERS];
std::unique_ptr<GLWorkerCompositor> pre_compositor_;
- // mutable since we need to acquire in HaveQueuedComposites
+ SquashState squash_state_;
+ int squash_framebuffer_index_;
+ DrmFramebuffer squash_framebuffers_[2];
+
+ // mutable since we need to acquire in Dump()
mutable pthread_mutex_t lock_;
// State tracking progress since our last Dump(). These are mutable since