OSDN Git Service

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