GraphicBufferAllocator.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. #define LOG_TAG "GraphicBufferAllocator"
  18. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  19. #include <cutils/log.h>
  20. #include <utils/Singleton.h>
  21. #include <utils/String8.h>
  22. #include <utils/Trace.h>
  23. #include <ui/GraphicBufferAllocator.h>
  24. namespace android {
  25. // ---------------------------------------------------------------------------
  26. ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferAllocator )
  27. Mutex GraphicBufferAllocator::sLock;
  28. KeyedVector<buffer_handle_t,
  29. GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
  30. GraphicBufferAllocator::GraphicBufferAllocator()
  31. : mAllocDev(0)
  32. {
  33. hw_module_t const* module;
  34. int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
  35. ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
  36. if (err == 0) {
  37. gralloc_open(module, &mAllocDev);
  38. }
  39. }
  40. GraphicBufferAllocator::~GraphicBufferAllocator()
  41. {
  42. gralloc_close(mAllocDev);
  43. }
  44. void GraphicBufferAllocator::dump(String8& result) const
  45. {
  46. Mutex::Autolock _l(sLock);
  47. KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
  48. size_t total = 0;
  49. const size_t SIZE = 4096;
  50. char buffer[SIZE];
  51. snprintf(buffer, SIZE, "Allocated buffers:\n");
  52. result.append(buffer);
  53. const size_t c = list.size();
  54. for (size_t i=0 ; i<c ; i++) {
  55. const alloc_rec_t& rec(list.valueAt(i));
  56. if (rec.size) {
  57. snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
  58. list.keyAt(i), rec.size/1024.0f,
  59. rec.width, rec.stride, rec.height, rec.format, rec.usage);
  60. } else {
  61. snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x\n",
  62. list.keyAt(i),
  63. rec.width, rec.stride, rec.height, rec.format, rec.usage);
  64. }
  65. result.append(buffer);
  66. total += rec.size;
  67. }
  68. snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0f);
  69. result.append(buffer);
  70. if (mAllocDev->common.version >= 1 && mAllocDev->dump) {
  71. mAllocDev->dump(mAllocDev, buffer, SIZE);
  72. result.append(buffer);
  73. }
  74. }
  75. void GraphicBufferAllocator::dumpToSystemLog()
  76. {
  77. String8 s;
  78. GraphicBufferAllocator::getInstance().dump(s);
  79. ALOGD("%s", s.string());
  80. }
  81. status_t GraphicBufferAllocator::alloc(uint32_t width, uint32_t height,
  82. PixelFormat format, uint32_t usage, buffer_handle_t* handle,
  83. uint32_t* stride)
  84. {
  85. ATRACE_CALL();
  86. // make sure to not allocate a N x 0 or 0 x N buffer, since this is
  87. // allowed from an API stand-point allocate a 1x1 buffer instead.
  88. if (!width || !height)
  89. width = height = 1;
  90. // we have a h/w allocator and h/w buffer is requested
  91. status_t err;
  92. // Filter out any usage bits that should not be passed to the gralloc module
  93. usage &= GRALLOC_USAGE_ALLOC_MASK;
  94. int outStride = 0;
  95. err = mAllocDev->alloc(mAllocDev, static_cast<int>(width),
  96. static_cast<int>(height), format, static_cast<int>(usage), handle,
  97. &outStride);
  98. *stride = static_cast<uint32_t>(outStride);
  99. ALOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
  100. width, height, format, usage, err, strerror(-err));
  101. if (err == NO_ERROR) {
  102. Mutex::Autolock _l(sLock);
  103. KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
  104. uint32_t bpp = bytesPerPixel(format);
  105. alloc_rec_t rec;
  106. rec.width = width;
  107. rec.height = height;
  108. rec.stride = *stride;
  109. rec.format = format;
  110. rec.usage = usage;
  111. rec.size = static_cast<size_t>(height * (*stride) * bpp);
  112. list.add(*handle, rec);
  113. }
  114. return err;
  115. }
  116. status_t GraphicBufferAllocator::free(buffer_handle_t handle)
  117. {
  118. ATRACE_CALL();
  119. status_t err;
  120. err = mAllocDev->free(mAllocDev, handle);
  121. ALOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err));
  122. if (err == NO_ERROR) {
  123. Mutex::Autolock _l(sLock);
  124. KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
  125. list.removeItem(handle);
  126. }
  127. return err;
  128. }
  129. // ---------------------------------------------------------------------------
  130. }; // namespace android