sdm: Notify surfaceflinger to draw S3D framebuffer target
Set S3D flag to private handle so that SurfaceFlinger can help
to draw S3D framebuffer target according to the flag in case
MDP can not handle some of S3D cases.
Change-Id: Ic39d0c0dd47c71e8a677d1e52af2c485494235b3
CRs-fixed: 999055
diff --git a/libqdutils/qdMetaData.cpp b/libqdutils/qdMetaData.cpp
index 72edfdf..130cf46 100644
--- a/libqdutils/qdMetaData.cpp
+++ b/libqdutils/qdMetaData.cpp
@@ -87,6 +87,43 @@
case SET_SINGLE_BUFFER_MODE:
data->isSingleBufferMode = *((uint32_t *)param);
break;
+ case SET_S3D_COMP:
+ data->s3dComp = *((S3DGpuComp_t *)param);
+ break;
+ default:
+ ALOGE("Unknown paramType %d", paramType);
+ break;
+ }
+ if(munmap(base, size))
+ ALOGE("%s: failed to unmap ptr %p, err %d", __func__, (void*)base,
+ errno);
+ return 0;
+}
+
+int clearMetaData(private_handle_t *handle, DispParamType paramType) {
+ if (!handle) {
+ ALOGE("%s: Private handle is null!", __func__);
+ return -1;
+ }
+ if (handle->fd_metadata == -1) {
+ ALOGE("%s: Bad fd for extra data!", __func__);
+ return -1;
+ }
+
+ unsigned long size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+ void *base = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED,
+ handle->fd_metadata, 0);
+ if (base == reinterpret_cast<void*>(MAP_FAILED)) {
+ ALOGE("%s: mmap() failed: error is %s!", __func__, strerror(errno));
+ return -1;
+ }
+ MetaData_t *data = reinterpret_cast <MetaData_t *>(base);
+ data->operation &= ~paramType;
+ switch (paramType) {
+ case SET_S3D_COMP:
+ data->s3dComp.displayId = -1;
+ data->s3dComp.s3dMode = 0;
+ break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
@@ -120,7 +157,6 @@
}
MetaData_t *data = reinterpret_cast <MetaData_t *>(base);
- data->operation |= paramType;
switch (paramType) {
case GET_PP_PARAM_INTERLACED:
*((int32_t *)param) = data->interlaced;
@@ -149,6 +185,9 @@
case GET_SINGLE_BUFFER_MODE:
*((uint32_t *)param) = data->isSingleBufferMode ;
break;
+ case GET_S3D_COMP:
+ *((S3DGpuComp_t *)param) = data->s3dComp;
+ break;
default:
ALOGE("Unknown paramType %d", paramType);
break;
diff --git a/libqdutils/qdMetaData.h b/libqdutils/qdMetaData.h
index fd4f444..8c0a0b0 100644
--- a/libqdutils/qdMetaData.h
+++ b/libqdutils/qdMetaData.h
@@ -57,6 +57,11 @@
int32_t sliceHeight;
};
+struct S3DGpuComp_t {
+ int32_t displayId; /* on which display S3D is composed by client */
+ uint32_t s3dMode; /* the S3D format of this layer to be accessed by client */
+};
+
struct MetaData_t {
int32_t operation;
int32_t interlaced;
@@ -79,6 +84,8 @@
/* Set by graphics to indicate that this buffer will be written to but not
* swapped out */
uint32_t isSingleBufferMode;
+ /* Indicate GPU to draw S3D layer on dedicate display device */
+ struct S3DGpuComp_t s3dComp;
};
enum DispParamType {
@@ -97,6 +104,7 @@
LINEAR_FORMAT = 0x1000,
SET_IGC = 0x2000,
SET_SINGLE_BUFFER_MODE = 0x4000,
+ SET_S3D_COMP = 0x8000,
};
enum DispFetchParamType {
@@ -109,6 +117,7 @@
GET_LINEAR_FORMAT = 0x1000,
GET_IGC = 0x2000,
GET_SINGLE_BUFFER_MODE = 0x4000,
+ GET_S3D_COMP = 0x8000,
};
struct private_handle_t;
@@ -119,6 +128,9 @@
void *param);
int copyMetaData(struct private_handle_t *src, struct private_handle_t *dst);
+
+int clearMetaData(struct private_handle_t *handle, enum DispParamType paramType);
+
#ifdef __cplusplus
}
#endif
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index ebb16d5..ccaa0b5 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -595,6 +595,12 @@
*/
virtual DisplayError GetDisplayPort(DisplayPort *port) = 0;
+ /*! @brief Method to query whether it is Primrary device.
+
+ @return \link Bool \endlink
+ */
+ virtual bool IsPrimaryDisplay() = 0;
+
protected:
virtual ~DisplayInterface() { }
};
diff --git a/sdm/include/core/layer_buffer.h b/sdm/include/core/layer_buffer.h
index 801938d..0bf1aa4 100644
--- a/sdm/include/core/layer_buffer.h
+++ b/sdm/include/core/layer_buffer.h
@@ -259,7 +259,8 @@
LayerBufferFlags flags; //!< Flags associated with this buffer.
LayerBufferS3DFormat s3d_format = kS3dFormatNone;
- //!< Represents the format of the buffer content in 3D.
+ //!< Represents the format of the buffer content in 3D. This field
+ //!< could be modified by both client and SDM.
uint64_t buffer_id __attribute__((aligned(8))) = 0;
//!< Specifies the buffer id.
};
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index 7493418..39b54c7 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -68,6 +68,10 @@
//!< device will mark the layer for GPU composition if it can not handle
//!< it completely.
+ kCompositionGPUS3D, //!< This layer will be drawn onto the target buffer in s3d mode by GPU.
+ //!< Display device should mark the layer for GPU composition if it can
+ //!< not handle it completely.
+
kCompositionSDE, //!< This layer will be handled by SDE. It must not be composed by GPU.
kCompositionHWCursor, //!< This layer will be handled by SDE using HWCursor. It must not be
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 948e261..0e48f2c 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -1048,4 +1048,10 @@
return kErrorNone;
}
+bool DisplayBase::IsPrimaryDisplay() {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+
+ return hw_panel_info_.is_primary_panel;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 2ef6eb5..91bbc37 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -110,6 +110,7 @@
virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data);
virtual DisplayError GetDisplayPort(DisplayPort *port);
+ virtual bool IsPrimaryDisplay();
protected:
// DumpImpl method
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index be02ac7..b4dfe6e 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -572,6 +572,19 @@
return 0;
}
+void HWCDisplay::SetLayerS3DMode(const LayerBufferS3DFormat &source, uint32_t *target) {
+#ifdef QTI_BSP
+ switch (source) {
+ case kS3dFormatNone: *target = HWC_S3DMODE_NONE; break;
+ case kS3dFormatLeftRight: *target = HWC_S3DMODE_LR; break;
+ case kS3dFormatRightLeft: *target = HWC_S3DMODE_RL; break;
+ case kS3dFormatTopBottom: *target = HWC_S3DMODE_TB; break;
+ case kS3dFormatFramePacking: *target = HWC_S3DMODE_FP; break;
+ default: *target = HWC_S3DMODE_MAX; break;
+ }
+#endif
+}
+
int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
if (shutdown_pending_) {
return 0;
@@ -607,12 +620,26 @@
hwc_layer_1_t &hwc_layer = content_list->hwLayers[i];
Layer *layer = layer_stack_.layers.at(i);
LayerComposition composition = layer->composition;
+ private_handle_t* pvt_handle = static_cast<private_handle_t*>
+ (const_cast<native_handle_t*>(hwc_layer.handle));
+ MetaData_t *meta_data = pvt_handle ?
+ reinterpret_cast<MetaData_t *>(pvt_handle->base_metadata) : NULL;
if ((composition == kCompositionSDE) || (composition == kCompositionHybrid) ||
(composition == kCompositionBlit)) {
hwc_layer.hints |= HWC_HINT_CLEAR_FB;
}
SetComposition(composition, &hwc_layer.compositionType);
+
+ if (meta_data != NULL) {
+ if (composition == kCompositionGPUS3D) {
+ // Align HWC and client's dispaly ID in case of HDMI as primary
+ meta_data->s3dComp.displayId =
+ display_intf_->IsPrimaryDisplay() ? HWC_DISPLAY_PRIMARY: id_;
+ SetLayerS3DMode(layer->input_buffer->s3d_format,
+ &meta_data->s3dComp.s3dMode);
+ }
+ }
}
return 0;
@@ -776,6 +803,7 @@
switch (source) {
case kCompositionGPUTarget: *target = HWC_FRAMEBUFFER_TARGET; break;
case kCompositionGPU: *target = HWC_FRAMEBUFFER; break;
+ case kCompositionGPUS3D: *target = HWC_FRAMEBUFFER; break;
case kCompositionHWCursor: *target = HWC_CURSOR_OVERLAY; break;
default: *target = HWC_OVERLAY; break;
}
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index 014bd02..e68c1d9 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -160,6 +160,7 @@
inline void SetComposition(const LayerComposition &source, int32_t *target);
inline void SetBlending(const int32_t &source, LayerBlending *target);
int SetFormat(const int32_t &source, const int flags, LayerBufferFormat *target);
+ void SetLayerS3DMode(const LayerBufferS3DFormat &source, uint32_t *target);
LayerBufferFormat GetSDMFormat(const int32_t &source, const int flags);
const char *GetHALPixelFormatString(int format);
const char *GetDisplayString();