You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
832 lines
21 KiB
832 lines
21 KiB
/* |
|
* Copyright (c) 2009-2011 Intel Corporation. All rights reserved. |
|
* |
|
* 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. |
|
*/ |
|
|
|
//#define LOG_NDEBUG 0 |
|
#define LOG_TAG "IntelMetadataBuffer" |
|
#include <wrs_omxil_core/log.h> |
|
|
|
#include "IntelMetadataBuffer.h" |
|
#include <string.h> |
|
#include <stdio.h> |
|
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING |
|
#include <binder/IServiceManager.h> |
|
#include <binder/MemoryBase.h> |
|
#include <binder/Parcel.h> |
|
#include <utils/List.h> |
|
#include <utils/threads.h> |
|
#include <ui/GraphicBuffer.h> |
|
|
|
//#define TEST |
|
|
|
struct ShareMemMap { |
|
uint32_t sessionflag; |
|
intptr_t value; |
|
intptr_t value_backup; |
|
uint32_t type; |
|
sp<MemoryBase> membase; |
|
sp<GraphicBuffer> gbuffer; |
|
}; |
|
|
|
List <ShareMemMap *> gShareMemMapList; |
|
Mutex gShareMemMapListLock; |
|
|
|
enum { |
|
SHARE_MEM = IBinder::FIRST_CALL_TRANSACTION, |
|
GET_MEM, |
|
CLEAR_MEM, |
|
}; |
|
|
|
enum { |
|
ST_MEMBASE = 0, |
|
ST_GFX, |
|
ST_MAX, |
|
}; |
|
|
|
#define REMOTE_PROVIDER 0x80000000 |
|
#define REMOTE_CONSUMER 0x40000000 |
|
|
|
static ShareMemMap* ReadMemObjFromBinder(const Parcel& data, uint32_t sessionflag, intptr_t value) { |
|
|
|
uint32_t type = data.readInt32(); |
|
if (type >= ST_MAX) |
|
return NULL; |
|
|
|
ShareMemMap* map = new ShareMemMap; |
|
map->sessionflag = sessionflag; |
|
map->type = type; |
|
map->value_backup = value; |
|
map->membase = NULL; |
|
map->gbuffer= NULL; |
|
|
|
// LOGI("ReadMemObjFromBinder"); |
|
|
|
if (type == ST_MEMBASE) /*offset, size, heap*/ |
|
{ |
|
ssize_t offset = data.readInt32(); |
|
size_t size = data.readInt32(); |
|
|
|
sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder()); |
|
|
|
sp<MemoryBase> mem = new MemoryBase(heap, offset, size); |
|
if (mem == NULL) |
|
{ |
|
delete map; |
|
return NULL; |
|
} |
|
|
|
map->value = (intptr_t)( mem->pointer() + 0x0FFF) & ~0x0FFF; |
|
map->membase = mem; |
|
|
|
#ifdef TEST |
|
ALOGI("membase heapID:%d, pointer:%x data:%x, aligned value:%x", \ |
|
heap->getHeapID(), mem->pointer(), *((intptr_t *)(mem->pointer())), map->value); |
|
#endif |
|
|
|
} |
|
else if (type == ST_GFX) /*graphicbuffer*/ |
|
{ |
|
sp<GraphicBuffer> buffer = new GraphicBuffer(); |
|
if (buffer == NULL) |
|
{ |
|
delete map; |
|
return NULL; |
|
} |
|
data.read(*buffer); |
|
|
|
map->value = (intptr_t)buffer->handle; |
|
map->gbuffer = buffer; |
|
|
|
#ifdef TEST |
|
void* usrptr[3]; |
|
buffer->lock(GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN, &usrptr[0]); |
|
buffer->unlock(); |
|
ALOGI("gfx handle:%p data:%x", (intptr_t)buffer->handle, *((intptr_t *)usrptr[0])); |
|
#endif |
|
} |
|
|
|
gShareMemMapListLock.lock(); |
|
gShareMemMapList.push_back(map); |
|
gShareMemMapListLock.unlock(); |
|
return map; |
|
} |
|
|
|
static status_t WriteMemObjToBinder(Parcel& data, ShareMemMap* smem) { |
|
|
|
if (smem->type >= ST_MAX) |
|
return BAD_VALUE; |
|
|
|
// LOGI("WriteMemObjToBinder"); |
|
|
|
data.writeInt32(smem->type); |
|
|
|
if (smem->type == ST_MEMBASE) /*offset, size, heap*/ |
|
{ |
|
ssize_t offset; |
|
size_t size; |
|
sp<IMemoryHeap> heap = smem->membase->getMemory(&offset, &size); |
|
data.writeInt32(offset); |
|
data.writeInt32(size); |
|
data.writeStrongBinder(IInterface::asBinder(heap)); |
|
#ifdef TEST |
|
ALOGI("membase heapID:%d pointer:%x data:%x", \ |
|
heap->getHeapID(), smem->membase->pointer(), *((int *)(smem->membase->pointer()))); |
|
#endif |
|
} |
|
else if (smem->type == ST_GFX) /*graphicbuffer*/ |
|
data.write(*(smem->gbuffer)); |
|
|
|
return NO_ERROR; |
|
} |
|
|
|
static void ClearLocalMem(uint32_t sessionflag) |
|
{ |
|
List<ShareMemMap *>::iterator node; |
|
|
|
gShareMemMapListLock.lock(); |
|
|
|
for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); ) |
|
{ |
|
if ((*node)->sessionflag == sessionflag) //remove all buffers belong to this session |
|
{ |
|
(*node)->membase = NULL; |
|
(*node)->gbuffer = NULL; |
|
delete (*node); |
|
node = gShareMemMapList.erase(node); |
|
} |
|
else |
|
node ++; |
|
} |
|
|
|
gShareMemMapListLock.unlock(); |
|
} |
|
|
|
static ShareMemMap* FindShareMem(uint32_t sessionflag, intptr_t value, bool isBackup) |
|
{ |
|
List<ShareMemMap *>::iterator node; |
|
|
|
gShareMemMapListLock.lock(); |
|
for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); node++) |
|
{ |
|
if (isBackup) |
|
{ |
|
if ((*node)->sessionflag == sessionflag && (*node)->value_backup == value) |
|
{ |
|
gShareMemMapListLock.unlock(); |
|
return (*node); |
|
} |
|
} |
|
else if ((*node)->sessionflag == sessionflag && (*node)->value == value) |
|
{ |
|
gShareMemMapListLock.unlock(); |
|
return (*node); |
|
} |
|
} |
|
gShareMemMapListLock.unlock(); |
|
|
|
return NULL; |
|
} |
|
|
|
static ShareMemMap* PopShareMem(uint32_t sessionflag, intptr_t value) |
|
{ |
|
List<ShareMemMap *>::iterator node; |
|
|
|
gShareMemMapListLock.lock(); |
|
for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); node++) |
|
{ |
|
if ((*node)->sessionflag == sessionflag && (*node)->value == value) |
|
{ |
|
gShareMemMapList.erase(node); |
|
gShareMemMapListLock.unlock(); |
|
return (*node); |
|
} |
|
} |
|
gShareMemMapListLock.unlock(); |
|
|
|
return NULL; |
|
} |
|
|
|
static void PushShareMem(ShareMemMap* &smem) |
|
{ |
|
gShareMemMapListLock.lock(); |
|
gShareMemMapList.push_back(smem); |
|
gShareMemMapListLock.unlock(); |
|
} |
|
|
|
static sp<IBinder> GetIntelBufferSharingService() { |
|
|
|
sp<IServiceManager> sm = defaultServiceManager(); |
|
sp<IBinder> binder = sm->checkService(String16("media.IntelBufferSharing")); |
|
|
|
if (binder == 0) |
|
ALOGE("media.IntelBufferSharing service is not published"); |
|
|
|
return binder; |
|
} |
|
|
|
IntelBufferSharingService* IntelBufferSharingService::gBufferService = NULL; |
|
|
|
status_t IntelBufferSharingService::instantiate(){ |
|
status_t ret = NO_ERROR; |
|
|
|
if (gBufferService == NULL) { |
|
gBufferService = new IntelBufferSharingService(); |
|
ret = defaultServiceManager()->addService(String16("media.IntelBufferSharing"), gBufferService); |
|
LOGI("IntelBufferSharingService::instantiate() ret = %d\n", ret); |
|
} |
|
|
|
return ret; |
|
} |
|
|
|
status_t IntelBufferSharingService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { |
|
|
|
//TODO: if pid is int32? |
|
pid_t pid = data.readInt32(); |
|
uint32_t sessionflag = data.readInt32(); |
|
|
|
switch(code) |
|
{ |
|
case SHARE_MEM: |
|
{ |
|
|
|
if (pid == getpid()) //in same process, should not use binder |
|
{ |
|
ALOGE("onTransact in same process, wrong sessionflag?"); |
|
return UNKNOWN_ERROR; |
|
} |
|
|
|
intptr_t value = data.readIntPtr(); |
|
|
|
// LOGI("onTransact SHARE_MEM value=%x", value); |
|
|
|
//different process |
|
ShareMemMap* map = ReadMemObjFromBinder(data, sessionflag, value); |
|
if (map == NULL) |
|
return UNKNOWN_ERROR; |
|
|
|
reply->writeIntPtr(map->value); |
|
|
|
return NO_ERROR; |
|
} |
|
case CLEAR_MEM: |
|
{ |
|
// LOGI("onTransact CLEAR_MEM sessionflag=%x", sessionflag); |
|
|
|
if (pid == getpid()) //in same process, should not use binder |
|
{ |
|
//same process, return same pointer in data |
|
ALOGE("onTransact CLEAR_MEM in same process, wrong sessionflag?"); |
|
return UNKNOWN_ERROR; |
|
} |
|
|
|
ClearLocalMem(sessionflag); |
|
return NO_ERROR; |
|
} |
|
case GET_MEM: |
|
{ |
|
|
|
if (pid == getpid()) //in same process, should not use binder |
|
{ |
|
ALOGE("onTransact GET_MEM in same process, wrong sessionflag?"); |
|
return UNKNOWN_ERROR; |
|
} |
|
|
|
intptr_t value = data.readIntPtr(); |
|
|
|
// LOGI("onTransact GET_MEM value=%x", value); |
|
|
|
ShareMemMap* smem = FindShareMem(sessionflag, value, false); |
|
if (smem && (NO_ERROR == WriteMemObjToBinder(*reply, smem))) |
|
return NO_ERROR; |
|
else |
|
ALOGE("onTransact GET_MEM: Not find mem"); |
|
|
|
return UNKNOWN_ERROR; |
|
} |
|
default: |
|
return BBinder::onTransact(code, data, reply, flags); |
|
|
|
} |
|
return NO_ERROR; |
|
} |
|
#endif |
|
|
|
IntelMetadataBuffer::IntelMetadataBuffer() |
|
{ |
|
mType = IntelMetadataBufferTypeCameraSource; |
|
mValue = 0; |
|
mInfo = NULL; |
|
mExtraValues = NULL; |
|
mExtraValues_Count = 0; |
|
mBytes = NULL; |
|
mSize = 0; |
|
#ifdef INTEL_VIDEO_XPROC_SHARING |
|
mSessionFlag = 0; |
|
#endif |
|
} |
|
|
|
IntelMetadataBuffer::IntelMetadataBuffer(IntelMetadataBufferType type, intptr_t value) |
|
{ |
|
mType = type; |
|
mValue = value; |
|
mInfo = NULL; |
|
mExtraValues = NULL; |
|
mExtraValues_Count = 0; |
|
mBytes = NULL; |
|
mSize = 0; |
|
#ifdef INTEL_VIDEO_XPROC_SHARING |
|
mSessionFlag = 0; |
|
#endif |
|
} |
|
|
|
IntelMetadataBuffer::~IntelMetadataBuffer() |
|
{ |
|
if (mInfo) |
|
delete mInfo; |
|
|
|
if (mExtraValues) |
|
delete[] mExtraValues; |
|
|
|
if (mBytes) |
|
delete[] mBytes; |
|
} |
|
|
|
|
|
IntelMetadataBuffer::IntelMetadataBuffer(const IntelMetadataBuffer& imb) |
|
:mType(imb.mType), mValue(imb.mValue), mInfo(NULL), mExtraValues(NULL), |
|
mExtraValues_Count(imb.mExtraValues_Count), mBytes(NULL), mSize(imb.mSize) |
|
#ifdef INTEL_VIDEO_XPROC_SHARING |
|
,mSessionFlag(imb.mSessionFlag) |
|
#endif |
|
{ |
|
if (imb.mInfo) |
|
mInfo = new ValueInfo(*imb.mInfo); |
|
|
|
if (imb.mExtraValues) |
|
{ |
|
mExtraValues = new intptr_t[mExtraValues_Count]; |
|
memcpy(mExtraValues, imb.mExtraValues, sizeof(mValue) * mExtraValues_Count); |
|
} |
|
|
|
if (imb.mBytes) |
|
{ |
|
mBytes = new uint8_t[mSize]; |
|
memcpy(mBytes, imb.mBytes, mSize); |
|
} |
|
} |
|
|
|
const IntelMetadataBuffer& IntelMetadataBuffer::operator=(const IntelMetadataBuffer& imb) |
|
{ |
|
mType = imb.mType; |
|
mValue = imb.mValue; |
|
mInfo = NULL; |
|
mExtraValues = NULL; |
|
mExtraValues_Count = imb.mExtraValues_Count; |
|
mBytes = NULL; |
|
mSize = imb.mSize; |
|
#ifdef INTEL_VIDEO_XPROC_SHARING |
|
mSessionFlag = imb.mSessionFlag; |
|
#endif |
|
|
|
if (imb.mInfo) |
|
mInfo = new ValueInfo(*imb.mInfo); |
|
|
|
if (imb.mExtraValues) |
|
{ |
|
mExtraValues = new intptr_t[mExtraValues_Count]; |
|
memcpy(mExtraValues, imb.mExtraValues, sizeof(mValue) * mExtraValues_Count); |
|
} |
|
|
|
if (imb.mBytes) |
|
{ |
|
mBytes = new uint8_t[mSize]; |
|
memcpy(mBytes, imb.mBytes, mSize); |
|
} |
|
|
|
return *this; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::GetType(IntelMetadataBufferType& type) |
|
{ |
|
type = mType; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::SetType(IntelMetadataBufferType type) |
|
{ |
|
if (type < IntelMetadataBufferTypeLast) |
|
mType = type; |
|
else |
|
return IMB_INVAL_PARAM; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::GetValue(intptr_t& value) |
|
{ |
|
value = mValue; |
|
|
|
#ifndef INTEL_VIDEO_XPROC_SHARING |
|
return IMB_SUCCESS; |
|
#else |
|
if ((mSessionFlag & REMOTE_CONSUMER) == 0) //no sharing or is local consumer |
|
return IMB_SUCCESS; |
|
|
|
//try to find if it is already cached. |
|
ShareMemMap* smem = FindShareMem(mSessionFlag, mValue, true); |
|
if(smem) |
|
{ |
|
value = smem->value; |
|
return IMB_SUCCESS; |
|
} |
|
|
|
//is remote provider and not find from cache, then pull from service |
|
sp<IBinder> binder = GetIntelBufferSharingService(); |
|
if (binder == 0) |
|
return IMB_NO_SERVICE; |
|
|
|
//Detect IntelBufferSharingService, share mem to service |
|
Parcel data, reply; |
|
|
|
//send pid, sessionflag, and memtype |
|
pid_t pid = getpid(); |
|
//TODO: if pid is int32? |
|
data.writeInt32(pid); |
|
data.writeInt32(mSessionFlag); |
|
data.writeIntPtr(mValue); |
|
|
|
//do transcation |
|
if (binder->transact(GET_MEM, data, &reply) != NO_ERROR) |
|
return IMB_SERVICE_FAIL; |
|
|
|
//get type/Mem OBJ |
|
smem = ReadMemObjFromBinder(reply, mSessionFlag, mValue); |
|
if (smem) |
|
value = smem->value; |
|
else |
|
return IMB_SERVICE_FAIL; |
|
|
|
return IMB_SUCCESS; |
|
#endif |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::SetValue(intptr_t value) |
|
{ |
|
mValue = value; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::GetValueInfo(ValueInfo* &info) |
|
{ |
|
info = mInfo; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::SetValueInfo(ValueInfo* info) |
|
{ |
|
if (info) |
|
{ |
|
if (mInfo == NULL) |
|
mInfo = new ValueInfo; |
|
|
|
memcpy(mInfo, info, sizeof(ValueInfo)); |
|
} |
|
else |
|
return IMB_INVAL_PARAM; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::GetExtraValues(intptr_t* &values, uint32_t& num) |
|
{ |
|
values = mExtraValues; |
|
num = mExtraValues_Count; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::SetExtraValues(intptr_t* values, uint32_t num) |
|
{ |
|
if (values && num > 0) |
|
{ |
|
if (mExtraValues && mExtraValues_Count != num) |
|
{ |
|
delete[] mExtraValues; |
|
mExtraValues = NULL; |
|
} |
|
|
|
if (mExtraValues == NULL) |
|
mExtraValues = new intptr_t[num]; |
|
|
|
memcpy(mExtraValues, values, sizeof(intptr_t) * num); |
|
mExtraValues_Count = num; |
|
} |
|
else |
|
return IMB_INVAL_PARAM; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::UnSerialize(uint8_t* data, uint32_t size) |
|
{ |
|
if (!data || size == 0) |
|
return IMB_INVAL_PARAM; |
|
|
|
IntelMetadataBufferType type; |
|
intptr_t value; |
|
uint32_t extrasize = size - sizeof(type) - sizeof(value); |
|
ValueInfo* info = NULL; |
|
intptr_t* ExtraValues = NULL; |
|
uint32_t ExtraValues_Count = 0; |
|
|
|
memcpy(&type, data, sizeof(type)); |
|
data += sizeof(type); |
|
memcpy(&value, data, sizeof(value)); |
|
data += sizeof(value); |
|
|
|
switch (type) |
|
{ |
|
case IntelMetadataBufferTypeCameraSource: |
|
case IntelMetadataBufferTypeEncoder: |
|
case IntelMetadataBufferTypeUser: |
|
{ |
|
if (extrasize >0 && extrasize < sizeof(ValueInfo)) |
|
return IMB_INVAL_BUFFER; |
|
|
|
if (extrasize > sizeof(ValueInfo)) //has extravalues |
|
{ |
|
if ( (extrasize - sizeof(ValueInfo)) % sizeof(mValue) != 0 ) |
|
return IMB_INVAL_BUFFER; |
|
ExtraValues_Count = (extrasize - sizeof(ValueInfo)) / sizeof(mValue); |
|
} |
|
|
|
if (extrasize > 0) |
|
{ |
|
info = new ValueInfo; |
|
memcpy(info, data, sizeof(ValueInfo)); |
|
data += sizeof(ValueInfo); |
|
} |
|
|
|
if (ExtraValues_Count > 0) |
|
{ |
|
ExtraValues = new intptr_t[ExtraValues_Count]; |
|
memcpy(ExtraValues, data, ExtraValues_Count * sizeof(mValue)); |
|
} |
|
|
|
break; |
|
} |
|
case IntelMetadataBufferTypeGrallocSource: |
|
if (extrasize > 0) |
|
return IMB_INVAL_BUFFER; |
|
|
|
break; |
|
default: |
|
return IMB_INVAL_BUFFER; |
|
} |
|
|
|
//store data |
|
mType = type; |
|
mValue = value; |
|
if (mInfo) |
|
delete mInfo; |
|
mInfo = info; |
|
if (mExtraValues) |
|
delete[] mExtraValues; |
|
mExtraValues = ExtraValues; |
|
mExtraValues_Count = ExtraValues_Count; |
|
#ifdef INTEL_VIDEO_XPROC_SHARING |
|
if (mInfo != NULL) |
|
mSessionFlag = mInfo->sessionFlag; |
|
#endif |
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::Serialize(uint8_t* &data, uint32_t& size) |
|
{ |
|
if (mBytes == NULL) |
|
{ |
|
if (mType == IntelMetadataBufferTypeGrallocSource && mInfo) |
|
return IMB_INVAL_PARAM; |
|
|
|
//assemble bytes according members |
|
mSize = sizeof(mType) + sizeof(mValue); |
|
if (mInfo) |
|
{ |
|
mSize += sizeof(ValueInfo); |
|
if (mExtraValues) |
|
mSize += sizeof(mValue) * mExtraValues_Count; |
|
} |
|
|
|
mBytes = new uint8_t[mSize]; |
|
uint8_t *ptr = mBytes; |
|
memcpy(ptr, &mType, sizeof(mType)); |
|
ptr += sizeof(mType); |
|
memcpy(ptr, &mValue, sizeof(mValue)); |
|
ptr += sizeof(mValue); |
|
|
|
if (mInfo) |
|
{ |
|
#ifdef INTEL_VIDEO_XPROC_SHARING |
|
mInfo->sessionFlag = mSessionFlag; |
|
#endif |
|
memcpy(ptr, mInfo, sizeof(ValueInfo)); |
|
ptr += sizeof(ValueInfo); |
|
|
|
if (mExtraValues) |
|
memcpy(ptr, mExtraValues, mExtraValues_Count * sizeof(mValue)); |
|
} |
|
} |
|
|
|
data = mBytes; |
|
size = mSize; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
uint32_t IntelMetadataBuffer::GetMaxBufferSize() |
|
{ |
|
return 256; |
|
} |
|
|
|
#ifdef INTEL_VIDEO_XPROC_SHARING |
|
IMB_Result IntelMetadataBuffer::GetSessionFlag(uint32_t& sessionflag) |
|
{ |
|
sessionflag = mSessionFlag; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::SetSessionFlag(uint32_t sessionflag) |
|
{ |
|
mSessionFlag = sessionflag; |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::ShareValue(sp<MemoryBase> mem) |
|
{ |
|
mValue = (intptr_t)((intptr_t) ( mem->pointer() + 0x0FFF) & ~0x0FFF); |
|
|
|
if ( !(mSessionFlag & REMOTE_PROVIDER) && !(mSessionFlag & REMOTE_CONSUMER)) //no sharing |
|
return IMB_SUCCESS; |
|
|
|
if (mSessionFlag & REMOTE_PROVIDER) //is remote provider |
|
{ |
|
sp<IBinder> binder = GetIntelBufferSharingService(); |
|
if (binder == 0) |
|
return IMB_NO_SERVICE; |
|
|
|
//Detect IntelBufferSharingService, share mem to service |
|
Parcel data, reply; |
|
|
|
//send pid, sessionflag, and value |
|
pid_t pid = getpid(); |
|
//TODO: if pid is int32? |
|
data.writeInt32(pid); |
|
data.writeInt32(mSessionFlag); |
|
data.writeIntPtr(mValue); |
|
|
|
//send type/obj (offset/size/MemHeap) |
|
ShareMemMap smem; |
|
smem.membase = mem; |
|
smem.type = ST_MEMBASE; |
|
if (WriteMemObjToBinder(data, &smem) != NO_ERROR) |
|
return IMB_SERVICE_FAIL; |
|
|
|
//do transcation |
|
if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR) |
|
return IMB_SERVICE_FAIL; |
|
|
|
//set new value gotten from peer |
|
mValue = reply.readIntPtr(); |
|
// LOGI("ShareValue(membase) Get reply from sevice, new value:%x\n", mValue); |
|
} |
|
else //is local provider , direct access list |
|
{ |
|
ShareMemMap* smem = new ShareMemMap; |
|
smem->sessionflag = mSessionFlag; |
|
smem->value = mValue; |
|
smem->value_backup = mValue; |
|
smem->type = ST_MEMBASE; |
|
smem->membase = mem; |
|
smem->gbuffer = NULL; |
|
PushShareMem(smem); |
|
} |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::ShareValue(sp<GraphicBuffer> gbuffer) |
|
{ |
|
mValue = (intptr_t)gbuffer->handle; |
|
|
|
if ( !(mSessionFlag & REMOTE_PROVIDER) && !(mSessionFlag & REMOTE_CONSUMER)) //no sharing |
|
return IMB_SUCCESS; |
|
|
|
if (mSessionFlag & REMOTE_PROVIDER == 0) //is remote provider |
|
{ |
|
sp<IBinder> binder = GetIntelBufferSharingService(); |
|
if (binder == 0) |
|
return IMB_NO_SERVICE; |
|
|
|
Parcel data, reply; |
|
|
|
//send pid, sessionflag, and memtype |
|
pid_t pid = getpid(); |
|
//TODO: if pid is int32 ? |
|
data.writeInt32(pid); |
|
data.writeInt32(mSessionFlag); |
|
data.writeIntPtr(mValue); |
|
|
|
//send value/graphicbuffer obj |
|
ShareMemMap smem; |
|
smem.gbuffer = gbuffer; |
|
smem.type = ST_GFX; |
|
if (WriteMemObjToBinder(data, &smem) != NO_ERROR) |
|
return IMB_SERVICE_FAIL; |
|
|
|
//do transcation |
|
if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR) |
|
return IMB_SERVICE_FAIL; |
|
|
|
//set new value gotten from peer |
|
mValue = reply.readIntPtr(); |
|
// LOGI("ShareValue(gfx) Get reply from sevice, new value:%x\n", mValue); |
|
} |
|
else //is local provider, direct access list |
|
{ |
|
ShareMemMap* smem = new ShareMemMap; |
|
smem->sessionflag = mSessionFlag; |
|
smem->value = mValue; |
|
smem->value_backup = mValue; |
|
smem->type = ST_GFX; |
|
smem->membase = NULL; |
|
smem->gbuffer = gbuffer; |
|
PushShareMem(smem); |
|
} |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
IMB_Result IntelMetadataBuffer::ClearContext(uint32_t sessionflag, bool isProvider) |
|
{ |
|
if ( !(sessionflag & REMOTE_PROVIDER) && !(sessionflag & REMOTE_CONSUMER)) //no sharing |
|
return IMB_SUCCESS; |
|
|
|
//clear local firstly |
|
ClearLocalMem(sessionflag); |
|
|
|
//clear mem on service if it is remote user |
|
if ((isProvider && (sessionflag & REMOTE_PROVIDER)) || (!isProvider && (sessionflag & REMOTE_CONSUMER))) |
|
{ |
|
// LOGI("CLEAR_MEM sessionflag=%x", sessionflag); |
|
|
|
sp<IBinder> binder = GetIntelBufferSharingService(); |
|
if (binder == 0) |
|
return IMB_NO_SERVICE; |
|
|
|
//Detect IntelBufferSharingService, unshare mem from service |
|
Parcel data, reply; |
|
|
|
//send pid and sessionflag |
|
pid_t pid = getpid(); |
|
//TODO: if pid is int32? |
|
data.writeInt32(pid); |
|
data.writeInt32(sessionflag); |
|
|
|
if (binder->transact(CLEAR_MEM, data, &reply) != NO_ERROR) |
|
return IMB_SERVICE_FAIL; |
|
} |
|
|
|
return IMB_SUCCESS; |
|
} |
|
|
|
uint32_t IntelMetadataBuffer::MakeSessionFlag(bool romoteProvider, bool remoteConsumer, uint16_t sindex) |
|
{ |
|
uint32_t sessionflag = 0; |
|
|
|
if (romoteProvider) |
|
sessionflag |= REMOTE_PROVIDER; |
|
|
|
if (remoteConsumer) |
|
sessionflag |= REMOTE_CONSUMER; |
|
|
|
return sessionflag + sindex; |
|
} |
|
#endif
|
|
|