display_client.cpp revision 3c3f4314efbf7578fcd90d36dbe4111d72ce44cc
1#include "include/private/dvr/display_client.h" 2 3#include <cutils/native_handle.h> 4#include <log/log.h> 5#include <pdx/default_transport/client_channel.h> 6#include <pdx/default_transport/client_channel_factory.h> 7#include <pdx/status.h> 8 9#include <mutex> 10 11#include <private/dvr/display_protocol.h> 12#include <private/dvr/native_buffer.h> 13 14using android::pdx::ErrorStatus; 15using android::pdx::LocalHandle; 16using android::pdx::LocalChannelHandle; 17using android::pdx::Status; 18using android::pdx::Transaction; 19using android::pdx::rpc::IfAnyOf; 20 21namespace android { 22namespace dvr { 23namespace display { 24 25Surface::Surface(LocalChannelHandle channel_handle, int* error) 26 : BASE{pdx::default_transport::ClientChannel::Create( 27 std::move(channel_handle))} { 28 auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>(); 29 if (!status) { 30 ALOGE("Surface::Surface: Failed to get surface info: %s", 31 status.GetErrorMessage().c_str()); 32 Close(status.error()); 33 if (error) 34 *error = status.error(); 35 } 36 37 surface_id_ = status.get().surface_id; 38 z_order_ = status.get().z_order; 39 visible_ = status.get().visible; 40} 41 42Surface::Surface(const SurfaceAttributes& attributes, int* error) 43 : BASE{pdx::default_transport::ClientChannelFactory::Create( 44 DisplayProtocol::kClientPath), 45 kInfiniteTimeout} { 46 auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes); 47 if (!status) { 48 ALOGE("Surface::Surface: Failed to create display surface: %s", 49 status.GetErrorMessage().c_str()); 50 Close(status.error()); 51 if (error) 52 *error = status.error(); 53 } 54 55 surface_id_ = status.get().surface_id; 56 z_order_ = status.get().z_order; 57 visible_ = status.get().visible; 58} 59 60Status<void> Surface::SetVisible(bool visible) { 61 return SetAttributes( 62 {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}}); 63} 64 65Status<void> Surface::SetZOrder(int z_order) { 66 return SetAttributes( 67 {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}}); 68} 69 70Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) { 71 auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes); 72 if (!status) { 73 ALOGE( 74 "Surface::SetAttributes: Failed to set display surface " 75 "attributes: %s", 76 status.GetErrorMessage().c_str()); 77 return status.error_status(); 78 } 79 80 // Set the local cached copies of the attributes we care about from the full 81 // set of attributes sent to the display service. 82 for (const auto& attribute : attributes) { 83 const auto& key = attribute.first; 84 const auto* variant = &attribute.second; 85 bool invalid_value = false; 86 switch (key) { 87 case SurfaceAttribute::Visible: 88 invalid_value = 89 !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_); 90 break; 91 case SurfaceAttribute::ZOrder: 92 invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_); 93 break; 94 } 95 96 if (invalid_value) { 97 ALOGW( 98 "Surface::SetAttributes: Failed to set display surface " 99 "attribute %d because of incompatible type: %d", 100 key, variant->index()); 101 } 102 } 103 104 return {}; 105} 106 107Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(uint32_t width, 108 uint32_t height, 109 uint32_t format) { 110 ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue."); 111 auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>( 112 ProducerQueueConfigBuilder() 113 .SetDefaultWidth(width) 114 .SetDefaultHeight(height) 115 .SetDefaultFormat(format) 116 .Build()); 117 if (!status) { 118 ALOGE("Surface::CreateQueue: Failed to create queue: %s", 119 status.GetErrorMessage().c_str()); 120 return status.error_status(); 121 } 122 123 auto producer_queue = ProducerQueue::Import(status.take()); 124 if (!producer_queue) { 125 ALOGE("Surface::CreateQueue: Failed to import producer queue!"); 126 return ErrorStatus(ENOMEM); 127 } 128 129 return {std::move(producer_queue)}; 130} 131 132Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue( 133 uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format, 134 uint64_t usage, size_t capacity) { 135 ALOGD_IF(TRACE, 136 "Surface::CreateQueue: width=%u height=%u layer_count=%u format=%u " 137 "usage=%" PRIx64 " capacity=%zu", 138 width, height, layer_count, format, usage, capacity); 139 auto status = CreateQueue(width, height, format); 140 if (!status) 141 return status.error_status(); 142 143 auto producer_queue = status.take(); 144 145 ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity); 146 for (size_t i = 0; i < capacity; i++) { 147 size_t slot; 148 auto allocate_status = producer_queue->AllocateBuffer( 149 width, height, layer_count, format, usage, &slot); 150 if (!allocate_status) { 151 ALOGE( 152 "Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s", 153 producer_queue->id(), allocate_status.GetErrorMessage().c_str()); 154 return allocate_status.error_status(); 155 } 156 ALOGD_IF( 157 TRACE, 158 "Surface::CreateQueue: Allocated buffer at slot=%zu of capacity=%zu", 159 slot, capacity); 160 } 161 162 return {std::move(producer_queue)}; 163} 164 165DisplayClient::DisplayClient(int* error) 166 : BASE(pdx::default_transport::ClientChannelFactory::Create( 167 DisplayProtocol::kClientPath), 168 kInfiniteTimeout) { 169 if (error) 170 *error = Client::error(); 171} 172 173Status<Metrics> DisplayClient::GetDisplayMetrics() { 174 return InvokeRemoteMethod<DisplayProtocol::GetMetrics>(); 175} 176 177Status<std::string> DisplayClient::GetConfigurationData( 178 ConfigFileType config_type) { 179 auto status = 180 InvokeRemoteMethod<DisplayProtocol::GetConfigurationData>(config_type); 181 if (!status && status.error() != ENOENT) { 182 ALOGE( 183 "DisplayClient::GetConfigurationData: Unable to get" 184 "configuration data. Error: %s", 185 status.GetErrorMessage().c_str()); 186 } 187 return status; 188} 189 190Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface( 191 const SurfaceAttributes& attributes) { 192 int error; 193 if (auto client = Surface::Create(attributes, &error)) 194 return {std::move(client)}; 195 else 196 return ErrorStatus(error); 197} 198 199Status<std::unique_ptr<IonBuffer>> DisplayClient::GetGlobalBuffer( 200 DvrGlobalBufferKey key) { 201 auto status = InvokeRemoteMethod<DisplayProtocol::GetGlobalBuffer>(key); 202 if (!status) { 203 ALOGE( 204 "DisplayClient::GetGlobalBuffer: Failed to get named buffer: key=%d; " 205 "error=%s", 206 key, status.GetErrorMessage().c_str()); 207 return status.error_status(); 208 } 209 210 auto ion_buffer = std::make_unique<IonBuffer>(); 211 auto native_buffer_handle = status.take(); 212 const int ret = native_buffer_handle.Import(ion_buffer.get()); 213 if (ret < 0) { 214 ALOGE( 215 "DisplayClient::GetGlobalBuffer: Failed to import global buffer: " 216 "key=%d; error=%s", 217 key, strerror(-ret)); 218 return ErrorStatus(-ret); 219 } 220 221 return {std::move(ion_buffer)}; 222} 223 224Status<bool> DisplayClient::IsVrAppRunning() { 225 return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>(); 226} 227 228} // namespace display 229} // namespace dvr 230} // namespace android 231