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
This commit is contained in:
Ray Zhang
2016-08-08 19:36:03 +08:00
committed by rayz
parent 31d3cc7e54
commit 8ace84d117
9 changed files with 100 additions and 2 deletions

View File

@@ -87,6 +87,43 @@ int setMetaData(private_handle_t *handle, DispParamType paramType,
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 @@ int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
}
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 @@ int getMetaData(private_handle_t *handle, DispFetchParamType paramType,
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;

View File

@@ -57,6 +57,11 @@ struct BufferDim_t {
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 @@ struct MetaData_t {
/* 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 @@ enum DispParamType {
LINEAR_FORMAT = 0x1000,
SET_IGC = 0x2000,
SET_SINGLE_BUFFER_MODE = 0x4000,
SET_S3D_COMP = 0x8000,
};
enum DispFetchParamType {
@@ -109,6 +117,7 @@ enum DispFetchParamType {
GET_LINEAR_FORMAT = 0x1000,
GET_IGC = 0x2000,
GET_SINGLE_BUFFER_MODE = 0x4000,
GET_S3D_COMP = 0x8000,
};
struct private_handle_t;
@@ -119,6 +128,9 @@ int getMetaData(struct private_handle_t *handle, enum DispFetchParamType paramTy
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

View File

@@ -595,6 +595,12 @@ class DisplayInterface {
*/
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() { }
};

View File

@@ -259,7 +259,8 @@ struct LayerBuffer {
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.
};

View File

@@ -68,6 +68,10 @@ enum LayerComposition {
//!< 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

View File

@@ -1048,4 +1048,10 @@ DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) {
return kErrorNone;
}
bool DisplayBase::IsPrimaryDisplay() {
lock_guard<recursive_mutex> obj(recursive_mutex_);
return hw_panel_info_.is_primary_panel;
}
} // namespace sdm

View File

@@ -110,6 +110,7 @@ class DisplayBase : public DisplayInterface, DumpImpl {
virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data);
virtual DisplayError GetDisplayPort(DisplayPort *port);
virtual bool IsPrimaryDisplay();
protected:
// DumpImpl method

View File

@@ -572,6 +572,19 @@ int HWCDisplay::PrePrepareLayerStack(hwc_display_contents_1_t *content_list) {
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 @@ int HWCDisplay::PrepareLayerStack(hwc_display_contents_1_t *content_list) {
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 @@ void HWCDisplay::SetComposition(const LayerComposition &source, int32_t *target)
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;
}

View File

@@ -160,6 +160,7 @@ class HWCDisplay : public DisplayEventHandler {
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();