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 39 GraphicBufferAllocator::GraphicBufferAllocator() 40 : mLoader(std::make_unique<Gralloc1::Loader>()), 41 mDevice(mLoader->getDevice()) {} 42 43 GraphicBufferAllocator::~GraphicBufferAllocator() {} 44 45 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 77 void GraphicBufferAllocator::dumpToSystemLog() 78 { 79 String8 s; 80 GraphicBufferAllocator::getInstance().dump(s); 81 ALOGD("%s", s.string()); 82 } 83 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 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