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 
26 #include "mali_gralloc_debug.h"
27 
28 static pthread_mutex_t dump_lock = PTHREAD_MUTEX_INITIALIZER;
29 static std::vector<private_handle_t *> dump_buffers;
30 static android::String8 dumpStrings;
31 
mali_gralloc_dump_buffer_add(private_handle_t * handle)32 void mali_gralloc_dump_buffer_add(private_handle_t *handle)
33 {
34 	if (NULL == handle)
35 	{
36 		MALI_GRALLOC_LOGE("Invalid handle %p and return", handle);
37 		return;
38 	}
39 
40 	pthread_mutex_lock(&dump_lock);
41 	dump_buffers.push_back(handle);
42 	pthread_mutex_unlock(&dump_lock);
43 }
44 
mali_gralloc_dump_buffer_erase(private_handle_t * handle)45 void mali_gralloc_dump_buffer_erase(private_handle_t *handle)
46 {
47 	if (NULL == handle)
48 	{
49 		MALI_GRALLOC_LOGE("Invalid handle %p and return", handle);
50 		return;
51 	}
52 
53 	pthread_mutex_lock(&dump_lock);
54 	dump_buffers.erase(std::remove(dump_buffers.begin(), dump_buffers.end(), handle), dump_buffers.end());
55 	pthread_mutex_unlock(&dump_lock);
56 }
57 
mali_gralloc_dump_string(android::String8 & buf,const char * fmt,...)58 void mali_gralloc_dump_string(android::String8 &buf, const char *fmt, ...)
59 {
60 	va_list args;
61 	va_start(args, fmt);
62 	buf.appendFormatV(fmt, args);
63 	va_end(args);
64 }
65 
mali_gralloc_dump_buffers(android::String8 & dumpStrings,uint32_t * outSize)66 void mali_gralloc_dump_buffers(android::String8 &dumpStrings, uint32_t *outSize)
67 {
68 	if (NULL == outSize)
69 	{
70 		MALI_GRALLOC_LOGE("Invalid pointer to dump buffer size and return");
71 		return;
72 	}
73 
74 	dumpStrings.clear();
75 	mali_gralloc_dump_string(dumpStrings,
76 	                         "-------------------------Start to dump Gralloc buffers info------------------------\n");
77 	private_handle_t *hnd;
78 	size_t num;
79 
80 	mali_gralloc_dump_string(dumpStrings, "    handle  | width | height | stride |   req format   |alloc "
81 	                                      "format|consumer usage|producer usage| shared fd | AFBC "
82 	                                      "|\n");
83 	mali_gralloc_dump_string(dumpStrings, "------------+-------+--------+--------+----------------+---------------+----"
84 	                                      "----------+--------------+-----------+------+\n");
85 	pthread_mutex_lock(&dump_lock);
86 
87 	for (num = 0; num < dump_buffers.size(); num++)
88 	{
89 		hnd = dump_buffers[num];
90 		mali_gralloc_dump_string(dumpStrings, " %08" PRIxPTR " | %5d |  %5d |  %5d |    %08x    |    %09" PRIx64
91 		                                      "  |   %09" PRIx64 "  |   %09" PRIx64 "  |  %08x | %4d |\n",
92 		                         hnd, hnd->width, hnd->height, hnd->stride, hnd->req_format, hnd->alloc_format,
93 		                         hnd->consumer_usage, hnd->producer_usage, hnd->fds[0],
94 		                         (hnd->alloc_format & MALI_GRALLOC_INTFMT_AFBCENABLE_MASK) ? true : false);
95 	}
96 
97 	pthread_mutex_unlock(&dump_lock);
98 	mali_gralloc_dump_string(
99 	    dumpStrings, "---------------------End dump Gralloc buffers info with num %zu----------------------\n", num);
100 
101 	*outSize = dumpStrings.size();
102 }
103 
mali_gralloc_dump_internal(uint32_t * outSize,char * outBuffer)104 void mali_gralloc_dump_internal(uint32_t *outSize, char *outBuffer)
105 {
106 	uint32_t dumpSize;
107 
108 	if (NULL == outSize)
109 	{
110 		MALI_GRALLOC_LOGE("Invalid pointer to dump buffer size and return");
111 		return;
112 	}
113 
114 	if (NULL == outBuffer)
115 	{
116 		if (!dumpStrings.isEmpty())
117 		{
118 			dumpStrings.clear();
119 		}
120 
121 		mali_gralloc_dump_buffers(dumpStrings, outSize);
122 	}
123 	else
124 	{
125 		if (dumpStrings.isEmpty())
126 		{
127 			*outSize = 0;
128 		}
129 		else
130 		{
131 			dumpSize = dumpStrings.size();
132 			*outSize = (dumpSize < *outSize) ? dumpSize : *outSize;
133 			memcpy(outBuffer, dumpStrings.string(), *outSize);
134 		}
135 	}
136 }
137