OSDN Git Service

Unify resource tracking for Media and 3D buffers.
authorKalyan Kondapally <kalyan.kondapally@intel.com>
Wed, 20 Dec 2017 00:39:51 +0000 (16:39 -0800)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Wed, 20 Dec 2017 23:19:47 +0000 (15:19 -0800)
We want to make sure we re-use caching, resource management
for all backends. We didn't take this into use for va backend.
This patchs adds the needed support for this.

Jira: None.
Test: Video continues to work as now.

Signed-off-by: Kalyan Kondapally <kalyan.kondapally@intel.com>
21 files changed:
common/compositor/compositordefs.h
common/compositor/compositorthread.cpp
common/compositor/gl/glsurface.cpp
common/compositor/nativesurface.h
common/compositor/renderer.h
common/compositor/va/varenderer.cpp
common/compositor/va/varenderer.h
common/compositor/va/vasurface.cpp
common/compositor/va/vasurface.h
common/compositor/va/vautils.cpp
common/core/overlaylayer.cpp
common/core/resourcemanager.cpp
common/core/resourcemanager.h
os/android/platformdefines.h
os/linux/platformdefines.h
os/platformcommondefines.h
wsi/Android.mk
wsi/Makefile.am
wsi/drm/drmbuffer.cpp
wsi/drm/drmbuffer.h
wsi/overlaybuffer.h

index 1b301df..b537efc 100644 (file)
@@ -70,5 +70,13 @@ typedef void* ResourceHandle;
 typedef void* GpuDisplay;
 #endif
 
+typedef struct media_import {
+  VASurfaceID surface_ = VA_INVALID_ID;
+  HWCNativeHandle handle_ = 0;
+  uint32_t drm_fd_ = 0;
+} MediaResourceHandle;
+
+typedef void* MediaDisplay;
+
 }  // namespace hwcomposer
 #endif  // COMMON_COMPOSITOR_COMPOSITORDEFS_H_
index 6a48b92..12610ed 100644 (file)
@@ -145,22 +145,48 @@ void CompositorThread::HandleReleaseRequest() {
   ScopedSpinLock lock(tasks_lock_);
   tasks_ &= ~kReleaseResources;
 
-  std::vector<ResourceHandle> purged_resources;
+  std::vector<ResourceHandle> purged_gl_resources;
+  std::vector<MediaResourceHandle> purged_media_resources;
   bool has_gpu_resource = false;
-  resource_manager_->GetPurgedResources(purged_resources, &has_gpu_resource);
-  size_t purged_size = purged_resources.size();
+  resource_manager_->GetPurgedResources(
+      purged_gl_resources, purged_media_resources, &has_gpu_resource);
+  size_t purged_size = purged_gl_resources.size();
 
   if (purged_size != 0) {
     if (has_gpu_resource) {
       Ensure3DRenderer();
-      gpu_resource_handler_->ReleaseGPUResources(purged_resources);
+      gpu_resource_handler_->ReleaseGPUResources(purged_gl_resources);
     }
 
     const NativeBufferHandler *handler =
         resource_manager_->GetNativeBufferHandler();
 
     for (size_t i = 0; i < purged_size; i++) {
-      const ResourceHandle &handle = purged_resources.at(i);
+      const ResourceHandle &handle = purged_gl_resources.at(i);
+      if (handle.drm_fd_ && ReleaseFrameBuffer(gpu_fd_, handle.drm_fd_)) {
+        ETRACE("Failed to remove fb %s", PRINTERROR());
+      }
+
+      if (!handle.handle_) {
+        continue;
+      }
+
+      handler->ReleaseBuffer(handle.handle_);
+      handler->DestroyHandle(handle.handle_);
+    }
+  }
+
+  purged_size = purged_media_resources.size();
+
+  if (purged_size != 0) {
+    EnsureMediaRenderer();
+    media_renderer_->DestroyMediaResources(purged_media_resources);
+
+    const NativeBufferHandler *handler =
+        resource_manager_->GetNativeBufferHandler();
+
+    for (size_t i = 0; i < purged_size; i++) {
+      const MediaResourceHandle &handle = purged_media_resources.at(i);
       if (handle.drm_fd_ && ReleaseFrameBuffer(gpu_fd_, handle.drm_fd_)) {
         ETRACE("Failed to remove fb %s", PRINTERROR());
       }
index e3da393..eb05fd2 100644 (file)
@@ -28,14 +28,6 @@ GLSurface::GLSurface(uint32_t width, uint32_t height)
 }
 
 GLSurface::~GLSurface() {
-  if (resource_manager_ && layer_.GetBuffer()) {
-    const ResourceHandle& current = layer_.GetBuffer()->GetGpuResource();
-    ResourceHandle temp;
-    std::memcpy(&temp, &current, sizeof temp);
-    temp.fb_ = fb_;
-    resource_manager_->MarkResourceForDeletion(temp,
-                                               fb_ > 0 || temp.texture_ > 0);
-  }
 }
 
 bool GLSurface::InitializeGPUResources() {
@@ -49,14 +41,13 @@ bool GLSurface::InitializeGPUResources() {
     return false;
   }
 
-  // Create Fb.
-  GLuint gl_fb;
-  glGenFramebuffers(1, &gl_fb);
-  glBindFramebuffer(GL_FRAMEBUFFER, gl_fb);
+  // Bind Fb.
+  fb_ = import.fb_;
+  glBindFramebuffer(GL_FRAMEBUFFER, fb_);
   glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                          import.texture_, 0);
 
-  fb_ = gl_fb;
+  fb_ = import.fb_;
   GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
   if (status != GL_FRAMEBUFFER_COMPLETE) {
     switch (status) {
index 2dd7c41..f8ef12e 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <memory>
 
-#include "overlaybuffer.h"
 #include "overlaylayer.h"
 #include "platformdefines.h"
 
index 16f343e..9921fd2 100644 (file)
@@ -27,6 +27,7 @@ namespace hwcomposer {
 class NativeSurface;
 struct RenderState;
 struct MediaState;
+struct media_import;
 
 class Renderer {
  public:
@@ -51,6 +52,11 @@ class Renderer {
     return false;
   }
 
+  virtual bool DestroyMediaResources(
+      std::vector<struct media_import>& /*resources*/) {
+    return true;
+  }
+
   virtual bool Draw(const MediaState& /*state*/, NativeSurface* /*surface*/) {
     return false;
   }
index f849193..7dda65f 100644 (file)
 
 #include <xf86drm.h>
 #include <drm_fourcc.h>
-#include <va/va_drmcommon.h>
-#ifdef ANDROID
-#include <va/va_android.h>
-#else
-#include <va/va_drm.h>
-#endif
 
 #include "hwctrace.h"
 #include "nativesurface.h"
 
 namespace hwcomposer {
 
-class ScopedVASurfaceID {
- public:
-  ScopedVASurfaceID(VADisplay display) : display_(display) {
-  }
-
-  ~ScopedVASurfaceID() {
-    if (surface_ != VA_INVALID_ID) {
-      vaDestroySurfaces(display_, &surface_, 1);
-    }
-  }
-
-  bool CreateSurface(int format, VASurfaceAttribExternalBuffers& external) {
-    CTRACE();
-    VASurfaceAttrib attribs[2];
-    attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
-    attribs[0].type = VASurfaceAttribMemoryType;
-    attribs[0].value.type = VAGenericValueTypeInteger;
-    attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
-
-    attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
-    attribs[1].type = VASurfaceAttribExternalBufferDescriptor;
-    attribs[1].value.type = VAGenericValueTypePointer;
-    attribs[1].value.value.p = &external;
-
-    VAStatus ret = vaCreateSurfaces(display_, format, external.width,
-                                    external.height, &surface_, 1, attribs, 2);
-    return ret == VA_STATUS_SUCCESS ? true : false;
-  }
-
-  operator VASurfaceID() const {
-    return surface_;
-  }
-
-  VASurfaceID surface() const {
-    return surface_;
-  }
-
- private:
-  VADisplay display_;
-  VASurfaceID surface_ = VA_INVALID_ID;
-};
-
 VARenderer::~VARenderer() {
   DestroyContext();
 
@@ -180,47 +132,47 @@ bool VARenderer::Draw(const MediaState& state, NativeSurface* surface) {
     return false;
   }
 
-  VASurfaceAttribExternalBuffers external_in;
-  memset(&external_in, 0, sizeof(external_in));
-  const OverlayBuffer* buffer_in = state.layer_->GetBuffer();
-  unsigned long prime_fd_in = buffer_in->GetPrimeFD();
-  rt_format = DrmFormatToRTFormat(buffer_in->GetFormat());
-  external_in.pixel_format = DrmFormatToVAFormat(buffer_in->GetFormat());
-  external_in.width = buffer_in->GetWidth();
-  external_in.height = buffer_in->GetHeight();
-  external_in.num_planes = buffer_in->GetTotalPlanes();
-  const uint32_t* pitches = buffer_in->GetPitches();
-  const uint32_t* offsets = buffer_in->GetOffsets();
-  for (unsigned int i = 0; i < external_in.num_planes; i++) {
-    external_in.pitches[i] = pitches[i];
-    external_in.offsets[i] = offsets[i];
-  }
-  external_in.num_buffers = 1;
-  external_in.buffers = &prime_fd_in;
-
-  ScopedVASurfaceID surface_in(va_display_);
-  if (!surface_in.CreateSurface(rt_format, external_in)) {
-    DTRACE("Create Input surface failed\n");
+  // Get Input Surface.
+  OverlayBuffer* buffer_in = state.layer_->GetBuffer();
+  const MediaResourceHandle& resource = buffer_in->GetMediaResource(
+      va_display_, state.layer_->GetSourceCropWidth(),
+      state.layer_->GetSourceCropHeight());
+  VASurfaceID surface_in = resource.surface_;
+  if (surface_in == VA_INVALID_ID) {
+    ETRACE("Failed to create Va Input Surface. \n");
     return false;
   }
 
-  VASurface* out_surface = static_cast<VASurface*>(surface);
-
-  out_surface->CreateVASurface(va_display_);
-  if (!out_surface) {
-    ETRACE("Failed to create Va Surface. \n");
+  // Get Output Surface.
+  OverlayLayer* layer_out = surface->GetLayer();
+  const MediaResourceHandle& out_resource =
+      layer_out->GetBuffer()->GetMediaResource(
+          va_display_, layer_out->GetSourceCropWidth(),
+          layer_out->GetSourceCropHeight());
+  VASurfaceID surface_out = out_resource.surface_;
+  if (surface_out == VA_INVALID_ID) {
+    ETRACE("Failed to create Va Output Surface. \n");
     return false;
   }
 
   VARectangle surface_region;
-  const HwcRect<float>& source_crop = state.layer_->GetSourceCrop();
+  OverlayLayer* layer_in = state.layer_;
+  const HwcRect<float>& source_crop = layer_in->GetSourceCrop();
   surface_region.x = static_cast<int>(source_crop.left);
   surface_region.y = static_cast<int>(source_crop.top);
-  surface_region.width = state.layer_->GetSourceCropWidth();
-  surface_region.height = state.layer_->GetSourceCropHeight();
+  surface_region.width = layer_in->GetSourceCropWidth();
+  surface_region.height = layer_in->GetSourceCropHeight();
+
+  VARectangle output_region;
+  const HwcRect<float>& source_crop_out = layer_out->GetSourceCrop();
+  output_region.x = static_cast<int>(source_crop_out.left);
+  output_region.y = static_cast<int>(source_crop_out.top);
+  output_region.width = layer_out->GetSourceCropWidth();
+  output_region.height = layer_out->GetSourceCropHeight();
+
   param_.surface = surface_in;
   param_.surface_region = &surface_region;
-  param_.output_region = out_surface->GetOutputRegion();
+  param_.output_region = &output_region;
 
   DUMPTRACE("surface_region: (%d, %d, %d, %d)\n", surface_region.x,
             surface_region.y, surface_region.width, surface_region.height);
@@ -240,7 +192,7 @@ bool VARenderer::Draw(const MediaState& state, NativeSurface* surface) {
   }
 
   VAStatus ret = VA_STATUS_SUCCESS;
-  ret = vaBeginPicture(va_display_, va_context_, out_surface->GetSurfaceID());
+  ret = vaBeginPicture(va_display_, va_context_, surface_out);
   ret |=
       vaRenderPicture(va_display_, va_context_, &pipeline_buffer.buffer(), 1);
   ret |= vaEndPicture(va_display_, va_context_);
@@ -248,6 +200,19 @@ bool VARenderer::Draw(const MediaState& state, NativeSurface* surface) {
   return ret == VA_STATUS_SUCCESS ? true : false;
 }
 
+bool VARenderer::DestroyMediaResources(
+    std::vector<struct media_import>& resources) {
+  size_t purged_size = resources.size();
+  for (size_t i = 0; i < purged_size; i++) {
+    MediaResourceHandle& handle = resources.at(i);
+    if (handle.surface_ != VA_INVALID_ID) {
+      vaDestroySurfaces(va_display_, &handle.surface_, 1);
+    }
+  }
+
+  return true;
+}
+
 bool VARenderer::CreateContext() {
   DestroyContext();
 
index 5a165bb..db6be85 100644 (file)
 #define COMMON_COMPOSITOR_VA_VARENDERER_H_
 
 #include <map>
-#include <va/va.h>
-#include <va/va_vpp.h>
 
 #include "renderer.h"
 #include "hwcdefs.h"
 
 #include "vautils.h"
 
+#include <platformdefines.h>
+
 namespace hwcomposer {
 
 struct OverlayLayer;
@@ -84,6 +84,8 @@ class VARenderer : public Renderer {
   void SetExplicitSyncSupport(bool /*disable_explicit_sync*/) override {
   }
 
+  bool DestroyMediaResources(std::vector<struct media_import>&) override;
+
  private:
   bool QueryVAProcFilterCaps(VAContextID context, VAProcFilterType type,
                              void* caps, uint32_t* num);
index 4cd9afa..0277f0b 100644 (file)
 
 #include "vasurface.h"
 
-#include "hwctrace.h"
 #include "overlaybuffer.h"
 
-#ifdef ANDROID
-#include <va/va_android.h>
-#else
-#include <va/va_drm.h>
-#endif
-
-#include <va/va_drmcommon.h>
-
-#include <drm_fourcc.h>
-
-#include "vautils.h"
-
 namespace hwcomposer {
 
 VASurface::VASurface(uint32_t width, uint32_t height)
     : NativeSurface(width, height) {
-  memset(&output_region_, 0, sizeof(output_region_));
 }
 
 VASurface::~VASurface() {
-  if (surface_ != VA_INVALID_ID) {
-    vaDestroySurfaces(display_, &surface_, 1);
-  }
 }
 
 bool VASurface::MakeCurrent() {
   return true;
 }
 
-bool VASurface::CreateVASurface(void* va_display) {
-  const OverlayLayer* layer = GetLayer();
-  uint32_t width = layer->GetSourceCropWidth();
-  uint32_t height = layer->GetSourceCropHeight();
-  if ((surface_ != VA_INVALID_ID) &&
-      ((previous_width_ != width) || (previous_height_ != height))) {
-    vaDestroySurfaces(display_, &surface_, 1);
-    surface_ = VA_INVALID_ID;
-  }
-
-  previous_width_ = width;
-  previous_height_ = height;
-
-  if (surface_ == VA_INVALID_ID) {
-    display_ = va_display;
-    VASurfaceAttribExternalBuffers external_out;
-    memset(&external_out, 0, sizeof(external_out));
-    OverlayBuffer* buffer_out = GetLayer()->GetBuffer();
-    unsigned long prime_fd_out = buffer_out->GetPrimeFD();
-    int rt_format = DrmFormatToRTFormat(buffer_out->GetFormat());
-    external_out.pixel_format = DrmFormatToVAFormat(buffer_out->GetFormat());
-    external_out.width = previous_width_;
-    external_out.height = previous_height_;
-    external_out.num_planes = buffer_out->GetTotalPlanes();
-    const uint32_t* pitches = buffer_out->GetPitches();
-    const uint32_t* offsets = buffer_out->GetOffsets();
-    for (unsigned int i = 0; i < external_out.num_planes; i++) {
-      external_out.pitches[i] = pitches[i];
-      external_out.offsets[i] = offsets[i];
-    }
-    external_out.num_buffers = 1;
-    external_out.buffers = &prime_fd_out;
-
-    VASurfaceAttrib attribs[2];
-    attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
-    attribs[0].type = VASurfaceAttribMemoryType;
-    attribs[0].value.type = VAGenericValueTypeInteger;
-    attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
-
-    attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
-    attribs[1].type = VASurfaceAttribExternalBufferDescriptor;
-    attribs[1].value.type = VAGenericValueTypePointer;
-    attribs[1].value.value.p = &external_out;
-
-    VAStatus ret =
-        vaCreateSurfaces(display_, rt_format, external_out.width,
-                         external_out.height, &surface_, 1, attribs, 2);
-
-    output_region_.x = 0;
-    output_region_.y = 0;
-    output_region_.width = previous_width_;
-    output_region_.height = previous_height_;
-
-    return ret == VA_STATUS_SUCCESS ? true : false;
-  }
-
-  return true;
-}
-
 }  // namespace hwcomposer
index 0c4fa20..2d9ca2f 100644 (file)
@@ -19,9 +19,6 @@
 
 #include "nativesurface.h"
 
-#include <va/va.h>
-#include <va/va_vpp.h>
-
 namespace hwcomposer {
 
 class VASurface : public NativeSurface {
@@ -31,22 +28,6 @@ class VASurface : public NativeSurface {
   VASurface(uint32_t width, uint32_t height);
 
   bool MakeCurrent() override;
-  const VASurfaceID& GetSurfaceID() const {
-    return surface_;
-  }
-
-  VARectangle* GetOutputRegion() {
-    return &output_region_;
-  }
-
-  bool CreateVASurface(void* va_display);
-
- private:
-  VADisplay display_;
-  VASurfaceID surface_ = VA_INVALID_ID;
-  VARectangle output_region_;
-  uint32_t previous_width_ = 0;
-  uint32_t previous_height_ = 0;
 };
 
 }  // namespace hwcomposer
index 3100d0b..edbac63 100644 (file)
 
 #include "vautils.h"
 
-#ifdef ANDROID
-#include <va/va_android.h>
-#else
-#include <va/va_drm.h>
-#endif
-
-#include <va/va_drmcommon.h>
+#include <platformdefines.h>
 
 #include <drm_fourcc.h>
 
index c985563..5b3d4a5 100644 (file)
@@ -75,8 +75,7 @@ void OverlayLayer::SetBuffer(HWCNativeHandle handle, int32_t acquire_fence,
 
   if (buffer == NULL) {
     buffer = OverlayBuffer::CreateOverlayBuffer();
-    buffer->InitializeFromNativeHandle(handle, resource_manager,
-                                       register_buffer);
+    buffer->InitializeFromNativeHandle(handle, resource_manager);
     if (register_buffer) {
       resource_manager->RegisterBuffer(GETNATIVEBUFFER(handle), buffer);
     }
index 1b34712..661f8c7 100644 (file)
@@ -30,7 +30,11 @@ ResourceManager::~ResourceManager() {
   }
 
   if (purged_resources_.size() > 0) {
-    ETRACE("ResourceManager destroyed with valid GPU resources \n");
+    ETRACE("ResourceManager destroyed with valid 3D resources \n");
+  }
+
+  if (purged_media_resources_.size() > 0) {
+    ETRACE("ResourceManager destroyed with valid Media resources \n");
   }
 }
 
@@ -88,8 +92,18 @@ void ResourceManager::MarkResourceForDeletion(const ResourceHandle& handle,
   lock_.unlock();
 }
 
-void ResourceManager::GetPurgedResources(std::vector<ResourceHandle>& resources,
-                                         bool* has_gpu_resource) {
+void ResourceManager::MarkMediaResourceForDeletion(
+    const MediaResourceHandle& handle) {
+  lock_.lock();
+  purged_media_resources_.emplace_back();
+  MediaResourceHandle& temp = purged_media_resources_.back();
+  std::memcpy(&temp, &handle, sizeof temp);
+  lock_.unlock();
+}
+
+void ResourceManager::GetPurgedResources(
+    std::vector<ResourceHandle>& gl_resources,
+    std::vector<MediaResourceHandle>& media_resources, bool* has_gpu_resource) {
   lock_.lock();
   size_t purged_size = purged_resources_.size();
   *has_gpu_resource = has_purged_gpu_resources_;
@@ -97,8 +111,8 @@ void ResourceManager::GetPurgedResources(std::vector<ResourceHandle>& resources,
   if (purged_size != 0) {
     for (size_t i = 0; i < purged_size; i++) {
       const ResourceHandle& handle = purged_resources_.at(i);
-      resources.emplace_back();
-      ResourceHandle& temp = resources.back();
+      gl_resources.emplace_back();
+      ResourceHandle& temp = gl_resources.back();
       std::memcpy(&temp, &handle, sizeof temp);
     }
 
@@ -106,15 +120,30 @@ void ResourceManager::GetPurgedResources(std::vector<ResourceHandle>& resources,
     has_purged_gpu_resources_ = false;
   }
 
+  purged_size = purged_media_resources_.size();
+  if (purged_size != 0) {
+    for (size_t i = 0; i < purged_size; i++) {
+      const MediaResourceHandle& handle = purged_media_resources_.at(i);
+      media_resources.emplace_back();
+      MediaResourceHandle& temp = media_resources.back();
+      std::memcpy(&temp, &handle, sizeof temp);
+    }
+
+    std::vector<MediaResourceHandle>().swap(purged_media_resources_);
+  }
+
   lock_.unlock();
 }
 
 bool ResourceManager::HasPurgedResources() {
   lock_.lock();
-  bool status = purged_resources_.empty();
+  bool status = false;
+  if (!purged_resources_.empty() || !purged_media_resources_.empty())
+    status = true;
+
   lock_.unlock();
 
-  return !status;
+  return status;
 }
 
 void ResourceManager::RefreshBufferCache() {
index 478161d..bd9bdd2 100644 (file)
@@ -66,8 +66,11 @@ class ResourceManager {
                       std::shared_ptr<OverlayBuffer>& pBuffer);
   void MarkResourceForDeletion(const ResourceHandle& handle,
                                bool has_valid_gpu_resources);
+
+  void MarkMediaResourceForDeletion(const MediaResourceHandle& handle);
   void RefreshBufferCache();
-  void GetPurgedResources(std::vector<ResourceHandle>& resources,
+  void GetPurgedResources(std::vector<ResourceHandle>& gl_resources,
+                          std::vector<MediaResourceHandle>& media_resources,
                           bool* has_gpu_resource);
   bool HasPurgedResources();
   void PurgeBuffer();
@@ -82,6 +85,7 @@ class ResourceManager {
                              BufferHash, BufferEqual> BUFFER_MAP;
   std::vector<BUFFER_MAP> cached_buffers_;
   std::vector<ResourceHandle> purged_resources_;
+  std::vector<MediaResourceHandle> purged_media_resources_;
   bool has_purged_gpu_resources_ = false;
   NativeBufferHandler* buffer_handler_;
   SpinLock lock_;
index fbe61ed..bd945ac 100644 (file)
@@ -32,6 +32,8 @@
 #include <ui/GraphicBuffer.h>
 #include "platformcommondefines.h"
 #include <cros_gralloc_handle.h>
+#include <va/va_android.h>
+
 #define DRV_I915 1
 #include <i915_private_android_types.h>
 
index 6e163ab..e17c009 100644 (file)
@@ -21,6 +21,8 @@
 #include <stddef.h>
 #include <gbm.h>
 
+#include <va/va_drm.h>
+
 #include <cstring>
 #include <algorithm>
 #include <cstddef>
index d9d63f7..2fc1569 100644 (file)
@@ -27,6 +27,9 @@ VkFormat NativeToVkFormat(int native_format);
 
 #include <xf86drm.h>
 #include <xf86drmMode.h>
+#include <va/va.h>
+#include <va/va_vpp.h>
+#include <va/va_drmcommon.h>
 
 #define DRM_FORMAT_NONE fourcc_code('0', '0', '0', '0')
 
index 5409b31..52f7cd2 100644 (file)
@@ -34,12 +34,16 @@ LOCAL_C_INCLUDES := \
         $(LOCAL_PATH)/../common/core \
         $(LOCAL_PATH)/../common/compositor \
         $(LOCAL_PATH)/../common/compositor/gl \
+       $(LOCAL_PATH)/../common/compositor/va \
         $(LOCAL_PATH)/../common/display \
         $(LOCAL_PATH)/../common/utils \
         $(LOCAL_PATH)/../os \
         $(LOCAL_PATH)/../os/android \
         $(LOCAL_PATH)/../wsi \
-        $(LOCAL_PATH)/../wsi/drm
+       $(LOCAL_PATH)/../wsi/drm
+
+LOCAL_SHARED_LIBRARIES += \
+       libva
 
 LOCAL_SRC_FILES := \
         physicaldisplay.cpp \
index 3eb1e0c..59b201b 100644 (file)
@@ -23,7 +23,7 @@ SUBDIRS = .
 
 MAINTAINERCLEANFILES = ChangeLog INSTALL
 
-AM_CPP_INCLUDES = -Idrm -I../os/ -I../os/linux/ -I../public/ -I../common/display/ -I../common/core/ -I../common/utils/ -I../common/compositor/
+AM_CPP_INCLUDES = -Idrm -I../os/ -I../os/linux/ -I../public/ -I../common/display/ -I../common/core/ -I../common/utils/ -I../common/compositor/ -I../common/compositor/va
 AM_CPPFLAGS = -std=c++11 -fPIC -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fPIE -DENABLE_DOUBLE_BUFFERING
 AM_CPPFLAGS += $(AM_CPP_INCLUDES) $(CWARNFLAGS) $(DRM_CFLAGS) $(DEBUG_CFLAGS) -Wformat -Wformat-security
 
index 25902d5..79a6020 100644 (file)
 
 #include "hwctrace.h"
 #include "resourcemanager.h"
+#include "vautils.h"
 
 namespace hwcomposer {
 
 DrmBuffer::~DrmBuffer() {
-  if (owns_gpu_resources_) {
+  if (media_image_.surface_ == VA_INVALID_ID) {
     resource_manager_->MarkResourceForDeletion(image_, image_.texture_ > 0);
+  } else {
+    if (image_.texture_ > 0) {
+      image_.handle_ = 0;
+      image_.drm_fd_ = 0;
+      resource_manager_->MarkResourceForDeletion(image_, true);
+    }
+
+    resource_manager_->MarkMediaResourceForDeletion(media_image_);
   }
 }
 
@@ -89,8 +98,7 @@ void DrmBuffer::Initialize(const HwcBuffer& bo) {
 }
 
 void DrmBuffer::InitializeFromNativeHandle(HWCNativeHandle handle,
-                                           ResourceManager* resource_manager,
-                                           bool owns_gpu_resources) {
+                                           ResourceManager* resource_manager) {
   const NativeBufferHandler* handler =
       resource_manager->GetNativeBufferHandler();
   handler->CopyHandle(handle, &image_.handle_);
@@ -100,7 +108,7 @@ void DrmBuffer::InitializeFromNativeHandle(HWCNativeHandle handle,
   }
 
   resource_manager_ = resource_manager;
-  owns_gpu_resources_ = owns_gpu_resources;
+  media_image_.handle_ = image_.handle_;
   Initialize(image_.handle_->meta_data_);
 }
 
@@ -223,13 +231,77 @@ const ResourceHandle& DrmBuffer::GetGpuResource(GpuDisplay egl_display,
     glBindTexture(target, 0);
     image_.texture_ = texture;
   }
+
+  if (!external_import && image_.fb_ == 0) {
+    glGenFramebuffers(1, &image_.fb_);
+  }
 #elif USE_VK
-  ETRACE("Missing implementation for Vulkan. \n");
+  ETRACE("Missing implementation for creating FB and Texture with Vulkan. \n");
 #endif
 
   return image_;
 }
 
+const MediaResourceHandle& DrmBuffer::GetMediaResource(MediaDisplay display,
+                                                       uint32_t width,
+                                                       uint32_t height) {
+  uint32_t temp_width = width;
+  uint32_t temp_height = height;
+  if ((temp_height == 0) || temp_height > height_) {
+    temp_height = height_;
+  }
+
+  if ((temp_width == 0) || temp_width > width_) {
+    temp_width = width_;
+  }
+
+  if (media_image_.surface_ != VA_INVALID_ID) {
+    if ((previous_width_ == temp_width) && (previous_height_ == temp_height)) {
+      return media_image_;
+    }
+
+    MediaResourceHandle media_resource;
+    media_resource.surface_ = media_image_.surface_;
+    media_image_.surface_ = VA_INVALID_ID;
+    resource_manager_->MarkMediaResourceForDeletion(media_resource);
+  }
+
+  previous_width_ = width;
+  previous_height_ = height;
+
+  VASurfaceAttribExternalBuffers external;
+  memset(&external, 0, sizeof(external));
+  uint32_t rt_format = DrmFormatToRTFormat(format_);
+  external.pixel_format = DrmFormatToVAFormat(format_);
+  external.width = temp_width;
+  external.height = temp_height;
+  external.num_planes = total_planes_;
+  unsigned long prime_fd = prime_fd_;
+  for (unsigned int i = 0; i < total_planes_; i++) {
+    external.pitches[i] = pitches_[i];
+    external.offsets[i] = offsets_[i];
+  }
+
+  external.num_buffers = 1;
+  external.buffers = &prime_fd;
+
+  VASurfaceAttrib attribs[2];
+  attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
+  attribs[0].type = VASurfaceAttribMemoryType;
+  attribs[0].value.type = VAGenericValueTypeInteger;
+  attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME;
+
+  attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
+  attribs[1].type = VASurfaceAttribExternalBufferDescriptor;
+  attribs[1].value.type = VAGenericValueTypePointer;
+  attribs[1].value.value.p = &external;
+
+  vaCreateSurfaces(display, rt_format, external.width, external.height,
+                   &media_image_.surface_, 1, attribs, 2);
+
+  return media_image_;
+}
+
 const ResourceHandle& DrmBuffer::GetGpuResource() {
   return image_;
 }
@@ -246,6 +318,7 @@ bool DrmBuffer::CreateFrameBuffer(uint32_t gpu_fd) {
   }
 
   image_.drm_fd_ = 0;
+  media_image_.drm_fd_ = 0;
 
   int ret = drmModeAddFB2(gpu_fd, width_, height_, frame_buffer_format_,
                           gem_handles_, pitches_, offsets_, &image_.drm_fd_, 0);
@@ -260,6 +333,7 @@ bool DrmBuffer::CreateFrameBuffer(uint32_t gpu_fd) {
     return false;
   }
 
+  media_image_.drm_fd_ = image_.drm_fd_;
   return true;
 }
 
index ec4101b..d84d56e 100644 (file)
@@ -36,8 +36,7 @@ class DrmBuffer : public OverlayBuffer {
   void Initialize(const HwcBuffer& bo);
 
   void InitializeFromNativeHandle(HWCNativeHandle handle,
-                                  ResourceManager* buffer_manager,
-                                  bool owns_gpu_resources) override;
+                                  ResourceManager* buffer_manager) override;
 
   uint32_t GetWidth() const override {
     return width_;
@@ -80,6 +79,10 @@ class DrmBuffer : public OverlayBuffer {
 
   const ResourceHandle& GetGpuResource() override;
 
+  const MediaResourceHandle& GetMediaResource(MediaDisplay display,
+                                              uint32_t width,
+                                              uint32_t height) override;
+
   bool CreateFrameBuffer(uint32_t gpu_fd) override;
 
   void SetRecommendedFormat(uint32_t format) override;
@@ -101,10 +104,12 @@ class DrmBuffer : public OverlayBuffer {
   uint32_t prime_fd_ = 0;
   uint32_t usage_ = 0;
   uint32_t total_planes_ = 0;
+  uint32_t previous_width_ = 0;   // For Media usage.
+  uint32_t previous_height_ = 0;  // For Media usage.
   bool is_yuv_ = false;
-  bool owns_gpu_resources_ = false;
   ResourceManager* resource_manager_ = 0;
   ResourceHandle image_;
+  MediaResourceHandle media_image_;
 };
 
 }  // namespace hwcomposer
index fd660ae..0c9cda4 100644 (file)
@@ -38,13 +38,8 @@ class OverlayBuffer {
   virtual ~OverlayBuffer() {
   }
 
-  // If owns_gpu_resources is true, than OverlayBuffer implementation
-  // is expected to mark these resources for deletion by calling
-  // MarkResourceForDeletion API of ResourceManager. If owns_gpu_resources
-  // is false than NativeSurface will handle this.
   virtual void InitializeFromNativeHandle(HWCNativeHandle handle,
-                                          ResourceManager* buffer_manager,
-                                          bool owns_gpu_resources) = 0;
+                                          ResourceManager* buffer_manager) = 0;
 
   virtual uint32_t GetWidth() const = 0;
 
@@ -65,11 +60,20 @@ class OverlayBuffer {
   virtual const uint32_t* GetOffsets() const = 0;
 
   // external_import should be true if this resource is not owned by HWC.
+  // If resource is owned by HWC, than the implementation needs to create
+  // frame buffer for this buffer.
   virtual const ResourceHandle& GetGpuResource(GpuDisplay egl_display,
                                                bool external_import) = 0;
 
   virtual const ResourceHandle& GetGpuResource() = 0;
 
+  // Returns Media resource for this buffer which can be used by compositor.
+  // Surface will be clipped to width, height even if buffer size is
+  // greater than these values.
+  virtual const MediaResourceHandle& GetMediaResource(MediaDisplay display,
+                                                      uint32_t width,
+                                                      uint32_t height) = 0;
+
   virtual bool CreateFrameBuffer(uint32_t gpu_fd) = 0;
 
   virtual void SetRecommendedFormat(uint32_t format) = 0;