1 /*
2  * Copyright (C) 2018 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 <cstdint>
18 
19 extern "C" {
20 #include "virgl_hw.h"
21 }
22 
23 #include "Resource.h"
24 
25 #include <android/sync.h>
26 #include <hardware/gralloc1.h>
27 
28 #include <cerrno>
29 
30 #define ALIGN(A, B) (((A) + (B)-1) / (B) * (B))
31 
32 static int gralloc1_device_open(const hw_module_t*, const char*, hw_device_t**);
33 
34 static hw_module_methods_t g_gralloc1_methods = {
35     .open = gralloc1_device_open,
36 };
37 
38 static hw_module_t g_gralloc1_module = {
39     .tag = HARDWARE_MODULE_TAG,
40     .module_api_version = GRALLOC_MODULE_API_VERSION_1_0,
41     .hal_api_version = HARDWARE_HAL_API_VERSION,
42     .id = GRALLOC_HARDWARE_MODULE_ID,
43     .name = "AVDVirglRenderer",
44     .author = "Google",
45     .methods = &g_gralloc1_methods,
46 };
47 
gralloc1_device_close(hw_device_t *)48 static int gralloc1_device_close(hw_device_t*) {
49     // No-op
50     return 0;
51 }
52 
gralloc1_getCapabilities(gralloc1_device_t *,uint32_t * outCount,int32_t *)53 static void gralloc1_getCapabilities(gralloc1_device_t*, uint32_t* outCount, int32_t*) {
54     *outCount = 0U;
55 }
56 
gralloc1_lock(gralloc1_device_t *,buffer_handle_t buffer,uint64_t producerUsage,uint64_t consumerUsage,const gralloc1_rect_t * rect,void ** outData,int32_t)57 static int32_t gralloc1_lock(gralloc1_device_t*, buffer_handle_t buffer, uint64_t producerUsage,
58                              uint64_t consumerUsage, const gralloc1_rect_t* rect, void** outData,
59                              int32_t) {
60     uint32_t resource_id = (uint32_t) reinterpret_cast<uintptr_t>(buffer);
61     std::map<uint32_t, Resource*>::iterator it;
62     it = Resource::map.find(resource_id);
63     if (it == Resource::map.end())
64         return GRALLOC1_ERROR_BAD_HANDLE;
65 
66     Resource* res = it->second;
67 
68     // validate the lock rectangle
69     if (rect->width < 0 || rect->height < 0 || rect->left < 0 || rect->top < 0 ||
70         (uint32_t)rect->width + (uint32_t)rect->left > res->args.width ||
71         (uint32_t)rect->height + (uint32_t)rect->top > res->args.height) {
72         return GRALLOC1_ERROR_BAD_VALUE;
73     }
74 
75     uint32_t bpp;
76     switch (res->args.format) {
77         case VIRGL_FORMAT_R8_UNORM:
78             bpp = 1U;
79             break;
80         case VIRGL_FORMAT_B5G6R5_UNORM:
81             bpp = 2U;
82             break;
83         default:
84             bpp = 4U;
85             break;
86     }
87     uint32_t stride = ALIGN(res->args.width * bpp, 16U);
88     *outData = (char*)res->linear + rect->top * stride + rect->left * bpp;
89     return GRALLOC1_ERROR_NONE;
90 }
91 
gralloc1_unlock(gralloc1_device_t *,buffer_handle_t buffer,int32_t * outReleaseFence)92 static int32_t gralloc1_unlock(gralloc1_device_t*, buffer_handle_t buffer,
93                                int32_t* outReleaseFence) {
94     uint32_t resource_id = (uint32_t) reinterpret_cast<uintptr_t>(buffer);
95     std::map<uint32_t, Resource*>::iterator it;
96     it = Resource::map.find(resource_id);
97     if (it == Resource::map.end())
98         return GRALLOC1_ERROR_BAD_HANDLE;
99     if (outReleaseFence)
100         *outReleaseFence = -1;
101 
102     return GRALLOC1_ERROR_NONE;
103 }
104 
gralloc1_getFunction(gralloc1_device_t *,int32_t descriptor)105 static gralloc1_function_pointer_t gralloc1_getFunction(gralloc1_device_t*, int32_t descriptor) {
106     switch (descriptor) {
107         case GRALLOC1_FUNCTION_LOCK:
108             return reinterpret_cast<gralloc1_function_pointer_t>(&gralloc1_lock);
109         case GRALLOC1_FUNCTION_UNLOCK:
110             return reinterpret_cast<gralloc1_function_pointer_t>(&gralloc1_unlock);
111         default:
112             return nullptr;
113     }
114 }
115 
116 static gralloc1_device_t g_gralloc1_device = {
117     .common =
118         {
119             .tag = HARDWARE_DEVICE_TAG,
120             .module = &g_gralloc1_module,
121             .close = gralloc1_device_close,
122         },
123     .getCapabilities = gralloc1_getCapabilities,
124     .getFunction = gralloc1_getFunction,
125 };
126 
gralloc1_device_open(const hw_module_t * module,const char * id,hw_device_t ** device)127 static int gralloc1_device_open(const hw_module_t* module, const char* id, hw_device_t** device) {
128     if (module != &g_gralloc1_module)
129         return -EINVAL;
130     if (strcmp(id, g_gralloc1_module.id))
131         return -EINVAL;
132     *device = &g_gralloc1_device.common;
133     return 0;
134 }
135 
hw_get_module(const char * id,const hw_module_t ** module)136 int hw_get_module(const char* id, const hw_module_t** module) {
137     if (strcmp(id, g_gralloc1_module.id))
138         return -EINVAL;
139     *module = const_cast<const hw_module_t*>(&g_gralloc1_module);
140     return 0;
141 }
142 
sync_wait(int,int)143 int sync_wait(int, int) {
144     return 0;
145 }
146