From bdbc508d9faf131e8408fceac2bfff5ca7927b84 Mon Sep 17 00:00:00 2001 From: Marissa Wall Date: Tue, 6 Sep 2016 14:13:19 -0700 Subject: hwc2: present display Presents the validated display. It is equivalent to calling HWC1's set. Test: Add "TARGET_USES_HWC2 := true" to BoardConfig.mk. Recompile. Run testcases: https://android-review.googlesource.com/#/q/project: platform/frameworks/native+branch:master+topic:test-hwc2 Change-Id: Ib78be9df59ac1370b57cd4dae5412b15267b77b6 --- hwc2/Android.mk | 3 +- hwc2/hwc2.cpp | 17 +- hwc2/hwc2.h | 57 +++ hwc2/hwc2_buffer.cpp | 171 +++++++++ hwc2/hwc2_dev.cpp | 56 ++- hwc2/hwc2_display.cpp | 205 +++++++++++ hwc2/hwc2_gralloc.cpp | 51 ++- hwc2/hwc2_layer.cpp | 13 + hwc2/include/tegra_dc_ext.h | 394 ++++++++++++++++++++ hwc2/include/tegrafb.h | 105 ++++++ hwc2/original-kernel-headers/tegra_dc_ext.h | 544 ++++++++++++++++++++++++++++ hwc2/original-kernel-headers/tegrafb.h | 47 +++ 12 files changed, 1644 insertions(+), 19 deletions(-) create mode 100644 hwc2/include/tegra_dc_ext.h create mode 100644 hwc2/include/tegrafb.h create mode 100644 hwc2/original-kernel-headers/tegra_dc_ext.h create mode 100644 hwc2/original-kernel-headers/tegrafb.h diff --git a/hwc2/Android.mk b/hwc2/Android.mk index b0a33cd..b2c32c0 100644 --- a/hwc2/Android.mk +++ b/hwc2/Android.mk @@ -36,7 +36,8 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_STATIC_LIBRARIES := \ libadfhwc \ - libadf + libadf \ + libbase LOCAL_SRC_FILES := \ hwc2.cpp \ diff --git a/hwc2/hwc2.cpp b/hwc2/hwc2.cpp index 2864d34..e2a5ebc 100644 --- a/hwc2/hwc2.cpp +++ b/hwc2/hwc2.cpp @@ -181,17 +181,20 @@ hwc2_error_t get_hdr_capabilities(hwc2_device_t* /*device*/, return HWC2_ERROR_NONE; } -hwc2_error_t get_release_fences(hwc2_device_t* /*device*/, - hwc2_display_t /*display*/, uint32_t* /*out_num_elements*/, - hwc2_layer_t* /*out_layers*/, int32_t* /*out_fences*/) +hwc2_error_t get_release_fences(hwc2_device_t *device, hwc2_display_t display, + uint32_t *out_num_elements, hwc2_layer_t *out_layers, + int32_t *out_fences) { - return HWC2_ERROR_NONE; + hwc2_dev *dev = reinterpret_cast(device)->hwc2_dev; + return dev->get_release_fences(display, out_num_elements, out_layers, + out_fences); } -hwc2_error_t present_display(hwc2_device_t* /*device*/, - hwc2_display_t /*display*/, int32_t* /*out_present_fence*/) +hwc2_error_t present_display(hwc2_device_t *device, hwc2_display_t display, + int32_t *out_present_fence) { - return HWC2_ERROR_NONE; + hwc2_dev *dev = reinterpret_cast(device)->hwc2_dev; + return dev->present_display(display, out_present_fence); } hwc2_error_t set_active_config(hwc2_device_t *device, hwc2_display_t display, diff --git a/hwc2/hwc2.h b/hwc2/hwc2.h index 8ca3507..1893037 100644 --- a/hwc2/hwc2.h +++ b/hwc2/hwc2.h @@ -17,6 +17,7 @@ #ifndef _HWC2_H #define _HWC2_H +#include #include #include @@ -79,7 +80,14 @@ public: int get_format(buffer_handle_t handle) const; void get_surfaces(buffer_handle_t handle, const void **surf, size_t *surf_cnt) const; + void get_dma_buf(const void *surf, uint32_t surf_idx, int *out_fd) const; int32_t get_layout(const void *surf, uint32_t surf_idx) const; + uint32_t get_pitch(const void *surf, uint32_t surf_idx) const; + uint32_t get_hmem(const void *surf, uint32_t surf_idx) const; + uint32_t get_offset(const void *surf, uint32_t surf_idx) const; + uint32_t get_block_height_log2(const void *surf, uint32_t surf_idx) const; + uint32_t decompress(buffer_handle_t handle, int in_fence, + int *out_fence) const; private: hwc2_gralloc(); @@ -106,6 +114,16 @@ private: void (*nvgr_get_surfaces)(buffer_handle_t handle, const void **surf, size_t *surf_cnt); + /* The address of the NvRmMemDmaBufFdFromHandle symbol. This NVIDIA function + * returns the dma bufs assicated with a buffer handle */ + void (*NvRmMemDmaBufFdFromHandle)(uint32_t hmem, int *fd); + + /* The address of the nvgr_decompress symbol. This NVIDIA function + * decompresses the buffer and returns an out fence that fires when the + * buffer is done decompressing */ + int (*nvgr_decompress)(buffer_handle_t handle, int in_fence, + int *out_fence); + /* A symbol table handle to the NVIDIA gralloc .so file. */ void *nvgr; }; @@ -115,6 +133,11 @@ public: hwc2_buffer(); ~hwc2_buffer(); + hwc2_error_t decompress(); + hwc2_error_t get_adf_post_props(struct tegra_adf_flip_windowattr *win_attr, + struct adf_buffer_config *adf_buf, size_t win_idx, + size_t buf_idx, uint32_t z_order) const; + void close_acquire_fence(); /* Get properties */ @@ -198,6 +221,10 @@ private: /* The buffer is modified and will force revalidation of the display */ bool modified; + + hwc2_error_t get_adf_buf_config(struct adf_buffer_config *adf_buf) const; + hwc2_error_t get_adf_win_attr(struct tegra_adf_flip_windowattr *win_attr, + size_t win_idx, size_t buf_idx, uint32_t z_order) const; }; class hwc2_config { @@ -253,6 +280,14 @@ class hwc2_layer { public: hwc2_layer(hwc2_layer_t id); + hwc2_error_t decompress_buffer(); + + hwc2_error_t get_adf_post_props(struct tegra_adf_flip_windowattr *win_attr, + struct adf_buffer_config *adf_buf, size_t win_idx, + size_t buf_idx, uint32_t z_order) const; + + void close_acquire_fence() { buffer.close_acquire_fence(); } + /* Get properties */ hwc2_layer_t get_id() const { return id; } hwc2_composition_t get_comp_type() const { return comp_type; } @@ -390,12 +425,21 @@ public: hwc2_layer_request_t *out_layer_requests) const; hwc2_error_t accept_display_changes(); + hwc2_error_t present_display(int32_t *out_present_fence); + hwc2_error_t prepare_present_display(); + void close_acquire_fences(); + + hwc2_error_t get_release_fences(uint32_t *out_num_elements, + hwc2_layer_t *out_layers, int32_t *out_fences) const; + /* Window functions */ void init_windows(); void clear_windows(); hwc2_error_t assign_client_target_window(uint32_t z_order); hwc2_error_t assign_layer_window(uint32_t z_order, hwc2_layer_t lyr_id); + hwc2_error_t decompress_window_buffers(); + /* Config functions */ int retrieve_display_configs(struct adf_hwc_helper *adf_helper); hwc2_error_t get_display_attribute(hwc2_config_t config, @@ -413,6 +457,7 @@ public: hwc2_error_t set_client_target(buffer_handle_t target, int32_t acquire_fence, android_dataspace_t dataspace, const hwc_region_t &surface_damage); + hwc2_error_t set_client_target_properties(); /* Set layer functions */ hwc2_error_t create_layer(hwc2_layer_t *out_layer); @@ -500,6 +545,10 @@ private: /* The current power mode of the display */ hwc2_power_mode_t power_mode; + /* Sync fence object which will be signaled after the device has finished + * reading from the buffer presented in the prior frame */ + android::base::unique_fd release_fence; + /* The adf interface file descriptor for the display */ int adf_intf_fd; @@ -538,6 +587,11 @@ public: uint32_t *out_num_elements, hwc2_layer_t *out_layers, hwc2_layer_request_t *out_layer_requests) const; hwc2_error_t accept_display_changes(hwc2_display_t dpy_id); + hwc2_error_t present_display(hwc2_display_t dpy_id, + int32_t *out_present_fence); + hwc2_error_t get_release_fences(hwc2_display_t dpy_id, + uint32_t *out_num_elements, hwc2_layer_t *out_layers, + int32_t *out_fences) const; /* Config functions */ hwc2_error_t get_display_attribute(hwc2_display_t dpy_id, @@ -603,6 +657,9 @@ public: int open_adf_device(); private: + /* The mutex is used to protect changing the connection and power mode */ + std::mutex state_mutex; + /* General callback functions for all displays */ hwc2_callback callback_handler; diff --git a/hwc2/hwc2_buffer.cpp b/hwc2/hwc2_buffer.cpp index cbe7595..1af83ee 100644 --- a/hwc2/hwc2_buffer.cpp +++ b/hwc2/hwc2_buffer.cpp @@ -15,6 +15,10 @@ */ #include +#include +#include +#include +#include #include "hwc2.h" @@ -68,6 +72,173 @@ hwc2_buffer::~hwc2_buffer() close_acquire_fence(); } +hwc2_error_t hwc2_buffer::decompress() +{ + int ret = hwc2_gralloc::get_instance().decompress(handle, acquire_fence, + &acquire_fence); + if (ret < 0) { + ALOGE("failed to decompress buffer: %s", strerror(ret)); + return HWC2_ERROR_NO_RESOURCES; + } + return HWC2_ERROR_NONE; +} + +hwc2_error_t hwc2_buffer::get_adf_post_props( + struct tegra_adf_flip_windowattr *win_attr, + struct adf_buffer_config *adf_buf, size_t win_idx, + size_t buf_idx, uint32_t z_order) const +{ + if (!hwc2_gralloc::get_instance().is_valid(handle)) { + ALOGE("invalid buffer handle"); + return HWC2_ERROR_NO_RESOURCES; + } + + hwc2_error_t ret = get_adf_buf_config(adf_buf); + if (ret != HWC2_ERROR_NONE) { + ALOGE("failed to set adf buf configs"); + return ret; + } + + ret = get_adf_win_attr(win_attr, win_idx, buf_idx, z_order); + if (ret != HWC2_ERROR_NONE) { + ALOGE("failed to set win attr"); + return ret; + } + + return HWC2_ERROR_NONE; +} + +hwc2_error_t hwc2_buffer::get_adf_buf_config( + struct adf_buffer_config *adf_buf) const +{ + const hwc2_gralloc& gralloc = hwc2_gralloc::get_instance(); + + adf_buf->overlay_engine = 0; + adf_buf->w = (uint32_t) (ceil(source_crop.right) - ceil(source_crop.left)); + adf_buf->h = (uint32_t) (ceil(source_crop.bottom) - ceil(source_crop.top)); + adf_buf->format = gralloc.get_format(handle); + + const void *surf; + size_t surf_cnt; + gralloc.get_surfaces(handle, &surf, &surf_cnt); + if (!surf || surf_cnt == 0) { + ALOGE("failed to get surfaces"); + return HWC2_ERROR_NO_RESOURCES; + } + + adf_buf->n_planes = surf_cnt; + + int fd; + gralloc.get_dma_buf(surf, 0, &fd); + for (size_t idx = 0; idx < arraysize(adf_buf->fd); idx++) { + if (idx < adf_buf->n_planes) + adf_buf->fd[idx] = fd; + else + adf_buf->fd[idx] = -1; + } + + adf_buf->pitch[0] = gralloc.get_pitch(surf, 0); + adf_buf->offset[0] = gralloc.get_offset(surf, 0); + + if (surf_cnt == 1) { + adf_buf->pitch[1] = 0; + adf_buf->pitch[2] = 0; + adf_buf->offset[1] = 0; + adf_buf->offset[2] = 0; + } else { + switch (surf_cnt) { + case 2: + adf_buf->pitch[1] = gralloc.get_pitch(surf, 1); + adf_buf->pitch[2] = gralloc.get_pitch(surf, 1); + adf_buf->offset[1] = gralloc.get_offset(surf, 1); + adf_buf->offset[2] = 0; + break; + case 3: + adf_buf->pitch[1] = gralloc.get_pitch(surf, 1); + adf_buf->pitch[2] = gralloc.get_pitch(surf, 1); + adf_buf->offset[1] = gralloc.get_offset(surf, 1); + adf_buf->offset[2] = gralloc.get_offset(surf, 2); + break; + default: + LOG_ALWAYS_FATAL("Invalid surface count. There must be between 1 to" + " 3 surfaces per buffer."); + break; + } + } + + adf_buf->acquire_fence = acquire_fence; + + return HWC2_ERROR_NONE; +} + +hwc2_error_t hwc2_buffer::get_adf_win_attr( + struct tegra_adf_flip_windowattr *win_attr, size_t win_idx, + size_t buf_idx, uint32_t z_order) const +{ + const hwc2_gralloc& gralloc = hwc2_gralloc::get_instance(); + const void *surf; + size_t surf_cnt; + uint32_t layout; + + win_attr->win_index = win_idx; + win_attr->buf_index = buf_idx; + + switch (blend_mode) { + case HWC2_BLEND_MODE_PREMULTIPLIED: + win_attr->blend = TEGRA_ADF_BLEND_PREMULT; + break; + case HWC2_BLEND_MODE_COVERAGE: + win_attr->blend = TEGRA_ADF_BLEND_COVERAGE; + break; + case HWC2_BLEND_MODE_NONE: + win_attr->blend = TEGRA_ADF_BLEND_NONE; + break; + default: + ALOGW("invalid blend mode %d", blend_mode); + win_attr->blend = TEGRA_ADF_BLEND_NONE; + } + + win_attr->x = ((uint32_t) ceil(source_crop.left)) << 12; + win_attr->y = ((uint32_t) ceil(source_crop.top)) << 12; + win_attr->out_x = display_frame.left; + win_attr->out_y = display_frame.top; + win_attr->out_w = display_frame.right - display_frame.left; + win_attr->out_h = display_frame.bottom - display_frame.top; + win_attr->z = z_order; + win_attr->flags = 0; + + gralloc.get_surfaces(handle, &surf, &surf_cnt); + if (!surf || surf_cnt == 0) { + ALOGE("failed to get surfaces"); + return HWC2_ERROR_NO_RESOURCES; + } + + layout = gralloc.get_layout(surf, 0); + if (layout == HWC2_WINDOW_CAP_TILED) + win_attr->flags |= TEGRA_FB_WIN_FLAG_TILED; + + if (layout == HWC2_WINDOW_CAP_BLOCK_LINEAR) { + win_attr->flags |= TEGRA_DC_EXT_FLIP_FLAG_BLOCKLINEAR; + win_attr->block_height_log2 = gralloc.get_block_height_log2(surf, 0); + } + + win_attr->flags |= TEGRA_DC_EXT_FLIP_FLAG_GLOBAL_ALPHA; + win_attr->global_alpha = (uint8_t) (plane_alpha * 0xFF); + + if (transform & HWC_TRANSFORM_FLIP_H) + win_attr->flags |= TEGRA_DC_EXT_FLIP_FLAG_INVERT_H; + + if (transform & HWC_TRANSFORM_FLIP_V) + win_attr->flags |= TEGRA_DC_EXT_FLIP_FLAG_INVERT_V; + + if (transform & HWC_TRANSFORM_ROT_90) { + win_attr->flags |= TEGRA_DC_EXT_FLIP_FLAG_SCAN_COLUMN; + win_attr->flags ^= TEGRA_DC_EXT_FLIP_FLAG_INVERT_V; + } + + return HWC2_ERROR_NONE; +} + void hwc2_buffer::close_acquire_fence() { if (acquire_fence >= 0) { diff --git a/hwc2/hwc2_dev.cpp b/hwc2/hwc2_dev.cpp index 9af6a56..5b4eec9 100644 --- a/hwc2/hwc2_dev.cpp +++ b/hwc2/hwc2_dev.cpp @@ -49,7 +49,8 @@ const struct adf_hwc_event_callbacks hwc2_adfhwc_callbacks = { }; hwc2_dev::hwc2_dev() - : callback_handler(), + : state_mutex(), + callback_handler(), displays(), adf_helper(nullptr) { } @@ -88,6 +89,8 @@ hwc2_error_t hwc2_dev::get_display_type(hwc2_display_t dpy_id, hwc2_error_t hwc2_dev::set_power_mode(hwc2_display_t dpy_id, hwc2_power_mode_t mode) { + std::lock_guard guard(state_mutex); + auto it = displays.find(dpy_id); if (it == displays.end()) { ALOGE("dpy %" PRIu64 ": invalid display handle", dpy_id); @@ -161,6 +164,34 @@ hwc2_error_t hwc2_dev::accept_display_changes(hwc2_display_t dpy_id) return it->second.accept_display_changes(); } +hwc2_error_t hwc2_dev::present_display(hwc2_display_t dpy_id, + int32_t *out_present_fence) +{ + std::lock_guard guard(state_mutex); + + auto it = displays.find(dpy_id); + if (it == displays.end()) { + ALOGE("dpy %" PRIu64 ": invalid display handle", dpy_id); + return HWC2_ERROR_BAD_DISPLAY; + } + + return it->second.present_display(out_present_fence); +} + +hwc2_error_t hwc2_dev::get_release_fences(hwc2_display_t dpy_id, + uint32_t *out_num_elements, hwc2_layer_t *out_layers, + int32_t *out_fences) const +{ + auto it = displays.find(dpy_id); + if (it == displays.end()) { + ALOGE("dpy %" PRIu64 ": invalid display handle", dpy_id); + return HWC2_ERROR_BAD_DISPLAY; + } + + return it->second.get_release_fences(out_num_elements, out_layers, + out_fences); +} + hwc2_error_t hwc2_dev::get_display_attribute(hwc2_display_t dpy_id, hwc2_config_t config, hwc2_attribute_t attribute, int32_t *out_value) const @@ -354,16 +385,20 @@ hwc2_error_t hwc2_dev::set_cursor_position(hwc2_display_t dpy_id, void hwc2_dev::hotplug(hwc2_display_t dpy_id, hwc2_connection_t connection) { - auto it = displays.find(dpy_id); - if (it == displays.end()) { - ALOGW("dpy %" PRIu64 ": invalid display handle preventing hotplug" - " callback", dpy_id); - return; - } + { + std::lock_guard guard(state_mutex); - hwc2_error_t ret = it->second.set_connection(connection); - if (ret != HWC2_ERROR_NONE) - return; + auto it = displays.find(dpy_id); + if (it == displays.end()) { + ALOGW("dpy %" PRIu64 ": invalid display handle preventing hotplug" + " callback", dpy_id); + return; + } + + hwc2_error_t ret = it->second.set_connection(connection); + if (ret != HWC2_ERROR_NONE) + return; + } callback_handler.call_hotplug(dpy_id, connection); } @@ -470,6 +505,7 @@ int hwc2_dev::open_adf_device() dpy.second.get_id(), strerror(ret)); goto err_rtrv; } + dpy.second.set_client_target_properties(); } for (auto &dpy: displays) diff --git a/hwc2/hwc2_display.cpp b/hwc2/hwc2_display.cpp index ff3fba6..fd24e4c 100644 --- a/hwc2/hwc2_display.cpp +++ b/hwc2/hwc2_display.cpp @@ -15,8 +15,10 @@ */ #include +#include #include +#include #include #include #include @@ -42,6 +44,7 @@ hwc2_display::hwc2_display(hwc2_display_t id, int adf_intf_fd, configs(), active_config(0), power_mode(power_mode), + release_fence(-1), adf_intf_fd(adf_intf_fd), adf_dev(adf_dev) { @@ -306,6 +309,158 @@ hwc2_error_t hwc2_display::accept_display_changes() return HWC2_ERROR_NONE; } +hwc2_error_t hwc2_display::present_display(int32_t *out_present_fence) +{ + std::vector adf_bufs(windows.size()); + std::array interfaces = {{0}}; + int new_release_fence = -1, err; + + hwc2_error_t ret = prepare_present_display(); + if (ret != HWC2_ERROR_NONE) { + ALOGE("dpy %" PRIu64 ": failed to prepare display for presenting", id); + *out_present_fence = -1; + return ret; + } + + tegra_adf_flip *args; + size_t args_size = sizeof(*args) + windows.size() * sizeof(args->win[0]); + + args = static_cast(calloc(1, args_size)); + if (!args) { + ALOGE("dpy %" PRIu64 ": failed to alloc tegra_adf_flip", id); + *out_present_fence = -1; + return HWC2_ERROR_NO_RESOURCES; + } + + args->win_num = windows.size(); + + size_t win_idx = 0, buf_idx = 0; + for (auto &win: windows) { + if (win.contains_client_target()) { + + ret = client_target.get_adf_post_props(&args->win[win_idx], + &adf_bufs[buf_idx], win_idx, buf_idx, win.get_z_order()); + if (ret != HWC2_ERROR_NONE) { + ALOGE("dpy %" PRIu64 ": failed to get client target adf props", id); + goto done; + } + buf_idx++; + + } else if (win.contains_layer()) { + hwc2_layer_t lyr_id = win.get_layer(); + + ret = layers.find(lyr_id)->second.get_adf_post_props( + &args->win[win_idx], &adf_bufs[buf_idx], win_idx, + buf_idx, win.get_z_order()); + if (ret != HWC2_ERROR_NONE) { + ALOGE("dpy %" PRIu64 " lyr %" PRIu64 ": failed to get layer adf" + " props", id, lyr_id); + goto done; + } + buf_idx++; + + } else { + struct tegra_adf_flip_windowattr *win_attr = &args->win[win_idx]; + win_attr->win_index = win_idx; + win_attr->buf_index = -1; + win_attr->z = win.get_z_order(); + win_attr->blend = TEGRA_ADF_BLEND_NONE; + win_attr->flags = 0; + } + + win_idx++; + } + + err = adf_device_post_v2(&adf_dev, interfaces.data(), interfaces.size(), + adf_bufs.data(), buf_idx, args, args_size, ADF_COMPLETE_FENCE_PRESENT, + &new_release_fence); + if (err < 0) { + ALOGE("dpy %" PRIu64 ": adf_device_post_v2 failed %s", id, strerror(err)); + err = HWC2_ERROR_NO_RESOURCES; + new_release_fence = -1; + } + + release_fence.reset(new_release_fence); + + close_acquire_fences(); + + for (size_t idx = 0; idx < buf_idx; idx++) + if (adf_bufs[idx].fd[0] >= 0) + close(adf_bufs[idx].fd[0]); + +done: + free(args); + *out_present_fence = dup(release_fence.get()); + return ret; +} + +hwc2_error_t hwc2_display::prepare_present_display() +{ + if (display_state != valid) { + ALOGE("dpy %" PRIu64 ": display not validated: %d", id, display_state); + return HWC2_ERROR_NOT_VALIDATED; + } + + if (connection != HWC2_CONNECTION_CONNECTED) { + ALOGW("dpy %" PRIu64 ": invalid connection: %d", id, connection); + return HWC2_ERROR_BAD_DISPLAY; + } + + if (power_mode == HWC2_POWER_MODE_OFF) { + ALOGW("dpy %" PRIu64 ": invalid power mode: %d", id, power_mode); + return HWC2_ERROR_BAD_DISPLAY; + } + + hwc2_error_t ret = decompress_window_buffers(); + if (ret != HWC2_ERROR_NONE) { + ALOGE("dpy %" PRIu64 ": failed to decompress buffers", id); + return ret; + } + + return HWC2_ERROR_NONE; +} + + +void hwc2_display::close_acquire_fences() +{ + for (auto &lyr: layers) + lyr.second.close_acquire_fence(); + + if (client_target_used) + client_target.close_acquire_fence(); +} + +hwc2_error_t hwc2_display::get_release_fences(uint32_t *out_num_elements, + hwc2_layer_t *out_layers, int32_t *out_fences) const +{ + if (release_fence.get() < 0) { + *out_num_elements = 0; + return HWC2_ERROR_NONE; + } + + size_t num = 0; + + if (!out_layers || !out_fences) { + for (auto &window: windows) + if (window.contains_layer()) + num++; + *out_num_elements = num; + return HWC2_ERROR_NONE; + } + + for (auto it = windows.begin(); num < *out_num_elements, + it != windows.end(); it++) { + if (it->contains_layer()) { + out_layers[num] = it->get_layer(); + out_fences[num] = dup(release_fence.get()); + num++; + } + } + + *out_num_elements = num; + return HWC2_ERROR_NONE; +} + void hwc2_display::init_windows() { for (auto it = windows.begin(); it != windows.end(); it++) @@ -342,6 +497,30 @@ hwc2_error_t hwc2_display::assign_layer_window(uint32_t z_order, return HWC2_ERROR_NO_RESOURCES; } +hwc2_error_t hwc2_display::decompress_window_buffers() +{ + hwc2_error_t ret; + + for (auto &win: windows) { + if (win.contains_client_target()) { + ret = client_target.decompress(); + if (ret != HWC2_ERROR_NONE) { + ALOGE("dpy %" PRIu64 ": failed to decompress client target" + " buffer", id); + return ret; + } + } else if (win.contains_layer()) { + ret = layers.at(win.get_layer()).decompress_buffer(); + if (ret != HWC2_ERROR_NONE) { + ALOGE("dpy %" PRIu64 " lyr %" PRIu64 ": failed to decompress" + " layer buffer", id, win.get_layer()); + return ret; + } + } + } + return HWC2_ERROR_NONE; +} + int hwc2_display::retrieve_display_configs(struct adf_hwc_helper *adf_helper) { size_t num_configs = 0; @@ -454,6 +633,7 @@ hwc2_error_t hwc2_display::set_active_config( } active_config = config; + set_client_target_properties(); return HWC2_ERROR_NONE; } @@ -510,6 +690,31 @@ hwc2_error_t hwc2_display::set_client_target(buffer_handle_t handle, return client_target.set_surface_damage(surface_damage); } +hwc2_error_t hwc2_display::set_client_target_properties() +{ + int32_t width = configs.at(active_config).get_attribute(HWC2_ATTRIBUTE_WIDTH); + int32_t height = configs.at(active_config).get_attribute(HWC2_ATTRIBUTE_HEIGHT); + + hwc_rect_t frame; + frame.left = 0; + frame.top = 0; + frame.right = width; + frame.bottom = height; + client_target.set_display_frame(frame); + + hwc_frect_t crop; + crop.left = 0.0; + crop.top = 0.0; + crop.right = static_cast(width); + crop.bottom = static_cast(height); + client_target.set_source_crop(crop); + + client_target.set_blend_mode(HWC2_BLEND_MODE_PREMULTIPLIED); + client_target.set_z_order(UINT32_MAX); + + return HWC2_ERROR_NONE; +} + hwc2_error_t hwc2_display::create_layer(hwc2_layer_t *out_layer) { display_state = modified; diff --git a/hwc2/hwc2_gralloc.cpp b/hwc2/hwc2_gralloc.cpp index 0b82b45..db6220f 100644 --- a/hwc2/hwc2_gralloc.cpp +++ b/hwc2/hwc2_gralloc.cpp @@ -40,7 +40,11 @@ #define NVGR_GET_STRUCT_MEMBER(ptr, member_type, member_offset) \ (*((member_type *)((char *) ptr + member_offset))) -#define NVGR_SURFACE_OFFSET_LAYOUT 12 +#define NVGR_SURFACE_OFFSET_LAYOUT 12 +#define NVGR_SURFACE_OFFSET_PITCH 16 +#define NVGR_SURFACE_OFFSET_HMEM 20 +#define NVGR_SURFACE_OFFSET_OFFSET 24 +#define NVGR_SURFACE_OFFSET_BLOCK_HEIGHT_LOG2 32 hwc2_gralloc::hwc2_gralloc() { @@ -64,6 +68,15 @@ hwc2_gralloc::hwc2_gralloc() *(void **)(&nvgr_get_surfaces) = dlsym(nvgr, "nvgr_get_surfaces"); LOG_ALWAYS_FATAL_IF(!nvgr_get_surfaces, "failed to find nvgr_get_surfaces" " symbol"); + + *(void **)(&NvRmMemDmaBufFdFromHandle) = dlsym(nvgr, + "NvRmMemDmaBufFdFromHandle"); + LOG_ALWAYS_FATAL_IF(!NvRmMemDmaBufFdFromHandle, "failed to find" + " NvRmMemDmaBufFdFromHandle symbol"); + + *(void **)(&nvgr_decompress) = dlsym(nvgr, "nvgr_decompress"); + LOG_ALWAYS_FATAL_IF(!nvgr_decompress, "failed to find nvgr_decompress" + " symbol"); } hwc2_gralloc::~hwc2_gralloc() @@ -120,6 +133,12 @@ void hwc2_gralloc::get_surfaces(buffer_handle_t handle, nvgr_get_surfaces(handle, surf, surf_cnt); } +void hwc2_gralloc::get_dma_buf(const void *surf, uint32_t surf_idx, + int *out_fd) const +{ + NvRmMemDmaBufFdFromHandle(get_hmem(surf, surf_idx), out_fd); +} + int32_t hwc2_gralloc::get_layout(const void *surf, uint32_t surf_idx) const { uint32_t layout = NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx), @@ -137,3 +156,33 @@ int32_t hwc2_gralloc::get_layout(const void *surf, uint32_t surf_idx) const return -1; } } + +uint32_t hwc2_gralloc::get_pitch(const void *surf, uint32_t surf_idx) const +{ + return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx), + uint32_t, NVGR_SURFACE_OFFSET_PITCH); +} + +uint32_t hwc2_gralloc::get_hmem(const void *surf, uint32_t surf_idx) const +{ + return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx), + uint32_t, NVGR_SURFACE_OFFSET_HMEM); +} + +uint32_t hwc2_gralloc::get_offset(const void *surf, uint32_t surf_idx) const +{ + return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx), + uint32_t, NVGR_SURFACE_OFFSET_OFFSET); +} + +uint32_t hwc2_gralloc::get_block_height_log2(const void *surf, uint32_t surf_idx) const +{ + return NVGR_GET_STRUCT_MEMBER(NVGR_GET_SURFACE(surf, surf_idx), + uint32_t, NVGR_SURFACE_OFFSET_BLOCK_HEIGHT_LOG2); +} + +uint32_t hwc2_gralloc::decompress(buffer_handle_t handle, int in_fence, + int *out_fence) const +{ + return nvgr_decompress(handle, in_fence, out_fence); +} diff --git a/hwc2/hwc2_layer.cpp b/hwc2/hwc2_layer.cpp index ec7eb54..2c24d95 100644 --- a/hwc2/hwc2_layer.cpp +++ b/hwc2/hwc2_layer.cpp @@ -27,6 +27,19 @@ hwc2_layer::hwc2_layer(hwc2_layer_t id) comp_type(HWC2_COMPOSITION_INVALID), modified(true) { } +hwc2_error_t hwc2_layer::decompress_buffer() +{ + return buffer.decompress(); +} + +hwc2_error_t hwc2_layer::get_adf_post_props( + struct tegra_adf_flip_windowattr *win_attr, + struct adf_buffer_config *adf_buf, size_t win_idx, + size_t buf_idx, uint32_t z_order) const +{ + return buffer.get_adf_post_props(win_attr, adf_buf, win_idx, buf_idx, z_order); +} + buffer_handle_t hwc2_layer::get_buffer_handle() const { return buffer.get_buffer_handle(); diff --git a/hwc2/include/tegra_dc_ext.h b/hwc2/include/tegra_dc_ext.h new file mode 100644 index 0000000..c95c927 --- /dev/null +++ b/hwc2/include/tegra_dc_ext.h @@ -0,0 +1,394 @@ +/**************************************************************************** + **************************************************************************** + *** + *** This header was automatically generated from a Linux kernel header + *** of the same name, to make information necessary for userspace to + *** call into the kernel available to libc. It contains only constants, + *** structures, and macros generated from the original header, and thus, + *** contains no copyrightable information. + *** + *** To edit the content of this header, modify the corresponding + *** source file (e.g. under external/kernel-headers/original/) then + *** run bionic/libc/kernel/tools/update_all.py + *** + *** Any manual change here will be lost the next time this script will + *** be run. You've been warned! + *** + **************************************************************************** + ****************************************************************************/ +#ifndef __TEGRA_DC_EXT_H +#define __TEGRA_DC_EXT_H +#include +#include +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#include +#include +#define TEGRA_DC_EXT_FMT_P1 0 +#define TEGRA_DC_EXT_FMT_P2 1 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_P4 2 +#define TEGRA_DC_EXT_FMT_P8 3 +#define TEGRA_DC_EXT_FMT_B4G4R4A4 4 +#define TEGRA_DC_EXT_FMT_B5G5R5A 5 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_B5G6R5 6 +#define TEGRA_DC_EXT_FMT_AB5G5R5 7 +#define TEGRA_DC_EXT_FMT_B8G8R8A8 12 +#define TEGRA_DC_EXT_FMT_R8G8B8A8 13 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_B6x2G6x2R6x2A8 14 +#define TEGRA_DC_EXT_FMT_R6x2G6x2B6x2A8 15 +#define TEGRA_DC_EXT_FMT_YCbCr422 16 +#define TEGRA_DC_EXT_FMT_YUV422 17 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_YCbCr420P 18 +#define TEGRA_DC_EXT_FMT_YUV420P 19 +#define TEGRA_DC_EXT_FMT_YCbCr422P 20 +#define TEGRA_DC_EXT_FMT_YUV422P 21 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_YCbCr422R 22 +#define TEGRA_DC_EXT_FMT_YUV422R 23 +#define TEGRA_DC_EXT_FMT_YCbCr422RA 24 +#define TEGRA_DC_EXT_FMT_YUV422RA 25 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_YCbCr444P 41 +#define TEGRA_DC_EXT_FMT_YUV444P 52 +#define TEGRA_DC_EXT_FMT_YCrCb420SP 42 +#define TEGRA_DC_EXT_FMT_YCbCr420SP 43 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_YCrCb422SP 44 +#define TEGRA_DC_EXT_FMT_YCbCr422SP 45 +#define TEGRA_DC_EXT_FMT_YVU420SP 53 +#define TEGRA_DC_EXT_FMT_YUV420SP 54 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_YVU422SP 55 +#define TEGRA_DC_EXT_FMT_YUV422SP 56 +#define TEGRA_DC_EXT_FMT_YVU444SP 59 +#define TEGRA_DC_EXT_FMT_YUV444SP 60 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_SHIFT 0 +#define TEGRA_DC_EXT_FMT_MASK (0xff << TEGRA_DC_EXT_FMT_SHIFT) +#define TEGRA_DC_EXT_FMT_BYTEORDER_NOSWAP (0 << 8) +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAP2 (1 << 8) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAP4 (2 << 8) +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAP4HW (3 << 8) +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAP02 (4 << 8) +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAPLEFT (5 << 8) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FMT_BYTEORDER_SHIFT 8 +#define TEGRA_DC_EXT_FMT_BYTEORDER_MASK (0x0f << TEGRA_DC_EXT_FMT_BYTEORDER_SHIFT) +#define TEGRA_DC_EXT_BLEND_NONE 0 +#define TEGRA_DC_EXT_BLEND_PREMULT 1 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_BLEND_COVERAGE 2 +#define TEGRA_DC_EXT_FLIP_FLAG_INVERT_H (1 << 0) +#define TEGRA_DC_EXT_FLIP_FLAG_INVERT_V (1 << 1) +#define TEGRA_DC_EXT_FLIP_FLAG_TILED (1 << 2) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FLIP_FLAG_CURSOR (1 << 3) +#define TEGRA_DC_EXT_FLIP_FLAG_GLOBAL_ALPHA (1 << 4) +#define TEGRA_DC_EXT_FLIP_FLAG_BLOCKLINEAR (1 << 5) +#define TEGRA_DC_EXT_FLIP_FLAG_SCAN_COLUMN (1 << 6) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FLIP_FLAG_INTERLACE (1 << 7) +#define TEGRA_DC_EXT_FLIP_FLAG_UPDATE_CSC (1 << 9) +struct tegra_timespec { + __s32 tv_sec; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __s32 tv_nsec; +}; +struct tegra_dc_ext_flip_windowattr { + __s32 index; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 buff_id; + __u32 blend; + __u32 offset; + __u32 offset_u; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 offset_v; + __u32 stride; + __u32 stride_uv; + __u32 pixformat; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 x; + __u32 y; + __u32 w; + __u32 h; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 out_x; + __u32 out_y; + __u32 out_w; + __u32 out_h; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 z; + __u32 swap_interval; + struct tegra_timespec timestamp; + union { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + struct { + __u32 pre_syncpt_id; + __u32 pre_syncpt_val; + }; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __s32 pre_syncpt_fd; + }; + __u32 buff_id_u; + __u32 buff_id_v; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 flags; + __u8 global_alpha; + __u8 block_height_log2; + __u8 pad1[2]; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + union { + struct { + __u32 offset2; + __u32 offset_u2; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 offset_v2; + __u32 pad2[1]; + }; + struct { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u16 yof; + __u16 kyrgb; + __u16 kur; + __u16 kvr; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u16 kug; + __u16 kvg; + __u16 kub; + __u16 kvb; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + } csc; + }; +}; +#define TEGRA_DC_EXT_FLIP_N_WINDOWS 3 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +struct tegra_dc_ext_flip { + struct tegra_dc_ext_flip_windowattr win[TEGRA_DC_EXT_FLIP_N_WINDOWS]; + __u32 post_syncpt_id; + __u32 post_syncpt_val; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +}; +struct tegra_dc_ext_flip_2 { + struct tegra_dc_ext_flip_windowattr * win; + __u8 win_num; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u8 reserved1; + __u16 reserved2; + __u32 post_syncpt_id; + __u32 post_syncpt_val; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u16 dirty_rect[4]; +}; +struct tegra_dc_ext_flip_3 { + __u64 win; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u8 win_num; + __u8 reserved1; + __u16 reserved2; + __s32 post_syncpt_fd; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u16 dirty_rect[4]; +}; +struct tegra_dc_ext_set_vblank { + __u8 enable; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u8 reserved[3]; +}; +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_32x32 ((1 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_64x64 ((2 & 0x7) << 0) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_128x128 ((3 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_256x256 ((4 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE(x) (((x) & 0x7) >> 0) +#define TEGRA_DC_EXT_CURSOR_FORMAT_2BIT_LEGACY (0) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_CURSOR_FORMAT_RGBA_NON_PREMULT_ALPHA (1) +#define TEGRA_DC_EXT_CURSOR_FORMAT_RGBA_PREMULT_ALPHA (3) +#define TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_2BIT_LEGACY (TEGRA_DC_EXT_CURSOR_FORMAT_2BIT_LEGACY << 16) +#define TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_RGBA_NON_PREMULT_ALPHA (TEGRA_DC_EXT_CURSOR_FORMAT_RGBA_NON_PREMULT_ALPHA << 16) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_RGBA_PREMULT_ALPHA (TEGRA_DC_EXT_CURSOR_FORMAT_RGBA_PREMULT_ALPHA << 16) +#define TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS(x) (((x) >> 16) & 0x7) +#define TEGRA_DC_EXT_CURSOR_FLAGS_RGBA_NORMAL TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_RGBA_NON_PREMULT_ALPHA +#define TEGRA_DC_EXT_CURSOR_FLAGS_2BIT_LEGACY TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_2BIT_LEGACY +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +enum CR_MODE { + legacy, + normal, +}; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +struct tegra_dc_ext_cursor_image { + struct { + __u8 r; + __u8 g; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u8 b; + } foreground, background; + __u32 buff_id; + __u32 flags; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __s16 x; + __s16 y; + __u32 vis; + enum CR_MODE mode; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +}; +#define TEGRA_DC_EXT_CURSOR_FLAGS_VISIBLE (1 << 0) +struct tegra_dc_ext_cursor { + __s16 x; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __s16 y; + __u32 flags; +}; +struct tegra_dc_ext_csc { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 win_index; + __u16 yof; + __u16 kyrgb; + __u16 kur; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u16 kvr; + __u16 kug; + __u16 kvg; + __u16 kub; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u16 kvb; +}; +struct tegra_dc_ext_cmu { + __u16 cmu_enable; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u16 csc[9]; + __u16 lut1[256]; + __u16 lut2[960]; +}; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +struct tegra_dc_ext_lut { + __u32 win_index; + __u32 flags; + __u32 start; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 len; + __u16 * r; + __u16 * g; + __u16 * b; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +}; +#define TEGRA_DC_EXT_LUT_FLAGS_FBOVERRIDE 0x01 +#define TEGRA_DC_EXT_FLAGS_ENABLED 1 +struct tegra_dc_ext_status { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 flags; + __u32 pad[3]; +}; +struct tegra_dc_ext_feature { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 length; + __u32 * entries; +}; +#define TEGRA_DC_EXT_SET_NVMAP_FD _IOW('D', 0x00, __s32) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_GET_WINDOW _IOW('D', 0x01, __u32) +#define TEGRA_DC_EXT_PUT_WINDOW _IOW('D', 0x02, __u32) +#define TEGRA_DC_EXT_FLIP _IOWR('D', 0x03, struct tegra_dc_ext_flip) +#define TEGRA_DC_EXT_GET_CURSOR _IO('D', 0x04) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_PUT_CURSOR _IO('D', 0x05) +#define TEGRA_DC_EXT_SET_CURSOR_IMAGE _IOW('D', 0x06, struct tegra_dc_ext_cursor_image) +#define TEGRA_DC_EXT_SET_CURSOR _IOW('D', 0x07, struct tegra_dc_ext_cursor) +#define TEGRA_DC_EXT_SET_CSC _IOW('D', 0x08, struct tegra_dc_ext_csc) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_GET_STATUS _IOR('D', 0x09, struct tegra_dc_ext_status) +#define TEGRA_DC_EXT_GET_VBLANK_SYNCPT _IOR('D', 0x09, __u32) +#define TEGRA_DC_EXT_SET_LUT _IOW('D', 0x0A, struct tegra_dc_ext_lut) +#define TEGRA_DC_EXT_GET_FEATURES _IOW('D', 0x0B, struct tegra_dc_ext_feature) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_CURSOR_CLIP _IOW('D', 0x0C, __s32) +#define TEGRA_DC_EXT_SET_CMU _IOW('D', 0x0D, struct tegra_dc_ext_cmu) +#define TEGRA_DC_EXT_FLIP2 _IOWR('D', 0x0E, struct tegra_dc_ext_flip_2) +#define TEGRA_DC_EXT_GET_CMU _IOR('D', 0x0F, struct tegra_dc_ext_cmu) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_GET_CUSTOM_CMU _IOR('D', 0x10, struct tegra_dc_ext_cmu) +#define TEGRA_DC_EXT_SET_CURSOR_IMAGE_LOW_LATENCY _IOW('D', 0x11, struct tegra_dc_ext_cursor_image) +#define TEGRA_DC_EXT_SET_CURSOR_LOW_LATENCY _IOW('D', 0x12, struct tegra_dc_ext_cursor_image) +#define TEGRA_DC_EXT_SET_PROPOSED_BW _IOR('D', 0x13, struct tegra_dc_ext_flip_2) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_FLIP3 _IOWR('D', 0x14, struct tegra_dc_ext_flip_3) +#define TEGRA_DC_EXT_SET_VBLANK _IOW('D', 0x15, struct tegra_dc_ext_set_vblank) +enum tegra_dc_ext_control_output_type { + TEGRA_DC_EXT_DSI, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + TEGRA_DC_EXT_LVDS, + TEGRA_DC_EXT_VGA, + TEGRA_DC_EXT_HDMI, + TEGRA_DC_EXT_DVI, +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + TEGRA_DC_EXT_DP, +}; +struct tegra_dc_ext_control_output_properties { + __u32 handle; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + enum tegra_dc_ext_control_output_type type; + __u32 connected; + __s32 associated_head; + __u32 head_mask; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +}; +struct tegra_dc_ext_control_output_edid { + __u32 handle; + __u32 size; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + void * data; +}; +struct tegra_dc_ext_event { + __u32 type; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 data_size; + char data[0]; +}; +#define TEGRA_DC_EXT_EVENT_HOTPLUG (1 << 0) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +struct tegra_dc_ext_control_event_hotplug { + __u32 handle; +}; +#define TEGRA_DC_EXT_EVENT_VBLANK (1 << 1) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +struct tegra_dc_ext_control_event_vblank { + __u32 handle; + __u32 reserved; + __u64 timestamp_ns; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +}; +#define TEGRA_DC_EXT_EVENT_BANDWIDTH_INC (1 << 2) +#define TEGRA_DC_EXT_EVENT_BANDWIDTH_DEC (1 << 3) +struct tegra_dc_ext_control_event_bandwidth { +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 handle; + __u32 total_bw; + __u32 avail_bw; + __u32 resvd_bw; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +}; +#define TEGRA_DC_EXT_CAPABILITIES_CURSOR_MODE (1 << 0) +#define TEGRA_DC_EXT_CAPABILITIES_BLOCKLINEAR (1 << 1) +#define TEGRA_DC_EXT_CAPABILITIES_CURSOR_TWO_COLOR (1 << 2) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_CAPABILITIES_CURSOR_RGBA_NON_PREMULT_ALPHA (1 << 3) +#define TEGRA_DC_EXT_CAPABILITIES_CURSOR_RGBA_PREMULT_ALPHA (1 << 4) +struct tegra_dc_ext_control_capabilities { + __u32 caps; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 pad[3]; +}; +#define TEGRA_DC_EXT_CONTROL_GET_NUM_OUTPUTS _IOR('C', 0x00, __u32) +#define TEGRA_DC_EXT_CONTROL_GET_OUTPUT_PROPERTIES _IOWR('C', 0x01, struct tegra_dc_ext_control_output_properties) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_DC_EXT_CONTROL_GET_OUTPUT_EDID _IOWR('C', 0x02, struct tegra_dc_ext_control_output_edid) +#define TEGRA_DC_EXT_CONTROL_SET_EVENT_MASK _IOW('C', 0x03, __u32) +#define TEGRA_DC_EXT_CONTROL_GET_CAPABILITIES _IOR('C', 0x04, struct tegra_dc_ext_control_capabilities) +#endif +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + diff --git a/hwc2/include/tegrafb.h b/hwc2/include/tegrafb.h new file mode 100644 index 0000000..8bdf464 --- /dev/null +++ b/hwc2/include/tegrafb.h @@ -0,0 +1,105 @@ +/**************************************************************************** + **************************************************************************** + *** + *** This header was automatically generated from a Linux kernel header + *** of the same name, to make information necessary for userspace to + *** call into the kernel available to libc. It contains only constants, + *** structures, and macros generated from the original header, and thus, + *** contains no copyrightable information. + *** + *** To edit the content of this header, modify the corresponding + *** source file (e.g. under external/kernel-headers/original/) then + *** run bionic/libc/kernel/tools/update_all.py + *** + *** Any manual change here will be lost the next time this script will + *** be run. You've been warned! + *** + **************************************************************************** + ****************************************************************************/ +#ifndef _LINUX_TEGRAFB_H_ +#define _LINUX_TEGRAFB_H_ +#include +#include +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#include +#define TEGRA_FB_WIN_FMT_P1 0 +#define TEGRA_FB_WIN_FMT_P2 1 +#define TEGRA_FB_WIN_FMT_P4 2 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_FB_WIN_FMT_P8 3 +#define TEGRA_FB_WIN_FMT_B4G4R4A4 4 +#define TEGRA_FB_WIN_FMT_B5G5R5A 5 +#define TEGRA_FB_WIN_FMT_B5G6R5 6 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_FB_WIN_FMT_AB5G5R5 7 +#define TEGRA_FB_WIN_FMT_B8G8R8A8 12 +#define TEGRA_FB_WIN_FMT_R8G8B8A8 13 +#define TEGRA_FB_WIN_FMT_B6x2G6x2R6x2A8 14 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_FB_WIN_FMT_R6x2G6x2B6x2A8 15 +#define TEGRA_FB_WIN_FMT_YCbCr422 16 +#define TEGRA_FB_WIN_FMT_YUV422 17 +#define TEGRA_FB_WIN_FMT_YCbCr420P 18 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_FB_WIN_FMT_YUV420P 19 +#define TEGRA_FB_WIN_FMT_YCbCr422P 20 +#define TEGRA_FB_WIN_FMT_YUV422P 21 +#define TEGRA_FB_WIN_FMT_YCbCr422R 22 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_FB_WIN_FMT_YUV422R 23 +#define TEGRA_FB_WIN_FMT_YCbCr422RA 24 +#define TEGRA_FB_WIN_FMT_YUV422RA 25 +#define TEGRA_FB_WIN_BLEND_NONE 0 +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_FB_WIN_BLEND_PREMULT 1 +#define TEGRA_FB_WIN_BLEND_COVERAGE 2 +#define TEGRA_FB_WIN_FLAG_INVERT_H (1 << 0) +#define TEGRA_FB_WIN_FLAG_INVERT_V (1 << 1) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_FB_WIN_FLAG_TILED (1 << 2) +struct tegra_fb_windowattr { + __s32 index; + __u32 buff_id; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 flags; + __u32 blend; + __u32 offset; + __u32 offset_u; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 offset_v; + __u32 stride; + __u32 stride_uv; + __u32 pixformat; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 x; + __u32 y; + __u32 w; + __u32 h; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 out_x; + __u32 out_y; + __u32 out_w; + __u32 out_h; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 z; + __u32 pre_syncpt_id; + __u32 pre_syncpt_val; +}; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define TEGRA_FB_FLIP_N_WINDOWS 3 +struct tegra_fb_flip_args { + struct tegra_fb_windowattr win[TEGRA_FB_FLIP_N_WINDOWS]; + __u32 post_syncpt_id; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 post_syncpt_val; +}; +struct tegra_fb_modedb { + struct fb_var_screeninfo *modedb; +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ + __u32 modedb_len; +}; +#define FBIO_TEGRA_SET_NVMAP_FD _IOW('F', 0x40, __u32) +#define FBIO_TEGRA_FLIP _IOW('F', 0x41, struct tegra_fb_flip_args) +/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ +#define FBIO_TEGRA_GET_MODEDB _IOWR('F', 0x42, struct tegra_fb_modedb) +#endif diff --git a/hwc2/original-kernel-headers/tegra_dc_ext.h b/hwc2/original-kernel-headers/tegra_dc_ext.h new file mode 100644 index 0000000..3f5f660 --- /dev/null +++ b/hwc2/original-kernel-headers/tegra_dc_ext.h @@ -0,0 +1,544 @@ +/* + * Copyright (C) 2011-2014, NVIDIA Corporation. All rights reserved. + * + * Author: Robert Morell + * Some code based on fbdev extensions written by: + * Erik Gilling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __TEGRA_DC_EXT_H +#define __TEGRA_DC_EXT_H + +#include +#include +#if defined(__KERNEL__) +# include +#else +# include +# include +#endif + +/* pixformat - color format */ +#define TEGRA_DC_EXT_FMT_P1 0 +#define TEGRA_DC_EXT_FMT_P2 1 +#define TEGRA_DC_EXT_FMT_P4 2 +#define TEGRA_DC_EXT_FMT_P8 3 +#define TEGRA_DC_EXT_FMT_B4G4R4A4 4 +#define TEGRA_DC_EXT_FMT_B5G5R5A 5 +#define TEGRA_DC_EXT_FMT_B5G6R5 6 +#define TEGRA_DC_EXT_FMT_AB5G5R5 7 +#define TEGRA_DC_EXT_FMT_B8G8R8A8 12 +#define TEGRA_DC_EXT_FMT_R8G8B8A8 13 +#define TEGRA_DC_EXT_FMT_B6x2G6x2R6x2A8 14 +#define TEGRA_DC_EXT_FMT_R6x2G6x2B6x2A8 15 +#define TEGRA_DC_EXT_FMT_YCbCr422 16 +#define TEGRA_DC_EXT_FMT_YUV422 17 +#define TEGRA_DC_EXT_FMT_YCbCr420P 18 +#define TEGRA_DC_EXT_FMT_YUV420P 19 +#define TEGRA_DC_EXT_FMT_YCbCr422P 20 +#define TEGRA_DC_EXT_FMT_YUV422P 21 +#define TEGRA_DC_EXT_FMT_YCbCr422R 22 +#define TEGRA_DC_EXT_FMT_YUV422R 23 +#define TEGRA_DC_EXT_FMT_YCbCr422RA 24 +#define TEGRA_DC_EXT_FMT_YUV422RA 25 +#define TEGRA_DC_EXT_FMT_YCbCr444P 41 +#define TEGRA_DC_EXT_FMT_YUV444P 52 +#define TEGRA_DC_EXT_FMT_YCrCb420SP 42 +#define TEGRA_DC_EXT_FMT_YCbCr420SP 43 +#define TEGRA_DC_EXT_FMT_YCrCb422SP 44 +#define TEGRA_DC_EXT_FMT_YCbCr422SP 45 +#define TEGRA_DC_EXT_FMT_YVU420SP 53 +#define TEGRA_DC_EXT_FMT_YUV420SP 54 +#define TEGRA_DC_EXT_FMT_YVU422SP 55 +#define TEGRA_DC_EXT_FMT_YUV422SP 56 +#define TEGRA_DC_EXT_FMT_YVU444SP 59 +#define TEGRA_DC_EXT_FMT_YUV444SP 60 +/* color format type field is 8-bits */ +#define TEGRA_DC_EXT_FMT_SHIFT 0 +#define TEGRA_DC_EXT_FMT_MASK (0xff << TEGRA_DC_EXT_FMT_SHIFT) + +/* pixformat - byte order options ( w x y z ) */ +#define TEGRA_DC_EXT_FMT_BYTEORDER_NOSWAP (0 << 8) /* ( 3 2 1 0 ) */ +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAP2 (1 << 8) /* ( 2 3 0 1 ) */ +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAP4 (2 << 8) /* ( 0 1 2 3 ) */ +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAP4HW (3 << 8) /* ( 1 0 3 2 ) */ +/* the next two are not available on T30 or earlier */ +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAP02 (4 << 8) /* ( 3 0 1 2 ) */ +#define TEGRA_DC_EXT_FMT_BYTEORDER_SWAPLEFT (5 << 8) /* ( 2 1 0 3 ) */ +/* byte order field is 4-bits */ +#define TEGRA_DC_EXT_FMT_BYTEORDER_SHIFT 8 +#define TEGRA_DC_EXT_FMT_BYTEORDER_MASK \ + (0x0f << TEGRA_DC_EXT_FMT_BYTEORDER_SHIFT) + +#define TEGRA_DC_EXT_BLEND_NONE 0 +#define TEGRA_DC_EXT_BLEND_PREMULT 1 +#define TEGRA_DC_EXT_BLEND_COVERAGE 2 + +#define TEGRA_DC_EXT_FLIP_FLAG_INVERT_H (1 << 0) +#define TEGRA_DC_EXT_FLIP_FLAG_INVERT_V (1 << 1) +#define TEGRA_DC_EXT_FLIP_FLAG_TILED (1 << 2) +#define TEGRA_DC_EXT_FLIP_FLAG_CURSOR (1 << 3) +#define TEGRA_DC_EXT_FLIP_FLAG_GLOBAL_ALPHA (1 << 4) +#define TEGRA_DC_EXT_FLIP_FLAG_BLOCKLINEAR (1 << 5) +#define TEGRA_DC_EXT_FLIP_FLAG_SCAN_COLUMN (1 << 6) +#define TEGRA_DC_EXT_FLIP_FLAG_INTERLACE (1 << 7) +#define TEGRA_DC_EXT_FLIP_FLAG_UPDATE_CSC (1 << 9) + +struct tegra_timespec { + __s32 tv_sec; /* seconds */ + __s32 tv_nsec; /* nanoseconds */ +}; + +struct tegra_dc_ext_flip_windowattr { + __s32 index; + __u32 buff_id; + __u32 blend; + __u32 offset; + __u32 offset_u; + __u32 offset_v; + __u32 stride; + __u32 stride_uv; + __u32 pixformat; + /* + * x, y, w, h are fixed-point: 20 bits of integer (MSB) and 12 bits of + * fractional (LSB) + */ + __u32 x; + __u32 y; + __u32 w; + __u32 h; + __u32 out_x; + __u32 out_y; + __u32 out_w; + __u32 out_h; + __u32 z; + __u32 swap_interval; + struct tegra_timespec timestamp; + union { + struct { + __u32 pre_syncpt_id; + __u32 pre_syncpt_val; + }; + __s32 pre_syncpt_fd; + }; + /* These two are optional; if zero, U and V are taken from buff_id */ + __u32 buff_id_u; + __u32 buff_id_v; + __u32 flags; + __u8 global_alpha; /* requires TEGRA_DC_EXT_FLIP_FLAG_GLOBAL_ALPHA */ + /* log2(blockheight) for blocklinear format */ + __u8 block_height_log2; + __u8 pad1[2]; + union { /* fields for mutually exclusive options */ + struct { /* TEGRA_DC_EXT_FLIP_FLAG_INTERLACE */ + __u32 offset2; + __u32 offset_u2; + __u32 offset_v2; + __u32 pad2[1]; + }; + struct { /* TEGRA_DC_EXT_FLIP_FLAG_UPDATE_CSC */ + __u16 yof; /* s.7.0 */ + __u16 kyrgb; /* 2.8 */ + __u16 kur; /* s.2.8 */ + __u16 kvr; /* s.2.8 */ + __u16 kug; /* s.1.8 */ + __u16 kvg; /* s.1.8 */ + __u16 kub; /* s.2.8 */ + __u16 kvb; /* s.2.8 */ + } csc; + }; +}; + +#define TEGRA_DC_EXT_FLIP_N_WINDOWS 3 + +struct tegra_dc_ext_flip { + struct tegra_dc_ext_flip_windowattr win[TEGRA_DC_EXT_FLIP_N_WINDOWS]; + __u32 post_syncpt_id; + __u32 post_syncpt_val; +}; + +struct tegra_dc_ext_flip_2 { + struct tegra_dc_ext_flip_windowattr *win; + __u8 win_num; + __u8 reserved1; /* unused - must be 0 */ + __u16 reserved2; /* unused - must be 0 */ + __u32 post_syncpt_id; + __u32 post_syncpt_val; + __u16 dirty_rect[4]; /* x,y,w,h for partial screen update. 0 ignores */ +}; + +struct tegra_dc_ext_flip_3 { + __u64 win; /* pointer: struct tegra_dc_ext_flip_windowattr* */ + __u8 win_num; + __u8 reserved1; /* unused - must be 0 */ + __u16 reserved2; /* unused - must be 0 */ + __s32 post_syncpt_fd; + __u16 dirty_rect[4]; /* x,y,w,h for partial screen update. 0 ignores */ +}; + +/* + * vblank control - enable or disable vblank events + */ + +struct tegra_dc_ext_set_vblank { + __u8 enable; + __u8 reserved[3]; /* unused - must be 0 */ +}; + +/* + * Cursor image format: + * + * Tegra hardware supports two different cursor formats: + * + * (1) Two color cursor: foreground and background colors are + * specified by the client in RGB8. + * + * The two-color image should be specified as two 1bpp bitmaps + * immediately following each other in memory. Each pixel in the + * final cursor will be constructed from the bitmaps with the + * following logic: + * + * bitmap1 bitmap0 + * (mask) (color) + * 1 0 transparent + * 1 1 inverted + * 0 0 background color + * 0 1 foreground color + * + * This format is supported when TEGRA_DC_EXT_CONTROL_GET_CAPABILITIES + * reports the TEGRA_DC_EXT_CAPABILITIES_CURSOR_TWO_COLOR bit. + * + * (2) RGBA cursor: in this case the image is four bytes per pixel, + * with alpha in the low eight bits. + * + * The RGB components of the cursor image can be either + * premultipled by alpha: + * + * cursor[r,g,b] + desktop[r,g,b] * (1 - cursor[a]) + * + * or not: + * + * cursor[r,g,b] * cursor[a] + desktop[r,g,b] * (1 - cursor[a]) + * + * TEGRA_DC_EXT_CONTROL_GET_CAPABILITIES will report one or more of + * TEGRA_DC_EXT_CURSOR_FLAGS_RGBA{,_NON}_PREMULT_ALPHA to indicate + * which are supported on the current hardware. + * + * Specify one of TEGRA_DC_EXT_CURSOR_FLAGS to indicate the format. + * + * Exactly one of the SIZE flags must be specified. + */ + + +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_32x32 ((1 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_64x64 ((2 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_128x128 ((3 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE_256x256 ((4 & 0x7) << 0) +#define TEGRA_DC_EXT_CURSOR_IMAGE_FLAGS_SIZE(x) (((x) & 0x7) >> 0) + +#define TEGRA_DC_EXT_CURSOR_FORMAT_2BIT_LEGACY (0) +#define TEGRA_DC_EXT_CURSOR_FORMAT_RGBA_NON_PREMULT_ALPHA (1) +#define TEGRA_DC_EXT_CURSOR_FORMAT_RGBA_PREMULT_ALPHA (3) + +#define TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_2BIT_LEGACY \ + (TEGRA_DC_EXT_CURSOR_FORMAT_2BIT_LEGACY << 16) +#define TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_RGBA_NON_PREMULT_ALPHA \ + (TEGRA_DC_EXT_CURSOR_FORMAT_RGBA_NON_PREMULT_ALPHA << 16) +#define TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_RGBA_PREMULT_ALPHA \ + (TEGRA_DC_EXT_CURSOR_FORMAT_RGBA_PREMULT_ALPHA << 16) + +#define TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS(x) (((x) >> 16) & 0x7) + +/* aliases for source-level backwards compatibility */ +#define TEGRA_DC_EXT_CURSOR_FLAGS_RGBA_NORMAL \ + TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_RGBA_NON_PREMULT_ALPHA +#define TEGRA_DC_EXT_CURSOR_FLAGS_2BIT_LEGACY \ + TEGRA_DC_EXT_CURSOR_FORMAT_FLAGS_2BIT_LEGACY + +enum CR_MODE { + legacy, + normal, +}; + +struct tegra_dc_ext_cursor_image { + struct { + __u8 r; + __u8 g; + __u8 b; + } foreground, background; + __u32 buff_id; + __u32 flags; + __s16 x; + __s16 y; + __u32 vis; + enum CR_MODE mode; +}; + +/* Possible flags for struct nvdc_cursor's flags field */ +#define TEGRA_DC_EXT_CURSOR_FLAGS_VISIBLE (1 << 0) + +struct tegra_dc_ext_cursor { + __s16 x; + __s16 y; + __u32 flags; +}; + +/* + * Color conversion is performed as follows: + * + * r = sat(kyrgb * sat(y + yof) + kur * u + kvr * v) + * g = sat(kyrgb * sat(y + yof) + kug * u + kvg * v) + * b = sat(kyrgb * sat(y + yof) + kub * u + kvb * v) + * + * Coefficients should be specified as fixed-point values; the exact format + * varies for each coefficient. + * The format for each coefficient is listed below with the syntax: + * - A "s." prefix means that the coefficient has a sign bit (twos complement). + * - The first number is the number of bits in the integer component (not + * including the optional sign bit). + * - The second number is the number of bits in the fractional component. + * + * All three fields should be tightly packed, justified to the LSB of the + * 16-bit value. For example, the "s.2.8" value should be packed as: + * (MSB) 5 bits of 0, 1 bit of sign, 2 bits of integer, 8 bits of frac (LSB) + */ +struct tegra_dc_ext_csc { + __u32 win_index; + __u16 yof; /* s.7.0 */ + __u16 kyrgb; /* 2.8 */ + __u16 kur; /* s.2.8 */ + __u16 kvr; /* s.2.8 */ + __u16 kug; /* s.1.8 */ + __u16 kvg; /* s.1.8 */ + __u16 kub; /* s.2.8 */ + __u16 kvb; /* s.2.8 */ +}; + +struct tegra_dc_ext_cmu { + __u16 cmu_enable; + __u16 csc[9]; + __u16 lut1[256]; + __u16 lut2[960]; +}; + +/* + * RGB Lookup table + * + * In true-color and YUV modes this is used for post-CSC RGB->RGB lookup, i.e. + * gamma-correction. In palette-indexed RGB modes, this table designates the + * mode's color palette. + * + * To convert 8-bit per channel RGB values to 16-bit, duplicate the 8 bits + * in low and high byte, e.g. r=r|(r<<8) + * + * To just update flags, set len to 0. + * + * Current Tegra DC hardware supports 8-bit per channel to 8-bit per channel, + * and each hardware window (overlay) uses its own lookup table. + * + */ +struct tegra_dc_ext_lut { + __u32 win_index; /* window index to set lut for */ + __u32 flags; /* Flag bitmask, see TEGRA_DC_EXT_LUT_FLAGS_* */ + __u32 start; /* start index to update lut from */ + __u32 len; /* number of valid lut entries */ + __u16 *r; /* array of 16-bit red values, 0 to reset */ + __u16 *g; /* array of 16-bit green values, 0 to reset */ + __u16 *b; /* array of 16-bit blue values, 0 to reset */ +}; + +/* tegra_dc_ext_lut.flags - override global fb device lookup table. + * Default behaviour is double-lookup. + */ +#define TEGRA_DC_EXT_LUT_FLAGS_FBOVERRIDE 0x01 + +#define TEGRA_DC_EXT_FLAGS_ENABLED 1 +struct tegra_dc_ext_status { + __u32 flags; + /* Leave some wiggle room for future expansion */ + __u32 pad[3]; +}; + +struct tegra_dc_ext_feature { + __u32 length; + __u32 *entries; +}; + +#define TEGRA_DC_EXT_SET_NVMAP_FD \ + _IOW('D', 0x00, __s32) + +#define TEGRA_DC_EXT_GET_WINDOW \ + _IOW('D', 0x01, __u32) +#define TEGRA_DC_EXT_PUT_WINDOW \ + _IOW('D', 0x02, __u32) + +#define TEGRA_DC_EXT_FLIP \ + _IOWR('D', 0x03, struct tegra_dc_ext_flip) + +#define TEGRA_DC_EXT_GET_CURSOR \ + _IO('D', 0x04) +#define TEGRA_DC_EXT_PUT_CURSOR \ + _IO('D', 0x05) +#define TEGRA_DC_EXT_SET_CURSOR_IMAGE \ + _IOW('D', 0x06, struct tegra_dc_ext_cursor_image) +#define TEGRA_DC_EXT_SET_CURSOR \ + _IOW('D', 0x07, struct tegra_dc_ext_cursor) + +#define TEGRA_DC_EXT_SET_CSC \ + _IOW('D', 0x08, struct tegra_dc_ext_csc) + +#define TEGRA_DC_EXT_GET_STATUS \ + _IOR('D', 0x09, struct tegra_dc_ext_status) + +/* + * Returns the auto-incrementing vblank syncpoint for the head associated with + * this device node + */ +#define TEGRA_DC_EXT_GET_VBLANK_SYNCPT \ + _IOR('D', 0x09, __u32) + +#define TEGRA_DC_EXT_SET_LUT \ + _IOW('D', 0x0A, struct tegra_dc_ext_lut) + +#define TEGRA_DC_EXT_GET_FEATURES \ + _IOW('D', 0x0B, struct tegra_dc_ext_feature) + +#define TEGRA_DC_EXT_CURSOR_CLIP \ + _IOW('D', 0x0C, __s32) + +#define TEGRA_DC_EXT_SET_CMU \ + _IOW('D', 0x0D, struct tegra_dc_ext_cmu) + +#define TEGRA_DC_EXT_FLIP2 \ + _IOWR('D', 0x0E, struct tegra_dc_ext_flip_2) + +#define TEGRA_DC_EXT_GET_CMU \ + _IOR('D', 0x0F, struct tegra_dc_ext_cmu) + +#define TEGRA_DC_EXT_GET_CUSTOM_CMU \ + _IOR('D', 0x10, struct tegra_dc_ext_cmu) + +/* obsolete - do not use */ +#define TEGRA_DC_EXT_SET_CURSOR_IMAGE_LOW_LATENCY \ + _IOW('D', 0x11, struct tegra_dc_ext_cursor_image) + +/* obsolete - do not use */ +#define TEGRA_DC_EXT_SET_CURSOR_LOW_LATENCY \ + _IOW('D', 0x12, struct tegra_dc_ext_cursor_image) + +#define TEGRA_DC_EXT_SET_PROPOSED_BW \ + _IOR('D', 0x13, struct tegra_dc_ext_flip_2) + +#define TEGRA_DC_EXT_FLIP3 \ + _IOWR('D', 0x14, struct tegra_dc_ext_flip_3) + +#define TEGRA_DC_EXT_SET_VBLANK \ + _IOW('D', 0x15, struct tegra_dc_ext_set_vblank) + +enum tegra_dc_ext_control_output_type { + TEGRA_DC_EXT_DSI, + TEGRA_DC_EXT_LVDS, + TEGRA_DC_EXT_VGA, + TEGRA_DC_EXT_HDMI, + TEGRA_DC_EXT_DVI, + TEGRA_DC_EXT_DP, +}; + +/* + * Get the properties for a given output. + * + * handle (in): Which output to query + * type (out): Describes the type of the output + * connected (out): Non-zero iff the output is currently connected + * associated_head (out): The head number that the output is currently + * bound to. -1 iff the output is not associated with any head. + * head_mask (out): Bitmask of which heads the output may be bound to (some + * outputs are permanently bound to a single head). + */ +struct tegra_dc_ext_control_output_properties { + __u32 handle; + enum tegra_dc_ext_control_output_type type; + __u32 connected; + __s32 associated_head; + __u32 head_mask; +}; + +/* + * This allows userspace to query the raw EDID data for the specified output + * handle. + * + * Here, the size parameter is both an input and an output: + * 1. Userspace passes in the size of the buffer allocated for data. + * 2. If size is too small, the call fails with the error EFBIG; otherwise, the + * raw EDID data is written to the buffer pointed to by data. In both + * cases, size will be filled in with the size of the data. + */ +struct tegra_dc_ext_control_output_edid { + __u32 handle; + __u32 size; + void *data; +}; + +struct tegra_dc_ext_event { + __u32 type; + __u32 data_size; + char data[0]; +}; + +/* Events types are bits in a mask */ +#define TEGRA_DC_EXT_EVENT_HOTPLUG (1 << 0) +struct tegra_dc_ext_control_event_hotplug { + __u32 handle; +}; + +#define TEGRA_DC_EXT_EVENT_VBLANK (1 << 1) +struct tegra_dc_ext_control_event_vblank { + __u32 handle; + __u32 reserved; /* unused */ + __u64 timestamp_ns; +}; + +#define TEGRA_DC_EXT_EVENT_BANDWIDTH_INC (1 << 2) +#define TEGRA_DC_EXT_EVENT_BANDWIDTH_DEC (1 << 3) +struct tegra_dc_ext_control_event_bandwidth { + __u32 handle; + __u32 total_bw; + __u32 avail_bw; + __u32 resvd_bw; +}; + +#define TEGRA_DC_EXT_CAPABILITIES_CURSOR_MODE (1 << 0) +#define TEGRA_DC_EXT_CAPABILITIES_BLOCKLINEAR (1 << 1) + +#define TEGRA_DC_EXT_CAPABILITIES_CURSOR_TWO_COLOR (1 << 2) +#define TEGRA_DC_EXT_CAPABILITIES_CURSOR_RGBA_NON_PREMULT_ALPHA (1 << 3) +#define TEGRA_DC_EXT_CAPABILITIES_CURSOR_RGBA_PREMULT_ALPHA (1 << 4) + +struct tegra_dc_ext_control_capabilities { + __u32 caps; + /* Leave some wiggle room for future expansion */ + __u32 pad[3]; +}; + +#define TEGRA_DC_EXT_CONTROL_GET_NUM_OUTPUTS \ + _IOR('C', 0x00, __u32) +#define TEGRA_DC_EXT_CONTROL_GET_OUTPUT_PROPERTIES \ + _IOWR('C', 0x01, struct tegra_dc_ext_control_output_properties) +#define TEGRA_DC_EXT_CONTROL_GET_OUTPUT_EDID \ + _IOWR('C', 0x02, struct tegra_dc_ext_control_output_edid) +#define TEGRA_DC_EXT_CONTROL_SET_EVENT_MASK \ + _IOW('C', 0x03, __u32) +#define TEGRA_DC_EXT_CONTROL_GET_CAPABILITIES \ + _IOR('C', 0x04, struct tegra_dc_ext_control_capabilities) + +#endif /* __TEGRA_DC_EXT_H */ diff --git a/hwc2/original-kernel-headers/tegrafb.h b/hwc2/original-kernel-headers/tegrafb.h new file mode 100644 index 0000000..c524c08 --- /dev/null +++ b/hwc2/original-kernel-headers/tegrafb.h @@ -0,0 +1,47 @@ +/* + * include/video/tegrafb.h + * + * Copyright (C) 2010 Google, Inc. + * Author: Erik Gilling + * + * Copyright (c) 2014 NVIDIA CORPORATION. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_TEGRAFB_H_ +#define _LINUX_TEGRAFB_H_ + +#include +#include +#include +#if defined(__KERNEL__) +#include +#endif + +struct tegra_fb_modedb { + struct fb_var_screeninfo *modedb; + __u32 modedb_len; +}; + +#ifdef CONFIG_COMPAT +struct tegra_fb_modedb_compat { + __u32 modedb; + __u32 modedb_len; +}; + +#define FBIO_TEGRA_GET_MODEDB_COMPAT \ + _IOWR('F', 0x42, struct tegra_fb_modedb_compat) +#endif + +#define FBIO_TEGRA_GET_MODEDB _IOWR('F', 0x42, struct tegra_fb_modedb) + +#endif -- cgit v1.2.3