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 #include <utils/NativeHandle.h>
     28 
     29 #include <ui/Fence.h>
     30 #include <ui/Region.h>
     31 
     32 #include <gui/IProducerListener.h>
     33 #include <gui/ISurfaceComposer.h>
     34 #include <gui/SurfaceComposerClient.h>
     35 #include <gui/GLConsumer.h>
     36 #include <gui/Surface.h>
     37 
     38 #include <private/gui/ComposerService.h>
     39 
     40 namespace android {
     41 
     42 Surface::Surface(
     43         const sp<IGraphicBufferProducer>& bufferProducer,
     44         bool controlledByApp)
     45     : mGraphicBufferProducer(bufferProducer),
     46       mCrop(Rect::EMPTY_RECT),
     47       mGenerationNumber(0),
     48       mSharedBufferMode(false),
     49       mAutoRefresh(false),
     50       mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
     51       mSharedBufferHasBeenQueued(false),
     52       mNextFrameNumber(1)
     53 {
     54     // Initialize the ANativeWindow function pointers.
     55     ANativeWindow::setSwapInterval  = hook_setSwapInterval;
     56     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
     57     ANativeWindow::cancelBuffer     = hook_cancelBuffer;
     58     ANativeWindow::queueBuffer      = hook_queueBuffer;
     59     ANativeWindow::query            = hook_query;
     60     ANativeWindow::perform          = hook_perform;
     61 
     62     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
     63     ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
     64     ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
     65     ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;
     66 
     67     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
     68     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
     69 
     70     mReqWidth = 0;
     71     mReqHeight = 0;
     72     mReqFormat = 0;
     73     mReqUsage = 0;
     74     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
     75     mDataSpace = HAL_DATASPACE_UNKNOWN;
     76     mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
     77     mTransform = 0;
     78     mStickyTransform = 0;
     79     mDefaultWidth = 0;
     80     mDefaultHeight = 0;
     81     mUserWidth = 0;
     82     mUserHeight = 0;
     83     mTransformHint = 0;
     84     mConsumerRunningBehind = false;
     85     mConnectedToCpu = false;
     86     mProducerControlledByApp = controlledByApp;
     87     mSwapIntervalZero = false;
     88 }
     89 
     90 Surface::~Surface() {
     91     if (mConnectedToCpu) {
     92         Surface::disconnect(NATIVE_WINDOW_API_CPU);
     93     }
     94 }
     95 
     96 sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
     97     return mGraphicBufferProducer;
     98 }
     99 
    100 void Surface::setSidebandStream(const sp<NativeHandle>& stream) {
    101     mGraphicBufferProducer->setSidebandStream(stream);
    102 }
    103 
    104 void Surface::allocateBuffers() {
    105     uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
    106     uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
    107     mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight,
    108             mReqFormat, mReqUsage);
    109 }
    110 
    111 status_t Surface::setGenerationNumber(uint32_t generation) {
    112     status_t result = mGraphicBufferProducer->setGenerationNumber(generation);
    113     if (result == NO_ERROR) {
    114         mGenerationNumber = generation;
    115     }
    116     return result;
    117 }
    118 
    119 uint64_t Surface::getNextFrameNumber() const {
    120     Mutex::Autolock lock(mMutex);
    121     return mNextFrameNumber;
    122 }
    123 
    124 String8 Surface::getConsumerName() const {
    125     return mGraphicBufferProducer->getConsumerName();
    126 }
    127 
    128 status_t Surface::setDequeueTimeout(nsecs_t timeout) {
    129     return mGraphicBufferProducer->setDequeueTimeout(timeout);
    130 }
    131 
    132 status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
    133         sp<Fence>* outFence, float outTransformMatrix[16]) {
    134     return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence,
    135             outTransformMatrix);
    136 }
    137 
    138 bool Surface::getFrameTimestamps(uint64_t frameNumber, nsecs_t* outPostedTime,
    139         nsecs_t* outAcquireTime, nsecs_t* outRefreshStartTime,
    140         nsecs_t* outGlCompositionDoneTime, nsecs_t* outDisplayRetireTime,
    141         nsecs_t* outReleaseTime) {
    142     ATRACE_CALL();
    143 
    144     FrameTimestamps timestamps;
    145     bool found = mGraphicBufferProducer->getFrameTimestamps(frameNumber,
    146             &timestamps);
    147     if (found) {
    148         if (outPostedTime) {
    149             *outPostedTime = timestamps.postedTime;
    150         }
    151         if (outAcquireTime) {
    152             *outAcquireTime = timestamps.acquireTime;
    153         }
    154         if (outRefreshStartTime) {
    155             *outRefreshStartTime = timestamps.refreshStartTime;
    156         }
    157         if (outGlCompositionDoneTime) {
    158             *outGlCompositionDoneTime = timestamps.glCompositionDoneTime;
    159         }
    160         if (outDisplayRetireTime) {
    161             *outDisplayRetireTime = timestamps.displayRetireTime;
    162         }
    163         if (outReleaseTime) {
    164             *outReleaseTime = timestamps.releaseTime;
    165         }
    166         return true;
    167     }
    168     return false;
    169 }
    170 
    171 int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
    172     Surface* c = getSelf(window);
    173     return c->setSwapInterval(interval);
    174 }
    175 
    176 int Surface::hook_dequeueBuffer(ANativeWindow* window,
    177         ANativeWindowBuffer** buffer, int* fenceFd) {
    178     Surface* c = getSelf(window);
    179     return c->dequeueBuffer(buffer, fenceFd);
    180 }
    181 
    182 int Surface::hook_cancelBuffer(ANativeWindow* window,
    183         ANativeWindowBuffer* buffer, int fenceFd) {
    184     Surface* c = getSelf(window);
    185     return c->cancelBuffer(buffer, fenceFd);
    186 }
    187 
    188 int Surface::hook_queueBuffer(ANativeWindow* window,
    189         ANativeWindowBuffer* buffer, int fenceFd) {
    190     Surface* c = getSelf(window);
    191     return c->queueBuffer(buffer, fenceFd);
    192 }
    193 
    194 int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
    195         ANativeWindowBuffer** buffer) {
    196     Surface* c = getSelf(window);
    197     ANativeWindowBuffer* buf;
    198     int fenceFd = -1;
    199     int result = c->dequeueBuffer(&buf, &fenceFd);
    200     if (result != OK) {
    201         return result;
    202     }
    203     sp<Fence> fence(new Fence(fenceFd));
    204     int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
    205     if (waitResult != OK) {
    206         ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
    207                 waitResult);
    208         c->cancelBuffer(buf, -1);
    209         return waitResult;
    210     }
    211     *buffer = buf;
    212     return result;
    213 }
    214 
    215 int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
    216         ANativeWindowBuffer* buffer) {
    217     Surface* c = getSelf(window);
    218     return c->cancelBuffer(buffer, -1);
    219 }
    220 
    221 int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
    222         ANativeWindowBuffer* buffer) {
    223     Surface* c = getSelf(window);
    224     return c->lockBuffer_DEPRECATED(buffer);
    225 }
    226 
    227 int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
    228         ANativeWindowBuffer* buffer) {
    229     Surface* c = getSelf(window);
    230     return c->queueBuffer(buffer, -1);
    231 }
    232 
    233 int Surface::hook_query(const ANativeWindow* window,
    234                                 int what, int* value) {
    235     const Surface* c = getSelf(window);
    236     return c->query(what, value);
    237 }
    238 
    239 int Surface::hook_perform(ANativeWindow* window, int operation, ...) {
    240     va_list args;
    241     va_start(args, operation);
    242     Surface* c = getSelf(window);
    243     int result = c->perform(operation, args);
    244     va_end(args);
    245     return result;
    246 }
    247 
    248 int Surface::setSwapInterval(int interval) {
    249     ATRACE_CALL();
    250     // EGL specification states:
    251     //  interval is silently clamped to minimum and maximum implementation
    252     //  dependent values before being stored.
    253 
    254     if (interval < minSwapInterval)
    255         interval = minSwapInterval;
    256 
    257     if (interval > maxSwapInterval)
    258         interval = maxSwapInterval;
    259 
    260     mSwapIntervalZero = (interval == 0);
    261     mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero);
    262 
    263     return NO_ERROR;
    264 }
    265 
    266 int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    267     ATRACE_CALL();
    268     ALOGV("Surface::dequeueBuffer");
    269 
    270     uint32_t reqWidth;
    271     uint32_t reqHeight;
    272     PixelFormat reqFormat;
    273     uint32_t reqUsage;
    274 
    275     {
    276         Mutex::Autolock lock(mMutex);
    277 
    278         reqWidth = mReqWidth ? mReqWidth : mUserWidth;
    279         reqHeight = mReqHeight ? mReqHeight : mUserHeight;
    280 
    281         reqFormat = mReqFormat;
    282         reqUsage = mReqUsage;
    283 
    284         if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot !=
    285                 BufferItem::INVALID_BUFFER_SLOT) {
    286             sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer);
    287             if (gbuf != NULL) {
    288                 *buffer = gbuf.get();
    289                 *fenceFd = -1;
    290                 return OK;
    291             }
    292         }
    293     } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
    294 
    295     int buf = -1;
    296     sp<Fence> fence;
    297     nsecs_t now = systemTime();
    298     status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
    299             reqWidth, reqHeight, reqFormat, reqUsage);
    300     mLastDequeueDuration = systemTime() - now;
    301 
    302     if (result < 0) {
    303         ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer"
    304                 "(%d, %d, %d, %d) failed: %d", reqWidth, reqHeight, reqFormat,
    305                 reqUsage, result);
    306         return result;
    307     }
    308 
    309     Mutex::Autolock lock(mMutex);
    310 
    311     sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
    312 
    313     // this should never happen
    314     ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
    315 
    316     if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
    317         freeAllBuffers();
    318     }
    319 
    320     if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
    321         result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
    322         if (result != NO_ERROR) {
    323             ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
    324             mGraphicBufferProducer->cancelBuffer(buf, fence);
    325             return result;
    326         }
    327     }
    328 
    329     if (fence->isValid()) {
    330         *fenceFd = fence->dup();
    331         if (*fenceFd == -1) {
    332             ALOGE("dequeueBuffer: error duping fence: %d", errno);
    333             // dup() should never fail; something is badly wrong. Soldier on
    334             // and hope for the best; the worst that should happen is some
    335             // visible corruption that lasts until the next frame.
    336         }
    337     } else {
    338         *fenceFd = -1;
    339     }
    340 
    341     *buffer = gbuf.get();
    342 
    343     if (mSharedBufferMode && mAutoRefresh) {
    344         mSharedBufferSlot = buf;
    345         mSharedBufferHasBeenQueued = false;
    346     } else if (mSharedBufferSlot == buf) {
    347         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
    348         mSharedBufferHasBeenQueued = false;
    349     }
    350 
    351     return OK;
    352 }
    353 
    354 int Surface::cancelBuffer(android_native_buffer_t* buffer,
    355         int fenceFd) {
    356     ATRACE_CALL();
    357     ALOGV("Surface::cancelBuffer");
    358     Mutex::Autolock lock(mMutex);
    359     int i = getSlotFromBufferLocked(buffer);
    360     if (i < 0) {
    361         if (fenceFd >= 0) {
    362             close(fenceFd);
    363         }
    364         return i;
    365     }
    366     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
    367         if (fenceFd >= 0) {
    368             close(fenceFd);
    369         }
    370         return OK;
    371     }
    372     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
    373     mGraphicBufferProducer->cancelBuffer(i, fence);
    374 
    375     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
    376         mSharedBufferHasBeenQueued = true;
    377     }
    378 
    379     return OK;
    380 }
    381 
    382 int Surface::getSlotFromBufferLocked(
    383         android_native_buffer_t* buffer) const {
    384     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    385         if (mSlots[i].buffer != NULL &&
    386                 mSlots[i].buffer->handle == buffer->handle) {
    387             return i;
    388         }
    389     }
    390     ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
    391     return BAD_VALUE;
    392 }
    393 
    394 int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) {
    395     ALOGV("Surface::lockBuffer");
    396     Mutex::Autolock lock(mMutex);
    397     return OK;
    398 }
    399 
    400 int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    401     ATRACE_CALL();
    402     ALOGV("Surface::queueBuffer");
    403     Mutex::Autolock lock(mMutex);
    404     int64_t timestamp;
    405     bool isAutoTimestamp = false;
    406 
    407     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
    408         timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
    409         isAutoTimestamp = true;
    410         ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
    411             timestamp / 1000000.f);
    412     } else {
    413         timestamp = mTimestamp;
    414     }
    415     int i = getSlotFromBufferLocked(buffer);
    416     if (i < 0) {
    417         if (fenceFd >= 0) {
    418             close(fenceFd);
    419         }
    420         return i;
    421     }
    422     if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) {
    423         if (fenceFd >= 0) {
    424             close(fenceFd);
    425         }
    426         return OK;
    427     }
    428 
    429 
    430     // Make sure the crop rectangle is entirely inside the buffer.
    431     Rect crop(Rect::EMPTY_RECT);
    432     mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
    433 
    434     sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
    435     IGraphicBufferProducer::QueueBufferOutput output;
    436     IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
    437             mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform,
    438             fence, mStickyTransform);
    439 
    440     if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
    441         input.setSurfaceDamage(Region::INVALID_REGION);
    442     } else {
    443         // Here we do two things:
    444         // 1) The surface damage was specified using the OpenGL ES convention of
    445         //    the origin being in the bottom-left corner. Here we flip to the
    446         //    convention that the rest of the system uses (top-left corner) by
    447         //    subtracting all top/bottom coordinates from the buffer height.
    448         // 2) If the buffer is coming in rotated (for example, because the EGL
    449         //    implementation is reacting to the transform hint coming back from
    450         //    SurfaceFlinger), the surface damage needs to be rotated the
    451         //    opposite direction, since it was generated assuming an unrotated
    452         //    buffer (the app doesn't know that the EGL implementation is
    453         //    reacting to the transform hint behind its back). The
    454         //    transformations in the switch statement below apply those
    455         //    complementary rotations (e.g., if 90 degrees, rotate 270 degrees).
    456 
    457         int width = buffer->width;
    458         int height = buffer->height;
    459         bool rotated90 = (mTransform ^ mStickyTransform) &
    460                 NATIVE_WINDOW_TRANSFORM_ROT_90;
    461         if (rotated90) {
    462             std::swap(width, height);
    463         }
    464 
    465         Region flippedRegion;
    466         for (auto rect : mDirtyRegion) {
    467             int left = rect.left;
    468             int right = rect.right;
    469             int top = height - rect.bottom; // Flip from OpenGL convention
    470             int bottom = height - rect.top; // Flip from OpenGL convention
    471             switch (mTransform ^ mStickyTransform) {
    472                 case NATIVE_WINDOW_TRANSFORM_ROT_90: {
    473                     // Rotate 270 degrees
    474                     Rect flippedRect{top, width - right, bottom, width - left};
    475                     flippedRegion.orSelf(flippedRect);
    476                     break;
    477                 }
    478                 case NATIVE_WINDOW_TRANSFORM_ROT_180: {
    479                     // Rotate 180 degrees
    480                     Rect flippedRect{width - right, height - bottom,
    481                             width - left, height - top};
    482                     flippedRegion.orSelf(flippedRect);
    483                     break;
    484                 }
    485                 case NATIVE_WINDOW_TRANSFORM_ROT_270: {
    486                     // Rotate 90 degrees
    487                     Rect flippedRect{height - bottom, left,
    488                             height - top, right};
    489                     flippedRegion.orSelf(flippedRect);
    490                     break;
    491                 }
    492                 default: {
    493                     Rect flippedRect{left, top, right, bottom};
    494                     flippedRegion.orSelf(flippedRect);
    495                     break;
    496                 }
    497             }
    498         }
    499 
    500         input.setSurfaceDamage(flippedRegion);
    501     }
    502 
    503     nsecs_t now = systemTime();
    504     status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
    505     mLastQueueDuration = systemTime() - now;
    506     if (err != OK)  {
    507         ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
    508     }
    509 
    510     uint32_t numPendingBuffers = 0;
    511     uint32_t hint = 0;
    512     output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
    513             &numPendingBuffers, &mNextFrameNumber);
    514 
    515     // Disable transform hint if sticky transform is set.
    516     if (mStickyTransform == 0) {
    517         mTransformHint = hint;
    518     }
    519 
    520     mConsumerRunningBehind = (numPendingBuffers >= 2);
    521 
    522     if (!mConnectedToCpu) {
    523         // Clear surface damage back to full-buffer
    524         mDirtyRegion = Region::INVALID_REGION;
    525     }
    526 
    527     if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) {
    528         mSharedBufferHasBeenQueued = true;
    529     }
    530 
    531     mQueueBufferCondition.broadcast();
    532 
    533     return err;
    534 }
    535 
    536 int Surface::query(int what, int* value) const {
    537     ATRACE_CALL();
    538     ALOGV("Surface::query");
    539     { // scope for the lock
    540         Mutex::Autolock lock(mMutex);
    541         switch (what) {
    542             case NATIVE_WINDOW_FORMAT:
    543                 if (mReqFormat) {
    544                     *value = static_cast<int>(mReqFormat);
    545                     return NO_ERROR;
    546                 }
    547                 break;
    548             case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
    549                 sp<ISurfaceComposer> composer(
    550                         ComposerService::getComposerService());
    551                 if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
    552                     *value = 1;
    553                 } else {
    554                     *value = 0;
    555                 }
    556                 return NO_ERROR;
    557             }
    558             case NATIVE_WINDOW_CONCRETE_TYPE:
    559                 *value = NATIVE_WINDOW_SURFACE;
    560                 return NO_ERROR;
    561             case NATIVE_WINDOW_DEFAULT_WIDTH:
    562                 *value = static_cast<int>(
    563                         mUserWidth ? mUserWidth : mDefaultWidth);
    564                 return NO_ERROR;
    565             case NATIVE_WINDOW_DEFAULT_HEIGHT:
    566                 *value = static_cast<int>(
    567                         mUserHeight ? mUserHeight : mDefaultHeight);
    568                 return NO_ERROR;
    569             case NATIVE_WINDOW_TRANSFORM_HINT:
    570                 *value = static_cast<int>(mTransformHint);
    571                 return NO_ERROR;
    572             case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
    573                 status_t err = NO_ERROR;
    574                 if (!mConsumerRunningBehind) {
    575                     *value = 0;
    576                 } else {
    577                     err = mGraphicBufferProducer->query(what, value);
    578                     if (err == NO_ERROR) {
    579                         mConsumerRunningBehind = *value;
    580                     }
    581                 }
    582                 return err;
    583             }
    584             case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: {
    585                 int64_t durationUs = mLastDequeueDuration / 1000;
    586                 *value = durationUs > std::numeric_limits<int>::max() ?
    587                         std::numeric_limits<int>::max() :
    588                         static_cast<int>(durationUs);
    589                 return NO_ERROR;
    590             }
    591             case NATIVE_WINDOW_LAST_QUEUE_DURATION: {
    592                 int64_t durationUs = mLastQueueDuration / 1000;
    593                 *value = durationUs > std::numeric_limits<int>::max() ?
    594                         std::numeric_limits<int>::max() :
    595                         static_cast<int>(durationUs);
    596                 return NO_ERROR;
    597             }
    598         }
    599     }
    600     return mGraphicBufferProducer->query(what, value);
    601 }
    602 
    603 int Surface::perform(int operation, va_list args)
    604 {
    605     int res = NO_ERROR;
    606     switch (operation) {
    607     case NATIVE_WINDOW_CONNECT:
    608         // deprecated. must return NO_ERROR.
    609         break;
    610     case NATIVE_WINDOW_DISCONNECT:
    611         // deprecated. must return NO_ERROR.
    612         break;
    613     case NATIVE_WINDOW_SET_USAGE:
    614         res = dispatchSetUsage(args);
    615         break;
    616     case NATIVE_WINDOW_SET_CROP:
    617         res = dispatchSetCrop(args);
    618         break;
    619     case NATIVE_WINDOW_SET_BUFFER_COUNT:
    620         res = dispatchSetBufferCount(args);
    621         break;
    622     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
    623         res = dispatchSetBuffersGeometry(args);
    624         break;
    625     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
    626         res = dispatchSetBuffersTransform(args);
    627         break;
    628     case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM:
    629         res = dispatchSetBuffersStickyTransform(args);
    630         break;
    631     case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
    632         res = dispatchSetBuffersTimestamp(args);
    633         break;
    634     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
    635         res = dispatchSetBuffersDimensions(args);
    636         break;
    637     case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
    638         res = dispatchSetBuffersUserDimensions(args);
    639         break;
    640     case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
    641         res = dispatchSetBuffersFormat(args);
    642         break;
    643     case NATIVE_WINDOW_LOCK:
    644         res = dispatchLock(args);
    645         break;
    646     case NATIVE_WINDOW_UNLOCK_AND_POST:
    647         res = dispatchUnlockAndPost(args);
    648         break;
    649     case NATIVE_WINDOW_SET_SCALING_MODE:
    650         res = dispatchSetScalingMode(args);
    651         break;
    652     case NATIVE_WINDOW_API_CONNECT:
    653         res = dispatchConnect(args);
    654         break;
    655     case NATIVE_WINDOW_API_DISCONNECT:
    656         res = dispatchDisconnect(args);
    657         break;
    658     case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
    659         res = dispatchSetSidebandStream(args);
    660         break;
    661     case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
    662         res = dispatchSetBuffersDataSpace(args);
    663         break;
    664     case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
    665         res = dispatchSetSurfaceDamage(args);
    666         break;
    667     case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE:
    668         res = dispatchSetSharedBufferMode(args);
    669         break;
    670     case NATIVE_WINDOW_SET_AUTO_REFRESH:
    671         res = dispatchSetAutoRefresh(args);
    672         break;
    673     case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS:
    674         res = dispatchGetFrameTimestamps(args);
    675         break;
    676     default:
    677         res = NAME_NOT_FOUND;
    678         break;
    679     }
    680     return res;
    681 }
    682 
    683 int Surface::dispatchConnect(va_list args) {
    684     int api = va_arg(args, int);
    685     return connect(api);
    686 }
    687 
    688 int Surface::dispatchDisconnect(va_list args) {
    689     int api = va_arg(args, int);
    690     return disconnect(api);
    691 }
    692 
    693 int Surface::dispatchSetUsage(va_list args) {
    694     int usage = va_arg(args, int);
    695     return setUsage(static_cast<uint32_t>(usage));
    696 }
    697 
    698 int Surface::dispatchSetCrop(va_list args) {
    699     android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
    700     return setCrop(reinterpret_cast<Rect const*>(rect));
    701 }
    702 
    703 int Surface::dispatchSetBufferCount(va_list args) {
    704     size_t bufferCount = va_arg(args, size_t);
    705     return setBufferCount(static_cast<int32_t>(bufferCount));
    706 }
    707 
    708 int Surface::dispatchSetBuffersGeometry(va_list args) {
    709     uint32_t width = va_arg(args, uint32_t);
    710     uint32_t height = va_arg(args, uint32_t);
    711     PixelFormat format = va_arg(args, PixelFormat);
    712     int err = setBuffersDimensions(width, height);
    713     if (err != 0) {
    714         return err;
    715     }
    716     return setBuffersFormat(format);
    717 }
    718 
    719 int Surface::dispatchSetBuffersDimensions(va_list args) {
    720     uint32_t width = va_arg(args, uint32_t);
    721     uint32_t height = va_arg(args, uint32_t);
    722     return setBuffersDimensions(width, height);
    723 }
    724 
    725 int Surface::dispatchSetBuffersUserDimensions(va_list args) {
    726     uint32_t width = va_arg(args, uint32_t);
    727     uint32_t height = va_arg(args, uint32_t);
    728     return setBuffersUserDimensions(width, height);
    729 }
    730 
    731 int Surface::dispatchSetBuffersFormat(va_list args) {
    732     PixelFormat format = va_arg(args, PixelFormat);
    733     return setBuffersFormat(format);
    734 }
    735 
    736 int Surface::dispatchSetScalingMode(va_list args) {
    737     int mode = va_arg(args, int);
    738     return setScalingMode(mode);
    739 }
    740 
    741 int Surface::dispatchSetBuffersTransform(va_list args) {
    742     uint32_t transform = va_arg(args, uint32_t);
    743     return setBuffersTransform(transform);
    744 }
    745 
    746 int Surface::dispatchSetBuffersStickyTransform(va_list args) {
    747     uint32_t transform = va_arg(args, uint32_t);
    748     return setBuffersStickyTransform(transform);
    749 }
    750 
    751 int Surface::dispatchSetBuffersTimestamp(va_list args) {
    752     int64_t timestamp = va_arg(args, int64_t);
    753     return setBuffersTimestamp(timestamp);
    754 }
    755 
    756 int Surface::dispatchLock(va_list args) {
    757     ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
    758     ARect* inOutDirtyBounds = va_arg(args, ARect*);
    759     return lock(outBuffer, inOutDirtyBounds);
    760 }
    761 
    762 int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) {
    763     return unlockAndPost();
    764 }
    765 
    766 int Surface::dispatchSetSidebandStream(va_list args) {
    767     native_handle_t* sH = va_arg(args, native_handle_t*);
    768     sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false);
    769     setSidebandStream(sidebandHandle);
    770     return OK;
    771 }
    772 
    773 int Surface::dispatchSetBuffersDataSpace(va_list args) {
    774     android_dataspace dataspace =
    775             static_cast<android_dataspace>(va_arg(args, int));
    776     return setBuffersDataSpace(dataspace);
    777 }
    778 
    779 int Surface::dispatchSetSurfaceDamage(va_list args) {
    780     android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
    781     size_t numRects = va_arg(args, size_t);
    782     setSurfaceDamage(rects, numRects);
    783     return NO_ERROR;
    784 }
    785 
    786 int Surface::dispatchSetSharedBufferMode(va_list args) {
    787     bool sharedBufferMode = va_arg(args, int);
    788     return setSharedBufferMode(sharedBufferMode);
    789 }
    790 
    791 int Surface::dispatchSetAutoRefresh(va_list args) {
    792     bool autoRefresh = va_arg(args, int);
    793     return setAutoRefresh(autoRefresh);
    794 }
    795 
    796 int Surface::dispatchGetFrameTimestamps(va_list args) {
    797     uint32_t framesAgo = va_arg(args, uint32_t);
    798     nsecs_t* outPostedTime = va_arg(args, int64_t*);
    799     nsecs_t* outAcquireTime = va_arg(args, int64_t*);
    800     nsecs_t* outRefreshStartTime = va_arg(args, int64_t*);
    801     nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*);
    802     nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*);
    803     nsecs_t* outReleaseTime = va_arg(args, int64_t*);
    804     bool ret = getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo,
    805             outPostedTime, outAcquireTime, outRefreshStartTime,
    806             outGlCompositionDoneTime, outDisplayRetireTime, outReleaseTime);
    807     return ret ? NO_ERROR : BAD_VALUE;
    808 }
    809 
    810 int Surface::connect(int api) {
    811     static sp<IProducerListener> listener = new DummyProducerListener();
    812     return connect(api, listener);
    813 }
    814 
    815 int Surface::connect(int api, const sp<IProducerListener>& listener) {
    816     ATRACE_CALL();
    817     ALOGV("Surface::connect");
    818     Mutex::Autolock lock(mMutex);
    819     IGraphicBufferProducer::QueueBufferOutput output;
    820     int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
    821     if (err == NO_ERROR) {
    822         uint32_t numPendingBuffers = 0;
    823         uint32_t hint = 0;
    824         output.deflate(&mDefaultWidth, &mDefaultHeight, &hint,
    825                 &numPendingBuffers, &mNextFrameNumber);
    826 
    827         // Disable transform hint if sticky transform is set.
    828         if (mStickyTransform == 0) {
    829             mTransformHint = hint;
    830         }
    831 
    832         mConsumerRunningBehind = (numPendingBuffers >= 2);
    833     }
    834     if (!err && api == NATIVE_WINDOW_API_CPU) {
    835         mConnectedToCpu = true;
    836         // Clear the dirty region in case we're switching from a non-CPU API
    837         mDirtyRegion.clear();
    838     } else if (!err) {
    839         // Initialize the dirty region for tracking surface damage
    840         mDirtyRegion = Region::INVALID_REGION;
    841     }
    842 
    843     return err;
    844 }
    845 
    846 
    847 int Surface::disconnect(int api) {
    848     ATRACE_CALL();
    849     ALOGV("Surface::disconnect");
    850     Mutex::Autolock lock(mMutex);
    851     mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
    852     mSharedBufferHasBeenQueued = false;
    853     freeAllBuffers();
    854     int err = mGraphicBufferProducer->disconnect(api);
    855     if (!err) {
    856         mReqFormat = 0;
    857         mReqWidth = 0;
    858         mReqHeight = 0;
    859         mReqUsage = 0;
    860         mCrop.clear();
    861         mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
    862         mTransform = 0;
    863         mStickyTransform = 0;
    864 
    865         if (api == NATIVE_WINDOW_API_CPU) {
    866             mConnectedToCpu = false;
    867         }
    868     }
    869     return err;
    870 }
    871 
    872 int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
    873         sp<Fence>* outFence) {
    874     ATRACE_CALL();
    875     ALOGV("Surface::detachNextBuffer");
    876 
    877     if (outBuffer == NULL || outFence == NULL) {
    878         return BAD_VALUE;
    879     }
    880 
    881     Mutex::Autolock lock(mMutex);
    882 
    883     sp<GraphicBuffer> buffer(NULL);
    884     sp<Fence> fence(NULL);
    885     status_t result = mGraphicBufferProducer->detachNextBuffer(
    886             &buffer, &fence);
    887     if (result != NO_ERROR) {
    888         return result;
    889     }
    890 
    891     *outBuffer = buffer;
    892     if (fence != NULL && fence->isValid()) {
    893         *outFence = fence;
    894     } else {
    895         *outFence = Fence::NO_FENCE;
    896     }
    897 
    898     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
    899         if (mSlots[i].buffer != NULL &&
    900                 mSlots[i].buffer->handle == buffer->handle) {
    901             mSlots[i].buffer = NULL;
    902         }
    903     }
    904 
    905     return NO_ERROR;
    906 }
    907 
    908 int Surface::attachBuffer(ANativeWindowBuffer* buffer)
    909 {
    910     ATRACE_CALL();
    911     ALOGV("Surface::attachBuffer");
    912 
    913     Mutex::Autolock lock(mMutex);
    914 
    915     sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
    916     uint32_t priorGeneration = graphicBuffer->mGenerationNumber;
    917     graphicBuffer->mGenerationNumber = mGenerationNumber;
    918     int32_t attachedSlot = -1;
    919     status_t result = mGraphicBufferProducer->attachBuffer(
    920             &attachedSlot, graphicBuffer);
    921     if (result != NO_ERROR) {
    922         ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
    923         graphicBuffer->mGenerationNumber = priorGeneration;
    924         return result;
    925     }
    926     mSlots[attachedSlot].buffer = graphicBuffer;
    927 
    928     return NO_ERROR;
    929 }
    930 
    931 int Surface::setUsage(uint32_t reqUsage)
    932 {
    933     ALOGV("Surface::setUsage");
    934     Mutex::Autolock lock(mMutex);
    935     if (reqUsage != mReqUsage) {
    936         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
    937     }
    938     mReqUsage = reqUsage;
    939     return OK;
    940 }
    941 
    942 int Surface::setCrop(Rect const* rect)
    943 {
    944     ATRACE_CALL();
    945 
    946     Rect realRect(Rect::EMPTY_RECT);
    947     if (rect == NULL || rect->isEmpty()) {
    948         realRect.clear();
    949     } else {
    950         realRect = *rect;
    951     }
    952 
    953     ALOGV("Surface::setCrop rect=[%d %d %d %d]",
    954             realRect.left, realRect.top, realRect.right, realRect.bottom);
    955 
    956     Mutex::Autolock lock(mMutex);
    957     mCrop = realRect;
    958     return NO_ERROR;
    959 }
    960 
    961 int Surface::setBufferCount(int bufferCount)
    962 {
    963     ATRACE_CALL();
    964     ALOGV("Surface::setBufferCount");
    965     Mutex::Autolock lock(mMutex);
    966 
    967     status_t err = NO_ERROR;
    968     if (bufferCount == 0) {
    969         err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1);
    970     } else {
    971         int minUndequeuedBuffers = 0;
    972         err = mGraphicBufferProducer->query(
    973                 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers);
    974         if (err == NO_ERROR) {
    975             err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
    976                     bufferCount - minUndequeuedBuffers);
    977         }
    978     }
    979 
    980     ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
    981              bufferCount, strerror(-err));
    982 
    983     return err;
    984 }
    985 
    986 int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
    987     ATRACE_CALL();
    988     ALOGV("Surface::setMaxDequeuedBufferCount");
    989     Mutex::Autolock lock(mMutex);
    990 
    991     status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount(
    992             maxDequeuedBuffers);
    993     ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) "
    994             "returned %s", maxDequeuedBuffers, strerror(-err));
    995 
    996     return err;
    997 }
    998 
    999 int Surface::setAsyncMode(bool async) {
   1000     ATRACE_CALL();
   1001     ALOGV("Surface::setAsyncMode");
   1002     Mutex::Autolock lock(mMutex);
   1003 
   1004     status_t err = mGraphicBufferProducer->setAsyncMode(async);
   1005     ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s",
   1006             async, strerror(-err));
   1007 
   1008     return err;
   1009 }
   1010 
   1011 int Surface::setSharedBufferMode(bool sharedBufferMode) {
   1012     ATRACE_CALL();
   1013     ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode);
   1014     Mutex::Autolock lock(mMutex);
   1015 
   1016     status_t err = mGraphicBufferProducer->setSharedBufferMode(
   1017             sharedBufferMode);
   1018     if (err == NO_ERROR) {
   1019         mSharedBufferMode = sharedBufferMode;
   1020     }
   1021     ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned"
   1022             "%s", sharedBufferMode, strerror(-err));
   1023 
   1024     return err;
   1025 }
   1026 
   1027 int Surface::setAutoRefresh(bool autoRefresh) {
   1028     ATRACE_CALL();
   1029     ALOGV("Surface::setAutoRefresh (%d)", autoRefresh);
   1030     Mutex::Autolock lock(mMutex);
   1031 
   1032     status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh);
   1033     if (err == NO_ERROR) {
   1034         mAutoRefresh = autoRefresh;
   1035     }
   1036     ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s",
   1037             autoRefresh, strerror(-err));
   1038     return err;
   1039 }
   1040 
   1041 int Surface::setBuffersDimensions(uint32_t width, uint32_t height)
   1042 {
   1043     ATRACE_CALL();
   1044     ALOGV("Surface::setBuffersDimensions");
   1045 
   1046     if ((width && !height) || (!width && height))
   1047         return BAD_VALUE;
   1048 
   1049     Mutex::Autolock lock(mMutex);
   1050     if (width != mReqWidth || height != mReqHeight) {
   1051         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
   1052     }
   1053     mReqWidth = width;
   1054     mReqHeight = height;
   1055     return NO_ERROR;
   1056 }
   1057 
   1058 int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height)
   1059 {
   1060     ATRACE_CALL();
   1061     ALOGV("Surface::setBuffersUserDimensions");
   1062 
   1063     if ((width && !height) || (!width && height))
   1064         return BAD_VALUE;
   1065 
   1066     Mutex::Autolock lock(mMutex);
   1067     if (width != mUserWidth || height != mUserHeight) {
   1068         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
   1069     }
   1070     mUserWidth = width;
   1071     mUserHeight = height;
   1072     return NO_ERROR;
   1073 }
   1074 
   1075 int Surface::setBuffersFormat(PixelFormat format)
   1076 {
   1077     ALOGV("Surface::setBuffersFormat");
   1078 
   1079     Mutex::Autolock lock(mMutex);
   1080     if (format != mReqFormat) {
   1081         mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT;
   1082     }
   1083     mReqFormat = format;
   1084     return NO_ERROR;
   1085 }
   1086 
   1087 int Surface::setScalingMode(int mode)
   1088 {
   1089     ATRACE_CALL();
   1090     ALOGV("Surface::setScalingMode(%d)", mode);
   1091 
   1092     switch (mode) {
   1093         case NATIVE_WINDOW_SCALING_MODE_FREEZE:
   1094         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
   1095         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
   1096         case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
   1097             break;
   1098         default:
   1099             ALOGE("unknown scaling mode: %d", mode);
   1100             return BAD_VALUE;
   1101     }
   1102 
   1103     Mutex::Autolock lock(mMutex);
   1104     mScalingMode = mode;
   1105     return NO_ERROR;
   1106 }
   1107 
   1108 int Surface::setBuffersTransform(uint32_t transform)
   1109 {
   1110     ATRACE_CALL();
   1111     ALOGV("Surface::setBuffersTransform");
   1112     Mutex::Autolock lock(mMutex);
   1113     mTransform = transform;
   1114     return NO_ERROR;
   1115 }
   1116 
   1117 int Surface::setBuffersStickyTransform(uint32_t transform)
   1118 {
   1119     ATRACE_CALL();
   1120     ALOGV("Surface::setBuffersStickyTransform");
   1121     Mutex::Autolock lock(mMutex);
   1122     mStickyTransform = transform;
   1123     return NO_ERROR;
   1124 }
   1125 
   1126 int Surface::setBuffersTimestamp(int64_t timestamp)
   1127 {
   1128     ALOGV("Surface::setBuffersTimestamp");
   1129     Mutex::Autolock lock(mMutex);
   1130     mTimestamp = timestamp;
   1131     return NO_ERROR;
   1132 }
   1133 
   1134 int Surface::setBuffersDataSpace(android_dataspace dataSpace)
   1135 {
   1136     ALOGV("Surface::setBuffersDataSpace");
   1137     Mutex::Autolock lock(mMutex);
   1138     mDataSpace = dataSpace;
   1139     return NO_ERROR;
   1140 }
   1141 
   1142 void Surface::freeAllBuffers() {
   1143     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
   1144         mSlots[i].buffer = 0;
   1145     }
   1146 }
   1147 
   1148 void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
   1149     ATRACE_CALL();
   1150     ALOGV("Surface::setSurfaceDamage");
   1151     Mutex::Autolock lock(mMutex);
   1152 
   1153     if (mConnectedToCpu || numRects == 0) {
   1154         mDirtyRegion = Region::INVALID_REGION;
   1155         return;
   1156     }
   1157 
   1158     mDirtyRegion.clear();
   1159     for (size_t r = 0; r < numRects; ++r) {
   1160         // We intentionally flip top and bottom here, since because they're
   1161         // specified with a bottom-left origin, top > bottom, which fails
   1162         // validation in the Region class. We will fix this up when we flip to a
   1163         // top-left origin in queueBuffer.
   1164         Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top);
   1165         mDirtyRegion.orSelf(rect);
   1166     }
   1167 }
   1168 
   1169 // ----------------------------------------------------------------------
   1170 // the lock/unlock APIs must be used from the same thread
   1171 
   1172 static status_t copyBlt(
   1173         const sp<GraphicBuffer>& dst,
   1174         const sp<GraphicBuffer>& src,
   1175         const Region& reg)
   1176 {
   1177     // src and dst with, height and format must be identical. no verification
   1178     // is done here.
   1179     status_t err;
   1180     uint8_t* src_bits = NULL;
   1181     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(),
   1182             reinterpret_cast<void**>(&src_bits));
   1183     ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
   1184 
   1185     uint8_t* dst_bits = NULL;
   1186     err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(),
   1187             reinterpret_cast<void**>(&dst_bits));
   1188     ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
   1189 
   1190     Region::const_iterator head(reg.begin());
   1191     Region::const_iterator tail(reg.end());
   1192     if (head != tail && src_bits && dst_bits) {
   1193         const size_t bpp = bytesPerPixel(src->format);
   1194         const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp;
   1195         const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp;
   1196 
   1197         while (head != tail) {
   1198             const Rect& r(*head++);
   1199             int32_t h = r.height();
   1200             if (h <= 0) continue;
   1201             size_t size = static_cast<uint32_t>(r.width()) * bpp;
   1202             uint8_t const * s = src_bits +
   1203                     static_cast<uint32_t>(r.left + src->stride * r.top) * bpp;
   1204             uint8_t       * d = dst_bits +
   1205                     static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp;
   1206             if (dbpr==sbpr && size==sbpr) {
   1207                 size *= static_cast<size_t>(h);
   1208                 h = 1;
   1209             }
   1210             do {
   1211                 memcpy(d, s, size);
   1212                 d += dbpr;
   1213                 s += sbpr;
   1214             } while (--h > 0);
   1215         }
   1216     }
   1217 
   1218     if (src_bits)
   1219         src->unlock();
   1220 
   1221     if (dst_bits)
   1222         dst->unlock();
   1223 
   1224     return err;
   1225 }
   1226 
   1227 // ----------------------------------------------------------------------------
   1228 
   1229 status_t Surface::lock(
   1230         ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
   1231 {
   1232     if (mLockedBuffer != 0) {
   1233         ALOGE("Surface::lock failed, already locked");
   1234         return INVALID_OPERATION;
   1235     }
   1236 
   1237     if (!mConnectedToCpu) {
   1238         int err = Surface::connect(NATIVE_WINDOW_API_CPU);
   1239         if (err) {
   1240             return err;
   1241         }
   1242         // we're intending to do software rendering from this point
   1243         setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
   1244     }
   1245 
   1246     ANativeWindowBuffer* out;
   1247     int fenceFd = -1;
   1248     status_t err = dequeueBuffer(&out, &fenceFd);
   1249     ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
   1250     if (err == NO_ERROR) {
   1251         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
   1252         const Rect bounds(backBuffer->width, backBuffer->height);
   1253 
   1254         Region newDirtyRegion;
   1255         if (inOutDirtyBounds) {
   1256             newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
   1257             newDirtyRegion.andSelf(bounds);
   1258         } else {
   1259             newDirtyRegion.set(bounds);
   1260         }
   1261 
   1262         // figure out if we can copy the frontbuffer back
   1263         const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
   1264         const bool canCopyBack = (frontBuffer != 0 &&
   1265                 backBuffer->width  == frontBuffer->width &&
   1266                 backBuffer->height == frontBuffer->height &&
   1267                 backBuffer->format == frontBuffer->format);
   1268 
   1269         if (canCopyBack) {
   1270             // copy the area that is invalid and not repainted this round
   1271             const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
   1272             if (!copyback.isEmpty())
   1273                 copyBlt(backBuffer, frontBuffer, copyback);
   1274         } else {
   1275             // if we can't copy-back anything, modify the user's dirty
   1276             // region to make sure they redraw the whole buffer
   1277             newDirtyRegion.set(bounds);
   1278             mDirtyRegion.clear();
   1279             Mutex::Autolock lock(mMutex);
   1280             for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
   1281                 mSlots[i].dirtyRegion.clear();
   1282             }
   1283         }
   1284 
   1285 
   1286         { // scope for the lock
   1287             Mutex::Autolock lock(mMutex);
   1288             int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
   1289             if (backBufferSlot >= 0) {
   1290                 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
   1291                 mDirtyRegion.subtract(dirtyRegion);
   1292                 dirtyRegion = newDirtyRegion;
   1293             }
   1294         }
   1295 
   1296         mDirtyRegion.orSelf(newDirtyRegion);
   1297         if (inOutDirtyBounds) {
   1298             *inOutDirtyBounds = newDirtyRegion.getBounds();
   1299         }
   1300 
   1301         void* vaddr;
   1302         status_t res = backBuffer->lockAsync(
   1303                 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
   1304                 newDirtyRegion.bounds(), &vaddr, fenceFd);
   1305 
   1306         ALOGW_IF(res, "failed locking buffer (handle = %p)",
   1307                 backBuffer->handle);
   1308 
   1309         if (res != 0) {
   1310             err = INVALID_OPERATION;
   1311         } else {
   1312             mLockedBuffer = backBuffer;
   1313             outBuffer->width  = backBuffer->width;
   1314             outBuffer->height = backBuffer->height;
   1315             outBuffer->stride = backBuffer->stride;
   1316             outBuffer->format = backBuffer->format;
   1317             outBuffer->bits   = vaddr;
   1318         }
   1319     }
   1320     return err;
   1321 }
   1322 
   1323 status_t Surface::unlockAndPost()
   1324 {
   1325     if (mLockedBuffer == 0) {
   1326         ALOGE("Surface::unlockAndPost failed, no locked buffer");
   1327         return INVALID_OPERATION;
   1328     }
   1329 
   1330     int fd = -1;
   1331     status_t err = mLockedBuffer->unlockAsync(&fd);
   1332     ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
   1333 
   1334     err = queueBuffer(mLockedBuffer.get(), fd);
   1335     ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
   1336             mLockedBuffer->handle, strerror(-err));
   1337 
   1338     mPostedBuffer = mLockedBuffer;
   1339     mLockedBuffer = 0;
   1340     return err;
   1341 }
   1342 
   1343 bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) {
   1344     Mutex::Autolock lock(mMutex);
   1345     if (mNextFrameNumber > lastFrame) {
   1346       return true;
   1347     }
   1348     return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK;
   1349 }
   1350 
   1351 status_t Surface::getUniqueId(uint64_t* outId) const {
   1352     Mutex::Autolock lock(mMutex);
   1353     return mGraphicBufferProducer->getUniqueId(outId);
   1354 }
   1355 
   1356 namespace view {
   1357 
   1358 status_t Surface::writeToParcel(Parcel* parcel) const {
   1359     return writeToParcel(parcel, false);
   1360 }
   1361 
   1362 status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
   1363     if (parcel == nullptr) return BAD_VALUE;
   1364 
   1365     status_t res = OK;
   1366 
   1367     if (!nameAlreadyWritten) res = parcel->writeString16(name);
   1368 
   1369     if (res == OK) {
   1370         res = parcel->writeStrongBinder(
   1371                 IGraphicBufferProducer::asBinder(graphicBufferProducer));
   1372     }
   1373     return res;
   1374 }
   1375 
   1376 status_t Surface::readFromParcel(const Parcel* parcel) {
   1377     return readFromParcel(parcel, false);
   1378 }
   1379 
   1380 status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
   1381     if (parcel == nullptr) return BAD_VALUE;
   1382 
   1383     if (!nameAlreadyRead) {
   1384         name = readMaybeEmptyString16(parcel);
   1385     }
   1386 
   1387     sp<IBinder> binder;
   1388 
   1389     status_t res = parcel->readStrongBinder(&binder);
   1390     if (res != OK) return res;
   1391 
   1392     graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
   1393 
   1394     return OK;
   1395 }
   1396 
   1397 String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
   1398     size_t len;
   1399     const char16_t* str = parcel->readString16Inplace(&len);
   1400     if (str != nullptr) {
   1401         return String16(str, len);
   1402     } else {
   1403         return String16();
   1404     }
   1405 }
   1406 
   1407 } // namespace view
   1408 
   1409 }; // namespace android
   1410