Home | History | Annotate | Download | only in gui
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      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 // tag as surfaceflinger
     18 #define LOG_TAG "SurfaceFlinger"
     19 
     20 #include <stdint.h>
     21 #include <sys/types.h>
     22 
     23 #include <binder/Parcel.h>
     24 
     25 #include <ui/GraphicBuffer.h>
     26 
     27 #include <gui/IGraphicBufferAlloc.h>
     28 
     29 // ---------------------------------------------------------------------------
     30 
     31 namespace android {
     32 
     33 enum {
     34     CREATE_GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
     35 };
     36 
     37 class BpGraphicBufferAlloc : public BpInterface<IGraphicBufferAlloc>
     38 {
     39 public:
     40     BpGraphicBufferAlloc(const sp<IBinder>& impl)
     41         : BpInterface<IGraphicBufferAlloc>(impl)
     42     {
     43     }
     44 
     45     virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
     46             PixelFormat format, uint32_t usage, status_t* error) {
     47         Parcel data, reply;
     48         data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
     49         data.writeInt32(w);
     50         data.writeInt32(h);
     51         data.writeInt32(format);
     52         data.writeInt32(usage);
     53         remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply);
     54         sp<GraphicBuffer> graphicBuffer;
     55         status_t result = reply.readInt32();
     56         if (result == NO_ERROR) {
     57             graphicBuffer = new GraphicBuffer();
     58             result = reply.read(*graphicBuffer);
     59             // reply.readStrongBinder();
     60             // here we don't even have to read the BufferReference from
     61             // the parcel, it'll die with the parcel.
     62         }
     63         *error = result;
     64         return graphicBuffer;
     65     }
     66 };
     67 
     68 IMPLEMENT_META_INTERFACE(GraphicBufferAlloc, "android.ui.IGraphicBufferAlloc");
     69 
     70 // ----------------------------------------------------------------------
     71 
     72 status_t BnGraphicBufferAlloc::onTransact(
     73     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
     74 {
     75     // codes that don't require permission check
     76 
     77     /* BufferReference just keeps a strong reference to a
     78      * GraphicBuffer until it is destroyed (that is, until
     79      * no local or remote process have a reference to it).
     80      */
     81     class BufferReference : public BBinder {
     82         sp<GraphicBuffer> buffer;
     83     public:
     84         BufferReference(const sp<GraphicBuffer>& buffer) : buffer(buffer) { }
     85     };
     86 
     87 
     88     switch(code) {
     89         case CREATE_GRAPHIC_BUFFER: {
     90             CHECK_INTERFACE(IGraphicBufferAlloc, data, reply);
     91             uint32_t w = data.readInt32();
     92             uint32_t h = data.readInt32();
     93             PixelFormat format = data.readInt32();
     94             uint32_t usage = data.readInt32();
     95             status_t error;
     96             sp<GraphicBuffer> result =
     97                     createGraphicBuffer(w, h, format, usage, &error);
     98             reply->writeInt32(error);
     99             if (result != 0) {
    100                 reply->write(*result);
    101                 // We add a BufferReference to this parcel to make sure the
    102                 // buffer stays alive until the GraphicBuffer object on
    103                 // the other side has been created.
    104                 // This is needed so that the buffer handle can be
    105                 // registered before the buffer is destroyed on implementations
    106                 // that do not use file-descriptors to track their buffers.
    107                 reply->writeStrongBinder( new BufferReference(result) );
    108             }
    109             return NO_ERROR;
    110         } break;
    111         default:
    112             return BBinder::onTransact(code, data, reply, flags);
    113     }
    114 }
    115 
    116 }; // namespace android
    117