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