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/IConsumerListener.h>
     27 #include <gui/IGraphicBufferConsumer.h>
     28 
     29 #include <ui/GraphicBuffer.h>
     30 #include <ui/Fence.h>
     31 
     32 #include <system/window.h>
     33 
     34 namespace android {
     35 // ---------------------------------------------------------------------------
     36 
     37 IGraphicBufferConsumer::BufferItem::BufferItem() :
     38     mTransform(0),
     39     mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
     40     mTimestamp(0),
     41     mIsAutoTimestamp(false),
     42     mFrameNumber(0),
     43     mBuf(INVALID_BUFFER_SLOT),
     44     mIsDroppable(false),
     45     mAcquireCalled(false),
     46     mTransformToDisplayInverse(false) {
     47     mCrop.makeInvalid();
     48 }
     49 
     50 size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
     51     size_t c =  sizeof(mCrop) +
     52             sizeof(mTransform) +
     53             sizeof(mScalingMode) +
     54             sizeof(mTimestamp) +
     55             sizeof(mIsAutoTimestamp) +
     56             sizeof(mFrameNumber) +
     57             sizeof(mBuf) +
     58             sizeof(mIsDroppable) +
     59             sizeof(mAcquireCalled) +
     60             sizeof(mTransformToDisplayInverse);
     61     return c;
     62 }
     63 
     64 size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const {
     65     size_t c = 0;
     66     if (mGraphicBuffer != 0) {
     67         c += mGraphicBuffer->getFlattenedSize();
     68         c = FlattenableUtils::align<4>(c);
     69     }
     70     if (mFence != 0) {
     71         c += mFence->getFlattenedSize();
     72         c = FlattenableUtils::align<4>(c);
     73     }
     74     return sizeof(int32_t) + c + getPodSize();
     75 }
     76 
     77 size_t IGraphicBufferConsumer::BufferItem::getFdCount() const {
     78     size_t c = 0;
     79     if (mGraphicBuffer != 0) {
     80         c += mGraphicBuffer->getFdCount();
     81     }
     82     if (mFence != 0) {
     83         c += mFence->getFdCount();
     84     }
     85     return c;
     86 }
     87 
     88 static void writeBoolAsInt(void*& buffer, size_t& size, bool b) {
     89     FlattenableUtils::write(buffer, size, static_cast<int32_t>(b));
     90 }
     91 
     92 static bool readBoolFromInt(void const*& buffer, size_t& size) {
     93     int32_t i;
     94     FlattenableUtils::read(buffer, size, i);
     95     return static_cast<bool>(i);
     96 }
     97 
     98 status_t IGraphicBufferConsumer::BufferItem::flatten(
     99         void*& buffer, size_t& size, int*& fds, size_t& count) const {
    100 
    101     // make sure we have enough space
    102     if (size < BufferItem::getFlattenedSize()) {
    103         return NO_MEMORY;
    104     }
    105 
    106     // content flags are stored first
    107     uint32_t& flags = *static_cast<uint32_t*>(buffer);
    108 
    109     // advance the pointer
    110     FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
    111 
    112     flags = 0;
    113     if (mGraphicBuffer != 0) {
    114         status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
    115         if (err) return err;
    116         size -= FlattenableUtils::align<4>(buffer);
    117         flags |= 1;
    118     }
    119     if (mFence != 0) {
    120         status_t err = mFence->flatten(buffer, size, fds, count);
    121         if (err) return err;
    122         size -= FlattenableUtils::align<4>(buffer);
    123         flags |= 2;
    124     }
    125 
    126     // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
    127     if (size < getPodSize()) {
    128         return NO_MEMORY;
    129     }
    130 
    131     FlattenableUtils::write(buffer, size, mCrop);
    132     FlattenableUtils::write(buffer, size, mTransform);
    133     FlattenableUtils::write(buffer, size, mScalingMode);
    134     FlattenableUtils::write(buffer, size, mTimestamp);
    135     writeBoolAsInt(buffer, size, mIsAutoTimestamp);
    136     FlattenableUtils::write(buffer, size, mFrameNumber);
    137     FlattenableUtils::write(buffer, size, mBuf);
    138     writeBoolAsInt(buffer, size, mIsDroppable);
    139     writeBoolAsInt(buffer, size, mAcquireCalled);
    140     writeBoolAsInt(buffer, size, mTransformToDisplayInverse);
    141 
    142     return NO_ERROR;
    143 }
    144 
    145 status_t IGraphicBufferConsumer::BufferItem::unflatten(
    146         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
    147 
    148     if (size < sizeof(uint32_t))
    149         return NO_MEMORY;
    150 
    151     uint32_t flags = 0;
    152     FlattenableUtils::read(buffer, size, flags);
    153 
    154     if (flags & 1) {
    155         mGraphicBuffer = new GraphicBuffer();
    156         status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
    157         if (err) return err;
    158         size -= FlattenableUtils::align<4>(buffer);
    159     }
    160 
    161     if (flags & 2) {
    162         mFence = new Fence();
    163         status_t err = mFence->unflatten(buffer, size, fds, count);
    164         if (err) return err;
    165         size -= FlattenableUtils::align<4>(buffer);
    166     }
    167 
    168     // check we have enough space
    169     if (size < getPodSize()) {
    170         return NO_MEMORY;
    171     }
    172 
    173     FlattenableUtils::read(buffer, size, mCrop);
    174     FlattenableUtils::read(buffer, size, mTransform);
    175     FlattenableUtils::read(buffer, size, mScalingMode);
    176     FlattenableUtils::read(buffer, size, mTimestamp);
    177     mIsAutoTimestamp = readBoolFromInt(buffer, size);
    178     FlattenableUtils::read(buffer, size, mFrameNumber);
    179     FlattenableUtils::read(buffer, size, mBuf);
    180     mIsDroppable = readBoolFromInt(buffer, size);
    181     mAcquireCalled = readBoolFromInt(buffer, size);
    182     mTransformToDisplayInverse = readBoolFromInt(buffer, size);
    183 
    184     return NO_ERROR;
    185 }
    186 
    187 // ---------------------------------------------------------------------------
    188 
    189 enum {
    190     ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
    191     DETACH_BUFFER,
    192     ATTACH_BUFFER,
    193     RELEASE_BUFFER,
    194     CONSUMER_CONNECT,
    195     CONSUMER_DISCONNECT,
    196     GET_RELEASED_BUFFERS,
    197     SET_DEFAULT_BUFFER_SIZE,
    198     SET_DEFAULT_MAX_BUFFER_COUNT,
    199     DISABLE_ASYNC_BUFFER,
    200     SET_MAX_ACQUIRED_BUFFER_COUNT,
    201     SET_CONSUMER_NAME,
    202     SET_DEFAULT_BUFFER_FORMAT,
    203     SET_CONSUMER_USAGE_BITS,
    204     SET_TRANSFORM_HINT,
    205     GET_SIDEBAND_STREAM,
    206     DUMP,
    207 };
    208 
    209 
    210 class BpGraphicBufferConsumer : public BpInterface<IGraphicBufferConsumer>
    211 {
    212 public:
    213     BpGraphicBufferConsumer(const sp<IBinder>& impl)
    214         : BpInterface<IGraphicBufferConsumer>(impl)
    215     {
    216     }
    217 
    218     virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
    219         Parcel data, reply;
    220         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    221         data.writeInt64(presentWhen);
    222         status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply);
    223         if (result != NO_ERROR) {
    224             return result;
    225         }
    226         result = reply.read(*buffer);
    227         if (result != NO_ERROR) {
    228             return result;
    229         }
    230         return reply.readInt32();
    231     }
    232 
    233     virtual status_t detachBuffer(int slot) {
    234         Parcel data, reply;
    235         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    236         data.writeInt32(slot);
    237         status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
    238         if (result != NO_ERROR) {
    239             return result;
    240         }
    241         result = reply.readInt32();
    242         return result;
    243     }
    244 
    245     virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
    246         Parcel data, reply;
    247         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    248         data.write(*buffer.get());
    249         status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
    250         if (result != NO_ERROR) {
    251             return result;
    252         }
    253         *slot = reply.readInt32();
    254         result = reply.readInt32();
    255         return result;
    256     }
    257 
    258     virtual status_t releaseBuffer(int buf, uint64_t frameNumber,
    259             EGLDisplay display __attribute__((unused)), EGLSyncKHR fence __attribute__((unused)),
    260             const sp<Fence>& releaseFence) {
    261         Parcel data, reply;
    262         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    263         data.writeInt32(buf);
    264         data.writeInt64(frameNumber);
    265         data.write(*releaseFence);
    266         status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
    267         if (result != NO_ERROR) {
    268             return result;
    269         }
    270         return reply.readInt32();
    271     }
    272 
    273     virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
    274         Parcel data, reply;
    275         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    276         data.writeStrongBinder(consumer->asBinder());
    277         data.writeInt32(controlledByApp);
    278         status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
    279         if (result != NO_ERROR) {
    280             return result;
    281         }
    282         return reply.readInt32();
    283     }
    284 
    285     virtual status_t consumerDisconnect() {
    286         Parcel data, reply;
    287         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    288         status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply);
    289         if (result != NO_ERROR) {
    290             return result;
    291         }
    292         return reply.readInt32();
    293     }
    294 
    295     virtual status_t getReleasedBuffers(uint64_t* slotMask) {
    296         Parcel data, reply;
    297         if (slotMask == NULL) {
    298             ALOGE("getReleasedBuffers: slotMask must not be NULL");
    299             return BAD_VALUE;
    300         }
    301         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    302         status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply);
    303         if (result != NO_ERROR) {
    304             return result;
    305         }
    306         *slotMask = reply.readInt64();
    307         return reply.readInt32();
    308     }
    309 
    310     virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) {
    311         Parcel data, reply;
    312         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    313         data.writeInt32(w);
    314         data.writeInt32(h);
    315         status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
    316         if (result != NO_ERROR) {
    317             return result;
    318         }
    319         return reply.readInt32();
    320     }
    321 
    322     virtual status_t setDefaultMaxBufferCount(int bufferCount) {
    323         Parcel data, reply;
    324         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    325         data.writeInt32(bufferCount);
    326         status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply);
    327         if (result != NO_ERROR) {
    328             return result;
    329         }
    330         return reply.readInt32();
    331     }
    332 
    333     virtual status_t disableAsyncBuffer() {
    334         Parcel data, reply;
    335         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    336         status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply);
    337         if (result != NO_ERROR) {
    338             return result;
    339         }
    340         return reply.readInt32();
    341     }
    342 
    343     virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
    344         Parcel data, reply;
    345         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    346         data.writeInt32(maxAcquiredBuffers);
    347         status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
    348         if (result != NO_ERROR) {
    349             return result;
    350         }
    351         return reply.readInt32();
    352     }
    353 
    354     virtual void setConsumerName(const String8& name) {
    355         Parcel data, reply;
    356         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    357         data.writeString8(name);
    358         remote()->transact(SET_CONSUMER_NAME, data, &reply);
    359     }
    360 
    361     virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) {
    362         Parcel data, reply;
    363         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    364         data.writeInt32(defaultFormat);
    365         status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
    366         if (result != NO_ERROR) {
    367             return result;
    368         }
    369         return reply.readInt32();
    370     }
    371 
    372     virtual status_t setConsumerUsageBits(uint32_t usage) {
    373         Parcel data, reply;
    374         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    375         data.writeInt32(usage);
    376         status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
    377         if (result != NO_ERROR) {
    378             return result;
    379         }
    380         return reply.readInt32();
    381     }
    382 
    383     virtual status_t setTransformHint(uint32_t hint) {
    384         Parcel data, reply;
    385         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    386         data.writeInt32(hint);
    387         status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
    388         if (result != NO_ERROR) {
    389             return result;
    390         }
    391         return reply.readInt32();
    392     }
    393 
    394     virtual sp<NativeHandle> getSidebandStream() const {
    395         Parcel data, reply;
    396         status_t err;
    397         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    398         if ((err = remote()->transact(GET_SIDEBAND_STREAM, data, &reply)) != NO_ERROR) {
    399             return NULL;
    400         }
    401         sp<NativeHandle> stream;
    402         if (reply.readInt32()) {
    403             stream = NativeHandle::create(reply.readNativeHandle(), true);
    404         }
    405         return stream;
    406     }
    407 
    408     virtual void dump(String8& result, const char* prefix) const {
    409         Parcel data, reply;
    410         data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
    411         data.writeString8(result);
    412         data.writeString8(String8(prefix ? prefix : ""));
    413         remote()->transact(DUMP, data, &reply);
    414         reply.readString8();
    415     }
    416 };
    417 
    418 IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
    419 
    420 // ----------------------------------------------------------------------
    421 
    422 status_t BnGraphicBufferConsumer::onTransact(
    423         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    424 {
    425     switch(code) {
    426         case ACQUIRE_BUFFER: {
    427             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    428             BufferItem item;
    429             int64_t presentWhen = data.readInt64();
    430             status_t result = acquireBuffer(&item, presentWhen);
    431             status_t err = reply->write(item);
    432             if (err) return err;
    433             reply->writeInt32(result);
    434             return NO_ERROR;
    435         } break;
    436         case DETACH_BUFFER: {
    437             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    438             int slot = data.readInt32();
    439             int result = detachBuffer(slot);
    440             reply->writeInt32(result);
    441             return NO_ERROR;
    442         } break;
    443         case ATTACH_BUFFER: {
    444             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    445             sp<GraphicBuffer> buffer = new GraphicBuffer();
    446             data.read(*buffer.get());
    447             int slot;
    448             int result = attachBuffer(&slot, buffer);
    449             reply->writeInt32(slot);
    450             reply->writeInt32(result);
    451             return NO_ERROR;
    452         } break;
    453         case RELEASE_BUFFER: {
    454             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    455             int buf = data.readInt32();
    456             uint64_t frameNumber = data.readInt64();
    457             sp<Fence> releaseFence = new Fence();
    458             status_t err = data.read(*releaseFence);
    459             if (err) return err;
    460             status_t result = releaseBuffer(buf, frameNumber,
    461                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
    462             reply->writeInt32(result);
    463             return NO_ERROR;
    464         } break;
    465         case CONSUMER_CONNECT: {
    466             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    467             sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
    468             bool controlledByApp = data.readInt32();
    469             status_t result = consumerConnect(consumer, controlledByApp);
    470             reply->writeInt32(result);
    471             return NO_ERROR;
    472         } break;
    473         case CONSUMER_DISCONNECT: {
    474             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    475             status_t result = consumerDisconnect();
    476             reply->writeInt32(result);
    477             return NO_ERROR;
    478         } break;
    479         case GET_RELEASED_BUFFERS: {
    480             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    481             uint64_t slotMask;
    482             status_t result = getReleasedBuffers(&slotMask);
    483             reply->writeInt64(slotMask);
    484             reply->writeInt32(result);
    485             return NO_ERROR;
    486         } break;
    487         case SET_DEFAULT_BUFFER_SIZE: {
    488             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    489             uint32_t w = data.readInt32();
    490             uint32_t h = data.readInt32();
    491             status_t result = setDefaultBufferSize(w, h);
    492             reply->writeInt32(result);
    493             return NO_ERROR;
    494         } break;
    495         case SET_DEFAULT_MAX_BUFFER_COUNT: {
    496             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    497             uint32_t bufferCount = data.readInt32();
    498             status_t result = setDefaultMaxBufferCount(bufferCount);
    499             reply->writeInt32(result);
    500             return NO_ERROR;
    501         } break;
    502         case DISABLE_ASYNC_BUFFER: {
    503             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    504             status_t result = disableAsyncBuffer();
    505             reply->writeInt32(result);
    506             return NO_ERROR;
    507         } break;
    508         case SET_MAX_ACQUIRED_BUFFER_COUNT: {
    509             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    510             uint32_t maxAcquiredBuffers = data.readInt32();
    511             status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
    512             reply->writeInt32(result);
    513             return NO_ERROR;
    514         } break;
    515         case SET_CONSUMER_NAME: {
    516             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    517             setConsumerName( data.readString8() );
    518             return NO_ERROR;
    519         } break;
    520         case SET_DEFAULT_BUFFER_FORMAT: {
    521             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    522             uint32_t defaultFormat = data.readInt32();
    523             status_t result = setDefaultBufferFormat(defaultFormat);
    524             reply->writeInt32(result);
    525             return NO_ERROR;
    526         } break;
    527         case SET_CONSUMER_USAGE_BITS: {
    528             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    529             uint32_t usage = data.readInt32();
    530             status_t result = setConsumerUsageBits(usage);
    531             reply->writeInt32(result);
    532             return NO_ERROR;
    533         } break;
    534         case SET_TRANSFORM_HINT: {
    535             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    536             uint32_t hint = data.readInt32();
    537             status_t result = setTransformHint(hint);
    538             reply->writeInt32(result);
    539             return NO_ERROR;
    540         } break;
    541         case DUMP: {
    542             CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
    543             String8 result = data.readString8();
    544             String8 prefix = data.readString8();
    545             static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
    546             reply->writeString8(result);
    547             return NO_ERROR;
    548         }
    549     }
    550     return BBinder::onTransact(code, data, reply, flags);
    551 }
    552 
    553 }; // namespace android
    554