drm_hwcomposer: Remove GL compositing support
The GL based compositing adds alot of complexity and was only ever well
tested on closed stacks. It also only supports GLES3.x and still relies
on sw_sync timeline which is now a debugfs feature. Those are just the
known issues.
Removing the GL compositor means everything related to squashing layers
and pre-compositing can be removed. The planner is left as it may be
useful when adding back support for overlay planes. With this change,
only a single plane is supported until ValidateDisplay learns to do
atomic modesetting test for overlay planes.
Tested-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Rob Herring <robh@kernel.org>
diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp
index 24a8e9c..ccf2676 100644
--- a/drmdisplaycomposition.cpp
+++ b/drmdisplaycomposition.cpp
@@ -29,17 +29,12 @@
#include <unordered_set>
#include <log/log.h>
-#include <sw_sync.h>
#include <sync/sync.h>
#include <xf86drmMode.h>
namespace android {
DrmDisplayComposition::~DrmDisplayComposition() {
- if (timeline_fd_ >= 0) {
- SignalCompositionDone();
- close(timeline_fd_);
- }
}
int DrmDisplayComposition::Init(DrmResources *drm, DrmCrtc *crtc,
@@ -51,12 +46,6 @@
planner_ = planner;
frame_no_ = frame_no;
- int ret = sw_sync_timeline_create();
- if (ret < 0) {
- ALOGE("Failed to create sw sync timeline %d", ret);
- return ret;
- }
- timeline_fd_ = ret;
return 0;
}
@@ -64,26 +53,6 @@
return type_ == DRM_COMPOSITION_TYPE_EMPTY || type_ == des;
}
-int DrmDisplayComposition::CreateNextTimelineFence() {
- ++timeline_;
- return sw_sync_fence_create(timeline_fd_, "hwc drm display composition fence",
- timeline_);
-}
-
-int DrmDisplayComposition::IncreaseTimelineToPoint(int point) {
- int timeline_increase = point - timeline_current_;
- if (timeline_increase <= 0)
- return 0;
-
- int ret = sw_sync_timeline_inc(timeline_fd_, timeline_increase);
- if (ret)
- ALOGE("Failed to increment sync timeline %d", ret);
- else
- timeline_current_ = point;
-
- return ret;
-}
-
int DrmDisplayComposition::SetLayers(DrmHwcLayer *layers, size_t num_layers,
bool geometry_changed) {
if (!validate_composition_type(DRM_COMPOSITION_TYPE_FRAME))
@@ -122,253 +91,37 @@
return 0;
}
-static std::vector<size_t> SetBitsToVector(
- uint64_t in, const std::vector<size_t> &index_map) {
- std::vector<size_t> out;
- size_t msb = sizeof(in) * 8 - 1;
- uint64_t mask = (uint64_t)1 << msb;
- for (size_t i = msb; mask != (uint64_t)0; i--, mask >>= 1)
- if (in & mask)
- out.push_back(index_map[i]);
- return out;
-}
-
int DrmDisplayComposition::AddPlaneComposition(DrmCompositionPlane plane) {
composition_planes_.emplace_back(std::move(plane));
return 0;
}
-void DrmDisplayComposition::SeparateLayers(DrmHwcRect<int> *exclude_rects,
- size_t num_exclude_rects) {
- DrmCompositionPlane *comp = NULL;
+void DrmDisplayComposition::SeparateLayers(DrmHwcRect<int> *, size_t) {
std::vector<size_t> dedicated_layers;
- // Go through the composition and find the precomp layer as well as any
- // layers that have a dedicated plane located below the precomp layer.
+ // Go through the composition and find the layers that have a dedicated plane.
for (auto &i : composition_planes_) {
if (i.type() == DrmCompositionPlane::Type::kLayer) {
dedicated_layers.insert(dedicated_layers.end(), i.source_layers().begin(),
i.source_layers().end());
- } else if (i.type() == DrmCompositionPlane::Type::kPrecomp) {
- comp = &i;
- break;
}
}
- if (!comp)
- return;
-
- const std::vector<size_t> &comp_layers = comp->source_layers();
- if (comp_layers.size() > 64) {
- ALOGE("Failed to separate layers because there are more than 64");
- return;
- }
-
- // Index at which the actual layers begin
- size_t layer_offset = num_exclude_rects + dedicated_layers.size();
- if (comp_layers.size() + layer_offset > 64) {
- ALOGW(
- "Exclusion rectangles are being truncated to make the rectangle count "
- "fit into 64");
- num_exclude_rects = 64 - comp_layers.size() - dedicated_layers.size();
- }
-
- // We inject all the exclude rects into the rects list. Any resulting rect
- // that includes ANY of the first num_exclude_rects is rejected. After the
- // exclude rects, we add the lower layers. The rects that intersect with
- // these layers will be inspected and only those which are to be composited
- // above the layer will be included in the composition regions.
- std::vector<DrmHwcRect<int>> layer_rects(comp_layers.size() + layer_offset);
- std::copy(exclude_rects, exclude_rects + num_exclude_rects,
- layer_rects.begin());
- std::transform(
- dedicated_layers.begin(), dedicated_layers.end(),
- layer_rects.begin() + num_exclude_rects,
- [=](size_t layer_index) { return layers_[layer_index].display_frame; });
- std::transform(comp_layers.begin(), comp_layers.end(),
- layer_rects.begin() + layer_offset, [=](size_t layer_index) {
- return layers_[layer_index].display_frame;
- });
-
- std::vector<separate_rects::RectSet<uint64_t, int>> separate_regions;
- separate_rects::separate_rects_64(layer_rects, &separate_regions);
- uint64_t exclude_mask = ((uint64_t)1 << num_exclude_rects) - 1;
- uint64_t dedicated_mask = (((uint64_t)1 << dedicated_layers.size()) - 1)
- << num_exclude_rects;
-
- for (separate_rects::RectSet<uint64_t, int> ®ion : separate_regions) {
- if (region.id_set.getBits() & exclude_mask)
- continue;
-
- // If a rect intersects one of the dedicated layers, we need to remove the
- // layers from the composition region which appear *below* the dedicated
- // layer. This effectively punches a hole through the composition layer such
- // that the dedicated layer can be placed below the composition and not
- // be occluded.
- uint64_t dedicated_intersect = region.id_set.getBits() & dedicated_mask;
- for (size_t i = 0; dedicated_intersect && i < dedicated_layers.size();
- ++i) {
- // Only exclude layers if they intersect this particular dedicated layer
- if (!(dedicated_intersect & (1 << (i + num_exclude_rects))))
- continue;
-
- for (size_t j = 0; j < comp_layers.size(); ++j) {
- if (comp_layers[j] < dedicated_layers[i])
- region.id_set.subtract(j + layer_offset);
- }
- }
- if (!(region.id_set.getBits() >> layer_offset))
- continue;
-
- pre_comp_regions_.emplace_back(DrmCompositionRegion{
- region.rect,
- SetBitsToVector(region.id_set.getBits() >> layer_offset, comp_layers)});
- }
}
-int DrmDisplayComposition::CreateAndAssignReleaseFences() {
- std::unordered_set<DrmHwcLayer *> squash_layers;
- std::unordered_set<DrmHwcLayer *> pre_comp_layers;
- std::unordered_set<DrmHwcLayer *> comp_layers;
-
- for (const DrmCompositionRegion ®ion : squash_regions_) {
- for (size_t source_layer_index : region.source_layers) {
- DrmHwcLayer *source_layer = &layers_[source_layer_index];
- squash_layers.emplace(source_layer);
- }
- }
-
- for (const DrmCompositionRegion ®ion : pre_comp_regions_) {
- for (size_t source_layer_index : region.source_layers) {
- DrmHwcLayer *source_layer = &layers_[source_layer_index];
- pre_comp_layers.emplace(source_layer);
- squash_layers.erase(source_layer);
- }
- }
-
- for (const DrmCompositionPlane &plane : composition_planes_) {
- if (plane.type() == DrmCompositionPlane::Type::kLayer) {
- for (auto i : plane.source_layers()) {
- DrmHwcLayer *source_layer = &layers_[i];
- comp_layers.emplace(source_layer);
- pre_comp_layers.erase(source_layer);
- }
- }
- }
-
- for (DrmHwcLayer *layer : squash_layers) {
- if (!layer->release_fence)
- continue;
- int ret = layer->release_fence.Set(CreateNextTimelineFence());
- if (ret < 0) {
- ALOGE("Failed to set the release fence (squash) %d", ret);
- return ret;
- }
- }
- timeline_squash_done_ = timeline_;
-
- for (DrmHwcLayer *layer : pre_comp_layers) {
- if (!layer->release_fence)
- continue;
- int ret = layer->release_fence.Set(CreateNextTimelineFence());
- if (ret < 0)
- return ret;
- }
- timeline_pre_comp_done_ = timeline_;
-
- for (DrmHwcLayer *layer : comp_layers) {
- if (!layer->release_fence)
- continue;
- int ret = layer->release_fence.Set(CreateNextTimelineFence());
- if (ret < 0) {
- ALOGE("Failed to set the release fence (comp) %d", ret);
- return ret;
- }
- }
-
- return 0;
-}
-
-int DrmDisplayComposition::Plan(SquashState *squash,
- std::vector<DrmPlane *> *primary_planes,
+int DrmDisplayComposition::Plan(std::vector<DrmPlane *> *primary_planes,
std::vector<DrmPlane *> *overlay_planes) {
if (type_ != DRM_COMPOSITION_TYPE_FRAME)
return 0;
- // Used to track which layers should be sent to the planner. We exclude layers
- // that are entirely squashed so the planner can provision a precomposition
- // layer as appropriate (ex: if 5 layers are squashed and 1 is not, we don't
- // want to plan a precomposition layer that will be comprised of the already
- // squashed layers).
std::map<size_t, DrmHwcLayer *> to_composite;
- bool use_squash_framebuffer = false;
- // Used to determine which layers were entirely squashed
- std::vector<int> layer_squash_area(layers_.size(), 0);
- // Used to avoid rerendering regions that were squashed
- std::vector<DrmHwcRect<int>> exclude_rects;
- if (squash != NULL) {
- if (geometry_changed_) {
- squash->Init(layers_.data(), layers_.size());
- } else {
- std::vector<bool> changed_regions;
- squash->GenerateHistory(layers_.data(), layers_.size(), changed_regions);
-
- std::vector<bool> stable_regions;
- squash->StableRegionsWithMarginalHistory(changed_regions, stable_regions);
-
- // Only if SOME region is stable
- use_squash_framebuffer =
- std::find(stable_regions.begin(), stable_regions.end(), true) !=
- stable_regions.end();
-
- squash->RecordHistory(layers_.data(), layers_.size(), changed_regions);
-
- // Changes in which regions are squashed triggers a rerender via
- // squash_regions.
- bool render_squash = squash->RecordAndCompareSquashed(stable_regions);
-
- for (size_t region_index = 0; region_index < stable_regions.size();
- region_index++) {
- const SquashState::Region ®ion = squash->regions()[region_index];
- if (!stable_regions[region_index])
- continue;
-
- exclude_rects.emplace_back(region.rect);
-
- if (render_squash) {
- squash_regions_.emplace_back();
- squash_regions_.back().frame = region.rect;
- }
-
- int frame_area = region.rect.area();
- // Source layers are sorted front to back i.e. top layer has lowest
- // index.
- for (size_t layer_index = layers_.size();
- layer_index-- > 0; // Yes, I double checked this
- /* See condition */) {
- if (!region.layer_refs[layer_index])
- continue;
- layer_squash_area[layer_index] += frame_area;
- if (render_squash)
- squash_regions_.back().source_layers.push_back(layer_index);
- }
- }
- }
-
- for (size_t i = 0; i < layers_.size(); ++i) {
- if (layer_squash_area[i] < layers_[i].display_frame.area())
- to_composite.emplace(std::make_pair(i, &layers_[i]));
- }
- } else {
- for (size_t i = 0; i < layers_.size(); ++i)
- to_composite.emplace(std::make_pair(i, &layers_[i]));
- }
+ for (size_t i = 0; i < layers_.size(); ++i)
+ to_composite.emplace(std::make_pair(i, &layers_[i]));
int ret;
std::vector<DrmCompositionPlane> plan;
- std::tie(ret, composition_planes_) =
- planner_->ProvisionPlanes(to_composite, use_squash_framebuffer, crtc_,
- primary_planes, overlay_planes);
+ std::tie(ret, composition_planes_) = planner_->ProvisionPlanes(
+ to_composite, crtc_, primary_planes, overlay_planes);
if (ret) {
ALOGE("Planner failed provisioning planes ret=%d", ret);
return ret;
@@ -396,17 +149,7 @@
}
}
- return FinalizeComposition(exclude_rects.data(), exclude_rects.size());
-}
-
-int DrmDisplayComposition::FinalizeComposition() {
- return FinalizeComposition(NULL, 0);
-}
-
-int DrmDisplayComposition::FinalizeComposition(DrmHwcRect<int> *exclude_rects,
- size_t num_exclude_rects) {
- SeparateLayers(exclude_rects, num_exclude_rects);
- return CreateAndAssignReleaseFences();
+ return 0;
}
static const char *DrmCompositionTypeToString(DrmCompositionType type) {
@@ -506,23 +249,6 @@
}
}
-static void DumpRegion(const DrmCompositionRegion ®ion,
- std::ostringstream *out) {
- *out << "frame";
- region.frame.Dump(out);
- *out << " source_layers=(";
-
- const std::vector<size_t> &source_layers = region.source_layers;
- for (size_t i = 0; i < source_layers.size(); i++) {
- *out << source_layers[i];
- if (i < source_layers.size() - 1) {
- *out << " ";
- }
- }
-
- *out << ")";
-}
-
void DrmDisplayComposition::Dump(std::ostringstream *out) const {
*out << "----DrmDisplayComposition"
<< " crtc=" << (crtc_ ? crtc_->id() : -1)
@@ -540,10 +266,6 @@
break;
}
- *out << " timeline[current/squash/pre-comp/done]=" << timeline_current_ << "/"
- << timeline_squash_done_ << "/" << timeline_pre_comp_done_ << "/"
- << timeline_ << "\n";
-
*out << " Layers: count=" << layers_.size() << "\n";
for (size_t i = 0; i < layers_.size(); i++) {
const DrmHwcLayer &layer = layers_[i];
@@ -578,12 +300,6 @@
case DrmCompositionPlane::Type::kLayer:
*out << "LAYER";
break;
- case DrmCompositionPlane::Type::kPrecomp:
- *out << "PRECOMP";
- break;
- case DrmCompositionPlane::Type::kSquash:
- *out << "SQUASH";
- break;
default:
*out << "<invalid>";
break;
@@ -595,19 +311,5 @@
}
*out << "\n";
}
-
- *out << " Squash Regions: count=" << squash_regions_.size() << "\n";
- for (size_t i = 0; i < squash_regions_.size(); i++) {
- *out << " [" << i << "] ";
- DumpRegion(squash_regions_[i], out);
- *out << "\n";
- }
-
- *out << " Pre-Comp Regions: count=" << pre_comp_regions_.size() << "\n";
- for (size_t i = 0; i < pre_comp_regions_.size(); i++) {
- *out << " [" << i << "] ";
- DumpRegion(pre_comp_regions_[i], out);
- *out << "\n";
- }
}
}