BufferItem.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright 2014 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <gui/BufferItem.h>
  17. #include <ui/Fence.h>
  18. #include <ui/GraphicBuffer.h>
  19. #include <system/window.h>
  20. namespace android {
  21. template<typename T>
  22. static inline constexpr uint32_t low32(const T n) {
  23. return static_cast<uint32_t>(static_cast<uint64_t>(n));
  24. }
  25. template<typename T>
  26. static inline constexpr uint32_t high32(const T n) {
  27. return static_cast<uint32_t>(static_cast<uint64_t>(n)>>32);
  28. }
  29. template<typename T>
  30. static inline constexpr T to64(const uint32_t lo, const uint32_t hi) {
  31. return static_cast<T>(static_cast<uint64_t>(hi)<<32 | lo);
  32. }
  33. BufferItem::BufferItem() :
  34. mGraphicBuffer(nullptr),
  35. mFence(nullptr),
  36. mCrop(Rect::INVALID_RECT),
  37. mTransform(0),
  38. mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
  39. mTimestamp(0),
  40. mIsAutoTimestamp(false),
  41. mDataSpace(HAL_DATASPACE_UNKNOWN),
  42. mFrameNumber(0),
  43. mSlot(INVALID_BUFFER_SLOT),
  44. mIsDroppable(false),
  45. mAcquireCalled(false),
  46. mTransformToDisplayInverse(false),
  47. mSurfaceDamage(),
  48. mAutoRefresh(false),
  49. mQueuedBuffer(true),
  50. mIsStale(false),
  51. mApi(0) {
  52. }
  53. BufferItem::~BufferItem() {}
  54. template <typename T>
  55. static void addAligned(size_t& size, T /* value */) {
  56. size = FlattenableUtils::align<sizeof(T)>(size);
  57. size += sizeof(T);
  58. }
  59. size_t BufferItem::getPodSize() const {
  60. size_t size = 0;
  61. addAligned(size, mCrop);
  62. addAligned(size, mTransform);
  63. addAligned(size, mScalingMode);
  64. addAligned(size, low32(mTimestamp));
  65. addAligned(size, high32(mTimestamp));
  66. addAligned(size, mIsAutoTimestamp);
  67. addAligned(size, mDataSpace);
  68. addAligned(size, low32(mFrameNumber));
  69. addAligned(size, high32(mFrameNumber));
  70. addAligned(size, mSlot);
  71. addAligned(size, mIsDroppable);
  72. addAligned(size, mAcquireCalled);
  73. addAligned(size, mTransformToDisplayInverse);
  74. addAligned(size, mAutoRefresh);
  75. addAligned(size, mQueuedBuffer);
  76. addAligned(size, mIsStale);
  77. addAligned(size, mApi);
  78. return size;
  79. }
  80. size_t BufferItem::getFlattenedSize() const {
  81. size_t size = sizeof(uint32_t); // Flags
  82. if (mGraphicBuffer != nullptr) {
  83. size += mGraphicBuffer->getFlattenedSize();
  84. size = FlattenableUtils::align<4>(size);
  85. }
  86. if (mFence != nullptr) {
  87. size += mFence->getFlattenedSize();
  88. size = FlattenableUtils::align<4>(size);
  89. }
  90. size += mSurfaceDamage.getFlattenedSize();
  91. size += mHdrMetadata.getFlattenedSize();
  92. size = FlattenableUtils::align<8>(size);
  93. return size + getPodSize();
  94. }
  95. size_t BufferItem::getFdCount() const {
  96. size_t count = 0;
  97. if (mGraphicBuffer != nullptr) {
  98. count += mGraphicBuffer->getFdCount();
  99. }
  100. if (mFence != nullptr) {
  101. count += mFence->getFdCount();
  102. }
  103. return count;
  104. }
  105. template <typename T>
  106. static void writeAligned(void*& buffer, size_t& size, T value) {
  107. size -= FlattenableUtils::align<alignof(T)>(buffer);
  108. FlattenableUtils::write(buffer, size, value);
  109. }
  110. status_t BufferItem::flatten(
  111. void*& buffer, size_t& size, int*& fds, size_t& count) const {
  112. // make sure we have enough space
  113. if (size < BufferItem::getFlattenedSize()) {
  114. return NO_MEMORY;
  115. }
  116. // content flags are stored first
  117. uint32_t& flags = *static_cast<uint32_t*>(buffer);
  118. // advance the pointer
  119. FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
  120. flags = 0;
  121. if (mGraphicBuffer != nullptr) {
  122. status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
  123. if (err) return err;
  124. size -= FlattenableUtils::align<4>(buffer);
  125. flags |= 1;
  126. }
  127. if (mFence != nullptr) {
  128. status_t err = mFence->flatten(buffer, size, fds, count);
  129. if (err) return err;
  130. size -= FlattenableUtils::align<4>(buffer);
  131. flags |= 2;
  132. }
  133. status_t err = mSurfaceDamage.flatten(buffer, size);
  134. if (err) return err;
  135. FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
  136. err = mHdrMetadata.flatten(buffer, size);
  137. if (err) return err;
  138. FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
  139. // Check we still have enough space
  140. if (size < getPodSize()) {
  141. return NO_MEMORY;
  142. }
  143. writeAligned(buffer, size, mCrop);
  144. writeAligned(buffer, size, mTransform);
  145. writeAligned(buffer, size, mScalingMode);
  146. writeAligned(buffer, size, low32(mTimestamp));
  147. writeAligned(buffer, size, high32(mTimestamp));
  148. writeAligned(buffer, size, mIsAutoTimestamp);
  149. writeAligned(buffer, size, mDataSpace);
  150. writeAligned(buffer, size, low32(mFrameNumber));
  151. writeAligned(buffer, size, high32(mFrameNumber));
  152. writeAligned(buffer, size, mSlot);
  153. writeAligned(buffer, size, mIsDroppable);
  154. writeAligned(buffer, size, mAcquireCalled);
  155. writeAligned(buffer, size, mTransformToDisplayInverse);
  156. writeAligned(buffer, size, mAutoRefresh);
  157. writeAligned(buffer, size, mQueuedBuffer);
  158. writeAligned(buffer, size, mIsStale);
  159. writeAligned(buffer, size, mApi);
  160. return NO_ERROR;
  161. }
  162. template <typename T>
  163. static void readAligned(const void*& buffer, size_t& size, T& value) {
  164. size -= FlattenableUtils::align<alignof(T)>(buffer);
  165. FlattenableUtils::read(buffer, size, value);
  166. }
  167. status_t BufferItem::unflatten(
  168. void const*& buffer, size_t& size, int const*& fds, size_t& count) {
  169. if (size < sizeof(uint32_t)) {
  170. return NO_MEMORY;
  171. }
  172. uint32_t flags = 0;
  173. FlattenableUtils::read(buffer, size, flags);
  174. if (flags & 1) {
  175. mGraphicBuffer = new GraphicBuffer();
  176. status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
  177. if (err) return err;
  178. size -= FlattenableUtils::align<4>(buffer);
  179. }
  180. if (flags & 2) {
  181. mFence = new Fence();
  182. status_t err = mFence->unflatten(buffer, size, fds, count);
  183. if (err) return err;
  184. size -= FlattenableUtils::align<4>(buffer);
  185. mFenceTime = std::make_shared<FenceTime>(mFence);
  186. }
  187. status_t err = mSurfaceDamage.unflatten(buffer, size);
  188. if (err) return err;
  189. FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
  190. err = mHdrMetadata.unflatten(buffer, size);
  191. if (err) return err;
  192. FlattenableUtils::advance(buffer, size, mHdrMetadata.getFlattenedSize());
  193. // Check we still have enough space
  194. if (size < getPodSize()) {
  195. return NO_MEMORY;
  196. }
  197. uint32_t timestampLo = 0, timestampHi = 0;
  198. uint32_t frameNumberLo = 0, frameNumberHi = 0;
  199. readAligned(buffer, size, mCrop);
  200. readAligned(buffer, size, mTransform);
  201. readAligned(buffer, size, mScalingMode);
  202. readAligned(buffer, size, timestampLo);
  203. readAligned(buffer, size, timestampHi);
  204. mTimestamp = to64<int64_t>(timestampLo, timestampHi);
  205. readAligned(buffer, size, mIsAutoTimestamp);
  206. readAligned(buffer, size, mDataSpace);
  207. readAligned(buffer, size, frameNumberLo);
  208. readAligned(buffer, size, frameNumberHi);
  209. mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
  210. readAligned(buffer, size, mSlot);
  211. readAligned(buffer, size, mIsDroppable);
  212. readAligned(buffer, size, mAcquireCalled);
  213. readAligned(buffer, size, mTransformToDisplayInverse);
  214. readAligned(buffer, size, mAutoRefresh);
  215. readAligned(buffer, size, mQueuedBuffer);
  216. readAligned(buffer, size, mIsStale);
  217. readAligned(buffer, size, mApi);
  218. return NO_ERROR;
  219. }
  220. const char* BufferItem::scalingModeName(uint32_t scalingMode) {
  221. switch (scalingMode) {
  222. case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
  223. case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
  224. case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
  225. default: return "Unknown";
  226. }
  227. }
  228. } // namespace android