sdm: Add support for UBWC in C2D
Add support for UBWC in gralloc alloc_buffer api and copybit
Change-Id: I264114d51c2d3caeb1611139641d99ddb006a7ce
diff --git a/libcopybit/c2d2.h b/libcopybit/c2d2.h
index 886f38a..315a3ba 100644
--- a/libcopybit/c2d2.h
+++ b/libcopybit/c2d2.h
@@ -72,6 +72,7 @@
C2D_FORMAT_MACROTILED = (1 << 16), /* tiled in macro level */
C2D_FORMAT_TILED_4x4 = (1 << 17), /* 4x4 tiled format */
C2D_FORMAT_SWAP_RB = (1 << 18), /* Swap R & B color components */
+ C2D_FORMAT_UBWC_COMPRESSED = (1 << 23), /* UBWC compressed format */
} C2D_FORMAT_MODE;
/* Definitions of supported RGB formats, used in C2D_RGB_SURFACE_DEF.
@@ -408,7 +409,8 @@
C2D_DRIVER_SUPPORTS_TARGET_RECT_OP = (1 << 15),
C2D_DRIVER_SUPPORTS_ROTATE_OP = (1 << 16), /* all rotations */
C2D_DRIVER_SUPPORTS_FLUSH_WITH_FENCE_FD_OP = (1 << 17), /* all rotations */
- C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP = ((0xFFFFFFFF) >> (31 - 17)) /* mask for all capabilities supported */
+ C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP = (1 << 18), /* UBWC Compression */
+ C2D_DRIVER_SUPPORTS_ALL_CAPABILITIES_OP = ((0xFFFFFFFF) >> (31 - 18)) /* mask for all capabilities supported */
} C2D_DRIVER_CAPABILITIES;
/* 2D driver workaround bits used by the 2D applications */
diff --git a/libcopybit/copybit.h b/libcopybit/copybit.h
index 1fc17ed..de585ee 100644
--- a/libcopybit/copybit.h
+++ b/libcopybit/copybit.h
@@ -80,6 +80,10 @@
COPYBIT_FRAMEBUFFER_HEIGHT = 8,
COPYBIT_FG_LAYER = 9,
COPYBIT_DYNAMIC_FPS = 10,
+ /* Source Format Mode */
+ COPYBIT_SRC_FORMAT_MODE = 11,
+ /* Destination Format Mode */
+ COPYBIT_DST_FORMAT_MODE = 12,
};
/* values for copybit_set_parameter(COPYBIT_TRANSFORM) */
@@ -116,6 +120,13 @@
COPYBIT_BLENDING_COVERAGE = 0x0405
};
+enum {
+ /* Linear format mode*/
+ COPYBIT_LINEAR = 0x0000,
+ /* UBWC format mode*/
+ COPYBIT_UBWC_COMPRESSED = 0x0001,
+};
+
/* use get_static_info() to query static informations about the hardware */
enum {
/* Maximum amount of minification supported by the hardware*/
@@ -126,6 +137,8 @@
COPYBIT_SCALING_FRAC_BITS = 3,
/* Supported rotation step in degres. */
COPYBIT_ROTATION_STEP_DEG = 4,
+ /* UBWC support*/
+ COPYBIT_UBWC_SUPPORT = 5,
};
/* Image structure */
diff --git a/libcopybit/copybit_c2d.cpp b/libcopybit/copybit_c2d.cpp
index cc13fec..9936eb6 100644
--- a/libcopybit/copybit_c2d.cpp
+++ b/libcopybit/copybit_c2d.cpp
@@ -124,7 +124,8 @@
enum eC2DFlags {
FLAGS_PREMULTIPLIED_ALPHA = 1<<0,
FLAGS_YUV_DESTINATION = 1<<1,
- FLAGS_TEMP_SRC_DST = 1<<2
+ FLAGS_TEMP_SRC_DST = 1<<2,
+ FLAGS_UBWC_FORMAT_MODE = 1<<3
};
static gralloc::IAllocController* sAlloc = 0;
@@ -159,6 +160,8 @@
void* time_stamp;
bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
void* dst_surface_base; // Stores the dst surface addr
+ bool is_src_ubwc_format;
+ bool is_dst_ubwc_format;
// used for signaling the wait thread
bool wait_timestamp;
@@ -543,6 +546,10 @@
surfaceDef.format = c2d_format |
((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
+
+ surfaceDef.format = surfaceDef.format |
+ ((flags & FLAGS_UBWC_FORMAT_MODE) ? C2D_FORMAT_UBWC_COMPRESSED : 0);
+
surfaceDef.width = rhs->w;
surfaceDef.height = rhs->h;
int aligned_width = ALIGN((int)surfaceDef.width,32);
@@ -699,6 +706,8 @@
int flags = FLAGS_PREMULTIPLIED_ALPHA;
int mapped_dst_idx = -1;
struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
+ if (ctx->is_dst_ubwc_format)
+ flags |= FLAGS_UBWC_FORMAT_MODE;
C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
pthread_mutex_lock(&ctx->wait_cleanup_lock);
if(!ctx->dst_surface_mapped) {
@@ -864,6 +873,12 @@
case COPYBIT_BLIT_TO_FRAMEBUFFER:
// Do nothing
break;
+ case COPYBIT_SRC_FORMAT_MODE:
+ ctx->is_src_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
+ break;
+ case COPYBIT_DST_FORMAT_MODE:
+ ctx->is_dst_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
+ break;
default:
ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
status = -EINVAL;
@@ -897,6 +912,12 @@
case COPYBIT_ROTATION_STEP_DEG:
value = 1;
break;
+ case COPYBIT_UBWC_SUPPORT:
+ value = 0;
+ if (ctx->c2d_driver_info.capabilities_mask & C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP) {
+ value = 1;
+ }
+ break;
default:
ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
value = -EINVAL;
@@ -1123,6 +1144,9 @@
}
int dst_surface_type;
+ if (ctx->is_dst_ubwc_format)
+ flags |= FLAGS_UBWC_FORMAT_MODE;
+
if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
dst_surface_type = RGB_SURFACE;
flags |= FLAGS_PREMULTIPLIED_ALPHA;
@@ -1305,6 +1329,7 @@
flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
+ flags |= (ctx->is_src_ubwc_format) ? FLAGS_UBWC_FORMAT_MODE : 0;
status = set_image(ctx, src_surface.surface_id, &src_image,
(eC2DFlags)flags, mapped_src_idx);
if(status) {
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 1b59fde..4e9e264 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -844,6 +844,10 @@
return -ENOMEM;
}
+ if(isUBwcEnabled(format, usage)) {
+ data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ }
+
private_handle_t* hnd = new private_handle_t(data.fd, data.size,
data.allocType, 0, format,
alignedw, alignedh);
diff --git a/sdm/libs/hwc/blit_engine_c2d.cpp b/sdm/libs/hwc/blit_engine_c2d.cpp
index e85e28c..8d9c09a 100644
--- a/sdm/libs/hwc/blit_engine_c2d.cpp
+++ b/sdm/libs/hwc/blit_engine_c2d.cpp
@@ -128,7 +128,8 @@
}
}
-int BlitEngineC2d::AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format) {
+int BlitEngineC2d::AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format,
+ uint32_t usage) {
int status = 0;
if (width <= 0 || height <= 0) {
return false;
@@ -144,8 +145,7 @@
for (uint32_t i = 0; i < kNumBlitTargetBuffers; i++) {
if (blit_target_buffer_[i] == NULL) {
- status = alloc_buffer(&blit_target_buffer_[i], width, height, format,
- GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
+ status = alloc_buffer(&blit_target_buffer_[i], width, height, format, usage);
}
if (status < 0) {
DLOGE("Allocation of Blit target Buffer failed");
@@ -182,6 +182,11 @@
buffer.format = hnd->format;
buffer.base = reinterpret_cast<void *>(hnd->base);
buffer.handle = reinterpret_cast<native_handle_t *>(hnd);
+ int dst_format_mode = COPYBIT_LINEAR;
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+ dst_format_mode = COPYBIT_UBWC_COMPRESSED;
+ }
+ blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DST_FORMAT_MODE, dst_format_mode);
status = blit_engine_c2d_->clear(blit_engine_c2d_, &buffer, &clear_rect);
return status;
@@ -299,6 +304,7 @@
uint32_t processed_blit = 0;
LayerRect dst_rects[kMaxBlitTargetLayers];
bool blit_needed = false;
+ uint32_t usage = 0;
for (uint32_t i = num_app_layers-1; (i > 0) && (processed_blit < num_blit_target_); i--) {
Layer &layer = layer_stack->layers[i];
@@ -312,9 +318,13 @@
LayerRect &blit_src_rect = blit_layer.src_rect;
int width = INT(layer.dst_rect.right - layer.dst_rect.left);
int height = INT(layer.dst_rect.bottom - layer.dst_rect.top);
+ usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_HW_TEXTURE;
+ if (blit_engine_c2d_->get(blit_engine_c2d_, COPYBIT_UBWC_SUPPORT) > 0) {
+ usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
+ }
// TODO(user): FrameBuffer is assumed to be RGBA
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, height,
- INT(HAL_PIXEL_FORMAT_RGBA_8888), 0, width, height);
+ INT(HAL_PIXEL_FORMAT_RGBA_8888), usage, width, height);
target_width = MAX(target_width, width);
target_height += height;
@@ -331,7 +341,7 @@
// Allocate a single buffer of RGBA8888 format
if (blit_needed && (AllocateBlitTargetBuffers(target_width, target_height,
- HAL_PIXEL_FORMAT_RGBA_8888) < 0)) {
+ HAL_PIXEL_FORMAT_RGBA_8888, usage) < 0)) {
status = -1;
return status;
}
@@ -344,6 +354,9 @@
if (layer.input_buffer) {
layer.input_buffer->width = target_width;
layer.input_buffer->height = target_height;
+ if (target_buffer->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+ layer.input_buffer->format = kFormatRGBA8888Ubwc;
+ }
layer.input_buffer->planes[0].fd = target_buffer->fd;
layer.input_buffer->planes[0].offset = 0;
layer.input_buffer->planes[0].stride = target_buffer->width;
@@ -508,6 +521,13 @@
blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_BLEND_MODE, hwc_layer->blending);
blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_DITHER,
(dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
+
+ int src_format_mode = COPYBIT_LINEAR;
+ if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+ src_format_mode = COPYBIT_UBWC_COMPRESSED;
+ }
+ blit_engine_c2d_->set_parameter(blit_engine_c2d_, COPYBIT_SRC_FORMAT_MODE, src_format_mode);
+
blit_engine_c2d_->set_sync(blit_engine_c2d_, acquireFd);
int err = blit_engine_c2d_->stretch(blit_engine_c2d_, &dst, &src, &dst_rect, &src_rect,
©bitRegion);
diff --git a/sdm/libs/hwc/blit_engine_c2d.h b/sdm/libs/hwc/blit_engine_c2d.h
index 4034114..74c4b81 100644
--- a/sdm/libs/hwc/blit_engine_c2d.h
+++ b/sdm/libs/hwc/blit_engine_c2d.h
@@ -97,7 +97,7 @@
mutable Range r;
};
- int AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format);
+ int AllocateBlitTargetBuffers(uint32_t width, uint32_t height, uint32_t format, uint32_t usage);
void FreeBlitTargetBuffers();
int ClearTargetBuffer(private_handle_t* hnd, const LayerRect& rect);
int DrawRectUsingCopybit(hwc_layer_1_t *hwc_layer, Layer *layer, LayerRect blit_rect,