Home | History | Annotate | Download | only in videoencoder
      1 /*
      2 * Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "IntelMetadataBuffer"
     19 #include <wrs_omxil_core/log.h>
     20 
     21 #include "IntelMetadataBuffer.h"
     22 #include <string.h>
     23 #include <stdio.h>
     24 
     25 #ifdef INTEL_VIDEO_XPROC_SHARING
     26 #include <binder/IServiceManager.h>
     27 #include <binder/MemoryBase.h>
     28 #include <binder/Parcel.h>
     29 #include <utils/List.h>
     30 #include <utils/threads.h>
     31 #include <ui/GraphicBuffer.h>
     32 
     33 //#define TEST
     34 
     35 struct ShareMemMap {
     36     uint32_t sessionflag;
     37     intptr_t value;
     38     intptr_t value_backup;
     39     uint32_t type;
     40     sp<MemoryBase> membase;
     41     sp<GraphicBuffer> gbuffer;
     42 };
     43 
     44 List <ShareMemMap *> gShareMemMapList;
     45 Mutex gShareMemMapListLock;
     46 
     47 enum {
     48     SHARE_MEM = IBinder::FIRST_CALL_TRANSACTION,
     49     GET_MEM,
     50     CLEAR_MEM,
     51 };
     52 
     53 enum {
     54     ST_MEMBASE = 0,
     55     ST_GFX,
     56     ST_MAX,
     57 };
     58 
     59 #define REMOTE_PROVIDER 0x80000000
     60 #define REMOTE_CONSUMER 0x40000000
     61 
     62 static ShareMemMap* ReadMemObjFromBinder(const Parcel& data, uint32_t sessionflag, intptr_t value) {
     63 
     64     uint32_t type = data.readInt32();
     65     if (type >= ST_MAX)
     66         return NULL;
     67 
     68     ShareMemMap* map = new ShareMemMap;
     69     map->sessionflag = sessionflag;
     70     map->type = type;
     71     map->value_backup = value;
     72     map->membase = NULL;
     73     map->gbuffer= NULL;
     74 
     75 //    LOGI("ReadMemObjFromBinder");
     76 
     77     if (type == ST_MEMBASE) /*offset, size, heap*/
     78     {
     79         ssize_t offset = data.readInt32();
     80         size_t size = data.readInt32();
     81 
     82         sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
     83 
     84         sp<MemoryBase> mem = new MemoryBase(heap, offset, size);
     85         if (mem == NULL)
     86         {
     87             delete map;
     88             return NULL;
     89         }
     90 
     91         map->value = (intptr_t)( mem->pointer() + 0x0FFF) & ~0x0FFF;
     92         map->membase = mem;
     93 
     94 #ifdef TEST
     95         ALOGI("membase heapID:%d, pointer:%x data:%x, aligned value:%x", \
     96            heap->getHeapID(), mem->pointer(), *((intptr_t *)(mem->pointer())), map->value);
     97 #endif
     98 
     99     }
    100     else if (type == ST_GFX) /*graphicbuffer*/
    101     {
    102         sp<GraphicBuffer> buffer = new GraphicBuffer();
    103         if (buffer == NULL)
    104         {
    105             delete map;
    106             return NULL;
    107         }
    108         data.read(*buffer);
    109 
    110         map->value = (intptr_t)buffer->handle;
    111         map->gbuffer = buffer;
    112 
    113 #ifdef TEST
    114         void* usrptr[3];
    115         buffer->lock(GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_SW_READ_OFTEN, &usrptr[0]);
    116         buffer->unlock();
    117         ALOGI("gfx handle:%p data:%x", (intptr_t)buffer->handle, *((intptr_t *)usrptr[0]));
    118 #endif
    119     }
    120 
    121     gShareMemMapListLock.lock();
    122     gShareMemMapList.push_back(map);
    123     gShareMemMapListLock.unlock();
    124     return map;
    125 }
    126 
    127 static status_t WriteMemObjToBinder(Parcel& data, ShareMemMap* smem) {
    128 
    129     if (smem->type >= ST_MAX)
    130         return BAD_VALUE;
    131 
    132 //    LOGI("WriteMemObjToBinder");
    133 
    134     data.writeInt32(smem->type);
    135 
    136     if (smem->type == ST_MEMBASE) /*offset, size, heap*/
    137     {
    138         ssize_t offset;
    139         size_t size;
    140         sp<IMemoryHeap> heap = smem->membase->getMemory(&offset, &size);
    141         data.writeInt32(offset);
    142         data.writeInt32(size);
    143         data.writeStrongBinder(IInterface::asBinder(heap));
    144 #ifdef TEST
    145         ALOGI("membase heapID:%d pointer:%x data:%x", \
    146             heap->getHeapID(), smem->membase->pointer(), *((int *)(smem->membase->pointer())));
    147 #endif
    148     }
    149     else if (smem->type == ST_GFX) /*graphicbuffer*/
    150         data.write(*(smem->gbuffer));
    151 
    152     return NO_ERROR;
    153 }
    154 
    155 static void ClearLocalMem(uint32_t sessionflag)
    156 {
    157     List<ShareMemMap *>::iterator node;
    158 
    159     gShareMemMapListLock.lock();
    160 
    161     for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); )
    162     {
    163         if ((*node)->sessionflag == sessionflag) //remove all buffers belong to this session
    164         {
    165             (*node)->membase = NULL;
    166             (*node)->gbuffer = NULL;
    167             delete (*node);
    168             node = gShareMemMapList.erase(node);
    169         }
    170         else
    171             node ++;
    172     }
    173 
    174     gShareMemMapListLock.unlock();
    175 }
    176 
    177 static ShareMemMap* FindShareMem(uint32_t sessionflag, intptr_t value, bool isBackup)
    178 {
    179     List<ShareMemMap *>::iterator node;
    180 
    181     gShareMemMapListLock.lock();
    182     for(node = gShareMemMapList.begin(); node !=  gShareMemMapList.end(); node++)
    183     {
    184         if (isBackup)
    185         {
    186             if ((*node)->sessionflag == sessionflag && (*node)->value_backup == value)
    187             {
    188                 gShareMemMapListLock.unlock();
    189                 return (*node);
    190             }
    191         }
    192         else if ((*node)->sessionflag == sessionflag && (*node)->value == value)
    193         {
    194             gShareMemMapListLock.unlock();
    195             return (*node);
    196         }
    197     }
    198     gShareMemMapListLock.unlock();
    199 
    200     return NULL;
    201 }
    202 
    203 static ShareMemMap* PopShareMem(uint32_t sessionflag, intptr_t value)
    204 {
    205     List<ShareMemMap *>::iterator node;
    206 
    207     gShareMemMapListLock.lock();
    208     for(node = gShareMemMapList.begin(); node != gShareMemMapList.end(); node++)
    209     {
    210         if ((*node)->sessionflag == sessionflag && (*node)->value == value)
    211         {
    212             gShareMemMapList.erase(node);
    213             gShareMemMapListLock.unlock();
    214             return (*node);
    215         }
    216     }
    217     gShareMemMapListLock.unlock();
    218 
    219     return NULL;
    220 }
    221 
    222 static void PushShareMem(ShareMemMap* &smem)
    223 {
    224     gShareMemMapListLock.lock();
    225     gShareMemMapList.push_back(smem);
    226     gShareMemMapListLock.unlock();
    227 }
    228 
    229 static sp<IBinder> GetIntelBufferSharingService() {
    230 
    231     sp<IServiceManager> sm = defaultServiceManager();
    232     sp<IBinder> binder = sm->checkService(String16("media.IntelBufferSharing"));
    233 
    234     if (binder == 0)
    235         ALOGE("media.IntelBufferSharing service is not published");
    236 
    237     return binder;
    238 }
    239 
    240 IntelBufferSharingService* IntelBufferSharingService::gBufferService = NULL;
    241 
    242 status_t IntelBufferSharingService::instantiate(){
    243     status_t ret = NO_ERROR;
    244 
    245     if (gBufferService == NULL) {
    246         gBufferService = new IntelBufferSharingService();
    247         ret = defaultServiceManager()->addService(String16("media.IntelBufferSharing"), gBufferService);
    248         LOGI("IntelBufferSharingService::instantiate() ret = %d\n", ret);
    249     }
    250 
    251     return ret;
    252 }
    253 
    254 status_t IntelBufferSharingService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
    255 
    256     //TODO: if pid is int32?
    257     pid_t pid = data.readInt32();
    258     uint32_t sessionflag = data.readInt32();
    259 
    260     switch(code)
    261     {
    262         case SHARE_MEM:
    263         {
    264 
    265             if (pid == getpid()) //in same process, should not use binder
    266             {
    267                 ALOGE("onTransact in same process, wrong sessionflag?");
    268                 return UNKNOWN_ERROR;
    269             }
    270 
    271             intptr_t value = data.readIntPtr();
    272 
    273 //            LOGI("onTransact SHARE_MEM value=%x", value);
    274 
    275             //different process
    276             ShareMemMap* map = ReadMemObjFromBinder(data, sessionflag, value);
    277             if (map == NULL)
    278                 return UNKNOWN_ERROR;
    279 
    280             reply->writeIntPtr(map->value);
    281 
    282             return NO_ERROR;
    283         }
    284         case CLEAR_MEM:
    285         {
    286 //            LOGI("onTransact CLEAR_MEM sessionflag=%x", sessionflag);
    287 
    288             if (pid == getpid()) //in same process, should not use binder
    289             {
    290                 //same process, return same pointer in data
    291                 ALOGE("onTransact CLEAR_MEM in same process, wrong sessionflag?");
    292                 return UNKNOWN_ERROR;
    293             }
    294 
    295             ClearLocalMem(sessionflag);
    296             return NO_ERROR;
    297         }
    298         case GET_MEM:
    299         {
    300 
    301             if (pid == getpid()) //in same process, should not use binder
    302             {
    303                 ALOGE("onTransact GET_MEM in same process, wrong sessionflag?");
    304                 return UNKNOWN_ERROR;
    305             }
    306 
    307             intptr_t value = data.readIntPtr();
    308 
    309 //            LOGI("onTransact GET_MEM value=%x", value);
    310 
    311             ShareMemMap* smem = FindShareMem(sessionflag, value, false);
    312             if (smem && (NO_ERROR == WriteMemObjToBinder(*reply, smem)))
    313                 return NO_ERROR;
    314             else
    315                 ALOGE("onTransact GET_MEM: Not find mem");
    316 
    317             return UNKNOWN_ERROR;
    318         }
    319         default:
    320             return BBinder::onTransact(code, data, reply, flags);
    321 
    322     }
    323     return NO_ERROR;
    324 }
    325 #endif
    326 
    327 IntelMetadataBuffer::IntelMetadataBuffer()
    328 {
    329     mType = IntelMetadataBufferTypeCameraSource;
    330     mValue = 0;
    331     mInfo = NULL;
    332     mExtraValues = NULL;
    333     mExtraValues_Count = 0;
    334     mBytes = NULL;
    335     mSize = 0;
    336 #ifdef INTEL_VIDEO_XPROC_SHARING
    337     mSessionFlag = 0;
    338 #endif
    339 }
    340 
    341 IntelMetadataBuffer::IntelMetadataBuffer(IntelMetadataBufferType type, intptr_t value)
    342 {
    343     mType = type;
    344     mValue = value;
    345     mInfo = NULL;
    346     mExtraValues = NULL;
    347     mExtraValues_Count = 0;
    348     mBytes = NULL;
    349     mSize = 0;
    350 #ifdef INTEL_VIDEO_XPROC_SHARING
    351     mSessionFlag = 0;
    352 #endif
    353 }
    354 
    355 IntelMetadataBuffer::~IntelMetadataBuffer()
    356 {
    357     if (mInfo)
    358         delete mInfo;
    359 
    360     if (mExtraValues)
    361         delete[] mExtraValues;
    362 
    363     if (mBytes)
    364         delete[] mBytes;
    365 }
    366 
    367 
    368 IntelMetadataBuffer::IntelMetadataBuffer(const IntelMetadataBuffer& imb)
    369      :mType(imb.mType), mValue(imb.mValue), mInfo(NULL), mExtraValues(NULL),
    370       mExtraValues_Count(imb.mExtraValues_Count), mBytes(NULL), mSize(imb.mSize)
    371 #ifdef INTEL_VIDEO_XPROC_SHARING
    372       ,mSessionFlag(imb.mSessionFlag)
    373 #endif
    374 {
    375     if (imb.mInfo)
    376         mInfo = new ValueInfo(*imb.mInfo);
    377 
    378     if (imb.mExtraValues)
    379     {
    380         mExtraValues = new intptr_t[mExtraValues_Count];
    381         memcpy(mExtraValues, imb.mExtraValues, sizeof(mValue) * mExtraValues_Count);
    382     }
    383 
    384     if (imb.mBytes)
    385     {
    386         mBytes = new uint8_t[mSize];
    387         memcpy(mBytes, imb.mBytes, mSize);
    388     }
    389 }
    390 
    391 const IntelMetadataBuffer& IntelMetadataBuffer::operator=(const IntelMetadataBuffer& imb)
    392 {
    393     mType = imb.mType;
    394     mValue = imb.mValue;
    395     mInfo = NULL;
    396     mExtraValues = NULL;
    397     mExtraValues_Count = imb.mExtraValues_Count;
    398     mBytes = NULL;
    399     mSize = imb.mSize;
    400 #ifdef INTEL_VIDEO_XPROC_SHARING
    401     mSessionFlag = imb.mSessionFlag;
    402 #endif
    403 
    404     if (imb.mInfo)
    405         mInfo = new ValueInfo(*imb.mInfo);
    406 
    407     if (imb.mExtraValues)
    408     {
    409         mExtraValues = new intptr_t[mExtraValues_Count];
    410         memcpy(mExtraValues, imb.mExtraValues, sizeof(mValue) * mExtraValues_Count);
    411     }
    412 
    413     if (imb.mBytes)
    414     {
    415         mBytes = new uint8_t[mSize];
    416         memcpy(mBytes, imb.mBytes, mSize);
    417     }
    418 
    419     return *this;
    420 }
    421 
    422 IMB_Result IntelMetadataBuffer::GetType(IntelMetadataBufferType& type)
    423 {
    424     type = mType;
    425 
    426     return IMB_SUCCESS;
    427 }
    428 
    429 IMB_Result IntelMetadataBuffer::SetType(IntelMetadataBufferType type)
    430 {
    431     if (type < IntelMetadataBufferTypeLast)
    432         mType = type;
    433     else
    434         return IMB_INVAL_PARAM;
    435 
    436     return IMB_SUCCESS;
    437 }
    438 
    439 IMB_Result IntelMetadataBuffer::GetValue(intptr_t& value)
    440 {
    441     value = mValue;
    442 
    443 #ifndef INTEL_VIDEO_XPROC_SHARING
    444     return IMB_SUCCESS;
    445 #else
    446     if ((mSessionFlag & REMOTE_CONSUMER) == 0) //no sharing or is local consumer
    447         return IMB_SUCCESS;
    448 
    449     //try to find if it is already cached.
    450     ShareMemMap* smem = FindShareMem(mSessionFlag, mValue, true);
    451     if(smem)
    452     {
    453         value = smem->value;
    454         return IMB_SUCCESS;
    455     }
    456 
    457     //is remote provider and not find from cache, then pull from service
    458     sp<IBinder> binder = GetIntelBufferSharingService();
    459     if (binder == 0)
    460         return IMB_NO_SERVICE;
    461 
    462     //Detect IntelBufferSharingService, share mem to service
    463     Parcel data, reply;
    464 
    465     //send pid, sessionflag, and memtype
    466     pid_t pid = getpid();
    467     //TODO: if pid is int32?
    468     data.writeInt32(pid);
    469     data.writeInt32(mSessionFlag);
    470     data.writeIntPtr(mValue);
    471 
    472     //do transcation
    473     if (binder->transact(GET_MEM, data, &reply) != NO_ERROR)
    474         return IMB_SERVICE_FAIL;
    475 
    476     //get type/Mem OBJ
    477     smem = ReadMemObjFromBinder(reply, mSessionFlag, mValue);
    478     if (smem)
    479         value = smem->value;
    480     else
    481         return IMB_SERVICE_FAIL;
    482 
    483     return IMB_SUCCESS;
    484 #endif
    485 }
    486 
    487 IMB_Result IntelMetadataBuffer::SetValue(intptr_t value)
    488 {
    489     mValue = value;
    490 
    491     return IMB_SUCCESS;
    492 }
    493 
    494 IMB_Result IntelMetadataBuffer::GetValueInfo(ValueInfo* &info)
    495 {
    496     info = mInfo;
    497 
    498     return IMB_SUCCESS;
    499 }
    500 
    501 IMB_Result IntelMetadataBuffer::SetValueInfo(ValueInfo* info)
    502 {
    503     if (info)
    504     {
    505         if (mInfo == NULL)
    506             mInfo = new ValueInfo;
    507 
    508         memcpy(mInfo, info, sizeof(ValueInfo));
    509     }
    510     else
    511         return IMB_INVAL_PARAM;
    512 
    513     return IMB_SUCCESS;
    514 }
    515 
    516 IMB_Result IntelMetadataBuffer::GetExtraValues(intptr_t* &values, uint32_t& num)
    517 {
    518     values = mExtraValues;
    519     num = mExtraValues_Count;
    520 
    521     return IMB_SUCCESS;
    522 }
    523 
    524 IMB_Result IntelMetadataBuffer::SetExtraValues(intptr_t* values, uint32_t num)
    525 {
    526     if (values && num > 0)
    527     {
    528         if (mExtraValues && mExtraValues_Count != num)
    529         {
    530             delete[] mExtraValues;
    531             mExtraValues = NULL;
    532         }
    533 
    534         if (mExtraValues == NULL)
    535             mExtraValues = new intptr_t[num];
    536 
    537         memcpy(mExtraValues, values, sizeof(intptr_t) * num);
    538         mExtraValues_Count = num;
    539     }
    540     else
    541         return IMB_INVAL_PARAM;
    542 
    543     return IMB_SUCCESS;
    544 }
    545 
    546 IMB_Result IntelMetadataBuffer::UnSerialize(uint8_t* data, uint32_t size)
    547 {
    548     if (!data || size == 0)
    549         return IMB_INVAL_PARAM;
    550 
    551     IntelMetadataBufferType type;
    552     intptr_t value;
    553     uint32_t extrasize = size - sizeof(type) - sizeof(value);
    554     ValueInfo* info = NULL;
    555     intptr_t* ExtraValues = NULL;
    556     uint32_t ExtraValues_Count = 0;
    557 
    558     memcpy(&type, data, sizeof(type));
    559     data += sizeof(type);
    560     memcpy(&value, data, sizeof(value));
    561     data += sizeof(value);
    562 
    563     switch (type)
    564     {
    565         case IntelMetadataBufferTypeCameraSource:
    566         case IntelMetadataBufferTypeEncoder:
    567         case IntelMetadataBufferTypeUser:
    568         {
    569             if (extrasize >0 && extrasize < sizeof(ValueInfo))
    570                 return IMB_INVAL_BUFFER;
    571 
    572             if (extrasize > sizeof(ValueInfo)) //has extravalues
    573             {
    574                 if ( (extrasize - sizeof(ValueInfo)) % sizeof(mValue) != 0 )
    575                     return IMB_INVAL_BUFFER;
    576                 ExtraValues_Count = (extrasize - sizeof(ValueInfo)) / sizeof(mValue);
    577             }
    578 
    579             if (extrasize > 0)
    580             {
    581                 info = new ValueInfo;
    582                 memcpy(info, data, sizeof(ValueInfo));
    583                 data += sizeof(ValueInfo);
    584             }
    585 
    586             if (ExtraValues_Count > 0)
    587             {
    588                 ExtraValues = new intptr_t[ExtraValues_Count];
    589                 memcpy(ExtraValues, data, ExtraValues_Count * sizeof(mValue));
    590             }
    591 
    592             break;
    593         }
    594         case IntelMetadataBufferTypeGrallocSource:
    595             if (extrasize > 0)
    596                 return IMB_INVAL_BUFFER;
    597 
    598             break;
    599         default:
    600             return IMB_INVAL_BUFFER;
    601     }
    602 
    603     //store data
    604     mType = type;
    605     mValue = value;
    606     if (mInfo)
    607         delete mInfo;
    608     mInfo = info;
    609     if (mExtraValues)
    610         delete[] mExtraValues;
    611     mExtraValues = ExtraValues;
    612     mExtraValues_Count = ExtraValues_Count;
    613 #ifdef INTEL_VIDEO_XPROC_SHARING
    614     if (mInfo != NULL)
    615         mSessionFlag = mInfo->sessionFlag;
    616 #endif
    617     return IMB_SUCCESS;
    618 }
    619 
    620 IMB_Result IntelMetadataBuffer::Serialize(uint8_t* &data, uint32_t& size)
    621 {
    622     if (mBytes == NULL)
    623     {
    624         if (mType == IntelMetadataBufferTypeGrallocSource && mInfo)
    625             return IMB_INVAL_PARAM;
    626 
    627         //assemble bytes according members
    628         mSize = sizeof(mType) + sizeof(mValue);
    629         if (mInfo)
    630         {
    631             mSize += sizeof(ValueInfo);
    632             if (mExtraValues)
    633                 mSize += sizeof(mValue) * mExtraValues_Count;
    634         }
    635 
    636         mBytes = new uint8_t[mSize];
    637         uint8_t *ptr = mBytes;
    638         memcpy(ptr, &mType, sizeof(mType));
    639         ptr += sizeof(mType);
    640         memcpy(ptr, &mValue, sizeof(mValue));
    641         ptr += sizeof(mValue);
    642 
    643         if (mInfo)
    644         {
    645         #ifdef INTEL_VIDEO_XPROC_SHARING
    646             mInfo->sessionFlag = mSessionFlag;
    647         #endif
    648             memcpy(ptr, mInfo, sizeof(ValueInfo));
    649             ptr += sizeof(ValueInfo);
    650 
    651             if (mExtraValues)
    652                 memcpy(ptr, mExtraValues, mExtraValues_Count * sizeof(mValue));
    653         }
    654     }
    655 
    656     data = mBytes;
    657     size = mSize;
    658 
    659     return IMB_SUCCESS;
    660 }
    661 
    662 uint32_t IntelMetadataBuffer::GetMaxBufferSize()
    663 {
    664     return 256;
    665 }
    666 
    667 #ifdef INTEL_VIDEO_XPROC_SHARING
    668 IMB_Result IntelMetadataBuffer::GetSessionFlag(uint32_t& sessionflag)
    669 {
    670     sessionflag = mSessionFlag;
    671 
    672     return IMB_SUCCESS;
    673 }
    674 
    675 IMB_Result IntelMetadataBuffer::SetSessionFlag(uint32_t sessionflag)
    676 {
    677     mSessionFlag = sessionflag;
    678 
    679     return IMB_SUCCESS;
    680 }
    681 
    682 IMB_Result IntelMetadataBuffer::ShareValue(sp<MemoryBase> mem)
    683 {
    684     mValue = (intptr_t)((intptr_t) ( mem->pointer() + 0x0FFF) & ~0x0FFF);
    685 
    686     if ( !(mSessionFlag & REMOTE_PROVIDER) && !(mSessionFlag & REMOTE_CONSUMER)) //no sharing
    687         return IMB_SUCCESS;
    688 
    689     if (mSessionFlag & REMOTE_PROVIDER) //is remote provider
    690     {
    691         sp<IBinder> binder = GetIntelBufferSharingService();
    692         if (binder == 0)
    693             return IMB_NO_SERVICE;
    694 
    695         //Detect IntelBufferSharingService, share mem to service
    696         Parcel data, reply;
    697 
    698         //send pid, sessionflag, and value
    699         pid_t pid = getpid();
    700         //TODO: if pid is int32?
    701         data.writeInt32(pid);
    702         data.writeInt32(mSessionFlag);
    703         data.writeIntPtr(mValue);
    704 
    705         //send type/obj (offset/size/MemHeap)
    706         ShareMemMap smem;
    707         smem.membase = mem;
    708         smem.type = ST_MEMBASE;
    709         if (WriteMemObjToBinder(data, &smem) != NO_ERROR)
    710             return IMB_SERVICE_FAIL;
    711 
    712         //do transcation
    713         if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR)
    714             return IMB_SERVICE_FAIL;
    715 
    716         //set new value gotten from peer
    717         mValue = reply.readIntPtr();
    718 //        LOGI("ShareValue(membase) Get reply from sevice, new value:%x\n", mValue);
    719     }
    720     else  //is local provider , direct access list
    721     {
    722         ShareMemMap* smem = new ShareMemMap;
    723         smem->sessionflag = mSessionFlag;
    724         smem->value = mValue;
    725         smem->value_backup = mValue;
    726         smem->type = ST_MEMBASE;
    727         smem->membase = mem;
    728         smem->gbuffer = NULL;
    729         PushShareMem(smem);
    730     }
    731 
    732     return IMB_SUCCESS;
    733 }
    734 
    735 IMB_Result IntelMetadataBuffer::ShareValue(sp<GraphicBuffer> gbuffer)
    736 {
    737     mValue = (intptr_t)gbuffer->handle;
    738 
    739     if ( !(mSessionFlag & REMOTE_PROVIDER) && !(mSessionFlag & REMOTE_CONSUMER)) //no sharing
    740         return IMB_SUCCESS;
    741 
    742     if (mSessionFlag & REMOTE_PROVIDER == 0) //is remote provider
    743     {
    744         sp<IBinder> binder = GetIntelBufferSharingService();
    745         if (binder == 0)
    746             return IMB_NO_SERVICE;
    747 
    748         Parcel data, reply;
    749 
    750         //send pid, sessionflag, and memtype
    751         pid_t pid = getpid();
    752         //TODO: if pid is int32 ?
    753         data.writeInt32(pid);
    754         data.writeInt32(mSessionFlag);
    755         data.writeIntPtr(mValue);
    756 
    757         //send value/graphicbuffer obj
    758         ShareMemMap smem;
    759         smem.gbuffer = gbuffer;
    760         smem.type = ST_GFX;
    761         if (WriteMemObjToBinder(data, &smem) != NO_ERROR)
    762             return IMB_SERVICE_FAIL;
    763 
    764         //do transcation
    765         if (binder->transact(SHARE_MEM, data, &reply) != NO_ERROR)
    766             return IMB_SERVICE_FAIL;
    767 
    768         //set new value gotten from peer
    769         mValue = reply.readIntPtr();
    770 //        LOGI("ShareValue(gfx) Get reply from sevice, new value:%x\n", mValue);
    771     }
    772     else //is local provider, direct access list
    773     {
    774         ShareMemMap* smem = new ShareMemMap;
    775         smem->sessionflag = mSessionFlag;
    776         smem->value = mValue;
    777         smem->value_backup = mValue;
    778         smem->type = ST_GFX;
    779         smem->membase = NULL;
    780         smem->gbuffer = gbuffer;
    781         PushShareMem(smem);
    782     }
    783 
    784     return IMB_SUCCESS;
    785 }
    786 
    787 IMB_Result IntelMetadataBuffer::ClearContext(uint32_t sessionflag, bool isProvider)
    788 {
    789     if ( !(sessionflag & REMOTE_PROVIDER) && !(sessionflag & REMOTE_CONSUMER)) //no sharing
    790         return IMB_SUCCESS;
    791 
    792     //clear local firstly
    793     ClearLocalMem(sessionflag);
    794 
    795     //clear mem on service if it is remote user
    796     if ((isProvider && (sessionflag & REMOTE_PROVIDER)) || (!isProvider && (sessionflag & REMOTE_CONSUMER)))
    797     {
    798 //        LOGI("CLEAR_MEM sessionflag=%x", sessionflag);
    799 
    800         sp<IBinder> binder = GetIntelBufferSharingService();
    801         if (binder == 0)
    802             return IMB_NO_SERVICE;
    803 
    804         //Detect IntelBufferSharingService, unshare mem from service
    805         Parcel data, reply;
    806 
    807         //send pid and sessionflag
    808         pid_t pid = getpid();
    809         //TODO: if pid is int32?
    810         data.writeInt32(pid);
    811         data.writeInt32(sessionflag);
    812 
    813         if (binder->transact(CLEAR_MEM, data, &reply) != NO_ERROR)
    814             return IMB_SERVICE_FAIL;
    815     }
    816 
    817     return IMB_SUCCESS;
    818 }
    819 
    820 uint32_t IntelMetadataBuffer::MakeSessionFlag(bool romoteProvider, bool remoteConsumer, uint16_t sindex)
    821 {
    822     uint32_t sessionflag = 0;
    823 
    824     if (romoteProvider)
    825         sessionflag |= REMOTE_PROVIDER;
    826 
    827     if (remoteConsumer)
    828         sessionflag |= REMOTE_CONSUMER;
    829 
    830     return sessionflag + sindex;
    831 }
    832 #endif
    833