1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "display_layer.h" 17#include <errno.h> 18#include <stdio.h> 19#include <unistd.h> 20#include <sys/mman.h> 21#include <securec.h> 22#include "hdf_log.h" 23#include "display_type.h" 24 25#define DEV_ID 0 26#define LAYER_ID 0 27#define FB_PATH "/dev/fb0" 28#define DISP_WIDTH 960 29#define DISP_HEIGHT 480 30#define BITS_PER_PIXEL 32 31#define BITS_TO_BYTE 8 32 33struct LayerPrivate { 34 int32_t fd; 35 uint32_t width; 36 uint32_t height; 37 int32_t pitch; 38 void *fbAddr; 39 uint32_t fbSize; 40 void *layerAddr; 41 PixelFormat pixFmt; 42}; 43 44static struct LayerPrivate *GetLayerInstance(void) 45{ 46 static struct LayerPrivate layerPriv = { 47 .fd = -1, 48 .width = DISP_WIDTH, 49 .height = DISP_HEIGHT, 50 .pixFmt = PIXEL_FMT_RGBA_8888, 51 }; 52 return &layerPriv; 53} 54 55static int32_t InitDisplay(uint32_t devId) 56{ 57 if (devId != DEV_ID) { 58 HDF_LOGE("%s: devId invalid", __func__); 59 return DISPLAY_FAILURE; 60 } 61 return DISPLAY_SUCCESS; 62} 63 64static int32_t DeinitDisplay(uint32_t devId) 65{ 66 if (devId != DEV_ID) { 67 HDF_LOGE("%s: devId invalid", __func__); 68 return DISPLAY_FAILURE; 69 } 70 return DISPLAY_SUCCESS; 71} 72 73static void SetBackground(void) 74{ 75 struct LayerPrivate *priv = GetLayerInstance(); 76 uint32_t i; 77 uint32_t j; 78 uint32_t *framebuffer = (uint32_t *)priv->fbAddr; 79 for (j = 0; j < priv->height; j++) { 80 for (i = 0; i < priv->width; i++) { 81 framebuffer[i + j * priv->width] = 0xFF; // Blue background 82 } 83 } 84} 85 86static int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId) 87{ 88 if (layerInfo == NULL || layerId == NULL) { 89 HDF_LOGE("%s: pointer is null", __func__); 90 return DISPLAY_NULL_PTR; 91 } 92 if (devId != DEV_ID) { 93 HDF_LOGE("%s: devId invalid", __func__); 94 return DISPLAY_FAILURE; 95 } 96 struct LayerPrivate *priv = GetLayerInstance(); 97 priv->fd = open(FB_PATH, O_RDWR, 0); 98 if (priv->fd < 0) { 99 HDF_LOGE("%s: open fb dev failed", __func__); 100 return DISPLAY_FD_ERR; 101 } 102 priv->pitch = layerInfo->width * BITS_PER_PIXEL / BITS_TO_BYTE; 103 priv->fbSize = ((priv->pitch * priv->height) + 0xfff) & (~0xfff); 104 priv->fbAddr = (void *)mmap(NULL, priv->fbSize, PROT_READ | PROT_WRITE, MAP_SHARED, priv->fd, 0); 105 if (priv->fbAddr == NULL) { 106 HDF_LOGE("%s: mmap fb address failure, errno: %d", __func__, errno); 107 close(priv->fd); 108 priv->fd = -1; 109 priv->pitch = 0; 110 priv->fbSize = 0; 111 return DISPLAY_FAILURE; 112 } 113 SetBackground(); 114 *layerId = LAYER_ID; 115 HDF_LOGI("%s: open layer success", __func__); 116 return DISPLAY_SUCCESS; 117} 118 119static int32_t CloseLayer(uint32_t devId, uint32_t layerId) 120{ 121 if (devId != DEV_ID) { 122 HDF_LOGE("%s: devId invalid", __func__); 123 return DISPLAY_FAILURE; 124 } 125 if (layerId != LAYER_ID) { 126 HDF_LOGE("%s: layerId invalid", __func__); 127 return DISPLAY_FAILURE; 128 } 129 struct LayerPrivate *priv = GetLayerInstance(); 130 if (priv->fd >= 0) { 131 close(priv->fd); 132 } 133 if (priv->layerAddr != NULL) { 134 free(priv->layerAddr); 135 priv->layerAddr = NULL; 136 } 137 if (priv->fbAddr != NULL) { 138 munmap(priv->fbAddr, priv->fbSize); 139 } 140 priv->fd = -1; 141 return DISPLAY_SUCCESS; 142} 143 144static int32_t GetDisplayInfo(uint32_t devId, DisplayInfo *dispInfo) 145{ 146 if (dispInfo == NULL) { 147 HDF_LOGE("%s: dispInfo is null", __func__); 148 return DISPLAY_NULL_PTR; 149 } 150 if (devId != DEV_ID) { 151 HDF_LOGE("%s: devId invalid", __func__); 152 return DISPLAY_FAILURE; 153 } 154 struct LayerPrivate *priv = GetLayerInstance(); 155 dispInfo->width = priv->width; 156 dispInfo->height = priv->height; 157 dispInfo->rotAngle = ROTATE_NONE; 158 HDF_LOGD("%s: width = %u, height = %u, rotAngle = %u", __func__, dispInfo->width, 159 dispInfo->height, dispInfo->rotAngle); 160 return DISPLAY_SUCCESS; 161} 162 163static int32_t Flush(uint32_t devId, uint32_t layerId, LayerBuffer *buffer) 164{ 165 int32_t ret; 166 if (devId != DEV_ID) { 167 HDF_LOGE("%s: devId invalid", __func__); 168 return DISPLAY_FAILURE; 169 } 170 if (layerId != LAYER_ID) { 171 HDF_LOGE("%s: layerId invalid", __func__); 172 return DISPLAY_FAILURE; 173 } 174 if (buffer == NULL) { 175 HDF_LOGE("%s: buffer is null", __func__); 176 return DISPLAY_FAILURE; 177 } 178 179 struct LayerPrivate *priv = GetLayerInstance(); 180 ret = memcpy_s(priv->fbAddr, priv->fbSize, buffer->data.virAddr, priv->fbSize); 181 if (ret != EOK) { 182 HDF_LOGE("%s: memcpy_s fail, ret %d", __func__, ret); 183 return ret; 184 } 185 return DISPLAY_SUCCESS; 186} 187 188static int32_t GetLayerBuffer(uint32_t devId, uint32_t layerId, LayerBuffer *buffer) 189{ 190 if (buffer == NULL) { 191 HDF_LOGE("%s: buffer is null", __func__); 192 return DISPLAY_NULL_PTR; 193 } 194 if (devId != DEV_ID) { 195 HDF_LOGE("%s: devId invalid", __func__); 196 return DISPLAY_FAILURE; 197 } 198 if (layerId != LAYER_ID) { 199 HDF_LOGE("%s: layerId invalid", __func__); 200 return DISPLAY_FAILURE; 201 } 202 struct LayerPrivate *priv = GetLayerInstance(); 203 if (priv->fd < 0) { 204 HDF_LOGE("%s: fd invalid", __func__); 205 return DISPLAY_FAILURE; 206 } 207 buffer->fenceId = 0; 208 buffer->width = priv->width; 209 buffer->height = priv->height; 210 buffer->pixFormat = priv->pixFmt; 211 buffer->pitch = priv->pitch; 212 buffer->data.virAddr = malloc(priv->fbSize); 213 if (buffer->data.virAddr == NULL) { 214 HDF_LOGE("%s: malloc failure", __func__); 215 return DISPLAY_FAILURE; 216 } 217 priv->layerAddr = buffer->data.virAddr; 218 (void)memset_s(buffer->data.virAddr, priv->fbSize, 0x00, priv->fbSize); 219 HDF_LOGD("%s: fenceId = %d, width = %d, height = %d, pixFormat = %d, pitch = %d", __func__, buffer->fenceId, 220 buffer->width, buffer->height, buffer->pixFormat, buffer->pitch); 221 return DISPLAY_SUCCESS; 222} 223 224int32_t LayerInitialize(LayerFuncs **funcs) 225{ 226 if (funcs == NULL) { 227 HDF_LOGE("%s: funcs is null", __func__); 228 return DISPLAY_NULL_PTR; 229 } 230 LayerFuncs *lFuncs = (LayerFuncs *)malloc(sizeof(LayerFuncs)); 231 if (lFuncs == NULL) { 232 HDF_LOGE("%s: lFuncs is null", __func__); 233 return DISPLAY_NULL_PTR; 234 } 235 (void)memset_s(lFuncs, sizeof(LayerFuncs), 0, sizeof(LayerFuncs)); 236 lFuncs->InitDisplay = InitDisplay; 237 lFuncs->DeinitDisplay = DeinitDisplay; 238 lFuncs->GetDisplayInfo = GetDisplayInfo; 239 lFuncs->CreateLayer = CreateLayer; 240 lFuncs->CloseLayer = CloseLayer; 241 lFuncs->Flush = Flush; 242 lFuncs->GetLayerBuffer = GetLayerBuffer; 243 *funcs = lFuncs; 244 HDF_LOGI("%s: success", __func__); 245 return DISPLAY_SUCCESS; 246} 247 248int32_t LayerUninitialize(LayerFuncs *funcs) 249{ 250 if (funcs == NULL) { 251 HDF_LOGE("%s: funcs is null", __func__); 252 return DISPLAY_NULL_PTR; 253 } 254 free(funcs); 255 HDF_LOGI("%s: layer uninitialize success", __func__); 256 return DISPLAY_SUCCESS; 257} 258