Merge "sde: Add support for UBWC in display engine"
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
index 54b0c83..e062e48 100644
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ b/displayengine/libs/core/hw_framebuffer.cpp
@@ -545,7 +545,11 @@
mdp_layer.alpha = layer.plane_alpha;
mdp_layer.z_order = static_cast<uint16_t>(i);
mdp_layer.transp_mask = 0xffffffff;
+ mdp_layer.horz_deci = pipe.horizontal_decimation;
+ mdp_layer.vert_deci = pipe.vertical_decimation;
+
SetBlending(layer.blending, &mdp_layer.blend_op);
+
SetRect(pipe.src_roi, &mdp_layer.src_rect);
SetRect(pipe.dst_roi, &mdp_layer.dst_rect);
@@ -669,10 +673,10 @@
}
void HWFrameBuffer::SetRect(const LayerRect &source, mdp_rect *target) {
- target->x = INT(ceilf(source.left));
- target->y = INT(ceilf(source.top));
- target->w = INT(floorf(source.right)) - target->x;
- target->h = INT(floorf(source.bottom)) - target->y;
+ target->x = UINT32(source.left);
+ target->y = UINT32(source.top);
+ target->w = UINT32(source.right) - target->x;
+ target->h = UINT32(source.bottom) - target->y;
}
void* HWFrameBuffer::DisplayEventThread(void *context) {
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index f4f33f9..c8611f9 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -93,7 +93,7 @@
};
struct HWRotateInfo {
- uint32_t pipe_id;
+ int pipe_id;
LayerRect src_roi;
LayerRect dst_roi;
HWBlockType writeback_id;
@@ -107,12 +107,13 @@
};
struct HWPipeInfo {
- uint32_t pipe_id;
+ int pipe_id;
LayerRect src_roi;
LayerRect dst_roi;
- uint8_t decimation;
+ uint8_t horizontal_decimation;
+ uint8_t vertical_decimation;
- HWPipeInfo() : pipe_id(0), decimation(1) { }
+ HWPipeInfo() : pipe_id(0), horizontal_decimation(0), vertical_decimation(0) { }
inline void Reset() { *this = HWPipeInfo(); }
};
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index d093ab2..1fc1598 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -185,6 +185,8 @@
return kErrorNotSupported;
struct HWLayerConfig *layer_config = &hw_layers->config[i];
+ HWPipeInfo &left_pipe = layer_config->left_pipe;
+ HWPipeInfo &right_pipe = layer_config->right_pipe;
// config rotator first
for (uint32_t j = 0; j < kMaxRotatePerLayer; j++) {
layer_config->rotates[j].Reset();
@@ -211,6 +213,20 @@
if (error != kErrorNone)
break;
+ // 1. Normalize Video layer source rectangle to multiple of 2, as MDP hardware require source
+ // rectangle of video layer to be even.
+ // 2. Normalize source and destination rect of a layer to multiple of 1.
+ uint32_t factor = (1 << layer.input_buffer->flags.video);
+ if (left_pipe.pipe_id == kPipeIdNeedsAssignment) {
+ NormalizeRect(factor, &left_pipe.src_roi);
+ NormalizeRect(1, &left_pipe.dst_roi);
+ }
+
+ if (right_pipe.pipe_id == kPipeIdNeedsAssignment) {
+ NormalizeRect(factor, &right_pipe.src_roi);
+ NormalizeRect(1, &right_pipe.dst_roi);
+ }
+
DLOGV_IF(kTagResources, "layer = %d, left pipe_id = %x",
i, layer_config->left_pipe.pipe_id);
LogRectVerbose("input layer src_rect", layer.src_rect);
@@ -248,6 +264,12 @@
return kErrorNotSupported;
}
+ if (((crop_width - dst_width) == 1) || ((crop_height - dst_height) == 1)) {
+ DLOGV_IF(kTagResources, "One pixel downscaling detected crop_w %d, dst_w %d, crop_h %d, " \
+ "dst_h %d", crop_width, dst_width, crop_height, dst_height);
+ return kErrorNotSupported;
+ }
+
float scale_x = crop_width / dst_width;
float scale_y = crop_height / dst_height;
@@ -404,22 +426,41 @@
}
}
-void ResManager::SetDecimationFactor(HWPipeInfo *pipe) {
+DisplayError ResManager::SetDecimationFactor(HWPipeInfo *pipe) {
float max_down_scale = FLOAT(hw_res_info_.max_scale_down);
float src_h = pipe->src_roi.bottom - pipe->src_roi.top;
float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
- float down_scale = src_h / dst_h;
- pipe->decimation = 1;
+ float down_scale_h = src_h / dst_h;
- if (!hw_res_info_.has_decimation || (down_scale <= max_down_scale))
- return;
+ float src_w = pipe->src_roi.right - pipe->src_roi.left;
+ float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
+ float down_scale_w = src_w / dst_w;
+
+
+ pipe->horizontal_decimation = 0;
+ pipe->vertical_decimation = 0;
+
+ // TODO(user): Need to check for the maximum downscale limit for decimation and return error
+ if (!hw_res_info_.has_decimation && ((down_scale_w > max_down_scale) ||
+ (down_scale_h > max_down_scale))) {
+ DLOGV("Downscaling exceeds the maximum MDP downscale limit and decimation not enabled");
+ return kErrorNotSupported;
+ }
+
+ if ((down_scale_w <= max_down_scale) && (down_scale_h <= max_down_scale))
+ return kErrorNone;
// Decimation is the remaining downscale factor after doing max SDE downscale.
// In SDE, decimation is supported in powers of 2.
// For ex: If a pipe needs downscale of 8 but max_down_scale is 4
// So decimation = powf(2.0, ceilf(log2f(8) - log2f(4))) = powf(2.0, 1.0) = 2
- float decimation_factor = ceilf(log2f(down_scale) - log2f(max_down_scale));
- pipe->decimation = UINT8(powf(2.0f, decimation_factor));
+ pipe->horizontal_decimation = UINT8(ceilf(log2f(down_scale_w) - log2f(max_down_scale)));
+ pipe->vertical_decimation = UINT8(ceilf(log2f(down_scale_h) - log2f(max_down_scale)));
+
+ DLOGI_IF(kTagResources, "horizontal_decimation %d, vertical_decimation %d",
+ pipe->horizontal_decimation, pipe->vertical_decimation);
+
+ return kErrorNone;
}
void ResManager::SplitRect(bool flip_horizontal, const LayerRect &src_rect,
@@ -476,4 +517,16 @@
prefix, roi.left, roi.top, roi.right, roi.bottom);
}
+void ResManager::NormalizeRect(const uint32_t &factor, LayerRect *rect) {
+ uint32_t left = UINT32(ceilf(rect->left));
+ uint32_t top = UINT32(ceilf(rect->top));
+ uint32_t right = UINT32(floorf(rect->right));
+ uint32_t bottom = UINT32(floorf(rect->bottom));
+
+ rect->left = FLOAT(CeilToMultipleOf(left, factor));
+ rect->top = FLOAT(CeilToMultipleOf(top, factor));
+ rect->right = FLOAT(FloorToMultipleOf(right, factor));
+ rect->bottom = FLOAT(FloorToMultipleOf(bottom, factor));
+}
+
} // namespace sde
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index 7b36563..12ef5bd 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -22,6 +22,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <math.h>
#include <utils/constants.h>
#include <utils/debug.h>
@@ -286,7 +287,10 @@
src_pipes_[left_index].reserved_hw_block = hw_block_id;
}
- SetDecimationFactor(pipe_info);
+ error = SetDecimationFactor(pipe_info);
+ if (error != kErrorNone) {
+ goto CleanupOnError;
+ }
pipe_info = &layer_config.right_pipe;
if (pipe_info->pipe_id == 0) {
@@ -318,7 +322,10 @@
src_pipes_[left_index].reserved_hw_block = hw_block_id;
src_pipes_[left_index].at_right = false;
layer_config.left_pipe.pipe_id = src_pipes_[left_index].mdss_pipe_id;
- SetDecimationFactor(pipe_info);
+ error = SetDecimationFactor(pipe_info);
+ if (error != kErrorNone) {
+ goto CleanupOnError;
+ }
DLOGV_IF(kTagResources, "Pipe acquired, layer index = %d, left_pipe = %x, right_pipe = %x",
i, layer_config.left_pipe.pipe_id, pipe_info->pipe_id);
@@ -418,7 +425,8 @@
float dst_h = pipe->dst_roi.bottom - pipe->dst_roi.top;
// Adjust src_h with pipe decimation
- src_h /= FLOAT(pipe->decimation);
+ float decimation = powf(2.0f, pipe->vertical_decimation);
+ src_h /= decimation;
float bw = src_w * src_h * bpp * display_attributes.fps;
@@ -440,7 +448,9 @@
float dst_w = pipe->dst_roi.right - pipe->dst_roi.left;
// Adjust src_h with pipe decimation
- src_h /= FLOAT(pipe->decimation);
+ float decimation = powf(2.0f, pipe->vertical_decimation);
+ src_h /= decimation;
+
// SDE Clock requirement in MHz
float clk = (dst_w * v_total * fps) / 1000000.0f;
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index 5b63299..cf0a55f 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -166,7 +166,7 @@
float GetPipeBw(DisplayResourceContext *display_ctx, HWPipeInfo *pipe, float bpp);
float GetClockForPipe(DisplayResourceContext *display_ctx, HWPipeInfo *pipe);
float GetOverlapBw(HWLayers *hw_layers, float *pipe_bw, bool left_mixer);
- void SetDecimationFactor(HWPipeInfo *pipe);
+ DisplayError SetDecimationFactor(HWPipeInfo *pipe);
float GetBpp(LayerBufferFormat format);
void SplitRect(bool flip_horizontal, const LayerRect &src_rect, const LayerRect &dst_rect,
LayerRect *src_left, LayerRect *dst_left, LayerRect *src_right,
@@ -183,6 +183,7 @@
const uint32_t roate_cnt);
void AssignRotator(HWRotateInfo *rotate, uint32_t *rotate_cnt);
void ClearRotator(DisplayResourceContext *display_resource_ctx);
+ void NormalizeRect(const uint32_t &factor, LayerRect *rect);
template <class T>
inline void Swap(T &a, T &b) {
@@ -191,6 +192,17 @@
b = c;
}
+ // factor value should be in powers of 2(eg: 1, 2, 4, 8)
+ template <class T1, class T2>
+ inline T1 FloorToMultipleOf(const T1 &value, const T2 &factor) {
+ return (T1)(value & (~(factor - 1)));
+ }
+
+ template <class T1, class T2>
+ inline T1 CeilToMultipleOf(const T1 &value, const T2 &factor) {
+ return (T1)((value + (factor - 1)) & (~(factor - 1)));
+ }
+
Locker locker_;
HWResourceInfo hw_res_info_;
HWBlockContext hw_block_ctx_[kHWBlockMax];
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index ce8f933..d765e04 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -302,9 +302,11 @@
layer_buffer->height = pvt_handle->height;
if (pvt_handle->bufferType == BUFFER_TYPE_VIDEO) {
layer_stack_.flags.video_present = true;
+ layer_buffer->flags.video = true;
}
if (pvt_handle->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
layer_stack_.flags.secure_present = true;
+ layer_buffer->flags.secure = true;
}
}
@@ -348,6 +350,10 @@
Layer &layer = layer_stack_.layers[i];
LayerComposition composition = layer.composition;
+ if (composition == kCompositionSDE) {
+ hwc_layer.hints |= HWC_HINT_CLEAR_FB;
+ }
+
// If current layer does not need frame buffer redraw, then mark it as HWC_OVERLAY
if (!needs_fb_refresh && (composition != kCompositionGPUTarget)) {
composition = kCompositionSDE;
diff --git a/libgralloc/adreno_utils.h b/libgralloc/adreno_utils.h
new file mode 100644
index 0000000..6cb7810
--- /dev/null
+++ b/libgralloc/adreno_utils.h
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2015, The Linux Foundation. All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without modification, are permitted
+* provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright notice, this list of
+* conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright notice, this list of
+* conditions and the following disclaimer in the documentation and/or other materials provided
+* with the distribution.
+* * Neither the name of The Linux Foundation nor the names of its contributors may be used to
+* endorse or promote products derived from this software without specific prior written
+* permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// Adreno Pixel Formats
+typedef enum {
+
+ ADRENO_PIXELFORMAT_UNKNOWN = 0,
+ ADRENO_PIXELFORMAT_R8G8B8A8 = 27,
+ ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
+ ADRENO_PIXELFORMAT_B5G6R5 = 85,
+ ADRENO_PIXELFORMAT_B5G5R5A1 = 86,
+ ADRENO_PIXELFORMAT_B8G8R8A8 = 90,
+ ADRENO_PIXELFORMAT_B8G8R8A8_SRGB = 91,
+ ADRENO_PIXELFORMAT_B8G8R8X8_SRGB = 93,
+ ADRENO_PIXELFORMAT_NV12 = 103,
+ ADRENO_PIXELFORMAT_YUY2 = 107,
+ ADRENO_PIXELFORMAT_B4G4R4A4 = 115,
+ ADRENO_PIXELFORMAT_R8G8B8 = 508, // GL_RGB8
+ ADRENO_PIXELFORMAT_A1B5G5R5 = 519, // GL_RGB5_A1
+ ADRENO_PIXELFORMAT_R8G8B8X8_SRGB = 520, // GL_SRGB8
+ ADRENO_PIXELFORMAT_R8G8B8_SRGB = 521, // GL_SRGB8
+ ADRENO_PIXELFORMAT_R5G6B5 = 610, // RGBA version of B5G6R5
+ ADRENO_PIXELFORMAT_R5G5B5A1 = 611, // RGBA version of B5G5R5A1
+ ADRENO_PIXELFORMAT_R4G4B4A4 = 612, // RGBA version of B4G4R4A4
+ ADRENO_PIXELFORMAT_UYVY = 614, // YUV 4:2:2 packed progressive (1 plane)
+ ADRENO_PIXELFORMAT_NV21 = 619,
+ ADRENO_PIXELFORMAT_Y8U8V8A8 = 620, // YUV 4:4:4 packed (1 plane)
+ ADRENO_PIXELFORMAT_Y8 = 625, // Single 8-bit luma only channel YUV format
+
+} ADRENOPIXELFORMAT;
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 596ca77..a7c4a9a 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -53,6 +53,9 @@
ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
+static void getUBwcWidthAndHeight(int, int, int, int&, int&);
+static unsigned int getUBwcSize(int, int, int, const int, const int);
+
//Common functions
static bool canFallback(int usage, bool triedSystem)
{
@@ -98,6 +101,7 @@
LINK_adreno_compute_padding = NULL;
LINK_adreno_isMacroTilingSupportedByGpu = NULL;
LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
+ LINK_adreno_isUBWCSupportedByGpu = NULL;
libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
if (libadreno_utils) {
@@ -110,6 +114,8 @@
*(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
::dlsym(libadreno_utils,
"compute_compressedfmt_aligned_width_and_height");
+ *(void **)&LINK_adreno_isUBWCSupportedByGpu =
+ ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
}
}
@@ -132,136 +138,183 @@
void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
- int tile_enabled, int& aligned_w, int& aligned_h)
+ int usage, int& aligned_w, int& aligned_h)
{
- aligned_w = width;
- aligned_h = height;
+
// Currently surface padding is only computed for RGB* surfaces.
if (format <= HAL_PIXEL_FORMAT_sRGB_X_8888) {
- aligned_w = ALIGN(width, 32);
- aligned_h = ALIGN(height, 32);
- // Don't add any additional padding if debug.gralloc.map_fb_memory
- // is enabled
- char property[PROPERTY_VALUE_MAX];
- if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
- (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
- (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
- return;
- }
+ int tileEnabled = isMacroTileEnabled(format, usage);
+ AdrenoMemInfo::getInstance().getGpuAlignedWidthHeight(width,
+ height, format, tileEnabled, aligned_w, aligned_h);
+ return;
+ }
- int bpp = 4;
- switch(format)
- {
- case HAL_PIXEL_FORMAT_RGB_888:
- bpp = 3;
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- case HAL_PIXEL_FORMAT_RGBA_5551:
- case HAL_PIXEL_FORMAT_RGBA_4444:
- bpp = 2;
- break;
- default: break;
- }
- if (libadreno_utils) {
- int raster_mode = 0; // Adreno unknown raster mode.
- int padding_threshold = 512; // Threshold for padding surfaces.
- // 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) {
- LINK_adreno_compute_aligned_width_and_height(width,
- height, bpp, tile_enabled,
- raster_mode, padding_threshold,
- &aligned_w, &aligned_h);
+ if (isUBwcEnabled(format, usage)) {
+ getUBwcWidthAndHeight(width, height, format, aligned_w, aligned_h);
+ return;
+ }
- } else if(LINK_adreno_compute_padding) {
- int surface_tile_height = 1; // Linear surface
- aligned_w = LINK_adreno_compute_padding(width, bpp,
- surface_tile_height, raster_mode,
- padding_threshold);
- ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
- __FUNCTION__);
+ aligned_w = width;
+ aligned_h = height;
+ switch (format)
+ {
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
+ case HAL_PIXEL_FORMAT_RAW_SENSOR:
+ aligned_w = ALIGN(width, 32);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ aligned_w = ALIGN(width, 128);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP:
+ case HAL_PIXEL_FORMAT_YV12:
+ case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+ case HAL_PIXEL_FORMAT_YCrCb_422_SP:
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ case HAL_PIXEL_FORMAT_YCrCb_422_I:
+ aligned_w = ALIGN(width, 16);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
+ aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
+ break;
+ case HAL_PIXEL_FORMAT_BLOB:
+ break;
+ case HAL_PIXEL_FORMAT_NV21_ZSL:
+ aligned_w = ALIGN(width, 64);
+ aligned_h = ALIGN(height, 64);
+ break;
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
+ case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+ if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
+ int bytesPerPixel = 0;
+ int raster_mode = 0; //Adreno unknown raster mode.
+ int padding_threshold = 512; //Threshold for padding
+ //surfaces.
+
+ LINK_adreno_compute_compressedfmt_aligned_width_and_height(
+ width, height, format, 0,raster_mode, padding_threshold,
+ &aligned_w, &aligned_h, &bytesPerPixel);
} else {
- ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
- "compute_aligned_width_and_height not found", __FUNCTION__);
+ ALOGW("%s: Warning!! Symbols" \
+ " compute_compressedfmt_aligned_width_and_height" \
+ " not found", __FUNCTION__);
}
+ break;
+ default: break;
+ }
+}
+
+void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
+ int tile_enabled, int& aligned_w, int& aligned_h)
+{
+ aligned_w = ALIGN(width, 32);
+ aligned_h = ALIGN(height, 32);
+
+ // Don't add any additional padding if debug.gralloc.map_fb_memory
+ // is enabled
+ char property[PROPERTY_VALUE_MAX];
+ if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
+ (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+ (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+ return;
+ }
+
+ int bpp = 4;
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_RGB_888:
+ bpp = 3;
+ break;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_5551:
+ case HAL_PIXEL_FORMAT_RGBA_4444:
+ bpp = 2;
+ break;
+ default: break;
+ }
+
+ if (libadreno_utils) {
+ int raster_mode = 0; // Adreno unknown raster mode.
+ int padding_threshold = 512; // Threshold for padding surfaces.
+ // 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) {
+ LINK_adreno_compute_aligned_width_and_height(width,
+ height, bpp, tile_enabled,
+ raster_mode, padding_threshold,
+ &aligned_w, &aligned_h);
+
+ } else if(LINK_adreno_compute_padding) {
+ int surface_tile_height = 1; // Linear surface
+ aligned_w = LINK_adreno_compute_padding(width, bpp,
+ surface_tile_height, raster_mode,
+ padding_threshold);
+ ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
+ __FUNCTION__);
+ } else {
+ ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
+ "compute_aligned_width_and_height not found", __FUNCTION__);
}
- } else {
- switch (format)
- {
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
- case HAL_PIXEL_FORMAT_RAW_SENSOR:
- aligned_w = ALIGN(width, 32);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- aligned_w = ALIGN(width, 128);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP:
- case HAL_PIXEL_FORMAT_YV12:
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- case HAL_PIXEL_FORMAT_YCrCb_422_SP:
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- case HAL_PIXEL_FORMAT_YCrCb_422_I:
- aligned_w = ALIGN(width, 16);
- break;
- case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
- case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
- aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
- aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
- break;
- case HAL_PIXEL_FORMAT_BLOB:
- break;
- case HAL_PIXEL_FORMAT_NV21_ZSL:
- aligned_w = ALIGN(width, 64);
- aligned_h = ALIGN(height, 64);
- break;
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
- case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
- if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
- int bytesPerPixel = 0;
- int raster_mode = 0; //Adreno unknown raster mode.
- int padding_threshold = 512; //Threshold for padding
- //surfaces.
+ }
+}
- LINK_adreno_compute_compressedfmt_aligned_width_and_height(
- width, height, format, 0,raster_mode, padding_threshold,
- &aligned_w, &aligned_h, &bytesPerPixel);
-
- } else {
- ALOGW("%s: Warning!! Symbols" \
- " compute_compressedfmt_aligned_width_and_height" \
- " not found", __FUNCTION__);
- }
- break;
- default: break;
+int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
+{
+ if (libadreno_utils) {
+ if (LINK_adreno_isUBWCSupportedByGpu) {
+ ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
+ return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
}
}
+ return 0;
+}
+
+ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
+{
+ switch (hal_format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return ADRENO_PIXELFORMAT_R8G8B8A8;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return ADRENO_PIXELFORMAT_B5G6R5;
+ case HAL_PIXEL_FORMAT_sRGB_A_8888:
+ return ADRENO_PIXELFORMAT_R8G8B8A8_SRGB;
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ return ADRENO_PIXELFORMAT_NV12;
+ default:
+ ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
+ break;
+ }
+ return ADRENO_PIXELFORMAT_UNKNOWN;
}
//-------------- IAllocController-----------------------//
@@ -404,10 +457,14 @@
}
// helper function
-unsigned int getSize(int format, int width, int height, const int alignedw,
- const int alignedh) {
- unsigned int size = 0;
+unsigned int getSize(int format, int width, int height, int usage,
+ const int alignedw, const int alignedh) {
+ if (isUBwcEnabled(format, usage)) {
+ return getUBwcSize(width, height, format, alignedw, alignedh);
+ }
+
+ unsigned int size = 0;
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
@@ -507,7 +564,7 @@
size = alignedw * alignedh * ASTC_BLOCK_SIZE;
break;
default:
- ALOGE("unrecognized pixel format: 0x%x", format);
+ ALOGE("Unrecognized pixel format: 0x%x", __FUNCTION__, format);
return 0;
}
return size;
@@ -521,11 +578,11 @@
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
height,
format,
- false,
+ 0,
alignedw,
alignedh);
- size = getSize(format, width, height, alignedw, alignedh);
+ size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
return size;
}
@@ -535,16 +592,15 @@
int usage, int& alignedw, int &alignedh)
{
unsigned int size;
- int tileEnabled = isMacroTileEnabled(format, usage);
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
height,
format,
- tileEnabled,
+ usage,
alignedw,
alignedh);
- size = getSize(format, width, height, alignedw, alignedh);
+ size = getSize(format, width, height, usage, alignedw, alignedh);
return size;
}
@@ -558,10 +614,10 @@
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
height,
format,
- tileEnabled,
+ usage,
alignedw,
alignedh);
- size = getSize(format, width, height, alignedw, alignedh);
+ size = getSize(format, width, height, usage, alignedw, alignedh);
}
int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
@@ -676,3 +732,142 @@
delete hnd;
}
+
+// UBWC helper functions
+static bool isUBwcFormat(int format)
+{
+ // Explicitly defined UBWC formats
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool isUBwcSupported(int format)
+{
+ // Existing HAL formats with UBWC support
+ switch(format)
+ {
+ case HAL_PIXEL_FORMAT_RGB_565:
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_sRGB_A_8888:
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool isUBwcEnabled(int format, int usage)
+{
+ if (isUBwcFormat(format) ||
+ ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)))
+ {
+ // Allow UBWC, only if GPU supports it and CPU usage flags are not set
+ if (AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format) &&
+ !(usage & (GRALLOC_USAGE_SW_READ_MASK |
+ GRALLOC_USAGE_SW_WRITE_MASK))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static void getUBwcWidthAndHeight(int width, int height, int format,
+ int& aligned_w, int& aligned_h)
+{
+ switch (format)
+ {
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
+ aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
+ break;
+ default:
+ ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+ aligned_w = 0;
+ aligned_h = 0;
+ break;
+ }
+}
+
+static void getUBwcBlockSize(int bpp, int& block_width, int& block_height)
+{
+ block_width = 0;
+ block_height = 0;
+
+ switch(bpp)
+ {
+ case 2:
+ case 4:
+ block_width = 16;
+ block_height = 4;
+ break;
+ case 8:
+ block_width = 8;
+ block_height = 4;
+ break;
+ case 16:
+ block_width = 4;
+ block_height = 4;
+ break;
+ default:
+ ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+ break;
+ }
+}
+
+static unsigned int getUBwcMetaBufferSize(int width, int height, int bpp)
+{
+ unsigned int size = 0;
+ int meta_width, meta_height;
+ int block_width, block_height;
+
+ getUBwcBlockSize(bpp, block_width, block_height);
+
+ if (!block_width || !block_height) {
+ ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
+ return size;
+ }
+
+ // Align meta buffer height to 16 blocks
+ meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
+
+ // Align meta buffer width to 64 blocks
+ meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
+
+ // Align meta buffer size to 4K
+ size = ((meta_width * meta_height), 4096);
+ return size;
+}
+
+static unsigned int getUBwcSize(int width, int height, int format,
+ const int alignedw, const int alignedh) {
+
+ unsigned int size = 0;
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGB_565:
+ size = alignedw * alignedh * 2;
+ size += getUBwcMetaBufferSize(width, height, 2);
+ break;
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_sRGB_A_8888:
+ size = alignedw * alignedh * 4;
+ size += getUBwcMetaBufferSize(width, height, 4);
+ break;
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
+ break;
+ default:
+ ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
+ break;
+ }
+ return size;
+}
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 5533ffb..9ab9d09 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -149,6 +149,10 @@
flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
}
+ if (isUBwcEnabled(format, usage)) {
+ flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
+ }
+
if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
}
diff --git a/libgralloc/gr.h b/libgralloc/gr.h
index 797d57e..5ee0cf8 100644
--- a/libgralloc/gr.h
+++ b/libgralloc/gr.h
@@ -27,6 +27,7 @@
#include <cutils/native_handle.h>
#include <utils/Singleton.h>
+#include "adreno_utils.h"
/*****************************************************************************/
@@ -71,6 +72,9 @@
void free_buffer(private_handle_t *hnd);
int getYUVPlaneInfo(private_handle_t* pHnd, struct android_ycbcr* ycbcr);
+// To query if UBWC is enabled, based on format and usage flags
+bool isUBwcEnabled(int format, int usage);
+
/*****************************************************************************/
class Locker {
@@ -106,12 +110,21 @@
~AdrenoMemInfo();
/*
+ * Function to compute aligned width and aligned height based on
+ * width, height, format and usage flags.
+ *
+ * @return aligned width, aligned height
+ */
+ void getAlignedWidthAndHeight(int width, int height, int format,
+ int usage, int& aligned_w, int& aligned_h);
+
+ /*
* Function to compute the adreno aligned width and aligned height
* based on the width and format.
*
* @return aligned width, aligned height
*/
- void getAlignedWidthAndHeight(int width, int height, int format,
+ void getGpuAlignedWidthHeight(int width, int height, int format,
int tileEnabled, int& alignedw, int &alignedh);
/*
@@ -122,6 +135,18 @@
*/
int isMacroTilingSupportedByGPU();
+ /*
+ * Function to query whether GPU supports UBWC for given HAL format
+ * @return > 0 : supported
+ * 0 : not supported
+ */
+ int isUBWCSupportedByGPU(int format);
+
+ /*
+ * Function to get the corresponding Adreno format for given HAL format
+ */
+ ADRENOPIXELFORMAT getGpuPixelFormat(int hal_format);
+
private:
// Pointer to the padding library.
void *libadreno_utils;
@@ -153,5 +178,7 @@
int *aligned_w,
int *aligned_h,
int *bpp);
+
+ int (*LINK_adreno_isUBWCSupportedByGpu) (ADRENOPIXELFORMAT format);
};
#endif /* GR_H_ */
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index b60eaff..8b134ea 100755
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -41,7 +41,8 @@
* can never be uncached, is not secured*/
GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP = GRALLOC_USAGE_PRIVATE_0,
- /* GRALLOC_USAGE_PRIVATE_1 is unused */
+ /* Non linear, Universal Bandwidth Compression */
+ GRALLOC_USAGE_PRIVATE_ALLOC_UBWC = GRALLOC_USAGE_PRIVATE_1,
/* IOMMU heap comes from manually allocated pages,
* can be cached/uncached, is not secured */
@@ -119,6 +120,9 @@
//format reduces the memory access bandwidth
#define HAL_PIXEL_FORMAT_YCbCr_422_I_10BIT_COMPRESSED 0x43574259
+// UBWC aligned Venus format
+#define HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC 0x7FA30C06
+
//Khronos ASTC formats
#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
#define HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
@@ -206,7 +210,9 @@
// Buffer is rendered in Tile Format
PRIV_FLAGS_TILE_RENDERED = 0x02000000,
// Buffer rendered using CPU/SW renderer
- PRIV_FLAGS_CPU_RENDERED = 0x04000000
+ PRIV_FLAGS_CPU_RENDERED = 0x04000000,
+ // Buffer is allocated with UBWC alignment
+ PRIV_FLAGS_UBWC_ALIGNED = 0x08000000
};
// file-descriptors
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 356001e..44f4fb2 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -353,7 +353,7 @@
int *stride = va_arg(args, int *);
int alignedw = 0, alignedh = 0;
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
- 0, format, false, alignedw, alignedh);
+ 0, format, 0, alignedw, alignedh);
*stride = alignedw;
res = 0;
} break;
@@ -404,8 +404,7 @@
int *tileEnabled = va_arg(args,int *);
*tileEnabled = isMacroTileEnabled(format, usage);
AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
- height, format, *tileEnabled, *alignedWidth,
- *alignedHeight);
+ height, format, usage, *alignedWidth, *alignedHeight);
res = 0;
} break;
diff --git a/libhdmi/hdmi.cpp b/libhdmi/hdmi.cpp
index 1aee664..7d709cb 100644
--- a/libhdmi/hdmi.cpp
+++ b/libhdmi/hdmi.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -109,11 +109,6 @@
//Get the best mode and set
mActiveConfig = getBestConfig();
}
- // Set the mode corresponding to the active index
- mCurrentMode = mEDIDModes[mActiveConfig];
- setAttributes();
- // set system property
- property_set("hw.hdmiON", "1");
// Read the system property to determine if downscale feature is enabled.
char value[PROPERTY_VALUE_MAX];
@@ -123,6 +118,12 @@
mMDPDownscaleEnabled = true;
}
+ // Set the mode corresponding to the active index
+ mCurrentMode = mEDIDModes[mActiveConfig];
+ setAttributes();
+ // set system property
+ property_set("hw.hdmiON", "1");
+
// XXX: A debug property can be used to enable resolution change for
// testing purposes: debug.hwc.enable_resolution_change
mEnableResolutionChange = false;
@@ -148,7 +149,7 @@
HDMIDisplay::HDMIDisplay():mFd(-1),
mCurrentMode(-1), mModeCount(0), mPrimaryWidth(0), mPrimaryHeight(0),
- mUnderscanSupported(false)
+ mUnderscanSupported(false), mMDPDownscaleEnabled(false)
{
memset(&mVInfo, 0, sizeof(mVInfo));
@@ -159,10 +160,12 @@
}
mFbNum = overlay::Overlay::getInstance()->getFbForDpy(mDisplayId);
- // disable HPD at start, it will be enabled later
+ // Disable HPD at start if HDMI is external, it will be enabled later
// when the display powers on
// This helps for framework reboot or adb shell stop/start
- writeHPDOption(0);
+ if (mDisplayId) {
+ writeHPDOption(0);
+ }
// for HDMI - retreive all the modes supported by the driver
if(mFbNum != -1) {
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 2bf421f..fd3bb69 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2015, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are retained
* for attribution purposes only.
@@ -255,7 +255,7 @@
hwc_context_t* ctx = (hwc_context_t*)(dev);
const int dpy = HWC_DISPLAY_PRIMARY;
bool fbComp = false;
- if (LIKELY(list && list->numHwLayers > 1) &&
+ if (LIKELY(list && list->numHwLayers > 1) && ctx->dpyAttr[dpy].connected &&
(ctx->dpyAttr[dpy].isActive ||
ctx->mHDMIDisplay->isHDMIPrimaryDisplay())
&& !ctx->dpyAttr[dpy].isPause) {
@@ -814,7 +814,8 @@
if (hotPluggable) {
ret = ctx->mHDMIDisplay->getAttrForConfig(config, xres, yres, refresh);
if(ret < 0) {
- ALOGE("%s Error getting attributes for config %d", config);
+ ALOGE("%s Error getting attributes for config %d",
+ __FUNCTION__, config);
return ret;
}
}
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 08a4fb9..b63fb3a 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -132,9 +132,10 @@
if (LIKELY(ctx->mOverlay)) {
overlay::Overlay& ov = *(ctx->mOverlay);
+ int flags = mTileEnabled ?
+ private_handle_t::PRIV_FLAGS_TILE_RENDERED : 0;
ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
- ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
- mTileEnabled));
+ ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888, flags));
Overlay::PipeSpecs pipeSpecs;
pipeSpecs.formatClass = Overlay::FORMAT_RGB;
@@ -276,9 +277,10 @@
bool ret = false;
hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
if (LIKELY(ctx->mOverlay)) {
+ int flags = mTileEnabled ?
+ private_handle_t::PRIV_FLAGS_TILE_RENDERED : 0;
ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
- ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
- mTileEnabled));
+ ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888, flags));
overlay::Overlay& ov = *(ctx->mOverlay);
ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
@@ -440,10 +442,10 @@
hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
overlay::Overlay& ov = *(ctx->mOverlay);
+ int flags = mTileEnabled ? private_handle_t::PRIV_FLAGS_TILE_RENDERED : 0;
ovutils::Whf info(mAlignedFBWidth,
mAlignedFBHeight,
- ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
- mTileEnabled));
+ ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888, flags));
ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
ovutils::setMdpFlags(mdpFlags,
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 7e7b44b..d2962a3 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -2701,7 +2701,7 @@
int transform = layer->transform;
eTransform orient = static_cast<eTransform>(transform);
int rotFlags = ROT_FLAGS_NONE;
- uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+ uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size);
ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index adb3b9c..8139013 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1793,7 +1793,7 @@
int dst_w = dst.right - dst.left;
int dst_h = dst.bottom - dst.top;
uint32_t color = layer->transform;
- Whf whf(w, h, getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888), 0);
+ Whf whf(w, h, getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888));
ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SOLID_FILL);
if (layer->blending == HWC_BLENDING_PREMULT)
@@ -1860,7 +1860,7 @@
bool isInterlaced = metadata && (metadata->operation & PP_PARAM_INTERLACED)
&& metadata->interlaced;
int transform = layer->transform;
- uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+ uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
if(isYuvBuffer(hnd)) {
if(ctx->mMDP.version >= qdutils::MDP_V4_2 &&
@@ -1970,7 +1970,7 @@
int transform = layer->transform;
eTransform orient = static_cast<eTransform>(transform);
int rotFlags = ovutils::ROT_FLAGS_NONE;
- uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+ uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
// Handle R/B swap
@@ -2066,7 +2066,7 @@
int transform = layer->transform;
eTransform orient = static_cast<eTransform>(transform);
int rotFlags = ROT_FLAGS_NONE;
- uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd));
+ uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);
// Handle R/B swap
diff --git a/libhwcomposer/hwc_virtual.cpp b/libhwcomposer/hwc_virtual.cpp
index 61e88c8..06418bf 100644
--- a/libhwcomposer/hwc_virtual.cpp
+++ b/libhwcomposer/hwc_virtual.cpp
@@ -91,9 +91,9 @@
ctx->dpyAttr[dpy].vsync_period
= ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period;
init(ctx);
- // XXX: for architectures with limited resources we would normally
- // allow one padding round to free up resources but this breaks
- // certain use cases.
+ // Do one padding round for cases where primary has all pipes
+ // The virtual composition falls back to GPU in such cases.
+ ctx->isPaddingRound = true;
}
if(!ctx->dpyAttr[dpy].isPause) {
ctx->dpyAttr[dpy].isConfiguring = false;
diff --git a/libmemtrack/kgsl.c b/libmemtrack/kgsl.c
index b120246..6dc9774 100644
--- a/libmemtrack/kgsl.c
+++ b/libmemtrack/kgsl.c
@@ -107,7 +107,7 @@
if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) {
- if (flags[6] == 'Y')
+ if (flags[5] == 'Y')
accounted_size += size;
else
unaccounted_size += size;
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index dd030ef..b37eba9 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -141,12 +141,28 @@
return -1;
}
-// This function returns corresponding tile format
-// MDSS support following RGB tile formats
-// 32 bit formats
-// 16 bit formats
-int getMdpFormat(int format, bool tileEnabled)
+int getMdpFormat(int format, int flags)
{
+ bool uBwcEnabled = (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED);
+ bool tileEnabled = (flags & private_handle_t::PRIV_FLAGS_TILE_RENDERED);
+
+ // Use UBWC extension, if UBWC is enabled
+ if (uBwcEnabled) {
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ return MDP_RGBA_8888_UBWC;
+ case HAL_PIXEL_FORMAT_RGB_565:
+ return MDP_RGB_565_UBWC;
+ case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
+ return MDP_Y_CBCR_H2V2_UBWC;
+ default:
+ ALOGE("%s: Unsupported HAL format = 0x%x", __func__, format);
+ break;
+ }
+ }
+
if(!tileEnabled) {
return getMdpFormat(format);
}
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 54ee0fd..5e3bd1f 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -368,7 +368,7 @@
};
int getMdpFormat(int format);
-int getMdpFormat(int format, bool tileEnabled);
+int getMdpFormat(int format, int flags);
int getHALFormat(int mdpFormat);
void getDecimationFactor(const int& src_w, const int& src_h,
const int& dst_w, const int& dst_h, uint8_t& horzDeci,