OSDN Git Service

drm_hwcomposer: fix new then free error for hwc_context_t
[android-x86/external-drm_hwcomposer.git] / hwcomposer_import_drm_gralloc.cpp
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 #include <stdlib.h>
18
19 #include <cutils/log.h>
20
21 #include <drm/drm_fourcc.h>
22
23 #include <gralloc_drm.h>
24 #include <gralloc_drm_priv.h>
25 #include <gralloc_drm_handle.h>
26
27 #include "drm_hwcomposer.h"
28
29 struct hwc_import_context {
30         struct drm_module_t *gralloc_module;
31 };
32
33 int hwc_import_init(struct hwc_import_context **ctx)
34 {
35         int ret;
36         struct hwc_import_context *import_ctx;
37
38         import_ctx = (struct hwc_import_context *)calloc(1,
39                                 sizeof(*import_ctx));
40         if (!ctx) {
41                 ALOGE("Failed to allocate gralloc import context");
42                 return -ENOMEM;
43         }
44
45         ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
46                         (const hw_module_t **)&import_ctx->gralloc_module);
47         if (ret) {
48                 ALOGE("Failed to open gralloc module");
49                 goto err;
50         }
51
52         *ctx = import_ctx;
53
54         return 0;
55
56 err:
57         free(import_ctx);
58         return ret;
59 }
60
61 int hwc_import_destroy(struct hwc_import_context *ctx)
62 {
63         free(ctx);
64         return 0;
65 }
66
67 static uint32_t hwc_convert_hal_format_to_drm_format(uint32_t hal_format)
68 {
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 hwc_import_bo_create(int fd, hwc_import_context *ctx,
89                         buffer_handle_t handle, struct hwc_drm_bo *bo)
90 {
91         gralloc_drm_handle_t *gr_handle = gralloc_drm_handle(handle);
92         struct gralloc_drm_bo_t *gralloc_bo;
93         uint32_t gem_handle;
94         int ret;
95
96         if (!gr_handle)
97                 return -EINVAL;
98
99         gralloc_bo = gr_handle->data;
100         if (!gralloc_bo) {
101                 ALOGE("Could not get drm bo from handle");
102                 return -EINVAL;
103         }
104
105         ret = drmPrimeFDToHandle(fd, gr_handle->prime_fd, &gem_handle);
106         if (ret) {
107                 ALOGE("failed to import prime fd %d ret=%d",
108                         gr_handle->prime_fd, ret);
109                 return ret;
110         }
111
112         bo->width = gr_handle->width;
113         bo->height = gr_handle->height;
114         bo->format = hwc_convert_hal_format_to_drm_format(gr_handle->format);
115         bo->pitches[0] = gr_handle->stride;
116         bo->gem_handles[0] = gem_handle;
117         bo->offsets[0] = 0;
118
119         ret = drmModeAddFB2(fd, bo->width, bo->height, bo->format,
120                         bo->gem_handles, bo->pitches, bo->offsets,
121                         &bo->fb_id, 0);
122         if (ret) {
123                 ALOGE("could not create drm fb %d", ret);
124                 return ret;
125         }
126
127         return ret;
128 }
129
130 bool hwc_import_bo_release(int fd, hwc_import_context *ctx,
131                         struct hwc_drm_bo *bo)
132 {
133         (void)ctx;
134
135         if (bo->fb_id)
136                 if (drmModeRmFB(fd, bo->fb_id))
137                         ALOGE("Failed to rm fb");
138
139         /* hwc may close the gem handles now. */
140         return true;
141 }