summaryrefslogtreecommitdiff
path: root/drmhwctwo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drmhwctwo.cpp')
-rw-r--r--drmhwctwo.cpp113
1 files changed, 79 insertions, 34 deletions
diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp
index 5ab4595..6bab17b 100644
--- a/drmhwctwo.cpp
+++ b/drmhwctwo.cpp
@@ -26,7 +26,7 @@
#include <inttypes.h>
#include <string>
-#include <cutils/log.h>
+#include <log/log.h>
#include <cutils/properties.h>
#include <hardware/hardware.h>
#include <hardware/hwcomposer2.h>
@@ -70,17 +70,9 @@ HWC2::Error DrmHwcTwo::Init() {
return HWC2::Error::NoResources;
}
- ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
- (const hw_module_t **)&gralloc_);
- if (ret) {
- ALOGE("Failed to open gralloc module %d", ret);
- return HWC2::Error::NoResources;
- }
-
displays_.emplace(std::piecewise_construct,
std::forward_as_tuple(HWC_DISPLAY_PRIMARY),
- std::forward_as_tuple(&drm_, importer_, gralloc_,
- HWC_DISPLAY_PRIMARY,
+ std::forward_as_tuple(&drm_, importer_, HWC_DISPLAY_PRIMARY,
HWC2::DisplayType::Physical));
DrmCrtc *crtc = drm_.GetCrtcForDisplay(static_cast<int>(HWC_DISPLAY_PRIMARY));
@@ -160,13 +152,8 @@ HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor,
DrmHwcTwo::HwcDisplay::HwcDisplay(DrmResources *drm,
std::shared_ptr<Importer> importer,
- const gralloc_module_t *gralloc,
hwc2_display_t handle, HWC2::DisplayType type)
- : drm_(drm),
- importer_(importer),
- gralloc_(gralloc),
- handle_(handle),
- type_(type) {
+ : drm_(drm), importer_(importer), handle_(handle), type_(type) {
supported(__func__);
}
@@ -480,8 +467,7 @@ void DrmHwcTwo::HwcDisplay::AddFenceToRetireFence(int fd) {
}
}
-HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
- supported(__func__);
+HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
std::vector<DrmCompositionDisplayLayersMap> layers_map;
layers_map.emplace_back();
DrmCompositionDisplayLayersMap &map = layers_map.back();
@@ -491,17 +477,23 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
// order the layers by z-order
bool use_client_layer = false;
- uint32_t client_z_order = 0;
+ uint32_t client_z_order = UINT32_MAX;
std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map;
for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
- switch (l.second.validated_type()) {
+ HWC2::Composition comp_type;
+ if (test)
+ comp_type = l.second.sf_type();
+ else
+ comp_type = l.second.validated_type();
+
+ switch (comp_type) {
case HWC2::Composition::Device:
z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
break;
case HWC2::Composition::Client:
- // Place it at the z_order of the highest client layer
+ // Place it at the z_order of the lowest client layer
use_client_layer = true;
- client_z_order = std::max(client_z_order, l.second.z_order());
+ client_z_order = std::min(client_z_order, l.second.z_order());
break;
default:
continue;
@@ -510,21 +502,20 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
if (use_client_layer)
z_map.emplace(std::make_pair(client_z_order, &client_layer_));
+ if (z_map.empty())
+ return HWC2::Error::BadLayer;
+
// now that they're ordered by z, add them to the composition
for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
DrmHwcLayer layer;
l.second->PopulateDrmLayer(&layer);
- int ret = layer.ImportBuffer(importer_.get(), gralloc_);
+ int ret = layer.ImportBuffer(importer_.get());
if (ret) {
ALOGE("Failed to import layer, ret=%d", ret);
return HWC2::Error::NoResources;
}
map.layers.emplace_back(std::move(layer));
}
- if (map.layers.empty()) {
- *retire_fence = -1;
- return HWC2::Error::None;
- }
std::unique_ptr<DrmDisplayComposition> composition =
compositor_.CreateComposition();
@@ -539,8 +530,7 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
std::vector<DrmPlane *> primary_planes(primary_planes_);
std::vector<DrmPlane *> overlay_planes(overlay_planes_);
- ret = composition->Plan(compositor_.squash_state(), &primary_planes,
- &overlay_planes);
+ ret = composition->Plan(&primary_planes, &overlay_planes);
if (ret) {
ALOGE("Failed to plan the composition ret=%d", ret);
return HWC2::Error::BadConfig;
@@ -556,13 +546,32 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
i = overlay_planes.erase(i);
}
- AddFenceToRetireFence(composition->take_out_fence());
-
- ret = compositor_.ApplyComposition(std::move(composition));
+ if (test) {
+ ret = compositor_.TestComposition(composition.get());
+ } else {
+ AddFenceToRetireFence(composition->take_out_fence());
+ ret = compositor_.ApplyComposition(std::move(composition));
+ }
if (ret) {
- ALOGE("Failed to apply the frame composition ret=%d", ret);
+ if (!test)
+ ALOGE("Failed to apply the frame composition ret=%d", ret);
return HWC2::Error::BadParameter;
}
+ return HWC2::Error::None;
+}
+
+HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) {
+ supported(__func__);
+ HWC2::Error ret;
+
+ ret = CreateComposition(false);
+ if (ret == HWC2::Error::BadLayer) {
+ // Can we really have no client or device layers?
+ *retire_fence = -1;
+ return HWC2::Error::None;
+ }
+ if (ret != HWC2::Error::None)
+ return ret;
// The retire fence returned here is for the last frame, so return it and
// promote the next retire fence
@@ -684,11 +693,47 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) {
HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
uint32_t *num_requests) {
supported(__func__);
+ size_t plane_count = 0;
*num_types = 0;
*num_requests = 0;
+ size_t avail_planes = primary_planes_.size() + overlay_planes_.size();
+
+ HWC2::Error ret;
+
+ for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_)
+ l.second.set_validated_type(HWC2::Composition::Invalid);
+
+ ret = CreateComposition(true);
+ if (ret != HWC2::Error::None)
+ // Assume the test failed due to overlay planes
+ avail_planes = 1;
+
+ std::map<uint32_t, DrmHwcTwo::HwcLayer *, std::greater<int>> z_map;
+ for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
+ if (l.second.sf_type() == HWC2::Composition::Device)
+ z_map.emplace(std::make_pair(l.second.z_order(), &l.second));
+ }
+
+ /*
+ * If more layers then planes, save one plane
+ * for client composited layers
+ */
+ if (avail_planes < layers_.size())
+ avail_planes--;
+
+ for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
+ if (!avail_planes--)
+ break;
+ l.second->set_validated_type(HWC2::Composition::Device);
+ }
+
for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
DrmHwcTwo::HwcLayer &layer = l.second;
switch (layer.sf_type()) {
+ case HWC2::Composition::Device:
+ if (layer.validated_type() == HWC2::Composition::Device)
+ break;
+ // fall thru
case HWC2::Composition::SolidColor:
case HWC2::Composition::Cursor:
case HWC2::Composition::Sideband:
@@ -821,7 +866,7 @@ void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) {
layer->acquire_fence = acquire_fence_.Release();
layer->release_fence = std::move(release_fence);
layer->SetDisplayFrame(display_frame_);
- layer->alpha = static_cast<uint8_t>(255.0f * alpha_ + 0.5f);
+ layer->alpha = static_cast<uint16_t>(65535.0f * alpha_ + 0.5f);
layer->SetSourceCrop(source_crop_);
layer->SetTransform(static_cast<int32_t>(transform_));
}