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 <ui/GraphicBufferAllocator.h>
     22 
     23 #include <stdio.h>
     24 
     25 #include <grallocusage/GrallocUsageConversion.h>
     26 
     27 #include <log/log.h>
     28 #include <utils/Singleton.h>
     29 #include <utils/String8.h>
     30 #include <utils/Trace.h>
     31 
     32 #include <ui/Gralloc2.h>
     33 #include <ui/GraphicBufferMapper.h>
     34 
     35 namespace android {
     36 // ---------------------------------------------------------------------------
     37 
     38 ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator )
     39 
     40 Mutex GraphicBufferAllocator::sLock;
     41 KeyedVector<buffer_handle_t,
     42     GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
     43 
     44 GraphicBufferAllocator::GraphicBufferAllocator()
     45   : mMapper(GraphicBufferMapper::getInstance()),
     46     mAllocator(std::make_unique<Gralloc2::Allocator>(
     47                 mMapper.getGrallocMapper()))
     48 {
     49 }
     50 
     51 GraphicBufferAllocator::~GraphicBufferAllocator() {}
     52 
     53 void GraphicBufferAllocator::dump(String8& result) const
     54 {
     55     Mutex::Autolock _l(sLock);
     56     KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
     57     size_t total = 0;
     58     const size_t SIZE = 4096;
     59     char buffer[SIZE];
     60     snprintf(buffer, SIZE, "Allocated buffers:\n");
     61     result.append(buffer);
     62     const size_t c = list.size();
     63     for (size_t i=0 ; i<c ; i++) {
     64         const alloc_rec_t& rec(list.valueAt(i));
     65         if (rec.size) {
     66             snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64
     67                     " | %s\n",
     68                     list.keyAt(i), rec.size/1024.0,
     69                     rec.width, rec.stride, rec.height, rec.layerCount, rec.format,
     70                     rec.usage, rec.requestorName.c_str());
     71         } else {
     72             snprintf(buffer, SIZE, "%10p: unknown     | %4u (%4u) x %4u | %4u | %8X | 0x%" PRIx64
     73                     " | %s\n",
     74                     list.keyAt(i),
     75                     rec.width, rec.stride, rec.height, rec.layerCount, rec.format,
     76                     rec.usage, rec.requestorName.c_str());
     77         }
     78         result.append(buffer);
     79         total += rec.size;
     80     }
     81     snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0);
     82     result.append(buffer);
     83 
     84     std::string deviceDump = mAllocator->dumpDebugInfo();
     85     result.append(deviceDump.c_str(), deviceDump.size());
     86 }
     87 
     88 void GraphicBufferAllocator::dumpToSystemLog()
     89 {
     90     String8 s;
     91     GraphicBufferAllocator::getInstance().dump(s);
     92     ALOGD("%s", s.string());
     93 }
     94 
     95 status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
     96         PixelFormat format, uint32_t layerCount, uint64_t usage,
     97         buffer_handle_t* handle, uint32_t* stride,
     98         uint64_t /*graphicBufferId*/, std::string requestorName)
     99 {
    100     ATRACE_CALL();
    101 
    102     // make sure to not allocate a N x 0 or 0 x N buffer, since this is
    103     // allowed from an API stand-point allocate a 1x1 buffer instead.
    104     if (!width || !height)
    105         width = height = 1;
    106 
    107     // Ensure that layerCount is valid.
    108     if (layerCount < 1)
    109         layerCount = 1;
    110 
    111     Gralloc2::IMapper::BufferDescriptorInfo info = {};
    112     info.width = width;
    113     info.height = height;
    114     info.layerCount = layerCount;
    115     info.format = static_cast<Gralloc2::PixelFormat>(format);
    116     info.usage = usage;
    117 
    118     Gralloc2::Error error = mAllocator->allocate(info, stride, handle);
    119     if (error == Gralloc2::Error::NONE) {
    120         Mutex::Autolock _l(sLock);
    121         KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
    122         uint32_t bpp = bytesPerPixel(format);
    123         alloc_rec_t rec;
    124         rec.width = width;
    125         rec.height = height;
    126         rec.stride = *stride;
    127         rec.format = format;
    128         rec.layerCount = layerCount;
    129         rec.usage = usage;
    130         rec.size = static_cast<size_t>(height * (*stride) * bpp);
    131         rec.requestorName = std::move(requestorName);
    132         list.add(*handle, rec);
    133 
    134         return NO_ERROR;
    135     } else {
    136         ALOGE("Failed to allocate (%u x %u) layerCount %u format %d "
    137                 "usage %" PRIx64 ": %d",
    138                 width, height, layerCount, format, usage,
    139                 error);
    140         return NO_MEMORY;
    141     }
    142 }
    143 
    144 status_t GraphicBufferAllocator::free(buffer_handle_t handle)
    145 {
    146     ATRACE_CALL();
    147 
    148     // We allocated a buffer from the allocator and imported it into the
    149     // mapper to get the handle.  We just need to free the handle now.
    150     mMapper.freeBuffer(handle);
    151 
    152     Mutex::Autolock _l(sLock);
    153     KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
    154     list.removeItem(handle);
    155 
    156     return NO_ERROR;
    157 }
    158 
    159 // ---------------------------------------------------------------------------
    160 }; // namespace android
    161