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