2 // Copyright (c) 2016 Intel Corporation
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "overlaylayer.h"
28 #include "nativebufferhandler.h"
29 #include "resourcemanager.h"
31 namespace hwcomposer {
33 OverlayLayer::ImportedBuffer::~ImportedBuffer() {
34 if (acquire_fence_ > 0) {
35 close(acquire_fence_);
39 OverlayLayer::ImportedBuffer::ImportedBuffer(
40 std::shared_ptr<OverlayBuffer>& buffer, int32_t acquire_fence)
41 : acquire_fence_(acquire_fence) {
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_);
52 imported_buffer_->acquire_fence_ = acquire_fence;
56 int32_t OverlayLayer::GetAcquireFence() const {
57 if (imported_buffer_.get()) {
58 return imported_buffer_->acquire_fence_;
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;
73 OverlayBuffer* OverlayLayer::GetBuffer() const {
74 if (imported_buffer_.get()) {
75 if (imported_buffer_->buffer_.get() == NULL)
76 ETRACE("hwc layer get NullBuffer");
78 return imported_buffer_->buffer_.get();
84 std::shared_ptr<OverlayBuffer>& OverlayLayer::GetSharedBuffer() const {
85 return imported_buffer_->buffer_;
88 void OverlayLayer::SetBuffer(HWCNativeHandle handle, int32_t acquire_fence,
89 ResourceManager* resource_manager,
91 FrameBufferManager* frame_buffer_manager) {
92 std::shared_ptr<OverlayBuffer> buffer(NULL);
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);
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);
110 buffer->SetOriginalHandle(handle);
113 buffer->SetDataSpace(dataspace_);
115 imported_buffer_.reset(new ImportedBuffer(buffer, acquire_fence));
116 ValidateForOverlayUsage();
119 void OverlayLayer::SetBlending(HWCBlending blending) {
120 blending_ = blending;
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;
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;
137 void OverlayLayer::SetTransform(uint32_t transform) {
138 plane_transform_ = transform;
139 transform_ = transform;
142 void OverlayLayer::ValidateTransform(uint32_t transform,
143 uint32_t display_transform) {
144 std::map<int, int> tmap = {{kIdentity, 0},
148 std::vector<int> inv_tmap = {kIdentity, kTransform90, kTransform180,
151 int mdisplay_transform = display_transform;
153 transform & (kIdentity | kTransform90 | kTransform180 | kTransform270);
155 if (tmap.find(mtransform) != tmap.end()) {
156 mtransform = tmap[mtransform];
158 // reaching here indicates that transform is
159 // is an OR of multiple values
160 // Assign Identity in this case
161 mtransform = kIdentity;
164 if (tmap.find(mdisplay_transform) != tmap.end()) {
165 mdisplay_transform = tmap[mdisplay_transform];
167 mdisplay_transform = kIdentity;
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;
175 if (plane_transform_ & kTransform90) {
176 if (transform & kReflectX)
177 plane_transform_ |= kReflectX;
179 if (transform & kReflectY)
180 plane_transform_ |= kReflectY;
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);
195 plane_transform_ = transform_;
198 alpha_ = layer->GetAlpha();
199 layer_index_ = layer_index;
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();
208 solid_color_ = layer->GetSolidColor();
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;
221 if (force_partial_clear) {
222 state_ |= kForcePartialClear;
224 } else if (!layer->IsCursorLayer()) {
225 state_ |= kNeedsReValidation;
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);
242 "HWC don't support a layer with no buffer handle except in SolidColor "
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();
254 if (!handle_constraints) {
255 if (previous_layer) {
256 ValidatePreviousFrameState(previous_layer, layer);
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;
277 if (display_frame_.right < left_source_constraint) {
278 state_ |= kInvisible;
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;
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;
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;
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);
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;
308 if ((surface_damage_.left < display_frame_.left) &&
309 (surface_damage_.right > display_frame_.left)) {
310 surface_damage_.left = display_frame_.left;
313 if (surface_damage_.right > display_frame_.right) {
314 surface_damage_.right = display_frame_.right;
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);
325 surface_damage_.reset();
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);
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
336 // we need get proportional content of source.
337 // 2. the UI content may cross the sub displays of Mosaic or Logical mode
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));
351 if (previous_layer) {
352 ValidatePreviousFrameState(previous_layer, layer);
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);
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);
380 void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
382 OverlayBuffer* buffer = NULL;
383 if (imported_buffer_.get())
384 buffer = imported_buffer_->buffer_.get();
386 supported_composition_ = rhs->supported_composition_;
387 actual_composition_ = rhs->actual_composition_;
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;
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;
414 } else if (type_ == kLayerCursor) {
415 if (layer->HasLayerAttributesChanged()) {
416 state_ |= kNeedsReValidation;
420 // Ensure the buffer can be supported by display for direct
422 if (!rhs->imported_buffer_.get()) {
423 state_ |= kNeedsReValidation;
425 } else if (buffer && (buffer->GetFormat() !=
426 rhs->imported_buffer_->buffer_->GetFormat())) {
427 state_ |= kNeedsReValidation;
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;
441 if (blending_ != rhs->blending_) {
442 state_ |= kNeedsReValidation;
446 if (rect_changed || layer->HasLayerAttributesChanged()) {
447 state_ |= kNeedsReValidation;
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;
463 state_ &= ~kDimensionsChanged;
466 if (!layer->HasVisibleRegionChanged() && !content_changed &&
467 surface_damage_.empty() && !layer->HasLayerContentChanged() &&
468 !(state_ & kNeedsReValidation)) {
469 state_ &= ~kLayerContentChanged;
473 void OverlayLayer::ValidateForOverlayUsage() {
474 const std::shared_ptr<OverlayBuffer>& buffer = imported_buffer_->buffer_;
475 type_ = buffer->GetUsage();
478 void OverlayLayer::CloneLayer(const OverlayLayer* layer,
479 const HwcRect<int>& display_frame,
480 ResourceManager* resource_manager,
482 FrameBufferManager* frame_buffer_manager) {
483 int32_t fence = layer->GetAcquireFence();
484 int32_t aquire_fence = 0;
486 aquire_fence = dup(fence);
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;
499 blending_ = layer->blending_;
500 solid_color_ = layer->solid_color_;
503 void OverlayLayer::Dump() {
504 DUMPTRACE("OverlayLayer Information Starts. -------------");
506 case HWCBlending::kBlendingNone:
507 DUMPTRACE("Blending: kBlendingNone.");
509 case HWCBlending::kBlendingPremult:
510 DUMPTRACE("Blending: kBlendingPremult.");
512 case HWCBlending::kBlendingCoverage:
513 DUMPTRACE("Blending: kBlendingCoverage.");
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.");
530 DUMPTRACE("Transform: kTransform0.");
532 DUMPTRACE("Alpha: %u", alpha_);
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_);
544 imported_buffer_->buffer_->Dump();
547 } // namespace hwcomposer