diff options
author | Marissa Wall <marissaw@google.com> | 2016-09-06 11:01:59 -0700 |
---|---|---|
committer | Marissa Wall <marissaw@google.com> | 2017-03-02 12:35:07 -0800 |
commit | 5190f6d533051d784524bdbe3946fa0e8ca4356d (patch) | |
tree | a03ee23151e735ff4ff52ec46df466c11cca8539 | |
parent | 9b0d80b6b4bc520a61af6f0e4cafc206660d9709 (diff) | |
download | flounder-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.cpp | 8 | ||||
-rw-r--r-- | hwc2/hwc2.h | 55 | ||||
-rw-r--r-- | hwc2/hwc2_buffer.cpp | 61 | ||||
-rw-r--r-- | hwc2/hwc2_dev.cpp | 12 | ||||
-rw-r--r-- | hwc2/hwc2_display.cpp | 191 | ||||
-rw-r--r-- | hwc2/hwc2_layer.cpp | 9 | ||||
-rw-r--r-- | hwc2/hwc2_window.cpp | 3 |
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; |