IGraphicBufferProducer.cpp revision eafabcdc1639fb96062d9e3c39b0ae27b0238ae1
1/*
2 * Copyright (C) 2010 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/RefBase.h>
22#include <utils/Vector.h>
23#include <utils/Timers.h>
24
25#include <binder/Parcel.h>
26#include <binder/IInterface.h>
27
28#include <gui/ISurfaceTexture.h>
29
30namespace android {
31// ----------------------------------------------------------------------------
32
33enum {
34    REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
35    SET_BUFFER_COUNT,
36    DEQUEUE_BUFFER,
37    QUEUE_BUFFER,
38    CANCEL_BUFFER,
39    SET_CROP,
40    SET_TRANSFORM,
41    GET_ALLOCATOR,
42    QUERY,
43};
44
45
46class BpSurfaceTexture : public BpInterface<ISurfaceTexture>
47{
48public:
49    BpSurfaceTexture(const sp<IBinder>& impl)
50        : BpInterface<ISurfaceTexture>(impl)
51    {
52    }
53
54    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx) {
55        Parcel data, reply;
56        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
57        data.writeInt32(bufferIdx);
58        remote()->transact(REQUEST_BUFFER, data, &reply);
59        sp<GraphicBuffer> buffer;
60        bool nonNull = reply.readInt32();
61        if (nonNull) {
62            buffer = new GraphicBuffer();
63            reply.read(*buffer);
64        }
65        return buffer;
66    }
67
68    virtual status_t setBufferCount(int bufferCount)
69    {
70        Parcel data, reply;
71        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
72        data.writeInt32(bufferCount);
73        remote()->transact(SET_BUFFER_COUNT, data, &reply);
74        status_t err = reply.readInt32();
75        return err;
76    }
77
78    virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
79            uint32_t format, uint32_t usage) {
80        Parcel data, reply;
81        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
82        data.writeInt32(w);
83        data.writeInt32(h);
84        data.writeInt32(format);
85        data.writeInt32(usage);
86        remote()->transact(DEQUEUE_BUFFER, data, &reply);
87        *buf = reply.readInt32();
88        int result = reply.readInt32();
89        return result;
90    }
91
92    virtual status_t queueBuffer(int buf, int64_t timestamp) {
93        Parcel data, reply;
94        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
95        data.writeInt32(buf);
96        data.writeInt64(timestamp);
97        remote()->transact(QUEUE_BUFFER, data, &reply);
98        status_t result = reply.readInt32();
99        return result;
100    }
101
102    virtual void cancelBuffer(int buf) {
103        Parcel data, reply;
104        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
105        data.writeInt32(buf);
106        remote()->transact(CANCEL_BUFFER, data, &reply);
107    }
108
109    virtual status_t setCrop(const Rect& reg) {
110        Parcel data, reply;
111        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
112        data.writeFloat(reg.left);
113        data.writeFloat(reg.top);
114        data.writeFloat(reg.right);
115        data.writeFloat(reg.bottom);
116        remote()->transact(SET_CROP, data, &reply);
117        status_t result = reply.readInt32();
118        return result;
119    }
120
121    virtual status_t setTransform(uint32_t transform) {
122        Parcel data, reply;
123        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
124        data.writeInt32(transform);
125        remote()->transact(SET_TRANSFORM, data, &reply);
126        status_t result = reply.readInt32();
127        return result;
128    }
129
130    virtual sp<IBinder> getAllocator() {
131        Parcel data, reply;
132        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
133        remote()->transact(GET_ALLOCATOR, data, &reply);
134        return reply.readStrongBinder();
135    }
136
137    virtual int query(int what, int* value) {
138        Parcel data, reply;
139        data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
140        data.writeInt32(what);
141        remote()->transact(QUERY, data, &reply);
142        value[0] = reply.readInt32();
143        status_t result = reply.readInt32();
144        return result;
145    }
146
147};
148
149IMPLEMENT_META_INTERFACE(SurfaceTexture, "android.gui.SurfaceTexture");
150
151// ----------------------------------------------------------------------
152
153status_t BnSurfaceTexture::onTransact(
154    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
155{
156    switch(code) {
157        case REQUEST_BUFFER: {
158            CHECK_INTERFACE(ISurfaceTexture, data, reply);
159            int bufferIdx   = data.readInt32();
160            sp<GraphicBuffer> buffer(requestBuffer(bufferIdx));
161            reply->writeInt32(buffer != 0);
162            if (buffer != 0) {
163                reply->write(*buffer);
164            }
165            return NO_ERROR;
166        } break;
167        case SET_BUFFER_COUNT: {
168            CHECK_INTERFACE(ISurfaceTexture, data, reply);
169            int bufferCount = data.readInt32();
170            int result = setBufferCount(bufferCount);
171            reply->writeInt32(result);
172            return NO_ERROR;
173        } break;
174        case DEQUEUE_BUFFER: {
175            CHECK_INTERFACE(ISurfaceTexture, data, reply);
176            uint32_t w      = data.readInt32();
177            uint32_t h      = data.readInt32();
178            uint32_t format = data.readInt32();
179            uint32_t usage  = data.readInt32();
180            int buf;
181            int result = dequeueBuffer(&buf, w, h, format, usage);
182            reply->writeInt32(buf);
183            reply->writeInt32(result);
184            return NO_ERROR;
185        } break;
186        case QUEUE_BUFFER: {
187            CHECK_INTERFACE(ISurfaceTexture, data, reply);
188            int buf = data.readInt32();
189            int64_t timestamp = data.readInt64();
190            status_t result = queueBuffer(buf, timestamp);
191            reply->writeInt32(result);
192            return NO_ERROR;
193        } break;
194        case CANCEL_BUFFER: {
195            CHECK_INTERFACE(ISurfaceTexture, data, reply);
196            int buf = data.readInt32();
197            cancelBuffer(buf);
198            return NO_ERROR;
199        } break;
200        case SET_CROP: {
201            Rect reg;
202            CHECK_INTERFACE(ISurfaceTexture, data, reply);
203            reg.left = data.readFloat();
204            reg.top = data.readFloat();
205            reg.right = data.readFloat();
206            reg.bottom = data.readFloat();
207            status_t result = setCrop(reg);
208            reply->writeInt32(result);
209            return NO_ERROR;
210        } break;
211        case SET_TRANSFORM: {
212            CHECK_INTERFACE(ISurfaceTexture, data, reply);
213            uint32_t transform = data.readInt32();
214            status_t result = setTransform(transform);
215            reply->writeInt32(result);
216            return NO_ERROR;
217        } break;
218        case GET_ALLOCATOR: {
219            CHECK_INTERFACE(ISurfaceTexture, data, reply);
220            sp<IBinder> result = getAllocator();
221            reply->writeStrongBinder(result);
222            return NO_ERROR;
223        } break;
224        case QUERY: {
225            CHECK_INTERFACE(ISurfaceTexture, data, reply);
226            int value;
227            int what = data.readInt32();
228            int res = query(what, &value);
229            reply->writeInt32(value);
230            reply->writeInt32(res);
231            return NO_ERROR;
232        } break;
233    }
234    return BBinder::onTransact(code, data, reply, flags);
235}
236
237// ----------------------------------------------------------------------------
238
239}; // namespace android
240