OSDN Git Service

Add full color range support
[android-x86/external-IA-Hardware-Composer.git] / common / core / hwclayer.cpp
1 /*
2 // Copyright (c) 2016 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include <hwclayer.h>
18 #include <libsync.h>
19 #include <cmath>
20
21 #include <hwcutils.h>
22
23 namespace hwcomposer {
24
25 HwcLayer::~HwcLayer() {
26   if (release_fd_ > 0) {
27     close(release_fd_);
28   }
29
30   if (acquire_fence_ > 0) {
31     close(acquire_fence_);
32   }
33 }
34
35 void HwcLayer::SetNativeHandle(HWCNativeHandle handle) {
36   sf_handle_ = handle;
37 }
38
39 void HwcLayer::SetTransform(int32_t transform) {
40   if (transform != transform_) {
41     layer_cache_ |= kLayerAttributesChanged;
42     transform_ = transform;
43     UpdateRenderingDamage(display_frame_, display_frame_, true);
44   }
45 }
46
47 void HwcLayer::SetDataSpace(uint32_t dataspace) {
48   if (dataspace_ != dataspace) {
49     dataspace_ = dataspace;
50   }
51 }
52
53 void HwcLayer::SetAlpha(uint8_t alpha) {
54   if (alpha_ != alpha) {
55     alpha_ = alpha;
56     UpdateRenderingDamage(display_frame_, display_frame_, true);
57   }
58 }
59
60 void HwcLayer::SetBlending(HWCBlending blending) {
61   if (blending != blending_) {
62     blending_ = blending;
63     UpdateRenderingDamage(display_frame_, display_frame_, true);
64   }
65 }
66
67 void HwcLayer::SetSourceCrop(const HwcRect<float>& source_crop) {
68   if ((source_crop.left != source_crop_.left) ||
69       (source_crop.right != source_crop_.right) ||
70       (source_crop.top != source_crop_.top) ||
71       (source_crop.bottom != source_crop_.bottom)) {
72     layer_cache_ |= kSourceRectChanged;
73     source_crop_ = source_crop;
74     source_crop_width_ =
75         static_cast<int>(ceilf(source_crop.right - source_crop.left));
76     source_crop_height_ =
77         static_cast<int>(ceilf(source_crop.bottom - source_crop.top));
78   }
79 }
80
81 void HwcLayer::SetDisplayFrame(const HwcRect<int>& display_frame,
82                                int translate_x_pos, int translate_y_pos) {
83   if (((display_frame.left + translate_x_pos) != display_frame_.left) ||
84       ((display_frame.right + translate_x_pos) != display_frame_.right) ||
85       ((display_frame.top + translate_y_pos) != display_frame_.top) ||
86       ((display_frame.bottom + translate_y_pos) != display_frame_.bottom)) {
87     layer_cache_ |= kDisplayFrameRectChanged;
88     HwcRect<int> frame = display_frame;
89     frame.left += translate_x_pos;
90     frame.right += translate_x_pos;
91     frame.top += translate_y_pos;
92     frame.bottom += translate_y_pos;
93     UpdateRenderingDamage(display_frame_, frame, false);
94
95     display_frame_ = frame;
96     display_frame_width_ = display_frame_.right - display_frame_.left;
97     display_frame_height_ = display_frame_.bottom - display_frame_.top;
98   }
99
100   if (!(state_ & kVisibleRegionSet)) {
101     visible_rect_ = display_frame_;
102   }
103 }
104
105 void HwcLayer::SetSurfaceDamage(const HwcRegion& surface_damage) {
106   uint32_t rects = surface_damage.size();
107   state_ |= kLayerContentChanged;
108   HwcRect<int> rect;
109   ResetRectToRegion(surface_damage, rect);
110   if (rects == 1) {
111     if ((rect.top == 0) && (rect.bottom == 0) && (rect.left == 0) &&
112         (rect.right == 0)) {
113       state_ &= ~kLayerContentChanged;
114       state_ &= ~kSurfaceDamageChanged;
115       UpdateRenderingDamage(rect, rect, true);
116       surface_damage_.reset();
117       return;
118     }
119   } else if (rects == 0) {
120     rect = display_frame_;
121   }
122
123   if ((surface_damage_.left == rect.left) &&
124       (surface_damage_.top == rect.top) &&
125       (surface_damage_.right == rect.right) &&
126       (surface_damage_.bottom == rect.bottom)) {
127     return;
128   }
129
130   state_ |= kSurfaceDamageChanged;
131
132   UpdateRenderingDamage(surface_damage_, rect, false);
133   surface_damage_ = rect;
134 }
135
136 void HwcLayer::SetVisibleRegion(const HwcRegion& visible_region) {
137   uint32_t rects = visible_region.size();
138   const HwcRect<int>& new_region = visible_region.at(0);
139   HwcRect<int> new_visible_rect = new_region;
140   state_ |= kVisibleRegionSet;
141   state_ &= ~kVisibleRegionChanged;
142
143   for (uint32_t r = 1; r < rects; r++) {
144     const HwcRect<int>& rect = visible_region.at(r);
145     new_visible_rect.left = std::min(new_region.left, rect.left);
146     new_visible_rect.top = std::min(new_region.top, rect.top);
147     new_visible_rect.right = std::max(new_region.right, rect.right);
148     new_visible_rect.bottom = std::max(new_region.bottom, rect.bottom);
149   }
150
151   if ((visible_rect_.left == new_visible_rect.left) &&
152       (visible_rect_.top == new_visible_rect.top) &&
153       (visible_rect_.right == new_visible_rect.right) &&
154       (visible_rect_.bottom == new_visible_rect.bottom)) {
155     return;
156   }
157
158   state_ |= kVisibleRegionChanged;
159   UpdateRenderingDamage(visible_rect_, new_visible_rect, false);
160   visible_rect_ = new_visible_rect;
161
162   if ((visible_rect_.top == 0) && (visible_rect_.bottom == 0) &&
163       (visible_rect_.left == 0) && (visible_rect_.right == 0)) {
164     state_ &= ~kVisible;
165   } else {
166     state_ |= kVisible;
167   }
168 }
169
170 void HwcLayer::SetReleaseFence(int32_t fd) {
171   if (release_fd_ > 0) {
172     if (fd != -1) {
173       int ret = sync_accumulate("iahwc_release_layerfence", &release_fd_, fd);
174       if (ret) {
175         ETRACE("Unable to merge layer release fence");
176         release_fd_ = -1;
177       }
178     } else {
179       release_fd_ = -1;
180     }
181   } else {
182     release_fd_ = fd;
183   }
184 }
185
186 int32_t HwcLayer::GetReleaseFence() {
187   int32_t old_fd = release_fd_;
188   release_fd_ = -1;
189   return old_fd;
190 }
191
192 void HwcLayer::SetAcquireFence(int32_t fd) {
193   if (!sf_handle_) {
194     if (fd > 0) {
195       close(fd);
196     }
197     acquire_fence_ = -1;
198   }
199   if (acquire_fence_ > 0) {
200     close(acquire_fence_);
201     acquire_fence_ = -1;
202   }
203
204   acquire_fence_ = fd;
205 }
206
207 void HwcLayer::SetSolidColor(uint32_t color) {
208   solid_color_ = color;
209 }
210
211 int32_t HwcLayer::GetAcquireFence() {
212   if (!sf_handle_)
213     return -1;
214   int32_t old_fd = acquire_fence_;
215   acquire_fence_ = -1;
216   return old_fd;
217 }
218
219 void HwcLayer::SufaceDamageTransfrom() {
220   int ox = 0, oy = 0;
221   HwcRect<int> translated_damage =
222       TranslateRect(surface_damage_, -source_crop_.left, -source_crop_.top);
223
224   // From observation: In Android, when the source crop coordinate
225   // is (0, 0), the surface damage is already translated to global display
226   // coordinate. Therefore, no translation is needed.
227   // The rotation scenario is not verified as the rotation is not supported on P
228   // Leave the rotation scenario code here temporary.
229
230   if (!surface_damage_.empty() &&
231       ((source_crop_.left == 0) && (source_crop_.top == 0))) {
232     if (transform_ == hwcomposer::HWCTransform::kTransform270) {
233       ox = display_frame_.left;
234       oy = display_frame_.bottom;
235       current_rendering_damage_.left = ox + translated_damage.top;
236       current_rendering_damage_.top = oy - translated_damage.right;
237       current_rendering_damage_.right = ox + translated_damage.bottom;
238       current_rendering_damage_.bottom = oy - translated_damage.left;
239     } else if (transform_ == hwcomposer::HWCTransform::kTransform180) {
240       ox = display_frame_.right;
241       oy = display_frame_.bottom;
242       current_rendering_damage_.left = ox - translated_damage.right;
243       current_rendering_damage_.top = oy - translated_damage.bottom;
244       current_rendering_damage_.right = ox - translated_damage.left;
245       current_rendering_damage_.bottom = oy - translated_damage.top;
246     } else if (transform_ & hwcomposer::HWCTransform::kTransform90) {
247       if (transform_ & hwcomposer::HWCTransform::kReflectX) {
248         ox = display_frame_.left;
249         oy = display_frame_.top;
250         current_rendering_damage_.left = ox + translated_damage.top;
251         current_rendering_damage_.top = oy + translated_damage.left;
252         current_rendering_damage_.right = ox + translated_damage.bottom;
253         current_rendering_damage_.bottom = oy + translated_damage.right;
254       } else if (transform_ & hwcomposer::HWCTransform::kReflectY) {
255         ox = display_frame_.right;
256         oy = display_frame_.bottom;
257         current_rendering_damage_.left = ox - translated_damage.bottom;
258         current_rendering_damage_.top = oy - translated_damage.right;
259         current_rendering_damage_.right = ox - translated_damage.top;
260         current_rendering_damage_.bottom = oy - translated_damage.left;
261       } else {
262         ox = display_frame_.right;
263         oy = display_frame_.top;
264         current_rendering_damage_.left = ox - translated_damage.bottom;
265         current_rendering_damage_.top = oy + translated_damage.left;
266         current_rendering_damage_.right = ox - translated_damage.top;
267         current_rendering_damage_.bottom = oy + translated_damage.right;
268       }
269     } else if (transform_ == 0) {
270       ox = display_frame_.left;
271       oy = display_frame_.top;
272       current_rendering_damage_.left = ox + translated_damage.left;
273       current_rendering_damage_.top = oy + translated_damage.top;
274       current_rendering_damage_.right = ox + translated_damage.right;
275       current_rendering_damage_.bottom = oy + translated_damage.bottom;
276     }
277   } else {
278     current_rendering_damage_ = translated_damage;
279   }
280 }
281
282 void HwcLayer::Validate() {
283   if (total_displays_ == 1) {
284     state_ &= ~kVisibleRegionChanged;
285     state_ |= kLayerValidated;
286     state_ &= ~kLayerContentChanged;
287     state_ &= ~kSurfaceDamageChanged;
288     state_ &= ~kZorderChanged;
289     layer_cache_ &= ~kLayerAttributesChanged;
290     layer_cache_ &= ~kDisplayFrameRectChanged;
291     layer_cache_ &= ~kSourceRectChanged;
292
293     SufaceDamageTransfrom();
294   }
295
296   if (left_constraint_.empty() && left_source_constraint_.empty())
297     return;
298
299   if (!left_constraint_.empty()) {
300     std::vector<int32_t>().swap(left_constraint_);
301   }
302
303   if (!right_constraint_.empty()) {
304     std::vector<int32_t>().swap(right_constraint_);
305   }
306
307   if (!left_source_constraint_.empty()) {
308     std::vector<int32_t>().swap(left_source_constraint_);
309   }
310
311   if (!right_source_constraint_.empty()) {
312     std::vector<int32_t>().swap(right_source_constraint_);
313   }
314 }
315
316 void HwcLayer::SetLayerZOrder(uint32_t order) {
317   if (z_order_ != static_cast<int>(order)) {
318     z_order_ = order;
319     state_ |= kZorderChanged;
320     UpdateRenderingDamage(display_frame_, visible_rect_, false);
321   }
322 }
323
324 void HwcLayer::SetLeftConstraint(int32_t left_constraint) {
325   left_constraint_.emplace_back(left_constraint);
326 }
327
328 void HwcLayer::SetRightConstraint(int32_t right_constraint) {
329   right_constraint_.emplace_back(right_constraint);
330 }
331
332 int32_t HwcLayer::GetLeftConstraint() {
333   size_t total = left_constraint_.size();
334   if (total == 0)
335     return -1;
336
337   if (total == 1)
338     return left_constraint_.at(0);
339
340   std::vector<int32_t> temp;
341   for (size_t i = 1; i < total; i++) {
342     temp.emplace_back(left_constraint_.at(i));
343   }
344
345   uint32_t value = left_constraint_.at(0);
346   left_constraint_.swap(temp);
347   return value;
348 }
349
350 int32_t HwcLayer::GetRightConstraint() {
351   size_t total = right_constraint_.size();
352   if (total == 0)
353     return -1;
354
355   if (total == 1)
356     return right_constraint_.at(0);
357
358   std::vector<int32_t> temp;
359   for (size_t i = 1; i < total; i++) {
360     temp.emplace_back(right_constraint_.at(i));
361   }
362
363   uint32_t value = right_constraint_.at(0);
364   right_constraint_.swap(temp);
365   return value;
366 }
367
368 void HwcLayer::SetLeftSourceConstraint(int32_t left_constraint) {
369   left_source_constraint_.emplace_back(left_constraint);
370 }
371
372 void HwcLayer::SetRightSourceConstraint(int32_t right_constraint) {
373   right_source_constraint_.emplace_back(right_constraint);
374 }
375
376 int32_t HwcLayer::GetLeftSourceConstraint() {
377   size_t total = left_source_constraint_.size();
378   if (total == 0)
379     return -1;
380
381   if (total == 1)
382     return left_source_constraint_.at(0);
383
384   std::vector<int32_t> temp;
385   for (size_t i = 1; i < total; i++) {
386     temp.emplace_back(left_source_constraint_.at(i));
387   }
388
389   uint32_t value = left_source_constraint_.at(0);
390   left_source_constraint_.swap(temp);
391   return value;
392 }
393
394 int32_t HwcLayer::GetRightSourceConstraint() {
395   size_t total = right_source_constraint_.size();
396   if (total == 0)
397     return -1;
398
399   if (total == 1)
400     return right_source_constraint_.at(0);
401
402   std::vector<int32_t> temp;
403   for (size_t i = 1; i < total; i++) {
404     temp.emplace_back(right_source_constraint_.at(i));
405   }
406
407   uint32_t value = right_source_constraint_.at(0);
408   right_source_constraint_.swap(temp);
409   return value;
410 }
411
412 void HwcLayer::MarkAsCursorLayer() {
413   is_cursor_layer_ = true;
414 }
415
416 bool HwcLayer::IsCursorLayer() const {
417   return is_cursor_layer_;
418 }
419
420 void HwcLayer::UpdateRenderingDamage(const HwcRect<int>& old_rect,
421                                      const HwcRect<int>& newrect,
422                                      bool same_rect) {
423   if (current_rendering_damage_.empty()) {
424     current_rendering_damage_ = old_rect;
425   } else {
426     CalculateRect(old_rect, current_rendering_damage_);
427   }
428
429   if (same_rect)
430     return;
431
432   CalculateRect(newrect, current_rendering_damage_);
433 }
434
435 const HwcRect<int>& HwcLayer::GetLayerDamage() {
436   return current_rendering_damage_;
437 }
438
439 void HwcLayer::SetTotalDisplays(uint32_t total_displays) {
440   total_displays_ = total_displays;
441 }
442
443 }  // namespace hwcomposer