1 /*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "impl/vr_hwc.h"
17
18 #include "android-base/stringprintf.h"
19 #include <binder/IServiceManager.h>
20 #include <cutils/properties.h>
21 #include <private/dvr/display_client.h>
22 #include <ui/Fence.h>
23 #include <utils/Trace.h>
24
25 #include <mutex>
26
27 #include "vr_composer_client.h"
28
29 using namespace android::hardware::graphics::common::V1_0;
30 using namespace android::hardware::graphics::composer::V2_1;
31
32 using android::base::StringPrintf;
33 using android::hardware::hidl_handle;
34 using android::hardware::hidl_string;
35 using android::hardware::hidl_vec;
36 using android::hardware::Return;
37 using android::hardware::Void;
38
39 namespace android {
40 namespace dvr {
41 namespace {
42
43 using android::hardware::graphics::common::V1_0::PixelFormat;
44
45 const Display kDefaultDisplayId = 1;
46 const Config kDefaultConfigId = 1;
47
CreateGraphicBuffer(const native_handle_t * handle,const IVrComposerClient::BufferMetadata & metadata)48 sp<GraphicBuffer> CreateGraphicBuffer(
49 const native_handle_t* handle,
50 const IVrComposerClient::BufferMetadata& metadata) {
51 sp<GraphicBuffer> buffer = new GraphicBuffer(
52 handle, GraphicBuffer::CLONE_HANDLE, metadata.width, metadata.height,
53 static_cast<int32_t>(metadata.format), metadata.layerCount,
54 metadata.usage, metadata.stride);
55 if (buffer->initCheck() != OK) {
56 ALOGE("Failed to create graphic buffer");
57 return nullptr;
58 }
59
60 return buffer;
61 }
62
GetPrimaryDisplaySize(int32_t * width,int32_t * height)63 void GetPrimaryDisplaySize(int32_t* width, int32_t* height) {
64 *width = 1080;
65 *height = 1920;
66
67 int error = 0;
68 auto display_client = display::DisplayClient::Create(&error);
69 if (!display_client) {
70 ALOGE("Could not connect to display service : %s(%d)", strerror(error),
71 error);
72 return;
73 }
74
75 auto status = display_client->GetDisplayMetrics();
76 if (!status) {
77 ALOGE("Could not get display metrics from display service : %s(%d)",
78 status.GetErrorMessage().c_str(), status.error());
79 return;
80 }
81
82 *width = status.get().display_width;
83 *height = status.get().display_height;
84 }
85
86 } // namespace
87
HwcDisplay(int32_t width,int32_t height)88 HwcDisplay::HwcDisplay(int32_t width, int32_t height)
89 : width_(width), height_(height) {}
90
~HwcDisplay()91 HwcDisplay::~HwcDisplay() {}
92
SetClientTarget(const native_handle_t * handle,base::unique_fd fence)93 bool HwcDisplay::SetClientTarget(const native_handle_t* handle,
94 base::unique_fd fence) {
95 if (handle)
96 buffer_ = CreateGraphicBuffer(handle, buffer_metadata_);
97
98 fence_ = new Fence(fence.release());
99 return true;
100 }
101
SetClientTargetMetadata(const IVrComposerClient::BufferMetadata & metadata)102 void HwcDisplay::SetClientTargetMetadata(
103 const IVrComposerClient::BufferMetadata& metadata) {
104 buffer_metadata_ = metadata;
105 }
106
CreateLayer()107 HwcLayer* HwcDisplay::CreateLayer() {
108 uint64_t layer_id = layer_ids_++;
109 layers_.push_back(HwcLayer(layer_id));
110 return &layers_.back();
111 }
112
GetLayer(Layer id)113 HwcLayer* HwcDisplay::GetLayer(Layer id) {
114 for (size_t i = 0; i < layers_.size(); ++i)
115 if (layers_[i].info.id == id)
116 return &layers_[i];
117
118 return nullptr;
119 }
120
DestroyLayer(Layer id)121 bool HwcDisplay::DestroyLayer(Layer id) {
122 for (auto it = layers_.begin(); it != layers_.end(); ++it) {
123 if (it->info.id == id) {
124 layers_.erase(it);
125 return true;
126 }
127 }
128
129 return false;
130 }
131
GetChangedCompositionTypes(std::vector<Layer> * layer_ids,std::vector<IComposerClient::Composition> * types)132 void HwcDisplay::GetChangedCompositionTypes(
133 std::vector<Layer>* layer_ids,
134 std::vector<IComposerClient::Composition>* types) {
135 std::sort(layers_.begin(), layers_.end(),
136 [](const auto& lhs, const auto& rhs) {
137 return lhs.info.z_order < rhs.info.z_order;
138 });
139
140 const size_t no_layer = std::numeric_limits<size_t>::max();
141 size_t first_client_layer = no_layer, last_client_layer = no_layer;
142 for (size_t i = 0; i < layers_.size(); ++i) {
143 switch (layers_[i].composition_type) {
144 case IComposerClient::Composition::SOLID_COLOR:
145 case IComposerClient::Composition::CURSOR:
146 case IComposerClient::Composition::SIDEBAND:
147 if (first_client_layer == no_layer)
148 first_client_layer = i;
149
150 last_client_layer = i;
151 break;
152 default:
153 break;
154 }
155 }
156
157 for (size_t i = 0; i < layers_.size(); ++i) {
158 if (i >= first_client_layer && i <= last_client_layer) {
159 if (layers_[i].composition_type != IComposerClient::Composition::CLIENT) {
160 layer_ids->push_back(layers_[i].info.id);
161 types->push_back(IComposerClient::Composition::CLIENT);
162 layers_[i].composition_type = IComposerClient::Composition::CLIENT;
163 }
164
165 continue;
166 }
167
168 if (layers_[i].composition_type != IComposerClient::Composition::DEVICE) {
169 layer_ids->push_back(layers_[i].info.id);
170 types->push_back(IComposerClient::Composition::DEVICE);
171 layers_[i].composition_type = IComposerClient::Composition::DEVICE;
172 }
173 }
174 }
175
GetFrame(std::vector<ComposerView::ComposerLayer> * out_frames)176 Error HwcDisplay::GetFrame(
177 std::vector<ComposerView::ComposerLayer>* out_frames) {
178 bool queued_client_target = false;
179 std::vector<ComposerView::ComposerLayer> frame;
180 for (const auto& layer : layers_) {
181 if (layer.composition_type == IComposerClient::Composition::CLIENT) {
182 if (queued_client_target)
183 continue;
184
185 if (!buffer_.get()) {
186 ALOGE("Client composition requested but no client target buffer");
187 return Error::BAD_LAYER;
188 }
189
190 ComposerView::ComposerLayer client_target_layer = {
191 .buffer = buffer_,
192 .fence = fence_.get() ? fence_ : new Fence(-1),
193 .display_frame = {0, 0, static_cast<int32_t>(buffer_->getWidth()),
194 static_cast<int32_t>(buffer_->getHeight())},
195 .crop = {0.0f, 0.0f, static_cast<float>(buffer_->getWidth()),
196 static_cast<float>(buffer_->getHeight())},
197 .blend_mode = IComposerClient::BlendMode::NONE,
198 };
199
200 frame.push_back(client_target_layer);
201 queued_client_target = true;
202 } else {
203 if (!layer.info.buffer.get() || !layer.info.fence.get()) {
204 ALOGV("Layer requested without valid buffer");
205 continue;
206 }
207
208 frame.push_back(layer.info);
209 }
210 }
211
212 out_frames->swap(frame);
213 return Error::NONE;
214 }
215
UpdateLastFrameAndGetLastFrameLayers()216 std::vector<Layer> HwcDisplay::UpdateLastFrameAndGetLastFrameLayers() {
217 std::vector<Layer> last_frame_layers;
218 last_frame_layers.swap(last_frame_layers_ids_);
219
220 for (const auto& layer : layers_)
221 last_frame_layers_ids_.push_back(layer.info.id);
222
223 return last_frame_layers;
224 }
225
SetColorTransform(const float * matrix,int32_t hint)226 void HwcDisplay::SetColorTransform(const float* matrix, int32_t hint) {
227 color_transform_hint_ = hint;
228 if (matrix)
229 memcpy(color_transform_, matrix, sizeof(color_transform_));
230 }
231
dumpDebugInfo(std::string * result) const232 void HwcDisplay::dumpDebugInfo(std::string* result) const {
233 if (!result) {
234 return;
235 }
236 *result += StringPrintf("HwcDisplay: width: %d, height: %d, layers size: %zu, colormode: %d\
237 , config: %d\n", width_, height_, layers_.size(), color_mode_, active_config_);
238 *result += StringPrintf("HwcDisplay buffer metadata: width: %d, height: %d, stride: %d,\
239 layerCount: %d, pixelFormat: %d\n", buffer_metadata_.width, buffer_metadata_.height,
240 buffer_metadata_.stride, buffer_metadata_.layerCount, buffer_metadata_.format);
241 for (const auto& layer : layers_) {
242 layer.dumpDebugInfo(result);
243 }
244 }
245
246 ////////////////////////////////////////////////////////////////////////////////
247 // VrHwcClient
248
VrHwc()249 VrHwc::VrHwc() {
250 vsync_callback_ = new VsyncCallback;
251 }
252
~VrHwc()253 VrHwc::~VrHwc() {
254 vsync_callback_->SetEventCallback(nullptr);
255 }
256
hasCapability(hwc2_capability_t)257 bool VrHwc::hasCapability(hwc2_capability_t /* capability */) { return false; }
258
registerEventCallback(EventCallback * callback)259 void VrHwc::registerEventCallback(EventCallback* callback) {
260 std::unique_lock<std::mutex> lock(mutex_);
261 event_callback_ = callback;
262 int32_t width, height;
263 GetPrimaryDisplaySize(&width, &height);
264 // Create the primary display late to avoid initialization issues between
265 // VR HWC and SurfaceFlinger.
266 displays_[kDefaultDisplayId].reset(new HwcDisplay(width, height));
267
268 // Surface flinger will make calls back into vr_hwc when it receives the
269 // onHotplug() call, so it's important to release mutex_ here.
270 lock.unlock();
271 event_callback_->onHotplug(kDefaultDisplayId,
272 IComposerCallback::Connection::CONNECTED);
273 lock.lock();
274 UpdateVsyncCallbackEnabledLocked();
275 }
276
unregisterEventCallback()277 void VrHwc::unregisterEventCallback() {
278 std::lock_guard<std::mutex> guard(mutex_);
279 event_callback_ = nullptr;
280 UpdateVsyncCallbackEnabledLocked();
281 }
282
getMaxVirtualDisplayCount()283 uint32_t VrHwc::getMaxVirtualDisplayCount() { return 1; }
284
createVirtualDisplay(uint32_t width,uint32_t height,PixelFormat * format,Display * outDisplay)285 Error VrHwc::createVirtualDisplay(uint32_t width, uint32_t height,
286 PixelFormat* format, Display* outDisplay) {
287 *format = PixelFormat::RGBA_8888;
288 *outDisplay = display_count_;
289 displays_[display_count_].reset(new HwcDisplay(width, height));
290 display_count_++;
291 return Error::NONE;
292 }
293
destroyVirtualDisplay(Display display)294 Error VrHwc::destroyVirtualDisplay(Display display) {
295 std::lock_guard<std::mutex> guard(mutex_);
296 if (display == kDefaultDisplayId || displays_.erase(display) == 0)
297 return Error::BAD_DISPLAY;
298 ComposerView::Frame frame;
299 frame.display_id = display;
300 frame.removed = true;
301 if (observer_)
302 observer_->OnNewFrame(frame);
303 return Error::NONE;
304 }
305
createLayer(Display display,Layer * outLayer)306 Error VrHwc::createLayer(Display display, Layer* outLayer) {
307 std::lock_guard<std::mutex> guard(mutex_);
308 auto display_ptr = FindDisplay(display);
309 if (!display_ptr)
310 return Error::BAD_DISPLAY;
311
312 HwcLayer* layer = display_ptr->CreateLayer();
313 *outLayer = layer->info.id;
314 return Error::NONE;
315 }
316
destroyLayer(Display display,Layer layer)317 Error VrHwc::destroyLayer(Display display, Layer layer) {
318 std::lock_guard<std::mutex> guard(mutex_);
319 auto display_ptr = FindDisplay(display);
320 if (!display_ptr) {
321 return Error::BAD_DISPLAY;
322 }
323
324 return display_ptr->DestroyLayer(layer) ? Error::NONE : Error::BAD_LAYER;
325 }
326
getActiveConfig(Display display,Config * outConfig)327 Error VrHwc::getActiveConfig(Display display, Config* outConfig) {
328 std::lock_guard<std::mutex> guard(mutex_);
329 if (!FindDisplay(display))
330 return Error::BAD_DISPLAY;
331 *outConfig = kDefaultConfigId;
332 return Error::NONE;
333 }
334
getClientTargetSupport(Display display,uint32_t,uint32_t,PixelFormat,Dataspace)335 Error VrHwc::getClientTargetSupport(Display display, uint32_t /* width */,
336 uint32_t /* height */,
337 PixelFormat /* format */,
338 Dataspace /* dataspace */) {
339 std::lock_guard<std::mutex> guard(mutex_);
340 if (!FindDisplay(display))
341 return Error::BAD_DISPLAY;
342
343 return Error::NONE;
344 }
345
getColorModes(Display,hidl_vec<ColorMode> * outModes)346 Error VrHwc::getColorModes(Display /* display */,
347 hidl_vec<ColorMode>* outModes) {
348 std::vector<ColorMode> color_modes(1, ColorMode::NATIVE);
349 *outModes = hidl_vec<ColorMode>(color_modes);
350 return Error::NONE;
351 }
352
getDisplayAttribute(Display display,Config config,IComposerClient::Attribute attribute,int32_t * outValue)353 Error VrHwc::getDisplayAttribute(Display display, Config config,
354 IComposerClient::Attribute attribute,
355 int32_t* outValue) {
356 std::lock_guard<std::mutex> guard(mutex_);
357 auto display_ptr = FindDisplay(display);
358 if (!display_ptr) {
359 return Error::BAD_DISPLAY;
360 }
361 if (config != kDefaultConfigId) {
362 return Error::BAD_CONFIG;
363 }
364
365 switch (attribute) {
366 case IComposerClient::Attribute::WIDTH:
367 *outValue = display_ptr->width();
368 break;
369 case IComposerClient::Attribute::HEIGHT:
370 *outValue = display_ptr->height();
371 break;
372 case IComposerClient::Attribute::VSYNC_PERIOD:
373 {
374 int error = 0;
375 auto display_client = display::DisplayClient::Create(&error);
376 if (!display_client) {
377 ALOGE("Could not connect to display service : %s(%d)",
378 strerror(error), error);
379 // Return a default value of 30 fps
380 *outValue = 1000 * 1000 * 1000 / 30;
381 } else {
382 auto metrics = display_client->GetDisplayMetrics();
383 *outValue = metrics.get().vsync_period_ns;
384 }
385 }
386 break;
387 case IComposerClient::Attribute::DPI_X:
388 case IComposerClient::Attribute::DPI_Y:
389 {
390 constexpr int32_t kDefaultDPI = 300;
391 int32_t dpi = property_get_int32("ro.vr.hwc.dpi", kDefaultDPI);
392 if (dpi <= 0) {
393 dpi = kDefaultDPI;
394 }
395 *outValue = 1000 * dpi;
396 }
397 break;
398 default:
399 return Error::BAD_PARAMETER;
400 }
401
402 return Error::NONE;
403 }
404
getDisplayConfigs(Display display,hidl_vec<Config> * outConfigs)405 Error VrHwc::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) {
406 std::lock_guard<std::mutex> guard(mutex_);
407 if (!FindDisplay(display))
408 return Error::BAD_DISPLAY;
409 std::vector<Config> configs(1, kDefaultConfigId);
410 *outConfigs = hidl_vec<Config>(configs);
411 return Error::NONE;
412 }
413
getDisplayName(Display,hidl_string * outName)414 Error VrHwc::getDisplayName(Display /* display */, hidl_string* outName) {
415 *outName = hidl_string();
416 return Error::NONE;
417 }
418
getDisplayType(Display display,IComposerClient::DisplayType * outType)419 Error VrHwc::getDisplayType(Display display,
420 IComposerClient::DisplayType* outType) {
421 std::lock_guard<std::mutex> guard(mutex_);
422 auto display_ptr = FindDisplay(display);
423 if (!display_ptr) {
424 *outType = IComposerClient::DisplayType::INVALID;
425 return Error::BAD_DISPLAY;
426 }
427
428 if (display == kDefaultDisplayId)
429 *outType = IComposerClient::DisplayType::PHYSICAL;
430 else
431 *outType = IComposerClient::DisplayType::VIRTUAL;
432
433 return Error::NONE;
434 }
435
getDozeSupport(Display display,bool * outSupport)436 Error VrHwc::getDozeSupport(Display display, bool* outSupport) {
437 *outSupport = false;
438 std::lock_guard<std::mutex> guard(mutex_);
439 if (!FindDisplay(display))
440 return Error::BAD_DISPLAY;
441 return Error::NONE;
442 }
443
getHdrCapabilities(Display,hidl_vec<Hdr> *,float * outMaxLuminance,float * outMaxAverageLuminance,float * outMinLuminance)444 Error VrHwc::getHdrCapabilities(Display /* display */,
445 hidl_vec<Hdr>* /* outTypes */,
446 float* outMaxLuminance,
447 float* outMaxAverageLuminance,
448 float* outMinLuminance) {
449 *outMaxLuminance = 0;
450 *outMaxAverageLuminance = 0;
451 *outMinLuminance = 0;
452 return Error::NONE;
453 }
454
setActiveConfig(Display display,Config config)455 Error VrHwc::setActiveConfig(Display display, Config config) {
456 std::lock_guard<std::mutex> guard(mutex_);
457 auto display_ptr = FindDisplay(display);
458 if (!display_ptr)
459 return Error::BAD_DISPLAY;
460 if (config != kDefaultConfigId)
461 return Error::BAD_CONFIG;
462
463 display_ptr->set_active_config(config);
464 return Error::NONE;
465 }
466
setColorMode(Display display,ColorMode mode)467 Error VrHwc::setColorMode(Display display, ColorMode mode) {
468 std::lock_guard<std::mutex> guard(mutex_);
469 auto display_ptr = FindDisplay(display);
470 if (!display_ptr)
471 return Error::BAD_DISPLAY;
472
473 if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_P3)
474 return Error::BAD_PARAMETER;
475
476 display_ptr->set_color_mode(mode);
477 return Error::NONE;
478 }
479
setPowerMode(Display display,IComposerClient::PowerMode mode)480 Error VrHwc::setPowerMode(Display display, IComposerClient::PowerMode mode) {
481 bool dozeSupported = false;
482
483 Error dozeSupportError = getDozeSupport(display, &dozeSupported);
484
485 if (dozeSupportError != Error::NONE)
486 return dozeSupportError;
487
488 std::lock_guard<std::mutex> guard(mutex_);
489 auto display_ptr = FindDisplay(display);
490 if (!display_ptr)
491 return Error::BAD_DISPLAY;
492
493 if (mode < IComposerClient::PowerMode::OFF ||
494 mode > IComposerClient::PowerMode::DOZE_SUSPEND) {
495 return Error::BAD_PARAMETER;
496 }
497
498 if (!dozeSupported &&
499 (mode == IComposerClient::PowerMode::DOZE ||
500 mode == IComposerClient::PowerMode::DOZE_SUSPEND)) {
501 return Error::UNSUPPORTED;
502 }
503
504 display_ptr->set_power_mode(mode);
505 return Error::NONE;
506 }
507
setVsyncEnabled(Display display,IComposerClient::Vsync enabled)508 Error VrHwc::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) {
509 std::lock_guard<std::mutex> guard(mutex_);
510 auto display_ptr = FindDisplay(display);
511 if (!display_ptr)
512 return Error::BAD_DISPLAY;
513
514 if (enabled != IComposerClient::Vsync::ENABLE &&
515 enabled != IComposerClient::Vsync::DISABLE) {
516 return Error::BAD_PARAMETER;
517 }
518
519 Error set_vsync_result = Error::NONE;
520 if (display == kDefaultDisplayId) {
521 sp<IVsyncService> vsync_service = interface_cast<IVsyncService>(
522 defaultServiceManager()->getService(
523 String16(IVsyncService::GetServiceName())));
524 if (vsync_service == nullptr) {
525 ALOGE("Failed to get vsync service");
526 return Error::NO_RESOURCES;
527 }
528
529 if (enabled == IComposerClient::Vsync::ENABLE) {
530 ALOGI("Enable vsync");
531 display_ptr->set_vsync_enabled(true);
532 status_t result = vsync_service->registerCallback(vsync_callback_);
533 if (result != OK) {
534 ALOGE("%s service registerCallback() failed: %s (%d)",
535 IVsyncService::GetServiceName(), strerror(-result), result);
536 set_vsync_result = Error::NO_RESOURCES;
537 }
538 } else if (enabled == IComposerClient::Vsync::DISABLE) {
539 ALOGI("Disable vsync");
540 display_ptr->set_vsync_enabled(false);
541 status_t result = vsync_service->unregisterCallback(vsync_callback_);
542 if (result != OK) {
543 ALOGE("%s service unregisterCallback() failed: %s (%d)",
544 IVsyncService::GetServiceName(), strerror(-result), result);
545 set_vsync_result = Error::NO_RESOURCES;
546 }
547 }
548
549 UpdateVsyncCallbackEnabledLocked();
550 }
551
552 return set_vsync_result;
553 }
554
setColorTransform(Display display,const float * matrix,int32_t hint)555 Error VrHwc::setColorTransform(Display display, const float* matrix,
556 int32_t hint) {
557 std::lock_guard<std::mutex> guard(mutex_);
558 auto display_ptr = FindDisplay(display);
559 if (!display_ptr)
560 return Error::BAD_DISPLAY;
561
562 display_ptr->SetColorTransform(matrix, hint);
563 return Error::NONE;
564 }
565
setClientTarget(Display display,buffer_handle_t target,int32_t acquireFence,int32_t,const std::vector<hwc_rect_t> &)566 Error VrHwc::setClientTarget(Display display, buffer_handle_t target,
567 int32_t acquireFence, int32_t /* dataspace */,
568 const std::vector<hwc_rect_t>& /* damage */) {
569 base::unique_fd fence(acquireFence);
570 std::lock_guard<std::mutex> guard(mutex_);
571 auto display_ptr = FindDisplay(display);
572 if (!display_ptr)
573 return Error::BAD_DISPLAY;
574
575 if (target == nullptr)
576 return Error::NONE;
577
578 if (!display_ptr->SetClientTarget(target, std::move(fence)))
579 return Error::BAD_PARAMETER;
580
581 return Error::NONE;
582 }
583
setOutputBuffer(Display display,buffer_handle_t,int32_t releaseFence)584 Error VrHwc::setOutputBuffer(Display display, buffer_handle_t /* buffer */,
585 int32_t releaseFence) {
586 base::unique_fd fence(releaseFence);
587 std::lock_guard<std::mutex> guard(mutex_);
588 auto display_ptr = FindDisplay(display);
589 if (!display_ptr)
590 return Error::BAD_DISPLAY;
591
592 // TODO(dnicoara): Is it necessary to do anything here?
593 return Error::NONE;
594 }
595
validateDisplay(Display display,std::vector<Layer> * outChangedLayers,std::vector<IComposerClient::Composition> * outCompositionTypes,uint32_t *,std::vector<Layer> *,std::vector<uint32_t> *)596 Error VrHwc::validateDisplay(
597 Display display, std::vector<Layer>* outChangedLayers,
598 std::vector<IComposerClient::Composition>* outCompositionTypes,
599 uint32_t* /* outDisplayRequestMask */,
600 std::vector<Layer>* /* outRequestedLayers */,
601 std::vector<uint32_t>* /* outRequestMasks */) {
602 std::lock_guard<std::mutex> guard(mutex_);
603 auto display_ptr = FindDisplay(display);
604 if (!display_ptr)
605 return Error::BAD_DISPLAY;
606
607 display_ptr->GetChangedCompositionTypes(outChangedLayers,
608 outCompositionTypes);
609 return Error::NONE;
610 }
611
acceptDisplayChanges(Display)612 Error VrHwc::acceptDisplayChanges(Display /* display */) { return Error::NONE; }
613
presentDisplay(Display display,int32_t * outPresentFence,std::vector<Layer> * outLayers,std::vector<int32_t> * outReleaseFences)614 Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence,
615 std::vector<Layer>* outLayers,
616 std::vector<int32_t>* outReleaseFences) {
617 *outPresentFence = -1;
618 outLayers->clear();
619 outReleaseFences->clear();
620
621 std::lock_guard<std::mutex> guard(mutex_);
622 auto display_ptr = FindDisplay(display);
623
624 if (!display_ptr)
625 return Error::BAD_DISPLAY;
626
627 ComposerView::Frame frame;
628 std::vector<Layer> last_frame_layers;
629 Error status = display_ptr->GetFrame(&frame.layers);
630 frame.display_id = display;
631 frame.display_width = display_ptr->width();
632 frame.display_height = display_ptr->height();
633 frame.active_config = display_ptr->active_config();
634 frame.power_mode = display_ptr->power_mode();
635 frame.vsync_enabled = display_ptr->vsync_enabled() ?
636 IComposerClient::Vsync::ENABLE : IComposerClient::Vsync::DISABLE;
637 frame.color_transform_hint = display_ptr->color_transform_hint();
638 frame.color_mode = display_ptr->color_mode();
639 memcpy(frame.color_transform, display_ptr->color_transform(),
640 sizeof(frame.color_transform));
641 if (status != Error::NONE)
642 return status;
643
644 last_frame_layers = display_ptr->UpdateLastFrameAndGetLastFrameLayers();
645
646 base::unique_fd fence;
647 if (observer_)
648 fence = observer_->OnNewFrame(frame);
649
650 if (fence.get() < 0)
651 return Error::NONE;
652
653 *outPresentFence = dup(fence.get());
654 outLayers->swap(last_frame_layers);
655 for (size_t i = 0; i < outLayers->size(); ++i)
656 outReleaseFences->push_back(dup(fence.get()));
657
658 return Error::NONE;
659 }
660
setLayerCursorPosition(Display display,Layer layer,int32_t x,int32_t y)661 Error VrHwc::setLayerCursorPosition(Display display, Layer layer, int32_t x,
662 int32_t y) {
663 std::lock_guard<std::mutex> guard(mutex_);
664 auto display_ptr = FindDisplay(display);
665 if (!display_ptr)
666 return Error::BAD_DISPLAY;
667
668 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
669 if (!hwc_layer)
670 return Error::BAD_LAYER;
671
672 hwc_layer->info.cursor_x = x;
673 hwc_layer->info.cursor_y = y;
674 return Error::NONE;
675 }
676
setLayerBuffer(Display display,Layer layer,buffer_handle_t buffer,int32_t acquireFence)677 Error VrHwc::setLayerBuffer(Display display, Layer layer,
678 buffer_handle_t buffer, int32_t acquireFence) {
679 base::unique_fd fence(acquireFence);
680 std::lock_guard<std::mutex> guard(mutex_);
681 auto display_ptr = FindDisplay(display);
682 if (!display_ptr)
683 return Error::BAD_DISPLAY;
684
685 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
686 if (!hwc_layer)
687 return Error::BAD_LAYER;
688
689 hwc_layer->info.buffer = CreateGraphicBuffer(
690 buffer, hwc_layer->buffer_metadata);
691 hwc_layer->info.fence = new Fence(fence.release());
692
693 return Error::NONE;
694 }
695
setLayerSurfaceDamage(Display display,Layer layer,const std::vector<hwc_rect_t> & damage)696 Error VrHwc::setLayerSurfaceDamage(Display display, Layer layer,
697 const std::vector<hwc_rect_t>& damage) {
698 std::lock_guard<std::mutex> guard(mutex_);
699 auto display_ptr = FindDisplay(display);
700 if (!display_ptr)
701 return Error::BAD_DISPLAY;
702
703 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
704 if (!hwc_layer)
705 return Error::BAD_LAYER;
706
707 hwc_layer->info.damaged_regions = damage;
708 return Error::NONE;
709 }
710
setLayerBlendMode(Display display,Layer layer,int32_t mode)711 Error VrHwc::setLayerBlendMode(Display display, Layer layer, int32_t mode) {
712 std::lock_guard<std::mutex> guard(mutex_);
713 auto display_ptr = FindDisplay(display);
714 if (!display_ptr)
715 return Error::BAD_DISPLAY;
716
717 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
718 if (!hwc_layer)
719 return Error::BAD_LAYER;
720
721 hwc_layer->info.blend_mode =
722 static_cast<ComposerView::ComposerLayer::BlendMode>(mode);
723
724 return Error::NONE;
725 }
726
setLayerColor(Display display,Layer layer,IComposerClient::Color color)727 Error VrHwc::setLayerColor(Display display, Layer layer,
728 IComposerClient::Color color) {
729 std::lock_guard<std::mutex> guard(mutex_);
730 auto display_ptr = FindDisplay(display);
731 if (!display_ptr)
732 return Error::BAD_DISPLAY;
733
734 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
735 if (!hwc_layer)
736 return Error::BAD_LAYER;
737
738 hwc_layer->info.color = color;
739 return Error::NONE;
740 }
741
setLayerCompositionType(Display display,Layer layer,int32_t type)742 Error VrHwc::setLayerCompositionType(Display display, Layer layer,
743 int32_t type) {
744 std::lock_guard<std::mutex> guard(mutex_);
745 auto display_ptr = FindDisplay(display);
746 if (!display_ptr)
747 return Error::BAD_DISPLAY;
748
749 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
750 if (!hwc_layer)
751 return Error::BAD_LAYER;
752
753 hwc_layer->composition_type = static_cast<HwcLayer::Composition>(type);
754
755 return Error::NONE;
756 }
757
setLayerDataspace(Display display,Layer layer,int32_t dataspace)758 Error VrHwc::setLayerDataspace(Display display, Layer layer,
759 int32_t dataspace) {
760 std::lock_guard<std::mutex> guard(mutex_);
761 auto display_ptr = FindDisplay(display);
762 if (!display_ptr)
763 return Error::BAD_DISPLAY;
764
765 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
766 if (!hwc_layer)
767 return Error::BAD_LAYER;
768
769 hwc_layer->info.dataspace = dataspace;
770 return Error::NONE;
771 }
772
setLayerDisplayFrame(Display display,Layer layer,const hwc_rect_t & frame)773 Error VrHwc::setLayerDisplayFrame(Display display, Layer layer,
774 const hwc_rect_t& frame) {
775 std::lock_guard<std::mutex> guard(mutex_);
776 auto display_ptr = FindDisplay(display);
777 if (!display_ptr)
778 return Error::BAD_DISPLAY;
779
780 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
781 if (!hwc_layer)
782 return Error::BAD_LAYER;
783
784 hwc_layer->info.display_frame =
785 {frame.left, frame.top, frame.right, frame.bottom};
786
787 return Error::NONE;
788 }
789
setLayerPlaneAlpha(Display display,Layer layer,float alpha)790 Error VrHwc::setLayerPlaneAlpha(Display display, Layer layer, float alpha) {
791 std::lock_guard<std::mutex> guard(mutex_);
792 auto display_ptr = FindDisplay(display);
793 if (!display_ptr)
794 return Error::BAD_DISPLAY;
795
796 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
797 if (!hwc_layer)
798 return Error::BAD_LAYER;
799
800 hwc_layer->info.alpha = alpha;
801
802 return Error::NONE;
803 }
804
setLayerSidebandStream(Display display,Layer,buffer_handle_t)805 Error VrHwc::setLayerSidebandStream(Display display, Layer /* layer */,
806 buffer_handle_t /* stream */) {
807 std::lock_guard<std::mutex> guard(mutex_);
808 if (!FindDisplay(display))
809 return Error::BAD_DISPLAY;
810 return Error::NONE;
811 }
812
setLayerSourceCrop(Display display,Layer layer,const hwc_frect_t & crop)813 Error VrHwc::setLayerSourceCrop(Display display, Layer layer,
814 const hwc_frect_t& crop) {
815 std::lock_guard<std::mutex> guard(mutex_);
816 auto display_ptr = FindDisplay(display);
817 if (!display_ptr)
818 return Error::BAD_DISPLAY;
819
820 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
821 if (!hwc_layer)
822 return Error::BAD_LAYER;
823
824 hwc_layer->info.crop = {crop.left, crop.top, crop.right, crop.bottom};
825
826 return Error::NONE;
827 }
828
setLayerTransform(Display display,Layer layer,int32_t transform)829 Error VrHwc::setLayerTransform(Display display, Layer layer,
830 int32_t transform) {
831 std::lock_guard<std::mutex> guard(mutex_);
832 auto display_ptr = FindDisplay(display);
833 if (!display_ptr)
834 return Error::BAD_DISPLAY;
835
836 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
837 if (!hwc_layer)
838 return Error::BAD_LAYER;
839
840 hwc_layer->info.transform = transform;
841 return Error::NONE;
842 }
843
setLayerVisibleRegion(Display display,Layer layer,const std::vector<hwc_rect_t> & visible)844 Error VrHwc::setLayerVisibleRegion(Display display, Layer layer,
845 const std::vector<hwc_rect_t>& visible) {
846 std::lock_guard<std::mutex> guard(mutex_);
847 auto display_ptr = FindDisplay(display);
848 if (!display_ptr)
849 return Error::BAD_DISPLAY;
850
851 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
852 if (!hwc_layer)
853 return Error::BAD_LAYER;
854
855 hwc_layer->info.visible_regions = visible;
856 return Error::NONE;
857 }
858
setLayerZOrder(Display display,Layer layer,uint32_t z)859 Error VrHwc::setLayerZOrder(Display display, Layer layer, uint32_t z) {
860 std::lock_guard<std::mutex> guard(mutex_);
861 auto display_ptr = FindDisplay(display);
862 if (!display_ptr)
863 return Error::BAD_DISPLAY;
864
865 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
866 if (!hwc_layer)
867 return Error::BAD_LAYER;
868
869 hwc_layer->info.z_order = z;
870
871 return Error::NONE;
872 }
873
setLayerInfo(Display display,Layer layer,uint32_t type,uint32_t appId)874 Error VrHwc::setLayerInfo(Display display, Layer layer, uint32_t type,
875 uint32_t appId) {
876 std::lock_guard<std::mutex> guard(mutex_);
877 auto display_ptr = FindDisplay(display);
878 if (!display_ptr)
879 return Error::BAD_DISPLAY;
880
881 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
882 if (!hwc_layer)
883 return Error::BAD_LAYER;
884
885 hwc_layer->info.type = type;
886 hwc_layer->info.app_id = appId;
887
888 return Error::NONE;
889 }
890
setClientTargetMetadata(Display display,const IVrComposerClient::BufferMetadata & metadata)891 Error VrHwc::setClientTargetMetadata(
892 Display display, const IVrComposerClient::BufferMetadata& metadata) {
893 std::lock_guard<std::mutex> guard(mutex_);
894 auto display_ptr = FindDisplay(display);
895 if (!display_ptr)
896 return Error::BAD_DISPLAY;
897
898 display_ptr->SetClientTargetMetadata(metadata);
899
900 return Error::NONE;
901 }
902
setLayerBufferMetadata(Display display,Layer layer,const IVrComposerClient::BufferMetadata & metadata)903 Error VrHwc::setLayerBufferMetadata(
904 Display display, Layer layer,
905 const IVrComposerClient::BufferMetadata& metadata) {
906 std::lock_guard<std::mutex> guard(mutex_);
907 auto display_ptr = FindDisplay(display);
908 if (!display_ptr)
909 return Error::BAD_DISPLAY;
910
911 HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
912 if (!hwc_layer)
913 return Error::BAD_LAYER;
914
915 hwc_layer->buffer_metadata = metadata;
916
917 return Error::NONE;
918 }
919
getCapabilities(getCapabilities_cb hidl_cb)920 Return<void> VrHwc::getCapabilities(getCapabilities_cb hidl_cb) {
921 hidl_cb(hidl_vec<Capability>());
922 return Void();
923 }
924
dumpDebugInfo(dumpDebugInfo_cb hidl_cb)925 Return<void> VrHwc::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
926 std::string result;
927
928 {
929 std::lock_guard<std::mutex> guard(mutex_);
930 result = "\nVrHwc states:\n";
931 for (const auto& pair : displays_) {
932 result += StringPrintf("Display id: %lu\n", (unsigned long)pair.first);
933 pair.second->dumpDebugInfo(&result);
934 }
935 result += "\n";
936 }
937
938 hidl_cb(hidl_string(result));
939 return Void();
940 }
941
createClient(createClient_cb hidl_cb)942 Return<void> VrHwc::createClient(createClient_cb hidl_cb) {
943 std::lock_guard<std::mutex> guard(mutex_);
944
945 Error status = Error::NONE;
946 sp<VrComposerClient> client;
947 if (!client_.promote().get()) {
948 client = new VrComposerClient(*this);
949 } else {
950 ALOGE("Already have a client");
951 status = Error::NO_RESOURCES;
952 }
953
954 client_ = client;
955 hidl_cb(status, client);
956 return Void();
957 }
958
ForceDisplaysRefresh()959 void VrHwc::ForceDisplaysRefresh() {
960 std::lock_guard<std::mutex> guard(mutex_);
961 if (event_callback_ != nullptr) {
962 for (const auto& pair : displays_)
963 event_callback_->onRefresh(pair.first);
964 }
965 }
966
RegisterObserver(Observer * observer)967 void VrHwc::RegisterObserver(Observer* observer) {
968 std::lock_guard<std::mutex> guard(mutex_);
969 if (observer_)
970 ALOGE("Overwriting observer");
971 else
972 observer_ = observer;
973 }
974
UnregisterObserver(Observer * observer)975 void VrHwc::UnregisterObserver(Observer* observer) {
976 std::lock_guard<std::mutex> guard(mutex_);
977 if (observer != observer_)
978 ALOGE("Trying to unregister unknown observer");
979 else
980 observer_ = nullptr;
981 }
982
FindDisplay(Display display)983 HwcDisplay* VrHwc::FindDisplay(Display display) {
984 auto iter = displays_.find(display);
985 return iter == displays_.end() ? nullptr : iter->second.get();
986 }
987
UpdateVsyncCallbackEnabledLocked()988 void VrHwc::UpdateVsyncCallbackEnabledLocked() {
989 auto primary_display = FindDisplay(kDefaultDisplayId);
990 LOG_ALWAYS_FATAL_IF(event_callback_ != nullptr && primary_display == nullptr,
991 "Should have created the primary display by now");
992 bool send_vsync =
993 event_callback_ != nullptr && primary_display->vsync_enabled();
994 vsync_callback_->SetEventCallback(send_vsync ? event_callback_ : nullptr);
995 }
996
dumpDebugInfo(std::string * result) const997 void HwcLayer::dumpDebugInfo(std::string* result) const {
998 if (!result) {
999 return;
1000 }
1001 *result += StringPrintf("Layer: composition_type: %d, type: %d, app_id: %d, z_order: %d,\
1002 cursor_x: %d, cursor_y: %d, color(rgba): (%d,%d,%d,%d), dataspace: %d, transform: %d,\
1003 display_frame(LTRB): (%d,%d,%d,%d), crop(LTRB): (%.1f,%.1f,%.1f,%.1f), blend_mode: %d\n",
1004 composition_type, info.type, info.app_id, info.z_order, info.cursor_x, info.cursor_y,
1005 info.color.r, info.color.g, info.color.b, info.color.a, info.dataspace, info.transform,
1006 info.display_frame.left, info.display_frame.top, info.display_frame.right,
1007 info.display_frame.bottom, info.crop.left, info.crop.top, info.crop.right,
1008 info.crop.bottom, info.blend_mode);
1009 *result += StringPrintf("Layer buffer metadata: width: %d, height: %d, stride: %d, layerCount: %d\
1010 , pixelFormat: %d\n", buffer_metadata.width, buffer_metadata.height, buffer_metadata.stride,
1011 buffer_metadata.layerCount, buffer_metadata.format);
1012 }
1013
onVsync(int64_t vsync_timestamp)1014 status_t VrHwc::VsyncCallback::onVsync(int64_t vsync_timestamp) {
1015 ATRACE_NAME("vr_hwc onVsync");
1016 std::lock_guard<std::mutex> guard(mutex_);
1017 if (callback_ != nullptr)
1018 callback_->onVsync(kDefaultDisplayId, vsync_timestamp);
1019 return OK;
1020 }
1021
SetEventCallback(EventCallback * callback)1022 void VrHwc::VsyncCallback::SetEventCallback(EventCallback* callback) {
1023 std::lock_guard<std::mutex> guard(mutex_);
1024 callback_ = callback;
1025 }
1026
1027 } // namespace dvr
1028 } // namespace android
1029