Home | History | Annotate | Download | only in ui
      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