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