diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-08-23 07:31:24 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-08-23 07:31:24 +0000 |
commit | fbfda3ae5c4d92b799c7fc621f1ab805e6560af5 (patch) | |
tree | 5f78eeca0ef448297762e0cf9e3b84fe93e25557 | |
parent | cd64cfb0559d57cd6c9ce9d0901060650013ec1f (diff) | |
parent | 9cc83934f92aab292f16213c1b716e8ecfcb5875 (diff) | |
download | drm_hwcomposer-fbfda3ae5c4d92b799c7fc621f1ab805e6560af5.tar.gz |
release-request-cff6d9b6-a564-4d17-99cb-c2d0bb282758-for-git_oc-mr1-release-4293817 snap-temp-L12800000095933585
Change-Id: I3c611a9442c57e060fc0ae2a63c5762b7c6e2b63
-rw-r--r-- | Android.mk | 7 | ||||
-rw-r--r-- | drmdisplaycomposition.cpp | 8 | ||||
-rw-r--r-- | drmdisplaycompositor.cpp | 8 | ||||
-rw-r--r-- | drmeventlistener.cpp | 2 | ||||
-rw-r--r-- | drmhwcomposer.h | 6 | ||||
-rw-r--r-- | drmhwctwo.cpp | 1088 | ||||
-rw-r--r-- | drmhwctwo.h | 271 | ||||
-rw-r--r-- | drmresources.cpp | 5 | ||||
-rw-r--r-- | drmresources.h | 11 | ||||
-rw-r--r-- | glworker.cpp | 16 | ||||
-rw-r--r-- | glworker.h | 3 | ||||
-rw-r--r-- | hwcomposer.cpp | 170 | ||||
-rw-r--r-- | hwcutils.cpp | 199 | ||||
-rw-r--r-- | platform.h | 4 | ||||
-rw-r--r-- | platformdrmgeneric.cpp | 17 | ||||
-rw-r--r-- | platformdrmgeneric.h | 1 | ||||
-rw-r--r-- | platformnv.cpp | 11 | ||||
-rw-r--r-- | platformnv.h | 1 | ||||
-rw-r--r-- | vsyncworker.cpp | 18 | ||||
-rw-r--r-- | vsyncworker.h | 15 |
20 files changed, 187 insertions, 1674 deletions
@@ -64,21 +64,16 @@ LOCAL_SRC_FILES := \ drmdisplaycompositor.cpp \ drmencoder.cpp \ drmeventlistener.cpp \ - drmhwctwo.cpp \ drmmode.cpp \ drmplane.cpp \ drmproperty.cpp \ glworker.cpp \ - hwcutils.cpp \ + hwcomposer.cpp \ platform.cpp \ separate_rects.cpp \ virtualcompositorworker.cpp \ vsyncworker.cpp -LOCAL_CPPFLAGS += \ - -DHWC2_USE_CPP11 \ - -DHWC2_INCLUDE_STRINGIFICATION - ifeq ($(strip $(BOARD_DRM_HWCOMPOSER_BUFFER_IMPORTER)),nvidia-gralloc) LOCAL_CPPFLAGS += -DUSE_NVIDIA_IMPORTER LOCAL_SRC_FILES += platformnv.cpp diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp index 293160b..949f4a3 100644 --- a/drmdisplaycomposition.cpp +++ b/drmdisplaycomposition.cpp @@ -258,10 +258,8 @@ int DrmDisplayComposition::CreateAndAssignReleaseFences() { if (!layer->release_fence) continue; int ret = layer->release_fence.Set(CreateNextTimelineFence()); - if (ret < 0) { - ALOGE("Failed to set the release fence (squash) %d", ret); + if (ret < 0) return ret; - } } timeline_squash_done_ = timeline_; @@ -278,10 +276,8 @@ int DrmDisplayComposition::CreateAndAssignReleaseFences() { if (!layer->release_fence) continue; int ret = layer->release_fence.Set(CreateNextTimelineFence()); - if (ret < 0) { - ALOGE("Failed to set the release fence (comp) %d", ret); + if (ret < 0) return ret; - } } return 0; diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp index 642a1c7..3d27f13 100644 --- a/drmdisplaycompositor.cpp +++ b/drmdisplaycompositor.cpp @@ -375,8 +375,7 @@ int DrmDisplayCompositor::ApplySquash(DrmDisplayComposition *display_comp) { std::vector<DrmCompositionRegion> ®ions = display_comp->squash_regions(); ret = pre_compositor_->Composite(display_comp->layers().data(), - regions.data(), regions.size(), fb.buffer(), - display_comp->importer()); + regions.data(), regions.size(), fb.buffer()); pre_compositor_->Finish(); if (ret) { @@ -409,8 +408,7 @@ int DrmDisplayCompositor::ApplyPreComposite( std::vector<DrmCompositionRegion> ®ions = display_comp->pre_comp_regions(); ret = pre_compositor_->Composite(display_comp->layers().data(), - regions.data(), regions.size(), fb.buffer(), - display_comp->importer()); + regions.data(), regions.size(), fb.buffer()); pre_compositor_->Finish(); if (ret) { @@ -628,8 +626,6 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp, if (ret) ALOGW("Acquire fence %d wait %d failed (%d). Total time %d", acquire_fence, i, ret, total_fence_timeout); - else - break; } if (ret) { ALOGE("Failed to wait for acquire %d/%d", acquire_fence, ret); diff --git a/drmeventlistener.cpp b/drmeventlistener.cpp index 7a21980..a07bd89 100644 --- a/drmeventlistener.cpp +++ b/drmeventlistener.cpp @@ -126,7 +126,7 @@ void DrmEventListener::Routine() { if (FD_ISSET(drm_->fd(), &fds_)) { drmEventContext event_context = { - .version = 2, + .version = DRM_EVENT_CONTEXT_VERSION, .vblank_handler = NULL, .page_flip_handler = DrmEventListener::FlipHandler}; drmHandleEvent(drm_->fd(), &event_context); diff --git a/drmhwcomposer.h b/drmhwcomposer.h index f8440fb..d087873 100644 --- a/drmhwcomposer.h +++ b/drmhwcomposer.h @@ -144,17 +144,13 @@ struct DrmHwcLayer { uint8_t alpha = 0xff; DrmHwcRect<float> source_crop; DrmHwcRect<int> display_frame; + std::vector<DrmHwcRect<int>> source_damage; UniqueFd acquire_fence; OutputFd release_fence; int InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer, const gralloc_module_t *gralloc); - int ImportBuffer(Importer *importer, const gralloc_module_t *gralloc); - - void SetTransform(int32_t sf_transform); - void SetSourceCrop(hwc_frect_t const &crop); - void SetDisplayFrame(hwc_rect_t const &frame); buffer_handle_t get_usable_handle() const { return handle.get() != NULL ? handle.get() : sf_handle; diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp deleted file mode 100644 index 8c853f4..0000000 --- a/drmhwctwo.cpp +++ /dev/null @@ -1,1088 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define ATRACE_TAG ATRACE_TAG_GRAPHICS -#define LOG_TAG "hwc-drm-two" - -#include "drmdisplaycomposition.h" -#include "drmhwcomposer.h" -#include "drmhwctwo.h" -#include "platform.h" -#include "vsyncworker.h" - -#include <inttypes.h> -#include <string> - -#include <cutils/log.h> -#include <cutils/properties.h> -#include <hardware/hardware.h> -#include <hardware/hwcomposer2.h> - -namespace android { - -class DrmVsyncCallback : public VsyncCallback { - public: - DrmVsyncCallback(hwc2_callback_data_t data, hwc2_function_pointer_t hook) - : data_(data), hook_(hook) { - } - - void Callback(int display, int64_t timestamp) { - auto hook = reinterpret_cast<HWC2_PFN_VSYNC>(hook_); - hook(data_, display, timestamp); - } - - private: - hwc2_callback_data_t data_; - hwc2_function_pointer_t hook_; -}; - -DrmHwcTwo::DrmHwcTwo() { - common.tag = HARDWARE_DEVICE_TAG; - common.version = HWC_DEVICE_API_VERSION_2_0; - common.close = HookDevClose; - getCapabilities = HookDevGetCapabilities; - getFunction = HookDevGetFunction; -} - -HWC2::Error DrmHwcTwo::Init() { - int ret = drm_.Init(); - if (ret) { - ALOGE("Can't initialize drm object %d", ret); - return HWC2::Error::NoResources; - } - - importer_.reset(Importer::CreateInstance(&drm_)); - if (!importer_) { - ALOGE("Failed to create importer instance"); - return HWC2::Error::NoResources; - } - - ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, - (const hw_module_t **)&gralloc_); - if (ret) { - ALOGE("Failed to open gralloc module %d", ret); - return HWC2::Error::NoResources; - } - - displays_.emplace(std::piecewise_construct, - std::forward_as_tuple(HWC_DISPLAY_PRIMARY), - std::forward_as_tuple(&drm_, importer_, gralloc_, - HWC_DISPLAY_PRIMARY, - HWC2::DisplayType::Physical)); - - DrmCrtc *crtc = drm_.GetCrtcForDisplay(static_cast<int>(HWC_DISPLAY_PRIMARY)); - if (!crtc) { - ALOGE("Failed to get crtc for display %d", - static_cast<int>(HWC_DISPLAY_PRIMARY)); - return HWC2::Error::BadDisplay; - } - - std::vector<DrmPlane *> display_planes; - for (auto &plane : drm_.planes()) { - if (plane->GetCrtcSupported(*crtc)) - display_planes.push_back(plane.get()); - } - displays_.at(HWC_DISPLAY_PRIMARY).Init(&display_planes); - return HWC2::Error::None; -} - -template <typename... Args> -static inline HWC2::Error unsupported(char const *func, Args... /*args*/) { - ALOGV("Unsupported function: %s", func); - return HWC2::Error::Unsupported; -} - -static inline void supported(char const *func) { - ALOGV("Supported function: %s", func); -} - -HWC2::Error DrmHwcTwo::CreateVirtualDisplay(uint32_t width, uint32_t height, - int32_t *format, - hwc2_display_t *display) { - // TODO: Implement virtual display - return unsupported(__func__, width, height, format, display); -} - -HWC2::Error DrmHwcTwo::DestroyVirtualDisplay(hwc2_display_t display) { - // TODO: Implement virtual display - return unsupported(__func__, display); -} - -void DrmHwcTwo::Dump(uint32_t *size, char *buffer) { - // TODO: Implement dump - unsupported(__func__, size, buffer); -} - -uint32_t DrmHwcTwo::GetMaxVirtualDisplayCount() { - // TODO: Implement virtual display - unsupported(__func__); - return 0; -} - -HWC2::Error DrmHwcTwo::RegisterCallback(int32_t descriptor, - hwc2_callback_data_t data, - hwc2_function_pointer_t function) { - supported(__func__); - auto callback = static_cast<HWC2::Callback>(descriptor); - callbacks_.emplace(callback, HwcCallback(data, function)); - - switch (callback) { - case HWC2::Callback::Hotplug: { - auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(function); - hotplug(data, HWC_DISPLAY_PRIMARY, - static_cast<int32_t>(HWC2::Connection::Connected)); - break; - } - case HWC2::Callback::Vsync: { - for (std::pair<const hwc2_display_t, DrmHwcTwo::HwcDisplay> &d : - displays_) - d.second.RegisterVsyncCallback(data, function); - break; - } - default: - break; - } - return HWC2::Error::None; -} - -DrmHwcTwo::HwcDisplay::HwcDisplay(DrmResources *drm, - std::shared_ptr<Importer> importer, - const gralloc_module_t *gralloc, - hwc2_display_t handle, HWC2::DisplayType type) - : drm_(drm), - importer_(importer), - gralloc_(gralloc), - handle_(handle), - type_(type) { - supported(__func__); -} - -HWC2::Error DrmHwcTwo::HwcDisplay::Init(std::vector<DrmPlane *> *planes) { - supported(__func__); - planner_ = Planner::CreateInstance(drm_); - if (!planner_) { - ALOGE("Failed to create planner instance for composition"); - return HWC2::Error::NoResources; - } - - int display = static_cast<int>(handle_); - int ret = compositor_.Init(drm_, display); - if (ret) { - ALOGE("Failed display compositor init for display %d (%d)", display, ret); - return HWC2::Error::NoResources; - } - - // Split up the given display planes into primary and overlay to properly - // interface with the composition - char use_overlay_planes_prop[PROPERTY_VALUE_MAX]; - property_get("hwc.drm.use_overlay_planes", use_overlay_planes_prop, "1"); - bool use_overlay_planes = atoi(use_overlay_planes_prop); - for (auto &plane : *planes) { - if (plane->type() == DRM_PLANE_TYPE_PRIMARY) - primary_planes_.push_back(plane); - else if (use_overlay_planes && (plane)->type() == DRM_PLANE_TYPE_OVERLAY) - overlay_planes_.push_back(plane); - } - - crtc_ = drm_->GetCrtcForDisplay(display); - if (!crtc_) { - ALOGE("Failed to get crtc for display %d", display); - return HWC2::Error::BadDisplay; - } - - connector_ = drm_->GetConnectorForDisplay(display); - if (!connector_) { - ALOGE("Failed to get connector for display %d", display); - return HWC2::Error::BadDisplay; - } - - // Fetch the number of modes from the display - uint32_t num_configs; - HWC2::Error err = GetDisplayConfigs(&num_configs, NULL); - if (err != HWC2::Error::None || !num_configs) - return err; - - // Grab the first mode, we'll choose this as the active mode - // TODO: Should choose the preferred mode here - hwc2_config_t default_config; - num_configs = 1; - err = GetDisplayConfigs(&num_configs, &default_config); - if (err != HWC2::Error::None) - return err; - - ret = vsync_worker_.Init(drm_, display); - if (ret) { - ALOGE("Failed to create event worker for d=%d %d\n", display, ret); - return HWC2::Error::BadDisplay; - } - - return SetActiveConfig(default_config); -} - -HWC2::Error DrmHwcTwo::HwcDisplay::RegisterVsyncCallback( - hwc2_callback_data_t data, hwc2_function_pointer_t func) { - supported(__func__); - auto callback = std::make_shared<DrmVsyncCallback>(data, func); - vsync_worker_.RegisterCallback(std::move(callback)); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::AcceptDisplayChanges() { - supported(__func__); - uint32_t num_changes = 0; - for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) - l.second.accept_type_change(); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::CreateLayer(hwc2_layer_t *layer) { - supported(__func__); - layers_.emplace(static_cast<hwc2_layer_t>(layer_idx_), HwcLayer()); - *layer = static_cast<hwc2_layer_t>(layer_idx_); - ++layer_idx_; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::DestroyLayer(hwc2_layer_t layer) { - supported(__func__); - layers_.erase(layer); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetActiveConfig(hwc2_config_t *config) { - supported(__func__); - DrmMode const &mode = connector_->active_mode(); - if (mode.id() == 0) - return HWC2::Error::BadConfig; - - *config = mode.id(); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetChangedCompositionTypes( - uint32_t *num_elements, hwc2_layer_t *layers, int32_t *types) { - supported(__func__); - uint32_t num_changes = 0; - for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { - if (l.second.type_changed()) { - if (layers && num_changes < *num_elements) - layers[num_changes] = l.first; - if (types && num_changes < *num_elements) - types[num_changes] = static_cast<int32_t>(l.second.validated_type()); - ++num_changes; - } - } - if (!layers && !types) - *num_elements = num_changes; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetClientTargetSupport(uint32_t width, - uint32_t height, - int32_t /*format*/, - int32_t dataspace) { - supported(__func__); - std::pair<uint32_t, uint32_t> min = drm_->min_resolution(); - std::pair<uint32_t, uint32_t> max = drm_->max_resolution(); - - if (width < min.first || height < min.second) - return HWC2::Error::Unsupported; - - if (width > max.first || height > max.second) - return HWC2::Error::Unsupported; - - if (dataspace != HAL_DATASPACE_UNKNOWN && - dataspace != HAL_DATASPACE_STANDARD_UNSPECIFIED) - return HWC2::Error::Unsupported; - - // TODO: Validate format can be handled by either GL or planes - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetColorModes(uint32_t *num_modes, - int32_t *modes) { - supported(__func__); - if (!modes) - *num_modes = 1; - - if (modes) - *modes = HAL_COLOR_MODE_NATIVE; - - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayAttribute(hwc2_config_t config, - int32_t attribute_in, - int32_t *value) { - supported(__func__); - auto mode = - std::find_if(connector_->modes().begin(), connector_->modes().end(), - [config](DrmMode const &m) { return m.id() == config; }); - if (mode == connector_->modes().end()) { - ALOGE("Could not find active mode for %d", config); - return HWC2::Error::BadConfig; - } - - static const int32_t kUmPerInch = 25400; - uint32_t mm_width = connector_->mm_width(); - uint32_t mm_height = connector_->mm_height(); - auto attribute = static_cast<HWC2::Attribute>(attribute_in); - switch (attribute) { - case HWC2::Attribute::Width: - *value = mode->h_display(); - break; - case HWC2::Attribute::Height: - *value = mode->v_display(); - break; - case HWC2::Attribute::VsyncPeriod: - // in nanoseconds - *value = 1000 * 1000 * 1000 / mode->v_refresh(); - break; - case HWC2::Attribute::DpiX: - // Dots per 1000 inches - *value = mm_width ? (mode->h_display() * kUmPerInch) / mm_width : -1; - break; - case HWC2::Attribute::DpiY: - // Dots per 1000 inches - *value = mm_height ? (mode->v_display() * kUmPerInch) / mm_height : -1; - break; - default: - *value = -1; - return HWC2::Error::BadConfig; - } - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayConfigs(uint32_t *num_configs, - hwc2_config_t *configs) { - supported(__func__); - // Since this callback is normally invoked twice (once to get the count, and - // once to populate configs), we don't really want to read the edid - // redundantly. Instead, only update the modes on the first invocation. While - // it's possible this will result in stale modes, it'll all come out in the - // wash when we try to set the active config later. - if (!configs) { - int ret = connector_->UpdateModes(); - if (ret) { - ALOGE("Failed to update display modes %d", ret); - return HWC2::Error::BadDisplay; - } - } - - auto num_modes = static_cast<uint32_t>(connector_->modes().size()); - if (!configs) { - *num_configs = num_modes; - return HWC2::Error::None; - } - - uint32_t idx = 0; - for (const DrmMode &mode : connector_->modes()) { - if (idx >= *num_configs) - break; - configs[idx++] = mode.id(); - } - *num_configs = idx; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayName(uint32_t *size, char *name) { - supported(__func__); - std::ostringstream stream; - stream << "display-" << connector_->id(); - std::string string = stream.str(); - size_t length = string.length(); - if (!name) { - *size = length; - return HWC2::Error::None; - } - - *size = std::min<uint32_t>(static_cast<uint32_t>(length - 1), *size); - strncpy(name, string.c_str(), *size); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayRequests(int32_t *display_requests, - uint32_t *num_elements, - hwc2_layer_t *layers, - int32_t *layer_requests) { - supported(__func__); - // TODO: I think virtual display should request - // HWC2_DISPLAY_REQUEST_WRITE_CLIENT_TARGET_TO_OUTPUT here - unsupported(__func__, display_requests, num_elements, layers, layer_requests); - *num_elements = 0; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetDisplayType(int32_t *type) { - supported(__func__); - *type = static_cast<int32_t>(type_); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetDozeSupport(int32_t *support) { - supported(__func__); - *support = 0; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetHdrCapabilities( - uint32_t *num_types, int32_t */*types*/, float */*max_luminance*/, - float */*max_average_luminance*/, float */*min_luminance*/) { - supported(__func__); - *num_types = 0; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::GetReleaseFences(uint32_t *num_elements, - hwc2_layer_t *layers, - int32_t *fences) { - supported(__func__); - uint32_t num_layers = 0; - - for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { - ++num_layers; - if (layers == NULL || fences == NULL) { - continue; - } else if (num_layers > *num_elements) { - ALOGW("Overflow num_elements %d/%d", num_layers, *num_elements); - return HWC2::Error::None; - } - - layers[num_layers - 1] = l.first; - fences[num_layers - 1] = l.second.take_release_fence(); - } - *num_elements = num_layers; - return HWC2::Error::None; -} - -void DrmHwcTwo::HwcDisplay::AddFenceToRetireFence(int fd) { - supported(__func__); - if (fd < 0) - return; - - if (next_retire_fence_.get() >= 0) { - int old_fence = next_retire_fence_.get(); - next_retire_fence_.Set(sync_merge("dc_retire", old_fence, fd)); - } else { - next_retire_fence_.Set(dup(fd)); - } -} - -HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { - supported(__func__); - std::vector<DrmCompositionDisplayLayersMap> layers_map; - layers_map.emplace_back(); - DrmCompositionDisplayLayersMap &map = layers_map.back(); - - map.display = static_cast<int>(handle_); - map.geometry_changed = true; // TODO: Fix this - - // order the layers by z-order - bool use_client_layer = false; - uint32_t client_z_order = 0; - std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map; - for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { - switch (l.second.validated_type()) { - case HWC2::Composition::Device: - z_map.emplace(std::make_pair(l.second.z_order(), &l.second)); - break; - case HWC2::Composition::Client: - // Place it at the z_order of the highest client layer - use_client_layer = true; - client_z_order = std::max(client_z_order, l.second.z_order()); - break; - default: - continue; - } - } - if (use_client_layer) - z_map.emplace(std::make_pair(client_z_order, &client_layer_)); - - // now that they're ordered by z, add them to the composition - for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) { - DrmHwcLayer layer; - l.second->PopulateDrmLayer(&layer); - int ret = layer.ImportBuffer(importer_.get(), gralloc_); - if (ret) { - ALOGE("Failed to import layer, ret=%d", ret); - return HWC2::Error::NoResources; - } - map.layers.emplace_back(std::move(layer)); - } - if (map.layers.empty()) { - *retire_fence = -1; - return HWC2::Error::None; - } - - std::unique_ptr<DrmDisplayComposition> composition = - compositor_.CreateComposition(); - composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); - - // TODO: Don't always assume geometry changed - int ret = composition->SetLayers(map.layers.data(), map.layers.size(), true); - if (ret) { - ALOGE("Failed to set layers in the composition ret=%d", ret); - return HWC2::Error::BadLayer; - } - - std::vector<DrmPlane *> primary_planes(primary_planes_); - std::vector<DrmPlane *> overlay_planes(overlay_planes_); - ret = composition->Plan(compositor_.squash_state(), &primary_planes, - &overlay_planes); - if (ret) { - ALOGE("Failed to plan the composition ret=%d", ret); - return HWC2::Error::BadConfig; - } - - // Disable the planes we're not using - for (auto i = primary_planes.begin(); i != primary_planes.end();) { - composition->AddPlaneDisable(*i); - i = primary_planes.erase(i); - } - for (auto i = overlay_planes.begin(); i != overlay_planes.end();) { - composition->AddPlaneDisable(*i); - i = overlay_planes.erase(i); - } - - ret = compositor_.QueueComposition(std::move(composition)); - if (ret) { - ALOGE("Failed to apply the frame composition ret=%d", ret); - return HWC2::Error::BadParameter; - } - - // Now that the release fences have been generated by the compositor, make - // sure they're managed properly - for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) { - l.second->manage_release_fence(); - AddFenceToRetireFence(l.second->release_fence()); - } - - // The retire fence returned here is for the last frame, so return it and - // promote the next retire fence - *retire_fence = retire_fence_.Release(); - retire_fence_ = std::move(next_retire_fence_); - - ++frame_no_; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::SetActiveConfig(hwc2_config_t config) { - supported(__func__); - auto mode = - std::find_if(connector_->modes().begin(), connector_->modes().end(), - [config](DrmMode const &m) { return m.id() == config; }); - if (mode == connector_->modes().end()) { - ALOGE("Could not find active mode for %d", config); - return HWC2::Error::BadConfig; - } - - std::unique_ptr<DrmDisplayComposition> composition = - compositor_.CreateComposition(); - composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); - int ret = composition->SetDisplayMode(*mode); - ret = compositor_.QueueComposition(std::move(composition)); - if (ret) { - ALOGE("Failed to queue dpms composition on %d", ret); - return HWC2::Error::BadConfig; - } - if (connector_->active_mode().id() == 0) - connector_->set_active_mode(*mode); - - // Setup the client layer's dimensions - hwc_rect_t display_frame = {.left = 0, - .top = 0, - .right = static_cast<int>(mode->h_display()), - .bottom = static_cast<int>(mode->v_display())}; - client_layer_.SetLayerDisplayFrame(display_frame); - hwc_frect_t source_crop = {.left = 0.0f, - .top = 0.0f, - .right = mode->h_display() + 0.0f, - .bottom = mode->v_display() + 0.0f}; - client_layer_.SetLayerSourceCrop(source_crop); - - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::SetClientTarget(buffer_handle_t target, - int32_t acquire_fence, - int32_t dataspace, - hwc_region_t damage) { - supported(__func__); - UniqueFd uf(acquire_fence); - - client_layer_.set_buffer(target); - client_layer_.set_acquire_fence(uf.get()); - client_layer_.SetLayerDataspace(dataspace); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::SetColorMode(int32_t mode) { - supported(__func__); - - if (mode != HAL_COLOR_MODE_NATIVE) - return HWC2::Error::Unsupported; - - color_mode_ = mode; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::SetColorTransform(const float *matrix, - int32_t hint) { - supported(__func__); - // TODO: Force client composition if we get this - return unsupported(__func__, matrix, hint); -} - -HWC2::Error DrmHwcTwo::HwcDisplay::SetOutputBuffer(buffer_handle_t buffer, - int32_t release_fence) { - supported(__func__); - // TODO: Need virtual display support - return unsupported(__func__, buffer, release_fence); -} - -HWC2::Error DrmHwcTwo::HwcDisplay::SetPowerMode(int32_t mode_in) { - supported(__func__); - uint64_t dpms_value = 0; - auto mode = static_cast<HWC2::PowerMode>(mode_in); - switch (mode) { - case HWC2::PowerMode::Off: - dpms_value = DRM_MODE_DPMS_OFF; - break; - case HWC2::PowerMode::On: - dpms_value = DRM_MODE_DPMS_ON; - break; - default: - ALOGI("Power mode %d is unsupported\n", mode); - return HWC2::Error::Unsupported; - }; - - std::unique_ptr<DrmDisplayComposition> composition = - compositor_.CreateComposition(); - composition->Init(drm_, crtc_, importer_.get(), planner_.get(), frame_no_); - composition->SetDpmsMode(dpms_value); - int ret = compositor_.QueueComposition(std::move(composition)); - if (ret) { - ALOGE("Failed to apply the dpms composition ret=%d", ret); - return HWC2::Error::BadParameter; - } - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) { - supported(__func__); - vsync_worker_.VSyncControl(enabled); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types, - uint32_t *num_requests) { - supported(__func__); - *num_types = 0; - *num_requests = 0; - for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { - DrmHwcTwo::HwcLayer &layer = l.second; - switch (layer.sf_type()) { - case HWC2::Composition::SolidColor: - case HWC2::Composition::Cursor: - case HWC2::Composition::Sideband: - layer.set_validated_type(HWC2::Composition::Client); - ++*num_types; - break; - default: - layer.set_validated_type(layer.sf_type()); - break; - } - } - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetCursorPosition(int32_t x, int32_t y) { - supported(__func__); - cursor_x_ = x; - cursor_y_ = y; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBlendMode(int32_t mode) { - supported(__func__); - blending_ = static_cast<HWC2::BlendMode>(mode); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerBuffer(buffer_handle_t buffer, - int32_t acquire_fence) { - supported(__func__); - UniqueFd uf(acquire_fence); - - // The buffer and acquire_fence are handled elsewhere - if (sf_type_ == HWC2::Composition::Client || - sf_type_ == HWC2::Composition::Sideband || - sf_type_ == HWC2::Composition::SolidColor) - return HWC2::Error::None; - - set_buffer(buffer); - set_acquire_fence(uf.get()); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerColor(hwc_color_t color) { - // TODO: Punt to client composition here? - return unsupported(__func__, color); -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerCompositionType(int32_t type) { - sf_type_ = static_cast<HWC2::Composition>(type); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDataspace(int32_t dataspace) { - supported(__func__); - dataspace_ = static_cast<android_dataspace_t>(dataspace); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerDisplayFrame(hwc_rect_t frame) { - supported(__func__); - display_frame_ = frame; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerPlaneAlpha(float alpha) { - supported(__func__); - alpha_ = alpha; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSidebandStream( - const native_handle_t *stream) { - supported(__func__); - // TODO: We don't support sideband - return unsupported(__func__, stream); -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSourceCrop(hwc_frect_t crop) { - supported(__func__); - source_crop_ = crop; - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerSurfaceDamage(hwc_region_t damage) { - supported(__func__); - // TODO: We don't use surface damage, marking as unsupported - unsupported(__func__, damage); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerTransform(int32_t transform) { - supported(__func__); - transform_ = static_cast<HWC2::Transform>(transform); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerVisibleRegion(hwc_region_t visible) { - supported(__func__); - // TODO: We don't use this information, marking as unsupported - unsupported(__func__, visible); - return HWC2::Error::None; -} - -HWC2::Error DrmHwcTwo::HwcLayer::SetLayerZOrder(uint32_t order) { - supported(__func__); - z_order_ = order; - return HWC2::Error::None; -} - -void DrmHwcTwo::HwcLayer::PopulateDrmLayer(DrmHwcLayer *layer) { - supported(__func__); - switch (blending_) { - case HWC2::BlendMode::None: - layer->blending = DrmHwcBlending::kNone; - break; - case HWC2::BlendMode::Premultiplied: - layer->blending = DrmHwcBlending::kPreMult; - break; - case HWC2::BlendMode::Coverage: - layer->blending = DrmHwcBlending::kCoverage; - break; - default: - ALOGE("Unknown blending mode b=%d", blending_); - layer->blending = DrmHwcBlending::kNone; - break; - } - - OutputFd release_fence = release_fence_output(); - - layer->sf_handle = buffer_; - layer->acquire_fence = acquire_fence_.Release(); - layer->release_fence = std::move(release_fence); - layer->SetDisplayFrame(display_frame_); - layer->alpha = static_cast<uint8_t>(255.0f * alpha_ + 0.5f); - layer->SetSourceCrop(source_crop_); - layer->SetTransform(static_cast<int32_t>(transform_)); -} - -// static -int DrmHwcTwo::HookDevClose(hw_device_t * /*dev*/) { - unsupported(__func__); - return 0; -} - -// static -void DrmHwcTwo::HookDevGetCapabilities(hwc2_device_t * /*dev*/, - uint32_t *out_count, - int32_t * /*out_capabilities*/) { - supported(__func__); - *out_count = 0; -} - -// static -hwc2_function_pointer_t DrmHwcTwo::HookDevGetFunction( - struct hwc2_device * /*dev*/, int32_t descriptor) { - supported(__func__); - auto func = static_cast<HWC2::FunctionDescriptor>(descriptor); - switch (func) { - // Device functions - case HWC2::FunctionDescriptor::CreateVirtualDisplay: - return ToHook<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>( - DeviceHook<int32_t, decltype(&DrmHwcTwo::CreateVirtualDisplay), - &DrmHwcTwo::CreateVirtualDisplay, uint32_t, uint32_t, - int32_t*, hwc2_display_t *>); - case HWC2::FunctionDescriptor::DestroyVirtualDisplay: - return ToHook<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>( - DeviceHook<int32_t, decltype(&DrmHwcTwo::DestroyVirtualDisplay), - &DrmHwcTwo::DestroyVirtualDisplay, hwc2_display_t>); - case HWC2::FunctionDescriptor::Dump: - return ToHook<HWC2_PFN_DUMP>( - DeviceHook<void, decltype(&DrmHwcTwo::Dump), &DrmHwcTwo::Dump, - uint32_t *, char *>); - case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount: - return ToHook<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>( - DeviceHook<uint32_t, decltype(&DrmHwcTwo::GetMaxVirtualDisplayCount), - &DrmHwcTwo::GetMaxVirtualDisplayCount>); - case HWC2::FunctionDescriptor::RegisterCallback: - return ToHook<HWC2_PFN_REGISTER_CALLBACK>( - DeviceHook<int32_t, decltype(&DrmHwcTwo::RegisterCallback), - &DrmHwcTwo::RegisterCallback, int32_t, - hwc2_callback_data_t, hwc2_function_pointer_t>); - - // Display functions - case HWC2::FunctionDescriptor::AcceptDisplayChanges: - return ToHook<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>( - DisplayHook<decltype(&HwcDisplay::AcceptDisplayChanges), - &HwcDisplay::AcceptDisplayChanges>); - case HWC2::FunctionDescriptor::CreateLayer: - return ToHook<HWC2_PFN_CREATE_LAYER>( - DisplayHook<decltype(&HwcDisplay::CreateLayer), - &HwcDisplay::CreateLayer, hwc2_layer_t *>); - case HWC2::FunctionDescriptor::DestroyLayer: - return ToHook<HWC2_PFN_DESTROY_LAYER>( - DisplayHook<decltype(&HwcDisplay::DestroyLayer), - &HwcDisplay::DestroyLayer, hwc2_layer_t>); - case HWC2::FunctionDescriptor::GetActiveConfig: - return ToHook<HWC2_PFN_GET_ACTIVE_CONFIG>( - DisplayHook<decltype(&HwcDisplay::GetActiveConfig), - &HwcDisplay::GetActiveConfig, hwc2_config_t *>); - case HWC2::FunctionDescriptor::GetChangedCompositionTypes: - return ToHook<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>( - DisplayHook<decltype(&HwcDisplay::GetChangedCompositionTypes), - &HwcDisplay::GetChangedCompositionTypes, uint32_t *, - hwc2_layer_t *, int32_t *>); - case HWC2::FunctionDescriptor::GetClientTargetSupport: - return ToHook<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>( - DisplayHook<decltype(&HwcDisplay::GetClientTargetSupport), - &HwcDisplay::GetClientTargetSupport, uint32_t, uint32_t, - int32_t, int32_t>); - case HWC2::FunctionDescriptor::GetColorModes: - return ToHook<HWC2_PFN_GET_COLOR_MODES>( - DisplayHook<decltype(&HwcDisplay::GetColorModes), - &HwcDisplay::GetColorModes, uint32_t *, int32_t *>); - case HWC2::FunctionDescriptor::GetDisplayAttribute: - return ToHook<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(DisplayHook< - decltype(&HwcDisplay::GetDisplayAttribute), - &HwcDisplay::GetDisplayAttribute, hwc2_config_t, int32_t, int32_t *>); - case HWC2::FunctionDescriptor::GetDisplayConfigs: - return ToHook<HWC2_PFN_GET_DISPLAY_CONFIGS>(DisplayHook< - decltype(&HwcDisplay::GetDisplayConfigs), - &HwcDisplay::GetDisplayConfigs, uint32_t *, hwc2_config_t *>); - case HWC2::FunctionDescriptor::GetDisplayName: - return ToHook<HWC2_PFN_GET_DISPLAY_NAME>( - DisplayHook<decltype(&HwcDisplay::GetDisplayName), - &HwcDisplay::GetDisplayName, uint32_t *, char *>); - case HWC2::FunctionDescriptor::GetDisplayRequests: - return ToHook<HWC2_PFN_GET_DISPLAY_REQUESTS>( - DisplayHook<decltype(&HwcDisplay::GetDisplayRequests), - &HwcDisplay::GetDisplayRequests, int32_t *, uint32_t *, - hwc2_layer_t *, int32_t *>); - case HWC2::FunctionDescriptor::GetDisplayType: - return ToHook<HWC2_PFN_GET_DISPLAY_TYPE>( - DisplayHook<decltype(&HwcDisplay::GetDisplayType), - &HwcDisplay::GetDisplayType, int32_t *>); - case HWC2::FunctionDescriptor::GetDozeSupport: - return ToHook<HWC2_PFN_GET_DOZE_SUPPORT>( - DisplayHook<decltype(&HwcDisplay::GetDozeSupport), - &HwcDisplay::GetDozeSupport, int32_t *>); - case HWC2::FunctionDescriptor::GetHdrCapabilities: - return ToHook<HWC2_PFN_GET_HDR_CAPABILITIES>( - DisplayHook<decltype(&HwcDisplay::GetHdrCapabilities), - &HwcDisplay::GetHdrCapabilities, uint32_t *, int32_t *, - float *, float *, float *>); - case HWC2::FunctionDescriptor::GetReleaseFences: - return ToHook<HWC2_PFN_GET_RELEASE_FENCES>( - DisplayHook<decltype(&HwcDisplay::GetReleaseFences), - &HwcDisplay::GetReleaseFences, uint32_t *, hwc2_layer_t *, - int32_t *>); - case HWC2::FunctionDescriptor::PresentDisplay: - return ToHook<HWC2_PFN_PRESENT_DISPLAY>( - DisplayHook<decltype(&HwcDisplay::PresentDisplay), - &HwcDisplay::PresentDisplay, int32_t *>); - case HWC2::FunctionDescriptor::SetActiveConfig: - return ToHook<HWC2_PFN_SET_ACTIVE_CONFIG>( - DisplayHook<decltype(&HwcDisplay::SetActiveConfig), - &HwcDisplay::SetActiveConfig, hwc2_config_t>); - case HWC2::FunctionDescriptor::SetClientTarget: - return ToHook<HWC2_PFN_SET_CLIENT_TARGET>(DisplayHook< - decltype(&HwcDisplay::SetClientTarget), &HwcDisplay::SetClientTarget, - buffer_handle_t, int32_t, int32_t, hwc_region_t>); - case HWC2::FunctionDescriptor::SetColorMode: - return ToHook<HWC2_PFN_SET_COLOR_MODE>( - DisplayHook<decltype(&HwcDisplay::SetColorMode), - &HwcDisplay::SetColorMode, int32_t>); - case HWC2::FunctionDescriptor::SetColorTransform: - return ToHook<HWC2_PFN_SET_COLOR_TRANSFORM>( - DisplayHook<decltype(&HwcDisplay::SetColorTransform), - &HwcDisplay::SetColorTransform, const float *, int32_t>); - case HWC2::FunctionDescriptor::SetOutputBuffer: - return ToHook<HWC2_PFN_SET_OUTPUT_BUFFER>( - DisplayHook<decltype(&HwcDisplay::SetOutputBuffer), - &HwcDisplay::SetOutputBuffer, buffer_handle_t, int32_t>); - case HWC2::FunctionDescriptor::SetPowerMode: - return ToHook<HWC2_PFN_SET_POWER_MODE>( - DisplayHook<decltype(&HwcDisplay::SetPowerMode), - &HwcDisplay::SetPowerMode, int32_t>); - case HWC2::FunctionDescriptor::SetVsyncEnabled: - return ToHook<HWC2_PFN_SET_VSYNC_ENABLED>( - DisplayHook<decltype(&HwcDisplay::SetVsyncEnabled), - &HwcDisplay::SetVsyncEnabled, int32_t>); - case HWC2::FunctionDescriptor::ValidateDisplay: - return ToHook<HWC2_PFN_VALIDATE_DISPLAY>( - DisplayHook<decltype(&HwcDisplay::ValidateDisplay), - &HwcDisplay::ValidateDisplay, uint32_t *, uint32_t *>); - - // Layer functions - case HWC2::FunctionDescriptor::SetCursorPosition: - return ToHook<HWC2_PFN_SET_CURSOR_POSITION>( - LayerHook<decltype(&HwcLayer::SetCursorPosition), - &HwcLayer::SetCursorPosition, int32_t, int32_t>); - case HWC2::FunctionDescriptor::SetLayerBlendMode: - return ToHook<HWC2_PFN_SET_LAYER_BLEND_MODE>( - LayerHook<decltype(&HwcLayer::SetLayerBlendMode), - &HwcLayer::SetLayerBlendMode, int32_t>); - case HWC2::FunctionDescriptor::SetLayerBuffer: - return ToHook<HWC2_PFN_SET_LAYER_BUFFER>( - LayerHook<decltype(&HwcLayer::SetLayerBuffer), - &HwcLayer::SetLayerBuffer, buffer_handle_t, int32_t>); - case HWC2::FunctionDescriptor::SetLayerColor: - return ToHook<HWC2_PFN_SET_LAYER_COLOR>( - LayerHook<decltype(&HwcLayer::SetLayerColor), - &HwcLayer::SetLayerColor, hwc_color_t>); - case HWC2::FunctionDescriptor::SetLayerCompositionType: - return ToHook<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>( - LayerHook<decltype(&HwcLayer::SetLayerCompositionType), - &HwcLayer::SetLayerCompositionType, int32_t>); - case HWC2::FunctionDescriptor::SetLayerDataspace: - return ToHook<HWC2_PFN_SET_LAYER_DATASPACE>( - LayerHook<decltype(&HwcLayer::SetLayerDataspace), - &HwcLayer::SetLayerDataspace, int32_t>); - case HWC2::FunctionDescriptor::SetLayerDisplayFrame: - return ToHook<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>( - LayerHook<decltype(&HwcLayer::SetLayerDisplayFrame), - &HwcLayer::SetLayerDisplayFrame, hwc_rect_t>); - case HWC2::FunctionDescriptor::SetLayerPlaneAlpha: - return ToHook<HWC2_PFN_SET_LAYER_PLANE_ALPHA>( - LayerHook<decltype(&HwcLayer::SetLayerPlaneAlpha), - &HwcLayer::SetLayerPlaneAlpha, float>); - case HWC2::FunctionDescriptor::SetLayerSidebandStream: - return ToHook<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(LayerHook< - decltype(&HwcLayer::SetLayerSidebandStream), - &HwcLayer::SetLayerSidebandStream, const native_handle_t *>); - case HWC2::FunctionDescriptor::SetLayerSourceCrop: - return ToHook<HWC2_PFN_SET_LAYER_SOURCE_CROP>( - LayerHook<decltype(&HwcLayer::SetLayerSourceCrop), - &HwcLayer::SetLayerSourceCrop, hwc_frect_t>); - case HWC2::FunctionDescriptor::SetLayerSurfaceDamage: - return ToHook<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>( - LayerHook<decltype(&HwcLayer::SetLayerSurfaceDamage), - &HwcLayer::SetLayerSurfaceDamage, hwc_region_t>); - case HWC2::FunctionDescriptor::SetLayerTransform: - return ToHook<HWC2_PFN_SET_LAYER_TRANSFORM>( - LayerHook<decltype(&HwcLayer::SetLayerTransform), - &HwcLayer::SetLayerTransform, int32_t>); - case HWC2::FunctionDescriptor::SetLayerVisibleRegion: - return ToHook<HWC2_PFN_SET_LAYER_VISIBLE_REGION>( - LayerHook<decltype(&HwcLayer::SetLayerVisibleRegion), - &HwcLayer::SetLayerVisibleRegion, hwc_region_t>); - case HWC2::FunctionDescriptor::SetLayerZOrder: - return ToHook<HWC2_PFN_SET_LAYER_Z_ORDER>( - LayerHook<decltype(&HwcLayer::SetLayerZOrder), - &HwcLayer::SetLayerZOrder, uint32_t>); - case HWC2::FunctionDescriptor::Invalid: - default: - return NULL; - } -} - -// static -int DrmHwcTwo::HookDevOpen(const struct hw_module_t *module, const char *name, - struct hw_device_t **dev) { - supported(__func__); - if (strcmp(name, HWC_HARDWARE_COMPOSER)) { - ALOGE("Invalid module name- %s", name); - return -EINVAL; - } - - std::unique_ptr<DrmHwcTwo> ctx(new DrmHwcTwo()); - if (!ctx) { - ALOGE("Failed to allocate DrmHwcTwo"); - return -ENOMEM; - } - - HWC2::Error err = ctx->Init(); - if (err != HWC2::Error::None) { - ALOGE("Failed to initialize DrmHwcTwo err=%d\n", err); - return -EINVAL; - } - - ctx->common.module = const_cast<hw_module_t *>(module); - *dev = &ctx->common; - ctx.release(); - return 0; -} -} - -static struct hw_module_methods_t hwc2_module_methods = { - .open = android::DrmHwcTwo::HookDevOpen, -}; - -hw_module_t HAL_MODULE_INFO_SYM = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = HARDWARE_MODULE_API_VERSION(2, 0), - .id = HWC_HARDWARE_MODULE_ID, - .name = "DrmHwcTwo module", - .author = "The Android Open Source Project", - .methods = &hwc2_module_methods, - .dso = NULL, - .reserved = {0}, -}; diff --git a/drmhwctwo.h b/drmhwctwo.h deleted file mode 100644 index 0490e2a..0000000 --- a/drmhwctwo.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "drmdisplaycompositor.h" -#include "drmhwcomposer.h" -#include "drmresources.h" -#include "platform.h" -#include "vsyncworker.h" - -#include <hardware/hwcomposer2.h> - -#include <map> - -namespace android { - -class DrmHwcTwo : public hwc2_device_t { - public: - static int HookDevOpen(const struct hw_module_t *module, const char *name, - struct hw_device_t **dev); - - DrmHwcTwo(); - - HWC2::Error Init(); - - private: - class HwcLayer { - public: - HWC2::Composition sf_type() const { - return sf_type_; - } - HWC2::Composition validated_type() const { - return validated_type_; - } - void accept_type_change() { - sf_type_ = validated_type_; - } - void set_validated_type(HWC2::Composition type) { - validated_type_ = type; - } - bool type_changed() const { - return sf_type_ != validated_type_; - } - - uint32_t z_order() const { - return z_order_; - } - - buffer_handle_t buffer() { - return buffer_; - } - void set_buffer(buffer_handle_t buffer) { - buffer_ = buffer; - } - - int take_acquire_fence() { - return acquire_fence_.Release(); - } - void set_acquire_fence(int acquire_fence) { - acquire_fence_.Set(dup(acquire_fence)); - } - - int release_fence() { - return release_fence_.get(); - } - int take_release_fence() { - return release_fence_.Release(); - } - void manage_release_fence() { - release_fence_.Set(release_fence_raw_); - release_fence_raw_ = -1; - } - OutputFd release_fence_output() { - return OutputFd(&release_fence_raw_); - } - - void PopulateDrmLayer(DrmHwcLayer *layer); - - // Layer hooks - HWC2::Error SetCursorPosition(int32_t x, int32_t y); - HWC2::Error SetLayerBlendMode(int32_t mode); - HWC2::Error SetLayerBuffer(buffer_handle_t buffer, int32_t acquire_fence); - HWC2::Error SetLayerColor(hwc_color_t color); - HWC2::Error SetLayerCompositionType(int32_t type); - HWC2::Error SetLayerDataspace(int32_t dataspace); - HWC2::Error SetLayerDisplayFrame(hwc_rect_t frame); - HWC2::Error SetLayerPlaneAlpha(float alpha); - HWC2::Error SetLayerSidebandStream(const native_handle_t *stream); - HWC2::Error SetLayerSourceCrop(hwc_frect_t crop); - HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage); - HWC2::Error SetLayerTransform(int32_t transform); - HWC2::Error SetLayerVisibleRegion(hwc_region_t visible); - HWC2::Error SetLayerZOrder(uint32_t z); - - private: - // sf_type_ stores the initial type given to us by surfaceflinger, - // validated_type_ stores the type after running ValidateDisplay - HWC2::Composition sf_type_ = HWC2::Composition::Invalid; - HWC2::Composition validated_type_ = HWC2::Composition::Invalid; - - HWC2::BlendMode blending_ = HWC2::BlendMode::None; - buffer_handle_t buffer_; - UniqueFd acquire_fence_; - int release_fence_raw_ = -1; - UniqueFd release_fence_; - hwc_rect_t display_frame_; - float alpha_ = 1.0f; - hwc_frect_t source_crop_; - int32_t cursor_x_; - int32_t cursor_y_; - HWC2::Transform transform_ = HWC2::Transform::None; - uint32_t z_order_ = 0; - android_dataspace_t dataspace_ = HAL_DATASPACE_UNKNOWN; - }; - - struct HwcCallback { - HwcCallback(hwc2_callback_data_t d, hwc2_function_pointer_t f) - : data(d), func(f) { - } - hwc2_callback_data_t data; - hwc2_function_pointer_t func; - }; - - class HwcDisplay { - public: - HwcDisplay(DrmResources *drm, std::shared_ptr<Importer> importer, - const gralloc_module_t *gralloc, hwc2_display_t handle, - HWC2::DisplayType type); - HwcDisplay(const HwcDisplay &) = delete; - HWC2::Error Init(std::vector<DrmPlane *> *planes); - - HWC2::Error RegisterVsyncCallback(hwc2_callback_data_t data, - hwc2_function_pointer_t func); - - // HWC Hooks - HWC2::Error AcceptDisplayChanges(); - HWC2::Error CreateLayer(hwc2_layer_t *layer); - HWC2::Error DestroyLayer(hwc2_layer_t layer); - HWC2::Error GetActiveConfig(hwc2_config_t *config); - HWC2::Error GetChangedCompositionTypes(uint32_t *num_elements, - hwc2_layer_t *layers, - int32_t *types); - HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height, - int32_t format, int32_t dataspace); - HWC2::Error GetColorModes(uint32_t *num_modes, int32_t *modes); - HWC2::Error GetDisplayAttribute(hwc2_config_t config, int32_t attribute, - int32_t *value); - HWC2::Error GetDisplayConfigs(uint32_t *num_configs, - hwc2_config_t *configs); - HWC2::Error GetDisplayName(uint32_t *size, char *name); - HWC2::Error GetDisplayRequests(int32_t *display_requests, - uint32_t *num_elements, hwc2_layer_t *layers, - int32_t *layer_requests); - HWC2::Error GetDisplayType(int32_t *type); - HWC2::Error GetDozeSupport(int32_t *support); - HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types, - float *max_luminance, - float *max_average_luminance, - float *min_luminance); - HWC2::Error GetReleaseFences(uint32_t *num_elements, hwc2_layer_t *layers, - int32_t *fences); - HWC2::Error PresentDisplay(int32_t *retire_fence); - HWC2::Error SetActiveConfig(hwc2_config_t config); - HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence, - int32_t dataspace, hwc_region_t damage); - HWC2::Error SetColorMode(int32_t mode); - HWC2::Error SetColorTransform(const float *matrix, int32_t hint); - HWC2::Error SetOutputBuffer(buffer_handle_t buffer, int32_t release_fence); - HWC2::Error SetPowerMode(int32_t mode); - HWC2::Error SetVsyncEnabled(int32_t enabled); - HWC2::Error ValidateDisplay(uint32_t *num_types, uint32_t *num_requests); - HwcLayer &get_layer(hwc2_layer_t layer) { - return layers_.at(layer); - } - - private: - void AddFenceToRetireFence(int fd); - - DrmResources *drm_; - DrmDisplayCompositor compositor_; - std::shared_ptr<Importer> importer_; - std::unique_ptr<Planner> planner_; - const gralloc_module_t *gralloc_; - - std::vector<DrmPlane *> primary_planes_; - std::vector<DrmPlane *> overlay_planes_; - - VSyncWorker vsync_worker_; - DrmConnector *connector_ = NULL; - DrmCrtc *crtc_ = NULL; - hwc2_display_t handle_; - HWC2::DisplayType type_; - uint32_t layer_idx_ = 0; - std::map<hwc2_layer_t, HwcLayer> layers_; - HwcLayer client_layer_; - UniqueFd retire_fence_; - UniqueFd next_retire_fence_; - int32_t color_mode_; - - uint32_t frame_no_ = 0; - }; - - static DrmHwcTwo *toDrmHwcTwo(hwc2_device_t *dev) { - return static_cast<DrmHwcTwo *>(dev); - } - - template <typename PFN, typename T> - static hwc2_function_pointer_t ToHook(T function) { - static_assert(std::is_same<PFN, T>::value, "Incompatible fn pointer"); - return reinterpret_cast<hwc2_function_pointer_t>(function); - } - - template <typename T, typename HookType, HookType func, typename... Args> - static T DeviceHook(hwc2_device_t *dev, Args... args) { - DrmHwcTwo *hwc = toDrmHwcTwo(dev); - return static_cast<T>(((*hwc).*func)(std::forward<Args>(args)...)); - } - - template <typename HookType, HookType func, typename... Args> - static int32_t DisplayHook(hwc2_device_t *dev, hwc2_display_t display_handle, - Args... args) { - DrmHwcTwo *hwc = toDrmHwcTwo(dev); - HwcDisplay &display = hwc->displays_.at(display_handle); - return static_cast<int32_t>((display.*func)(std::forward<Args>(args)...)); - } - - template <typename HookType, HookType func, typename... Args> - static int32_t LayerHook(hwc2_device_t *dev, hwc2_display_t display_handle, - hwc2_layer_t layer_handle, Args... args) { - DrmHwcTwo *hwc = toDrmHwcTwo(dev); - HwcDisplay &display = hwc->displays_.at(display_handle); - HwcLayer &layer = display.get_layer(layer_handle); - return static_cast<int32_t>((layer.*func)(std::forward<Args>(args)...)); - } - - // hwc2_device_t hooks - static int HookDevClose(hw_device_t *dev); - static void HookDevGetCapabilities(hwc2_device_t *dev, uint32_t *out_count, - int32_t *out_capabilities); - static hwc2_function_pointer_t HookDevGetFunction(struct hwc2_device *device, - int32_t descriptor); - - // Device functions - HWC2::Error CreateVirtualDisplay(uint32_t width, uint32_t height, - int32_t *format, - hwc2_display_t *display); - HWC2::Error DestroyVirtualDisplay(hwc2_display_t display); - void Dump(uint32_t *size, char *buffer); - uint32_t GetMaxVirtualDisplayCount(); - HWC2::Error RegisterCallback(int32_t descriptor, hwc2_callback_data_t data, - hwc2_function_pointer_t function); - - DrmResources drm_; - std::shared_ptr<Importer> importer_; // Shared with HwcDisplay - const gralloc_module_t *gralloc_; - std::map<hwc2_display_t, HwcDisplay> displays_; - std::map<HWC2::Callback, HwcCallback> callbacks_; -}; -} diff --git a/drmresources.cpp b/drmresources.cpp index 6b8ed03..e433239 100644 --- a/drmresources.cpp +++ b/drmresources.cpp @@ -71,11 +71,6 @@ int DrmResources::Init() { return -ENODEV; } - min_resolution_ = - std::pair<uint32_t, uint32_t>(res->min_width, res->min_height); - max_resolution_ = - std::pair<uint32_t, uint32_t>(res->max_width, res->max_height); - bool found_primary = false; int display_num = 1; diff --git a/drmresources.h b/drmresources.h index 011f87e..64e6b57 100644 --- a/drmresources.h +++ b/drmresources.h @@ -47,14 +47,6 @@ class DrmResources { return planes_; } - std::pair<uint32_t, uint32_t> min_resolution() const { - return min_resolution_; - } - - std::pair<uint32_t, uint32_t> max_resolution() const { - return max_resolution_; - } - DrmConnector *GetConnectorForDisplay(int display) const; DrmCrtc *GetCrtcForDisplay(int display) const; DrmPlane *GetPlane(uint32_t id) const; @@ -91,9 +83,6 @@ class DrmResources { std::vector<std::unique_ptr<DrmPlane>> planes_; DrmCompositor compositor_; DrmEventListener event_listener_; - - std::pair<uint32_t, uint32_t> min_resolution_; - std::pair<uint32_t, uint32_t> max_resolution_; }; } diff --git a/glworker.cpp b/glworker.cpp index e12995e..6ce2de3 100644 --- a/glworker.cpp +++ b/glworker.cpp @@ -35,10 +35,14 @@ #include <utils/Trace.h> #include "drmdisplaycomposition.h" -#include "platform.h" #include "glworker.h" +// TODO(zachr): use hwc_drm_bo to turn buffer handles into textures +#ifndef EGL_NATIVE_HANDLE_ANDROID_NVX +#define EGL_NATIVE_HANDLE_ANDROID_NVX 0x322A +#endif + #define MAX_OVERLAPPING_LAYERS 64 namespace android { @@ -412,9 +416,10 @@ static int EGLFenceWait(EGLDisplay egl_display, int acquireFenceFd) { static int CreateTextureFromHandle(EGLDisplay egl_display, buffer_handle_t handle, - Importer *importer, AutoEGLImageAndGLTexture *out) { - EGLImageKHR image = importer->ImportImage(egl_display, handle); + EGLImageKHR image = eglCreateImageKHR( + egl_display, EGL_NO_CONTEXT, EGL_NATIVE_HANDLE_ANDROID_NVX, + (EGLClientBuffer)handle, NULL /* no attribs */); if (image == EGL_NO_IMAGE_KHR) { ALOGE("Failed to make image %s %p", GetEGLError(), handle); @@ -547,8 +552,7 @@ GLWorkerCompositor::~GLWorkerCompositor() { int GLWorkerCompositor::Composite(DrmHwcLayer *layers, DrmCompositionRegion *regions, size_t num_regions, - const sp<GraphicBuffer> &framebuffer, - Importer *importer) { + const sp<GraphicBuffer> &framebuffer) { ATRACE_CALL(); int ret = 0; std::vector<AutoEGLImageAndGLTexture> layer_textures; @@ -586,7 +590,7 @@ int GLWorkerCompositor::Composite(DrmHwcLayer *layers, continue; ret = CreateTextureFromHandle(egl_display_, layer->get_usable_handle(), - importer, &layer_textures.back()); + &layer_textures.back()); if (!ret) { ret = EGLFenceWait(egl_display_, layer->acquire_fence.Release()); @@ -43,8 +43,7 @@ class GLWorkerCompositor { int Init(); int Composite(DrmHwcLayer *layers, DrmCompositionRegion *regions, - size_t num_regions, const sp<GraphicBuffer> &framebuffer, - Importer *importer); + size_t num_regions, const sp<GraphicBuffer> &framebuffer); void Finish(); private: diff --git a/hwcomposer.cpp b/hwcomposer.cpp index 875056d..8d8e1d0 100644 --- a/hwcomposer.cpp +++ b/hwcomposer.cpp @@ -201,17 +201,165 @@ struct hwc_context_t { DrmHotplugHandler hotplug_handler; }; -class DrmVsyncCallback : public VsyncCallback { - public: - DrmVsyncCallback(hwc_procs_t const *procs) : procs_(procs) { +static native_handle_t *dup_buffer_handle(buffer_handle_t handle) { + native_handle_t *new_handle = + native_handle_create(handle->numFds, handle->numInts); + if (new_handle == NULL) + return NULL; + + const int *old_data = handle->data; + int *new_data = new_handle->data; + for (int i = 0; i < handle->numFds; i++) { + *new_data = dup(*old_data); + old_data++; + new_data++; + } + memcpy(new_data, old_data, sizeof(int) * handle->numInts); + + return new_handle; +} + +static void free_buffer_handle(native_handle_t *handle) { + int ret = native_handle_close(handle); + if (ret) + ALOGE("Failed to close native handle %d", ret); + ret = native_handle_delete(handle); + if (ret) + ALOGE("Failed to delete native handle %d", ret); +} + +const hwc_drm_bo *DrmHwcBuffer::operator->() const { + if (importer_ == NULL) { + ALOGE("Access of non-existent BO"); + exit(1); + return NULL; } + return &bo_; +} - void Callback(int display, int64_t timestamp) { - procs_->vsync(procs_, display, timestamp); +void DrmHwcBuffer::Clear() { + if (importer_ != NULL) { + importer_->ReleaseBuffer(&bo_); + importer_ = NULL; } - private: - hwc_procs_t const *procs_; -}; +} + +int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) { + hwc_drm_bo tmp_bo; + + int ret = importer->ImportBuffer(handle, &tmp_bo); + if (ret) + return ret; + + if (importer_ != NULL) { + importer_->ReleaseBuffer(&bo_); + } + + importer_ = importer; + + bo_ = tmp_bo; + + return 0; +} + +int DrmHwcNativeHandle::CopyBufferHandle(buffer_handle_t handle, + const gralloc_module_t *gralloc) { + native_handle_t *handle_copy = dup_buffer_handle(handle); + if (handle_copy == NULL) { + ALOGE("Failed to duplicate handle"); + return -ENOMEM; + } + + int ret = gralloc->registerBuffer(gralloc, handle_copy); + if (ret) { + ALOGE("Failed to register buffer handle %d", ret); + free_buffer_handle(handle_copy); + return ret; + } + + Clear(); + + gralloc_ = gralloc; + handle_ = handle_copy; + + return 0; +} + +DrmHwcNativeHandle::~DrmHwcNativeHandle() { + Clear(); +} + +void DrmHwcNativeHandle::Clear() { + if (gralloc_ != NULL && handle_ != NULL) { + gralloc_->unregisterBuffer(gralloc_, handle_); + free_buffer_handle(handle_); + gralloc_ = NULL; + handle_ = NULL; + } +} + +int DrmHwcLayer::InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer, + const gralloc_module_t *gralloc) { + sf_handle = sf_layer->handle; + alpha = sf_layer->planeAlpha; + + source_crop = DrmHwcRect<float>( + sf_layer->sourceCropf.left, sf_layer->sourceCropf.top, + sf_layer->sourceCropf.right, sf_layer->sourceCropf.bottom); + display_frame = DrmHwcRect<int>( + sf_layer->displayFrame.left, sf_layer->displayFrame.top, + sf_layer->displayFrame.right, sf_layer->displayFrame.bottom); + + transform = 0; + // 270* and 180* cannot be combined with flips. More specifically, they + // already contain both horizontal and vertical flips, so those fields are + // redundant in this case. 90* rotation can be combined with either horizontal + // flip or vertical flip, so treat it differently + if (sf_layer->transform == HWC_TRANSFORM_ROT_270) { + transform = DrmHwcTransform::kRotate270; + } else if (sf_layer->transform == HWC_TRANSFORM_ROT_180) { + transform = DrmHwcTransform::kRotate180; + } else { + if (sf_layer->transform & HWC_TRANSFORM_FLIP_H) + transform |= DrmHwcTransform::kFlipH; + if (sf_layer->transform & HWC_TRANSFORM_FLIP_V) + transform |= DrmHwcTransform::kFlipV; + if (sf_layer->transform & HWC_TRANSFORM_ROT_90) + transform |= DrmHwcTransform::kRotate90; + } + + switch (sf_layer->blending) { + case HWC_BLENDING_NONE: + blending = DrmHwcBlending::kNone; + break; + case HWC_BLENDING_PREMULT: + blending = DrmHwcBlending::kPreMult; + break; + case HWC_BLENDING_COVERAGE: + blending = DrmHwcBlending::kCoverage; + break; + default: + ALOGE("Invalid blending in hwc_layer_1_t %d", sf_layer->blending); + return -EINVAL; + } + + int ret = buffer.ImportBuffer(sf_layer->handle, importer); + if (ret) + return ret; + + ret = handle.CopyBufferHandle(sf_layer->handle, gralloc); + if (ret) + return ret; + + ret = gralloc->perform(gralloc, GRALLOC_MODULE_PERFORM_GET_USAGE, + handle.get(), &gralloc_buffer_usage); + if (ret) { + ALOGE("Failed to get usage for buffer %p (%d)", handle.get(), ret); + return ret; + } + + return 0; +} static void hwc_dump(struct hwc_composer_device_1 *dev, char *buff, int buff_len) { @@ -535,10 +683,8 @@ static void hwc_register_procs(struct hwc_composer_device_1 *dev, ctx->procs = procs; - for (std::pair<const int, hwc_drm_display> &display_entry : ctx->displays) { - auto callback = std::make_shared<DrmVsyncCallback>(procs); - display_entry.second.vsync_worker.RegisterCallback(std::move(callback)); - } + for (std::pair<const int, hwc_drm_display> &display_entry : ctx->displays) + display_entry.second.vsync_worker.SetProcs(procs); ctx->hotplug_handler.Init(&ctx->drm, procs); ctx->drm.event_listener()->RegisterHotplugHandler(&ctx->hotplug_handler); diff --git a/hwcutils.cpp b/hwcutils.cpp deleted file mode 100644 index 0091575..0000000 --- a/hwcutils.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define ATRACE_TAG ATRACE_TAG_GRAPHICS -#define LOG_TAG "hwc-drm-utils" - -#include "drmhwcomposer.h" -#include "platform.h" - -#include <cutils/log.h> - -namespace android { - -const hwc_drm_bo *DrmHwcBuffer::operator->() const { - if (importer_ == NULL) { - ALOGE("Access of non-existent BO"); - exit(1); - return NULL; - } - return &bo_; -} - -void DrmHwcBuffer::Clear() { - if (importer_ != NULL) { - importer_->ReleaseBuffer(&bo_); - importer_ = NULL; - } -} - -int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) { - hwc_drm_bo tmp_bo; - - int ret = importer->ImportBuffer(handle, &tmp_bo); - if (ret) - return ret; - - if (importer_ != NULL) { - importer_->ReleaseBuffer(&bo_); - } - - importer_ = importer; - - bo_ = tmp_bo; - - return 0; -} - -static native_handle_t *dup_buffer_handle(buffer_handle_t handle) { - native_handle_t *new_handle = - native_handle_create(handle->numFds, handle->numInts); - if (new_handle == NULL) - return NULL; - - const int *old_data = handle->data; - int *new_data = new_handle->data; - for (int i = 0; i < handle->numFds; i++) { - *new_data = dup(*old_data); - old_data++; - new_data++; - } - memcpy(new_data, old_data, sizeof(int) * handle->numInts); - - return new_handle; -} - -static void free_buffer_handle(native_handle_t *handle) { - int ret = native_handle_close(handle); - if (ret) - ALOGE("Failed to close native handle %d", ret); - ret = native_handle_delete(handle); - if (ret) - ALOGE("Failed to delete native handle %d", ret); -} - -int DrmHwcNativeHandle::CopyBufferHandle(buffer_handle_t handle, - const gralloc_module_t *gralloc) { - native_handle_t *handle_copy = dup_buffer_handle(handle); - if (handle_copy == NULL) { - ALOGE("Failed to duplicate handle"); - return -ENOMEM; - } - - int ret = gralloc->registerBuffer(gralloc, handle_copy); - if (ret) { - ALOGE("Failed to register buffer handle %d", ret); - free_buffer_handle(handle_copy); - return ret; - } - - Clear(); - - gralloc_ = gralloc; - handle_ = handle_copy; - - return 0; -} - -DrmHwcNativeHandle::~DrmHwcNativeHandle() { - Clear(); -} - -void DrmHwcNativeHandle::Clear() { - if (gralloc_ != NULL && handle_ != NULL) { - gralloc_->unregisterBuffer(gralloc_, handle_); - free_buffer_handle(handle_); - gralloc_ = NULL; - handle_ = NULL; - } -} - -int DrmHwcLayer::InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer, - const gralloc_module_t *gralloc) { - alpha = sf_layer->planeAlpha; - - SetSourceCrop(sf_layer->sourceCropf); - SetDisplayFrame(sf_layer->displayFrame); - SetTransform(sf_layer->transform); - - switch (sf_layer->blending) { - case HWC_BLENDING_NONE: - blending = DrmHwcBlending::kNone; - break; - case HWC_BLENDING_PREMULT: - blending = DrmHwcBlending::kPreMult; - break; - case HWC_BLENDING_COVERAGE: - blending = DrmHwcBlending::kCoverage; - break; - default: - ALOGE("Invalid blending in hwc_layer_1_t %d", sf_layer->blending); - return -EINVAL; - } - - sf_handle = sf_layer->handle; - - return ImportBuffer(importer, gralloc); -} - -int DrmHwcLayer::ImportBuffer(Importer *importer, - const gralloc_module_t *gralloc) { - int ret = buffer.ImportBuffer(sf_handle, importer); - if (ret) - return ret; - - ret = handle.CopyBufferHandle(sf_handle, gralloc); - if (ret) - return ret; - - ret = gralloc->perform(gralloc, GRALLOC_MODULE_PERFORM_GET_USAGE, - handle.get(), &gralloc_buffer_usage); - if (ret) { - ALOGE("Failed to get usage for buffer %p (%d)", handle.get(), ret); - return ret; - } - return 0; -} - -void DrmHwcLayer::SetSourceCrop(hwc_frect_t const &crop) { - source_crop = DrmHwcRect<float>(crop.left, crop.top, crop.right, crop.bottom); -} - -void DrmHwcLayer::SetDisplayFrame(hwc_rect_t const &frame) { - display_frame = - DrmHwcRect<int>(frame.left, frame.top, frame.right, frame.bottom); -} - -void DrmHwcLayer::SetTransform(int32_t sf_transform) { - transform = 0; - // 270* and 180* cannot be combined with flips. More specifically, they - // already contain both horizontal and vertical flips, so those fields are - // redundant in this case. 90* rotation can be combined with either horizontal - // flip or vertical flip, so treat it differently - if (sf_transform == HWC_TRANSFORM_ROT_270) { - transform = DrmHwcTransform::kRotate270; - } else if (sf_transform == HWC_TRANSFORM_ROT_180) { - transform = DrmHwcTransform::kRotate180; - } else { - if (sf_transform & HWC_TRANSFORM_FLIP_H) - transform |= DrmHwcTransform::kFlipH; - if (sf_transform & HWC_TRANSFORM_FLIP_V) - transform |= DrmHwcTransform::kFlipV; - if (sf_transform & HWC_TRANSFORM_ROT_90) - transform |= DrmHwcTransform::kRotate90; - } -} -} @@ -38,10 +38,6 @@ class Importer { // Creates a platform-specific importer instance static Importer *CreateInstance(DrmResources *drm); - // Imports EGLImage for glcompositor, since NV handles this in non-standard - // way, and fishing out the details is specific to the gralloc used. - virtual EGLImageKHR ImportImage(EGLDisplay egl_display, buffer_handle_t handle) = 0; - // Imports the buffer referred to by handle into bo. // // Note: This can be called from a different thread than ReleaseBuffer. The diff --git a/platformdrmgeneric.cpp b/platformdrmgeneric.cpp index aa3d0fa..90ba0e2 100644 --- a/platformdrmgeneric.cpp +++ b/platformdrmgeneric.cpp @@ -27,7 +27,6 @@ #include <cutils/log.h> #include <gralloc_drm_handle.h> #include <hardware/gralloc.h> -#include <EGL/eglext.h> namespace android { @@ -84,22 +83,6 @@ uint32_t DrmGenericImporter::ConvertHalFormatToDrm(uint32_t hal_format) { } } -EGLImageKHR DrmGenericImporter::ImportImage(EGLDisplay egl_display, buffer_handle_t handle) { - gralloc_drm_handle_t *gr_handle = gralloc_drm_handle(handle); - if (!gr_handle) - return NULL; - EGLint attr[] = { - EGL_WIDTH, gr_handle->width, - EGL_HEIGHT, gr_handle->height, - EGL_LINUX_DRM_FOURCC_EXT, (EGLint)ConvertHalFormatToDrm(gr_handle->format), - EGL_DMA_BUF_PLANE0_FD_EXT, gr_handle->prime_fd, - EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, - EGL_DMA_BUF_PLANE0_PITCH_EXT, gr_handle->stride, - EGL_NONE, - }; - return eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attr); -} - int DrmGenericImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { gralloc_drm_handle_t *gr_handle = gralloc_drm_handle(handle); if (!gr_handle) diff --git a/platformdrmgeneric.h b/platformdrmgeneric.h index 8376580..3400876 100644 --- a/platformdrmgeneric.h +++ b/platformdrmgeneric.h @@ -31,7 +31,6 @@ class DrmGenericImporter : public Importer { int Init(); - EGLImageKHR ImportImage(EGLDisplay egl_display, buffer_handle_t handle) override; int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override; int ReleaseBuffer(hwc_drm_bo_t *bo) override; diff --git a/platformnv.cpp b/platformnv.cpp index d3e5d70..9ea1467 100644 --- a/platformnv.cpp +++ b/platformnv.cpp @@ -29,10 +29,6 @@ #include <cutils/log.h> #include <hardware/gralloc.h> -#ifndef EGL_NATIVE_HANDLE_ANDROID_NVX -#define EGL_NATIVE_HANDLE_ANDROID_NVX 0x322A -#endif - namespace android { #ifdef USE_NVIDIA_IMPORTER @@ -73,13 +69,6 @@ int NvImporter::Init() { return 0; } - -EGLImageKHR NvImporter::ImportImage(EGLDisplay egl_display, buffer_handle_t handle) { - return eglCreateImageKHR( - egl_display, EGL_NO_CONTEXT, EGL_NATIVE_HANDLE_ANDROID_NVX, - (EGLClientBuffer)handle, NULL /* no attribs */); -} - int NvImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) { memset(bo, 0, sizeof(hwc_drm_bo_t)); NvBuffer_t *buf = GrallocGetNvBuffer(handle); diff --git a/platformnv.h b/platformnv.h index 3c1f49e..df2a242 100644 --- a/platformnv.h +++ b/platformnv.h @@ -34,7 +34,6 @@ class NvImporter : public Importer { int Init(); - EGLImageKHR ImportImage(EGLDisplay egl_display, buffer_handle_t handle) override; int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override; int ReleaseBuffer(hwc_drm_bo_t *bo) override; diff --git a/vsyncworker.cpp b/vsyncworker.cpp index 2177521..ee140cb 100644 --- a/vsyncworker.cpp +++ b/vsyncworker.cpp @@ -34,6 +34,7 @@ namespace android { VSyncWorker::VSyncWorker() : Worker("vsync", HAL_PRIORITY_URGENT_DISPLAY), drm_(NULL), + procs_(NULL), display_(-1), last_timestamp_(-1) { } @@ -48,9 +49,9 @@ int VSyncWorker::Init(DrmResources *drm, int display) { return InitWorker(); } -void VSyncWorker::RegisterCallback(std::shared_ptr<VsyncCallback> callback) { +void VSyncWorker::SetProcs(hwc_procs_t const *procs) { Lock(); - callback_ = callback; + procs_ = procs; Unlock(); } @@ -125,8 +126,7 @@ void VSyncWorker::Routine() { bool enabled = enabled_; int display = display_; - std::shared_ptr<VsyncCallback> callback(callback_); - + hwc_procs_t const *procs = procs_; Unlock(); if (!enabled) @@ -159,16 +159,16 @@ void VSyncWorker::Routine() { } /* - * There's a race here where a change in callback_ will not take effect until + * There's a race here where a change in procs_ will not take effect until * the next subsequent requested vsync. This is unavoidable since we can't * call the vsync hook while holding the thread lock. * - * We could shorten the race window by caching callback_ right before calling - * the hook. However, in practice, callback_ is only updated once, so it's not + * We could shorten the race window by caching procs_ right before calling + * the hook. However, in practice, procs_ is only updated once, so it's not * worth the overhead. */ - if (callback) - callback->Callback(display, timestamp); + if (procs && procs->vsync) + procs->vsync(procs, display, timestamp); last_timestamp_ = timestamp; } } diff --git a/vsyncworker.h b/vsyncworker.h index 787152e..3e1f814 100644 --- a/vsyncworker.h +++ b/vsyncworker.h @@ -28,20 +28,13 @@ namespace android { -class VsyncCallback { - public: - virtual ~VsyncCallback() { - } - virtual void Callback(int display, int64_t timestamp) = 0; -}; - class VSyncWorker : public Worker { public: VSyncWorker(); ~VSyncWorker() override; int Init(DrmResources *drm, int display); - void RegisterCallback(std::shared_ptr<VsyncCallback> callback); + void SetProcs(hwc_procs_t const *procs); void VSyncControl(bool enabled); @@ -53,11 +46,7 @@ class VSyncWorker : public Worker { int SyntheticWaitVBlank(int64_t *timestamp); DrmResources *drm_; - - // shared_ptr since we need to use this outside of the thread lock (to - // actually call the hook) and we don't want the memory freed until we're - // done - std::shared_ptr<VsyncCallback> callback_ = NULL; + hwc_procs_t const *procs_; int display_; bool enabled_; |