Merge "drm_hwcomposer: fix logic error in premult blending" into mnc-dr-dev
diff --git a/autogl.h b/autogl.h
index 5eeca85..fc77fb0 100644
--- a/autogl.h
+++ b/autogl.h
@@ -52,8 +52,7 @@
AUTO_GL_TYPE(AutoGLProgram, GLint, 0, glDeleteProgram(p))
struct AutoEGLDisplayImage {
- AutoEGLDisplayImage() : display_(EGL_NO_DISPLAY), image_(EGL_NO_IMAGE_KHR) {
- }
+ AutoEGLDisplayImage() = default;
AutoEGLDisplayImage(EGLDisplay display, EGLImageKHR image)
: display_(display), image_(image) {
@@ -98,8 +97,8 @@
}
private:
- EGLDisplay display_;
- EGLImageKHR image_;
+ EGLDisplay display_ = EGL_NO_DISPLAY;
+ EGLImageKHR image_ = EGL_NO_IMAGE_KHR;
};
struct AutoEGLImageAndGLTexture {
diff --git a/drm_hwcomposer.h b/drm_hwcomposer.h
index fdf389b..1490438 100644
--- a/drm_hwcomposer.h
+++ b/drm_hwcomposer.h
@@ -175,7 +175,7 @@
return importer_ != NULL;
}
- hwc_drm_bo *operator->();
+ const hwc_drm_bo *operator->() const;
void Clear();
@@ -257,11 +257,12 @@
UniqueFd acquire_fence;
OutputFd release_fence;
- DrmHwcLayer() = default;
- DrmHwcLayer(DrmHwcLayer &&rhs) = default;
-
int InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer,
const gralloc_module_t *gralloc);
+
+ buffer_handle_t get_usable_handle() const {
+ return handle.get() != NULL ? handle.get() : sf_handle;
+ }
};
struct DrmHwcDisplayContents {
diff --git a/drmcomposition.cpp b/drmcomposition.cpp
index 55fa00c..4b293ee 100644
--- a/drmcomposition.cpp
+++ b/drmcomposition.cpp
@@ -58,10 +58,9 @@
// If the display hasn't been modeset yet, this will be NULL
DrmCrtc *crtc = drm_->GetCrtcForDisplay(display);
- int ret = composition_map_[(*iter)->display()]->Init(drm_, crtc, importer_,
- frame_no);
+ int ret = composition_map_[display]->Init(drm_, crtc, importer_, frame_no);
if (ret) {
- ALOGE("Failed to init display composition for %d", (*iter)->display());
+ ALOGE("Failed to init display composition for %d", display);
return ret;
}
}
diff --git a/drmcompositor.cpp b/drmcompositor.cpp
index ad4cf88..b486d7b 100644
--- a/drmcompositor.cpp
+++ b/drmcompositor.cpp
@@ -76,7 +76,7 @@
int ret = compositor_map_[display].QueueComposition(
composition->TakeDisplayComposition(display));
if (ret) {
- ALOGE("Failed to queue composition for display %d", display);
+ ALOGE("Failed to queue composition for display %d (%d)", display, ret);
return ret;
}
}
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index 5676f1d..3b3deef 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -300,7 +300,12 @@
for (DrmCompositionLayer &layer : *layers) {
int acquire_fence = layer.acquire_fence.get();
if (acquire_fence >= 0) {
- ret = sync_wait(acquire_fence, kAcquireWaitTimeoutMs);
+ for (int i = 0; i < kAcquireWaitTries; ++i) {
+ ret = sync_wait(acquire_fence, kAcquireWaitTimeoutMs);
+ if (ret)
+ ALOGW("Acquire fence %d wait %d failed (%d). Total time %d",
+ acquire_fence, i, ret, (i + 1) * kAcquireWaitTimeoutMs);
+ }
if (ret) {
ALOGE("Failed to wait for acquire %d/%d", acquire_fence, ret);
drmModePropertySetFree(pset);
diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h
index 0f3a12f..419960c 100644
--- a/drmdisplaycompositor.h
+++ b/drmdisplaycompositor.h
@@ -51,9 +51,10 @@
private:
DrmDisplayCompositor(const DrmDisplayCompositor &) = delete;
- // Set to 83ms (~12fps) which is somewhere between a reasonable amount of
- // time to wait for a long render and a small enough delay to limit jank.
- static const int kAcquireWaitTimeoutMs = 83;
+ // We'll wait for acquire fences to fire for kAcquireWaitTimeoutMs,
+ // kAcquireWaitTries times, logging a warning in between.
+ static const int kAcquireWaitTries = 5;
+ static const int kAcquireWaitTimeoutMs = 100;
int ApplyPreComposite(DrmDisplayComposition *display_comp);
int ApplyFrame(DrmDisplayComposition *display_comp);
diff --git a/hwcomposer.cpp b/hwcomposer.cpp
index a7c9e43..6a0f4cd 100644
--- a/hwcomposer.cpp
+++ b/hwcomposer.cpp
@@ -191,9 +191,9 @@
return *this;
}
-hwc_drm_bo *DrmHwcBuffer::operator->() {
+const hwc_drm_bo *DrmHwcBuffer::operator->() const {
if (importer_ == NULL) {
- ALOGE("Access of none existent BO");
+ ALOGE("Access of non-existent BO");
exit(1);
return NULL;
}
@@ -264,16 +264,15 @@
int DrmHwcLayer::InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer,
const gralloc_module_t *gralloc) {
sf_handle = sf_layer->handle;
- int ret = buffer.ImportBuffer(sf_layer->handle, importer);
- if (ret)
- return ret;
-
- ret = handle.CopyBufferHandle(sf_layer->handle, gralloc);
- if (ret)
- return ret;
-
alpha = sf_layer->planeAlpha;
+ source_crop = DrmHwcRect<float>(
+ sf_layer->sourceCropf.left, sf_layer->sourceCropf.top,
+ sf_layer->sourceCropf.right, sf_layer->sourceCropf.bottom);
+ display_frame = DrmHwcRect<int>(
+ sf_layer->displayFrame.left, sf_layer->displayFrame.top,
+ sf_layer->displayFrame.right, sf_layer->displayFrame.bottom);
+
switch (sf_layer->transform) {
case 0:
transform = DrmHwcTransform::kIdentity;
@@ -313,12 +312,13 @@
return -EINVAL;
}
- source_crop = DrmHwcRect<float>(
- sf_layer->sourceCropf.left, sf_layer->sourceCropf.top,
- sf_layer->sourceCropf.right, sf_layer->sourceCropf.bottom);
- display_frame = DrmHwcRect<int>(
- sf_layer->displayFrame.left, sf_layer->displayFrame.top,
- sf_layer->displayFrame.right, sf_layer->displayFrame.bottom);
+ int ret = buffer.ImportBuffer(sf_layer->handle, importer);
+ if (ret)
+ return ret;
+
+ ret = handle.CopyBufferHandle(sf_layer->handle, gralloc);
+ if (ret)
+ return ret;
return 0;
}
@@ -501,13 +501,18 @@
layers_map.emplace_back();
DrmCompositionDisplayLayersMap &map = layers_map.back();
+ map.display = i;
std::vector<size_t> &indices_to_composite = layers_indices[i];
for (size_t j : indices_to_composite) {
hwc_layer_1_t *sf_layer = &dc->hwLayers[j];
DrmHwcLayer &layer = display_contents.layers[j];
- layer.InitFromHwcLayer(sf_layer, ctx->importer, ctx->gralloc);
+ ret = layer.InitFromHwcLayer(sf_layer, ctx->importer, ctx->gralloc);
+ if (ret) {
+ ALOGE("Failed to init composition from layer %d", ret);
+ return ret;
+ }
map.layers.emplace_back(std::move(layer));
}
}
diff --git a/seperate_rects.cpp b/seperate_rects.cpp
index bdf07bc..06fbe39 100644
--- a/seperate_rects.cpp
+++ b/seperate_rects.cpp
@@ -71,8 +71,8 @@
}
template <typename TNum, typename TId>
-void seperate_rects(const std::vector<Rect<TNum> > &in,
- std::vector<RectSet<TId, TNum> > *out) {
+void seperate_rects(const std::vector<Rect<TNum>> &in,
+ std::vector<RectSet<TId, TNum>> *out) {
// Overview:
// This algorithm is a line sweep algorithm that travels from left to right.
// The sweep stops at each vertical edge of each input rectangle in sorted
@@ -91,8 +91,8 @@
// Events are when the sweep line encounters the starting or ending edge of
// any input rectangle.
- std::set<SweepEvent<TId, TNum> > sweep_h_events; // Left or right bounds
- std::set<SweepEvent<TId, TNum> > sweep_v_events; // Top or bottom bounds
+ std::set<SweepEvent<TId, TNum>> sweep_h_events; // Left or right bounds
+ std::set<SweepEvent<TId, TNum>> sweep_v_events; // Top or bottom bounds
// A started rect is a rectangle whose left, top, bottom edge, and set of
// rectangle IDs is known. The key of this map includes all that information
@@ -102,7 +102,7 @@
// This is cleared after every event. Its declaration is here to avoid
// reallocating a vector and its buffers every event.
- std::vector<std::pair<TNum, IdSet<TId> > > active_regions;
+ std::vector<std::pair<TNum, IdSet<TId>>> active_regions;
// This pass will add rectangle start and end events to be triggered as the
// algorithm sweeps from left to right.
@@ -120,7 +120,7 @@
sweep_h_events.insert(evt);
}
- for (typename std::set<SweepEvent<TId, TNum> >::iterator it =
+ for (typename std::set<SweepEvent<TId, TNum>>::iterator it =
sweep_h_events.begin();
it != sweep_h_events.end(); ++it) {
const SweepEvent<TId, TNum> &h_evt = *it;
@@ -142,14 +142,14 @@
} else {
v_evt.type = START;
v_evt.y = rect.top;
- typename std::set<SweepEvent<TId, TNum> >::iterator start_it =
+ typename std::set<SweepEvent<TId, TNum>>::iterator start_it =
sweep_v_events.find(v_evt);
assert(start_it != sweep_v_events.end());
sweep_v_events.erase(start_it);
v_evt.type = END;
v_evt.y = rect.bottom;
- typename std::set<SweepEvent<TId, TNum> >::iterator end_it =
+ typename std::set<SweepEvent<TId, TNum>>::iterator end_it =
sweep_v_events.find(v_evt);
assert(end_it != sweep_v_events.end());
sweep_v_events.erase(end_it);
@@ -159,7 +159,7 @@
// with the current sweep line. If so, we want to continue marking up the
// sweep line before actually processing the rectangles the sweep line is
// intersecting.
- typename std::set<SweepEvent<TId, TNum> >::iterator next_it = it;
+ typename std::set<SweepEvent<TId, TNum>>::iterator next_it = it;
++next_it;
if (next_it != sweep_h_events.end()) {
if (next_it->x == h_evt.x) {
@@ -179,7 +179,7 @@
// 5), active_regions will be [({ 0 }, 3), {}, 5].
active_regions.clear();
IdSet<TId> active_set;
- for (typename std::set<SweepEvent<TId, TNum> >::iterator it =
+ for (typename std::set<SweepEvent<TId, TNum>>::iterator it =
sweep_v_events.begin();
it != sweep_v_events.end(); ++it) {
const SweepEvent<TId, TNum> &v_evt = *it;
@@ -199,7 +199,7 @@
#ifdef RECTS_DEBUG
std::cout << "x:" << h_evt.x;
- for (std::vector<std::pair<TNum, IdSet> >::iterator it =
+ for (std::vector<std::pair<TNum, IdSet>>::iterator it =
active_regions.begin();
it != active_regions.end(); ++it) {
std::cout << " " << it->first << "(" << it->second << ")"
@@ -226,7 +226,7 @@
// case, we have a new rectangle, and the already existing started rectangle
// will not be marked as seen ("true" in the std::pair) and will get ended
// by the for loop after this one. This is as intended.
- for (typename std::vector<std::pair<TNum, IdSet<TId> > >::iterator it =
+ for (typename std::vector<std::pair<TNum, IdSet<TId>>>::iterator it =
active_regions.begin();
it != active_regions.end(); ++it) {
IdSet<TId> region_set = it->second;
@@ -237,8 +237,7 @@
// An important property of active_regions is that each region where a set
// of rectangles applies is bounded at the bottom by the next (in the
// vector) region's starting y-coordinate.
- typename std::vector<std::pair<TNum, IdSet<TId> > >::iterator next_it =
- it;
+ typename std::vector<std::pair<TNum, IdSet<TId>>>::iterator next_it = it;
++next_it;
assert(next_it != active_regions.end());
@@ -300,8 +299,13 @@
}
}
-void seperate_frects_64(const std::vector<Rect<float> > &in,
- std::vector<RectSet<uint64_t, float> > *out) {
+void seperate_frects_64(const std::vector<Rect<float>> &in,
+ std::vector<RectSet<uint64_t, float>> *out) {
+ seperate_rects(in, out);
+}
+
+void seperate_rects_64(const std::vector<Rect<int>> &in,
+ std::vector<RectSet<uint64_t, int>> *out) {
seperate_rects(in, out);
}
diff --git a/seperate_rects.h b/seperate_rects.h
index 540a5e8..1e0a267 100644
--- a/seperate_rects.h
+++ b/seperate_rects.h
@@ -64,6 +64,18 @@
return true;
}
+
+ TFloat width() const {
+ return bounds[2] - bounds[0];
+ }
+
+ TFloat height() const {
+ return bounds[3] - bounds[1];
+ }
+
+ TFloat area() const {
+ return width() * height();
+ }
};
template <typename TUInt>
@@ -140,8 +152,10 @@
// rectangle indices that overlap the output rectangle encoded in a bitset. For
// example, an output rectangle that overlaps input rectangles in[0], in[1], and
// in[4], the bitset would be (ommitting leading zeroes) 10011.
-void seperate_frects_64(const std::vector<Rect<float> > &in,
- std::vector<RectSet<uint64_t, float> > *out);
+void seperate_frects_64(const std::vector<Rect<float>> &in,
+ std::vector<RectSet<uint64_t, float>> *out);
+void seperate_rects_64(const std::vector<Rect<int>> &in,
+ std::vector<RectSet<uint64_t, int>> *out);
} // namespace seperate_rects