Home | History | Annotate | Download | only in surfaceflinger_client
      1 /*
      2  * Copyright (C) 2007 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 LOG_TAG "ISurface"
     18 
     19 #include <stdio.h>
     20 #include <stdint.h>
     21 #include <sys/types.h>
     22 
     23 #include <binder/Parcel.h>
     24 #include <binder/IMemory.h>
     25 
     26 #include <ui/Overlay.h>
     27 #include <ui/GraphicBuffer.h>
     28 
     29 #include <surfaceflinger/Surface.h>
     30 #include <surfaceflinger/ISurface.h>
     31 
     32 namespace android {
     33 
     34 // ----------------------------------------------------------------------
     35 
     36 ISurface::BufferHeap::BufferHeap()
     37     : w(0), h(0), hor_stride(0), ver_stride(0), format(0),
     38     transform(0), flags(0)
     39 {
     40 }
     41 
     42 ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
     43         int32_t hor_stride, int32_t ver_stride,
     44         PixelFormat format, const sp<IMemoryHeap>& heap)
     45     : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
     46       format(format), transform(0), flags(0), heap(heap)
     47 {
     48 }
     49 
     50 ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
     51         int32_t hor_stride, int32_t ver_stride,
     52         PixelFormat format, uint32_t transform, uint32_t flags,
     53         const sp<IMemoryHeap>& heap)
     54         : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
     55           format(format), transform(transform), flags(flags), heap(heap)
     56 {
     57 }
     58 
     59 
     60 ISurface::BufferHeap::~BufferHeap()
     61 {
     62 }
     63 
     64 // ----------------------------------------------------------------------
     65 
     66 class BpSurface : public BpInterface<ISurface>
     67 {
     68 public:
     69     BpSurface(const sp<IBinder>& impl)
     70         : BpInterface<ISurface>(impl)
     71     {
     72     }
     73 
     74     virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
     75             uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
     76     {
     77         Parcel data, reply;
     78         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
     79         data.writeInt32(bufferIdx);
     80         data.writeInt32(w);
     81         data.writeInt32(h);
     82         data.writeInt32(format);
     83         data.writeInt32(usage);
     84         remote()->transact(REQUEST_BUFFER, data, &reply);
     85         sp<GraphicBuffer> buffer = new GraphicBuffer();
     86         reply.read(*buffer);
     87         return buffer;
     88     }
     89 
     90     virtual status_t setBufferCount(int bufferCount)
     91     {
     92         Parcel data, reply;
     93         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
     94         data.writeInt32(bufferCount);
     95         remote()->transact(SET_BUFFER_COUNT, data, &reply);
     96         status_t err = reply.readInt32();
     97         return err;
     98     }
     99 
    100     virtual status_t registerBuffers(const BufferHeap& buffers)
    101     {
    102         Parcel data, reply;
    103         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
    104         data.writeInt32(buffers.w);
    105         data.writeInt32(buffers.h);
    106         data.writeInt32(buffers.hor_stride);
    107         data.writeInt32(buffers.ver_stride);
    108         data.writeInt32(buffers.format);
    109         data.writeInt32(buffers.transform);
    110         data.writeInt32(buffers.flags);
    111         data.writeStrongBinder(buffers.heap->asBinder());
    112         remote()->transact(REGISTER_BUFFERS, data, &reply);
    113         status_t result = reply.readInt32();
    114         return result;
    115     }
    116 
    117     virtual void postBuffer(ssize_t offset)
    118     {
    119         Parcel data, reply;
    120         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
    121         data.writeInt32(offset);
    122         remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
    123     }
    124 
    125     virtual void unregisterBuffers()
    126     {
    127         Parcel data, reply;
    128         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
    129         remote()->transact(UNREGISTER_BUFFERS, data, &reply);
    130     }
    131 
    132     virtual sp<OverlayRef> createOverlay(
    133              uint32_t w, uint32_t h, int32_t format, int32_t orientation)
    134     {
    135         Parcel data, reply;
    136         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
    137         data.writeInt32(w);
    138         data.writeInt32(h);
    139         data.writeInt32(format);
    140         data.writeInt32(orientation);
    141         remote()->transact(CREATE_OVERLAY, data, &reply);
    142         return OverlayRef::readFromParcel(reply);
    143     }
    144 };
    145 
    146 IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
    147 
    148 // ----------------------------------------------------------------------
    149 
    150 status_t BnSurface::onTransact(
    151     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    152 {
    153     switch(code) {
    154         case REQUEST_BUFFER: {
    155             CHECK_INTERFACE(ISurface, data, reply);
    156             int bufferIdx = data.readInt32();
    157             uint32_t w = data.readInt32();
    158             uint32_t h = data.readInt32();
    159             uint32_t format = data.readInt32();
    160             uint32_t usage = data.readInt32();
    161             sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, w, h, format, usage));
    162             if (buffer == NULL)
    163                 return BAD_VALUE;
    164             return reply->write(*buffer);
    165         }
    166         case SET_BUFFER_COUNT: {
    167             CHECK_INTERFACE(ISurface, data, reply);
    168             int bufferCount = data.readInt32();
    169             status_t err = setBufferCount(bufferCount);
    170             reply->writeInt32(err);
    171             return NO_ERROR;
    172         }
    173         case REGISTER_BUFFERS: {
    174             CHECK_INTERFACE(ISurface, data, reply);
    175             BufferHeap buffer;
    176             buffer.w = data.readInt32();
    177             buffer.h = data.readInt32();
    178             buffer.hor_stride = data.readInt32();
    179             buffer.ver_stride= data.readInt32();
    180             buffer.format = data.readInt32();
    181             buffer.transform = data.readInt32();
    182             buffer.flags = data.readInt32();
    183             buffer.heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
    184             status_t err = registerBuffers(buffer);
    185             reply->writeInt32(err);
    186             return NO_ERROR;
    187         } break;
    188         case UNREGISTER_BUFFERS: {
    189             CHECK_INTERFACE(ISurface, data, reply);
    190             unregisterBuffers();
    191             return NO_ERROR;
    192         } break;
    193         case POST_BUFFER: {
    194             CHECK_INTERFACE(ISurface, data, reply);
    195             ssize_t offset = data.readInt32();
    196             postBuffer(offset);
    197             return NO_ERROR;
    198         } break;
    199         case CREATE_OVERLAY: {
    200             CHECK_INTERFACE(ISurface, data, reply);
    201             int w = data.readInt32();
    202             int h = data.readInt32();
    203             int f = data.readInt32();
    204             int orientation = data.readInt32();
    205             sp<OverlayRef> o = createOverlay(w, h, f, orientation);
    206             return OverlayRef::writeToParcel(reply, o);
    207         } break;
    208         default:
    209             return BBinder::onTransact(code, data, reply, flags);
    210     }
    211 }
    212 
    213 }; // namespace android
    214