summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarissa Wall <marissaw@google.com>2016-09-06 11:01:59 -0700
committerMarissa Wall <marissaw@google.com>2017-03-02 12:35:07 -0800
commit5190f6d533051d784524bdbe3946fa0e8ca4356d (patch)
treea03ee23151e735ff4ff52ec46df466c11cca8539
parent9b0d80b6b4bc520a61af6f0e4cafc206660d9709 (diff)
downloadflounder-5190f6d533051d784524bdbe3946fa0e8ca4356d.tar.gz
hwc2: validate display
Determine if a particular configuration of layers is valid. If the configuration is invalid, decide which composition types must change. Test: Add "TARGET_USES_HWC2 := true" to BoardConfig.mk. Recompile. Run testcases: https://android-review.googlesource.com/#/q/project: platform/frameworks/native+branch:master+topic:test-hwc2 Change-Id: I1b5c13bb2e195888d751640f87936e41e31544c2
-rw-r--r--hwc2/hwc2.cpp8
-rw-r--r--hwc2/hwc2.h55
-rw-r--r--hwc2/hwc2_buffer.cpp61
-rw-r--r--hwc2/hwc2_dev.cpp12
-rw-r--r--hwc2/hwc2_display.cpp191
-rw-r--r--hwc2/hwc2_layer.cpp9
-rw-r--r--hwc2/hwc2_window.cpp3
7 files changed, 323 insertions, 16 deletions
diff --git a/hwc2/hwc2.cpp b/hwc2/hwc2.cpp
index f6ed40d..3c450ca 100644
--- a/hwc2/hwc2.cpp
+++ b/hwc2/hwc2.cpp
@@ -237,11 +237,11 @@ hwc2_error_t set_vsync_enabled(hwc2_device_t *device, hwc2_display_t display,
return dev->set_vsync_enabled(display, static_cast<hwc2_vsync_t>(enabled));
}
-hwc2_error_t validate_display(hwc2_device_t* /*device*/,
- hwc2_display_t /*display*/, uint32_t* /*out_num_types*/,
- uint32_t* /*out_num_requests*/)
+hwc2_error_t validate_display(hwc2_device_t *device, hwc2_display_t display,
+ uint32_t *out_num_types, uint32_t *out_num_requests)
{
- return HWC2_ERROR_NONE;
+ hwc2_dev *dev = reinterpret_cast<hwc2_context *>(device)->hwc2_dev;
+ return dev->validate_display(display, out_num_types, out_num_requests);
}
hwc2_error_t set_cursor_position(hwc2_device_t *device, hwc2_display_t display,
diff --git a/hwc2/hwc2.h b/hwc2/hwc2.h
index 3ef4cef..6c556c7 100644
--- a/hwc2/hwc2.h
+++ b/hwc2/hwc2.h
@@ -22,6 +22,7 @@
#include <unordered_map>
#include <queue>
#include <array>
+#include <vector>
#include <mutex>
#include <string>
@@ -117,6 +118,7 @@ public:
void close_acquire_fence();
/* Get properties */
+ uint32_t get_z_order() const { return z_order; }
buffer_handle_t get_buffer_handle() const { return handle; }
hwc_transform_t get_transform() const { return transform; }
uint32_t get_adf_buffer_format() const;
@@ -131,6 +133,9 @@ public:
bool is_source_crop_int_aligned() const;
bool is_stereo() const;
bool is_yuv() const;
+ bool is_overlapped() const;
+
+ bool get_modified() const { return modified; }
/* Set properties */
hwc2_error_t set_buffer(buffer_handle_t handle, int32_t acquire_fence);
@@ -144,6 +149,8 @@ public:
hwc2_error_t set_transform(hwc_transform_t transform);
hwc2_error_t set_visible_region(const hwc_region_t &visible_region);
+ void set_modified(bool modified) { this->modified = modified; }
+
private:
/* A handle to the buffer */
buffer_handle_t handle;
@@ -184,6 +191,13 @@ private:
/* The portion of the layer that is visible including portions under
* translucent areas of other buffers */
std::vector<hwc_rect_t> visible_region;
+
+ /* Used to determine if the current buffer has a different format than the
+ * previous buffer */
+ uint32_t previous_format;
+
+ /* The buffer is modified and will force revalidation of the display */
+ bool modified;
};
class hwc2_config {
@@ -242,6 +256,7 @@ public:
/* Get properties */
hwc2_layer_t get_id() const { return id; }
hwc2_composition_t get_comp_type() const { return comp_type; }
+ uint32_t get_z_order() const { return buffer.get_z_order(); }
buffer_handle_t get_buffer_handle() const;
hwc_transform_t get_transform() const;
uint32_t get_adf_buffer_format() const;
@@ -256,6 +271,9 @@ public:
bool is_source_crop_int_aligned() const;
bool is_stereo() const;
bool is_yuv() const;
+ bool is_overlapped() const;
+
+ bool get_modified() const { return modified || buffer.get_modified(); }
/* Set properties */
hwc2_error_t set_comp_type(hwc2_composition_t comp_type);
@@ -270,6 +288,9 @@ public:
hwc2_error_t set_transform(hwc_transform_t transform);
hwc2_error_t set_visible_region(const hwc_region_t &visible_region);
+ void set_modified(bool modified) { this->modified = modified;
+ buffer.set_modified(modified); }
+
static hwc2_layer_t get_next_id();
private:
@@ -282,6 +303,9 @@ private:
/* Composition type of the layer */
hwc2_composition_t comp_type;
+ /* The layer is modified and will force revalidation of the display */
+ bool modified;
+
/* Keep track to total number of layers so new layer ids can be
* generated */
static uint64_t layer_cnt;
@@ -352,6 +376,12 @@ public:
hwc2_error_t set_power_mode(hwc2_power_mode_t mode);
hwc2_error_t get_doze_support(int32_t *out_support) const;
+ /* Display present functions */
+ hwc2_error_t validate_display(uint32_t *out_num_types,
+ uint32_t *out_num_requests);
+ void assign_composition();
+
+
/* Window functions */
void init_windows();
void clear_windows();
@@ -412,6 +442,23 @@ private:
/* Physical or virtual */
hwc2_display_type_t type;
+ /* The current state of the display */
+ enum display_state_t {
+ /* The display has been modified since the last validate_display or
+ * accept_display_changes call */
+ modified = 0,
+ /* The display failed the last validate_display attempt and has not been
+ * modified since and has not called accept_display_changes*/
+ invalid = 1,
+ /* The display passed the last validate_display attempt or has called
+ * accept_display_changes */
+ valid = 2,
+ } display_state;
+
+ /* The last call to validate determined that the client target buffer is
+ * necessary */
+ bool client_target_used;
+
/* The display windows */
std::array<hwc2_window, HWC2_WINDOW_COUNT> windows;
@@ -421,6 +468,10 @@ private:
/* Is vsync enabled */
hwc2_vsync_t vsync_enabled;
+ /* The layers that need a composition change. The list is populated during
+ * validate_display. */
+ std::unordered_map<hwc2_layer_t, hwc2_composition_t> changed_comp_types;
+
/* All the valid configurations for the display */
std::unordered_map<hwc2_config_t, hwc2_config> configs;
@@ -457,6 +508,10 @@ public:
hwc2_error_t get_doze_support(hwc2_display_t dpy_id, int32_t *out_support)
const;
+ /* Display present functions */
+ hwc2_error_t validate_display(hwc2_display_t dpy_id,
+ uint32_t *out_num_types, uint32_t *out_num_requests);
+
/* Config functions */
hwc2_error_t get_display_attribute(hwc2_display_t dpy_id,
hwc2_config_t config, hwc2_attribute_t attribute,
diff --git a/hwc2/hwc2_buffer.cpp b/hwc2/hwc2_buffer.cpp
index 56b8115..cbe7595 100644
--- a/hwc2/hwc2_buffer.cpp
+++ b/hwc2/hwc2_buffer.cpp
@@ -18,6 +18,36 @@
#include "hwc2.h"
+static bool operator==(const hwc_rect_t &r1, const hwc_rect_t &r2)
+{
+ return r1.left == r2.left && r1.top == r2.top && r1.right == r2.right
+ && r1.bottom == r2.bottom;
+}
+
+static bool operator!=(const hwc_rect_t &r1, const hwc_rect_t &r2)
+{
+ return !(r1 == r2);
+}
+
+static bool operator==(const hwc_frect_t &r1, const hwc_frect_t &r2)
+{
+ return r1.left == r2.left && r1.top == r2.top && r1.right == r2.right
+ && r1.bottom == r2.bottom;
+}
+
+static bool operator!=(const hwc_frect_t &r1, const hwc_frect_t &r2)
+{
+ return !(r1 == r2);
+}
+
+static bool cmp_region(std::vector<hwc_rect_t> &r1, const hwc_region_t &r2)
+{
+ if (r1.size() != r2.numRects)
+ return false;
+
+ return std::equal(r1.begin(), r1.end(), r2.rects);
+}
+
hwc2_buffer::hwc2_buffer()
: handle(),
acquire_fence(-1),
@@ -29,7 +59,9 @@ hwc2_buffer::hwc2_buffer()
blend_mode(HWC2_BLEND_MODE_NONE),
plane_alpha(1.0),
transform(),
- visible_region() { }
+ visible_region(),
+ previous_format(0),
+ modified(true) { }
hwc2_buffer::~hwc2_buffer()
{
@@ -136,6 +168,20 @@ bool hwc2_buffer::is_yuv() const
return hwc2_gralloc::get_instance().is_yuv(handle);
}
+bool hwc2_buffer::is_overlapped() const
+{
+ if (visible_region.size() != 1)
+ return true;
+
+ if (visible_region.at(0).left != display_frame.left
+ || visible_region.at(0).top != display_frame.top
+ || visible_region.at(0).right != display_frame.right
+ || visible_region.at(0).bottom != display_frame.bottom)
+ return true;
+
+ return false;
+}
+
hwc2_error_t hwc2_buffer::set_buffer(buffer_handle_t handle,
int32_t acquire_fence)
{
@@ -152,11 +198,16 @@ hwc2_error_t hwc2_buffer::set_buffer(buffer_handle_t handle,
this->handle = handle;
this->acquire_fence = acquire_fence;
+ uint32_t format = get_adf_buffer_format();
+ modified = modified || format != previous_format;
+ previous_format = format;
+
return HWC2_ERROR_NONE;
}
hwc2_error_t hwc2_buffer::set_dataspace(android_dataspace_t dataspace)
{
+ modified = modified || dataspace != this->dataspace;
this->dataspace = dataspace;
return HWC2_ERROR_NONE;
@@ -164,6 +215,7 @@ hwc2_error_t hwc2_buffer::set_dataspace(android_dataspace_t dataspace)
hwc2_error_t hwc2_buffer::set_display_frame(const hwc_rect_t &display_frame)
{
+ modified = modified || display_frame != this->display_frame;
this->display_frame = display_frame;
return HWC2_ERROR_NONE;
@@ -171,6 +223,7 @@ hwc2_error_t hwc2_buffer::set_display_frame(const hwc_rect_t &display_frame)
hwc2_error_t hwc2_buffer::set_source_crop(const hwc_frect_t &source_crop)
{
+ modified = modified || source_crop != this->source_crop;
this->source_crop = source_crop;
return HWC2_ERROR_NONE;
@@ -178,6 +231,7 @@ hwc2_error_t hwc2_buffer::set_source_crop(const hwc_frect_t &source_crop)
hwc2_error_t hwc2_buffer::set_z_order(uint32_t z_order)
{
+ modified = modified || z_order != this->z_order;
this->z_order = z_order;
return HWC2_ERROR_NONE;
@@ -199,6 +253,7 @@ hwc2_error_t hwc2_buffer::set_blend_mode(hwc2_blend_mode_t blend_mode)
return HWC2_ERROR_BAD_PARAMETER;
}
+ modified = modified || blend_mode != this->blend_mode;
this->blend_mode = blend_mode;
return HWC2_ERROR_NONE;
@@ -206,6 +261,7 @@ hwc2_error_t hwc2_buffer::set_blend_mode(hwc2_blend_mode_t blend_mode)
hwc2_error_t hwc2_buffer::set_plane_alpha(float plane_alpha)
{
+ modified = modified || plane_alpha != this->plane_alpha;
this->plane_alpha = plane_alpha;
return HWC2_ERROR_NONE;
@@ -213,6 +269,7 @@ hwc2_error_t hwc2_buffer::set_plane_alpha(float plane_alpha)
hwc2_error_t hwc2_buffer::set_transform(const hwc_transform_t transform)
{
+ modified = modified || transform != this->transform;
this->transform = transform;
return HWC2_ERROR_NONE;
@@ -220,6 +277,8 @@ hwc2_error_t hwc2_buffer::set_transform(const hwc_transform_t transform)
hwc2_error_t hwc2_buffer::set_visible_region(const hwc_region_t &visible_region)
{
+ modified = modified || !cmp_region(this->visible_region, visible_region);
+
this->visible_region.clear();
for (size_t idx = 0; idx < visible_region.numRects; idx++)
this->visible_region.push_back(visible_region.rects[idx]);
diff --git a/hwc2/hwc2_dev.cpp b/hwc2/hwc2_dev.cpp
index cbe9bc2..2f58920 100644
--- a/hwc2/hwc2_dev.cpp
+++ b/hwc2/hwc2_dev.cpp
@@ -109,6 +109,18 @@ hwc2_error_t hwc2_dev::get_doze_support(hwc2_display_t dpy_id,
return it->second.get_doze_support(out_support);
}
+hwc2_error_t hwc2_dev::validate_display(hwc2_display_t dpy_id,
+ uint32_t *out_num_types, uint32_t *out_num_requests)
+{
+ auto it = displays.find(dpy_id);
+ if (it == displays.end()) {
+ ALOGE("dpy %" PRIu64 ": invalid display handle", dpy_id);
+ return HWC2_ERROR_BAD_DISPLAY;
+ }
+
+ return it->second.validate_display(out_num_types, out_num_requests);
+}
+
hwc2_error_t hwc2_dev::get_display_attribute(hwc2_display_t dpy_id,
hwc2_config_t config, hwc2_attribute_t attribute, int32_t *out_value)
const
diff --git a/hwc2/hwc2_display.cpp b/hwc2/hwc2_display.cpp
index a874aba..fa8f0e9 100644
--- a/hwc2/hwc2_display.cpp
+++ b/hwc2/hwc2_display.cpp
@@ -17,6 +17,7 @@
#include <cutils/log.h>
#include <inttypes.h>
+#include <map>
#include <vector>
#include <array>
@@ -31,9 +32,12 @@ hwc2_display::hwc2_display(hwc2_display_t id, int adf_intf_fd,
name(),
connection(connection),
type(type),
+ display_state(modified),
+ client_target_used(false),
windows(),
layers(),
vsync_enabled(HWC2_VSYNC_DISABLE),
+ changed_comp_types(),
configs(),
active_config(0),
power_mode(power_mode),
@@ -57,6 +61,7 @@ hwc2_error_t hwc2_display::set_connection(hwc2_connection_t connection)
return HWC2_ERROR_BAD_PARAMETER;
}
+ display_state = modified;
this->connection = connection;
return HWC2_ERROR_NONE;
}
@@ -128,6 +133,119 @@ hwc2_error_t hwc2_display::set_vsync_enabled(hwc2_vsync_t enabled)
return HWC2_ERROR_NONE;
}
+hwc2_error_t hwc2_display::validate_display(uint32_t *out_num_types,
+ uint32_t *out_num_requests)
+{
+ if (display_state == valid) {
+ *out_num_types = 0;
+ *out_num_requests = 0;
+ return HWC2_ERROR_NONE;
+ }
+
+ clear_windows();
+ changed_comp_types.clear();
+
+ assign_composition();
+
+ *out_num_requests = 0;
+ *out_num_types = changed_comp_types.size();
+
+ for (auto &lyr: layers)
+ lyr.second.set_modified(false);
+
+ if (*out_num_types > 0) {
+ display_state = invalid;
+ return HWC2_ERROR_HAS_CHANGES;
+ }
+
+ display_state = valid;
+ return HWC2_ERROR_NONE;
+}
+
+void hwc2_display::assign_composition()
+{
+ hwc2_error_t ret;
+
+ std::map<uint32_t, hwc2_layer_t> ordered_layers;
+ for (auto &lyr: layers)
+ ordered_layers.emplace(lyr.second.get_z_order(), lyr.second.get_id());
+
+ bool client_target_assigned = false;
+
+ /* If there will definitely be a client target, assign it to the front most
+ * window */
+ if (layers.size() > windows.size()) {
+ ret = assign_client_target_window(0);
+ ALOG_ASSERT(ret == HWC2_ERROR_NONE, "No valid client target window");
+
+ client_target_assigned = true;
+ }
+
+ bool retry_assignment;
+
+ do {
+ retry_assignment = false;
+ /* The display controller uses a different z order than SurfaceFlinger */
+ uint32_t z_order = windows.size() - 1;
+ client_target_used = false;
+
+ /* Iterate over the layers from the back to the front.
+ * assign windows to device layers. Upon reaching a layer that must
+ * be composed by the client all subsequent layers will be assigned
+ * client composition */
+ for (auto &ordered_layer: ordered_layers) {
+ hwc2_layer_t lyr_id = ordered_layer.second;
+ hwc2_composition_t comp_type = layers.find(
+ lyr_id)->second.get_comp_type();
+
+ if (comp_type == HWC2_COMPOSITION_INVALID) {
+ ALOGW("dpy %" PRIu64 " lyr %" PRIu64 ": invalid composition"
+ " type %u", id, lyr_id, comp_type);
+ continue;
+ }
+
+ /* If the layer is not overlapped and can be assigned a window,
+ assign it and continue to the next layer */
+ if (comp_type == HWC2_COMPOSITION_DEVICE && !client_target_used
+ && assign_layer_window(z_order, lyr_id) == HWC2_ERROR_NONE) {
+ z_order--;
+ continue;
+ }
+
+ /* The layer will be composited into a client target buffer so
+ * find a window for the client target */
+ if (!client_target_assigned) {
+
+ ret = assign_client_target_window(0);
+ if (ret != HWC2_ERROR_NONE) {
+ /* If no client target can be assigned, clear all the
+ * windows, assign a client target and retry assigning
+ * windows */
+ retry_assignment = true;
+
+ changed_comp_types.clear();
+ clear_windows();
+
+ ret = assign_client_target_window(0);
+ ALOG_ASSERT(ret == HWC2_ERROR_NONE, "No valid client target"
+ " window");
+
+ client_target_assigned = true;
+ break;
+ }
+
+ client_target_assigned = true;
+ }
+
+ /* Assign the layer to client composition */
+ if (comp_type != HWC2_COMPOSITION_CLIENT)
+ changed_comp_types.emplace(lyr_id, HWC2_COMPOSITION_CLIENT);
+
+ client_target_used = true;
+ }
+ } while (retry_assignment);
+}
+
void hwc2_display::init_windows()
{
for (auto it = windows.begin(); it != windows.end(); it++)
@@ -282,6 +400,8 @@ hwc2_error_t hwc2_display::set_active_config(
hwc2_error_t hwc2_display::create_layer(hwc2_layer_t *out_layer)
{
+ display_state = modified;
+
hwc2_layer_t lyr_id = hwc2_layer::get_next_id();
layers.emplace(std::piecewise_construct, std::forward_as_tuple(lyr_id),
std::forward_as_tuple(lyr_id));
@@ -298,6 +418,7 @@ hwc2_error_t hwc2_display::destroy_layer(hwc2_layer_t lyr_id)
return HWC2_ERROR_BAD_LAYER;
}
+ display_state = modified;
layers.erase(lyr_id);
return HWC2_ERROR_NONE;
}
@@ -311,7 +432,12 @@ hwc2_error_t hwc2_display::set_layer_composition_type(hwc2_layer_t lyr_id,
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_comp_type(comp_type);
+ hwc2_error_t ret = it->second.set_comp_type(comp_type);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_buffer(hwc2_layer_t lyr_id,
@@ -323,7 +449,12 @@ hwc2_error_t hwc2_display::set_layer_buffer(hwc2_layer_t lyr_id,
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_buffer(handle, acquire_fence);
+ hwc2_error_t ret = it->second.set_buffer(handle, acquire_fence);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_dataspace(hwc2_layer_t lyr_id,
@@ -335,7 +466,12 @@ hwc2_error_t hwc2_display::set_layer_dataspace(hwc2_layer_t lyr_id,
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_dataspace(dataspace);
+ hwc2_error_t ret = it->second.set_dataspace(dataspace);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_display_frame(hwc2_layer_t lyr_id,
@@ -347,7 +483,12 @@ hwc2_error_t hwc2_display::set_layer_display_frame(hwc2_layer_t lyr_id,
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_display_frame(display_frame);
+ hwc2_error_t ret = it->second.set_display_frame(display_frame);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_source_crop(hwc2_layer_t lyr_id,
@@ -359,7 +500,12 @@ hwc2_error_t hwc2_display::set_layer_source_crop(hwc2_layer_t lyr_id,
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_source_crop(source_crop);
+ hwc2_error_t ret = it->second.set_source_crop(source_crop);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_z_order(hwc2_layer_t lyr_id, uint32_t z_order)
@@ -370,7 +516,12 @@ hwc2_error_t hwc2_display::set_layer_z_order(hwc2_layer_t lyr_id, uint32_t z_ord
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_z_order(z_order);
+ hwc2_error_t ret = it->second.set_z_order(z_order);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_surface_damage(hwc2_layer_t lyr_id,
@@ -394,7 +545,12 @@ hwc2_error_t hwc2_display::set_layer_blend_mode(hwc2_layer_t lyr_id,
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_blend_mode(blend_mode);
+ hwc2_error_t ret = it->second.set_blend_mode(blend_mode);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_plane_alpha(hwc2_layer_t lyr_id, float plane_alpha)
@@ -405,7 +561,12 @@ hwc2_error_t hwc2_display::set_layer_plane_alpha(hwc2_layer_t lyr_id, float plan
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_plane_alpha(plane_alpha);
+ hwc2_error_t ret = it->second.set_plane_alpha(plane_alpha);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_transform(hwc2_layer_t lyr_id,
@@ -417,7 +578,12 @@ hwc2_error_t hwc2_display::set_layer_transform(hwc2_layer_t lyr_id,
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_transform(transform);
+ hwc2_error_t ret = it->second.set_transform(transform);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_visible_region(hwc2_layer_t lyr_id,
@@ -429,7 +595,12 @@ hwc2_error_t hwc2_display::set_layer_visible_region(hwc2_layer_t lyr_id,
return HWC2_ERROR_BAD_LAYER;
}
- return it->second.set_visible_region(visible_region);
+ hwc2_error_t ret = it->second.set_visible_region(visible_region);
+
+ if (it->second.get_modified())
+ display_state = modified;
+
+ return ret;
}
hwc2_error_t hwc2_display::set_layer_color(hwc2_layer_t lyr_id,
diff --git a/hwc2/hwc2_layer.cpp b/hwc2/hwc2_layer.cpp
index 4da2919..ec7eb54 100644
--- a/hwc2/hwc2_layer.cpp
+++ b/hwc2/hwc2_layer.cpp
@@ -24,7 +24,8 @@ uint64_t hwc2_layer::layer_cnt = 0;
hwc2_layer::hwc2_layer(hwc2_layer_t id)
: id(id),
buffer(),
- comp_type(HWC2_COMPOSITION_INVALID) { }
+ comp_type(HWC2_COMPOSITION_INVALID),
+ modified(true) { }
buffer_handle_t hwc2_layer::get_buffer_handle() const
{
@@ -96,6 +97,11 @@ bool hwc2_layer::is_yuv() const
return buffer.is_yuv();
}
+bool hwc2_layer::is_overlapped() const
+{
+ return buffer.is_overlapped();
+}
+
hwc2_error_t hwc2_layer::set_comp_type(hwc2_composition_t comp_type)
{
hwc2_error_t ret = HWC2_ERROR_NONE;
@@ -117,6 +123,7 @@ hwc2_error_t hwc2_layer::set_comp_type(hwc2_composition_t comp_type)
ret = HWC2_ERROR_BAD_PARAMETER;
}
+ modified = modified || comp_type != this->comp_type;
this->comp_type = comp_type;
return ret;
}
diff --git a/hwc2/hwc2_window.cpp b/hwc2/hwc2_window.cpp
index ca2f7f6..ba30d02 100644
--- a/hwc2/hwc2_window.cpp
+++ b/hwc2/hwc2_window.cpp
@@ -129,6 +129,9 @@ bool hwc2_window::is_supported(const hwc2_layer &lyr)
if (lyr.is_stereo())
return false;
+ if (lyr.is_overlapped())
+ return false;
+
if (lyr.get_display_frame_width() < HWC2_WINDOW_MIN_DISPLAY_FRAME_WIDTH
|| lyr.get_display_frame_height() < HWC2_WINDOW_MIN_DISPLAY_FRAME_HEIGHT)
return false;