blob: 6d39cdb8c5ee3d6ca5351bf16de863876fdc7885 [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
Corey Tabaka1db8a5d2017-03-22 02:12:52 -0700163 producer_queue_ = ProducerQueue::Import(status.take());
Jiwen 'Steve' Caia3613612017-03-08 17:41:48 -0800164 }
165 return producer_queue_;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800166}
167
168volatile DisplaySurfaceMetadata* DisplaySurfaceClient::GetMetadataBufferPtr() {
169 if (!mapped_metadata_buffer_) {
170 if (auto buffer_producer = GetMetadataBuffer()) {
171 void* addr = nullptr;
172 const int ret = buffer_producer->GetBlobReadWritePointer(
173 sizeof(DisplaySurfaceMetadata), &addr);
174 if (ret < 0) {
175 ALOGE(
176 "DisplaySurfaceClient::GetMetadataBufferPtr: Failed to map surface "
177 "metadata: %s",
178 strerror(-ret));
179 return nullptr;
180 }
181 mapped_metadata_buffer_ = static_cast<DisplaySurfaceMetadata*>(addr);
182 }
183 }
184
185 return mapped_metadata_buffer_;
186}
187
188LocalChannelHandle DisplaySurfaceClient::CreateVideoMeshSurface() {
189 auto status = InvokeRemoteMethod<DisplayRPC::CreateVideoMeshSurface>();
190 if (!status) {
191 ALOGE(
192 "DisplaySurfaceClient::CreateVideoMeshSurface: Failed to create "
193 "video mesh surface: %s",
194 status.GetErrorMessage().c_str());
195 }
196 return status.take();
197}
198
199DisplayClient::DisplayClient(int* error)
200 : BASE(pdx::default_transport::ClientChannelFactory::Create(
201 DisplayRPC::kClientPath),
202 kInfiniteTimeout) {
203 if (error)
204 *error = Client::error();
205}
206
207int DisplayClient::GetDisplayMetrics(SystemDisplayMetrics* metrics) {
208 auto status = InvokeRemoteMethod<DisplayRPC::GetMetrics>();
209 if (!status) {
210 ALOGE("DisplayClient::GetDisplayMetrics: Failed to get metrics: %s",
211 status.GetErrorMessage().c_str());
212 return -status.error();
213 }
214
215 *metrics = status.get();
216 return 0;
217}
218
219pdx::Status<void> DisplayClient::SetViewerParams(const ViewerParams& viewer_params) {
220 auto status = InvokeRemoteMethod<DisplayRPC::SetViewerParams>(viewer_params);
221 if (!status) {
222 ALOGE("DisplayClient::SetViewerParams: Failed to set viewer params: %s",
223 status.GetErrorMessage().c_str());
224 }
225 return status;
226}
227
228int DisplayClient::GetLastFrameEdsTransform(LateLatchOutput* ll_out) {
229 auto status = InvokeRemoteMethod<DisplayRPC::GetEdsCapture>();
230 if (!status) {
231 ALOGE(
232 "DisplayClient::GetLastFrameLateLatch: Failed to get most recent late"
233 " latch: %s",
234 status.GetErrorMessage().c_str());
235 return -status.error();
236 }
237
238 if (status.get().size() != sizeof(LateLatchOutput)) {
239 ALOGE(
240 "DisplayClient::GetLastFrameLateLatch: Error expected to receive %zu "
241 "bytes but received %zu",
242 sizeof(LateLatchOutput), status.get().size());
243 return -EIO;
244 }
245
246 *ll_out = *reinterpret_cast<const LateLatchOutput*>(status.get().data());
247 return 0;
248}
249
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800250std::unique_ptr<DisplaySurfaceClient> DisplayClient::CreateDisplaySurface(
251 int width, int height, int format, int usage, int flags) {
252 return DisplaySurfaceClient::Create(width, height, format, usage, flags);
253}
254
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700255std::unique_ptr<BufferConsumer> DisplayClient::GetPoseBuffer() {
256 auto status = InvokeRemoteMethod<DisplayRPC::GetPoseBuffer>();
257 if (!status) {
258 ALOGE(
259 "DisplayClient::GetPoseBuffer: Failed to get pose buffer %s",
260 status.GetErrorMessage().c_str());
261 return nullptr;
262 }
263
264 return BufferConsumer::Import(std::move(status));
265}
266
Albert Chaulkb7c8a4b2017-03-20 13:03:39 -0400267bool DisplayClient::IsVrAppRunning() {
268 auto status = InvokeRemoteMethod<DisplayRPC::IsVrAppRunning>();
269 if (!status)
270 return 0;
271 return static_cast<bool>(status.get());
272}
Hendrik Wagenaar10e68eb2017-03-15 13:29:02 -0700273
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800274} // namespace dvr
275} // namespace android