OSDN Git Service

Initial Commit
[android-x86/external-drmfb-composer.git] / DrmFramebuffer.cpp
1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright (C) 2019 Stephan Gerhold
3
4 #define LOG_TAG "drmfb-framebuffer"
5
6 #include <android-base/logging.h>
7 #include <drm/drm_fourcc.h>
8 #include <xf86drm.h>
9 #include <xf86drmMode.h>
10 #include <system/graphics.h>
11 #include <android/gralloc_handle.h>
12 #include "DrmFramebuffer.h"
13 #include "DrmDevice.h"
14
15 namespace android {
16 namespace hardware {
17 namespace graphics {
18 namespace composer {
19 namespace V2_1 {
20 namespace drmfb {
21
22 namespace {
23 static uint32_t convertAndroidToDrmFbFormat(uint32_t format) {
24     switch (format) {
25     case HAL_PIXEL_FORMAT_RGBA_8888:
26         /* Avoid using alpha bits for the framebuffer.
27          * They are not supported on older Intel GPUs for primary planes. */
28     case HAL_PIXEL_FORMAT_RGBX_8888:
29         return DRM_FORMAT_XBGR8888;
30     case HAL_PIXEL_FORMAT_RGB_888:
31         return DRM_FORMAT_BGR888;
32     case HAL_PIXEL_FORMAT_RGB_565:
33         return DRM_FORMAT_BGR565;
34     case HAL_PIXEL_FORMAT_BGRA_8888:
35         return DRM_FORMAT_ARGB8888;
36     default:
37         LOG(ERROR) << "Unsupported framebuffer format: " << format;
38         return 0;
39     }
40 }
41
42 uint32_t addFramebuffer(int fd, buffer_handle_t buffer) {
43     auto handle = gralloc_handle(buffer);
44     if (!handle) {
45         LOG(ERROR) << "Failed to add framebuffer for buffer " << buffer
46             << ": Not a libdrm gralloc handle";
47         return 0;
48     }
49
50     // Lookup the handle for the prime fd
51     uint32_t id;
52     if (drmPrimeFDToHandle(fd, handle->prime_fd, &id)) {
53         PLOG(ERROR) << "Failed to add framebuffer for buffer " << buffer
54             << ": Failed to get handle for prime fd " << handle->prime_fd;
55         return 0;
56     }
57
58     // Add a new framebuffer
59     uint32_t pitches[4] = { handle->stride, 0, 0, 0 };
60     uint32_t offsets[4] = { 0, 0, 0, 0 };
61     uint32_t handles[4] = { id, 0, 0, 0 };
62
63     if (drmModeAddFB2(fd, handle->width, handle->height,
64             convertAndroidToDrmFbFormat(handle->format),
65             handles, pitches, offsets, &id, 0)) {
66         PLOG(ERROR) << "drmModeAddFB2 failed for buffer " << buffer;
67         return 0;
68     }
69
70     return id;
71 }
72 }
73
74 DrmFramebuffer::DrmFramebuffer(const DrmDevice& device, buffer_handle_t buffer)
75     : mDevice(device), mId(addFramebuffer(device.fd(), buffer)) {}
76
77 DrmFramebuffer::~DrmFramebuffer() {
78     if (mId)
79         drmModeRmFB(mDevice.fd(), mId);
80 }
81
82 }  // namespace drmfb
83 }  // namespace V2_1
84 }  // namespace composer
85 }  // namespace graphics
86 }  // namespace hardware
87 }  // namespace android