Skip to content

Commit 46c9a1d

Browse files
HaihongxLisysopenci
authored andcommitted
Ensure hwc use device composition for Video Layer
Video layer, protected or non-protected, need to use device composition, meanwhile hwc can use overlay planes, so just layers number is not greater than available planes number, hwc ensure use device composition for video layer. This commit target is to ensure use device composition for video layer if layers number is greater than available planes number. The main logic code is in GetExtraClientRange2. When device_size is less than or equal to avail_planes, besides the planes used to compose video layer, the remaining planes also need to be used to compose other layers. GetExtraClientRange2 will return client_start, client_size, then ValidateDisplay will set the client composition according to client_start and client_size, and the rest is device composition. Because the number of available planes is limited, GetExtraClientRange2 mainly do parameter checks under this condition. For example: GetExtraClientRange2 before z_order type format 0 1 2 client 3 client 4 device video 5 6 7 GetExtraClientRange2 after z_order type format 0 client 1 client 2 client 3 client 4 device video 5 device 6 device 7 device z_order 2 and 3 are confirmed to use client composition by IsClientLayer. z_order 4 is the video layer, which needs device compsition. There are only 4 available planes, and the remaining 3 planes can be used for z_order 5, 6, 7. GetExtraClientRange2 returns client_start(0), client_size(4), and then MarkValidated will set 0~3 client composition and 4~7 device composition. Tracked-On: OAM-123606 Signed-off-by: Li, HaihongX <[email protected]>
1 parent d526817 commit 46c9a1d

File tree

5 files changed

+141
-4
lines changed

5 files changed

+141
-4
lines changed

backend/Backend.cpp

Lines changed: 133 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
#include "BackendManager.h"
2323
#include "bufferinfo/BufferInfoGetter.h"
2424

25+
#ifdef LOG_TAG
26+
#undef LOG_TAG
27+
#endif
28+
#define LOG_TAG "hwc-backend"
29+
2530
namespace android {
2631

2732
HWC2::Error Backend::ValidateDisplay(HwcDisplay *display, uint32_t *num_types,
@@ -71,19 +76,47 @@ HWC2::Error Backend::ValidateDisplay(HwcDisplay *display, uint32_t *num_types,
7176
}
7277

7378
std::tuple<int, size_t> Backend::GetClientLayers(
74-
HwcDisplay *display, const std::vector<HwcLayer *> &layers) {
79+
HwcDisplay *display, std::vector<HwcLayer *> &layers) {
7580
int client_start = -1;
7681
size_t client_size = 0;
7782

83+
int device_start = -1;
84+
size_t device_size = 0;
7885
for (size_t z_order = 0; z_order < layers.size(); ++z_order) {
7986
if (IsClientLayer(display, layers[z_order])) {
8087
if (client_start < 0)
8188
client_start = (int)z_order;
8289
client_size = (z_order - client_start) + 1;
8390
}
91+
if (IsVideoLayer(layers[z_order])) {
92+
if (device_start < 0)
93+
device_start = (int)z_order;
94+
device_size = (z_order - device_start) + 1;
95+
}
96+
}
97+
if (device_size == 0)
98+
return GetExtraClientRange(display, layers, client_start, client_size);
99+
else {
100+
bool status = true;
101+
MarkValidated(layers, client_start, client_size);
102+
for (size_t z_order = 0; z_order < layers.size(); ++z_order) {
103+
if (z_order >= client_start &&
104+
z_order <= (client_start + client_size - 1) &&
105+
IsVideoLayer(layers[z_order]))
106+
status = false;
107+
108+
if (z_order >= device_start &&
109+
z_order <= (device_start + device_size - 1) &&
110+
layers[z_order]->GetValidatedType() == HWC2::Composition::Client)
111+
status = false;
112+
}
113+
if (!status) {
114+
ALOGE("status is abnormal");
115+
return GetExtraClientRange(display, layers, client_start, client_size);
116+
}
117+
return GetExtraClientRange2(display, layers, client_start, client_size, device_start, device_size);
84118
}
85119

86-
return GetExtraClientRange(display, layers, client_start, client_size);
87120
}
88121

89122
bool Backend::IsClientLayer(HwcDisplay *display, HwcLayer *layer) {
@@ -94,6 +127,13 @@ bool Backend::IsClientLayer(HwcDisplay *display, HwcLayer *layer) {
94127
display->GetHwc2()->GetResMan().ForcedScalingWithGpu());
95128
}
96129

130+
bool Backend::IsVideoLayer(HwcLayer *layer) {
131+
std::optional<BufferInfo> bi;
132+
if (layer->GetBufferHandle())
133+
bi = BufferInfoGetter::GetInstance()->GetBoInfo(layer->GetBufferHandle());
134+
return bi && bi->usage & GRALLOC_USAGE_HW_VIDEO_ENCODER;
135+
}
136+
97137
bool Backend::HardwareSupportsLayerType(HWC2::Composition comp_type) {
98138
return comp_type == HWC2::Composition::Device ||
99139
comp_type == HWC2::Composition::Cursor;
@@ -166,6 +206,97 @@ std::tuple<int, int> Backend::GetExtraClientRange(
166206
return std::make_tuple(client_start, client_size);
167207
}
168208

209+
std::tuple<int, int> Backend::GetExtraClientRange2(
210+
HwcDisplay *display, const std::vector<HwcLayer *> &layers,
211+
int client_start, size_t client_size, int device_start, size_t device_size) {
212+
auto planes = display->GetPipe().GetUsablePlanes();
213+
size_t avail_planes = planes.size();
214+
215+
/*
216+
* If more layers then planes, save one plane
217+
* for client composited layers
218+
*/
219+
if (avail_planes < display->layers().size())
220+
avail_planes--;
221+
222+
if (avail_planes < device_size) {
223+
ALOGE("too many device video layers(%zd), no enough planes(%zd) to use", device_size, avail_planes);
224+
return GetExtraClientRange(display, layers, client_start, client_size);
225+
} else if (avail_planes == device_size) {
226+
if (device_start != 0 && (device_start + device_size) != layers.size()) {
227+
ALOGE("status is abnormal");
228+
return GetExtraClientRange(display, layers, client_start, client_size);
229+
}
230+
231+
if (device_start == 0)
232+
return std::make_tuple(device_start + device_size, layers.size() - device_size);
233+
else
234+
return std::make_tuple(0, layers.size() - device_size);
235+
} else {
236+
if (client_start == -1) {
237+
int extra_device = std::min(layers.size() - device_size - client_size, avail_planes - device_size);
238+
int prepend = device_start;
239+
int append = layers.size() - (device_start + device_size);
240+
if (std::min(prepend, append) > extra_device) {
241+
ALOGE("status is abnormal");
242+
return GetExtraClientRange(display, layers, client_start, client_size);
243+
}
244+
245+
if (prepend == std::min(prepend, append)) {
246+
int remain = extra_device - prepend;
247+
return std::make_tuple(device_start + device_size + remain, layers.size() - extra_device - device_size);
248+
}
249+
if (append == std::min(prepend, append)) {
250+
return std::make_tuple(0, layers.size() - extra_device - device_size);
251+
}
252+
} else {
253+
int extra_device = std::min(layers.size() - device_size - client_size, avail_planes - device_size);
254+
if (client_start > device_start) {
255+
int prepend = device_start;
256+
int midpend = client_start - (device_start + device_size);
257+
int append = layers.size() - (client_start + client_size);
258+
if (prepend > extra_device) {
259+
ALOGE("status is abnormal");
260+
return GetExtraClientRange(display, layers, client_start, client_size);
261+
}
262+
int remain = extra_device - prepend;
263+
if (remain == 0) {
264+
return std::make_tuple(device_start + device_size, layers.size() - extra_device - device_size);
265+
} else {
266+
midpend = std::min(midpend, remain);
267+
if (midpend == remain) {
268+
return std::make_tuple(device_start + device_size + midpend,
269+
layers.size() - prepend - midpend - device_size);
270+
} else {
271+
return std::make_tuple(device_start + device_size + midpend,
272+
layers.size() - prepend - midpend - std::min(remain - midpend, append) - device_size);
273+
}
274+
}
275+
} else {
276+
int prepend = client_start;
277+
int midpend = device_start - (client_start + client_size);
278+
int append = layers.size() - (device_start + device_size);
279+
if (append > extra_device) {
280+
ALOGE("status is abnormal");
281+
return GetExtraClientRange(display, layers, client_start, client_size);
282+
}
283+
int remain = extra_device - append;
284+
if (remain == 0)
285+
return std::make_tuple(0, layers.size() - extra_device - device_size);
286+
else {
287+
midpend = std::min(midpend, remain);
288+
if (midpend == remain) {
289+
return std::make_tuple(0, layers.size() - append - midpend - device_size);
290+
} else {
291+
return std::make_tuple(std::min(remain - midpend, prepend),
292+
layers.size() - append - midpend - std::min(remain - midpend, prepend) - device_size);
293+
}
294+
}
295+
}
296+
}
297+
}
298+
return GetExtraClientRange(display, layers, client_start, client_size);
299+
}
169300
// clang-format off
170301
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables, cert-err58-cpp)
171302
REGISTER_BACKEND("generic", Backend);

backend/Backend.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ class Backend {
2727
virtual HWC2::Error ValidateDisplay(HwcDisplay *display, uint32_t *num_types,
2828
uint32_t *num_requests);
2929
virtual std::tuple<int, size_t> GetClientLayers(
30-
HwcDisplay *display, const std::vector<HwcLayer *> &layers);
30+
HwcDisplay *display, std::vector<HwcLayer *> &layers);
3131
virtual bool IsClientLayer(HwcDisplay *display, HwcLayer *layer);
32-
32+
virtual bool IsVideoLayer(HwcLayer *layer);
3333
protected:
3434
static bool HardwareSupportsLayerType(HWC2::Composition comp_type);
3535
static uint32_t CalcPixOps(const std::vector<HwcLayer *> &layers,
@@ -39,6 +39,9 @@ class Backend {
3939
static std::tuple<int, int> GetExtraClientRange(
4040
HwcDisplay *display, const std::vector<HwcLayer *> &layers,
4141
int client_start, size_t client_size);
42+
static std::tuple<int, int> GetExtraClientRange2(
43+
HwcDisplay *display, const std::vector<HwcLayer *> &layers,
44+
int client_start, size_t client_size, int device_start, size_t device_size);
4245
};
4346
} // namespace android
4447

bufferinfo/BufferInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct BufferInfo {
4646
uint32_t format; /* DRM_FORMAT_* from drm_fourcc.h */
4747
uint32_t pitches[kBufferMaxPlanes];
4848
uint32_t offsets[kBufferMaxPlanes];
49+
uint64_t usage;
4950
/* sizes[] is used only by mapper@4 metadata getter for internal purposes */
5051
uint32_t sizes[kBufferMaxPlanes];
5152
int prime_fds[kBufferMaxPlanes];

bufferinfo/BufferInfoMapperMetadata.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ auto BufferInfoMapperMetadata::GetBoInfo(buffer_handle_t handle)
100100
return {};
101101
}
102102

103+
mapper.getUsage(handle, &bi.usage);
103104
err = mapper.getPixelFormatModifier(handle, &bi.modifiers[0]);
104105
if (err != 0) {
105106
ALOGE("Failed to get DRM Modifier err=%d", err);

hwc2_device/HwcLayer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class HwcLayer {
114114
public:
115115
void PopulateLayerData(bool test);
116116

117+
buffer_handle_t GetBufferHandle() {return buffer_handle_;}
117118
bool IsLayerUsableAsDevice() const {
118119
return !bi_get_failed_ && !fb_import_failed_ && buffer_handle_ != nullptr;
119120
}

0 commit comments

Comments
 (0)