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