display_client.cpp revision 4fe60582f314e381098f8f3bc2e39c5880e9243a
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<BufferProducer> DisplaySurfaceClient::AllocateBuffer(
152    uint32_t* buffer_index) {
153  auto status = InvokeRemoteMethod<DisplayRPC::AllocateBuffer>();
154  if (!status) {
155    ALOGE("DisplaySurfaceClient::AllocateBuffer: Failed to allocate buffer: %s",
156          status.GetErrorMessage().c_str());
157    return nullptr;
158  }
159
160  if (buffer_index)
161    *buffer_index = status.get().first;
162  return BufferProducer::Import(status.take().second);
163}
164
165volatile DisplaySurfaceMetadata* DisplaySurfaceClient::GetMetadataBufferPtr() {
166  if (!mapped_metadata_buffer_) {
167    if (auto buffer_producer = GetMetadataBuffer()) {
168      void* addr = nullptr;
169      const int ret = buffer_producer->GetBlobReadWritePointer(
170          sizeof(DisplaySurfaceMetadata), &addr);
171      if (ret < 0) {
172        ALOGE(
173            "DisplaySurfaceClient::GetMetadataBufferPtr: Failed to map surface "
174            "metadata: %s",
175            strerror(-ret));
176        return nullptr;
177      }
178      mapped_metadata_buffer_ = static_cast<DisplaySurfaceMetadata*>(addr);
179    }
180  }
181
182  return mapped_metadata_buffer_;
183}
184
185LocalChannelHandle DisplaySurfaceClient::CreateVideoMeshSurface() {
186  auto status = InvokeRemoteMethod<DisplayRPC::CreateVideoMeshSurface>();
187  if (!status) {
188    ALOGE(
189        "DisplaySurfaceClient::CreateVideoMeshSurface: Failed to create "
190        "video mesh surface: %s",
191        status.GetErrorMessage().c_str());
192  }
193  return status.take();
194}
195
196DisplayClient::DisplayClient(int* error)
197    : BASE(pdx::default_transport::ClientChannelFactory::Create(
198               DisplayRPC::kClientPath),
199           kInfiniteTimeout) {
200  if (error)
201    *error = Client::error();
202}
203
204int DisplayClient::GetDisplayMetrics(SystemDisplayMetrics* metrics) {
205  auto status = InvokeRemoteMethod<DisplayRPC::GetMetrics>();
206  if (!status) {
207    ALOGE("DisplayClient::GetDisplayMetrics: Failed to get metrics: %s",
208          status.GetErrorMessage().c_str());
209    return -status.error();
210  }
211
212  *metrics = status.get();
213  return 0;
214}
215
216pdx::Status<void> DisplayClient::SetViewerParams(const ViewerParams& viewer_params) {
217  auto status = InvokeRemoteMethod<DisplayRPC::SetViewerParams>(viewer_params);
218  if (!status) {
219    ALOGE("DisplayClient::SetViewerParams: Failed to set viewer params: %s",
220          status.GetErrorMessage().c_str());
221  }
222  return status;
223}
224
225int DisplayClient::GetLastFrameEdsTransform(LateLatchOutput* ll_out) {
226  auto status = InvokeRemoteMethod<DisplayRPC::GetEdsCapture>();
227  if (!status) {
228    ALOGE(
229        "DisplayClient::GetLastFrameLateLatch: Failed to get most recent late"
230        " latch: %s",
231        status.GetErrorMessage().c_str());
232    return -status.error();
233  }
234
235  if (status.get().size() != sizeof(LateLatchOutput)) {
236    ALOGE(
237        "DisplayClient::GetLastFrameLateLatch: Error expected to receive %zu "
238        "bytes but received %zu",
239        sizeof(LateLatchOutput), status.get().size());
240    return -EIO;
241  }
242
243  *ll_out = *reinterpret_cast<const LateLatchOutput*>(status.get().data());
244  return 0;
245}
246
247int DisplayClient::EnterVrMode() {
248  auto status = InvokeRemoteMethod<DisplayRPC::EnterVrMode>();
249  if (!status) {
250    ALOGE(
251        "DisplayClient::EnterVrMode: Failed to set display service to Vr mode");
252    return -status.error();
253  }
254
255  return 0;
256}
257
258int DisplayClient::ExitVrMode() {
259  auto status = InvokeRemoteMethod<DisplayRPC::ExitVrMode>();
260  if (!status) {
261    ALOGE(
262        "DisplayClient::ExitVrMode: Failed to revert display service from Vr "
263        "mode");
264    return -status.error();
265  }
266
267  return 0;
268}
269
270std::unique_ptr<DisplaySurfaceClient> DisplayClient::CreateDisplaySurface(
271    int width, int height, int format, int usage, int flags) {
272  return DisplaySurfaceClient::Create(width, height, format, usage, flags);
273}
274
275}  // namespace dvr
276}  // namespace android
277