diff mbox

[hwc,v2,16/18] drm_hwcomposer: Find writeback connector for scene flattening

Message ID 1523460149-1740-17-git-send-email-alexandru-cosmin.gheorghe@arm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Alexandru-Cosmin Gheorghe April 11, 2018, 3:22 p.m. UTC
Add logic for finding a suitable writeback connector, there are two
possibilities for finding an usable writeback connector:

1) Attached to the same CRTC as the display and can function
   concurrently with the display connector.

2) On a different CRTC and the display connector is not used (state !=
DRM_MODE_CONNECTED). What's not handled here and should be handle is
what happens if connector changes state while flattening, but since
hotplug is not wired yet, it's not something we should worry about.

Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
---
 drmresources.cpp    | 25 +++++++++++++++++++++++++
 drmresources.h      |  2 +-
 resourcemanager.cpp | 24 ++++++++++++++++++++++++
 resourcemanager.h   |  1 +
 4 files changed, 51 insertions(+), 1 deletion(-)

Comments

Sean Paul April 17, 2018, 5:15 p.m. UTC | #1
On Wed, Apr 11, 2018 at 04:22:27PM +0100, Alexandru Gheorghe wrote:
> Add logic for finding a suitable writeback connector, there are two
> possibilities for finding an usable writeback connector:
> 
> 1) Attached to the same CRTC as the display and can function
>    concurrently with the display connector.
> 
> 2) On a different CRTC and the display connector is not used (state !=
> DRM_MODE_CONNECTED). What's not handled here and should be handle is
> what happens if connector changes state while flattening, but since
> hotplug is not wired yet, it's not something we should worry about.
> 
> Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
> ---
>  drmresources.cpp    | 25 +++++++++++++++++++++++++
>  drmresources.h      |  2 +-
>  resourcemanager.cpp | 24 ++++++++++++++++++++++++
>  resourcemanager.h   |  1 +
>  4 files changed, 51 insertions(+), 1 deletion(-)
> 
> diff --git a/drmresources.cpp b/drmresources.cpp
> index fef6835..70126a4 100644
> --- a/drmresources.cpp
> +++ b/drmresources.cpp
> @@ -269,6 +269,31 @@ DrmConnector *DrmResources::GetWritebackConnectorForDisplay(int display) const {
>    return NULL;
>  }
>  
> +// TODO what happens when hotplugging
> +DrmConnector *DrmResources::AvailableWritebackConnector(int display) const {
> +  DrmConnector *writeback_conn = GetWritebackConnectorForDisplay(display);
> +  DrmConnector *display_conn = GetConnectorForDisplay(display);
> +  // If we have a writeback already attached to the same CRTC, just use that, if
> +  // possible
> +  if (display_conn && writeback_conn &&
> +      writeback_conn->encoder()->can_clone(display_conn->encoder()))
> +    return writeback_conn;
> +
> +  // Use another CRTC if available and doesn't have any connector
> +  for (auto &crtc : crtcs_) {
> +    if (crtc->display() == display)
> +      continue;
> +    display_conn = GetConnectorForDisplay(crtc->display());
> +    // If we have a display connected don't use it for writeback
> +    if (display_conn && display_conn->state() == DRM_MODE_CONNECTED)
> +      continue;
> +    writeback_conn = GetWritebackConnectorForDisplay(crtc->display());
> +    if (writeback_conn)
> +      return writeback_conn;
> +  }
> +  return NULL;
> +}
> +
>  DrmCrtc *DrmResources::GetCrtcForDisplay(int display) const {
>    for (auto &crtc : crtcs_) {
>      if (crtc->display() == display)
> diff --git a/drmresources.h b/drmresources.h
> index 4fb17fc..9176b8e 100644
> --- a/drmresources.h
> +++ b/drmresources.h
> @@ -60,7 +60,7 @@ class DrmResources {
>  
>    DrmConnector *GetConnectorForDisplay(int display) const;
>    DrmConnector *GetWritebackConnectorForDisplay(int display) const;
> -  DrmConnector *FindWritebackConnector(int display) const;

What's up with this?

> +  DrmConnector *AvailableWritebackConnector(int display) const;
>    DrmCrtc *GetCrtcForDisplay(int display) const;
>    DrmPlane *GetPlane(uint32_t id) const;
>    DrmEventListener *event_listener();
> diff --git a/resourcemanager.cpp b/resourcemanager.cpp
> index e7b654e..b2a4458 100644
> --- a/resourcemanager.cpp
> +++ b/resourcemanager.cpp
> @@ -49,6 +49,30 @@ int ResourceManager::Init() {
>                         (const hw_module_t **)&gralloc_);
>  }
>  
> +DrmConnector *ResourceManager::AvailableWritebackConnector(int display) {
> +  DrmResources *drm_resource = GetDrmResources(display);
> +  DrmConnector *writeback_conn = NULL;
> +  if (drm_resource) {
> +    writeback_conn = drm_resource->AvailableWritebackConnector(display);
> +    if (writeback_conn) {
> +      ALOGI("Use writeback connected to display %d\n",
> +            writeback_conn->display());

This seems a little chatty, it's written every flatten, yeah?

> +      return writeback_conn;
> +    }
> +  }
> +  for (auto &drm : drms_) {
> +    if (drm.get() == drm_resource)
> +      continue;
> +    writeback_conn = drm->AvailableWritebackConnector(display);
> +    if (writeback_conn) {
> +      ALOGI("Use writeback connected to display %d\n",
> +            writeback_conn->display());
> +      return writeback_conn;
> +    }
> +  }
> +  return writeback_conn;
> +}
> +
>  DrmResources *ResourceManager::GetDrmResources(int display) {
>    for (uint32_t i = 0; i < drms_.size(); i++) {
>      if (drms_[i]->HandlesDisplay(display))
> diff --git a/resourcemanager.h b/resourcemanager.h
> index b8caa9a..57f7a2a 100644
> --- a/resourcemanager.h
> +++ b/resourcemanager.h
> @@ -18,6 +18,7 @@ class ResourceManager {
>    DrmResources *GetDrmResources(int display);
>    std::shared_ptr<Importer> GetImporter(int display);
>    const gralloc_module_t *GetGralloc();
> +  DrmConnector *AvailableWritebackConnector(int display);
>  
>   private:
>    std::vector<std::unique_ptr<DrmResources>> drms_;
> -- 
> 2.7.4
>
diff mbox

Patch

diff --git a/drmresources.cpp b/drmresources.cpp
index fef6835..70126a4 100644
--- a/drmresources.cpp
+++ b/drmresources.cpp
@@ -269,6 +269,31 @@  DrmConnector *DrmResources::GetWritebackConnectorForDisplay(int display) const {
   return NULL;
 }
 
+// TODO what happens when hotplugging
+DrmConnector *DrmResources::AvailableWritebackConnector(int display) const {
+  DrmConnector *writeback_conn = GetWritebackConnectorForDisplay(display);
+  DrmConnector *display_conn = GetConnectorForDisplay(display);
+  // If we have a writeback already attached to the same CRTC, just use that, if
+  // possible
+  if (display_conn && writeback_conn &&
+      writeback_conn->encoder()->can_clone(display_conn->encoder()))
+    return writeback_conn;
+
+  // Use another CRTC if available and doesn't have any connector
+  for (auto &crtc : crtcs_) {
+    if (crtc->display() == display)
+      continue;
+    display_conn = GetConnectorForDisplay(crtc->display());
+    // If we have a display connected don't use it for writeback
+    if (display_conn && display_conn->state() == DRM_MODE_CONNECTED)
+      continue;
+    writeback_conn = GetWritebackConnectorForDisplay(crtc->display());
+    if (writeback_conn)
+      return writeback_conn;
+  }
+  return NULL;
+}
+
 DrmCrtc *DrmResources::GetCrtcForDisplay(int display) const {
   for (auto &crtc : crtcs_) {
     if (crtc->display() == display)
diff --git a/drmresources.h b/drmresources.h
index 4fb17fc..9176b8e 100644
--- a/drmresources.h
+++ b/drmresources.h
@@ -60,7 +60,7 @@  class DrmResources {
 
   DrmConnector *GetConnectorForDisplay(int display) const;
   DrmConnector *GetWritebackConnectorForDisplay(int display) const;
-  DrmConnector *FindWritebackConnector(int display) const;
+  DrmConnector *AvailableWritebackConnector(int display) const;
   DrmCrtc *GetCrtcForDisplay(int display) const;
   DrmPlane *GetPlane(uint32_t id) const;
   DrmEventListener *event_listener();
diff --git a/resourcemanager.cpp b/resourcemanager.cpp
index e7b654e..b2a4458 100644
--- a/resourcemanager.cpp
+++ b/resourcemanager.cpp
@@ -49,6 +49,30 @@  int ResourceManager::Init() {
                        (const hw_module_t **)&gralloc_);
 }
 
+DrmConnector *ResourceManager::AvailableWritebackConnector(int display) {
+  DrmResources *drm_resource = GetDrmResources(display);
+  DrmConnector *writeback_conn = NULL;
+  if (drm_resource) {
+    writeback_conn = drm_resource->AvailableWritebackConnector(display);
+    if (writeback_conn) {
+      ALOGI("Use writeback connected to display %d\n",
+            writeback_conn->display());
+      return writeback_conn;
+    }
+  }
+  for (auto &drm : drms_) {
+    if (drm.get() == drm_resource)
+      continue;
+    writeback_conn = drm->AvailableWritebackConnector(display);
+    if (writeback_conn) {
+      ALOGI("Use writeback connected to display %d\n",
+            writeback_conn->display());
+      return writeback_conn;
+    }
+  }
+  return writeback_conn;
+}
+
 DrmResources *ResourceManager::GetDrmResources(int display) {
   for (uint32_t i = 0; i < drms_.size(); i++) {
     if (drms_[i]->HandlesDisplay(display))
diff --git a/resourcemanager.h b/resourcemanager.h
index b8caa9a..57f7a2a 100644
--- a/resourcemanager.h
+++ b/resourcemanager.h
@@ -18,6 +18,7 @@  class ResourceManager {
   DrmResources *GetDrmResources(int display);
   std::shared_ptr<Importer> GetImporter(int display);
   const gralloc_module_t *GetGralloc();
+  DrmConnector *AvailableWritebackConnector(int display);
 
  private:
   std::vector<std::unique_ptr<DrmResources>> drms_;