• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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