OSDN Git Service

Check for supported formats before creating fbs for native
authorKalyan Kondapally <kalyan.kondapally@intel.com>
Sun, 29 Jan 2017 03:00:09 +0000 (19:00 -0800)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Sun, 29 Jan 2017 03:20:30 +0000 (19:20 -0800)
 surface.

We always create RGBA buffers for these surfaces but we might not
be able to support this format during scanout. Now, instead of
making an assumption, we check if this format is supported and
if not fall back to RGBX.

Jira: AIA-120
Test: No graphics regressions on Android and Linux. Home screen
      is visible on HSW device.

Signed-off-by: Kalyan Kondapally <kalyan.kondapally@intel.com>
common/compositor/compositor.cpp
common/compositor/nativesurface.cpp
common/compositor/nativesurface.h
common/display/displayplane.cpp
common/display/displayplane.h
common/display/displayplanestate.h
common/display/overlaybuffer.cpp

index 93e9538..0e84ecc 100644 (file)
@@ -113,6 +113,7 @@ bool Compositor::Draw(DisplayPlaneStateList &comp_planes,
       if (comp_regions.empty())
         continue;
 
+      in_flight_surfaces_.back()->CreateFrameBuffer(plane, gpu_fd_);
       Render(layers, in_flight_surfaces_.back(), comp_regions);
       plane.SetOverlayLayer(&layers.back());
     }
@@ -189,7 +190,7 @@ bool Compositor::PrepareForComposition() {
 
   if (!surface) {
     NativeSurface *new_surface = CreateBackBuffer(width_, height_);
-    new_surface->Init(buffer_handler_, gpu_fd_);
+    new_surface->Init(buffer_handler_);
     surfaces_.emplace_back(std::move(new_surface));
     surface = surfaces_.back().get();
   }
index de3cd07..a8e7ef0 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "nativesurface.h"
 
+#include "displayplane.h"
 #include "hwctrace.h"
 #include "nativebufferhandler.h"
 
@@ -27,6 +28,7 @@ NativeSurface::NativeSurface(uint32_t width, uint32_t height)
       width_(width),
       height_(height),
       ref_count_(0),
+      framebuffer_format_(0),
       in_flight_(false) {
 }
 
@@ -39,7 +41,7 @@ NativeSurface::~NativeSurface() {
   }
 }
 
-bool NativeSurface::Init(NativeBufferHandler *buffer_handler, uint32_t gpu_fd) {
+bool NativeSurface::Init(NativeBufferHandler *buffer_handler) {
   buffer_handler_ = buffer_handler;
   buffer_handler_->CreateBuffer(width_, height_, 0, &native_handle_);
   if (!native_handle_) {
@@ -49,7 +51,6 @@ bool NativeSurface::Init(NativeBufferHandler *buffer_handler, uint32_t gpu_fd) {
 
   overlay_buffer_.reset(new hwcomposer::OverlayBuffer());
   overlay_buffer_->InitializeFromNativeHandle(native_handle_, buffer_handler_);
-  overlay_buffer_->CreateFrameBuffer(gpu_fd);
 
   if (!InitializeGPUResources()) {
     ETRACE("Failed to initialize gpu resources.");
@@ -97,4 +98,16 @@ void NativeSurface::SetInFlightSurface() {
   in_flight_ = true;
 }
 
+void NativeSurface::CreateFrameBuffer(const DisplayPlaneState &plane,
+                                      uint32_t gpu_fd) {
+  uint32_t format =
+      plane.plane()->GetFormatForFrameBuffer(overlay_buffer_->GetFormat());
+  if (framebuffer_format_ == format)
+    return;
+
+  framebuffer_format_ = format;
+  overlay_buffer_->SetRecommendedFormat(framebuffer_format_);
+  overlay_buffer_->CreateFrameBuffer(gpu_fd);
+}
+
 }  // namespace hwcomposer
index 26d271f..9732afd 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <platformdefines.h>
 
+#include "displayplanestate.h"
 #include "nativefence.h"
 #include "overlaybuffer.h"
 
@@ -37,7 +38,7 @@ class NativeSurface {
 
   virtual ~NativeSurface();
 
-  bool Init(NativeBufferHandler* buffer_handler, uint32_t gpu_fd);
+  bool Init(NativeBufferHandler* buffer_handler);
 
   bool InitializeForOffScreenRendering(NativeBufferHandler* buffer_handler,
                                        HWCNativeHandle native_handle);
@@ -73,6 +74,8 @@ class NativeSurface {
     return ref_count_ > 1 || in_flight_;
   }
 
+  void CreateFrameBuffer(const DisplayPlaneState& plane, uint32_t gpu_fd);
+
  protected:
   virtual bool InitializeGPUResources() = 0;
 
@@ -84,6 +87,7 @@ class NativeSurface {
   uint32_t width_;
   uint32_t height_;
   uint32_t ref_count_;
+  uint32_t framebuffer_format_;
   bool in_flight_;
   NativeFence fd_;
 };
index 42156d4..2f6227e 100644 (file)
@@ -242,22 +242,6 @@ uint32_t DisplayPlane::type() const {
 }
 
 bool DisplayPlane::ValidateLayer(const OverlayLayer* layer) {
-  uint32_t format = layer->GetBuffer()->GetFormat();
-  if (!IsSupportedFormat(format)) {
-    // In case of primary we can fallback to XRGB.
-    if (type_ == DRM_PLANE_TYPE_PRIMARY) {
-      format = GetFormatForFrameBuffer(format);
-      if (IsSupportedFormat(format)) {
-        layer->GetBuffer()->SetRecommendedFormat(format);
-        return true;
-      }
-    }
-
-    IDISPLAYMANAGERTRACE(
-        "Layer cannot be supported as format is not supported.");
-    return false;
-  }
-
   uint64_t alpha = 0xFF;
 
   if (layer->GetBlending() == HWCBlending::kBlendingPremult)
@@ -277,6 +261,12 @@ bool DisplayPlane::ValidateLayer(const OverlayLayer* layer) {
     return false;
   }
 
+  if (!IsSupportedFormat(layer->GetBuffer()->GetFormat())) {
+    IDISPLAYMANAGERTRACE(
+        "Layer cannot be supported as format is not supported.");
+    return false;
+  }
+
   return true;
 }
 
@@ -294,17 +284,20 @@ bool DisplayPlane::IsSupportedFormat(uint32_t format) {
   return false;
 }
 
-uint32_t DisplayPlane::GetFormatForFrameBuffer(uint32_t format) const {
-  // We only support 24 bit colordepth for primary planes on
-  // pre SKL Hardware. Ideally, we query format support from
-  // plane to determine this.
-  switch (format) {
-    case DRM_FORMAT_ABGR8888:
-      return DRM_FORMAT_XBGR8888;
-    case DRM_FORMAT_ARGB8888:
-      return DRM_FORMAT_XRGB8888;
-    default:
-      break;
+uint32_t DisplayPlane::GetFormatForFrameBuffer(uint32_t format) {
+  if (IsSupportedFormat(format))
+    return format;
+
+  if (type_ == DRM_PLANE_TYPE_PRIMARY) {
+    // In case of alpha, fall back to XRGB.
+    switch (format) {
+      case DRM_FORMAT_ABGR8888:
+        return DRM_FORMAT_XBGR8888;
+      case DRM_FORMAT_ARGB8888:
+        return DRM_FORMAT_XRGB8888;
+      default:
+        break;
+    }
   }
 
   return format;
index 774867f..9e47514 100644 (file)
@@ -59,10 +59,11 @@ class DisplayPlane {
 
   bool IsSupportedFormat(uint32_t format);
 
+  uint32_t GetFormatForFrameBuffer(uint32_t format);
+
   void Dump() const;
 
  private:
-  uint32_t GetFormatForFrameBuffer(uint32_t format) const;
   struct Property {
     Property();
     bool Initialize(uint32_t fd, const char* name,
index 703b0d0..5f3f896 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <stdint.h>
 
+#include <vector>
+
 namespace hwcomposer {
 
 class DisplayPlane;
index 100446b..e136383 100644 (file)
@@ -110,6 +110,10 @@ void OverlayBuffer::SetRecommendedFormat(uint32_t format) {
 }
 
 bool OverlayBuffer::CreateFrameBuffer(uint32_t gpu_fd) {
+  if (fb_id_ && gpu_fd_ && drmModeRmFB(gpu_fd_, fb_id_))
+    ETRACE("Failed to remove fb %s", PRINTERROR());
+
+  fb_id_ = 0;
   int ret = drmModeAddFB2(gpu_fd, width_, height_, format_, gem_handles_,
                           pitches_, offsets_, &fb_id_, 0);