hwc: Add support for Macro Tile feature
Macro tile is enabled only if all the conditions are met:
1. GPU hardware should support Macro Tiling.
2. MDSS hardware should support Macro Tiling.
3. USAGE flags shouldnt contain GRALLOC_USAGE_SW_READ_OFTEN and
GRALLOC_USAGE_SW_WRITE_OFTEN.
4. RGB 16bit and 32bit formats.
5. persist.hwc.macro_tile_enable flag should be enabled.
PRIV_FLAGS_TILE_RENDERED flag is added to indicate whether the layer
is rendered/composited in Macro Tiling or Linear format.
Change-Id: Ie3139839c84d76c5d1a2300f33910a09eb7336f4
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 33c4f32..dc5f6ae 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -36,6 +36,7 @@
#include "ionalloc.h"
#include "gr.h"
#include "comptype.h"
+#include "mdp_version.h"
#ifdef VENUS_COLOR_FORMAT
#include <media/msm_media_info.h>
@@ -88,13 +89,16 @@
{
LINK_adreno_compute_aligned_width_and_height = NULL;
LINK_adreno_compute_padding = NULL;
+ LINK_adreno_isMacroTilingSupportedByGpu = NULL;
libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
if (libadreno_utils) {
*(void **)&LINK_adreno_compute_aligned_width_and_height =
- ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
- *(void **)&LINK_adreno_compute_padding = ::dlsym(libadreno_utils,
- "compute_surface_padding");
+ ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
+ *(void **)&LINK_adreno_compute_padding =
+ ::dlsym(libadreno_utils, "compute_surface_padding");
+ *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
+ ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
}
}
@@ -105,8 +109,19 @@
}
}
+int AdrenoMemInfo::isMacroTilingSupportedByGPU()
+{
+ if ((libadreno_utils)) {
+ if(LINK_adreno_isMacroTilingSupportedByGpu) {
+ return LINK_adreno_isMacroTilingSupportedByGpu();
+ }
+ }
+ return 0;
+}
+
+
void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
- int& aligned_w, int& aligned_h)
+ int tile_enabled, int& aligned_w, int& aligned_h)
{
aligned_w = ALIGN(width, 32);
aligned_h = ALIGN(height, 32);
@@ -138,9 +153,8 @@
// the function below computes aligned width and aligned height
// based on linear or macro tile mode selected.
if(LINK_adreno_compute_aligned_width_and_height) {
- int tile_mode = 0; // Linear surface
- LINK_adreno_compute_aligned_width_and_height(width,
- height, bpp, tile_mode,
+ LINK_adreno_compute_aligned_width_and_height(width,
+ height, bpp, tile_enabled,
raster_mode, padding_threshold,
&aligned_w, &aligned_h);
@@ -289,16 +303,42 @@
return memalloc;
}
-size_t getBufferSizeAndDimensions(int width, int height, int format,
- int& alignedw, int &alignedh)
+bool isMacroTileEnabled(int format, int usage)
+{
+ bool tileEnabled = false;
+
+ // Check whether GPU & MDSS supports MacroTiling feature
+ if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
+ qdutils::MDPVersion::getInstance().supportsMacroTile())
+ {
+ // check the format
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ {
+ tileEnabled = true;
+ // check the usage flags
+ if (usage & (GRALLOC_USAGE_SW_READ_MASK |
+ GRALLOC_USAGE_SW_WRITE_MASK)) {
+ // Application intends to use CPU for rendering
+ tileEnabled = false;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return tileEnabled;
+}
+
+// helper function
+size_t getSize(int format, int width, int height, int alignedw, int alignedh)
{
size_t size;
- AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
- height,
- format,
- alignedw,
- alignedh);
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
@@ -376,10 +416,64 @@
ALOGE("unrecognized pixel format: 0x%x", format);
return -EINVAL;
}
+ return size;
+}
+
+size_t getBufferSizeAndDimensions(int width, int height, int format,
+ int& alignedw, int &alignedh)
+{
+ size_t size;
+
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height,
+ format,
+ false,
+ alignedw,
+ alignedh);
+
+ size = getSize(format, width, height, alignedw, alignedh);
return size;
}
+
+size_t getBufferSizeAndDimensions(int width, int height, int format, int usage,
+ int& alignedw, int &alignedh)
+{
+ size_t size;
+ int tileEnabled = isMacroTileEnabled(format, usage);
+
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height,
+ format,
+ tileEnabled,
+ alignedw,
+ alignedh);
+
+ size = getSize(format, width, height, alignedw, alignedh);
+
+ return size;
+}
+
+
+void getBufferAttributes(int width, int height, int format, int usage,
+ int& alignedw, int &alignedh, int& tileEnabled, size_t& size)
+{
+ tileEnabled = isMacroTileEnabled(format, usage);
+
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height,
+ format,
+ tileEnabled,
+ alignedw,
+ alignedh);
+
+ if(size)
+ size = getSize(format, width, height, alignedw, alignedh);
+}
+
+
+
// Allocate buffer from width, height and format into a
// private_handle_t. It is the responsibility of the caller
// to free the buffer using the free_buffer function
@@ -392,7 +486,9 @@
data.base = 0;
data.fd = -1;
data.offset = 0;
- data.size = getBufferSizeAndDimensions(w, h, format, alignedw, alignedh);
+ data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
+ alignedh);
+
data.align = getpagesize();
data.uncached = useUncached(usage);
int allocFlags = usage;
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index b4da363..f4192c4 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -150,6 +150,10 @@
flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
}
+ if(isMacroTileEnabled(format, usage)) {
+ flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
+ }
+
flags |= data.allocType;
int eBaseAddr = int(eData.base) + eData.offset;
private_handle_t *hnd = new private_handle_t(data.fd, size, flags,
@@ -285,7 +289,8 @@
}
getGrallocInformationFromFormat(grallocFormat, &bufferType);
- size = getBufferSizeAndDimensions(w, h, grallocFormat, alignedw, alignedh);
+ size = getBufferSizeAndDimensions(w, h, grallocFormat, usage, alignedw,
+ alignedh);
if ((ssize_t)size <= 0)
return -EINVAL;
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 1949f45..8c68e16 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -51,9 +51,20 @@
int mapFrameBufferLocked(struct private_module_t* module);
int terminateBuffer(gralloc_module_t const* module, private_handle_t* hnd);
+size_t getBufferSizeAndDimensions(int width, int height, int format, int usage,
+ int& alignedw, int &alignedh);
size_t getBufferSizeAndDimensions(int width, int height, int format,
int& alignedw, int &alignedh);
+
+// Attributes include aligned width, aligned height, tileEnabled and size of the buffer
+void getBufferAttributes(int width, int height, int format, int usage,
+ int& alignedw, int &alignedh,
+ int& tileEnabled, size_t &size);
+
+
+bool isMacroTileEnabled(int format, int usage);
+
int decideBufferHandlingMechanism(int format, const char *compositionUsed,
int hasBlitEngine, int *needConversion,
int *useBufferDirectly);
@@ -95,7 +106,16 @@
* @return aligned width, aligned height
*/
void getAlignedWidthAndHeight(int width, int height, int format,
- int& alignedw, int &alignedh);
+ int tileEnabled, int& alignedw, int &alignedh);
+
+ /*
+ * Function to return whether GPU support MacroTile feature
+ *
+ * @return >0 : supported
+ * 0 : not supported
+ */
+ int isMacroTilingSupportedByGPU();
+
private:
// Pointer to the padding library.
void *libadreno_utils;
@@ -114,6 +134,8 @@
int padding_threshold,
int *aligned_w,
int *aligned_h);
+ // link to the surface padding library.
+ int (*LINK_adreno_isMacroTilingSupportedByGpu) (void);
};
#endif /* GR_H_ */
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index f6d244a..b00a95e 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -79,8 +79,12 @@
/* Gralloc perform enums
*/
GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 1,
+ // This will be deprecated from latest graphics drivers. This is kept
+ // for those backward compatibility i.e., newer Display HAL + older graphics
+ // libraries
GRALLOC_MODULE_PERFORM_GET_STRIDE,
GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE,
+ GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES,
};
#define GRALLOC_HEAP_MASK (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
@@ -170,6 +174,8 @@
PRIV_FLAGS_ITU_R_601_FR = 0x00400000,
PRIV_FLAGS_ITU_R_709 = 0x00800000,
PRIV_FLAGS_SECURE_DISPLAY = 0x01000000,
+ // Buffer is rendered in Tile Format
+ PRIV_FLAGS_TILE_RENDERED = 0x02000000
};
// file-descriptors
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index a07bdc3..109c141 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -331,10 +331,11 @@
int *stride = va_arg(args, int *);
int alignedw = 0, alignedh = 0;
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
- 0, format, alignedw, alignedh);
+ 0, format, false, alignedw, alignedh);
*stride = alignedw;
res = 0;
} break;
+
case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
{
private_handle_t* hnd = va_arg(args, private_handle_t*);
@@ -350,6 +351,23 @@
}
res = 0;
} break;
+
+ case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES:
+ {
+ int width = va_arg(args, int);
+ int height = va_arg(args, int);
+ int format = va_arg(args, int);
+ int usage = va_arg(args, int);
+ int *alignedWidth = va_arg(args, int *);
+ int *alignedHeight = va_arg(args, int *);
+ int *tileEnabled = va_arg(args,int *);
+ *tileEnabled = isMacroTileEnabled(format, usage);
+ AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
+ height, format, *tileEnabled, *alignedWidth,
+ *alignedHeight);
+ res = 0;
+ } break;
+
default:
break;
}