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