OSDN Git Service

Add full color range support
[android-x86/external-IA-Hardware-Composer.git] / common / core / overlaylayer.cpp
index 10dc9fc..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,56 +44,73 @@ 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, HwcLayer* layer) {
+                             bool register_buffer,
+                             FrameBufferManager* frame_buffer_manager) {
   std::shared_ptr<OverlayBuffer> buffer(NULL);
 
-  // FIXME: Enable cache again.
-  /*if (resource_manager && register_buffer) {
-    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();
-    bool is_cursor_layer = false;
-    if (layer) {
-      is_cursor_layer = layer->IsCursorLayer();
-    }
     buffer->InitializeFromNativeHandle(handle, resource_manager,
-                                       is_cursor_layer);
-    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);
   }
 
-  if (register_buffer && handle->is_raw_pixel_ && !surface_damage_.empty()) {
-    buffer->UpdateRawPixelBackingStore(handle->pixel_memory_);
-    state_ |= kRawPixelDataChanged;
-  }
+  buffer->SetDataSpace(dataspace_);
 
   imported_buffer_.reset(new ImportedBuffer(buffer, acquire_fence));
   ValidateForOverlayUsage();
@@ -112,7 +132,6 @@ 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) {
@@ -122,78 +141,43 @@ void OverlayLayer::SetTransform(uint32_t transform) {
 
 void OverlayLayer::ValidateTransform(uint32_t transform,
                                      uint32_t display_transform) {
-  if (transform & kTransform90) {
-    switch (display_transform) {
-      case HWCTransform::kTransform90:
-        plane_transform_ |= kTransform180;
-        break;
-      case HWCTransform::kTransform180:
-        plane_transform_ |= kTransform270;
-        break;
-      case HWCTransform::kIdentity:
-        plane_transform_ |= kTransform90;
-        if (transform & kReflectX) {
-          plane_transform_ |= kReflectX;
-        }
+  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 {
+    // reaching here indicates that transform is
+    // is an OR of multiple values
+    // Assign Identity in this case
+    mtransform = kIdentity;
+  }
 
-        if (transform & kReflectY) {
-          plane_transform_ |= kReflectY;
-        }
-        break;
-      default:
-        break;
-    }
-  } else if (transform & kTransform180) {
-    switch (display_transform) {
-      case HWCTransform::kTransform90:
-        plane_transform_ |= kTransform270;
-        break;
-      case HWCTransform::kTransform270:
-        plane_transform_ |= kTransform90;
-        break;
-      case HWCTransform::kIdentity:
-        plane_transform_ |= kTransform180;
-        break;
-      default:
-        break;
-    }
-  } else if (transform & kTransform270) {
-    switch (display_transform) {
-      case HWCTransform::kTransform270:
-        plane_transform_ |= kTransform180;
-        break;
-      case HWCTransform::kTransform180:
-        plane_transform_ |= kTransform90;
-        break;
-      case HWCTransform::kIdentity:
-        plane_transform_ |= kTransform270;
-        break;
-      default:
-        break;
-    }
+  if (tmap.find(mdisplay_transform) != tmap.end()) {
+    mdisplay_transform = tmap[mdisplay_transform];
   } else {
-    if (display_transform & HWCTransform::kTransform90) {
-      if (transform & kReflectX) {
-        plane_transform_ |= kReflectX;
-      }
+    mdisplay_transform = kIdentity;
+  }
 
-      if (transform & kReflectY) {
-        plane_transform_ |= kReflectY;
-      }
+  // 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;
 
-      plane_transform_ |= kTransform90;
-    } else {
-      switch (display_transform) {
-        case HWCTransform::kTransform270:
-          plane_transform_ |= kTransform270;
-          break;
-        case HWCTransform::kTransform180:
-          plane_transform_ |= kTransform180;
-          break;
-        default:
-          break;
-      }
-    }
+  if (plane_transform_ & kTransform90) {
+    if (transform & kReflectX)
+      plane_transform_ |= kReflectX;
+
+    if (transform & kReflectY)
+      plane_transform_ |= kReflectY;
   }
 }
 
@@ -202,7 +186,8 @@ void OverlayLayer::InitializeState(HwcLayer* layer,
                                    OverlayLayer* previous_layer,
                                    uint32_t z_order, uint32_t layer_index,
                                    uint32_t max_height, uint32_t rotation,
-                                   bool handle_constraints) {
+                                   bool handle_constraints,
+                                   FrameBufferManager* frame_buffer_manager) {
   transform_ = layer->GetTransform();
   if (rotation != kRotateNone) {
     ValidateTransform(layer->GetTransform(), rotation);
@@ -216,16 +201,55 @@ 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();
-  if (!layer->IsCursorLayer() && layer->HasZorderChanged() &&
-      (!previous_layer ||
-       (previous_layer && (previous_layer->z_order_ != z_order)))) {
-    state_ |= kLayerOrderChanged;
+  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;
+    }
   }
 
-  surface_damage_ = layer->GetLayerDamage();
-  SetBuffer(layer->GetNativeHandle(), layer->GetAcquireFence(),
-            resource_manager, true, layer);
+  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 (!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) {
     if (previous_layer) {
@@ -281,6 +305,15 @@ void OverlayLayer::InitializeState(HwcLayer* layer,
     display_frame_width_ = display_frame_.right - display_frame_.left;
     display_frame_height_ = display_frame_.bottom - display_frame_.top;
 
+    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);
@@ -323,27 +356,33 @@ void OverlayLayer::InitializeState(HwcLayer* layer,
 void OverlayLayer::InitializeFromHwcLayer(
     HwcLayer* layer, ResourceManager* resource_manager,
     OverlayLayer* previous_layer, uint32_t z_order, uint32_t layer_index,
-    uint32_t max_height, uint32_t 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, uint32_t rotation,
-    bool handle_constraints) {
+    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();
+  OverlayBuffer* buffer = NULL;
+  if (imported_buffer_.get())
+    buffer = imported_buffer_->buffer_.get();
+
   supported_composition_ = rhs->supported_composition_;
   actual_composition_ = rhs->actual_composition_;
 
@@ -354,7 +393,8 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
     state_ |= kSourceRectChanged;
 
   // We expect cursor plane to support alpha always.
-  if ((actual_composition_ & kGpu) || (type_ == kLayerCursor)) {
+  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
@@ -363,8 +403,9 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
         content_changed = true;
         CalculateRect(rhs->display_frame_, surface_damage_);
       } else if (!content_changed) {
-        if ((buffer->GetFormat() !=
-             rhs->imported_buffer_->buffer_->GetFormat()) ||
+        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;
@@ -378,7 +419,11 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
   } else {
     // Ensure the buffer can be supported by display for direct
     // scanout.
-    if (buffer->GetFormat() != rhs->imported_buffer_->buffer_->GetFormat()) {
+    if (!rhs->imported_buffer_.get()) {
+      state_ |= kNeedsReValidation;
+      return;
+    } else if (buffer && (buffer->GetFormat() !=
+                          rhs->imported_buffer_->buffer_->GetFormat())) {
       state_ |= kNeedsReValidation;
       return;
     }
@@ -420,7 +465,7 @@ void OverlayLayer::ValidatePreviousFrameState(OverlayLayer* rhs,
 
   if (!layer->HasVisibleRegionChanged() && !content_changed &&
       surface_damage_.empty() && !layer->HasLayerContentChanged() &&
-      !(state_ & kNeedsReValidation) && !(state_ & kRawPixelDataChanged)) {
+      !(state_ & kNeedsReValidation)) {
     state_ &= ~kLayerContentChanged;
   }
 }
@@ -430,6 +475,31 @@ void OverlayLayer::ValidateForOverlayUsage() {
   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() {
   DUMPTRACE("OverlayLayer Information Starts. -------------");
   switch (blending_) {
@@ -450,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)
@@ -465,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();
 }