dvr_surface.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. #include "include/dvr/dvr_surface.h"
  2. #include <inttypes.h>
  3. #include <pdx/rpc/variant.h>
  4. #include <private/android/AHardwareBufferHelpers.h>
  5. #include <private/dvr/display_client.h>
  6. #include "dvr_buffer_queue_internal.h"
  7. #include "dvr_internal.h"
  8. using android::AHardwareBuffer_convertToGrallocUsageBits;
  9. using android::dvr::display::DisplayClient;
  10. using android::dvr::display::Surface;
  11. using android::dvr::display::SurfaceAttributes;
  12. using android::dvr::display::SurfaceAttributeValue;
  13. using android::pdx::rpc::EmptyVariant;
  14. namespace {
  15. // Sets the Variant |destination| to the target std::array type and copies the C
  16. // array into it. Unsupported std::array configurations will fail to compile.
  17. template <typename T, std::size_t N>
  18. void ArrayCopy(SurfaceAttributeValue* destination, const T (&source)[N]) {
  19. using ArrayType = std::array<T, N>;
  20. *destination = ArrayType{};
  21. std::copy(std::begin(source), std::end(source),
  22. std::get<ArrayType>(*destination).begin());
  23. }
  24. bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
  25. size_t attribute_count,
  26. SurfaceAttributes* surface_attributes,
  27. size_t* error_index) {
  28. for (size_t i = 0; i < attribute_count; i++) {
  29. SurfaceAttributeValue value;
  30. switch (attributes[i].value.type) {
  31. case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
  32. value = attributes[i].value.int32_value;
  33. break;
  34. case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
  35. value = attributes[i].value.int64_value;
  36. break;
  37. case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
  38. // bool_value is defined in an extern "C" block, which makes it look
  39. // like an int to C++. Use a cast to assign the correct type to the
  40. // Variant type SurfaceAttributeValue.
  41. value = static_cast<bool>(attributes[i].value.bool_value);
  42. break;
  43. case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
  44. value = attributes[i].value.float_value;
  45. break;
  46. case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
  47. ArrayCopy(&value, attributes[i].value.float2_value);
  48. break;
  49. case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
  50. ArrayCopy(&value, attributes[i].value.float3_value);
  51. break;
  52. case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
  53. ArrayCopy(&value, attributes[i].value.float4_value);
  54. break;
  55. case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
  56. ArrayCopy(&value, attributes[i].value.float8_value);
  57. break;
  58. case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
  59. ArrayCopy(&value, attributes[i].value.float16_value);
  60. break;
  61. case DVR_SURFACE_ATTRIBUTE_TYPE_NONE:
  62. value = EmptyVariant{};
  63. break;
  64. default:
  65. *error_index = i;
  66. return false;
  67. }
  68. surface_attributes->emplace(attributes[i].key, value);
  69. }
  70. return true;
  71. }
  72. } // anonymous namespace
  73. extern "C" {
  74. struct DvrSurface {
  75. std::unique_ptr<Surface> surface;
  76. };
  77. int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
  78. size_t attribute_count, DvrSurface** out_surface) {
  79. if (out_surface == nullptr) {
  80. ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
  81. return -EINVAL;
  82. }
  83. size_t error_index;
  84. SurfaceAttributes surface_attributes;
  85. if (!ConvertSurfaceAttributes(attributes, attribute_count,
  86. &surface_attributes, &error_index)) {
  87. ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
  88. attributes[error_index].value.type);
  89. return -EINVAL;
  90. }
  91. auto status = Surface::CreateSurface(surface_attributes);
  92. if (!status) {
  93. ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
  94. status.GetErrorMessage().c_str());
  95. return -status.error();
  96. }
  97. *out_surface = new DvrSurface{status.take()};
  98. return 0;
  99. }
  100. void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
  101. int dvrSurfaceGetId(DvrSurface* surface) {
  102. return surface->surface->surface_id();
  103. }
  104. int dvrSurfaceSetAttributes(DvrSurface* surface,
  105. const DvrSurfaceAttribute* attributes,
  106. size_t attribute_count) {
  107. if (surface == nullptr || attributes == nullptr) {
  108. ALOGE(
  109. "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
  110. "attribute_count=%zu",
  111. surface, attributes, attribute_count);
  112. return -EINVAL;
  113. }
  114. size_t error_index;
  115. SurfaceAttributes surface_attributes;
  116. if (!ConvertSurfaceAttributes(attributes, attribute_count,
  117. &surface_attributes, &error_index)) {
  118. ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
  119. attributes[error_index].value.type);
  120. return -EINVAL;
  121. }
  122. auto status = surface->surface->SetAttributes(surface_attributes);
  123. if (!status) {
  124. ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
  125. status.GetErrorMessage().c_str());
  126. return -status.error();
  127. }
  128. return 0;
  129. }
  130. int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
  131. uint32_t height, uint32_t format,
  132. uint32_t layer_count, uint64_t usage,
  133. size_t capacity, size_t metadata_size,
  134. DvrWriteBufferQueue** out_writer) {
  135. if (surface == nullptr || out_writer == nullptr) {
  136. ALOGE(
  137. "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
  138. "out_writer=%p.",
  139. surface, out_writer);
  140. return -EINVAL;
  141. }
  142. auto status = surface->surface->CreateQueue(
  143. width, height, layer_count, format, usage, capacity, metadata_size);
  144. if (!status) {
  145. ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
  146. status.GetErrorMessage().c_str());
  147. return -status.error();
  148. }
  149. *out_writer = new DvrWriteBufferQueue(status.take());
  150. return 0;
  151. }
  152. int dvrSetupGlobalBuffer(DvrGlobalBufferKey key, size_t size, uint64_t usage,
  153. DvrBuffer** buffer_out) {
  154. if (!buffer_out)
  155. return -EINVAL;
  156. int error;
  157. auto client = DisplayClient::Create(&error);
  158. if (!client) {
  159. ALOGE("dvrSetupGlobalBuffer: Failed to create display client: %s",
  160. strerror(-error));
  161. return error;
  162. }
  163. uint64_t gralloc_usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
  164. auto buffer_status = client->SetupGlobalBuffer(key, size, gralloc_usage);
  165. if (!buffer_status) {
  166. ALOGE("dvrSetupGlobalBuffer: Failed to setup global buffer: %s",
  167. buffer_status.GetErrorMessage().c_str());
  168. return -buffer_status.error();
  169. }
  170. *buffer_out = CreateDvrBufferFromIonBuffer(buffer_status.take());
  171. return 0;
  172. }
  173. int dvrDeleteGlobalBuffer(DvrGlobalBufferKey key) {
  174. int error;
  175. auto client = DisplayClient::Create(&error);
  176. if (!client) {
  177. ALOGE("dvrDeleteGlobalBuffer: Failed to create display client: %s",
  178. strerror(-error));
  179. return error;
  180. }
  181. auto buffer_status = client->DeleteGlobalBuffer(key);
  182. if (!buffer_status) {
  183. ALOGE("dvrDeleteGlobalBuffer: Failed to delete named buffer: %s",
  184. buffer_status.GetErrorMessage().c_str());
  185. return -buffer_status.error();
  186. }
  187. return 0;
  188. }
  189. int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer) {
  190. if (!out_buffer)
  191. return -EINVAL;
  192. int error;
  193. auto client = DisplayClient::Create(&error);
  194. if (!client) {
  195. ALOGE("dvrGetGlobalBuffer: Failed to create display client: %s",
  196. strerror(-error));
  197. return error;
  198. }
  199. auto status = client->GetGlobalBuffer(key);
  200. if (!status) {
  201. return -status.error();
  202. }
  203. *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
  204. return 0;
  205. }
  206. int dvrGetNativeDisplayMetrics(size_t sizeof_metrics,
  207. DvrNativeDisplayMetrics* metrics) {
  208. ALOGE_IF(sizeof_metrics != sizeof(DvrNativeDisplayMetrics),
  209. "dvrGetNativeDisplayMetrics: metrics struct mismatch, your dvr api "
  210. "header is out of date.");
  211. auto client = DisplayClient::Create();
  212. if (!client) {
  213. ALOGE("dvrGetNativeDisplayMetrics: Failed to create display client!");
  214. return -ECOMM;
  215. }
  216. if (metrics == nullptr) {
  217. ALOGE("dvrGetNativeDisplayMetrics: output metrics buffer must be non-null");
  218. return -EINVAL;
  219. }
  220. auto status = client->GetDisplayMetrics();
  221. if (!status) {
  222. return -status.error();
  223. }
  224. if (sizeof_metrics >= 20) {
  225. metrics->display_width = status.get().display_width;
  226. metrics->display_height = status.get().display_height;
  227. metrics->display_x_dpi = status.get().display_x_dpi;
  228. metrics->display_y_dpi = status.get().display_y_dpi;
  229. metrics->vsync_period_ns = status.get().vsync_period_ns;
  230. }
  231. return 0;
  232. }
  233. } // extern "C"