2 // Copyright (c) 2016 Intel Corporation
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "gbmbufferhandler.h"
22 #include <drm_fourcc.h>
26 #include <platformdefines.h>
28 #include "commondrmutils.h"
30 namespace hwcomposer {
33 NativeBufferHandler *NativeBufferHandler::CreateInstance(uint32_t fd) {
34 GbmBufferHandler *handler = new GbmBufferHandler(fd);
38 if (!handler->Init()) {
39 ETRACE("Failed to initialize GbmBufferHandler.");
46 GbmBufferHandler::GbmBufferHandler(uint32_t fd) : fd_(fd), device_(0) {
49 GbmBufferHandler::~GbmBufferHandler() {
51 gbm_device_destroy(device_);
54 bool GbmBufferHandler::Init() {
55 device_ = gbm_create_device(fd_);
57 ETRACE("failed to create gbm device \n");
61 uint64_t width = 0, height = 0;
63 if (drmGetCap(fd_, DRM_CAP_CURSOR_WIDTH, &width)) {
65 ETRACE("could not get cursor width.");
68 if (drmGetCap(fd_, DRM_CAP_CURSOR_HEIGHT, &height)) {
70 ETRACE("could not get cursor height.");
73 preferred_cursor_width_ = width;
74 preferred_cursor_height_ = height;
79 bool GbmBufferHandler::CreateBuffer(uint32_t w, uint32_t h, int format,
80 HWCNativeHandle *handle,
81 uint32_t layer_type) const {
82 uint32_t gbm_format = format;
84 gbm_format = GBM_FORMAT_XRGB8888;
88 if (layer_type == kLayerNormal) {
89 flags |= (GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
91 } else if (layer_type == kLayerVideo) {
92 flags |= (GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING |
93 GBM_BO_USE_CAMERA_WRITE | GBM_BO_USE_CAMERA_READ);
97 if (layer_type == kLayerCursor) {
98 if (w < preferred_cursor_width_)
99 w = preferred_cursor_width_;
101 if (h < preferred_cursor_height_)
102 h = preferred_cursor_height_;
105 struct gbm_bo *bo = gbm_bo_create(device_, w, h, gbm_format, flags);
108 flags &= ~GBM_BO_USE_SCANOUT;
109 bo = gbm_bo_create(device_, w, h, gbm_format, flags);
113 flags &= ~GBM_BO_USE_RENDERING;
114 bo = gbm_bo_create(device_, w, h, gbm_format, flags);
118 ETRACE("GbmBufferHandler: failed to create gbm_bo");
122 struct gbm_handle *temp = new struct gbm_handle();
123 temp->import_data.width = gbm_bo_get_width(bo);
124 temp->import_data.height = gbm_bo_get_height(bo);
125 temp->import_data.format = gbm_bo_get_format(bo);
127 size_t total_planes = gbm_bo_get_num_planes(bo);
128 for (size_t i = 0; i < total_planes; i++) {
129 temp->import_data.fds[i] = gbm_bo_get_plane_fd(bo, i);
130 temp->import_data.offsets[i] = gbm_bo_get_plane_offset(bo, i);
131 temp->import_data.strides[i] = gbm_bo_get_plane_stride(bo, i);
133 temp->total_planes = total_planes;
135 temp->import_data.fd = gbm_bo_get_fd(bo);
136 temp->import_data.stride = gbm_bo_get_stride(bo);
137 temp->total_planes = drm_bo_get_num_planes(temp->import_data.format);
141 temp->hwc_buffer_ = true;
142 temp->gbm_flags = flags;
148 bool GbmBufferHandler::ReleaseBuffer(HWCNativeHandle handle) const {
149 if (handle->bo || handle->imported_bo) {
150 if (handle->bo && handle->hwc_buffer_) {
151 gbm_bo_destroy(handle->bo);
154 if (handle->imported_bo) {
155 gbm_bo_destroy(handle->imported_bo);
158 for (size_t i = 0; i < handle->total_planes; i++)
159 close(handle->import_data.fds[i]);
161 close(handle->import_data.fd);
168 void GbmBufferHandler::DestroyHandle(HWCNativeHandle handle) const {
173 void GbmBufferHandler::CopyHandle(HWCNativeHandle source,
174 HWCNativeHandle *target) const {
175 struct gbm_handle *temp = new struct gbm_handle();
176 temp->import_data.width = source->import_data.width;
177 temp->import_data.height = source->import_data.height;
178 temp->import_data.format = source->import_data.format;
180 size_t total_planes = source->total_planes;
181 for (size_t i = 0; i < total_planes; i++) {
182 temp->import_data.fds[i] = dup(source->import_data.fds[i]);
183 temp->import_data.offsets[i] = source->import_data.offsets[i];
184 temp->import_data.strides[i] = source->import_data.strides[i];
187 temp->import_data.fd = dup(source->import_data.fd);
188 temp->import_data.stride = source->import_data.stride;
190 temp->bo = source->bo;
191 temp->total_planes = source->total_planes;
192 temp->gbm_flags = source->gbm_flags;
196 bool GbmBufferHandler::ImportBuffer(HWCNativeHandle handle) const {
197 memset(&(handle->meta_data_), 0, sizeof(struct HwcBuffer));
198 uint32_t gem_handle = 0;
199 handle->meta_data_.format_ = handle->import_data.format;
200 handle->meta_data_.native_format_ = handle->import_data.format;
201 if (!handle->imported_bo) {
203 handle->imported_bo =
204 gbm_bo_import(device_, GBM_BO_IMPORT_FD_PLANAR, &handle->import_data,
206 if (!handle->imported_bo) {
207 ETRACE("can't import bo");
210 handle->imported_bo = gbm_bo_import(
211 device_, GBM_BO_IMPORT_FD, &handle->import_data, handle->gbm_flags);
212 if (!handle->imported_bo) {
213 ETRACE("can't import bo");
218 gem_handle = gbm_bo_get_handle(handle->imported_bo).u32;
221 ETRACE("Invalid GEM handle. \n");
225 handle->meta_data_.width_ = handle->import_data.width;
226 handle->meta_data_.height_ = handle->import_data.height;
227 // FIXME: Set right flag here.
228 handle->meta_data_.usage_ = hwcomposer::kLayerNormal;
231 handle->meta_data_.prime_fd_ = handle->import_data.fds[0];
232 size_t total_planes = gbm_bo_get_num_planes(handle->bo);
233 for (size_t i = 0; i < total_planes; i++) {
234 handle->meta_data_.gem_handles_[i] = gem_handle;
235 handle->meta_data_.offsets_[i] = gbm_bo_get_plane_offset(handle->bo, i);
236 handle->meta_data_.pitches_[i] = gbm_bo_get_plane_stride(handle->bo, i);
239 handle->meta_data_.prime_fd_ = handle->import_data.fd;
240 handle->meta_data_.gem_handles_[0] = gem_handle;
241 handle->meta_data_.offsets_[0] = 0;
242 handle->meta_data_.pitches_[0] = gbm_bo_get_stride(handle->bo);
248 uint32_t GbmBufferHandler::GetTotalPlanes(HWCNativeHandle handle) const {
249 return handle->total_planes;
252 void *GbmBufferHandler::Map(HWCNativeHandle handle, uint32_t x, uint32_t y,
253 uint32_t width, uint32_t height, uint32_t *stride,
254 void **map_data, size_t plane) const {
259 return gbm_bo_map(handle->bo, x, y, width, height, GBM_BO_TRANSFER_WRITE,
260 stride, map_data, plane);
262 return gbm_bo_map(handle->bo, x, y, width, height, GBM_BO_TRANSFER_WRITE,
267 int32_t GbmBufferHandler::UnMap(HWCNativeHandle handle, void *map_data) const {
271 gbm_bo_unmap(handle->bo, map_data);
275 } // namespace hwcomposer