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 
ReadMemObjFromBinder(const Parcel & data,uint32_t sessionflag,intptr_t value)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 
WriteMemObjToBinder(Parcel & data,ShareMemMap * smem)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 
ClearLocalMem(uint32_t sessionflag)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 
FindShareMem(uint32_t sessionflag,intptr_t value,bool isBackup)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 
PopShareMem(uint32_t sessionflag,intptr_t value)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 
PushShareMem(ShareMemMap * & smem)222 static void PushShareMem(ShareMemMap* &smem)
223 {
224     gShareMemMapListLock.lock();
225     gShareMemMapList.push_back(smem);
226     gShareMemMapListLock.unlock();
227 }
228 
GetIntelBufferSharingService()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 
instantiate()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 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)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 
IntelMetadataBuffer()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 
IntelMetadataBuffer(IntelMetadataBufferType type,intptr_t value)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 
~IntelMetadataBuffer()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 
IntelMetadataBuffer(const IntelMetadataBuffer & imb)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 
operator =(const IntelMetadataBuffer & imb)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 
GetType(IntelMetadataBufferType & type)422 IMB_Result IntelMetadataBuffer::GetType(IntelMetadataBufferType& type)
423 {
424     type = mType;
425 
426     return IMB_SUCCESS;
427 }
428 
SetType(IntelMetadataBufferType type)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 
GetValue(intptr_t & value)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 
SetValue(intptr_t value)487 IMB_Result IntelMetadataBuffer::SetValue(intptr_t value)
488 {
489     mValue = value;
490 
491     return IMB_SUCCESS;
492 }
493 
GetValueInfo(ValueInfo * & info)494 IMB_Result IntelMetadataBuffer::GetValueInfo(ValueInfo* &info)
495 {
496     info = mInfo;
497 
498     return IMB_SUCCESS;
499 }
500 
SetValueInfo(ValueInfo * info)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 
GetExtraValues(intptr_t * & values,uint32_t & num)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 
SetExtraValues(intptr_t * values,uint32_t num)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 
UnSerialize(uint8_t * data,uint32_t size)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 
Serialize(uint8_t * & data,uint32_t & size)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 
GetMaxBufferSize()662 uint32_t IntelMetadataBuffer::GetMaxBufferSize()
663 {
664     return 256;
665 }
666 
667 #ifdef INTEL_VIDEO_XPROC_SHARING
GetSessionFlag(uint32_t & sessionflag)668 IMB_Result IntelMetadataBuffer::GetSessionFlag(uint32_t& sessionflag)
669 {
670     sessionflag = mSessionFlag;
671 
672     return IMB_SUCCESS;
673 }
674 
SetSessionFlag(uint32_t sessionflag)675 IMB_Result IntelMetadataBuffer::SetSessionFlag(uint32_t sessionflag)
676 {
677     mSessionFlag = sessionflag;
678 
679     return IMB_SUCCESS;
680 }
681 
ShareValue(sp<MemoryBase> mem)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 
ShareValue(sp<GraphicBuffer> gbuffer)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 
ClearContext(uint32_t sessionflag,bool isProvider)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 
MakeSessionFlag(bool romoteProvider,bool remoteConsumer,uint16_t sindex)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