summaryrefslogtreecommitdiff
path: root/hwc2/hwc2_gralloc.cpp
blob: db6220f33ebdf0f07b1f9c358bbc7e5aad96648b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cutils/log.h>
#include <dlfcn.h>
#include <tegra_adf.h>

#include "hwc2.h"

#define NVGR_PIXEL_FORMAT_YUV420  0x100
#define NVGR_PIXEL_FORMAT_YUV422  0x101
#define NVGR_PIXEL_FORMAT_YUV422R 0x102
#define NVGR_PIXEL_FORMAT_UYVY    0x104
#define NVGR_PIXEL_FORMAT_NV12    0x106

#define NVGR_SURFACE_LAYOUT_PITCH        1
#define NVGR_SURFACE_LAYOUT_TILED        2
#define NVGR_SURFACE_LAYOUT_BLOCK_LINEAR 3

#define NVGR_SURFACE_SIZE 56

#define NVGR_GET_SURFACE(surfaces, idx) \
        ((void*)((char *) surfaces + (idx * NVGR_SURFACE_SIZE)))

/* The surface struct is defined in an NVIDIA binary. Accesses to the struct
 * will be done using member offsets */
#define NVGR_GET_STRUCT_MEMBER(ptr, member_type, member_offset) \
        (*((member_type *)((char *) ptr + member_offset)))

#define NVGR_SURFACE_OFFSET_LAYOUT            12
#define NVGR_SURFACE_OFFSET_PITCH             16
#define NVGR_SURFACE_OFFSET_HMEM              20
#define NVGR_SURFACE_OFFSET_OFFSET            24
#define NVGR_SURFACE_OFFSET_BLOCK_HEIGHT_LOG2 32

hwc2_gralloc::hwc2_gralloc()
{
    nvgr = dlopen("gralloc.tegra132.so", RTLD_LOCAL | RTLD_LAZY);
    LOG_ALWAYS_FATAL_IF(!nvgr, "failed to find module");

    *(void **)(&nvgr_is_valid) = dlsym(nvgr, "nvgr_is_valid");
    LOG_ALWAYS_FATAL_IF(!nvgr_is_valid, "failed to find nvgr_is_valid symbol");

    *(void **)(&nvgr_is_stereo) = dlsym(nvgr, "nvgr_is_stereo");
    LOG_ALWAYS_FATAL_IF(!nvgr_is_stereo, "failed to find nvgr_is_stereo"
            " symbol");

    *(void **)(&nvgr_is_yuv) = dlsym(nvgr, "nvgr_is_yuv");
    LOG_ALWAYS_FATAL_IF(!nvgr_is_stereo, "failed to find nvgr_is_yuv symbol");

    *(void **)(&nvgr_get_format) = dlsym(nvgr, "nvgr_get_format");
    LOG_ALWAYS_FATAL_IF(!nvgr_get_format, "failed to find nvgr_get_format"
            " symbol");

    *(void **)(&nvgr_get_surfaces) = dlsym(nvgr, "nvgr_get_surfaces");
    LOG_ALWAYS_FATAL_IF(!nvgr_get_surfaces, "failed to find nvgr_get_surfaces"
            " symbol");

    *(void **)(&NvRmMemDmaBufFdFromHandle) = dlsym(nvgr,
            "NvRmMemDmaBufFdFromHandle");
    LOG_ALWAYS_FATAL_IF(!NvRmMemDmaBufFdFromHandle, "failed to find"
            " NvRmMemDmaBufFdFromHandle symbol");

    *(void **)(&nvgr_decompress) = dlsym(nvgr, "nvgr_decompress");
    LOG_ALWAYS_FATAL_IF(!nvgr_decompress, "failed to find nvgr_decompress"
            " symbol");
}

hwc2_gralloc::~hwc2_gralloc()
{
    dlclose(nvgr);
}

const hwc2_gralloc &hwc2_gralloc::get_instance()
{
    static hwc2_gralloc instance;
    return instance;
}

bool hwc2_gralloc::is_valid(buffer_handle_t handle) const
{
    return nvgr_is_valid(handle);
}

bool hwc2_gralloc::is_stereo(buffer_handle_t handle) const
{
    return nvgr_is_stereo(handle);
}

bool hwc2_gralloc::is_yuv(buffer_handle_t handle) const
{
    return nvgr_is_yuv(handle);
}

int hwc2_gralloc::get_format(buffer_handle_t handle) const
{
    int format = nvgr_get_format(handle);

    switch (format) {
    case HAL_PIXEL_FORMAT_RGB_565:
        return DRM_FORMAT_BGR565;
    case NVGR_PIXEL_FORMAT_YUV420:
        return DRM_FORMAT_YUV420;
    case NVGR_PIXEL_FORMAT_YUV422:
        return DRM_FORMAT_YUV422;
    case NVGR_PIXEL_FORMAT_YUV422R:
        return TEGRA_ADF_FORMAT_YCbCr422R;
    case NVGR_PIXEL_FORMAT_UYVY:
        return DRM_FORMAT_UYVY;
    case NVGR_PIXEL_FORMAT_NV12:
        return DRM_FORMAT_NV12;
    default:
        return adf_fourcc_for_hal_pixel_format(format);
    }
}

void hwc2_gralloc::get_surfaces(buffer_handle_t handle,
        const void **surf, size_t *surf_cnt) const
{
    nvgr_get_surfaces(handle, surf, surf_cnt);
}

void hwc2_gralloc::get_dma_buf(const void *surf, uint32_t surf_idx,
        int *out_fd) const
{
    NvRmMemDmaBufFdFromHandle(get_hmem(surf, surf_idx), out_fd);
}

int32_t hwc2_gralloc::get_layout(const void *surf, uint32_t surf_idx) const
{
    uint32_t layout = NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_LAYOUT);

    switch (layout) {
    case NVGR_SURFACE_LAYOUT_PITCH:
        return HWC2_WINDOW_CAP_PITCH;
    case NVGR_SURFACE_LAYOUT_TILED:
        return HWC2_WINDOW_CAP_TILED;
    case NVGR_SURFACE_LAYOUT_BLOCK_LINEAR:
        return HWC2_WINDOW_CAP_BLOCK_LINEAR;
    default:
        ALOGE("Unrecognized layout");
        return -1;
    }
}

uint32_t hwc2_gralloc::get_pitch(const void *surf, uint32_t surf_idx) const
{
    return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_PITCH);
}

uint32_t hwc2_gralloc::get_hmem(const void *surf, uint32_t surf_idx) const
{
    return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_HMEM);
}

uint32_t hwc2_gralloc::get_offset(const void *surf, uint32_t surf_idx) const
{
    return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_OFFSET);
}

uint32_t hwc2_gralloc::get_block_height_log2(const void *surf, uint32_t surf_idx) const
{
    return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx),
            uint32_t, NVGR_SURFACE_OFFSET_BLOCK_HEIGHT_LOG2);
}

uint32_t hwc2_gralloc::decompress(buffer_handle_t handle, int in_fence,
        int *out_fence) const
{
    return nvgr_decompress(handle, in_fence, out_fence);
}