Home | History | Annotate | Download | only in gui
      1 /*
      2  * Copyright (C) 2013 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 #include <stdint.h>
     18 #include <sys/types.h>
     19 
     20 #include <utils/Errors.h>
     21 #include <utils/NativeHandle.h>
     22 
     23 #include <binder/Parcel.h>
     24 #include <binder/IInterface.h>
     25 
     26 #include <gui/BufferItem.h>
     27 #include <gui/IConsumerListener.h>
     28 #include <gui/IGraphicBufferConsumer.h>
     29 
     30 #include <ui/GraphicBuffer.h>
     31 #include <ui/Fence.h>
     32 
     33 #include <system/window.h>
     34 
     35 namespace android {
     36 
     37 enum {
     38     ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
     39     DETACH_BUFFER,
     40     ATTACH_BUFFER,
     41     RELEASE_BUFFER,
     42     CONSUMER_CONNECT,
     43     CONSUMER_DISCONNECT,
     44     GET_RELEASED_BUFFERS,
     45     SET_DEFAULT_BUFFER_SIZE,
     46     SET_DEFAULT_MAX_BUFFER_COUNT,
     47     DISABLE_ASYNC_BUFFER,
     48     SET_MAX_ACQUIRED_BUFFER_COUNT,
     49     SET_CONSUMER_NAME,
     50     SET_DEFAULT_BUFFER_FORMAT,
     51     SET_DEFAULT_BUFFER_DATA_SPACE,
     52     SET_CONSUMER_USAGE_BITS,
     53     SET_TRANSFORM_HINT,
     54     GET_SIDEBAND_STREAM,
     55     DUMP,
     56 };
     57 
     58 
     59 class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
     60 {
     61 public:
     62     BpGraphicBufferConsumer(const sp<IBinder>& impl)
     63         : BpInterface<IGraphicBufferConsumer>(impl)
     64     {
     65     }
     66 
     67     virtual ~BpGraphicBufferConsumer();
     68 
     69     virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen,
     70             uint64_t maxFrameNumber) {
     71         Parcel data, reply;
     72         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
     73         data.writeInt64(presentWhen);
     74         data.writeUint64(maxFrameNumber);
     75         status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
     76         if (result != NO_ERROR) {
     77             return result;
     78         }
     79         result = reply.read(*buffer);
     80         if (result != NO_ERROR) {
     81             return result;
     82         }
     83         return reply.readInt32();
     84     }
     85 
     86     virtual status_t detachBuffer(int slot) {
     87         Parcel data, reply;
     88         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
     89         data.writeInt32(slot);
     90         status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
     91         if (result != NO_ERROR) {
     92             return result;
     93         }
     94         result = reply.readInt32();
     95         return result;
     96     }
     97 
     98     virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
     99         Parcel data, reply;
    100         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    101         data.write(*buffer.get());
    102         status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
    103         if (result != NO_ERROR) {
    104             return result;
    105         }
    106         *slot = reply.readInt32();
    107         result = reply.readInt32();
    108         return result;
    109     }
    110 
    111     virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
    112             EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
    113             const sp<Fence>& releaseFence) {
    114         Parcel data, reply;
    115         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    116         data.writeInt32(buf);
    117         data.writeInt64(static_cast<int64_t>(frameNumber));
    118         data.write(*releaseFence);
    119         status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
    120         if (result != NO_ERROR) {
    121             return result;
    122         }
    123         return reply.readInt32();
    124     }
    125 
    126     virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
    127         Parcel data, reply;
    128         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    129         data.writeStrongBinder(IInterface::asBinder(consumer));
    130         data.writeInt32(controlledByApp);
    131         status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
    132         if (result != NO_ERROR) {
    133             return result;
    134         }
    135         return reply.readInt32();
    136     }
    137 
    138     virtual status_t consumerDisconnect() {
    139         Parcel data, reply;
    140         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    141         status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
    142         if (result != NO_ERROR) {
    143             return result;
    144         }
    145         return reply.readInt32();
    146     }
    147 
    148     virtual status_t getReleasedBuffers(uint64_t* slotMask) {
    149         Parcel data, reply;
    150         if (slotMask == NULL) {
    151             ALOGE("getReleasedBuffers: slotMask must not be NULL");
    152             return BAD_VALUE;
    153         }
    154         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    155         status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
    156         if (result != NO_ERROR) {
    157             return result;
    158         }
    159         *slotMask = static_cast<uint64_t>(reply.readInt64());
    160         return reply.readInt32();
    161     }
    162 
    163     virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height) {
    164         Parcel data, reply;
    165         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    166         data.writeUint32(width);
    167         data.writeUint32(height);
    168         status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
    169         if (result != NO_ERROR) {
    170             return result;
    171         }
    172         return reply.readInt32();
    173     }
    174 
    175     virtual status_t setDefaultMaxBufferCount(int bufferCount) {
    176         Parcel data, reply;
    177         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    178         data.writeInt32(bufferCount);
    179         status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
    180         if (result != NO_ERROR) {
    181             return result;
    182         }
    183         return reply.readInt32();
    184     }
    185 
    186     virtual status_t disableAsyncBuffer() {
    187         Parcel data, reply;
    188         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    189         status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
    190         if (result != NO_ERROR) {
    191             return result;
    192         }
    193         return reply.readInt32();
    194     }
    195 
    196     virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
    197         Parcel data, reply;
    198         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    199         data.writeInt32(maxAcquiredBuffers);
    200         status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
    201         if (result != NO_ERROR) {
    202             return result;
    203         }
    204         return reply.readInt32();
    205     }
    206 
    207     virtual void setConsumerName(const String8& name) {
    208         Parcel data, reply;
    209         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    210         data.writeString8(name);
    211         remote()->transact(SET_CONSUMER_NAME, data, &reply);
    212     }
    213 
    214     virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) {
    215         Parcel data, reply;
    216         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    217         data.writeInt32(static_cast<int32_t>(defaultFormat));
    218         status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
    219         if (result != NO_ERROR) {
    220             return result;
    221         }
    222         return reply.readInt32();
    223     }
    224 
    225     virtual status_t setDefaultBufferDataSpace(
    226             android_dataspace defaultDataSpace) {
    227         Parcel data, reply;
    228         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    229         data.writeInt32(static_cast<int32_t>(defaultDataSpace));
    230         status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE,
    231                 data, &reply);
    232         if (result != NO_ERROR) {
    233             return result;
    234         }
    235         return reply.readInt32();
    236     }
    237 
    238     virtual status_t setConsumerUsageBits(uint32_t usage) {
    239         Parcel data, reply;
    240         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    241         data.writeUint32(usage);
    242         status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
    243         if (result != NO_ERROR) {
    244             return result;
    245         }
    246         return reply.readInt32();
    247     }
    248 
    249     virtual status_t setTransformHint(uint32_t hint) {
    250         Parcel data, reply;
    251         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    252         data.writeUint32(hint);
    253         status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
    254         if (result != NO_ERROR) {
    255             return result;
    256         }
    257         return reply.readInt32();
    258     }
    259 
    260     virtual sp<NativeHandle> getSidebandStream() const {
    261         Parcel data, reply;
    262         status_t err;
    263         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    264         if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
    265             return NULL;
    266         }
    267         sp<NativeHandle> stream;
    268         if (reply.readInt32()) {
    269             stream = NativeHandle::create(reply.readNativeHandle(), true);
    270         }
    271         return stream;
    272     }
    273 
    274     virtual void dump(String8& result, const char* prefix) const {
    275         Parcel data, reply;
    276         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    277         data.writeString8(result);
    278         data.writeString8(String8(prefix ? prefix : ""));
    279         remote()->transact(DUMP, data, &reply);
    280         reply.readString8();
    281     }
    282 };
    283 
    284 // Out-of-line virtual method definition to trigger vtable emission in this
    285 // translation unit (see clang warning -Wweak-vtables)
    286 BpGraphicBufferConsumer::~BpGraphicBufferConsumer() {}
    287 
    288 IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
    289 
    290 // ----------------------------------------------------------------------
    291 
    292 status_t BnGraphicBufferConsumer::onTransact(
    293         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    294 {
    295     switch(code) {
    296         case ACQUIRE_BUFFER: {
    297             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    298             BufferItem item;
    299             int64_t presentWhen = data.readInt64();
    300             uint64_t maxFrameNumber = data.readUint64();
    301             status_t result = acquireBuffer(&item, presentWhen, maxFrameNumber);
    302             status_t err = reply->write(item);
    303             if (err) return err;
    304             reply->writeInt32(result);
    305             return NO_ERROR;
    306         }
    307         case DETACH_BUFFER: {
    308             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    309             int slot = data.readInt32();
    310             int result = detachBuffer(slot);
    311             reply->writeInt32(result);
    312             return NO_ERROR;
    313         }
    314         case ATTACH_BUFFER: {
    315             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    316             sp<GraphicBuffer> buffer = new GraphicBuffer();
    317             data.read(*buffer.get());
    318             int slot;
    319             int result = attachBuffer(&slot, buffer);
    320             reply->writeInt32(slot);
    321             reply->writeInt32(result);
    322             return NO_ERROR;
    323         }
    324         case RELEASE_BUFFER: {
    325             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    326             int buf = data.readInt32();
    327             uint64_t frameNumber = static_cast<uint64_t>(data.readInt64());
    328             sp<Fence> releaseFence = new Fence();
    329             status_t err = data.read(*releaseFence);
    330             if (err) return err;
    331             status_t result = releaseBuffer(buf, frameNumber,
    332                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
    333             reply->writeInt32(result);
    334             return NO_ERROR;
    335         }
    336         case CONSUMER_CONNECT: {
    337             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    338             sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
    339             bool controlledByApp = data.readInt32();
    340             status_t result = consumerConnect(consumer, controlledByApp);
    341             reply->writeInt32(result);
    342             return NO_ERROR;
    343         }
    344         case CONSUMER_DISCONNECT: {
    345             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    346             status_t result = consumerDisconnect();
    347             reply->writeInt32(result);
    348             return NO_ERROR;
    349         }
    350         case GET_RELEASED_BUFFERS: {
    351             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    352             uint64_t slotMask;
    353             status_t result = getReleasedBuffers(&slotMask);
    354             reply->writeInt64(static_cast<int64_t>(slotMask));
    355             reply->writeInt32(result);
    356             return NO_ERROR;
    357         }
    358         case SET_DEFAULT_BUFFER_SIZE: {
    359             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    360             uint32_t width = data.readUint32();
    361             uint32_t height = data.readUint32();
    362             status_t result = setDefaultBufferSize(width, height);
    363             reply->writeInt32(result);
    364             return NO_ERROR;
    365         }
    366         case SET_DEFAULT_MAX_BUFFER_COUNT: {
    367             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    368             int bufferCount = data.readInt32();
    369             status_t result = setDefaultMaxBufferCount(bufferCount);
    370             reply->writeInt32(result);
    371             return NO_ERROR;
    372         }
    373         case DISABLE_ASYNC_BUFFER: {
    374             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    375             status_t result = disableAsyncBuffer();
    376             reply->writeInt32(result);
    377             return NO_ERROR;
    378         }
    379         case SET_MAX_ACQUIRED_BUFFER_COUNT: {
    380             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    381             int maxAcquiredBuffers = data.readInt32();
    382             status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
    383             reply->writeInt32(result);
    384             return NO_ERROR;
    385         }
    386         case SET_CONSUMER_NAME: {
    387             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    388             setConsumerName( data.readString8() );
    389             return NO_ERROR;
    390         }
    391         case SET_DEFAULT_BUFFER_FORMAT: {
    392             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    393             PixelFormat defaultFormat = static_cast<PixelFormat>(data.readInt32());
    394             status_t result = setDefaultBufferFormat(defaultFormat);
    395             reply->writeInt32(result);
    396             return NO_ERROR;
    397         }
    398         case SET_DEFAULT_BUFFER_DATA_SPACE: {
    399             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    400             android_dataspace defaultDataSpace =
    401                     static_cast<android_dataspace>(data.readInt32());
    402             status_t result = setDefaultBufferDataSpace(defaultDataSpace);
    403             reply->writeInt32(result);
    404             return NO_ERROR;
    405         }
    406         case SET_CONSUMER_USAGE_BITS: {
    407             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    408             uint32_t usage = data.readUint32();
    409             status_t result = setConsumerUsageBits(usage);
    410             reply->writeInt32(result);
    411             return NO_ERROR;
    412         }
    413         case SET_TRANSFORM_HINT: {
    414             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    415             uint32_t hint = data.readUint32();
    416             status_t result = setTransformHint(hint);
    417             reply->writeInt32(result);
    418             return NO_ERROR;
    419         }
    420         case GET_SIDEBAND_STREAM: {
    421             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    422             sp<NativeHandle> stream = getSidebandStream();
    423             reply->writeInt32(static_cast<int32_t>(stream != NULL));
    424             if (stream != NULL) {
    425                 reply->writeNativeHandle(stream->handle());
    426             }
    427             return NO_ERROR;
    428         }
    429         case DUMP: {
    430             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    431             String8 result = data.readString8();
    432             String8 prefix = data.readString8();
    433             static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
    434             reply->writeString8(result);
    435             return NO_ERROR;
    436         }
    437     }
    438     return BBinder::onTransact(code, data, reply, flags);
    439 }
    440 
    441 }; // namespace android
    442