blob: 20b002527a7a5f487696597644c71e3a2001b331 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <binder/Parcel.h>
#include <binder/IInterface.h>
#include "IExynosHWC.h"
namespace android {
enum {
ADD_VIRTUAL_DISPLAY_DEVICE = 0,
DESTROY_VIRTUAL_DISPLAY_DEVICE,
SET_WFD_MODE,
GET_WFD_MODE,
SEND_WFD_COMMAND,
SET_SECURE_VDS_MODE,
SET_WFD_OUTPUT_RESOLUTION,
GET_WFD_OUTPUT_RESOLUTION,
SET_PRESENTATION_MODE,
GET_PRESENTATION_MODE,
SET_VDS_GLES_FORMAT,
HWC_CONTROL,
SET_BOOT_FINISHED,
SET_VIRTUAL_HPD,
GET_EXTERNAL_DISPLAY_CONFIG,
SET_EXTERNAL_DISPLAY_CONFIG,
ENABLE_MPP,
SET_EXTERNAL_VSYNC,
SET_DDISCALER,
GET_EXTERNAL_HDR_CAPA,
#if 0
NOTIFY_PSR_EXIT,
#endif
SET_HWC_DEBUG = 105,
GET_HWC_DEBUG = 106,
SET_HWC_FENCE_DEBUG = 107,
GET_HWC_FENCE_DEBUG = 108,
};
class BpExynosHWCService : public BpInterface<IExynosHWCService> {
public:
BpExynosHWCService(const sp<IBinder>& impl)
: BpInterface<IExynosHWCService>(impl)
{
}
virtual int addVirtualDisplayDevice()
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
int result = remote()->transact(ADD_VIRTUAL_DISPLAY_DEVICE, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("ADD_VIRTUAL_DISPLAY_DEVICE transact error(%d)", result);
return result;
}
virtual int destroyVirtualDisplayDevice()
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
int result = remote()->transact(DESTROY_VIRTUAL_DISPLAY_DEVICE, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("DESTROY_VIRTUAL_DISPLAY_DEVICE transact error(%d)", result);
return result;
}
virtual int setWFDMode(unsigned int mode)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(mode);
int result = remote()->transact(SET_WFD_MODE, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("SET_WFD_MODE transact error(%d)", result);
return result;
}
virtual int getWFDMode()
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
int result = remote()->transact(GET_WFD_MODE, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("GET_WFD_MODE transact error(%d)", result);
return result;
}
virtual int sendWFDCommand(int32_t cmd, int32_t ext1, int32_t ext2)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(cmd);
data.writeInt32(ext1);
data.writeInt32(ext2);
int result = remote()->transact(SEND_WFD_COMMAND, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("SEND_WFD_COMMAND transact error(%d)", result);
return result;
}
virtual int setSecureVDSMode(unsigned int mode)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(mode);
int result = remote()->transact(SET_SECURE_VDS_MODE, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("SET_SECURE_VDS_MODE transact error(%d)", result);
return result;
}
virtual int setWFDOutputResolution(unsigned int width, unsigned int height)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(width);
data.writeInt32(height);
int result = remote()->transact(SET_WFD_OUTPUT_RESOLUTION, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("SET_WFD_OUTPUT_RESOLUTION transact error(%d)", result);
return result;
}
virtual void getWFDOutputResolution(unsigned int *width, unsigned int *height)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
int result = remote()->transact(GET_WFD_OUTPUT_RESOLUTION, data, &reply);
if (result == NO_ERROR) {
*width = reply.readInt32();
*height = reply.readInt32();
} else
ALOGE("GET_WFD_OUTPUT_RESOLUTION transact error(%d)", result);
}
virtual void setPresentationMode(bool use)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(use);
int result = remote()->transact(SET_PRESENTATION_MODE, data, &reply);
if (result != NO_ERROR)
ALOGE("SET_PRESENTATION_MODE transact error(%d)", result);
}
virtual int getPresentationMode(void)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
int result = remote()->transact(GET_PRESENTATION_MODE, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("GET_PRESENTATION_MODE transact error(%d)", result);
return result;
}
virtual int setVDSGlesFormat(int format)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(format);
int result = remote()->transact(SET_VDS_GLES_FORMAT, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("SET_VDS_GLES_FORMAT transact error(%d)", result);
return result;
}
virtual int getExternalDisplayConfigs()
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
int result = remote()->transact(GET_EXTERNAL_DISPLAY_CONFIG, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("GET_EXTERNAL_DISPLAY_CONFIG transact error(%d)", result);
return result;
}
virtual int setExternalDisplayConfig(unsigned int index)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(index);
int result = remote()->transact(SET_EXTERNAL_DISPLAY_CONFIG, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("SET_EXTERNAL_DISPLAY_CONFIG transact error(%d)", result);
return result;
}
virtual int setExternalVsyncEnabled(unsigned int index)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(index);
int result = remote()->transact(SET_EXTERNAL_VSYNC, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("SET_EXTERNAL_VSYNC transact error(%d)", result);
return result;
}
virtual int getExternalHdrCapabilities()
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
int result = remote()->transact(GET_EXTERNAL_HDR_CAPA, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("GET_EXTERNAL_HDR_CAPA transact error(%d)", result);
return result;
}
virtual void setBootFinished()
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
int result = remote()->transact(SET_BOOT_FINISHED, data, &reply);
if (result != NO_ERROR)
ALOGE("SET_BOOT_FINISHED transact error(%d)", result);
}
virtual void enableMPP(uint32_t physicalType, uint32_t physicalIndex, uint32_t logicalIndex, uint32_t enable)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(physicalType);
data.writeInt32(physicalIndex);
data.writeInt32(logicalIndex);
data.writeInt32(enable);
int result = remote()->transact(ENABLE_MPP, data, &reply);
if (result != NO_ERROR)
ALOGE("ENABLE_MPP transact error(%d)", result);
}
virtual void setHWCDebug(int debug)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(debug);
int result = remote()->transact(SET_HWC_DEBUG, data, &reply);
if (result != NO_ERROR)
ALOGE("SET_HWC_DEBUG transact error(%d)", result);
}
virtual uint32_t getHWCDebug()
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
int result = remote()->transact(GET_HWC_DEBUG, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else {
ALOGE("GET_HWC_DEBUG transact error(%d)", result);
}
return result;
}
virtual void setHWCFenceDebug(uint32_t fenceNum, uint32_t ipNum, uint32_t mode)
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(fenceNum);
data.writeInt32(ipNum);
data.writeInt32(mode);
remote()->transact(SET_HWC_FENCE_DEBUG, data, &reply);
}
virtual void getHWCFenceDebug()
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
remote()->transact(GET_HWC_FENCE_DEBUG, data, &reply);
}
virtual int setHWCCtl(uint32_t display, uint32_t ctrl, int32_t val) {
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(display);
data.writeInt32(ctrl);
data.writeInt32(val);
int result = remote()->transact(HWC_CONTROL, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("HWC_CONTROL transact error(%d)", result);
return result;
};
virtual int setDDIScaler(uint32_t width, uint32_t height) {
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
data.writeInt32(width);
data.writeInt32(height);
int result = remote()->transact(SET_DDISCALER, data, &reply);
if (result == NO_ERROR)
result = reply.readInt32();
else
ALOGE("SET_DDISCALER transact error(%d)", result);
return result;
}
/*
virtual void notifyPSRExit()
{
Parcel data, reply;
data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
remote()->transact(NOTIFY_PSR_EXIT, data, &reply);
}
*/
};
IMPLEMENT_META_INTERFACE(ExynosHWCService, "android.hal.ExynosHWCService");
status_t BnExynosHWCService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case ADD_VIRTUAL_DISPLAY_DEVICE: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int res = addVirtualDisplayDevice();
reply->writeInt32(res);
return NO_ERROR;
} break;
case DESTROY_VIRTUAL_DISPLAY_DEVICE: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int res = destroyVirtualDisplayDevice();
reply->writeInt32(res);
return NO_ERROR;
} break;
case SET_WFD_MODE: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int mode = data.readInt32();
int res = setWFDMode(mode);
reply->writeInt32(res);
return NO_ERROR;
} break;
case GET_WFD_MODE: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int res = getWFDMode();
reply->writeInt32(res);
return NO_ERROR;
} break;
case SEND_WFD_COMMAND: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int cmd = data.readInt32();
int ext1 = data.readInt32();
int ext2 = data.readInt32();
int res = sendWFDCommand(cmd, ext1, ext2);
reply->writeInt32(res);
return NO_ERROR;
} break;
case SET_SECURE_VDS_MODE: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int mode = data.readInt32();
int res = setSecureVDSMode(mode);
reply->writeInt32(res);
return NO_ERROR;
} break;
case SET_WFD_OUTPUT_RESOLUTION: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int width = data.readInt32();
int height = data.readInt32();
int res = setWFDOutputResolution(width, height);
reply->writeInt32(res);
return NO_ERROR;
} break;
case GET_WFD_OUTPUT_RESOLUTION: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
uint32_t width, height;
getWFDOutputResolution(&width, &height);
reply->writeInt32(width);
reply->writeInt32(height);
return NO_ERROR;
} break;
case SET_PRESENTATION_MODE: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int use = data.readInt32();
setPresentationMode(use);
return NO_ERROR;
} break;
case GET_PRESENTATION_MODE: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int res = getPresentationMode();
reply->writeInt32(res);
return NO_ERROR;
} break;
case SET_VDS_GLES_FORMAT: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int format = data.readInt32();
int res = setVDSGlesFormat(format);
reply->writeInt32(res);
return NO_ERROR;
} break;
case HWC_CONTROL: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int display = data.readInt32();
int ctrl = data.readInt32();
int value = data.readInt32();
int res = setHWCCtl(display, ctrl, value);
reply->writeInt32(res);
return NO_ERROR;
} break;
case GET_EXTERNAL_DISPLAY_CONFIG: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int res = getExternalDisplayConfigs();
reply->writeInt32(res);
return NO_ERROR;
} break;
case SET_EXTERNAL_DISPLAY_CONFIG: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int index = data.readInt32();
int res = setExternalDisplayConfig(index);
reply->writeInt32(res);
return NO_ERROR;
} break;
case SET_EXTERNAL_VSYNC: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int index = data.readInt32();
int res = setExternalVsyncEnabled(index);
reply->writeInt32(res);
return NO_ERROR;
} break;
case GET_EXTERNAL_HDR_CAPA: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int res = getExternalHdrCapabilities();
reply->writeInt32(res);
return NO_ERROR;
} break;
case SET_BOOT_FINISHED: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
setBootFinished();
return NO_ERROR;
} break;
case ENABLE_MPP: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
uint32_t type = data.readInt32();
uint32_t physicalIdx = data.readInt32();
uint32_t logicalIdx = data.readInt32();
uint32_t enable = data.readInt32();
enableMPP(type, physicalIdx, logicalIdx, enable);
return NO_ERROR;
} break;
case SET_HWC_DEBUG: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int debug = data.readInt32();
setHWCDebug(debug);
reply->writeInt32(debug);
return NO_ERROR;
} break;
case GET_HWC_DEBUG: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int debugFlag = getHWCDebug();
reply->writeInt32(debugFlag);
return NO_ERROR;
} break;
case SET_HWC_FENCE_DEBUG: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
uint32_t fenceNum = data.readInt32();
uint32_t ipNum = data.readInt32();
uint32_t mode = data.readInt32();
setHWCFenceDebug(fenceNum, ipNum, mode);
return NO_ERROR;
} break;
case SET_DDISCALER: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
uint32_t width = data.readInt32();
uint32_t height = data.readInt32();
int error = setDDIScaler(width, height);
reply->writeInt32(error);
return NO_ERROR;
} break;
#if 0
case SET_HWC_CTL_MAX_OVLY_CNT: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int val = data.readInt32();
setHWCCtl(SET_HWC_CTL_MAX_OVLY_CNT, val);
return NO_ERROR;
} break;
case SET_HWC_CTL_VIDEO_OVLY_CNT: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int val = data.readInt32();
setHWCCtl(SET_HWC_CTL_VIDEO_OVLY_CNT, val);
return NO_ERROR;
} break;
case SET_HWC_CTL_DYNAMIC_RECOMP: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int val = data.readInt32();
setHWCCtl(SET_HWC_CTL_DYNAMIC_RECOMP, val);
return NO_ERROR;
} break;
case SET_HWC_CTL_SKIP_STATIC: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int val = data.readInt32();
setHWCCtl(SET_HWC_CTL_SKIP_STATIC, val);
return NO_ERROR;
} break;
case SET_HWC_CTL_SECURE_DMA: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
int val = data.readInt32();
setHWCCtl(SET_HWC_CTL_SECURE_DMA, val);
return NO_ERROR;
} break;
case NOTIFY_PSR_EXIT: {
CHECK_INTERFACE(IExynosHWCService, data, reply);
notifyPSRExit();
return NO_ERROR;
}
#endif
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
}