display_client.cpp revision 10e68eb8aa4db8b6f8cfbf2c3754e2677d7bf848
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
279std::unique_ptr<BufferConsumer> DisplayClient::GetPoseBuffer() {
280  auto status = InvokeRemoteMethod<DisplayRPC::GetPoseBuffer>();
281  if (!status) {
282    ALOGE(
283        "DisplayClient::GetPoseBuffer: Failed to get pose buffer %s",
284        status.GetErrorMessage().c_str());
285    return nullptr;
286  }
287
288  return BufferConsumer::Import(std::move(status));
289}
290
291
292}  // namespace dvr
293}  // namespace android
294