Home | History | Annotate | Download | only in gui
      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 "Surface"
     18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
     19 //#define LOG_NDEBUG 0
     20 
     21 #include <android/native_window.h>
     22 
     23 #include <binder/Parcel.h>
     24 
     25 #include <utils/Log.h>
     26 #include <utils/Trace.h>
     27 
     28 #include <ui/Fence.h>
     29 
     30 #include <gui/ISurfaceComposer.h>
     31 #include <gui/SurfaceComposerClient.h>
     32 #include <gui/GLConsumer.h>
     33 #include <gui/Surface.h>
     34 
     35 #include <private/gui/ComposerService.h>
     36 
     37 namespace android {
     38 
     39 Surface::Surface(
     40         const sp<IGraphicBufferProducer>& bufferProducer)
     41     : mGraphicBufferProducer(bufferProducer)
     42 {
     43     // Initialize the ANativeWindow function pointers.
     44     ANativeWindow::setSwapInterval  = hook_setSwapInterval;
     45     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
     46     ANativeWindow::cancelBuffer     = hook_cancelBuffer;
     47     ANativeWindow::queueBuffer      = hook_queueBuffer;
     48     ANativeWindow::query            = hook_query;
     49     ANativeWindow::perform          = hook_perform;
     50 
     51     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
     52     ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
     53     ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
     54     ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;
     55 
     56     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
     57     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
     58 
     59     mReqWidth = 0;
     60     mReqHeight = 0;
     61     mReqFormat = 0;
     62     mReqUsage = 0;
     63     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
     64     mCrop.clear();
     65     mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
     66     mTransform = 0;
     67     mDefaultWidth = 0;
     68     mDefaultHeight = 0;
     69     mUserWidth = 0;
     70     mUserHeight = 0;
     71     mTransformHint = 0;
     72     mConsumerRunningBehind = false;
     73     mConnectedToCpu = false;
     74 }
     75 
     76 Surface::~Surface() {
     77     if (mConnectedToCpu) {
     78         Surface::disconnect(NATIVE_WINDOW_API_CPU);
     79     }
     80 }
     81 
     82 sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
     83     return mGraphicBufferProducer;
     84 }
     85 
     86 int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
     87     Surface* c = getSelf(window);
     88     return c->setSwapInterval(interval);
     89 }
     90 
     91 int Surface::hook_dequeueBuffer(ANativeWindow* window,
     92         ANativeWindowBuffer** buffer, int* fenceFd) {
     93     Surface* c = getSelf(window);
     94     return c->dequeueBuffer(buffer, fenceFd);
     95 }
     96 
     97 int Surface::hook_cancelBuffer(ANativeWindow* window,
     98         ANativeWindowBuffer* buffer, int fenceFd) {
     99     Surface* c = getSelf(window);
    100     return c->cancelBuffer(buffer, fenceFd);
    101 }
    102 
    103 int Surface::hook_queueBuffer(ANativeWindow* window,
    104         ANativeWindowBuffer* buffer, int fenceFd) {
    105     Surface* c = getSelf(window);
    106     return c->queueBuffer(buffer, fenceFd);
    107 }
    108 
    109 int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
    110         ANativeWindowBuffer** buffer) {
    111     Surface* c = getSelf(window);
    112     ANativeWindowBuffer* buf;
    113     int fenceFd = -1;
    114     int result = c->dequeueBuffer(&buf, &fenceFd);
    115     sp<Fence> fence(new Fence(fenceFd));
    116     int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
    117     if (waitResult != OK) {
    118         ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
    119                 waitResult);
    120         c->cancelBuffer(buf, -1);
    121         return waitResult;
    122     }
    123     *buffer = buf;
    124     return result;
    125 }
    126 
    127 int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
    128         ANativeWindowBuffer* buffer) {
    129     Surface* c = getSelf(window);
    130     return c->cancelBuffer(buffer, -1);
    131 }
    132 
    133 int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
    134         ANativeWindowBuffer* buffer) {
    135     Surface* c = getSelf(window);
    136     return c->lockBuffer_DEPRECATED(buffer);
    137 }
    138 
    139 int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
    140         ANativeWindowBuffer* buffer) {
    141     Surface* c = getSelf(window);
    142     return c->queueBuffer(buffer, -1);
    143 }
    144 
    145 int Surface::hook_query(const ANativeWindow* window,
    146                                 int what, int* value) {
    147     const Surface* c = getSelf(window);
    148     return c->query(what, value);
    149 }
    150 
    151 int Surface::hook_perform(ANativeWindow* window, int operation, ...) {
    152     va_list args;
    153     va_start(args, operation);
    154     Surface* c = getSelf(window);
    155     return c->perform(operation, args);
    156 }
    157 
    158 int Surface::setSwapInterval(int interval) {
    159     ATRACE_CALL();
    160     // EGL specification states:
    161     //  interval is silently clamped to minimum and maximum implementation
    162     //  dependent values before being stored.
    163     // Although we don't have to, we apply the same logic here.
    164 
    165     if (interval < minSwapInterval)
    166         interval = minSwapInterval;
    167 
    168     if (interval > maxSwapInterval)
    169         interval = maxSwapInterval;
    170 
    171     status_t res = mGraphicBufferProducer->setSynchronousMode(interval ? true : false);
    172 
    173     return res;
    174 }
    175 
    176 int Surface::dequeueBuffer(android_native_buffer_t** buffer,
    177         int* fenceFd) {
    178     ATRACE_CALL();
    179     ALOGV("Surface::dequeueBuffer");
    180     Mutex::Autolock lock(mMutex);
    181     int buf = -1;
    182     int reqW = mReqWidth ? mReqWidth : mUserWidth;
    183     int reqH = mReqHeight ? mReqHeight : mUserHeight;
    184     sp<Fence> fence;
    185     status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
    186             reqW, reqH, mReqFormat, mReqUsage);
    187     if (result < 0) {
    188         ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d)"
    189              "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
    190              result);
    191         return result;
    192     }
    193     sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
    194     if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
    195         freeAllBuffers();
    196     }
    197 
    198     if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
    199         result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
    200         if (result != NO_ERROR) {
    201             ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d",
    202                     result);
    203             return result;
    204         }
    205     }
    206 
    207     if (fence->isValid()) {
    208         *fenceFd = fence->dup();
    209         if (*fenceFd == -1) {
    210             ALOGE("dequeueBuffer: error duping fence: %d", errno);
    211             // dup() should never fail; something is badly wrong. Soldier on
    212             // and hope for the best; the worst that should happen is some
    213             // visible corruption that lasts until the next frame.
    214         }
    215     } else {
    216         *fenceFd = -1;
    217     }
    218 
    219     *buffer = gbuf.get();
    220     return OK;
    221 }
    222 
    223 int Surface::cancelBuffer(android_native_buffer_t* buffer,
    224         int fenceFd) {
    225     ATRACE_CALL();
    226     ALOGV("Surface::cancelBuffer");
    227     Mutex::Autolock lock(mMutex);
    228     int i = getSlotFromBufferLocked(buffer);
    229     if (i < 0) {
    230         return i;
    231     }
    232     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
    233     mGraphicBufferProducer->cancelBuffer(i, fence);
    234     return OK;
    235 }
    236 
    237 int Surface::getSlotFromBufferLocked(
    238         android_native_buffer_t* buffer) const {
    239     bool dumpedState = false;
    240     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    241         if (mSlots[i].buffer != NULL &&
    242                 mSlots[i].buffer->handle == buffer->handle) {
    243             return i;
    244         }
    245     }
    246     ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
    247     return BAD_VALUE;
    248 }
    249 
    250 int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) {
    251     ALOGV("Surface::lockBuffer");
    252     Mutex::Autolock lock(mMutex);
    253     return OK;
    254 }
    255 
    256 int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    257     ATRACE_CALL();
    258     ALOGV("Surface::queueBuffer");
    259     Mutex::Autolock lock(mMutex);
    260     int64_t timestamp;
    261     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
    262         timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
    263         ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
    264              timestamp / 1000000.f);
    265     } else {
    266         timestamp = mTimestamp;
    267     }
    268     int i = getSlotFromBufferLocked(buffer);
    269     if (i < 0) {
    270         return i;
    271     }
    272 
    273 
    274     // Make sure the crop rectangle is entirely inside the buffer.
    275     Rect crop;
    276     mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
    277 
    278     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
    279     IGraphicBufferProducer::QueueBufferOutput output;
    280     IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode,
    281             mTransform, fence);
    282     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
    283     if (err != OK)  {
    284         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
    285     }
    286     uint32_t numPendingBuffers = 0;
    287     output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
    288             &numPendingBuffers);
    289 
    290     mConsumerRunningBehind = (numPendingBuffers >= 2);
    291 
    292     return err;
    293 }
    294 
    295 int Surface::query(int what, int* value) const {
    296     ATRACE_CALL();
    297     ALOGV("Surface::query");
    298     { // scope for the lock
    299         Mutex::Autolock lock(mMutex);
    300         switch (what) {
    301             case NATIVE_WINDOW_FORMAT:
    302                 if (mReqFormat) {
    303                     *value = mReqFormat;
    304                     return NO_ERROR;
    305                 }
    306                 break;
    307             case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
    308                 sp<ISurfaceComposer> composer(
    309                         ComposerService::getComposerService());
    310                 if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
    311                     *value = 1;
    312                 } else {
    313                     *value = 0;
    314                 }
    315                 return NO_ERROR;
    316             }
    317             case NATIVE_WINDOW_CONCRETE_TYPE:
    318                 *value = NATIVE_WINDOW_SURFACE;
    319                 return NO_ERROR;
    320             case NATIVE_WINDOW_DEFAULT_WIDTH:
    321                 *value = mUserWidth ? mUserWidth : mDefaultWidth;
    322                 return NO_ERROR;
    323             case NATIVE_WINDOW_DEFAULT_HEIGHT:
    324                 *value = mUserHeight ? mUserHeight : mDefaultHeight;
    325                 return NO_ERROR;
    326             case NATIVE_WINDOW_TRANSFORM_HINT:
    327                 *value = mTransformHint;
    328                 return NO_ERROR;
    329             case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
    330                 status_t err = NO_ERROR;
    331                 if (!mConsumerRunningBehind) {
    332                     *value = 0;
    333                 } else {
    334                     err = mGraphicBufferProducer->query(what, value);
    335                     if (err == NO_ERROR) {
    336                         mConsumerRunningBehind = *value;
    337                     }
    338                 }
    339                 return err;
    340             }
    341         }
    342     }
    343     return mGraphicBufferProducer->query(what, value);
    344 }
    345 
    346 int Surface::perform(int operation, va_list args)
    347 {
    348     int res = NO_ERROR;
    349     switch (operation) {
    350     case NATIVE_WINDOW_CONNECT:
    351         // deprecated. must return NO_ERROR.
    352         break;
    353     case NATIVE_WINDOW_DISCONNECT:
    354         // deprecated. must return NO_ERROR.
    355         break;
    356     case NATIVE_WINDOW_SET_USAGE:
    357         res = dispatchSetUsage(args);
    358         break;
    359     case NATIVE_WINDOW_SET_CROP:
    360         res = dispatchSetCrop(args);
    361         break;
    362     case NATIVE_WINDOW_SET_BUFFER_COUNT:
    363         res = dispatchSetBufferCount(args);
    364         break;
    365     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
    366         res = dispatchSetBuffersGeometry(args);
    367         break;
    368     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
    369         res = dispatchSetBuffersTransform(args);
    370         break;
    371     case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
    372         res = dispatchSetBuffersTimestamp(args);
    373         break;
    374     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
    375         res = dispatchSetBuffersDimensions(args);
    376         break;
    377     case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
    378         res = dispatchSetBuffersUserDimensions(args);
    379         break;
    380     case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
    381         res = dispatchSetBuffersFormat(args);
    382         break;
    383     case NATIVE_WINDOW_LOCK:
    384         res = dispatchLock(args);
    385         break;
    386     case NATIVE_WINDOW_UNLOCK_AND_POST:
    387         res = dispatchUnlockAndPost(args);
    388         break;
    389     case NATIVE_WINDOW_SET_SCALING_MODE:
    390         res = dispatchSetScalingMode(args);
    391         break;
    392     case NATIVE_WINDOW_API_CONNECT:
    393         res = dispatchConnect(args);
    394         break;
    395     case NATIVE_WINDOW_API_DISCONNECT:
    396         res = dispatchDisconnect(args);
    397         break;
    398     default:
    399         res = NAME_NOT_FOUND;
    400         break;
    401     }
    402     return res;
    403 }
    404 
    405 int Surface::dispatchConnect(va_list args) {
    406     int api = va_arg(args, int);
    407     return connect(api);
    408 }
    409 
    410 int Surface::dispatchDisconnect(va_list args) {
    411     int api = va_arg(args, int);
    412     return disconnect(api);
    413 }
    414 
    415 int Surface::dispatchSetUsage(va_list args) {
    416     int usage = va_arg(args, int);
    417     return setUsage(usage);
    418 }
    419 
    420 int Surface::dispatchSetCrop(va_list args) {
    421     android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
    422     return setCrop(reinterpret_cast<Rect const*>(rect));
    423 }
    424 
    425 int Surface::dispatchSetBufferCount(va_list args) {
    426     size_t bufferCount = va_arg(args, size_t);
    427     return setBufferCount(bufferCount);
    428 }
    429 
    430 int Surface::dispatchSetBuffersGeometry(va_list args) {
    431     int w = va_arg(args, int);
    432     int h = va_arg(args, int);
    433     int f = va_arg(args, int);
    434     int err = setBuffersDimensions(w, h);
    435     if (err != 0) {
    436         return err;
    437     }
    438     return setBuffersFormat(f);
    439 }
    440 
    441 int Surface::dispatchSetBuffersDimensions(va_list args) {
    442     int w = va_arg(args, int);
    443     int h = va_arg(args, int);
    444     return setBuffersDimensions(w, h);
    445 }
    446 
    447 int Surface::dispatchSetBuffersUserDimensions(va_list args) {
    448     int w = va_arg(args, int);
    449     int h = va_arg(args, int);
    450     return setBuffersUserDimensions(w, h);
    451 }
    452 
    453 int Surface::dispatchSetBuffersFormat(va_list args) {
    454     int f = va_arg(args, int);
    455     return setBuffersFormat(f);
    456 }
    457 
    458 int Surface::dispatchSetScalingMode(va_list args) {
    459     int m = va_arg(args, int);
    460     return setScalingMode(m);
    461 }
    462 
    463 int Surface::dispatchSetBuffersTransform(va_list args) {
    464     int transform = va_arg(args, int);
    465     return setBuffersTransform(transform);
    466 }
    467 
    468 int Surface::dispatchSetBuffersTimestamp(va_list args) {
    469     int64_t timestamp = va_arg(args, int64_t);
    470     return setBuffersTimestamp(timestamp);
    471 }
    472 
    473 int Surface::dispatchLock(va_list args) {
    474     ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
    475     ARect* inOutDirtyBounds = va_arg(args, ARect*);
    476     return lock(outBuffer, inOutDirtyBounds);
    477 }
    478 
    479 int Surface::dispatchUnlockAndPost(va_list args) {
    480     return unlockAndPost();
    481 }
    482 
    483 
    484 int Surface::connect(int api) {
    485     ATRACE_CALL();
    486     ALOGV("Surface::connect");
    487     Mutex::Autolock lock(mMutex);
    488     IGraphicBufferProducer::QueueBufferOutput output;
    489     int err = mGraphicBufferProducer->connect(api, &output);
    490     if (err == NO_ERROR) {
    491         uint32_t numPendingBuffers = 0;
    492         output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
    493                 &numPendingBuffers);
    494         mConsumerRunningBehind = (numPendingBuffers >= 2);
    495     }
    496     if (!err && api == NATIVE_WINDOW_API_CPU) {
    497         mConnectedToCpu = true;
    498     }
    499     return err;
    500 }
    501 
    502 int Surface::disconnect(int api) {
    503     ATRACE_CALL();
    504     ALOGV("Surface::disconnect");
    505     Mutex::Autolock lock(mMutex);
    506     freeAllBuffers();
    507     int err = mGraphicBufferProducer->disconnect(api);
    508     if (!err) {
    509         mReqFormat = 0;
    510         mReqWidth = 0;
    511         mReqHeight = 0;
    512         mReqUsage = 0;
    513         mCrop.clear();
    514         mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
    515         mTransform = 0;
    516         if (api == NATIVE_WINDOW_API_CPU) {
    517             mConnectedToCpu = false;
    518         }
    519     }
    520     return err;
    521 }
    522 
    523 int Surface::setUsage(uint32_t reqUsage)
    524 {
    525     ALOGV("Surface::setUsage");
    526     Mutex::Autolock lock(mMutex);
    527     mReqUsage = reqUsage;
    528     return OK;
    529 }
    530 
    531 int Surface::setCrop(Rect const* rect)
    532 {
    533     ATRACE_CALL();
    534 
    535     Rect realRect;
    536     if (rect == NULL || rect->isEmpty()) {
    537         realRect.clear();
    538     } else {
    539         realRect = *rect;
    540     }
    541 
    542     ALOGV("Surface::setCrop rect=[%d %d %d %d]",
    543             realRect.left, realRect.top, realRect.right, realRect.bottom);
    544 
    545     Mutex::Autolock lock(mMutex);
    546     mCrop = realRect;
    547     return NO_ERROR;
    548 }
    549 
    550 int Surface::setBufferCount(int bufferCount)
    551 {
    552     ATRACE_CALL();
    553     ALOGV("Surface::setBufferCount");
    554     Mutex::Autolock lock(mMutex);
    555 
    556     status_t err = mGraphicBufferProducer->setBufferCount(bufferCount);
    557     ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
    558             bufferCount, strerror(-err));
    559 
    560     if (err == NO_ERROR) {
    561         freeAllBuffers();
    562     }
    563 
    564     return err;
    565 }
    566 
    567 int Surface::setBuffersDimensions(int w, int h)
    568 {
    569     ATRACE_CALL();
    570     ALOGV("Surface::setBuffersDimensions");
    571 
    572     if (w<0 || h<0)
    573         return BAD_VALUE;
    574 
    575     if ((w && !h) || (!w && h))
    576         return BAD_VALUE;
    577 
    578     Mutex::Autolock lock(mMutex);
    579     mReqWidth = w;
    580     mReqHeight = h;
    581     return NO_ERROR;
    582 }
    583 
    584 int Surface::setBuffersUserDimensions(int w, int h)
    585 {
    586     ATRACE_CALL();
    587     ALOGV("Surface::setBuffersUserDimensions");
    588 
    589     if (w<0 || h<0)
    590         return BAD_VALUE;
    591 
    592     if ((w && !h) || (!w && h))
    593         return BAD_VALUE;
    594 
    595     Mutex::Autolock lock(mMutex);
    596     mUserWidth = w;
    597     mUserHeight = h;
    598     return NO_ERROR;
    599 }
    600 
    601 int Surface::setBuffersFormat(int format)
    602 {
    603     ALOGV("Surface::setBuffersFormat");
    604 
    605     if (format<0)
    606         return BAD_VALUE;
    607 
    608     Mutex::Autolock lock(mMutex);
    609     mReqFormat = format;
    610     return NO_ERROR;
    611 }
    612 
    613 int Surface::setScalingMode(int mode)
    614 {
    615     ATRACE_CALL();
    616     ALOGV("Surface::setScalingMode(%d)", mode);
    617 
    618     switch (mode) {
    619         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
    620         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
    621         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
    622             break;
    623         default:
    624             ALOGE("unknown scaling mode: %d", mode);
    625             return BAD_VALUE;
    626     }
    627 
    628     Mutex::Autolock lock(mMutex);
    629     mScalingMode = mode;
    630     return NO_ERROR;
    631 }
    632 
    633 int Surface::setBuffersTransform(int transform)
    634 {
    635     ATRACE_CALL();
    636     ALOGV("Surface::setBuffersTransform");
    637     Mutex::Autolock lock(mMutex);
    638     mTransform = transform;
    639     return NO_ERROR;
    640 }
    641 
    642 int Surface::setBuffersTimestamp(int64_t timestamp)
    643 {
    644     ALOGV("Surface::setBuffersTimestamp");
    645     Mutex::Autolock lock(mMutex);
    646     mTimestamp = timestamp;
    647     return NO_ERROR;
    648 }
    649 
    650 void Surface::freeAllBuffers() {
    651     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    652         mSlots[i].buffer = 0;
    653     }
    654 }
    655 
    656 // ----------------------------------------------------------------------
    657 // the lock/unlock APIs must be used from the same thread
    658 
    659 static status_t copyBlt(
    660         const sp<GraphicBuffer>& dst,
    661         const sp<GraphicBuffer>& src,
    662         const Region& reg)
    663 {
    664     // src and dst with, height and format must be identical. no verification
    665     // is done here.
    666     status_t err;
    667     uint8_t const * src_bits = NULL;
    668     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
    669     ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
    670 
    671     uint8_t* dst_bits = NULL;
    672     err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
    673     ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
    674 
    675     Region::const_iterator head(reg.begin());
    676     Region::const_iterator tail(reg.end());
    677     if (head != tail && src_bits && dst_bits) {
    678         const size_t bpp = bytesPerPixel(src->format);
    679         const size_t dbpr = dst->stride * bpp;
    680         const size_t sbpr = src->stride * bpp;
    681 
    682         while (head != tail) {
    683             const Rect& r(*head++);
    684             ssize_t h = r.height();
    685             if (h <= 0) continue;
    686             size_t size = r.width() * bpp;
    687             uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
    688             uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
    689             if (dbpr==sbpr && size==sbpr) {
    690                 size *= h;
    691                 h = 1;
    692             }
    693             do {
    694                 memcpy(d, s, size);
    695                 d += dbpr;
    696                 s += sbpr;
    697             } while (--h > 0);
    698         }
    699     }
    700 
    701     if (src_bits)
    702         src->unlock();
    703 
    704     if (dst_bits)
    705         dst->unlock();
    706 
    707     return err;
    708 }
    709 
    710 // ----------------------------------------------------------------------------
    711 
    712 status_t Surface::lock(
    713         ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
    714 {
    715     if (mLockedBuffer != 0) {
    716         ALOGE("Surface::lock failed, already locked");
    717         return INVALID_OPERATION;
    718     }
    719 
    720     if (!mConnectedToCpu) {
    721         int err = Surface::connect(NATIVE_WINDOW_API_CPU);
    722         if (err) {
    723             return err;
    724         }
    725         // we're intending to do software rendering from this point
    726         setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
    727     }
    728 
    729     ANativeWindowBuffer* out;
    730     int fenceFd = -1;
    731     status_t err = dequeueBuffer(&out, &fenceFd);
    732     ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
    733     if (err == NO_ERROR) {
    734         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
    735         sp<Fence> fence(new Fence(fenceFd));
    736 
    737         err = fence->waitForever("Surface::lock");
    738         if (err != OK) {
    739             ALOGE("Fence::wait failed (%s)", strerror(-err));
    740             cancelBuffer(out, fenceFd);
    741             return err;
    742         }
    743 
    744         const Rect bounds(backBuffer->width, backBuffer->height);
    745 
    746         Region newDirtyRegion;
    747         if (inOutDirtyBounds) {
    748             newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
    749             newDirtyRegion.andSelf(bounds);
    750         } else {
    751             newDirtyRegion.set(bounds);
    752         }
    753 
    754         // figure out if we can copy the frontbuffer back
    755         const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
    756         const bool canCopyBack = (frontBuffer != 0 &&
    757                 backBuffer->width  == frontBuffer->width &&
    758                 backBuffer->height == frontBuffer->height &&
    759                 backBuffer->format == frontBuffer->format);
    760 
    761         if (canCopyBack) {
    762             // copy the area that is invalid and not repainted this round
    763             const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
    764             if (!copyback.isEmpty())
    765                 copyBlt(backBuffer, frontBuffer, copyback);
    766         } else {
    767             // if we can't copy-back anything, modify the user's dirty
    768             // region to make sure they redraw the whole buffer
    769             newDirtyRegion.set(bounds);
    770             mDirtyRegion.clear();
    771             Mutex::Autolock lock(mMutex);
    772             for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
    773                 mSlots[i].dirtyRegion.clear();
    774             }
    775         }
    776 
    777 
    778         { // scope for the lock
    779             Mutex::Autolock lock(mMutex);
    780             int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
    781             if (backBufferSlot >= 0) {
    782                 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
    783                 mDirtyRegion.subtract(dirtyRegion);
    784                 dirtyRegion = newDirtyRegion;
    785             }
    786         }
    787 
    788         mDirtyRegion.orSelf(newDirtyRegion);
    789         if (inOutDirtyBounds) {
    790             *inOutDirtyBounds = newDirtyRegion.getBounds();
    791         }
    792 
    793         void* vaddr;
    794         status_t res = backBuffer->lock(
    795                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
    796                 newDirtyRegion.bounds(), &vaddr);
    797 
    798         ALOGW_IF(res, "failed locking buffer (handle = %p)",
    799                 backBuffer->handle);
    800 
    801         if (res != 0) {
    802             err = INVALID_OPERATION;
    803         } else {
    804             mLockedBuffer = backBuffer;
    805             outBuffer->width  = backBuffer->width;
    806             outBuffer->height = backBuffer->height;
    807             outBuffer->stride = backBuffer->stride;
    808             outBuffer->format = backBuffer->format;
    809             outBuffer->bits   = vaddr;
    810         }
    811     }
    812     return err;
    813 }
    814 
    815 status_t Surface::unlockAndPost()
    816 {
    817     if (mLockedBuffer == 0) {
    818         ALOGE("Surface::unlockAndPost failed, no locked buffer");
    819         return INVALID_OPERATION;
    820     }
    821 
    822     status_t err = mLockedBuffer->unlock();
    823     ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
    824 
    825     err = queueBuffer(mLockedBuffer.get(), -1);
    826     ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
    827             mLockedBuffer->handle, strerror(-err));
    828 
    829     mPostedBuffer = mLockedBuffer;
    830     mLockedBuffer = 0;
    831     return err;
    832 }
    833 
    834 }; // namespace android
    835