SurfaceTextureClient.cpp revision 749172269ac6b6f7a430e64f604e7f040524e0a1
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#define LOG_TAG "SurfaceTextureClient" 18//#define LOG_NDEBUG 0 19 20#include <gui/SurfaceTextureClient.h> 21 22#include <utils/Log.h> 23 24namespace android { 25 26SurfaceTextureClient::SurfaceTextureClient( 27 const sp<ISurfaceTexture>& surfaceTexture): 28 mSurfaceTexture(surfaceTexture), mReqWidth(1), mReqHeight(1), 29 mReqFormat(DEFAULT_FORMAT), mReqUsage(0), mMutex() { 30 // Initialize the ANativeWindow function pointers. 31 ANativeWindow::setSwapInterval = setSwapInterval; 32 ANativeWindow::dequeueBuffer = dequeueBuffer; 33 ANativeWindow::cancelBuffer = cancelBuffer; 34 ANativeWindow::lockBuffer = lockBuffer; 35 ANativeWindow::queueBuffer = queueBuffer; 36 ANativeWindow::query = query; 37 ANativeWindow::perform = perform; 38} 39 40int SurfaceTextureClient::setSwapInterval(ANativeWindow* window, int interval) { 41 SurfaceTextureClient* c = getSelf(window); 42 return c->setSwapInterval(interval); 43} 44 45int SurfaceTextureClient::dequeueBuffer(ANativeWindow* window, 46 android_native_buffer_t** buffer) { 47 SurfaceTextureClient* c = getSelf(window); 48 return c->dequeueBuffer(buffer); 49} 50 51int SurfaceTextureClient::cancelBuffer(ANativeWindow* window, 52 android_native_buffer_t* buffer) { 53 SurfaceTextureClient* c = getSelf(window); 54 return c->cancelBuffer(buffer); 55} 56 57int SurfaceTextureClient::lockBuffer(ANativeWindow* window, 58 android_native_buffer_t* buffer) { 59 SurfaceTextureClient* c = getSelf(window); 60 return c->lockBuffer(buffer); 61} 62 63int SurfaceTextureClient::queueBuffer(ANativeWindow* window, 64 android_native_buffer_t* buffer) { 65 SurfaceTextureClient* c = getSelf(window); 66 return c->queueBuffer(buffer); 67} 68 69int SurfaceTextureClient::query(ANativeWindow* window, int what, int* value) { 70 SurfaceTextureClient* c = getSelf(window); 71 return c->query(what, value); 72} 73 74int SurfaceTextureClient::perform(ANativeWindow* window, int operation, ...) { 75 va_list args; 76 va_start(args, operation); 77 SurfaceTextureClient* c = getSelf(window); 78 return c->perform(operation, args); 79} 80 81int SurfaceTextureClient::setSwapInterval(int interval) { 82 return INVALID_OPERATION; 83} 84 85int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) { 86 LOGV("SurfaceTextureClient::dequeueBuffer"); 87 Mutex::Autolock lock(mMutex); 88 int buf = -1; 89 status_t err = mSurfaceTexture->dequeueBuffer(&buf); 90 if (err < 0) { 91 LOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer failed: %d", err); 92 return err; 93 } 94 sp<GraphicBuffer>& gbuf(mSlots[buf]); 95 if (gbuf == 0 || gbuf->getWidth() != mReqWidth || 96 gbuf->getHeight() != mReqHeight || 97 uint32_t(gbuf->getPixelFormat()) != mReqFormat || 98 (gbuf->getUsage() & mReqUsage) != mReqUsage) { 99 gbuf = mSurfaceTexture->requestBuffer(buf, mReqWidth, mReqHeight, 100 mReqFormat, mReqUsage); 101 if (gbuf == 0) { 102 LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed"); 103 return NO_MEMORY; 104 } 105 } 106 *buffer = gbuf.get(); 107 return OK; 108} 109 110int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer) { 111 LOGV("SurfaceTextureClient::cancelBuffer"); 112 Mutex::Autolock lock(mMutex); 113 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 114 if (mSlots[i]->handle == buffer->handle) { 115 mSurfaceTexture->cancelBuffer(i); 116 return OK; 117 } 118 } 119 return BAD_VALUE; 120} 121 122int SurfaceTextureClient::lockBuffer(android_native_buffer_t* buffer) { 123 LOGV("SurfaceTextureClient::lockBuffer"); 124 Mutex::Autolock lock(mMutex); 125 return OK; 126} 127 128int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) { 129 LOGV("SurfaceTextureClient::queueBuffer"); 130 Mutex::Autolock lock(mMutex); 131 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 132 if (mSlots[i]->handle == buffer->handle) { 133 return mSurfaceTexture->queueBuffer(i); 134 } 135 } 136 LOGE("queueBuffer: unknown buffer queued"); 137 return BAD_VALUE; 138} 139 140int SurfaceTextureClient::query(int what, int* value) { 141 LOGV("SurfaceTextureClient::query"); 142 Mutex::Autolock lock(mMutex); 143 // XXX: Implement this! 144 return INVALID_OPERATION; 145} 146 147int SurfaceTextureClient::perform(int operation, va_list args) 148{ 149 int res = NO_ERROR; 150 switch (operation) { 151 case NATIVE_WINDOW_CONNECT: 152 res = dispatchConnect(args); 153 break; 154 case NATIVE_WINDOW_DISCONNECT: 155 res = dispatchDisconnect(args); 156 break; 157 case NATIVE_WINDOW_SET_USAGE: 158 res = dispatchSetUsage(args); 159 break; 160 case NATIVE_WINDOW_SET_CROP: 161 res = dispatchSetCrop(args); 162 break; 163 case NATIVE_WINDOW_SET_BUFFER_COUNT: 164 res = dispatchSetBufferCount(args); 165 break; 166 case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: 167 res = dispatchSetBuffersGeometry(args); 168 break; 169 case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: 170 res = dispatchSetBuffersTransform(args); 171 break; 172 default: 173 res = NAME_NOT_FOUND; 174 break; 175 } 176 return res; 177} 178 179int SurfaceTextureClient::dispatchConnect(va_list args) { 180 int api = va_arg(args, int); 181 return connect(api); 182} 183 184int SurfaceTextureClient::dispatchDisconnect(va_list args) { 185 int api = va_arg(args, int); 186 return disconnect(api); 187} 188 189int SurfaceTextureClient::dispatchSetUsage(va_list args) { 190 int usage = va_arg(args, int); 191 return setUsage(usage); 192} 193 194int SurfaceTextureClient::dispatchSetCrop(va_list args) { 195 android_native_rect_t const* rect = va_arg(args, android_native_rect_t*); 196 return setCrop(reinterpret_cast<Rect const*>(rect)); 197} 198 199int SurfaceTextureClient::dispatchSetBufferCount(va_list args) { 200 size_t bufferCount = va_arg(args, size_t); 201 return setBufferCount(bufferCount); 202} 203 204int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) { 205 int w = va_arg(args, int); 206 int h = va_arg(args, int); 207 int f = va_arg(args, int); 208 return setBuffersGeometry(w, h, f); 209} 210 211int SurfaceTextureClient::dispatchSetBuffersTransform(va_list args) { 212 int transform = va_arg(args, int); 213 return setBuffersTransform(transform); 214} 215 216int SurfaceTextureClient::connect(int api) { 217 LOGV("SurfaceTextureClient::connect"); 218 // XXX: Implement this! 219 return INVALID_OPERATION; 220} 221 222int SurfaceTextureClient::disconnect(int api) { 223 LOGV("SurfaceTextureClient::disconnect"); 224 // XXX: Implement this! 225 return INVALID_OPERATION; 226} 227 228int SurfaceTextureClient::setUsage(uint32_t reqUsage) 229{ 230 LOGV("SurfaceTextureClient::setUsage"); 231 Mutex::Autolock lock(mMutex); 232 mReqUsage = reqUsage; 233 return OK; 234} 235 236int SurfaceTextureClient::setCrop(Rect const* rect) 237{ 238 LOGV("SurfaceTextureClient::setCrop"); 239 Mutex::Autolock lock(mMutex); 240 241 // empty/invalid rects are not allowed 242 if (rect->isEmpty()) 243 return BAD_VALUE; 244 245 status_t err = mSurfaceTexture->setCrop(*rect); 246 LOGE_IF(err, "ISurfaceTexture::setCrop(...) returned %s", 247 strerror(-err)); 248 249 return err; 250} 251 252int SurfaceTextureClient::setBufferCount(int bufferCount) 253{ 254 LOGV("SurfaceTextureClient::setBufferCount"); 255 Mutex::Autolock lock(mMutex); 256 257 status_t err = mSurfaceTexture->setBufferCount(bufferCount); 258 LOGE_IF(err, "ISurfaceTexture::setBufferCount(%d) returned %s", 259 bufferCount, strerror(-err)); 260 261 if (err == NO_ERROR) { 262 freeAllBuffers(); 263 } 264 265 return err; 266} 267 268int SurfaceTextureClient::setBuffersGeometry(int w, int h, int format) 269{ 270 LOGV("SurfaceTextureClient::setBuffersGeometry"); 271 Mutex::Autolock lock(mMutex); 272 273 if (w<0 || h<0 || format<0) 274 return BAD_VALUE; 275 276 if ((w && !h) || (!w && h)) 277 return BAD_VALUE; 278 279 mReqWidth = w; 280 mReqHeight = h; 281 mReqFormat = format; 282 283 return NO_ERROR; 284} 285 286int SurfaceTextureClient::setBuffersTransform(int transform) 287{ 288 LOGV("SurfaceTextureClient::setBuffersTransform"); 289 Mutex::Autolock lock(mMutex); 290 status_t err = mSurfaceTexture->setTransform(transform); 291 return err; 292} 293 294void SurfaceTextureClient::freeAllBuffers() { 295 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 296 mSlots[i] = 0; 297 } 298} 299 300}; // namespace android 301