summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarissa Wall <marissaw@google.com>2017-03-02 22:10:21 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-03-02 22:10:21 +0000
commitedbca2bee44533d2dfdff6c1cfa1250db2c8eb9c (patch)
tree05e56df30bce63fe9e56e26612e0a1b81cafcfa1
parentd6e46d89c85decb0177e68f63fbfa444fe34ae2c (diff)
parentbdbc508d9faf131e8408fceac2bfff5ca7927b84 (diff)
downloadflounder-edbca2bee44533d2dfdff6c1cfa1250db2c8eb9c.tar.gz
hwc2: present display
am: bdbc508d9f Change-Id: I69f543884b61849c13961f55b388656ab0b62ed8
-rw-r--r--hwc2/Android.mk3
-rw-r--r--hwc2/hwc2.cpp17
-rw-r--r--hwc2/hwc2.h57
-rw-r--r--hwc2/hwc2_buffer.cpp171
-rw-r--r--hwc2/hwc2_dev.cpp56
-rw-r--r--hwc2/hwc2_display.cpp205
-rw-r--r--hwc2/hwc2_gralloc.cpp51
-rw-r--r--hwc2/hwc2_layer.cpp13
-rw-r--r--hwc2/include/tegra_dc_ext.h394
-rw-r--r--hwc2/include/tegrafb.h105
-rw-r--r--hwc2/original-kernel-headers/tegra_dc_ext.h544
-rw-r--r--hwc2/original-kernel-headers/tegrafb.h47
12 files changed, 1644 insertions, 19 deletions
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<hwc2_context *>(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<hwc2_context *>(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 <android-base/unique_fd.h>
#include <hardware/hwcomposer2.h>
#include <unordered_map>
@@ -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 <cutils/log.h>
+#include <tegra_dc_ext.h>
+#include <tegrafb.h>
+#include <tegra_adf.h>
+#include <android-base/macros.h>
#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<std::mutex> 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<std::mutex> 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<std::mutex> 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 <cutils/log.h>
+#include <tegra_adf.h>
#include <inttypes.h>
+#include <cstdlib>
#include <map>
#include <vector>
#include <array>
@@ -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<struct adf_buffer_config> adf_bufs(windows.size());
+ std::array<adf_id_t, 1> 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<tegra_adf_flip *>(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<float>(width);
+ crop.bottom = static_cast<float>(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 <linux/types.h>
+#include <linux/ioctl.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#include <time.h>
+#include <unistd.h>
+#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 <linux/fb.h>
+#include <linux/types.h>
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#include <asm/ioctl.h>
+#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 <rmorell@nvidia.com>
+ * Some code based on fbdev extensions written by:
+ * Erik Gilling <konkers@android.com>
+ *
+ * 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 <linux/types.h>
+#include <linux/ioctl.h>
+#if defined(__KERNEL__)
+# include <linux/time.h>
+#else
+# include <time.h>
+# include <unistd.h>
+#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 <konkers@android.com>
+ *
+ * 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 <linux/fb.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#if defined(__KERNEL__)
+#include <linux/compat.h>
+#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