Jiwen 'Steve' Cai | bdcee79 | 2017-03-22 16:59:53 -0700 | [diff] [blame] | 1 | #include "include/dvr/dvr_surface.h" |
| 2 | |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 3 | #include <inttypes.h> |
| 4 | |
Jiwen 'Steve' Cai | bdcee79 | 2017-03-22 16:59:53 -0700 | [diff] [blame] | 5 | #include <private/dvr/display_client.h> |
| 6 | |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 7 | #include "dvr_internal.h" |
Jiwen 'Steve' Cai | bdcee79 | 2017-03-22 16:59:53 -0700 | [diff] [blame] | 8 | |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 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::dvr::CreateDvrReadBufferFromBufferConsumer; |
| 14 | using android::dvr::CreateDvrWriteBufferQueueFromProducerQueue; |
| 15 | |
| 16 | namespace { |
| 17 | |
| 18 | bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes, |
| 19 | size_t attribute_count, |
| 20 | SurfaceAttributes* surface_attributes, |
| 21 | size_t* error_index) { |
| 22 | for (size_t i = 0; i < attribute_count; i++) { |
| 23 | SurfaceAttributeValue value; |
| 24 | switch (attributes[i].value.type) { |
| 25 | case DVR_SURFACE_ATTRIBUTE_TYPE_INT32: |
| 26 | value = attributes[i].value.int32_value; |
| 27 | break; |
| 28 | case DVR_SURFACE_ATTRIBUTE_TYPE_INT64: |
| 29 | value = attributes[i].value.int64_value; |
| 30 | break; |
| 31 | case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL: |
| 32 | value = attributes[i].value.bool_value; |
| 33 | break; |
| 34 | case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT: |
| 35 | value = attributes[i].value.float_value; |
| 36 | break; |
| 37 | case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2: |
| 38 | value = attributes[i].value.float2_value; |
| 39 | break; |
| 40 | case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3: |
| 41 | value = attributes[i].value.float3_value; |
| 42 | break; |
| 43 | case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4: |
| 44 | value = attributes[i].value.float4_value; |
| 45 | break; |
| 46 | case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8: |
| 47 | value = attributes[i].value.float8_value; |
| 48 | break; |
| 49 | case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16: |
| 50 | value = attributes[i].value.float16_value; |
| 51 | break; |
| 52 | default: |
| 53 | *error_index = i; |
| 54 | return false; |
| 55 | } |
| 56 | |
| 57 | surface_attributes->emplace(attributes[i].key, value); |
| 58 | } |
| 59 | |
| 60 | return true; |
| 61 | } |
| 62 | |
| 63 | } // anonymous namespace |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 64 | |
Jiwen 'Steve' Cai | bdcee79 | 2017-03-22 16:59:53 -0700 | [diff] [blame] | 65 | extern "C" { |
| 66 | |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 67 | struct DvrSurface { |
| 68 | std::unique_ptr<Surface> surface; |
| 69 | }; |
| 70 | |
| 71 | int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes, |
| 72 | size_t attribute_count, DvrSurface** out_surface) { |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 73 | if (out_surface == nullptr) { |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 74 | ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface); |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 75 | return -EINVAL; |
| 76 | } |
| 77 | |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 78 | size_t error_index; |
| 79 | SurfaceAttributes surface_attributes; |
| 80 | if (!ConvertSurfaceAttributes(attributes, attribute_count, |
| 81 | &surface_attributes, &error_index)) { |
| 82 | ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64, |
| 83 | attributes[error_index].value.type); |
| 84 | return -EINVAL; |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 85 | } |
| 86 | |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 87 | auto status = Surface::CreateSurface(surface_attributes); |
| 88 | if (!status) { |
| 89 | ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s", |
| 90 | status.GetErrorMessage().c_str()); |
| 91 | return -status.error(); |
| 92 | } |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 93 | |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 94 | *out_surface = new DvrSurface{status.take()}; |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 95 | return 0; |
| 96 | } |
| 97 | |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 98 | void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; } |
| 99 | |
| 100 | int dvrSurfaceGetId(DvrSurface* surface) { |
| 101 | return surface->surface->surface_id(); |
| 102 | } |
| 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 | |
| 115 | size_t error_index; |
| 116 | SurfaceAttributes surface_attributes; |
| 117 | if (!ConvertSurfaceAttributes(attributes, attribute_count, |
| 118 | &surface_attributes, &error_index)) { |
| 119 | ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64, |
| 120 | attributes[error_index].value.type); |
| 121 | return -EINVAL; |
| 122 | } |
| 123 | |
| 124 | auto status = surface->surface->SetAttributes(surface_attributes); |
| 125 | if (!status) { |
| 126 | ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s", |
| 127 | status.GetErrorMessage().c_str()); |
| 128 | return -status.error(); |
| 129 | } |
| 130 | |
| 131 | return 0; |
| 132 | } |
| 133 | |
| 134 | int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width, |
| 135 | uint32_t height, uint32_t format, |
Hendrik Wagenaar | 108e84f | 2017-05-07 22:19:17 -0700 | [diff] [blame] | 136 | uint32_t layer_count, uint64_t usage, |
| 137 | size_t capacity, |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 138 | DvrWriteBufferQueue** out_writer) { |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 139 | if (surface == nullptr || out_writer == nullptr) { |
| 140 | ALOGE( |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 141 | "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, " |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 142 | "out_writer=%p.", |
| 143 | surface, out_writer); |
| 144 | return -EINVAL; |
| 145 | } |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 146 | |
Hendrik Wagenaar | 108e84f | 2017-05-07 22:19:17 -0700 | [diff] [blame] | 147 | auto status = surface->surface->CreateQueue(width, height, layer_count, |
| 148 | format, usage, capacity); |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 149 | if (!status) { |
| 150 | ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s", |
| 151 | status.GetErrorMessage().c_str()); |
| 152 | return -status.error(); |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 153 | } |
| 154 | |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 155 | *out_writer = CreateDvrWriteBufferQueueFromProducerQueue(status.take()); |
Jiwen 'Steve' Cai | 74cf084 | 2017-03-23 18:53:16 -0700 | [diff] [blame] | 156 | return 0; |
| 157 | } |
| 158 | |
Okan Arikan | 36d2380 | 2017-05-15 15:20:39 -0700 | [diff] [blame^] | 159 | int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer) { |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 160 | auto client = DisplayClient::Create(); |
Jiwen 'Steve' Cai | bdcee79 | 2017-03-22 16:59:53 -0700 | [diff] [blame] | 161 | if (!client) { |
Okan Arikan | 36d2380 | 2017-05-15 15:20:39 -0700 | [diff] [blame^] | 162 | ALOGE("dvrGetGlobalBuffer: Failed to create display client!"); |
Jiwen 'Steve' Cai | bdcee79 | 2017-03-22 16:59:53 -0700 | [diff] [blame] | 163 | return -ECOMM; |
| 164 | } |
| 165 | |
Okan Arikan | 36d2380 | 2017-05-15 15:20:39 -0700 | [diff] [blame^] | 166 | if (out_buffer == nullptr) { |
| 167 | ALOGE("dvrGetGlobalBuffer: Invalid inputs: key=%d, out_buffer=%p.", key, |
Hendrik Wagenaar | eaa5522 | 2017-04-06 10:56:23 -0700 | [diff] [blame] | 168 | out_buffer); |
| 169 | return -EINVAL; |
| 170 | } |
| 171 | |
Okan Arikan | 36d2380 | 2017-05-15 15:20:39 -0700 | [diff] [blame^] | 172 | auto status = client->GetGlobalBuffer(key); |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 173 | if (!status) { |
Okan Arikan | 36d2380 | 2017-05-15 15:20:39 -0700 | [diff] [blame^] | 174 | ALOGE("dvrGetGlobalBuffer: Failed to find named buffer key=%d: %s", key, |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 175 | status.GetErrorMessage().c_str()); |
| 176 | return -status.error(); |
Hendrik Wagenaar | eaa5522 | 2017-04-06 10:56:23 -0700 | [diff] [blame] | 177 | } |
Corey Tabaka | 2251d82 | 2017-04-20 16:04:07 -0700 | [diff] [blame] | 178 | *out_buffer = CreateDvrBufferFromIonBuffer(status.take()); |
Jiwen 'Steve' Cai | bdcee79 | 2017-03-22 16:59:53 -0700 | [diff] [blame] | 179 | return 0; |
| 180 | } |
| 181 | |
| 182 | } // extern "C" |