1cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul/*
2cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul * Copyright (C) 2015 The Android Open Source Project
3cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul *
4cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul * Licensed under the Apache License, Version 2.0 (the "License");
5cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul * you may not use this file except in compliance with the License.
6cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul * You may obtain a copy of the License at
7cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul *
8cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul *      http://www.apache.org/licenses/LICENSE-2.0
9cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul *
10cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul * Unless required by applicable law or agreed to in writing, software
11cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul * distributed under the License is distributed on an "AS IS" BASIS,
12cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul * See the License for the specific language governing permissions and
14cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul * limitations under the License.
15cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul */
16cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
170f27fb9ece1707c76e70c35b5d757609801eef0eSean Paul#define LOG_TAG "hwc-platform-drm-generic"
18cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
19da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#include "drmresources.h"
2022fd62fbd30a8691555fd51090fa78542367971bSean Paul#include "platform.h"
21070a47e9ffa14edd1f6a8f9e9209840d421c7e33Sean Paul#include "platformdrmgeneric.h"
22cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
23cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul#include <drm/drm_fourcc.h>
24da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#include <xf86drm.h>
25da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#include <xf86drmMode.h>
26cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
27da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#include <cutils/log.h>
28cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul#include <gralloc_drm.h>
29cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul#include <gralloc_drm_priv.h>
30cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul#include <gralloc_drm_handle.h>
31da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#include <hardware/gralloc.h>
32cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
33da6270d4882eb0463717405bcadab3ac8fe902eaSean Paulnamespace android {
34cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
35da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#ifdef USE_DRM_GENERIC_IMPORTER
36da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul// static
37da6270d4882eb0463717405bcadab3ac8fe902eaSean PaulImporter *Importer::CreateInstance(DrmResources *drm) {
38da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  DrmGenericImporter *importer = new DrmGenericImporter(drm);
39da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  if (!importer)
40da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    return NULL;
41cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
42da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  int ret = importer->Init();
43da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  if (ret) {
44da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    ALOGE("Failed to initialize the nv importer %d", ret);
45da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    delete importer;
46da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    return NULL;
47ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  }
48da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  return importer;
49da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul}
50da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul#endif
51da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
52da6270d4882eb0463717405bcadab3ac8fe902eaSean PaulDrmGenericImporter::DrmGenericImporter(DrmResources *drm) : drm_(drm) {
53da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul}
54da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
55da6270d4882eb0463717405bcadab3ac8fe902eaSean PaulDrmGenericImporter::~DrmGenericImporter() {
56da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul}
57cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
58da6270d4882eb0463717405bcadab3ac8fe902eaSean Paulint DrmGenericImporter::Init() {
59ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
60da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul                          (const hw_module_t **)&gralloc_);
61ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  if (ret) {
62ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    ALOGE("Failed to open gralloc module");
63ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    return ret;
64ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  }
65ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  return 0;
66cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul}
67cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
68da6270d4882eb0463717405bcadab3ac8fe902eaSean Pauluint32_t DrmGenericImporter::ConvertHalFormatToDrm(uint32_t hal_format) {
69ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  switch (hal_format) {
70ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    case HAL_PIXEL_FORMAT_RGB_888:
71ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul      return DRM_FORMAT_BGR888;
72ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    case HAL_PIXEL_FORMAT_BGRA_8888:
73ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul      return DRM_FORMAT_ARGB8888;
74ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    case HAL_PIXEL_FORMAT_RGBX_8888:
75ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul      return DRM_FORMAT_XBGR8888;
76ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    case HAL_PIXEL_FORMAT_RGBA_8888:
77ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul      return DRM_FORMAT_ABGR8888;
78ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    case HAL_PIXEL_FORMAT_RGB_565:
79ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul      return DRM_FORMAT_BGR565;
80ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    case HAL_PIXEL_FORMAT_YV12:
81ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul      return DRM_FORMAT_YVU420;
82ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    default:
83ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul      ALOGE("Cannot convert hal format to drm format %u", hal_format);
84ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul      return -EINVAL;
85ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  }
86cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul}
87cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul
88da6270d4882eb0463717405bcadab3ac8fe902eaSean Paulint DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
89ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  gralloc_drm_handle_t *gr_handle = gralloc_drm_handle(handle);
90ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  if (!gr_handle)
91ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    return -EINVAL;
92ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul
93ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  struct gralloc_drm_bo_t *gralloc_bo = gr_handle->data;
94ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  if (!gralloc_bo) {
95ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    ALOGE("Could not get drm bo from handle");
96ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    return -EINVAL;
97ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  }
98ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul
99ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  uint32_t gem_handle;
100da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  int ret = drmPrimeFDToHandle(drm_->fd(), gr_handle->prime_fd, &gem_handle);
101ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  if (ret) {
102ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    ALOGE("failed to import prime fd %d ret=%d", gr_handle->prime_fd, ret);
103ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    return ret;
104ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  }
105ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul
106da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  memset(bo, 0, sizeof(hwc_drm_bo_t));
107ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  bo->width = gr_handle->width;
108ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  bo->height = gr_handle->height;
109da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  bo->format = ConvertHalFormatToDrm(gr_handle->format);
110ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  bo->pitches[0] = gr_handle->stride;
111ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  bo->gem_handles[0] = gem_handle;
112ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  bo->offsets[0] = 0;
113ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul
114da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
115da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul                      bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id, 0);
116ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  if (ret) {
117ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    ALOGE("could not create drm fb %d", ret);
118ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul    return ret;
119ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  }
120ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul
121ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  return ret;
12277d6d7a907dc23a1de7c5544fc0db79bf462ff6fLauri Peltonen}
12377d6d7a907dc23a1de7c5544fc0db79bf462ff6fLauri Peltonen
124da6270d4882eb0463717405bcadab3ac8fe902eaSean Paulint DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
125ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul  if (bo->fb_id)
126da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    if (drmModeRmFB(drm_->fd(), bo->fb_id))
127ef8f1f9905dbd1f49735f6df47f3128ecbc71c1eSean Paul      ALOGE("Failed to rm fb");
12877d6d7a907dc23a1de7c5544fc0db79bf462ff6fLauri Peltonen
129da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  struct drm_gem_close gem_close;
130da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  memset(&gem_close, 0, sizeof(gem_close));
131da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  int num_gem_handles = sizeof(bo->gem_handles) / sizeof(bo->gem_handles[0]);
132da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  for (int i = 0; i < num_gem_handles; i++) {
133da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    if (!bo->gem_handles[i])
134da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul      continue;
135da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul
136da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    gem_close.handle = bo->gem_handles[i];
137da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    int ret = drmIoctl(drm_->fd(), DRM_IOCTL_GEM_CLOSE, &gem_close);
138da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    if (ret)
139da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul      ALOGE("Failed to close gem handle %d %d", i, ret);
140da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul    else
141da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul      bo->gem_handles[i] = 0;
142da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  }
143da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul  return 0;
144da6270d4882eb0463717405bcadab3ac8fe902eaSean Paul}
145d9c3e2d9c8b15082b1ef2372406ba46e4bb7d199Sean Paul
146d9c3e2d9c8b15082b1ef2372406ba46e4bb7d199Sean Paul#ifdef USE_DRM_GENERIC_IMPORTER
147d9c3e2d9c8b15082b1ef2372406ba46e4bb7d199Sean Paulstd::unique_ptr<Planner> Planner::CreateInstance(DrmResources *) {
148d9c3e2d9c8b15082b1ef2372406ba46e4bb7d199Sean Paul  std::unique_ptr<Planner> planner(new Planner);
149d9c3e2d9c8b15082b1ef2372406ba46e4bb7d199Sean Paul  planner->AddStage<PlanStageGreedy>();
150d9c3e2d9c8b15082b1ef2372406ba46e4bb7d199Sean Paul  return planner;
151d9c3e2d9c8b15082b1ef2372406ba46e4bb7d199Sean Paul}
152d9c3e2d9c8b15082b1ef2372406ba46e4bb7d199Sean Paul#endif
153cd36a9e3864aaba47ba22af36fad97fe6c782637Sean Paul}
154