OSDN Git Service

Add full color range support
[android-x86/external-IA-Hardware-Composer.git] / common / core / overlaylayer.cpp
index f8a3358..39c2af6 100644 (file)
 
 #include <drm_mode.h>
 #include <hwctrace.h>
+#include <map>
+#include <vector>
 
 #include "hwcutils.h"
 
+#include "nativebufferhandler.h"
 #include "resourcemanager.h"
 
 namespace hwcomposer {
@@ -41,50 +44,76 @@ OverlayLayer::ImportedBuffer::ImportedBuffer(
 
 void OverlayLayer::SetAcquireFence(int32_t acquire_fence) {
   // Release any existing fence.
-  if (imported_buffer_->acquire_fence_ > 0) {
-    close(imported_buffer_->acquire_fence_);
-  }
+  if (imported_buffer_.get()) {
+    if (imported_buffer_->acquire_fence_ > 0) {
+      close(imported_buffer_->acquire_fence_);
+    }
 
-  imported_buffer_->acquire_fence_ = acquire_fence;
+    imported_buffer_->acquire_fence_ = acquire_fence;
+  }
 }
 
 int32_t OverlayLayer::GetAcquireFence() const {
-  return imported_buffer_->acquire_fence_;
+  if (imported_buffer_.get()) {
+    return imported_buffer_->acquire_fence_;
+  } else
+    return -1;
 }
 
 int32_t OverlayLayer::ReleaseAcquireFence() const {
-  int32_t fence = imported_buffer_->acquire_fence_;
-  imported_buffer_->acquire_fence_ = -1;
-  return fence;
+  if (imported_buffer_.get()) {
+    int32_t fence = imported_buffer_->acquire_fence_;
+    imported_buffer_->acquire_fence_ = -1;
+    return fence;
+  } else {
+    return -1;
+  }
 }
 
 OverlayBuffer* OverlayLayer::GetBuffer() const {
-  if (imported_buffer_->buffer_.get() == NULL)
-    ETRACE("hwc layer get NullBuffer");
-  return imported_buffer_->buffer_.get();
+  if (imported_buffer_.get()) {
+    if (imported_buffer_->buffer_.get() == NULL)
+      ETRACE("hwc layer get NullBuffer");
+
+    return imported_buffer_->buffer_.get();
+  } else {
+    return NULL;
+  }
+}
+
+std::shared_ptr<OverlayBuffer>& OverlayLayer::GetSharedBuffer() const {
+  return imported_buffer_->buffer_;
 }
 
 void OverlayLayer::SetBuffer(HWCNativeHandle handle, int32_t acquire_fence,
                              ResourceManager* resource_manager,
-                             bool register_buffer) {
+                             bool register_buffer,
+                             FrameBufferManager* frame_buffer_manager) {
   std::shared_ptr<OverlayBuffer> buffer(NULL);
 
-  if (resource_manager) {
-    buffer = resource_manager->FindCachedBuffer(GETNATIVEBUFFER(handle));
+  uint32_t id;
+
+  if (resource_manager && register_buffer) {
+    uint32_t gpu_fd = resource_manager->GetNativeBufferHandler()->GetFd();
+    id = GetNativeBuffer(gpu_fd, handle);
+    buffer = resource_manager->FindCachedBuffer(id);
   }
 
   if (buffer == NULL) {
     buffer = OverlayBuffer::CreateOverlayBuffer();
     buffer->InitializeFromNativeHandle(handle, resource_manager,
-                                       register_buffer);
-    if (register_buffer) {
-      resource_manager->RegisterBuffer(GETNATIVEBUFFER(handle), buffer);
+                                       frame_buffer_manager);
+    if (resource_manager && register_buffer) {
+      resource_manager->RegisterBuffer(id, buffer);
     }
+  } else {
+    buffer->SetOriginalHandle(handle);
   }
+
+  buffer->SetDataSpace(dataspace_);
+
   imported_buffer_.reset(new ImportedBuffer(buffer, acquire_fence));
-  if (!register_buffer) {
-    ValidateForOverlayUsage();
-  }
+  ValidateForOverlayUsage();
 }
 
 void OverlayLayer::SetBlending(HWCBlending blending) {
@@ -103,114 +132,65 @@ void OverlayLayer::SetDisplayFrame(const HwcRect<int>& display_frame) {
   display_frame_width_ = display_frame.right - display_frame.left;
   display_frame_height_ = display_frame.bottom - display_frame.top;
   display_frame_ = display_frame;
-  surface_damage_ = display_frame;
+}
+
+void OverlayLayer::SetTransform(uint32_t transform) {
+  plane_transform_ = transform;
+  transform_ = transform;
 }
 
 void OverlayLayer::ValidateTransform(uint32_t transform,
                                      uint32_t display_transform) {
-  if (transform & kTransform90) {
-    if (transform & kReflectX) {
-      plane_transform_ |= kReflectX;
-    }
-
-    if (transform & kReflectY) {
-      plane_transform_ |= kReflectY;
-    }
-
-    switch (display_transform) {
-      case kRotate90:
-        plane_transform_ |= kTransform180;
-        break;
-      case kRotate180:
-        plane_transform_ |= kTransform270;
-        break;
-      case kRotateNone:
-        plane_transform_ |= kTransform90;
-        break;
-      default:
-        break;
-    }
-  } else if (transform & kTransform180) {
-    switch (display_transform) {
-      case kRotate90:
-        plane_transform_ |= kTransform270;
-        break;
-      case kRotate270:
-        plane_transform_ |= kTransform90;
-        break;
-      case kRotateNone:
-        plane_transform_ |= kTransform180;
-        break;
-      default:
-        break;
-    }
-  } else if (transform & kTransform270) {
-    switch (display_transform) {
-      case kRotate270:
-        plane_transform_ |= kTransform180;
-        break;
-      case kRotate180:
-        plane_transform_ |= kTransform90;
-        break;
-      case kRotateNone:
-        plane_transform_ |= kTransform270;
-        break;
-      default:
-        break;
-    }
+  std::map<int, int> tmap = {{kIdentity, 0},
+                             {kTransform90, 1},
+                             {kTransform180, 2},
+                             {kTransform270, 3}};
+  std::vector<int> inv_tmap = {kIdentity, kTransform90, kTransform180,
+                               kTransform270};
+
+  int mdisplay_transform = display_transform;
+  int mtransform =
+      transform & (kIdentity | kTransform90 | kTransform180 | kTransform270);
+
+  if (tmap.find(mtransform) != tmap.end()) {
+    mtransform = tmap[mtransform];
   } else {
-    if (display_transform == kRotate90) {
-      if (transform & kReflectX) {
-        plane_transform_ |= kReflectX;
-      }
-
-      if (transform & kReflectY) {
-        plane_transform_ |= kReflectY;
-      }
-
-      plane_transform_ |= kTransform90;
-    } else {
-      switch (display_transform) {
-        case kRotate270:
-          plane_transform_ |= kTransform270;
-          break;
-        case kRotate180:
-          plane_transform_ |= kReflectY;
-          break;
-        default:
-          break;
-      }
-    }
+    // reaching here indicates that transform is
+    // is an OR of multiple values
+    // Assign Identity in this case
+    mtransform = kIdentity;
   }
-}
 
-void OverlayLayer::UpdateSurfaceDamage(HwcLayer* layer) {
-  if (!gpu_rendered_) {
-    surface_damage_ = display_frame_;
-    return;
+  if (tmap.find(mdisplay_transform) != tmap.end()) {
+    mdisplay_transform = tmap[mdisplay_transform];
+  } else {
+    mdisplay_transform = kIdentity;
   }
 
-  if ((state_ & kClearSurface) || (state_ & kDimensionsChanged) ||
-      (transform_ != kIdentity)) {
-    surface_damage_ = display_frame_;
-    return;
-  }
+  // The elements {0, 1, 2, 3} form a circulant matrix under mod 4 arithmetic
+  mtransform = (mtransform + mdisplay_transform) % 4;
+  mtransform = inv_tmap[mtransform];
+  plane_transform_ = mtransform;
 
-  surface_damage_ = layer->GetSurfaceDamage();
+  if (plane_transform_ & kTransform90) {
+    if (transform & kReflectX)
+      plane_transform_ |= kReflectX;
+
+    if (transform & kReflectY)
+      plane_transform_ |= kReflectY;
+  }
 }
 
 void OverlayLayer::InitializeState(HwcLayer* layer,
                                    ResourceManager* resource_manager,
                                    OverlayLayer* previous_layer,
                                    uint32_t z_order, uint32_t layer_index,
-                                   uint32_t max_height, HWCRotation rotation,
-                                   bool handle_constraints) {
+                                   uint32_t max_height, uint32_t rotation,
+                                   bool handle_constraints,
+                                   FrameBufferManager* frame_buffer_manager) {
   transform_ = layer->GetTransform();
   if (rotation != kRotateNone) {
     ValidateTransform(layer->GetTransform(), rotation);
-    // Remove this in case we enable support in future
-    // to apply display rotation at pipe level.
-    transform_ = plane_transform_;
   } else {
     plane_transform_ = transform_;
   }
@@ -221,22 +201,60 @@ void OverlayLayer::InitializeState(HwcLayer* layer,
   source_crop_width_ = layer->GetSourceCropWidth();
   source_crop_height_ = layer->GetSourceCropHeight();
   source_crop_ = layer->GetSourceCrop();
+  dataspace_ = layer->GetDataSpace();
   blending_ = layer->GetBlending();
-  SetBuffer(layer->GetNativeHandle(), layer->GetAcquireFence(),
-            resource_manager, true);
-  ValidateForOverlayUsage();
-  if (previous_layer) {
-    ValidatePreviousFrameState(previous_layer, layer);
+  surface_damage_ = layer->GetLayerDamage();
+
+  solid_color_ = layer->GetSolidColor();
+
+  if (previous_layer && layer->HasZorderChanged()) {
+    if (previous_layer->actual_composition_ == kGpu) {
+      CalculateRect(previous_layer->display_frame_, surface_damage_);
+      bool force_partial_clear = true;
+      // We can skip Clear in case display frame, transforms are same.
+      if (previous_layer->display_frame_ == display_frame_ &&
+          transform_ == previous_layer->transform_ &&
+          plane_transform_ == previous_layer->plane_transform_) {
+        force_partial_clear = false;
+      }
+
+      if (force_partial_clear) {
+        state_ |= kForcePartialClear;
+      }
+    } else if (!layer->IsCursorLayer()) {
+      state_ |= kNeedsReValidation;
+    }
+  }
+
+  if (layer->GetNativeHandle()) {
+    SetBuffer(layer->GetNativeHandle(), layer->GetAcquireFence(),
+              resource_manager, true, frame_buffer_manager);
+  } else if (Composition_SolidColor == layer->GetLayerCompositionType()) {
+    type_ = kLayerSolidColor;
+    source_crop_width_ = layer->GetDisplayFrameWidth();
+    source_crop_height_ = layer->GetDisplayFrameHeight();
+    source_crop_.left = source_crop_.top = 0;
+    source_crop_.right = source_crop_width_;
+    source_crop_.top = source_crop_height_;
+    imported_buffer_.reset(NULL);
+  } else {
+    ETRACE(
+        "HWC don't support a layer with no buffer handle except in SolidColor "
+        "type");
   }
 
-  if (layer->HasContentAttributesChanged() ||
-      layer->HasLayerAttributesChanged() || !layer->IsValidated()) {
-    state_ |= kClearSurface;
-    state_ |= kLayerContentChanged;
+  if (!surface_damage_.empty()) {
+    if (type_ == kLayerCursor) {
+      const std::shared_ptr<OverlayBuffer>& buffer = imported_buffer_->buffer_;
+      surface_damage_.right = surface_damage_.left + buffer->GetWidth();
+      surface_damage_.bottom = surface_damage_.top + buffer->GetHeight();
+    }
   }
 
   if (!handle_constraints) {
-    UpdateSurfaceDamage(layer);
+    if (previous_layer) {
+      ValidatePreviousFrameState(previous_layer, layer);
+    }
     return;
   }
 
@@ -271,32 +289,46 @@ void OverlayLayer::InitializeState(HwcLayer* layer,
       display_frame_.right = right_source_constraint;
     }
 
+    // Handle case where we might be using logical and Mosaic together.
     display_frame_.left =
         (display_frame_.left - left_source_constraint) + left_constraint;
     display_frame_.right =
         (display_frame_.right - left_source_constraint) + left_constraint;
+    IMOSAICDISPLAYTRACE(
+        "display_frame_ %d %d %d %d  left_source_constraint: %d "
+        "left_constraint: %d \n",
+        display_frame_.left, display_frame_.right, display_frame_.top,
+        display_frame_.bottom, left_source_constraint, left_constraint);
 
     display_frame_.bottom =
         std::min(max_height, static_cast<uint32_t>(display_frame_.bottom));
     display_frame_width_ = display_frame_.right - display_frame_.left;
     display_frame_height_ = display_frame_.bottom - display_frame_.top;
 
-    UpdateSurfaceDamage(layer);
-    if (gpu_rendered_) {
-      // If viewport and layer doesn't interact we can avoid re-rendering
-      // this layer.
-      if (AnalyseOverlap(surface_damage_, display_frame_) != kOutside) {
-        surface_damage_.left =
-            std::max(surface_damage_.left, display_frame_.left);
-        surface_damage_.right =
-            std::min(surface_damage_.right, display_frame_.right);
-        surface_damage_.top = std::max(surface_damage_.top, display_frame_.top);
-        surface_damage_.bottom =
-            std::min(surface_damage_.bottom, display_frame_.bottom);
-      } else {
-        surface_damage_ = HwcRect<int>(0, 0, 0, 0);
-      }
+    if ((surface_damage_.left < display_frame_.left) &&
+        (surface_damage_.right > display_frame_.left)) {
+      surface_damage_.left = display_frame_.left;
+    }
+
+    if (surface_damage_.right > display_frame_.right) {
+      surface_damage_.right = display_frame_.right;
+    }
+
+    if (AnalyseOverlap(surface_damage_, display_frame_) != kOutside) {
+      surface_damage_.bottom =
+          std::min(surface_damage_.bottom, display_frame_.bottom);
+      surface_damage_.right =
+          std::min(surface_damage_.right, display_frame_.right);
+      surface_damage_.left =
+          std::max(surface_damage_.left, display_frame_.left);
+    } else {
+      surface_damage_.reset();
     }
+    IMOSAICDISPLAYTRACE(
+        "surface_damage_ %d %d %d %d  left_source_constraint: %d "
+        "left_constraint: %d \n",
+        surface_damage_.left, surface_damage_.right, surface_damage_.top,
+        surface_damage_.bottom, left_source_constraint, left_constraint);
 
     // split the source in proportion of frame rect offset for sub displays as:
     // 1. the original source size may be different with the original frame
@@ -315,34 +347,44 @@ void OverlayLayer::InitializeState(HwcLayer* layer,
     source_crop_height_ = static_cast<int>(ceilf(source_crop_.bottom) -
                                            static_cast<int>(source_crop_.top));
   }
+
+  if (previous_layer) {
+    ValidatePreviousFrameState(previous_layer, layer);
+  }
 }
 
 void OverlayLayer::InitializeFromHwcLayer(
     HwcLayer* layer, ResourceManager* resource_manager,
     OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index,
-    uint32_t max_height, HWCRotation rotation, bool handle_constraints) {
+    uint32_t max_height, uint32_t rotation, bool handle_constraints,
+    FrameBufferManager* frame_buffer_manager) {
   display_frame_width_ = layer->GetDisplayFrameWidth();
   display_frame_height_ = layer->GetDisplayFrameHeight();
   display_frame_ = layer->GetDisplayFrame();
   InitializeState(layer, resource_manager, previous_layer, z_order, layer_index,
-                  max_height, rotation, handle_constraints);
+                  max_height, rotation, handle_constraints,
+                  frame_buffer_manager);
 }
 
 void OverlayLayer::InitializeFromScaledHwcLayer(
     HwcLayer* layer, ResourceManager* resource_manager,
     OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index,
-    const HwcRect<int>& display_frame, uint32_t max_height,
-    HWCRotation rotation, bool handle_constraints) {
+    const HwcRect<int>& display_frame, uint32_t max_height, uint32_t rotation,
+    bool handle_constraints, FrameBufferManager* frame_buffer_manager) {
   SetDisplayFrame(display_frame);
   InitializeState(layer, resource_manager, previous_layer, z_order, layer_index,
-                  max_height, rotation, handle_constraints);
+                  max_height, rotation, handle_constraints,
+                  frame_buffer_manager);
 }
 
 void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
                                               HwcLayer* layer) {
-  OverlayBuffer* buffer = imported_buffer_->buffer_.get();
-  if (buffer->GetFormat() != rhs->imported_buffer_->buffer_->GetFormat())
-    return;
+  OverlayBuffer* buffer = NULL;
+  if (imported_buffer_.get())
+    buffer = imported_buffer_->buffer_.get();
+
+  supported_composition_ = rhs->supported_composition_;
+  actual_composition_ = rhs->actual_composition_;
 
   bool content_changed = false;
   bool rect_changed = layer->HasDisplayRectChanged();
@@ -351,35 +393,59 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
     state_ |= kSourceRectChanged;
 
   // We expect cursor plane to support alpha always.
-  if (rhs->gpu_rendered_ || (type_ == kLayerCursor)) {
-    content_changed = rect_changed || source_rect_changed;
+  if ((actual_composition_ & kGpu) || (type_ == kLayerCursor) ||
+      (type_ == kLayerSolidColor)) {
+    if (actual_composition_ & kGpu) {
+      content_changed = rect_changed || source_rect_changed;
+      // This layer has replaced an existing layer, let's make sure
+      // we re-draw this and previous layer regions.
+      if (!layer->IsValidated()) {
+        content_changed = true;
+        CalculateRect(rhs->display_frame_, surface_damage_);
+      } else if (!content_changed) {
+        if ((buffer && rhs->imported_buffer_.get() &&
+             (buffer->GetFormat() !=
+              rhs->imported_buffer_->buffer_->GetFormat())) ||
+            (alpha_ != rhs->alpha_) || (blending_ != rhs->blending_) ||
+            (transform_ != rhs->transform_)) {
+          content_changed = true;
+        }
+      }
+    } else if (type_ == kLayerCursor) {
+      if (layer->HasLayerAttributesChanged()) {
+        state_ |= kNeedsReValidation;
+      }
+    }
   } else {
+    // Ensure the buffer can be supported by display for direct
+    // scanout.
+    if (!rhs->imported_buffer_.get()) {
+      state_ |= kNeedsReValidation;
+      return;
+    } else if (buffer && (buffer->GetFormat() !=
+                          rhs->imported_buffer_->buffer_->GetFormat())) {
+      state_ |= kNeedsReValidation;
+      return;
+    }
+
     // If previous layer was opaque and we have alpha now,
     // let's mark this layer for re-validation. Plane
     // supporting XRGB format might not necessarily support
     // transparent planes. We assume plane supporting
     // ARGB will support XRGB.
-    if ((rhs->alpha_ == 0xff) && (alpha_ != rhs->alpha_))
+    if ((rhs->alpha_ == 0xff) && (alpha_ != rhs->alpha_)) {
+      state_ |= kNeedsReValidation;
       return;
+    }
 
-    if (blending_ != rhs->blending_)
+    if (blending_ != rhs->blending_) {
+      state_ |= kNeedsReValidation;
       return;
+    }
 
     if (rect_changed || layer->HasLayerAttributesChanged()) {
-      if (layer->IsValidated()) {
-        return;
-      }
-
-      if (rhs->transform_ != transform_) {
-        return;
-      }
-
-      if ((rhs->display_frame_.left != display_frame_.left) ||
-          (rhs->display_frame_.right != display_frame_.right) ||
-          (rhs->display_frame_.top != display_frame_.top) ||
-          (rhs->display_frame_.bottom != display_frame_.bottom)) {
-        return;
-      }
+      state_ |= kNeedsReValidation;
+      return;
     }
 
     if (source_rect_changed) {
@@ -387,32 +453,51 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
       // shouldn't impact the plane composition results.
       if ((source_crop_width_ != rhs->source_crop_width_) ||
           (source_crop_height_ != rhs->source_crop_height_)) {
+        state_ |= kNeedsReValidation;
         return;
       }
     }
   }
 
-  state_ &= ~kLayerAttributesChanged;
-  gpu_rendered_ = rhs->gpu_rendered_;
-
   if (!rect_changed) {
     state_ &= ~kDimensionsChanged;
   }
 
-  if (!layer->HasVisibleRegionChanged() &&
-      !layer->HasSurfaceDamageRegionChanged() &&
-      !layer->HasLayerContentChanged() && !content_changed) {
+  if (!layer->HasVisibleRegionChanged() && !content_changed &&
+      surface_damage_.empty() && !layer->HasLayerContentChanged() &&
+      !(state_ & kNeedsReValidation)) {
     state_ &= ~kLayerContentChanged;
   }
 }
 
 void OverlayLayer::ValidateForOverlayUsage() {
   const std::shared_ptr<OverlayBuffer>& buffer = imported_buffer_->buffer_;
-  if (buffer->GetUsage() & kLayerCursor) {
-    type_ = kLayerCursor;
-  } else if (buffer->IsVideoBuffer()) {
-    type_ = kLayerVideo;
+  type_ = buffer->GetUsage();
+}
+
+void OverlayLayer::CloneLayer(const OverlayLayer* layer,
+                              const HwcRect<int>& display_frame,
+                              ResourceManager* resource_manager,
+                              uint32_t z_order,
+                              FrameBufferManager* frame_buffer_manager) {
+  int32_t fence = layer->GetAcquireFence();
+  int32_t aquire_fence = 0;
+  if (fence > 0) {
+    aquire_fence = dup(fence);
   }
+  SetDisplayFrame(display_frame);
+  SetSourceCrop(layer->GetSourceCrop());
+  SetBuffer(layer->GetBuffer()->GetOriginalHandle(), aquire_fence,
+            resource_manager, true, frame_buffer_manager);
+  ValidateForOverlayUsage();
+  surface_damage_ = layer->GetSurfaceDamage();
+  transform_ = layer->transform_;
+  plane_transform_ = layer->plane_transform_;
+  alpha_ = layer->alpha_;
+  layer_index_ = z_order;
+  z_order_ = z_order;
+  blending_ = layer->blending_;
+  solid_color_ = layer->solid_color_;
 }
 
 void OverlayLayer::Dump() {
@@ -435,8 +520,8 @@ void OverlayLayer::Dump() {
     DUMPTRACE("Transform: kReflectX.");
   if (transform_ & kReflectY)
     DUMPTRACE("Transform: kReflectY.");
-  if (transform_ & kReflectY)
-    DUMPTRACE("Transform: kReflectY.");
+  if (transform_ & kTransform90)
+    DUMPTRACE("Transform: kTransform90.");
   else if (transform_ & kTransform180)
     DUMPTRACE("Transform: kTransform180.");
   else if (transform_ & kTransform270)
@@ -450,7 +535,11 @@ void OverlayLayer::Dump() {
   DUMPTRACE("SourceHeight: %d", source_crop_height_);
   DUMPTRACE("DstWidth: %d", display_frame_width_);
   DUMPTRACE("DstHeight: %d", display_frame_height_);
-  DUMPTRACE("AquireFence: %d", imported_buffer_->acquire_fence_);
+  DUMPTRACE("Source crop %s", StringifyRect(source_crop_).c_str());
+  DUMPTRACE("Display frame %s", StringifyRect(display_frame_).c_str());
+  DUMPTRACE("Surface Damage %s", StringifyRect(surface_damage_).c_str());
+  if (imported_buffer_)
+    DUMPTRACE("AquireFence: %d", imported_buffer_->acquire_fence_);
 
   imported_buffer_->buffer_->Dump();
 }