1 /*
2  * Copyright (C) 2016, 2018 ARM Limited. All rights reserved.
3  *
4  * Copyright (C) 2008 The Android Open Source Project
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * You may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #include <inttypes.h>
20 #include <stdlib.h>
21 #include <vector>
22 #include <algorithm>
23 
24 #include <hardware/hardware.h>
25 #if GRALLOC_VERSION_MAJOR == 1
26 #include <hardware/gralloc1.h>
27 #elif GRALLOC_VERSION_MAJOR == 0
28 #include <hardware/gralloc.h>
29 #endif
30 
31 #include "mali_gralloc_module.h"
32 #include "gralloc_priv.h"
33 #include "mali_gralloc_debug.h"
34 
35 static pthread_mutex_t dump_lock = PTHREAD_MUTEX_INITIALIZER;
36 static std::vector<private_handle_t *> dump_buffers;
37 static android::String8 dumpStrings;
38 
mali_gralloc_dump_buffer_add(private_handle_t * handle)39 void mali_gralloc_dump_buffer_add(private_handle_t *handle)
40 {
41 	if (NULL == handle)
42 	{
43 		ALOGE("Invalid handle %p and return", handle);
44 		return;
45 	}
46 
47 	pthread_mutex_lock(&dump_lock);
48 	dump_buffers.push_back(handle);
49 	pthread_mutex_unlock(&dump_lock);
50 }
51 
mali_gralloc_dump_buffer_erase(private_handle_t * handle)52 void mali_gralloc_dump_buffer_erase(private_handle_t *handle)
53 {
54 	if (NULL == handle)
55 	{
56 		ALOGE("Invalid handle %p and return", handle);
57 		return;
58 	}
59 
60 	pthread_mutex_lock(&dump_lock);
61 	dump_buffers.erase(std::remove(dump_buffers.begin(), dump_buffers.end(), handle), dump_buffers.end());
62 	pthread_mutex_unlock(&dump_lock);
63 }
64 
mali_gralloc_dump_string(android::String8 & buf,const char * fmt,...)65 void mali_gralloc_dump_string(android::String8 &buf, const char *fmt, ...)
66 {
67 	va_list args;
68 	va_start(args, fmt);
69 	buf.appendFormatV(fmt, args);
70 	va_end(args);
71 }
72 
mali_gralloc_dump_buffers(android::String8 & dumpStrings,uint32_t * outSize)73 void mali_gralloc_dump_buffers(android::String8 &dumpStrings, uint32_t *outSize)
74 {
75 	if (NULL == outSize)
76 	{
77 		ALOGE("Invalid pointer to dump buffer size and return");
78 		return;
79 	}
80 
81 	dumpStrings.clear();
82 	mali_gralloc_dump_string(dumpStrings,
83 	                         "-------------------------Start to dump Gralloc buffers info------------------------\n");
84 	private_handle_t *hnd;
85 	size_t num;
86 
87 	mali_gralloc_dump_string(dumpStrings, "    handle  | width | height | stride |   req format   |internal "
88 	                                      "format|consumer usage|producer usage|    fd    |    fd1   |    fd2   | AFBC "
89 	                                      "|\n");
90 	mali_gralloc_dump_string(dumpStrings, "------------+-------+--------+--------+----------------+---------------+----"
91 	                                      "----------+--------------+-----------+------+\n");
92 	pthread_mutex_lock(&dump_lock);
93 
94 	for (num = 0; num < dump_buffers.size(); num++)
95 	{
96 		hnd = dump_buffers[num];
97 		mali_gralloc_dump_string(dumpStrings, " %08" PRIxPTR " | %5d |  %5d |  %5d |    %08x    |    %09" PRIx64
98 		                                      "  |   %09" PRIx64 "  |   %09" PRIx64 "  | %08x | %08x | %08x | %4d |\n",
99 		                         hnd, hnd->width, hnd->height, hnd->stride, hnd->req_format, hnd->internal_format,
100 		                         hnd->consumer_usage, hnd->producer_usage, hnd->fds[0], hnd->fds[1], hnd->fds[2],
101 		                         (hnd->internal_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) ? true : false);
102 	}
103 
104 	pthread_mutex_unlock(&dump_lock);
105 	mali_gralloc_dump_string(
106 	    dumpStrings, "---------------------End dump Gralloc buffers info with num %zu----------------------\n", num);
107 
108 	*outSize = dumpStrings.size();
109 }
110 
mali_gralloc_dump_internal(uint32_t * outSize,char * outBuffer)111 void mali_gralloc_dump_internal(uint32_t *outSize, char *outBuffer)
112 {
113 	uint32_t dumpSize;
114 
115 	if (NULL == outSize)
116 	{
117 		ALOGE("Invalid pointer to dump buffer size and return");
118 		return;
119 	}
120 
121 	if (NULL == outBuffer)
122 	{
123 		if (!dumpStrings.isEmpty())
124 		{
125 			dumpStrings.clear();
126 		}
127 
128 		mali_gralloc_dump_buffers(dumpStrings, outSize);
129 	}
130 	else
131 	{
132 		if (dumpStrings.isEmpty())
133 		{
134 			*outSize = 0;
135 		}
136 		else
137 		{
138 			dumpSize = dumpStrings.size();
139 			*outSize = (dumpSize < *outSize) ? dumpSize : *outSize;
140 			memcpy(outBuffer, dumpStrings.string(), *outSize);
141 		}
142 	}
143 }
144