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 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 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 88 HwcDisplay::HwcDisplay(int32_t width, int32_t height) 89 : width_(width), height_(height) {} 90 91 HwcDisplay::~HwcDisplay() {} 92 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 102 void HwcDisplay::SetClientTargetMetadata( 103 const IVrComposerClient::BufferMetadata& metadata) { 104 buffer_metadata_ = metadata; 105 } 106 107 HwcLayer* HwcDisplay::CreateLayer() { 108 uint64_t layer_id = layer_ids_++; 109 layers_.push_back(HwcLayer(layer_id)); 110 return &layers_.back(); 111 } 112 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 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 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 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 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 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 232 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 249 VrHwc::VrHwc() { 250 vsync_callback_ = new VsyncCallback; 251 } 252 253 VrHwc::~VrHwc() { 254 vsync_callback_->SetEventCallback(nullptr); 255 } 256 257 bool VrHwc::hasCapability(hwc2_capability_t /* capability */) { return false; } 258 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 277 void VrHwc::unregisterEventCallback() { 278 std::lock_guard<std::mutex> guard(mutex_); 279 event_callback_ = nullptr; 280 UpdateVsyncCallbackEnabledLocked(); 281 } 282 283 uint32_t VrHwc::getMaxVirtualDisplayCount() { return 1; } 284 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 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 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 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 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 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 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 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 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 414 Error VrHwc::getDisplayName(Display /* display */, hidl_string* outName) { 415 *outName = hidl_string(); 416 return Error::NONE; 417 } 418 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 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 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 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 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 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 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 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 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 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 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 612 Error VrHwc::acceptDisplayChanges(Display /* display */) { return Error::NONE; } 613 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 920 Return<void> VrHwc::getCapabilities(getCapabilities_cb hidl_cb) { 921 hidl_cb(hidl_vec<Capability>()); 922 return Void(); 923 } 924 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 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 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 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 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 983 HwcDisplay* VrHwc::FindDisplay(Display display) { 984 auto iter = displays_.find(display); 985 return iter == displays_.end() ? nullptr : iter->second.get(); 986 } 987 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 997 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 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 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