blob: 3ff355f6d2f890245fda7126dfbc8b0d59e110ac [file] [log] [blame]
John Stultz499db602018-03-13 16:51:12 -07001/*
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-hisi"
18
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +010019#include "drmdevice.h"
John Stultz499db602018-03-13 16:51:12 -070020#include "platform.h"
21#include "platformhisi.h"
22
23
24#include <drm/drm_fourcc.h>
25#include <cinttypes>
26#include <stdatomic.h>
27#include <xf86drm.h>
28#include <xf86drmMode.h>
29
John Stultz9057a6f2018-04-26 12:05:55 -070030#include <log/log.h>
John Stultz499db602018-03-13 16:51:12 -070031#include <hardware/gralloc.h>
32#include "gralloc_priv.h"
33
John Stultzdf35a812018-05-31 17:37:21 -070034#define MALI_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1))
John Stultz499db602018-03-13 16:51:12 -070035
36namespace android {
37
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +010038Importer *Importer::CreateInstance(DrmDevice *drm) {
John Stultz499db602018-03-13 16:51:12 -070039 HisiImporter *importer = new HisiImporter(drm);
40 if (!importer)
41 return NULL;
42
43 int ret = importer->Init();
44 if (ret) {
45 ALOGE("Failed to initialize the hisi importer %d", ret);
46 delete importer;
47 return NULL;
48 }
49 return importer;
50}
51
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +010052HisiImporter::HisiImporter(DrmDevice *drm)
53 : DrmGenericImporter(drm), drm_(drm) {
John Stultz499db602018-03-13 16:51:12 -070054}
55
56HisiImporter::~HisiImporter() {
57}
58
59int HisiImporter::Init() {
60 int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
61 (const hw_module_t **)&gralloc_);
62 if (ret) {
63 ALOGE("Failed to open gralloc module %d", ret);
64 return ret;
65 }
66
67 if (strcasecmp(gralloc_->common.author, "ARM Ltd."))
68 ALOGW("Using non-ARM gralloc module: %s/%s\n", gralloc_->common.name,
69 gralloc_->common.author);
70
71 return 0;
72}
73
John Stultz499db602018-03-13 16:51:12 -070074int HisiImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
Rob Herringaf0d9752018-05-04 16:34:19 -050075 private_handle_t const *hnd =
76 reinterpret_cast<private_handle_t const *>(handle);
John Stultz499db602018-03-13 16:51:12 -070077 if (!hnd)
78 return -EINVAL;
79
80 uint32_t gem_handle;
81 int ret = drmPrimeFDToHandle(drm_->fd(), hnd->share_fd, &gem_handle);
82 if (ret) {
83 ALOGE("failed to import prime fd %d ret=%d", hnd->share_fd, ret);
84 return ret;
85 }
86
Rob Herringaf0d9752018-05-04 16:34:19 -050087 int32_t fmt = ConvertHalFormatToDrm(hnd->req_format);
John Stultz499db602018-03-13 16:51:12 -070088 if (fmt < 0)
John Stultzdf35a812018-05-31 17:37:21 -070089 return fmt;
John Stultz499db602018-03-13 16:51:12 -070090
91 memset(bo, 0, sizeof(hwc_drm_bo_t));
92 bo->width = hnd->width;
93 bo->height = hnd->height;
94 bo->format = fmt;
95 bo->usage = hnd->usage;
John Stultzdf35a812018-05-31 17:37:21 -070096
John Stultz499db602018-03-13 16:51:12 -070097 bo->pitches[0] = hnd->byte_stride;
98 bo->gem_handles[0] = gem_handle;
99 bo->offsets[0] = 0;
100
John Stultzdf35a812018-05-31 17:37:21 -0700101 switch (fmt) {
102 case DRM_FORMAT_YVU420: {
103 int align = 128;
104 if (hnd->usage &
105 (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
106 align = 16;
107 int adjusted_height = MALI_ALIGN(hnd->height, 2);
108 int y_size = adjusted_height * hnd->byte_stride;
109 int vu_stride = MALI_ALIGN(hnd->byte_stride / 2, align);
110 int v_size = vu_stride * (adjusted_height / 2);
111
112 /* V plane*/
113 bo->gem_handles[1] = gem_handle;
114 bo->pitches[1] = vu_stride;
115 bo->offsets[1] = y_size;
116 /* U plane */
117 bo->gem_handles[2] = gem_handle;
118 bo->pitches[2] = vu_stride;
119 bo->offsets[2] = y_size + v_size;
120 break;
121 }
122 default:
123 break;
124 }
125
John Stultz499db602018-03-13 16:51:12 -0700126 ret = drmModeAddFB2(drm_->fd(), bo->width, bo->height, bo->format,
127 bo->gem_handles, bo->pitches, bo->offsets, &bo->fb_id, 0);
128 if (ret) {
129 ALOGE("could not create drm fb %d", ret);
130 return ret;
131 }
132
133 return ret;
134}
135
Alexandru Gheorghe0f5abd72018-05-01 14:37:10 +0100136std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
John Stultz499db602018-03-13 16:51:12 -0700137 std::unique_ptr<Planner> planner(new Planner);
138 planner->AddStage<PlanStageGreedy>();
139 return planner;
140}
141}