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 QUERY, 42 SET_SYNCHRONOUS_MODE, 43 CONNECT, 44 DISCONNECT, 45 SET_SCALING_MODE, 46}; 47 48 49class BpSurfaceTexture : public BpInterface<ISurfaceTexture> 50{ 51public: 52 BpSurfaceTexture(const sp<IBinder>& impl) 53 : BpInterface<ISurfaceTexture>(impl) 54 { 55 } 56 57 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) { 58 Parcel data, reply; 59 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 60 data.writeInt32(bufferIdx); 61 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply); 62 if (result != NO_ERROR) { 63 return result; 64 } 65 bool nonNull = reply.readInt32(); 66 if (nonNull) { 67 *buf = new GraphicBuffer(); 68 reply.read(**buf); 69 } 70 result = reply.readInt32(); 71 return result; 72 } 73 74 virtual status_t setBufferCount(int bufferCount) 75 { 76 Parcel data, reply; 77 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 78 data.writeInt32(bufferCount); 79 status_t result =remote()->transact(SET_BUFFER_COUNT, data, &reply); 80 if (result != NO_ERROR) { 81 return result; 82 } 83 result = reply.readInt32(); 84 return result; 85 } 86 87 virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h, 88 uint32_t format, uint32_t usage) { 89 Parcel data, reply; 90 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 91 data.writeInt32(w); 92 data.writeInt32(h); 93 data.writeInt32(format); 94 data.writeInt32(usage); 95 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply); 96 if (result != NO_ERROR) { 97 return result; 98 } 99 *buf = reply.readInt32(); 100 result = reply.readInt32(); 101 return result; 102 } 103 104 virtual status_t queueBuffer(int buf, int64_t timestamp, 105 uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 106 Parcel data, reply; 107 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 108 data.writeInt32(buf); 109 data.writeInt64(timestamp); 110 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply); 111 if (result != NO_ERROR) { 112 return result; 113 } 114 *outWidth = reply.readInt32(); 115 *outHeight = reply.readInt32(); 116 *outTransform = reply.readInt32(); 117 result = reply.readInt32(); 118 return result; 119 } 120 121 virtual void cancelBuffer(int buf) { 122 Parcel data, reply; 123 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 124 data.writeInt32(buf); 125 remote()->transact(CANCEL_BUFFER, data, &reply); 126 } 127 128 virtual status_t setCrop(const Rect& reg) { 129 Parcel data, reply; 130 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 131 data.writeFloat(reg.left); 132 data.writeFloat(reg.top); 133 data.writeFloat(reg.right); 134 data.writeFloat(reg.bottom); 135 status_t result = remote()->transact(SET_CROP, data, &reply); 136 if (result != NO_ERROR) { 137 return result; 138 } 139 result = reply.readInt32(); 140 return result; 141 } 142 143 virtual status_t setTransform(uint32_t transform) { 144 Parcel data, reply; 145 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 146 data.writeInt32(transform); 147 status_t result = remote()->transact(SET_TRANSFORM, data, &reply); 148 if (result != NO_ERROR) { 149 return result; 150 } 151 result = reply.readInt32(); 152 return result; 153 } 154 155 virtual status_t setScalingMode(int mode) { 156 Parcel data, reply; 157 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 158 data.writeInt32(mode); 159 status_t result = remote()->transact(SET_SCALING_MODE, data, &reply); 160 if (result != NO_ERROR) { 161 return result; 162 } 163 result = reply.readInt32(); 164 return result; 165 } 166 167 virtual int query(int what, int* value) { 168 Parcel data, reply; 169 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 170 data.writeInt32(what); 171 status_t result = remote()->transact(QUERY, data, &reply); 172 if (result != NO_ERROR) { 173 return result; 174 } 175 value[0] = reply.readInt32(); 176 result = reply.readInt32(); 177 return result; 178 } 179 180 virtual status_t setSynchronousMode(bool enabled) { 181 Parcel data, reply; 182 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 183 data.writeInt32(enabled); 184 status_t result = remote()->transact(SET_SYNCHRONOUS_MODE, data, &reply); 185 if (result != NO_ERROR) { 186 return result; 187 } 188 result = reply.readInt32(); 189 return result; 190 } 191 192 virtual status_t connect(int api, 193 uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 194 Parcel data, reply; 195 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 196 data.writeInt32(api); 197 status_t result = remote()->transact(CONNECT, data, &reply); 198 if (result != NO_ERROR) { 199 return result; 200 } 201 *outWidth = reply.readInt32(); 202 *outHeight = reply.readInt32(); 203 *outTransform = reply.readInt32(); 204 result = reply.readInt32(); 205 return result; 206 } 207 208 virtual status_t disconnect(int api) { 209 Parcel data, reply; 210 data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); 211 data.writeInt32(api); 212 status_t result =remote()->transact(DISCONNECT, data, &reply); 213 if (result != NO_ERROR) { 214 return result; 215 } 216 result = reply.readInt32(); 217 return result; 218 } 219}; 220 221IMPLEMENT_META_INTERFACE(SurfaceTexture, "android.gui.SurfaceTexture"); 222 223// ---------------------------------------------------------------------- 224 225status_t BnSurfaceTexture::onTransact( 226 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 227{ 228 switch(code) { 229 case REQUEST_BUFFER: { 230 CHECK_INTERFACE(ISurfaceTexture, data, reply); 231 int bufferIdx = data.readInt32(); 232 sp<GraphicBuffer> buffer; 233 int result = requestBuffer(bufferIdx, &buffer); 234 reply->writeInt32(buffer != 0); 235 if (buffer != 0) { 236 reply->write(*buffer); 237 } 238 reply->writeInt32(result); 239 return NO_ERROR; 240 } break; 241 case SET_BUFFER_COUNT: { 242 CHECK_INTERFACE(ISurfaceTexture, data, reply); 243 int bufferCount = data.readInt32(); 244 int result = setBufferCount(bufferCount); 245 reply->writeInt32(result); 246 return NO_ERROR; 247 } break; 248 case DEQUEUE_BUFFER: { 249 CHECK_INTERFACE(ISurfaceTexture, data, reply); 250 uint32_t w = data.readInt32(); 251 uint32_t h = data.readInt32(); 252 uint32_t format = data.readInt32(); 253 uint32_t usage = data.readInt32(); 254 int buf; 255 int result = dequeueBuffer(&buf, w, h, format, usage); 256 reply->writeInt32(buf); 257 reply->writeInt32(result); 258 return NO_ERROR; 259 } break; 260 case QUEUE_BUFFER: { 261 CHECK_INTERFACE(ISurfaceTexture, data, reply); 262 int buf = data.readInt32(); 263 int64_t timestamp = data.readInt64(); 264 uint32_t outWidth, outHeight, outTransform; 265 status_t result = queueBuffer(buf, timestamp, 266 &outWidth, &outHeight, &outTransform); 267 reply->writeInt32(outWidth); 268 reply->writeInt32(outHeight); 269 reply->writeInt32(outTransform); 270 reply->writeInt32(result); 271 return NO_ERROR; 272 } break; 273 case CANCEL_BUFFER: { 274 CHECK_INTERFACE(ISurfaceTexture, data, reply); 275 int buf = data.readInt32(); 276 cancelBuffer(buf); 277 return NO_ERROR; 278 } break; 279 case SET_CROP: { 280 Rect reg; 281 CHECK_INTERFACE(ISurfaceTexture, data, reply); 282 reg.left = data.readFloat(); 283 reg.top = data.readFloat(); 284 reg.right = data.readFloat(); 285 reg.bottom = data.readFloat(); 286 status_t result = setCrop(reg); 287 reply->writeInt32(result); 288 return NO_ERROR; 289 } break; 290 case SET_TRANSFORM: { 291 CHECK_INTERFACE(ISurfaceTexture, data, reply); 292 uint32_t transform = data.readInt32(); 293 status_t result = setTransform(transform); 294 reply->writeInt32(result); 295 return NO_ERROR; 296 } break; 297 case SET_SCALING_MODE: { 298 CHECK_INTERFACE(ISurfaceTexture, data, reply); 299 int mode = data.readInt32(); 300 status_t result = setScalingMode(mode); 301 reply->writeInt32(result); 302 return NO_ERROR; 303 } break; 304 case QUERY: { 305 CHECK_INTERFACE(ISurfaceTexture, data, reply); 306 int value; 307 int what = data.readInt32(); 308 int res = query(what, &value); 309 reply->writeInt32(value); 310 reply->writeInt32(res); 311 return NO_ERROR; 312 } break; 313 case SET_SYNCHRONOUS_MODE: { 314 CHECK_INTERFACE(ISurfaceTexture, data, reply); 315 bool enabled = data.readInt32(); 316 status_t res = setSynchronousMode(enabled); 317 reply->writeInt32(res); 318 return NO_ERROR; 319 } break; 320 case CONNECT: { 321 CHECK_INTERFACE(ISurfaceTexture, data, reply); 322 int api = data.readInt32(); 323 uint32_t outWidth, outHeight, outTransform; 324 status_t res = connect(api, 325 &outWidth, &outHeight, &outTransform); 326 reply->writeInt32(outWidth); 327 reply->writeInt32(outHeight); 328 reply->writeInt32(outTransform); 329 reply->writeInt32(res); 330 return NO_ERROR; 331 } break; 332 case DISCONNECT: { 333 CHECK_INTERFACE(ISurfaceTexture, data, reply); 334 int api = data.readInt32(); 335 status_t res = disconnect(api); 336 reply->writeInt32(res); 337 return NO_ERROR; 338 } break; 339 } 340 return BBinder::onTransact(code, data, reply, flags); 341} 342 343// ---------------------------------------------------------------------------- 344 345}; // namespace android 346