1 /*
2 **
3 ** Copyright 2009, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #define LOG_TAG "GraphicBufferAllocator"
19 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
20
21 #include <cutils/log.h>
22
23 #include <utils/Singleton.h>
24 #include <utils/String8.h>
25 #include <utils/Trace.h>
26
27 #include <ui/GraphicBufferAllocator.h>
28 #include <ui/Gralloc1On0Adapter.h>
29
30 namespace android {
31 // ---------------------------------------------------------------------------
32
33 ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator )
34
35 Mutex GraphicBufferAllocator::sLock;
36 KeyedVector<buffer_handle_t,
37 GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
38
GraphicBufferAllocator()39 GraphicBufferAllocator::GraphicBufferAllocator()
40 : mLoader(std::make_unique<Gralloc1::Loader>()),
41 mDevice(mLoader->getDevice()) {}
42
~GraphicBufferAllocator()43 GraphicBufferAllocator::~GraphicBufferAllocator() {}
44
dump(String8 & result) const45 void GraphicBufferAllocator::dump(String8& result) const
46 {
47 Mutex::Autolock _l(sLock);
48 KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
49 size_t total = 0;
50 const size_t SIZE = 4096;
51 char buffer[SIZE];
52 snprintf(buffer, SIZE, "Allocated buffers:\n");
53 result.append(buffer);
54 const size_t c = list.size();
55 for (size_t i=0 ; i<c ; i++) {
56 const alloc_rec_t& rec(list.valueAt(i));
57 if (rec.size) {
58 snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x | %s\n",
59 list.keyAt(i), rec.size/1024.0f,
60 rec.width, rec.stride, rec.height, rec.format, rec.usage,
61 rec.requestorName.c_str());
62 } else {
63 snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x | %s\n",
64 list.keyAt(i),
65 rec.width, rec.stride, rec.height, rec.format, rec.usage,
66 rec.requestorName.c_str());
67 }
68 result.append(buffer);
69 total += rec.size;
70 }
71 snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0f);
72 result.append(buffer);
73 std::string deviceDump = mDevice->dump();
74 result.append(deviceDump.c_str(), deviceDump.size());
75 }
76
dumpToSystemLog()77 void GraphicBufferAllocator::dumpToSystemLog()
78 {
79 String8 s;
80 GraphicBufferAllocator::getInstance().dump(s);
81 ALOGD("%s", s.string());
82 }
83
allocate(uint32_t width,uint32_t height,PixelFormat format,uint32_t usage,buffer_handle_t * handle,uint32_t * stride,uint64_t graphicBufferId,std::string requestorName)84 status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
85 PixelFormat format, uint32_t usage, buffer_handle_t* handle,
86 uint32_t* stride, uint64_t graphicBufferId, std::string requestorName)
87 {
88 ATRACE_CALL();
89
90 // make sure to not allocate a N x 0 or 0 x N buffer, since this is
91 // allowed from an API stand-point allocate a 1x1 buffer instead.
92 if (!width || !height)
93 width = height = 1;
94
95 // Filter out any usage bits that should not be passed to the gralloc module
96 usage &= GRALLOC_USAGE_ALLOC_MASK;
97
98 auto descriptor = mDevice->createDescriptor();
99 auto error = descriptor->setDimensions(width, height);
100 if (error != GRALLOC1_ERROR_NONE) {
101 ALOGE("Failed to set dimensions to (%u, %u): %d", width, height, error);
102 return BAD_VALUE;
103 }
104 error = descriptor->setFormat(static_cast<android_pixel_format_t>(format));
105 if (error != GRALLOC1_ERROR_NONE) {
106 ALOGE("Failed to set format to %d: %d", format, error);
107 return BAD_VALUE;
108 }
109 error = descriptor->setProducerUsage(
110 static_cast<gralloc1_producer_usage_t>(usage));
111 if (error != GRALLOC1_ERROR_NONE) {
112 ALOGE("Failed to set producer usage to %u: %d", usage, error);
113 return BAD_VALUE;
114 }
115 error = descriptor->setConsumerUsage(
116 static_cast<gralloc1_consumer_usage_t>(usage));
117 if (error != GRALLOC1_ERROR_NONE) {
118 ALOGE("Failed to set consumer usage to %u: %d", usage, error);
119 return BAD_VALUE;
120 }
121
122 error = mDevice->allocate(descriptor, graphicBufferId, handle);
123 if (error != GRALLOC1_ERROR_NONE) {
124 ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
125 width, height, format, usage, error);
126 return NO_MEMORY;
127 }
128
129 error = mDevice->getStride(*handle, stride);
130 if (error != GRALLOC1_ERROR_NONE) {
131 ALOGW("Failed to get stride from buffer: %d", error);
132 }
133
134 if (error == NO_ERROR) {
135 Mutex::Autolock _l(sLock);
136 KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
137 uint32_t bpp = bytesPerPixel(format);
138 alloc_rec_t rec;
139 rec.width = width;
140 rec.height = height;
141 rec.stride = *stride;
142 rec.format = format;
143 rec.usage = usage;
144 rec.size = static_cast<size_t>(height * (*stride) * bpp);
145 rec.requestorName = std::move(requestorName);
146 list.add(*handle, rec);
147 }
148
149 return NO_ERROR;
150 }
151
free(buffer_handle_t handle)152 status_t GraphicBufferAllocator::free(buffer_handle_t handle)
153 {
154 ATRACE_CALL();
155
156 auto error = mDevice->release(handle);
157 if (error != GRALLOC1_ERROR_NONE) {
158 ALOGE("Failed to free buffer: %d", error);
159 }
160
161 Mutex::Autolock _l(sLock);
162 KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
163 list.removeItem(handle);
164
165 return NO_ERROR;
166 }
167
168 // ---------------------------------------------------------------------------
169 }; // namespace android
170