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 "SurfaceTexture" 18 //#define LOG_NDEBUG 0 19 20 #define GL_GLEXT_PROTOTYPES 21 #define EGL_EGLEXT_PROTOTYPES 22 23 #include <EGL/egl.h> 24 #include <EGL/eglext.h> 25 #include <GLES2/gl2.h> 26 #include <GLES2/gl2ext.h> 27 28 #include <gui/SurfaceTexture.h> 29 30 #include <hardware/hardware.h> 31 32 #include <surfaceflinger/ISurfaceComposer.h> 33 #include <surfaceflinger/SurfaceComposerClient.h> 34 #include <surfaceflinger/IGraphicBufferAlloc.h> 35 36 #include <utils/Log.h> 37 #include <utils/String8.h> 38 39 // This compile option causes SurfaceTexture to return the buffer that is currently 40 // attached to the GL texture from dequeueBuffer when no other buffers are 41 // available. It requires the drivers (Gralloc, GL, OMX IL, and Camera) to do 42 // implicit cross-process synchronization to prevent the buffer from being 43 // written to before the buffer has (a) been detached from the GL texture and 44 // (b) all GL reads from the buffer have completed. 45 #ifdef ALLOW_DEQUEUE_CURRENT_BUFFER 46 #define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER true 47 #warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled" 48 #else 49 #define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER false 50 #endif 51 52 // This compile option makes SurfaceTexture use the EGL_KHR_fence_sync extension 53 // to synchronize access to the buffers. It will cause dequeueBuffer to stall, 54 // waiting for the GL reads for the buffer being dequeued to complete before 55 // allowing the buffer to be dequeued. 56 #ifdef USE_FENCE_SYNC 57 #ifdef ALLOW_DEQUEUE_CURRENT_BUFFER 58 #error "USE_FENCE_SYNC and ALLOW_DEQUEUE_CURRENT_BUFFER are incompatible" 59 #endif 60 #endif 61 62 // Macros for including the SurfaceTexture name in log messages 63 #define ST_LOGV(x, ...) LOGV("[%s] "x, mName.string(), ##__VA_ARGS__) 64 #define ST_LOGD(x, ...) LOGD("[%s] "x, mName.string(), ##__VA_ARGS__) 65 #define ST_LOGI(x, ...) LOGI("[%s] "x, mName.string(), ##__VA_ARGS__) 66 #define ST_LOGW(x, ...) LOGW("[%s] "x, mName.string(), ##__VA_ARGS__) 67 #define ST_LOGE(x, ...) LOGE("[%s] "x, mName.string(), ##__VA_ARGS__) 68 69 namespace android { 70 71 // Transform matrices 72 static float mtxIdentity[16] = { 73 1, 0, 0, 0, 74 0, 1, 0, 0, 75 0, 0, 1, 0, 76 0, 0, 0, 1, 77 }; 78 static float mtxFlipH[16] = { 79 -1, 0, 0, 0, 80 0, 1, 0, 0, 81 0, 0, 1, 0, 82 1, 0, 0, 1, 83 }; 84 static float mtxFlipV[16] = { 85 1, 0, 0, 0, 86 0, -1, 0, 0, 87 0, 0, 1, 0, 88 0, 1, 0, 1, 89 }; 90 static float mtxRot90[16] = { 91 0, 1, 0, 0, 92 -1, 0, 0, 0, 93 0, 0, 1, 0, 94 1, 0, 0, 1, 95 }; 96 static float mtxRot180[16] = { 97 -1, 0, 0, 0, 98 0, -1, 0, 0, 99 0, 0, 1, 0, 100 1, 1, 0, 1, 101 }; 102 static float mtxRot270[16] = { 103 0, -1, 0, 0, 104 1, 0, 0, 0, 105 0, 0, 1, 0, 106 0, 1, 0, 1, 107 }; 108 109 static void mtxMul(float out[16], const float a[16], const float b[16]); 110 111 // Get an ID that's unique within this process. 112 static int32_t createProcessUniqueId() { 113 static volatile int32_t globalCounter = 0; 114 return android_atomic_inc(&globalCounter); 115 } 116 117 SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode, 118 GLenum texTarget, bool useFenceSync) : 119 mDefaultWidth(1), 120 mDefaultHeight(1), 121 mPixelFormat(PIXEL_FORMAT_RGBA_8888), 122 mBufferCount(MIN_ASYNC_BUFFER_SLOTS), 123 mClientBufferCount(0), 124 mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS), 125 mCurrentTexture(INVALID_BUFFER_SLOT), 126 mCurrentTransform(0), 127 mCurrentTimestamp(0), 128 mNextTransform(0), 129 mNextScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 130 mTexName(tex), 131 mSynchronousMode(false), 132 mAllowSynchronousMode(allowSynchronousMode), 133 mConnectedApi(NO_CONNECTED_API), 134 mAbandoned(false), 135 #ifdef USE_FENCE_SYNC 136 mUseFenceSync(useFenceSync), 137 #else 138 mUseFenceSync(false), 139 #endif 140 mTexTarget(texTarget), 141 mFrameCounter(0) { 142 // Choose a name using the PID and a process-unique ID. 143 mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 144 145 ST_LOGV("SurfaceTexture"); 146 sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 147 mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); 148 mNextCrop.makeInvalid(); 149 memcpy(mCurrentTransformMatrix, mtxIdentity, 150 sizeof(mCurrentTransformMatrix)); 151 } 152 153 SurfaceTexture::~SurfaceTexture() { 154 ST_LOGV("~SurfaceTexture"); 155 freeAllBuffersLocked(); 156 } 157 158 status_t SurfaceTexture::setBufferCountServerLocked(int bufferCount) { 159 if (bufferCount > NUM_BUFFER_SLOTS) 160 return BAD_VALUE; 161 162 // special-case, nothing to do 163 if (bufferCount == mBufferCount) 164 return OK; 165 166 if (!mClientBufferCount && 167 bufferCount >= mBufferCount) { 168 // easy, we just have more buffers 169 mBufferCount = bufferCount; 170 mServerBufferCount = bufferCount; 171 mDequeueCondition.signal(); 172 } else { 173 // we're here because we're either 174 // - reducing the number of available buffers 175 // - or there is a client-buffer-count in effect 176 177 // less than 2 buffers is never allowed 178 if (bufferCount < 2) 179 return BAD_VALUE; 180 181 // when there is non client-buffer-count in effect, the client is not 182 // allowed to dequeue more than one buffer at a time, 183 // so the next time they dequeue a buffer, we know that they don't 184 // own one. the actual resizing will happen during the next 185 // dequeueBuffer. 186 187 mServerBufferCount = bufferCount; 188 } 189 return OK; 190 } 191 192 status_t SurfaceTexture::setBufferCountServer(int bufferCount) { 193 Mutex::Autolock lock(mMutex); 194 return setBufferCountServerLocked(bufferCount); 195 } 196 197 status_t SurfaceTexture::setBufferCount(int bufferCount) { 198 ST_LOGV("setBufferCount: count=%d", bufferCount); 199 Mutex::Autolock lock(mMutex); 200 201 if (mAbandoned) { 202 ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!"); 203 return NO_INIT; 204 } 205 if (bufferCount > NUM_BUFFER_SLOTS) { 206 ST_LOGE("setBufferCount: bufferCount larger than slots available"); 207 return BAD_VALUE; 208 } 209 210 // Error out if the user has dequeued buffers 211 for (int i=0 ; i<mBufferCount ; i++) { 212 if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 213 ST_LOGE("setBufferCount: client owns some buffers"); 214 return -EINVAL; 215 } 216 } 217 218 const int minBufferSlots = mSynchronousMode ? 219 MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS; 220 if (bufferCount == 0) { 221 mClientBufferCount = 0; 222 bufferCount = (mServerBufferCount >= minBufferSlots) ? 223 mServerBufferCount : minBufferSlots; 224 return setBufferCountServerLocked(bufferCount); 225 } 226 227 if (bufferCount < minBufferSlots) { 228 ST_LOGE("setBufferCount: requested buffer count (%d) is less than " 229 "minimum (%d)", bufferCount, minBufferSlots); 230 return BAD_VALUE; 231 } 232 233 // here we're guaranteed that the client doesn't have dequeued buffers 234 // and will release all of its buffer references. 235 freeAllBuffersLocked(); 236 mBufferCount = bufferCount; 237 mClientBufferCount = bufferCount; 238 mCurrentTexture = INVALID_BUFFER_SLOT; 239 mQueue.clear(); 240 mDequeueCondition.signal(); 241 return OK; 242 } 243 244 status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h) 245 { 246 ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 247 if (!w || !h) { 248 ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 249 w, h); 250 return BAD_VALUE; 251 } 252 253 Mutex::Autolock lock(mMutex); 254 mDefaultWidth = w; 255 mDefaultHeight = h; 256 return OK; 257 } 258 259 status_t SurfaceTexture::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 260 ST_LOGV("requestBuffer: slot=%d", slot); 261 Mutex::Autolock lock(mMutex); 262 if (mAbandoned) { 263 ST_LOGE("requestBuffer: SurfaceTexture has been abandoned!"); 264 return NO_INIT; 265 } 266 if (slot < 0 || mBufferCount <= slot) { 267 ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 268 mBufferCount, slot); 269 return BAD_VALUE; 270 } 271 mSlots[slot].mRequestBufferCalled = true; 272 *buf = mSlots[slot].mGraphicBuffer; 273 return NO_ERROR; 274 } 275 276 status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, 277 uint32_t format, uint32_t usage) { 278 ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 279 280 if ((w && !h) || (!w && h)) { 281 ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 282 return BAD_VALUE; 283 } 284 285 status_t returnFlags(OK); 286 EGLDisplay dpy = EGL_NO_DISPLAY; 287 EGLSyncKHR fence = EGL_NO_SYNC_KHR; 288 289 { // Scope for the lock 290 Mutex::Autolock lock(mMutex); 291 292 int found = -1; 293 int foundSync = -1; 294 int dequeuedCount = 0; 295 bool tryAgain = true; 296 while (tryAgain) { 297 if (mAbandoned) { 298 ST_LOGE("dequeueBuffer: SurfaceTexture has been abandoned!"); 299 return NO_INIT; 300 } 301 302 // We need to wait for the FIFO to drain if the number of buffer 303 // needs to change. 304 // 305 // The condition "number of buffers needs to change" is true if 306 // - the client doesn't care about how many buffers there are 307 // - AND the actual number of buffer is different from what was 308 // set in the last setBufferCountServer() 309 // - OR - 310 // setBufferCountServer() was set to a value incompatible with 311 // the synchronization mode (for instance because the sync mode 312 // changed since) 313 // 314 // As long as this condition is true AND the FIFO is not empty, we 315 // wait on mDequeueCondition. 316 317 const int minBufferCountNeeded = mSynchronousMode ? 318 MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS; 319 320 const bool numberOfBuffersNeedsToChange = !mClientBufferCount && 321 ((mServerBufferCount != mBufferCount) || 322 (mServerBufferCount < minBufferCountNeeded)); 323 324 if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) { 325 // wait for the FIFO to drain 326 mDequeueCondition.wait(mMutex); 327 // NOTE: we continue here because we need to reevaluate our 328 // whole state (eg: we could be abandoned or disconnected) 329 continue; 330 } 331 332 if (numberOfBuffersNeedsToChange) { 333 // here we're guaranteed that mQueue is empty 334 freeAllBuffersLocked(); 335 mBufferCount = mServerBufferCount; 336 if (mBufferCount < minBufferCountNeeded) 337 mBufferCount = minBufferCountNeeded; 338 mCurrentTexture = INVALID_BUFFER_SLOT; 339 returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS; 340 } 341 342 // look for a free buffer to give to the client 343 found = INVALID_BUFFER_SLOT; 344 foundSync = INVALID_BUFFER_SLOT; 345 dequeuedCount = 0; 346 for (int i = 0; i < mBufferCount; i++) { 347 const int state = mSlots[i].mBufferState; 348 if (state == BufferSlot::DEQUEUED) { 349 dequeuedCount++; 350 } 351 352 // if buffer is FREE it CANNOT be current 353 LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i), 354 "dequeueBuffer: buffer %d is both FREE and current!", 355 i); 356 357 if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) { 358 if (state == BufferSlot::FREE || i == mCurrentTexture) { 359 foundSync = i; 360 if (i != mCurrentTexture) { 361 found = i; 362 break; 363 } 364 } 365 } else { 366 if (state == BufferSlot::FREE) { 367 /* We return the oldest of the free buffers to avoid 368 * stalling the producer if possible. This is because 369 * the consumer may still have pending reads of the 370 * buffers in flight. 371 */ 372 bool isOlder = mSlots[i].mFrameNumber < 373 mSlots[found].mFrameNumber; 374 if (found < 0 || isOlder) { 375 foundSync = i; 376 found = i; 377 } 378 } 379 } 380 } 381 382 // clients are not allowed to dequeue more than one buffer 383 // if they didn't set a buffer count. 384 if (!mClientBufferCount && dequeuedCount) { 385 ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without " 386 "setting the buffer count"); 387 return -EINVAL; 388 } 389 390 // See whether a buffer has been queued since the last 391 // setBufferCount so we know whether to perform the 392 // MIN_UNDEQUEUED_BUFFERS check below. 393 bool bufferHasBeenQueued = mCurrentTexture != INVALID_BUFFER_SLOT; 394 if (bufferHasBeenQueued) { 395 // make sure the client is not trying to dequeue more buffers 396 // than allowed. 397 const int avail = mBufferCount - (dequeuedCount+1); 398 if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) { 399 ST_LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded " 400 "(dequeued=%d)", 401 MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode), 402 dequeuedCount); 403 return -EBUSY; 404 } 405 } 406 407 // we're in synchronous mode and didn't find a buffer, we need to 408 // wait for some buffers to be consumed 409 tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT); 410 if (tryAgain) { 411 mDequeueCondition.wait(mMutex); 412 } 413 } 414 415 if (mSynchronousMode && found == INVALID_BUFFER_SLOT) { 416 // foundSync guaranteed to be != INVALID_BUFFER_SLOT 417 found = foundSync; 418 } 419 420 if (found == INVALID_BUFFER_SLOT) { 421 // This should not happen. 422 ST_LOGE("dequeueBuffer: no available buffer slots"); 423 return -EBUSY; 424 } 425 426 const int buf = found; 427 *outBuf = found; 428 429 const bool useDefaultSize = !w && !h; 430 if (useDefaultSize) { 431 // use the default size 432 w = mDefaultWidth; 433 h = mDefaultHeight; 434 } 435 436 const bool updateFormat = (format != 0); 437 if (!updateFormat) { 438 // keep the current (or default) format 439 format = mPixelFormat; 440 } 441 442 // buffer is now in DEQUEUED (but can also be current at the same time, 443 // if we're in synchronous mode) 444 mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 445 446 const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 447 if ((buffer == NULL) || 448 (uint32_t(buffer->width) != w) || 449 (uint32_t(buffer->height) != h) || 450 (uint32_t(buffer->format) != format) || 451 ((uint32_t(buffer->usage) & usage) != usage)) 452 { 453 usage |= GraphicBuffer::USAGE_HW_TEXTURE; 454 status_t error; 455 sp<GraphicBuffer> graphicBuffer( 456 mGraphicBufferAlloc->createGraphicBuffer( 457 w, h, format, usage, &error)); 458 if (graphicBuffer == 0) { 459 ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " 460 "failed"); 461 return error; 462 } 463 if (updateFormat) { 464 mPixelFormat = format; 465 } 466 mSlots[buf].mGraphicBuffer = graphicBuffer; 467 mSlots[buf].mRequestBufferCalled = false; 468 mSlots[buf].mFence = EGL_NO_SYNC_KHR; 469 if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) { 470 eglDestroyImageKHR(mSlots[buf].mEglDisplay, 471 mSlots[buf].mEglImage); 472 mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR; 473 mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 474 } 475 if (mCurrentTexture == buf) { 476 // The current texture no longer references the buffer in this slot 477 // since we just allocated a new buffer. 478 mCurrentTexture = INVALID_BUFFER_SLOT; 479 } 480 returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; 481 } 482 483 dpy = mSlots[buf].mEglDisplay; 484 fence = mSlots[buf].mFence; 485 mSlots[buf].mFence = EGL_NO_SYNC_KHR; 486 } 487 488 if (fence != EGL_NO_SYNC_KHR) { 489 EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000); 490 // If something goes wrong, log the error, but return the buffer without 491 // synchronizing access to it. It's too late at this point to abort the 492 // dequeue operation. 493 if (result == EGL_FALSE) { 494 LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError()); 495 } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 496 LOGE("dequeueBuffer: timeout waiting for fence"); 497 } 498 eglDestroySyncKHR(dpy, fence); 499 } 500 501 ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", *outBuf, 502 mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); 503 504 return returnFlags; 505 } 506 507 status_t SurfaceTexture::setSynchronousMode(bool enabled) { 508 ST_LOGV("setSynchronousMode: enabled=%d", enabled); 509 Mutex::Autolock lock(mMutex); 510 511 if (mAbandoned) { 512 ST_LOGE("setSynchronousMode: SurfaceTexture has been abandoned!"); 513 return NO_INIT; 514 } 515 516 status_t err = OK; 517 if (!mAllowSynchronousMode && enabled) 518 return err; 519 520 if (!enabled) { 521 // going to asynchronous mode, drain the queue 522 err = drainQueueLocked(); 523 if (err != NO_ERROR) 524 return err; 525 } 526 527 if (mSynchronousMode != enabled) { 528 // - if we're going to asynchronous mode, the queue is guaranteed to be 529 // empty here 530 // - if the client set the number of buffers, we're guaranteed that 531 // we have at least 3 (because we don't allow less) 532 mSynchronousMode = enabled; 533 mDequeueCondition.signal(); 534 } 535 return err; 536 } 537 538 status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp, 539 uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 540 ST_LOGV("queueBuffer: slot=%d time=%lld", buf, timestamp); 541 542 sp<FrameAvailableListener> listener; 543 544 { // scope for the lock 545 Mutex::Autolock lock(mMutex); 546 if (mAbandoned) { 547 ST_LOGE("queueBuffer: SurfaceTexture has been abandoned!"); 548 return NO_INIT; 549 } 550 if (buf < 0 || buf >= mBufferCount) { 551 ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 552 mBufferCount, buf); 553 return -EINVAL; 554 } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 555 ST_LOGE("queueBuffer: slot %d is not owned by the client " 556 "(state=%d)", buf, mSlots[buf].mBufferState); 557 return -EINVAL; 558 } else if (buf == mCurrentTexture) { 559 ST_LOGE("queueBuffer: slot %d is current!", buf); 560 return -EINVAL; 561 } else if (!mSlots[buf].mRequestBufferCalled) { 562 ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 563 "buffer", buf); 564 return -EINVAL; 565 } 566 567 if (mSynchronousMode) { 568 // In synchronous mode we queue all buffers in a FIFO. 569 mQueue.push_back(buf); 570 571 // Synchronous mode always signals that an additional frame should 572 // be consumed. 573 listener = mFrameAvailableListener; 574 } else { 575 // In asynchronous mode we only keep the most recent buffer. 576 if (mQueue.empty()) { 577 mQueue.push_back(buf); 578 579 // Asynchronous mode only signals that a frame should be 580 // consumed if no previous frame was pending. If a frame were 581 // pending then the consumer would have already been notified. 582 listener = mFrameAvailableListener; 583 } else { 584 Fifo::iterator front(mQueue.begin()); 585 // buffer currently queued is freed 586 mSlots[*front].mBufferState = BufferSlot::FREE; 587 // and we record the new buffer index in the queued list 588 *front = buf; 589 } 590 } 591 592 mSlots[buf].mBufferState = BufferSlot::QUEUED; 593 mSlots[buf].mCrop = mNextCrop; 594 mSlots[buf].mTransform = mNextTransform; 595 mSlots[buf].mScalingMode = mNextScalingMode; 596 mSlots[buf].mTimestamp = timestamp; 597 mFrameCounter++; 598 mSlots[buf].mFrameNumber = mFrameCounter; 599 600 mDequeueCondition.signal(); 601 602 *outWidth = mDefaultWidth; 603 *outHeight = mDefaultHeight; 604 *outTransform = 0; 605 } // scope for the lock 606 607 // call back without lock held 608 if (listener != 0) { 609 listener->onFrameAvailable(); 610 } 611 return OK; 612 } 613 614 void SurfaceTexture::cancelBuffer(int buf) { 615 ST_LOGV("cancelBuffer: slot=%d", buf); 616 Mutex::Autolock lock(mMutex); 617 618 if (mAbandoned) { 619 ST_LOGW("cancelBuffer: SurfaceTexture has been abandoned!"); 620 return; 621 } 622 623 if (buf < 0 || buf >= mBufferCount) { 624 ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 625 mBufferCount, buf); 626 return; 627 } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 628 ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 629 buf, mSlots[buf].mBufferState); 630 return; 631 } 632 mSlots[buf].mBufferState = BufferSlot::FREE; 633 mSlots[buf].mFrameNumber = 0; 634 mDequeueCondition.signal(); 635 } 636 637 status_t SurfaceTexture::setCrop(const Rect& crop) { 638 ST_LOGV("setCrop: crop=[%d,%d,%d,%d]", crop.left, crop.top, crop.right, 639 crop.bottom); 640 641 Mutex::Autolock lock(mMutex); 642 if (mAbandoned) { 643 ST_LOGE("setCrop: SurfaceTexture has been abandoned!"); 644 return NO_INIT; 645 } 646 mNextCrop = crop; 647 return OK; 648 } 649 650 status_t SurfaceTexture::setTransform(uint32_t transform) { 651 ST_LOGV("setTransform: xform=%#x", transform); 652 Mutex::Autolock lock(mMutex); 653 if (mAbandoned) { 654 ST_LOGE("setTransform: SurfaceTexture has been abandoned!"); 655 return NO_INIT; 656 } 657 mNextTransform = transform; 658 return OK; 659 } 660 661 status_t SurfaceTexture::connect(int api, 662 uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) { 663 ST_LOGV("connect: api=%d", api); 664 Mutex::Autolock lock(mMutex); 665 666 if (mAbandoned) { 667 ST_LOGE("connect: SurfaceTexture has been abandoned!"); 668 return NO_INIT; 669 } 670 671 int err = NO_ERROR; 672 switch (api) { 673 case NATIVE_WINDOW_API_EGL: 674 case NATIVE_WINDOW_API_CPU: 675 case NATIVE_WINDOW_API_MEDIA: 676 case NATIVE_WINDOW_API_CAMERA: 677 if (mConnectedApi != NO_CONNECTED_API) { 678 ST_LOGE("connect: already connected (cur=%d, req=%d)", 679 mConnectedApi, api); 680 err = -EINVAL; 681 } else { 682 mConnectedApi = api; 683 *outWidth = mDefaultWidth; 684 *outHeight = mDefaultHeight; 685 *outTransform = 0; 686 } 687 break; 688 default: 689 err = -EINVAL; 690 break; 691 } 692 return err; 693 } 694 695 status_t SurfaceTexture::disconnect(int api) { 696 ST_LOGV("disconnect: api=%d", api); 697 Mutex::Autolock lock(mMutex); 698 699 if (mAbandoned) { 700 // it is not really an error to disconnect after the surface 701 // has been abandoned, it should just be a no-op. 702 return NO_ERROR; 703 } 704 705 int err = NO_ERROR; 706 switch (api) { 707 case NATIVE_WINDOW_API_EGL: 708 case NATIVE_WINDOW_API_CPU: 709 case NATIVE_WINDOW_API_MEDIA: 710 case NATIVE_WINDOW_API_CAMERA: 711 if (mConnectedApi == api) { 712 drainQueueAndFreeBuffersLocked(); 713 mConnectedApi = NO_CONNECTED_API; 714 mNextCrop.makeInvalid(); 715 mNextScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 716 mNextTransform = 0; 717 mDequeueCondition.signal(); 718 } else { 719 ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 720 mConnectedApi, api); 721 err = -EINVAL; 722 } 723 break; 724 default: 725 ST_LOGE("disconnect: unknown API %d", api); 726 err = -EINVAL; 727 break; 728 } 729 return err; 730 } 731 732 status_t SurfaceTexture::setScalingMode(int mode) { 733 ST_LOGV("setScalingMode: mode=%d", mode); 734 735 switch (mode) { 736 case NATIVE_WINDOW_SCALING_MODE_FREEZE: 737 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 738 break; 739 default: 740 ST_LOGE("unknown scaling mode: %d", mode); 741 return BAD_VALUE; 742 } 743 744 Mutex::Autolock lock(mMutex); 745 mNextScalingMode = mode; 746 return OK; 747 } 748 749 status_t SurfaceTexture::updateTexImage() { 750 ST_LOGV("updateTexImage"); 751 Mutex::Autolock lock(mMutex); 752 753 if (mAbandoned) { 754 ST_LOGE("calling updateTexImage() on an abandoned SurfaceTexture"); 755 return NO_INIT; 756 } 757 758 // In asynchronous mode the list is guaranteed to be one buffer 759 // deep, while in synchronous mode we use the oldest buffer. 760 if (!mQueue.empty()) { 761 Fifo::iterator front(mQueue.begin()); 762 int buf = *front; 763 764 // Update the GL texture object. 765 EGLImageKHR image = mSlots[buf].mEglImage; 766 EGLDisplay dpy = eglGetCurrentDisplay(); 767 if (image == EGL_NO_IMAGE_KHR) { 768 if (mSlots[buf].mGraphicBuffer == 0) { 769 ST_LOGE("buffer at slot %d is null", buf); 770 return BAD_VALUE; 771 } 772 image = createImage(dpy, mSlots[buf].mGraphicBuffer); 773 mSlots[buf].mEglImage = image; 774 mSlots[buf].mEglDisplay = dpy; 775 if (image == EGL_NO_IMAGE_KHR) { 776 // NOTE: if dpy was invalid, createImage() is guaranteed to 777 // fail. so we'd end up here. 778 return -EINVAL; 779 } 780 } 781 782 GLint error; 783 while ((error = glGetError()) != GL_NO_ERROR) { 784 ST_LOGW("updateTexImage: clearing GL error: %#04x", error); 785 } 786 787 glBindTexture(mTexTarget, mTexName); 788 glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image); 789 790 bool failed = false; 791 while ((error = glGetError()) != GL_NO_ERROR) { 792 ST_LOGE("error binding external texture image %p (slot %d): %#04x", 793 image, buf, error); 794 failed = true; 795 } 796 if (failed) { 797 return -EINVAL; 798 } 799 800 if (mCurrentTexture != INVALID_BUFFER_SLOT) { 801 if (mUseFenceSync) { 802 EGLSyncKHR fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, 803 NULL); 804 if (fence == EGL_NO_SYNC_KHR) { 805 LOGE("updateTexImage: error creating fence: %#x", 806 eglGetError()); 807 return -EINVAL; 808 } 809 glFlush(); 810 mSlots[mCurrentTexture].mFence = fence; 811 } 812 } 813 814 ST_LOGV("updateTexImage: (slot=%d buf=%p) -> (slot=%d buf=%p)", 815 mCurrentTexture, 816 mCurrentTextureBuf != NULL ? mCurrentTextureBuf->handle : 0, 817 buf, mSlots[buf].mGraphicBuffer->handle); 818 819 if (mCurrentTexture != INVALID_BUFFER_SLOT) { 820 // The current buffer becomes FREE if it was still in the queued 821 // state. If it has already been given to the client 822 // (synchronous mode), then it stays in DEQUEUED state. 823 if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED) { 824 mSlots[mCurrentTexture].mBufferState = BufferSlot::FREE; 825 } 826 } 827 828 // Update the SurfaceTexture state. 829 mCurrentTexture = buf; 830 mCurrentTextureBuf = mSlots[buf].mGraphicBuffer; 831 mCurrentCrop = mSlots[buf].mCrop; 832 mCurrentTransform = mSlots[buf].mTransform; 833 mCurrentScalingMode = mSlots[buf].mScalingMode; 834 mCurrentTimestamp = mSlots[buf].mTimestamp; 835 computeCurrentTransformMatrix(); 836 837 // Now that we've passed the point at which failures can happen, 838 // it's safe to remove the buffer from the front of the queue. 839 mQueue.erase(front); 840 mDequeueCondition.signal(); 841 } else { 842 // We always bind the texture even if we don't update its contents. 843 glBindTexture(mTexTarget, mTexName); 844 } 845 846 return OK; 847 } 848 849 bool SurfaceTexture::isExternalFormat(uint32_t format) 850 { 851 switch (format) { 852 // supported YUV formats 853 case HAL_PIXEL_FORMAT_YV12: 854 // Legacy/deprecated YUV formats 855 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 856 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 857 case HAL_PIXEL_FORMAT_YCbCr_422_I: 858 return true; 859 } 860 861 // Any OEM format needs to be considered 862 if (format>=0x100 && format<=0x1FF) 863 return true; 864 865 return false; 866 } 867 868 GLenum SurfaceTexture::getCurrentTextureTarget() const { 869 return mTexTarget; 870 } 871 872 void SurfaceTexture::getTransformMatrix(float mtx[16]) { 873 Mutex::Autolock lock(mMutex); 874 memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); 875 } 876 877 void SurfaceTexture::computeCurrentTransformMatrix() { 878 ST_LOGV("computeCurrentTransformMatrix"); 879 880 float xform[16]; 881 for (int i = 0; i < 16; i++) { 882 xform[i] = mtxIdentity[i]; 883 } 884 if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { 885 float result[16]; 886 mtxMul(result, xform, mtxFlipH); 887 for (int i = 0; i < 16; i++) { 888 xform[i] = result[i]; 889 } 890 } 891 if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { 892 float result[16]; 893 mtxMul(result, xform, mtxFlipV); 894 for (int i = 0; i < 16; i++) { 895 xform[i] = result[i]; 896 } 897 } 898 if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 899 float result[16]; 900 mtxMul(result, xform, mtxRot90); 901 for (int i = 0; i < 16; i++) { 902 xform[i] = result[i]; 903 } 904 } 905 906 sp<GraphicBuffer>& buf(mSlots[mCurrentTexture].mGraphicBuffer); 907 float tx, ty, sx, sy; 908 if (!mCurrentCrop.isEmpty()) { 909 // In order to prevent bilinear sampling at the of the crop rectangle we 910 // may need to shrink it by 2 texels in each direction. Normally this 911 // would just need to take 1/2 a texel off each end, but because the 912 // chroma channels will likely be subsampled we need to chop off a whole 913 // texel. This will cause artifacts if someone does nearest sampling 914 // with 1:1 pixel:texel ratio, but it's impossible to simultaneously 915 // accomodate the bilinear and nearest sampling uses. 916 // 917 // If nearest sampling turns out to be a desirable usage of these 918 // textures then we could add the ability to switch a SurfaceTexture to 919 // nearest-mode. Preferably, however, the image producers (video 920 // decoder, camera, etc.) would simply not use a crop rectangle (or at 921 // least not tell the framework about it) so that the GPU can do the 922 // correct edge behavior. 923 int xshrink = 0, yshrink = 0; 924 if (mCurrentCrop.left > 0) { 925 tx = float(mCurrentCrop.left + 1) / float(buf->getWidth()); 926 xshrink++; 927 } else { 928 tx = 0.0f; 929 } 930 if (mCurrentCrop.right < int32_t(buf->getWidth())) { 931 xshrink++; 932 } 933 if (mCurrentCrop.bottom < int32_t(buf->getHeight())) { 934 ty = (float(buf->getHeight() - mCurrentCrop.bottom) + 1.0f) / 935 float(buf->getHeight()); 936 yshrink++; 937 } else { 938 ty = 0.0f; 939 } 940 if (mCurrentCrop.top > 0) { 941 yshrink++; 942 } 943 sx = float(mCurrentCrop.width() - xshrink) / float(buf->getWidth()); 944 sy = float(mCurrentCrop.height() - yshrink) / float(buf->getHeight()); 945 } else { 946 tx = 0.0f; 947 ty = 0.0f; 948 sx = 1.0f; 949 sy = 1.0f; 950 } 951 float crop[16] = { 952 sx, 0, 0, 0, 953 0, sy, 0, 0, 954 0, 0, 1, 0, 955 tx, ty, 0, 1, 956 }; 957 958 float mtxBeforeFlipV[16]; 959 mtxMul(mtxBeforeFlipV, crop, xform); 960 961 // SurfaceFlinger expects the top of its window textures to be at a Y 962 // coordinate of 0, so SurfaceTexture must behave the same way. We don't 963 // want to expose this to applications, however, so we must add an 964 // additional vertical flip to the transform after all the other transforms. 965 mtxMul(mCurrentTransformMatrix, mtxFlipV, mtxBeforeFlipV); 966 } 967 968 nsecs_t SurfaceTexture::getTimestamp() { 969 ST_LOGV("getTimestamp"); 970 Mutex::Autolock lock(mMutex); 971 return mCurrentTimestamp; 972 } 973 974 void SurfaceTexture::setFrameAvailableListener( 975 const sp<FrameAvailableListener>& listener) { 976 ST_LOGV("setFrameAvailableListener"); 977 Mutex::Autolock lock(mMutex); 978 mFrameAvailableListener = listener; 979 } 980 981 void SurfaceTexture::freeBufferLocked(int i) { 982 mSlots[i].mGraphicBuffer = 0; 983 mSlots[i].mBufferState = BufferSlot::FREE; 984 mSlots[i].mFrameNumber = 0; 985 if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) { 986 eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage); 987 mSlots[i].mEglImage = EGL_NO_IMAGE_KHR; 988 mSlots[i].mEglDisplay = EGL_NO_DISPLAY; 989 } 990 } 991 992 void SurfaceTexture::freeAllBuffersLocked() { 993 LOGW_IF(!mQueue.isEmpty(), 994 "freeAllBuffersLocked called but mQueue is not empty"); 995 mCurrentTexture = INVALID_BUFFER_SLOT; 996 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 997 freeBufferLocked(i); 998 } 999 } 1000 1001 void SurfaceTexture::freeAllBuffersExceptHeadLocked() { 1002 LOGW_IF(!mQueue.isEmpty(), 1003 "freeAllBuffersExceptCurrentLocked called but mQueue is not empty"); 1004 int head = -1; 1005 if (!mQueue.empty()) { 1006 Fifo::iterator front(mQueue.begin()); 1007 head = *front; 1008 } 1009 mCurrentTexture = INVALID_BUFFER_SLOT; 1010 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 1011 if (i != head) { 1012 freeBufferLocked(i); 1013 } 1014 } 1015 } 1016 1017 status_t SurfaceTexture::drainQueueLocked() { 1018 while (mSynchronousMode && !mQueue.isEmpty()) { 1019 mDequeueCondition.wait(mMutex); 1020 if (mAbandoned) { 1021 ST_LOGE("drainQueueLocked: SurfaceTexture has been abandoned!"); 1022 return NO_INIT; 1023 } 1024 if (mConnectedApi == NO_CONNECTED_API) { 1025 ST_LOGE("drainQueueLocked: SurfaceTexture is not connected!"); 1026 return NO_INIT; 1027 } 1028 } 1029 return NO_ERROR; 1030 } 1031 1032 status_t SurfaceTexture::drainQueueAndFreeBuffersLocked() { 1033 status_t err = drainQueueLocked(); 1034 if (err == NO_ERROR) { 1035 if (mSynchronousMode) { 1036 freeAllBuffersLocked(); 1037 } else { 1038 freeAllBuffersExceptHeadLocked(); 1039 } 1040 } 1041 return err; 1042 } 1043 1044 EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy, 1045 const sp<GraphicBuffer>& graphicBuffer) { 1046 EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer(); 1047 EGLint attrs[] = { 1048 EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, 1049 EGL_NONE, 1050 }; 1051 EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 1052 EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); 1053 if (image == EGL_NO_IMAGE_KHR) { 1054 EGLint error = eglGetError(); 1055 ST_LOGE("error creating EGLImage: %#x", error); 1056 } 1057 return image; 1058 } 1059 1060 sp<GraphicBuffer> SurfaceTexture::getCurrentBuffer() const { 1061 Mutex::Autolock lock(mMutex); 1062 return mCurrentTextureBuf; 1063 } 1064 1065 Rect SurfaceTexture::getCurrentCrop() const { 1066 Mutex::Autolock lock(mMutex); 1067 return mCurrentCrop; 1068 } 1069 1070 uint32_t SurfaceTexture::getCurrentTransform() const { 1071 Mutex::Autolock lock(mMutex); 1072 return mCurrentTransform; 1073 } 1074 1075 uint32_t SurfaceTexture::getCurrentScalingMode() const { 1076 Mutex::Autolock lock(mMutex); 1077 return mCurrentScalingMode; 1078 } 1079 1080 bool SurfaceTexture::isSynchronousMode() const { 1081 Mutex::Autolock lock(mMutex); 1082 return mSynchronousMode; 1083 } 1084 1085 int SurfaceTexture::query(int what, int* outValue) 1086 { 1087 Mutex::Autolock lock(mMutex); 1088 1089 if (mAbandoned) { 1090 ST_LOGE("query: SurfaceTexture has been abandoned!"); 1091 return NO_INIT; 1092 } 1093 1094 int value; 1095 switch (what) { 1096 case NATIVE_WINDOW_WIDTH: 1097 value = mDefaultWidth; 1098 break; 1099 case NATIVE_WINDOW_HEIGHT: 1100 value = mDefaultHeight; 1101 break; 1102 case NATIVE_WINDOW_FORMAT: 1103 value = mPixelFormat; 1104 break; 1105 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 1106 value = mSynchronousMode ? 1107 (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS; 1108 break; 1109 default: 1110 return BAD_VALUE; 1111 } 1112 outValue[0] = value; 1113 return NO_ERROR; 1114 } 1115 1116 void SurfaceTexture::abandon() { 1117 Mutex::Autolock lock(mMutex); 1118 mQueue.clear(); 1119 mAbandoned = true; 1120 mCurrentTextureBuf.clear(); 1121 freeAllBuffersLocked(); 1122 mDequeueCondition.signal(); 1123 } 1124 1125 void SurfaceTexture::setName(const String8& name) { 1126 mName = name; 1127 } 1128 1129 void SurfaceTexture::dump(String8& result) const 1130 { 1131 char buffer[1024]; 1132 dump(result, "", buffer, 1024); 1133 } 1134 1135 void SurfaceTexture::dump(String8& result, const char* prefix, 1136 char* buffer, size_t SIZE) const 1137 { 1138 Mutex::Autolock _l(mMutex); 1139 snprintf(buffer, SIZE, 1140 "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], " 1141 "mPixelFormat=%d, mTexName=%d\n", 1142 prefix, mBufferCount, mSynchronousMode, mDefaultWidth, 1143 mDefaultHeight, mPixelFormat, mTexName); 1144 result.append(buffer); 1145 1146 String8 fifo; 1147 int fifoSize = 0; 1148 Fifo::const_iterator i(mQueue.begin()); 1149 while (i != mQueue.end()) { 1150 snprintf(buffer, SIZE, "%02d ", *i++); 1151 fifoSize++; 1152 fifo.append(buffer); 1153 } 1154 1155 snprintf(buffer, SIZE, 1156 "%scurrent: {crop=[%d,%d,%d,%d], transform=0x%02x, current=%d}\n" 1157 "%snext : {crop=[%d,%d,%d,%d], transform=0x%02x, FIFO(%d)={%s}}\n" 1158 , 1159 prefix, mCurrentCrop.left, 1160 mCurrentCrop.top, mCurrentCrop.right, mCurrentCrop.bottom, 1161 mCurrentTransform, mCurrentTexture, 1162 prefix, mNextCrop.left, mNextCrop.top, mNextCrop.right, 1163 mNextCrop.bottom, mNextTransform, fifoSize, fifo.string() 1164 ); 1165 result.append(buffer); 1166 1167 struct { 1168 const char * operator()(int state) const { 1169 switch (state) { 1170 case BufferSlot::DEQUEUED: return "DEQUEUED"; 1171 case BufferSlot::QUEUED: return "QUEUED"; 1172 case BufferSlot::FREE: return "FREE"; 1173 default: return "Unknown"; 1174 } 1175 } 1176 } stateName; 1177 1178 for (int i=0 ; i<mBufferCount ; i++) { 1179 const BufferSlot& slot(mSlots[i]); 1180 snprintf(buffer, SIZE, 1181 "%s%s[%02d] " 1182 "state=%-8s, crop=[%d,%d,%d,%d], " 1183 "transform=0x%02x, timestamp=%lld", 1184 prefix, (i==mCurrentTexture)?">":" ", i, 1185 stateName(slot.mBufferState), 1186 slot.mCrop.left, slot.mCrop.top, slot.mCrop.right, 1187 slot.mCrop.bottom, slot.mTransform, slot.mTimestamp 1188 ); 1189 result.append(buffer); 1190 1191 const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 1192 if (buf != NULL) { 1193 snprintf(buffer, SIZE, 1194 ", %p [%4ux%4u:%4u,%3X]", 1195 buf->handle, buf->width, buf->height, buf->stride, 1196 buf->format); 1197 result.append(buffer); 1198 } 1199 result.append("\n"); 1200 } 1201 } 1202 1203 static void mtxMul(float out[16], const float a[16], const float b[16]) { 1204 out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3]; 1205 out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3]; 1206 out[2] = a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3]; 1207 out[3] = a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3]; 1208 1209 out[4] = a[0]*b[4] + a[4]*b[5] + a[8]*b[6] + a[12]*b[7]; 1210 out[5] = a[1]*b[4] + a[5]*b[5] + a[9]*b[6] + a[13]*b[7]; 1211 out[6] = a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7]; 1212 out[7] = a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7]; 1213 1214 out[8] = a[0]*b[8] + a[4]*b[9] + a[8]*b[10] + a[12]*b[11]; 1215 out[9] = a[1]*b[8] + a[5]*b[9] + a[9]*b[10] + a[13]*b[11]; 1216 out[10] = a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11]; 1217 out[11] = a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11]; 1218 1219 out[12] = a[0]*b[12] + a[4]*b[13] + a[8]*b[14] + a[12]*b[15]; 1220 out[13] = a[1]*b[12] + a[5]*b[13] + a[9]*b[14] + a[13]*b[15]; 1221 out[14] = a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15]; 1222 out[15] = a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15]; 1223 } 1224 1225 }; // namespace android 1226