OSDN Git Service

Fix Damage rect regression
[android-x86/external-IA-Hardware-Composer.git] / common / core / overlaylayer.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 "overlaylayer.h"
18
19 #include <cmath>
20
21 #include <drm_mode.h>
22 #include <hwctrace.h>
23
24 #include "hwcutils.h"
25
26 #include "resourcemanager.h"
27 #include "nativebufferhandler.h"
28
29 namespace hwcomposer {
30
31 OverlayLayer::ImportedBuffer::~ImportedBuffer() {
32   if (acquire_fence_ > 0) {
33     close(acquire_fence_);
34   }
35 }
36
37 OverlayLayer::ImportedBuffer::ImportedBuffer(
38     std::shared_ptr<OverlayBuffer>& buffer, int32_t acquire_fence)
39     : acquire_fence_(acquire_fence) {
40   buffer_ = buffer;
41 }
42
43 void OverlayLayer::SetAcquireFence(int32_t acquire_fence) {
44   // Release any existing fence.
45   if (imported_buffer_->acquire_fence_ > 0) {
46     close(imported_buffer_->acquire_fence_);
47   }
48
49   imported_buffer_->acquire_fence_ = acquire_fence;
50 }
51
52 int32_t OverlayLayer::GetAcquireFence() const {
53   return imported_buffer_->acquire_fence_;
54 }
55
56 int32_t OverlayLayer::ReleaseAcquireFence() const {
57   int32_t fence = imported_buffer_->acquire_fence_;
58   imported_buffer_->acquire_fence_ = -1;
59   return fence;
60 }
61
62 OverlayBuffer* OverlayLayer::GetBuffer() const {
63   if (imported_buffer_->buffer_.get() == NULL)
64     ETRACE("hwc layer get NullBuffer");
65
66   return imported_buffer_->buffer_.get();
67 }
68
69 std::shared_ptr<OverlayBuffer>& OverlayLayer::GetSharedBuffer() const {
70   return imported_buffer_->buffer_;
71 }
72
73 void OverlayLayer::SetBuffer(HWCNativeHandle handle, int32_t acquire_fence,
74                              ResourceManager* resource_manager,
75                              bool register_buffer, HwcLayer* layer) {
76   std::shared_ptr<OverlayBuffer> buffer(NULL);
77
78   uint32_t id;
79
80   if (resource_manager && register_buffer) {
81     uint32_t gpu_fd = resource_manager->GetNativeBufferHandler()->GetFd();
82     id = GetNativeBuffer(gpu_fd, handle);
83     buffer = resource_manager->FindCachedBuffer(id);
84   }
85
86   if (buffer == NULL) {
87     buffer = OverlayBuffer::CreateOverlayBuffer();
88     bool is_cursor_layer = false;
89     if (layer) {
90       is_cursor_layer = layer->IsCursorLayer();
91     }
92     buffer->InitializeFromNativeHandle(handle, resource_manager,
93                                        is_cursor_layer);
94     if (resource_manager && register_buffer) {
95       resource_manager->RegisterBuffer(id, buffer);
96     }
97   }
98
99   if (handle->is_raw_pixel_ && !surface_damage_.empty()) {
100     buffer->UpdateRawPixelBackingStore(handle->pixel_memory_);
101     state_ |= kRawPixelDataChanged;
102   }
103
104   imported_buffer_.reset(new ImportedBuffer(buffer, acquire_fence));
105   ValidateForOverlayUsage();
106 }
107
108 void OverlayLayer::SetBlending(HWCBlending blending) {
109   blending_ = blending;
110 }
111
112 void OverlayLayer::SetSourceCrop(const HwcRect<float>& source_crop) {
113   source_crop_width_ = static_cast<int>(ceilf(source_crop.right) -
114                                         static_cast<int>(source_crop.left));
115   source_crop_height_ = static_cast<int>(ceilf(source_crop.bottom) -
116                                          static_cast<int>(source_crop.top));
117   source_crop_ = source_crop;
118 }
119
120 void OverlayLayer::SetDisplayFrame(const HwcRect<int>& display_frame) {
121   display_frame_width_ = display_frame.right - display_frame.left;
122   display_frame_height_ = display_frame.bottom - display_frame.top;
123   display_frame_ = display_frame;
124   surface_damage_ = display_frame;
125 }
126
127 void OverlayLayer::SetTransform(uint32_t transform) {
128   plane_transform_ = transform;
129   transform_ = transform;
130 }
131
132 void OverlayLayer::ValidateTransform(uint32_t transform,
133                                      uint32_t display_transform) {
134   if (transform & kTransform90) {
135     switch (display_transform) {
136       case HWCTransform::kTransform90:
137         plane_transform_ |= kTransform180;
138         break;
139       case HWCTransform::kTransform180:
140         plane_transform_ |= kTransform270;
141         break;
142       case HWCTransform::kIdentity:
143         plane_transform_ |= kTransform90;
144         if (transform & kReflectX) {
145           plane_transform_ |= kReflectX;
146         }
147
148         if (transform & kReflectY) {
149           plane_transform_ |= kReflectY;
150         }
151         break;
152       default:
153         break;
154     }
155   } else if (transform & kTransform180) {
156     switch (display_transform) {
157       case HWCTransform::kTransform90:
158         plane_transform_ |= kTransform270;
159         break;
160       case HWCTransform::kTransform270:
161         plane_transform_ |= kTransform90;
162         break;
163       case HWCTransform::kIdentity:
164         plane_transform_ |= kTransform180;
165         break;
166       default:
167         break;
168     }
169   } else if (transform & kTransform270) {
170     switch (display_transform) {
171       case HWCTransform::kTransform270:
172         plane_transform_ |= kTransform180;
173         break;
174       case HWCTransform::kTransform180:
175         plane_transform_ |= kTransform90;
176         break;
177       case HWCTransform::kIdentity:
178         plane_transform_ |= kTransform270;
179         break;
180       default:
181         break;
182     }
183   } else {
184     if (display_transform & HWCTransform::kTransform90) {
185       if (transform & kReflectX) {
186         plane_transform_ |= kReflectX;
187       }
188
189       if (transform & kReflectY) {
190         plane_transform_ |= kReflectY;
191       }
192
193       plane_transform_ |= kTransform90;
194     } else {
195       switch (display_transform) {
196         case HWCTransform::kTransform270:
197           plane_transform_ |= kTransform270;
198           break;
199         case HWCTransform::kTransform180:
200           plane_transform_ |= kTransform180;
201           break;
202         default:
203           break;
204       }
205     }
206   }
207 }
208
209 void OverlayLayer::InitializeState(HwcLayer* layer,
210                                    ResourceManager* resource_manager,
211                                    OverlayLayer* previous_layer,
212                                    uint32_t z_order, uint32_t layer_index,
213                                    uint32_t max_height, uint32_t rotation,
214                                    bool handle_constraints) {
215   transform_ = layer->GetTransform();
216   if (rotation != kRotateNone) {
217     ValidateTransform(layer->GetTransform(), rotation);
218   } else {
219     plane_transform_ = transform_;
220   }
221
222   alpha_ = layer->GetAlpha();
223   layer_index_ = layer_index;
224   z_order_ = z_order;
225   source_crop_width_ = layer->GetSourceCropWidth();
226   source_crop_height_ = layer->GetSourceCropHeight();
227   source_crop_ = layer->GetSourceCrop();
228   blending_ = layer->GetBlending();
229   if (!layer->IsCursorLayer() && layer->HasZorderChanged() &&
230       (!previous_layer ||
231        (previous_layer && (previous_layer->z_order_ != z_order)))) {
232     state_ |= kLayerOrderChanged;
233   }
234
235   if (layer->ForceClear()) {
236     state_ |= kForcePartialClear;
237   }
238
239   surface_damage_ = layer->GetLayerDamage();
240   // In case of layer using blening we need to force partial clear. Otherwise
241   // we see content not getting updated correctly. For example:
242   // on Android enable, settings put system user_rotation 1 and
243   // navigate to settings on Android.
244   if (((blending_ != HWCBlending::kBlendingNone) && !surface_damage_.empty())) {
245     state_ |= kForcePartialClear;
246     surface_damage_ = layer->GetDisplayFrame();
247   }
248
249   SetBuffer(layer->GetNativeHandle(), layer->GetAcquireFence(),
250             resource_manager, true, layer);
251
252   if (!surface_damage_.empty()) {
253     if (type_ == kLayerCursor) {
254       const std::shared_ptr<OverlayBuffer>& buffer = imported_buffer_->buffer_;
255       surface_damage_.right = surface_damage_.left + buffer->GetWidth();
256       surface_damage_.bottom = surface_damage_.top + buffer->GetHeight();
257     } else {
258       switch (plane_transform_) {
259         case HWCTransform::kTransform270:
260         case HWCTransform::kTransform90: {
261           std::swap(surface_damage_.left, surface_damage_.top);
262           std::swap(surface_damage_.right, surface_damage_.bottom);
263           break;
264         }
265         default:
266           break;
267       }
268     }
269   }
270
271   if (!handle_constraints) {
272     if (previous_layer) {
273       ValidatePreviousFrameState(previous_layer, layer);
274     }
275     return;
276   }
277
278   int32_t left_constraint = layer->GetLeftConstraint();
279   int32_t right_constraint = layer->GetRightConstraint();
280   int32_t left_source_constraint = layer->GetLeftSourceConstraint();
281   int32_t right_source_constraint = layer->GetRightSourceConstraint();
282   int32_t display_frame_left = display_frame_.left;
283   uint32_t frame_width = display_frame_.right - display_frame_.left;
284   uint32_t source_width =
285       static_cast<int>(source_crop_.right - source_crop_.left);
286   uint32_t frame_offset_left = 0;
287   uint32_t frame_offset_right = frame_width;
288   if (left_constraint >= 0 && right_constraint >= 0) {
289     if (display_frame_.left > right_source_constraint) {
290       state_ |= kInvisible;
291       return;
292     }
293
294     if (display_frame_.right < left_source_constraint) {
295       state_ |= kInvisible;
296       return;
297     }
298
299     if (display_frame_.left < left_source_constraint) {
300       frame_offset_left = left_source_constraint - display_frame_left;
301       display_frame_.left = left_source_constraint;
302     }
303
304     if (display_frame_.right > right_source_constraint) {
305       frame_offset_right = right_source_constraint - display_frame_left;
306       display_frame_.right = right_source_constraint;
307     }
308
309     // Handle case where we might be using logical and Mosaic together.
310     display_frame_.left =
311         (display_frame_.left - left_source_constraint) + left_constraint;
312     display_frame_.right =
313         (display_frame_.right - left_source_constraint) + left_constraint;
314     IMOSAICDISPLAYTRACE(
315         "display_frame_ %d %d %d %d  left_source_constraint: %d "
316         "left_constraint: %d \n",
317         display_frame_.left, display_frame_.right, display_frame_.top,
318         display_frame_.bottom, left_source_constraint, left_constraint);
319
320     display_frame_.bottom =
321         std::min(max_height, static_cast<uint32_t>(display_frame_.bottom));
322     display_frame_width_ = display_frame_.right - display_frame_.left;
323     display_frame_height_ = display_frame_.bottom - display_frame_.top;
324
325     if ((surface_damage_.left < display_frame_.left) &&
326         (surface_damage_.right > display_frame_.left)) {
327       surface_damage_.left = display_frame_.left;
328     }
329
330     if (surface_damage_.right > display_frame_.right) {
331       surface_damage_.right = display_frame_.right;
332     }
333
334     if (AnalyseOverlap(surface_damage_, display_frame_) != kOutside) {
335       surface_damage_.bottom =
336           std::min(surface_damage_.bottom, display_frame_.bottom);
337       surface_damage_.right =
338           std::min(surface_damage_.right, display_frame_.right);
339       surface_damage_.left =
340           std::max(surface_damage_.left, display_frame_.left);
341     } else {
342       surface_damage_.reset();
343     }
344     IMOSAICDISPLAYTRACE(
345         "surface_damage_ %d %d %d %d  left_source_constraint: %d "
346         "left_constraint: %d \n",
347         surface_damage_.left, surface_damage_.right, surface_damage_.top,
348         surface_damage_.bottom, left_source_constraint, left_constraint);
349
350     // split the source in proportion of frame rect offset for sub displays as:
351     // 1. the original source size may be different with the original frame
352     // rect,
353     //    we need get proportional content of source.
354     // 2. the UI content may cross the sub displays of Mosaic or Logical mode
355
356     source_crop_.left = static_cast<float>(source_width) *
357                         (static_cast<float>(frame_offset_left) /
358                          static_cast<float>(frame_width));
359     source_crop_.right = static_cast<float>(source_width) *
360                          (static_cast<float>(frame_offset_right) /
361                           static_cast<float>(frame_width));
362     source_crop_width_ = static_cast<int>(ceilf(source_crop_.right) -
363                                           static_cast<int>(source_crop_.left));
364     source_crop_height_ = static_cast<int>(ceilf(source_crop_.bottom) -
365                                            static_cast<int>(source_crop_.top));
366   }
367
368   if (previous_layer) {
369     ValidatePreviousFrameState(previous_layer, layer);
370   }
371 }
372
373 void OverlayLayer::InitializeFromHwcLayer(
374     HwcLayer* layer, ResourceManager* resource_manager,
375     OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index,
376     uint32_t max_height, uint32_t rotation, bool handle_constraints) {
377   display_frame_width_ = layer->GetDisplayFrameWidth();
378   display_frame_height_ = layer->GetDisplayFrameHeight();
379   display_frame_ = layer->GetDisplayFrame();
380   InitializeState(layer, resource_manager, previous_layer, z_order, layer_index,
381                   max_height, rotation, handle_constraints);
382 }
383
384 void OverlayLayer::InitializeFromScaledHwcLayer(
385     HwcLayer* layer, ResourceManager* resource_manager,
386     OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index,
387     const HwcRect<int>& display_frame, uint32_t max_height, uint32_t rotation,
388     bool handle_constraints) {
389   SetDisplayFrame(display_frame);
390   InitializeState(layer, resource_manager, previous_layer, z_order, layer_index,
391                   max_height, rotation, handle_constraints);
392 }
393
394 void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
395                                               HwcLayer* layer) {
396   OverlayBuffer* buffer = imported_buffer_->buffer_.get();
397   supported_composition_ = rhs->supported_composition_;
398   actual_composition_ = rhs->actual_composition_;
399
400   bool content_changed = false;
401   bool rect_changed = layer->HasDisplayRectChanged();
402   bool source_rect_changed = layer->HasSourceRectChanged();
403   if (source_rect_changed)
404     state_ |= kSourceRectChanged;
405
406   // We expect cursor plane to support alpha always.
407   if ((actual_composition_ & kGpu) || (type_ == kLayerCursor)) {
408     if (actual_composition_ & kGpu) {
409       content_changed = rect_changed || source_rect_changed;
410       // This layer has replaced an existing layer, let's make sure
411       // we re-draw this and previous layer regions.
412       if (!layer->IsValidated()) {
413         content_changed = true;
414         CalculateRect(rhs->display_frame_, surface_damage_);
415       } else if (!content_changed) {
416         if ((buffer->GetFormat() !=
417              rhs->imported_buffer_->buffer_->GetFormat()) ||
418             (alpha_ != rhs->alpha_) || (blending_ != rhs->blending_) ||
419             (transform_ != rhs->transform_)) {
420           content_changed = true;
421         }
422       }
423     } else if (type_ == kLayerCursor) {
424       if (layer->HasLayerAttributesChanged()) {
425         state_ |= kNeedsReValidation;
426       }
427     }
428   } else {
429     // Ensure the buffer can be supported by display for direct
430     // scanout.
431     if (buffer->GetFormat() != rhs->imported_buffer_->buffer_->GetFormat()) {
432       state_ |= kNeedsReValidation;
433       return;
434     }
435
436     // If previous layer was opaque and we have alpha now,
437     // let's mark this layer for re-validation. Plane
438     // supporting XRGB format might not necessarily support
439     // transparent planes. We assume plane supporting
440     // ARGB will support XRGB.
441     if ((rhs->alpha_ == 0xff) && (alpha_ != rhs->alpha_)) {
442       state_ |= kNeedsReValidation;
443       return;
444     }
445
446     if (blending_ != rhs->blending_) {
447       state_ |= kNeedsReValidation;
448       return;
449     }
450
451     if (rect_changed || layer->HasLayerAttributesChanged()) {
452       state_ |= kNeedsReValidation;
453       return;
454     }
455
456     if (source_rect_changed) {
457       // If the overall width and height hasn't changed, it
458       // shouldn't impact the plane composition results.
459       if ((source_crop_width_ != rhs->source_crop_width_) ||
460           (source_crop_height_ != rhs->source_crop_height_)) {
461         state_ |= kNeedsReValidation;
462         return;
463       }
464     }
465   }
466
467   if (!rect_changed) {
468     state_ &= ~kDimensionsChanged;
469   }
470
471   if (!layer->HasVisibleRegionChanged() && !content_changed &&
472       surface_damage_.empty() && !layer->HasLayerContentChanged() &&
473       !(state_ & kNeedsReValidation) && !(state_ & kRawPixelDataChanged)) {
474     state_ &= ~kLayerContentChanged;
475   }
476 }
477
478 void OverlayLayer::ValidateForOverlayUsage() {
479   const std::shared_ptr<OverlayBuffer>& buffer = imported_buffer_->buffer_;
480   type_ = buffer->GetUsage();
481 }
482
483 void OverlayLayer::CloneLayer(const OverlayLayer* layer,
484                               const HwcRect<int>& display_frame) {
485   int32_t fence = layer->GetAcquireFence();
486   if (fence > 0) {
487     fence = dup(fence);
488   }
489
490   SetDisplayFrame(display_frame);
491   SetSourceCrop(layer->GetSourceCrop());
492   imported_buffer_.reset(new ImportedBuffer(layer->GetSharedBuffer(), fence));
493   ValidateForOverlayUsage();
494   surface_damage_ = display_frame;
495   transform_ = 0;
496 }
497
498 void OverlayLayer::Dump() {
499   DUMPTRACE("OverlayLayer Information Starts. -------------");
500   switch (blending_) {
501     case HWCBlending::kBlendingNone:
502       DUMPTRACE("Blending: kBlendingNone.");
503       break;
504     case HWCBlending::kBlendingPremult:
505       DUMPTRACE("Blending: kBlendingPremult.");
506       break;
507     case HWCBlending::kBlendingCoverage:
508       DUMPTRACE("Blending: kBlendingCoverage.");
509       break;
510     default:
511       break;
512   }
513
514   if (transform_ & kReflectX)
515     DUMPTRACE("Transform: kReflectX.");
516   if (transform_ & kReflectY)
517     DUMPTRACE("Transform: kReflectY.");
518   if (transform_ & kReflectY)
519     DUMPTRACE("Transform: kReflectY.");
520   else if (transform_ & kTransform180)
521     DUMPTRACE("Transform: kTransform180.");
522   else if (transform_ & kTransform270)
523     DUMPTRACE("Transform: kTransform270.");
524   else
525     DUMPTRACE("Transform: kTransform0.");
526
527   DUMPTRACE("Alpha: %u", alpha_);
528
529   DUMPTRACE("SourceWidth: %d", source_crop_width_);
530   DUMPTRACE("SourceHeight: %d", source_crop_height_);
531   DUMPTRACE("DstWidth: %d", display_frame_width_);
532   DUMPTRACE("DstHeight: %d", display_frame_height_);
533   DUMPTRACE("AquireFence: %d", imported_buffer_->acquire_fence_);
534
535   imported_buffer_->buffer_->Dump();
536 }
537
538 }  // namespace hwcomposer