blob: 9952e59480c55e0720884e2d185be3900dd54492 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include "include/private/dvr/display_client.h"
2
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08003#include <cutils/native_handle.h>
Alex Vakulenko4fe60582017-02-02 11:35:59 -08004#include <log/log.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08005#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
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -0800151std::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",
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800159 status.GetErrorMessage().c_str());
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -0800160 return nullptr;
161 }
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800162
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -0800163 producer_queue_ =
164 ProducerQueue::Import<DisplaySurfaceMetadata>(status.take());
165 }
166 return producer_queue_;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800167}
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
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800251std::unique_ptr<DisplaySurfaceClient> DisplayClient::CreateDisplaySurface(
252 int width, int height, int format, int usage, int flags) {
253 return DisplaySurfaceClient::Create(width, height, format, usage, flags);
254}
255
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700256std::unique_ptr<BufferConsumer> DisplayClient::GetPoseBuffer() {
257 auto status = InvokeRemoteMethod<DisplayRPC::GetPoseBuffer>();
258 if (!status) {
259 ALOGE(
260 "DisplayClient::GetPoseBuffer: Failed to get pose buffer %s",
261 status.GetErrorMessage().c_str());
262 return nullptr;
263 }
264
265 return BufferConsumer::Import(std::move(status));
266}
267
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400268bool DisplayClient::IsVrAppRunning() {
269 auto status = InvokeRemoteMethod<DisplayRPC::IsVrAppRunning>();
270 if (!status)
271 return 0;
272 return static_cast<bool>(status.get());
273}
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700274
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800275} // namespace dvr
276} // namespace android