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
32namespace android {
33
34// ----------------------------------------------------------------------
35
36ISurface::BufferHeap::BufferHeap()
37    : w(0), h(0), hor_stride(0), ver_stride(0), format(0),
38    transform(0), flags(0)
39{
40}
41
42ISurface::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
50ISurface::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
60ISurface::BufferHeap::~BufferHeap()
61{
62}
63
64// ----------------------------------------------------------------------
65
66class BpSurface : public BpInterface<ISurface>
67{
68public:
69    BpSurface(const sp<IBinder>& impl)
70        : BpInterface<ISurface>(impl)
71    {
72    }
73
74    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage)
75    {
76        Parcel data, reply;
77        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
78        data.writeInt32(bufferIdx);
79        data.writeInt32(usage);
80        remote()->transact(REQUEST_BUFFER, data, &reply);
81        sp<GraphicBuffer> buffer = new GraphicBuffer();
82        reply.read(*buffer);
83        return buffer;
84    }
85
86    virtual status_t registerBuffers(const BufferHeap& buffers)
87    {
88        Parcel data, reply;
89        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
90        data.writeInt32(buffers.w);
91        data.writeInt32(buffers.h);
92        data.writeInt32(buffers.hor_stride);
93        data.writeInt32(buffers.ver_stride);
94        data.writeInt32(buffers.format);
95        data.writeInt32(buffers.transform);
96        data.writeInt32(buffers.flags);
97        data.writeStrongBinder(buffers.heap->asBinder());
98        remote()->transact(REGISTER_BUFFERS, data, &reply);
99        status_t result = reply.readInt32();
100        return result;
101    }
102
103    virtual void postBuffer(ssize_t offset)
104    {
105        Parcel data, reply;
106        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
107        data.writeInt32(offset);
108        remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
109    }
110
111    virtual void unregisterBuffers()
112    {
113        Parcel data, reply;
114        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
115        remote()->transact(UNREGISTER_BUFFERS, data, &reply);
116    }
117
118    virtual sp<OverlayRef> createOverlay(
119             uint32_t w, uint32_t h, int32_t format, int32_t orientation)
120    {
121        Parcel data, reply;
122        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
123        data.writeInt32(w);
124        data.writeInt32(h);
125        data.writeInt32(format);
126        data.writeInt32(orientation);
127        remote()->transact(CREATE_OVERLAY, data, &reply);
128        return OverlayRef::readFromParcel(reply);
129    }
130};
131
132IMPLEMENT_META_INTERFACE(Surface, "android.ui.ISurface");
133
134// ----------------------------------------------------------------------
135
136status_t BnSurface::onTransact(
137    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
138{
139    switch(code) {
140        case REQUEST_BUFFER: {
141            CHECK_INTERFACE(ISurface, data, reply);
142            int bufferIdx = data.readInt32();
143            int usage = data.readInt32();
144            sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, usage));
145            if (buffer == NULL)
146                return BAD_VALUE;
147            return reply->write(*buffer);
148        }
149        case REGISTER_BUFFERS: {
150            CHECK_INTERFACE(ISurface, data, reply);
151            BufferHeap buffer;
152            buffer.w = data.readInt32();
153            buffer.h = data.readInt32();
154            buffer.hor_stride = data.readInt32();
155            buffer.ver_stride= data.readInt32();
156            buffer.format = data.readInt32();
157            buffer.transform = data.readInt32();
158            buffer.flags = data.readInt32();
159            buffer.heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
160            status_t err = registerBuffers(buffer);
161            reply->writeInt32(err);
162            return NO_ERROR;
163        } break;
164        case UNREGISTER_BUFFERS: {
165            CHECK_INTERFACE(ISurface, data, reply);
166            unregisterBuffers();
167            return NO_ERROR;
168        } break;
169        case POST_BUFFER: {
170            CHECK_INTERFACE(ISurface, data, reply);
171            ssize_t offset = data.readInt32();
172            postBuffer(offset);
173            return NO_ERROR;
174        } break;
175        case CREATE_OVERLAY: {
176            CHECK_INTERFACE(ISurface, data, reply);
177            int w = data.readInt32();
178            int h = data.readInt32();
179            int f = data.readInt32();
180            int orientation = data.readInt32();
181            sp<OverlayRef> o = createOverlay(w, h, f, orientation);
182            return OverlayRef::writeToParcel(reply, o);
183        } break;
184        default:
185            return BBinder::onTransact(code, data, reply, flags);
186    }
187}
188
189}; // namespace android
190