display_client.cpp revision 7480c060cb3466d97ec3125d61bbace153f534c8
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_rpc.h> 12#include <private/dvr/late_latch.h> 13#include <private/dvr/native_buffer.h> 14 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 { 23 24SurfaceClient::SurfaceClient(LocalChannelHandle channel_handle, 25 SurfaceType type) 26 : Client{pdx::default_transport::ClientChannel::Create( 27 std::move(channel_handle))}, 28 type_(type) {} 29 30SurfaceClient::SurfaceClient(const std::string& endpoint_path, SurfaceType type) 31 : Client{pdx::default_transport::ClientChannelFactory::Create( 32 endpoint_path), 33 kInfiniteTimeout}, 34 type_(type) {} 35 36int SurfaceClient::GetMetadataBufferFd(LocalHandle* out_fd) { 37 auto buffer_producer = GetMetadataBuffer(); 38 if (!buffer_producer) 39 return -ENOMEM; 40 41 *out_fd = buffer_producer->GetBlobFd(); 42 return 0; 43} 44 45std::shared_ptr<BufferProducer> SurfaceClient::GetMetadataBuffer() { 46 if (!metadata_buffer_) { 47 auto status = InvokeRemoteMethod<DisplayRPC::GetMetadataBuffer>(); 48 if (!status) { 49 ALOGE( 50 "SurfaceClient::AllocateMetadataBuffer: Failed to allocate buffer: " 51 "%s", 52 status.GetErrorMessage().c_str()); 53 return nullptr; 54 } 55 56 metadata_buffer_ = BufferProducer::Import(status.take()); 57 } 58 59 return metadata_buffer_; 60} 61 62DisplaySurfaceClient::DisplaySurfaceClient(int width, int height, int format, 63 int usage, int flags) 64 : BASE(DisplayRPC::kClientPath, SurfaceTypeEnum::Normal), 65 width_(width), 66 height_(height), 67 format_(format), 68 usage_(usage), 69 flags_(flags), 70 z_order_(0), 71 visible_(true), 72 exclude_from_blur_(false), 73 blur_behind_(true), 74 mapped_metadata_buffer_(nullptr) { 75 auto status = InvokeRemoteMethod<DisplayRPC::CreateSurface>( 76 width, height, format, usage, flags); 77 if (!status) { 78 ALOGE( 79 "DisplaySurfaceClient::DisplaySurfaceClient: Failed to create display " 80 "surface: %s", 81 status.GetErrorMessage().c_str()); 82 Close(status.error()); 83 } 84} 85 86void DisplaySurfaceClient::SetVisible(bool visible) { 87 SetAttributes({{DisplaySurfaceAttributeEnum::Visible, 88 DisplaySurfaceAttributeValue{visible}}}); 89} 90 91void DisplaySurfaceClient::SetZOrder(int z_order) { 92 SetAttributes({{DisplaySurfaceAttributeEnum::ZOrder, 93 DisplaySurfaceAttributeValue{z_order}}}); 94} 95 96void DisplaySurfaceClient::SetExcludeFromBlur(bool exclude_from_blur) { 97 SetAttributes({{DisplaySurfaceAttributeEnum::ExcludeFromBlur, 98 DisplaySurfaceAttributeValue{exclude_from_blur}}}); 99} 100 101void DisplaySurfaceClient::SetBlurBehind(bool blur_behind) { 102 SetAttributes({{DisplaySurfaceAttributeEnum::BlurBehind, 103 DisplaySurfaceAttributeValue{blur_behind}}}); 104} 105 106void DisplaySurfaceClient::SetAttributes( 107 const DisplaySurfaceAttributes& attributes) { 108 Status<int> status = 109 InvokeRemoteMethod<DisplayRPC::SetAttributes>(attributes); 110 if (!status) { 111 ALOGE( 112 "DisplaySurfaceClient::SetAttributes: Failed to set display surface " 113 "attributes: %s", 114 status.GetErrorMessage().c_str()); 115 return; 116 } 117 118 // Set the local cached copies of the attributes we care about from the full 119 // set of attributes sent to the display service. 120 for (const auto& attribute : attributes) { 121 const auto& key = attribute.first; 122 const auto* variant = &attribute.second; 123 bool invalid_value = false; 124 switch (key) { 125 case DisplaySurfaceAttributeEnum::Visible: 126 invalid_value = 127 !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_); 128 break; 129 case DisplaySurfaceAttributeEnum::ZOrder: 130 invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_); 131 break; 132 case DisplaySurfaceAttributeEnum::ExcludeFromBlur: 133 invalid_value = 134 !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &exclude_from_blur_); 135 break; 136 case DisplaySurfaceAttributeEnum::BlurBehind: 137 invalid_value = 138 !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &blur_behind_); 139 break; 140 } 141 142 if (invalid_value) { 143 ALOGW( 144 "DisplaySurfaceClient::SetAttributes: Failed to set display " 145 "surface attribute '%s' because of incompatible type: %d", 146 DisplaySurfaceAttributeEnum::ToString(key).c_str(), variant->index()); 147 } 148 } 149} 150 151std::shared_ptr<ProducerQueue> DisplaySurfaceClient::GetProducerQueue() { 152 if (producer_queue_ == nullptr) { 153 // Create producer queue through DisplayRPC 154 auto status = InvokeRemoteMethod<DisplayRPC::CreateBufferQueue>(); 155 if (!status) { 156 ALOGE( 157 "DisplaySurfaceClient::GetProducerQueue: failed to create producer " 158 "queue: %s", 159 status.GetErrorMessage().c_str()); 160 return nullptr; 161 } 162 163 producer_queue_ = 164 ProducerQueue::Import<DisplaySurfaceMetadata>(status.take()); 165 } 166 return producer_queue_; 167} 168 169volatile DisplaySurfaceMetadata* DisplaySurfaceClient::GetMetadataBufferPtr() { 170 if (!mapped_metadata_buffer_) { 171 if (auto buffer_producer = GetMetadataBuffer()) { 172 void* addr = nullptr; 173 const int ret = buffer_producer->GetBlobReadWritePointer( 174 sizeof(DisplaySurfaceMetadata), &addr); 175 if (ret < 0) { 176 ALOGE( 177 "DisplaySurfaceClient::GetMetadataBufferPtr: Failed to map surface " 178 "metadata: %s", 179 strerror(-ret)); 180 return nullptr; 181 } 182 mapped_metadata_buffer_ = static_cast<DisplaySurfaceMetadata*>(addr); 183 } 184 } 185 186 return mapped_metadata_buffer_; 187} 188 189LocalChannelHandle DisplaySurfaceClient::CreateVideoMeshSurface() { 190 auto status = InvokeRemoteMethod<DisplayRPC::CreateVideoMeshSurface>(); 191 if (!status) { 192 ALOGE( 193 "DisplaySurfaceClient::CreateVideoMeshSurface: Failed to create " 194 "video mesh surface: %s", 195 status.GetErrorMessage().c_str()); 196 } 197 return status.take(); 198} 199 200DisplayClient::DisplayClient(int* error) 201 : BASE(pdx::default_transport::ClientChannelFactory::Create( 202 DisplayRPC::kClientPath), 203 kInfiniteTimeout) { 204 if (error) 205 *error = Client::error(); 206} 207 208int DisplayClient::GetDisplayMetrics(SystemDisplayMetrics* metrics) { 209 auto status = InvokeRemoteMethod<DisplayRPC::GetMetrics>(); 210 if (!status) { 211 ALOGE("DisplayClient::GetDisplayMetrics: Failed to get metrics: %s", 212 status.GetErrorMessage().c_str()); 213 return -status.error(); 214 } 215 216 *metrics = status.get(); 217 return 0; 218} 219 220pdx::Status<void> DisplayClient::SetViewerParams(const ViewerParams& viewer_params) { 221 auto status = InvokeRemoteMethod<DisplayRPC::SetViewerParams>(viewer_params); 222 if (!status) { 223 ALOGE("DisplayClient::SetViewerParams: Failed to set viewer params: %s", 224 status.GetErrorMessage().c_str()); 225 } 226 return status; 227} 228 229int DisplayClient::GetLastFrameEdsTransform(LateLatchOutput* ll_out) { 230 auto status = InvokeRemoteMethod<DisplayRPC::GetEdsCapture>(); 231 if (!status) { 232 ALOGE( 233 "DisplayClient::GetLastFrameLateLatch: Failed to get most recent late" 234 " latch: %s", 235 status.GetErrorMessage().c_str()); 236 return -status.error(); 237 } 238 239 if (status.get().size() != sizeof(LateLatchOutput)) { 240 ALOGE( 241 "DisplayClient::GetLastFrameLateLatch: Error expected to receive %zu " 242 "bytes but received %zu", 243 sizeof(LateLatchOutput), status.get().size()); 244 return -EIO; 245 } 246 247 *ll_out = *reinterpret_cast<const LateLatchOutput*>(status.get().data()); 248 return 0; 249} 250 251int DisplayClient::EnterVrMode() { 252 auto status = InvokeRemoteMethod<DisplayRPC::EnterVrMode>(); 253 if (!status) { 254 ALOGE( 255 "DisplayClient::EnterVrMode: Failed to set display service to Vr mode"); 256 return -status.error(); 257 } 258 259 return 0; 260} 261 262int DisplayClient::ExitVrMode() { 263 auto status = InvokeRemoteMethod<DisplayRPC::ExitVrMode>(); 264 if (!status) { 265 ALOGE( 266 "DisplayClient::ExitVrMode: Failed to revert display service from Vr " 267 "mode"); 268 return -status.error(); 269 } 270 271 return 0; 272} 273 274std::unique_ptr<DisplaySurfaceClient> DisplayClient::CreateDisplaySurface( 275 int width, int height, int format, int usage, int flags) { 276 return DisplaySurfaceClient::Create(width, height, format, usage, flags); 277} 278 279} // namespace dvr 280} // namespace android 281