blob: 54098e8a197fd540f644c430023395e43f3bf2a0 [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
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