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"
26 #include "resourcemanager.h"
27 #include "nativebufferhandler.h"
29 namespace hwcomposer {
31 OverlayLayer::ImportedBuffer::~ImportedBuffer() {
32 if (acquire_fence_ > 0) {
33 close(acquire_fence_);
37 OverlayLayer::ImportedBuffer::ImportedBuffer(
38 std::shared_ptr<OverlayBuffer>& buffer, int32_t acquire_fence)
39 : acquire_fence_(acquire_fence) {
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_);
49 imported_buffer_->acquire_fence_ = acquire_fence;
52 int32_t OverlayLayer::GetAcquireFence() const {
53 return imported_buffer_->acquire_fence_;
56 int32_t OverlayLayer::ReleaseAcquireFence() const {
57 int32_t fence = imported_buffer_->acquire_fence_;
58 imported_buffer_->acquire_fence_ = -1;
62 OverlayBuffer* OverlayLayer::GetBuffer() const {
63 if (imported_buffer_->buffer_.get() == NULL)
64 ETRACE("hwc layer get NullBuffer");
66 return imported_buffer_->buffer_.get();
69 std::shared_ptr<OverlayBuffer>& OverlayLayer::GetSharedBuffer() const {
70 return imported_buffer_->buffer_;
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);
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);
87 buffer = OverlayBuffer::CreateOverlayBuffer();
88 bool is_cursor_layer = false;
90 is_cursor_layer = layer->IsCursorLayer();
92 buffer->InitializeFromNativeHandle(handle, resource_manager,
94 if (resource_manager && register_buffer) {
95 resource_manager->RegisterBuffer(id, buffer);
99 if (handle->is_raw_pixel_ && !surface_damage_.empty()) {
100 buffer->UpdateRawPixelBackingStore(handle->pixel_memory_);
101 state_ |= kRawPixelDataChanged;
104 imported_buffer_.reset(new ImportedBuffer(buffer, acquire_fence));
105 ValidateForOverlayUsage();
108 void OverlayLayer::SetBlending(HWCBlending blending) {
109 blending_ = blending;
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;
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;
127 void OverlayLayer::SetTransform(uint32_t transform) {
128 plane_transform_ = transform;
129 transform_ = transform;
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;
139 case HWCTransform::kTransform180:
140 plane_transform_ |= kTransform270;
142 case HWCTransform::kIdentity:
143 plane_transform_ |= kTransform90;
144 if (transform & kReflectX) {
145 plane_transform_ |= kReflectX;
148 if (transform & kReflectY) {
149 plane_transform_ |= kReflectY;
155 } else if (transform & kTransform180) {
156 switch (display_transform) {
157 case HWCTransform::kTransform90:
158 plane_transform_ |= kTransform270;
160 case HWCTransform::kTransform270:
161 plane_transform_ |= kTransform90;
163 case HWCTransform::kIdentity:
164 plane_transform_ |= kTransform180;
169 } else if (transform & kTransform270) {
170 switch (display_transform) {
171 case HWCTransform::kTransform270:
172 plane_transform_ |= kTransform180;
174 case HWCTransform::kTransform180:
175 plane_transform_ |= kTransform90;
177 case HWCTransform::kIdentity:
178 plane_transform_ |= kTransform270;
184 if (display_transform & HWCTransform::kTransform90) {
185 if (transform & kReflectX) {
186 plane_transform_ |= kReflectX;
189 if (transform & kReflectY) {
190 plane_transform_ |= kReflectY;
193 plane_transform_ |= kTransform90;
195 switch (display_transform) {
196 case HWCTransform::kTransform270:
197 plane_transform_ |= kTransform270;
199 case HWCTransform::kTransform180:
200 plane_transform_ |= kTransform180;
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);
219 plane_transform_ = transform_;
222 alpha_ = layer->GetAlpha();
223 layer_index_ = layer_index;
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() &&
231 (previous_layer && (previous_layer->z_order_ != z_order)))) {
232 state_ |= kLayerOrderChanged;
235 if (layer->ForceClear()) {
236 state_ |= kForcePartialClear;
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();
249 SetBuffer(layer->GetNativeHandle(), layer->GetAcquireFence(),
250 resource_manager, true, layer);
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();
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);
271 if (!handle_constraints) {
272 if (previous_layer) {
273 ValidatePreviousFrameState(previous_layer, layer);
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;
294 if (display_frame_.right < left_source_constraint) {
295 state_ |= kInvisible;
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;
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;
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;
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);
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;
325 if ((surface_damage_.left < display_frame_.left) &&
326 (surface_damage_.right > display_frame_.left)) {
327 surface_damage_.left = display_frame_.left;
330 if (surface_damage_.right > display_frame_.right) {
331 surface_damage_.right = display_frame_.right;
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);
342 surface_damage_.reset();
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);
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
353 // we need get proportional content of source.
354 // 2. the UI content may cross the sub displays of Mosaic or Logical mode
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));
368 if (previous_layer) {
369 ValidatePreviousFrameState(previous_layer, layer);
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);
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);
394 void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
396 OverlayBuffer* buffer = imported_buffer_->buffer_.get();
397 supported_composition_ = rhs->supported_composition_;
398 actual_composition_ = rhs->actual_composition_;
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;
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;
423 } else if (type_ == kLayerCursor) {
424 if (layer->HasLayerAttributesChanged()) {
425 state_ |= kNeedsReValidation;
429 // Ensure the buffer can be supported by display for direct
431 if (buffer->GetFormat() != rhs->imported_buffer_->buffer_->GetFormat()) {
432 state_ |= kNeedsReValidation;
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;
446 if (blending_ != rhs->blending_) {
447 state_ |= kNeedsReValidation;
451 if (rect_changed || layer->HasLayerAttributesChanged()) {
452 state_ |= kNeedsReValidation;
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;
468 state_ &= ~kDimensionsChanged;
471 if (!layer->HasVisibleRegionChanged() && !content_changed &&
472 surface_damage_.empty() && !layer->HasLayerContentChanged() &&
473 !(state_ & kNeedsReValidation) && !(state_ & kRawPixelDataChanged)) {
474 state_ &= ~kLayerContentChanged;
478 void OverlayLayer::ValidateForOverlayUsage() {
479 const std::shared_ptr<OverlayBuffer>& buffer = imported_buffer_->buffer_;
480 type_ = buffer->GetUsage();
483 void OverlayLayer::CloneLayer(const OverlayLayer* layer,
484 const HwcRect<int>& display_frame) {
485 int32_t fence = layer->GetAcquireFence();
490 SetDisplayFrame(display_frame);
491 SetSourceCrop(layer->GetSourceCrop());
492 imported_buffer_.reset(new ImportedBuffer(layer->GetSharedBuffer(), fence));
493 ValidateForOverlayUsage();
494 surface_damage_ = display_frame;
498 void OverlayLayer::Dump() {
499 DUMPTRACE("OverlayLayer Information Starts. -------------");
501 case HWCBlending::kBlendingNone:
502 DUMPTRACE("Blending: kBlendingNone.");
504 case HWCBlending::kBlendingPremult:
505 DUMPTRACE("Blending: kBlendingPremult.");
507 case HWCBlending::kBlendingCoverage:
508 DUMPTRACE("Blending: kBlendingCoverage.");
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.");
525 DUMPTRACE("Transform: kTransform0.");
527 DUMPTRACE("Alpha: %u", alpha_);
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_);
535 imported_buffer_->buffer_->Dump();
538 } // namespace hwcomposer