Home | History | Annotate | Download | only in surfaceflinger_client
      1 /*
      2  * Copyright (C) 2007 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 
     19 #include <stdint.h>
     20 #include <unistd.h>
     21 #include <fcntl.h>
     22 #include <errno.h>
     23 #include <sys/types.h>
     24 #include <sys/stat.h>
     25 
     26 #include <utils/Errors.h>
     27 #include <utils/threads.h>
     28 #include <utils/CallStack.h>
     29 #include <utils/Log.h>
     30 
     31 #include <pixelflinger/pixelflinger.h>
     32 
     33 #include <binder/IPCThreadState.h>
     34 #include <binder/IMemory.h>
     35 
     36 #include <ui/DisplayInfo.h>
     37 #include <ui/GraphicBuffer.h>
     38 #include <ui/GraphicBufferMapper.h>
     39 #include <ui/Rect.h>
     40 
     41 #include <surfaceflinger/Surface.h>
     42 #include <surfaceflinger/ISurface.h>
     43 #include <surfaceflinger/ISurfaceComposer.h>
     44 #include <surfaceflinger/SurfaceComposerClient.h>
     45 
     46 #include <private/surfaceflinger/SharedBufferStack.h>
     47 #include <private/surfaceflinger/LayerState.h>
     48 
     49 namespace android {
     50 
     51 // ----------------------------------------------------------------------
     52 
     53 static status_t copyBlt(
     54         const sp<GraphicBuffer>& dst,
     55         const sp<GraphicBuffer>& src,
     56         const Region& reg)
     57 {
     58     status_t err;
     59     uint8_t const * src_bits = NULL;
     60     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
     61     LOGE_IF(err, "error locking src buffer %s", strerror(-err));
     62 
     63     uint8_t* dst_bits = NULL;
     64     err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
     65     LOGE_IF(err, "error locking dst buffer %s", strerror(-err));
     66 
     67     Region::const_iterator head(reg.begin());
     68     Region::const_iterator tail(reg.end());
     69     if (head != tail && src_bits && dst_bits) {
     70         // NOTE: dst and src must be the same format
     71         const size_t bpp = bytesPerPixel(src->format);
     72         const size_t dbpr = dst->stride * bpp;
     73         const size_t sbpr = src->stride * bpp;
     74 
     75         while (head != tail) {
     76             const Rect& r(*head++);
     77             ssize_t h = r.height();
     78             if (h <= 0) continue;
     79             size_t size = r.width() * bpp;
     80             uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
     81             uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
     82             if (dbpr==sbpr && size==sbpr) {
     83                 size *= h;
     84                 h = 1;
     85             }
     86             do {
     87                 memcpy(d, s, size);
     88                 d += dbpr;
     89                 s += sbpr;
     90             } while (--h > 0);
     91         }
     92     }
     93 
     94     if (src_bits)
     95         src->unlock();
     96 
     97     if (dst_bits)
     98         dst->unlock();
     99 
    100     return err;
    101 }
    102 
    103 // ============================================================================
    104 //  SurfaceControl
    105 // ============================================================================
    106 
    107 SurfaceControl::SurfaceControl(
    108         const sp<SurfaceComposerClient>& client,
    109         const sp<ISurface>& surface,
    110         const ISurfaceFlingerClient::surface_data_t& data,
    111         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
    112     : mClient(client), mSurface(surface),
    113       mToken(data.token), mIdentity(data.identity),
    114       mWidth(data.width), mHeight(data.height), mFormat(data.format),
    115       mFlags(flags)
    116 {
    117 }
    118 
    119 SurfaceControl::~SurfaceControl()
    120 {
    121     destroy();
    122 }
    123 
    124 void SurfaceControl::destroy()
    125 {
    126     if (isValid()) {
    127         mClient->destroySurface(mToken);
    128     }
    129 
    130     // clear all references and trigger an IPC now, to make sure things
    131     // happen without delay, since these resources are quite heavy.
    132     mClient.clear();
    133     mSurface.clear();
    134     IPCThreadState::self()->flushCommands();
    135 }
    136 
    137 void SurfaceControl::clear()
    138 {
    139     // here, the window manager tells us explicitly that we should destroy
    140     // the surface's resource. Soon after this call, it will also release
    141     // its last reference (which will call the dtor); however, it is possible
    142     // that a client living in the same process still holds references which
    143     // would delay the call to the dtor -- that is why we need this explicit
    144     // "clear()" call.
    145     destroy();
    146 }
    147 
    148 bool SurfaceControl::isSameSurface(
    149         const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
    150 {
    151     if (lhs == 0 || rhs == 0)
    152         return false;
    153     return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
    154 }
    155 
    156 status_t SurfaceControl::setLayer(int32_t layer) {
    157     const sp<SurfaceComposerClient>& client(mClient);
    158     status_t err = validate();
    159     if (err < 0) return err;
    160     return client->setLayer(mToken, layer);
    161 }
    162 status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
    163     const sp<SurfaceComposerClient>& client(mClient);
    164     status_t err = validate();
    165     if (err < 0) return err;
    166     return client->setPosition(mToken, x, y);
    167 }
    168 status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
    169     const sp<SurfaceComposerClient>& client(mClient);
    170     status_t err = validate();
    171     if (err < 0) return err;
    172     return client->setSize(mToken, w, h);
    173 }
    174 status_t SurfaceControl::hide() {
    175     const sp<SurfaceComposerClient>& client(mClient);
    176     status_t err = validate();
    177     if (err < 0) return err;
    178     return client->hide(mToken);
    179 }
    180 status_t SurfaceControl::show(int32_t layer) {
    181     const sp<SurfaceComposerClient>& client(mClient);
    182     status_t err = validate();
    183     if (err < 0) return err;
    184     return client->show(mToken, layer);
    185 }
    186 status_t SurfaceControl::freeze() {
    187     const sp<SurfaceComposerClient>& client(mClient);
    188     status_t err = validate();
    189     if (err < 0) return err;
    190     return client->freeze(mToken);
    191 }
    192 status_t SurfaceControl::unfreeze() {
    193     const sp<SurfaceComposerClient>& client(mClient);
    194     status_t err = validate();
    195     if (err < 0) return err;
    196     return client->unfreeze(mToken);
    197 }
    198 status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
    199     const sp<SurfaceComposerClient>& client(mClient);
    200     status_t err = validate();
    201     if (err < 0) return err;
    202     return client->setFlags(mToken, flags, mask);
    203 }
    204 status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
    205     const sp<SurfaceComposerClient>& client(mClient);
    206     status_t err = validate();
    207     if (err < 0) return err;
    208     return client->setTransparentRegionHint(mToken, transparent);
    209 }
    210 status_t SurfaceControl::setAlpha(float alpha) {
    211     const sp<SurfaceComposerClient>& client(mClient);
    212     status_t err = validate();
    213     if (err < 0) return err;
    214     return client->setAlpha(mToken, alpha);
    215 }
    216 status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
    217     const sp<SurfaceComposerClient>& client(mClient);
    218     status_t err = validate();
    219     if (err < 0) return err;
    220     return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
    221 }
    222 status_t SurfaceControl::setFreezeTint(uint32_t tint) {
    223     const sp<SurfaceComposerClient>& client(mClient);
    224     status_t err = validate();
    225     if (err < 0) return err;
    226     return client->setFreezeTint(mToken, tint);
    227 }
    228 
    229 status_t SurfaceControl::validate() const
    230 {
    231     if (mToken<0 || mClient==0) {
    232         LOGE("invalid token (%d, identity=%u) or client (%p)",
    233                 mToken, mIdentity, mClient.get());
    234         return NO_INIT;
    235     }
    236     SharedClient const* cblk = mClient->mControl;
    237     if (cblk == 0) {
    238         LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
    239         return NO_INIT;
    240     }
    241     status_t err = cblk->validate(mToken);
    242     if (err != NO_ERROR) {
    243         LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
    244                 mToken, mIdentity, err, strerror(-err));
    245         return err;
    246     }
    247     uint32_t identity = cblk->getIdentity(mToken);
    248     if (mIdentity != identity) {
    249         LOGE("using an invalid surface id=%d, identity=%u should be %d",
    250                 mToken, mIdentity, identity);
    251         return NO_INIT;
    252     }
    253     return NO_ERROR;
    254 }
    255 
    256 status_t SurfaceControl::writeSurfaceToParcel(
    257         const sp<SurfaceControl>& control, Parcel* parcel)
    258 {
    259     uint32_t flags = 0;
    260     uint32_t format = 0;
    261     SurfaceID token = -1;
    262     uint32_t identity = 0;
    263     uint32_t width = 0;
    264     uint32_t height = 0;
    265     sp<SurfaceComposerClient> client;
    266     sp<ISurface> sur;
    267     if (SurfaceControl::isValid(control)) {
    268         token    = control->mToken;
    269         identity = control->mIdentity;
    270         client   = control->mClient;
    271         sur      = control->mSurface;
    272         width    = control->mWidth;
    273         height   = control->mHeight;
    274         format   = control->mFormat;
    275         flags    = control->mFlags;
    276     }
    277     parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
    278     parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
    279     parcel->writeInt32(token);
    280     parcel->writeInt32(identity);
    281     parcel->writeInt32(width);
    282     parcel->writeInt32(height);
    283     parcel->writeInt32(format);
    284     parcel->writeInt32(flags);
    285     return NO_ERROR;
    286 }
    287 
    288 sp<Surface> SurfaceControl::getSurface() const
    289 {
    290     Mutex::Autolock _l(mLock);
    291     if (mSurfaceData == 0) {
    292         mSurfaceData = new Surface(const_cast<SurfaceControl*>(this));
    293     }
    294     return mSurfaceData;
    295 }
    296 
    297 // ============================================================================
    298 //  Surface
    299 // ============================================================================
    300 
    301 Surface::Surface(const sp<SurfaceControl>& surface)
    302     : mClient(surface->mClient), mSurface(surface->mSurface),
    303       mToken(surface->mToken), mIdentity(surface->mIdentity),
    304       mFormat(surface->mFormat), mFlags(surface->mFlags),
    305       mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL),
    306       mWidth(surface->mWidth), mHeight(surface->mHeight)
    307 {
    308     mSharedBufferClient = new SharedBufferClient(
    309             mClient->mControl, mToken, 2, mIdentity);
    310 
    311     init();
    312 }
    313 
    314 Surface::Surface(const Parcel& parcel)
    315     :  mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL)
    316 {
    317     sp<IBinder> clientBinder = parcel.readStrongBinder();
    318     mSurface    = interface_cast<ISurface>(parcel.readStrongBinder());
    319     mToken      = parcel.readInt32();
    320     mIdentity   = parcel.readInt32();
    321     mWidth      = parcel.readInt32();
    322     mHeight     = parcel.readInt32();
    323     mFormat     = parcel.readInt32();
    324     mFlags      = parcel.readInt32();
    325 
    326     // FIXME: what does that mean if clientBinder is NULL here?
    327     if (clientBinder != NULL) {
    328         mClient = SurfaceComposerClient::clientForConnection(clientBinder);
    329 
    330         mSharedBufferClient = new SharedBufferClient(
    331                 mClient->mControl, mToken, 2, mIdentity);
    332     }
    333 
    334     init();
    335 }
    336 
    337 void Surface::init()
    338 {
    339     android_native_window_t::setSwapInterval  = setSwapInterval;
    340     android_native_window_t::dequeueBuffer    = dequeueBuffer;
    341     android_native_window_t::lockBuffer       = lockBuffer;
    342     android_native_window_t::queueBuffer      = queueBuffer;
    343     android_native_window_t::query            = query;
    344     android_native_window_t::perform          = perform;
    345     mSwapRectangle.makeInvalid();
    346     DisplayInfo dinfo;
    347     SurfaceComposerClient::getDisplayInfo(0, &dinfo);
    348     const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi;
    349     const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi;
    350     // FIXME: set real values here
    351     const_cast<int&>(android_native_window_t::minSwapInterval) = 1;
    352     const_cast<int&>(android_native_window_t::maxSwapInterval) = 1;
    353     const_cast<uint32_t&>(android_native_window_t::flags) = 0;
    354     // be default we request a hardware surface
    355     mUsage = GRALLOC_USAGE_HW_RENDER;
    356     mConnected = 0;
    357     mNeedFullUpdate = false;
    358 }
    359 
    360 Surface::~Surface()
    361 {
    362     // this is a client-side operation, the surface is destroyed, unmap
    363     // its buffers in this process.
    364     for (int i=0 ; i<2 ; i++) {
    365         if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
    366             getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
    367         }
    368     }
    369 
    370     // clear all references and trigger an IPC now, to make sure things
    371     // happen without delay, since these resources are quite heavy.
    372     mClient.clear();
    373     mSurface.clear();
    374     delete mSharedBufferClient;
    375     IPCThreadState::self()->flushCommands();
    376 }
    377 
    378 sp<SurfaceComposerClient> Surface::getClient() const {
    379     return mClient;
    380 }
    381 
    382 sp<ISurface> Surface::getISurface() const {
    383     return mSurface;
    384 }
    385 
    386 bool Surface::isValid() {
    387     return mToken>=0 && mClient!=0;
    388 }
    389 
    390 status_t Surface::validate() const
    391 {
    392     sp<SurfaceComposerClient> client(getClient());
    393     if (mToken<0 || mClient==0) {
    394         LOGE("invalid token (%d, identity=%u) or client (%p)",
    395                 mToken, mIdentity, client.get());
    396         return NO_INIT;
    397     }
    398     SharedClient const* cblk = mClient->mControl;
    399     if (cblk == 0) {
    400         LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
    401         return NO_INIT;
    402     }
    403     status_t err = cblk->validate(mToken);
    404     if (err != NO_ERROR) {
    405         LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
    406                 mToken, mIdentity, err, strerror(-err));
    407         return err;
    408     }
    409     uint32_t identity = cblk->getIdentity(mToken);
    410     if (mIdentity != identity) {
    411         LOGE("using an invalid surface id=%d, identity=%u should be %d",
    412                 mToken, mIdentity, identity);
    413         return NO_INIT;
    414     }
    415     return NO_ERROR;
    416 }
    417 
    418 
    419 bool Surface::isSameSurface(
    420         const sp<Surface>& lhs, const sp<Surface>& rhs)
    421 {
    422     if (lhs == 0 || rhs == 0)
    423         return false;
    424 
    425     return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
    426 }
    427 
    428 // ----------------------------------------------------------------------------
    429 
    430 int Surface::setSwapInterval(android_native_window_t* window, int interval) {
    431     return 0;
    432 }
    433 
    434 int Surface::dequeueBuffer(android_native_window_t* window,
    435         android_native_buffer_t** buffer) {
    436     Surface* self = getSelf(window);
    437     return self->dequeueBuffer(buffer);
    438 }
    439 
    440 int Surface::lockBuffer(android_native_window_t* window,
    441         android_native_buffer_t* buffer) {
    442     Surface* self = getSelf(window);
    443     return self->lockBuffer(buffer);
    444 }
    445 
    446 int Surface::queueBuffer(android_native_window_t* window,
    447         android_native_buffer_t* buffer) {
    448     Surface* self = getSelf(window);
    449     return self->queueBuffer(buffer);
    450 }
    451 
    452 int Surface::query(android_native_window_t* window,
    453         int what, int* value) {
    454     Surface* self = getSelf(window);
    455     return self->query(what, value);
    456 }
    457 
    458 int Surface::perform(android_native_window_t* window,
    459         int operation, ...) {
    460     va_list args;
    461     va_start(args, operation);
    462     Surface* self = getSelf(window);
    463     int res = self->perform(operation, args);
    464     va_end(args);
    465     return res;
    466 }
    467 
    468 // ----------------------------------------------------------------------------
    469 
    470 status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer) {
    471     android_native_buffer_t* out;
    472     status_t err = dequeueBuffer(&out);
    473     if (err == NO_ERROR) {
    474         *buffer = GraphicBuffer::getSelf(out);
    475     }
    476     return err;
    477 }
    478 
    479 // ----------------------------------------------------------------------------
    480 
    481 
    482 int Surface::dequeueBuffer(android_native_buffer_t** buffer)
    483 {
    484     sp<SurfaceComposerClient> client(getClient());
    485     status_t err = validate();
    486     if (err != NO_ERROR)
    487         return err;
    488 
    489     ssize_t bufIdx = mSharedBufferClient->dequeue();
    490     if (bufIdx < 0) {
    491         LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
    492         return bufIdx;
    493     }
    494 
    495     // below we make sure we AT LEAST have the usage flags we want
    496     const uint32_t usage(getUsage());
    497     const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
    498     if (backBuffer == 0 ||
    499         ((uint32_t(backBuffer->usage) & usage) != usage) ||
    500         mSharedBufferClient->needNewBuffer(bufIdx))
    501     {
    502         err = getBufferLocked(bufIdx, usage);
    503         LOGE_IF(err, "getBufferLocked(%ld, %08x) failed (%s)",
    504                 bufIdx, usage, strerror(-err));
    505         if (err == NO_ERROR) {
    506             // reset the width/height with the what we get from the buffer
    507             mWidth  = uint32_t(backBuffer->width);
    508             mHeight = uint32_t(backBuffer->height);
    509         }
    510     }
    511 
    512     // if we still don't have a buffer here, we probably ran out of memory
    513     if (!err && backBuffer==0) {
    514         err = NO_MEMORY;
    515     }
    516 
    517     if (err == NO_ERROR) {
    518         mDirtyRegion.set(backBuffer->width, backBuffer->height);
    519         *buffer = backBuffer.get();
    520     } else {
    521         mSharedBufferClient->undoDequeue(bufIdx);
    522     }
    523 
    524     return err;
    525 }
    526 
    527 int Surface::lockBuffer(android_native_buffer_t* buffer)
    528 {
    529     sp<SurfaceComposerClient> client(getClient());
    530     status_t err = validate();
    531     if (err != NO_ERROR)
    532         return err;
    533 
    534     int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
    535     err = mSharedBufferClient->lock(bufIdx);
    536     LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
    537     return err;
    538 }
    539 
    540 int Surface::queueBuffer(android_native_buffer_t* buffer)
    541 {
    542     sp<SurfaceComposerClient> client(getClient());
    543     status_t err = validate();
    544     if (err != NO_ERROR)
    545         return err;
    546 
    547     if (mSwapRectangle.isValid()) {
    548         mDirtyRegion.set(mSwapRectangle);
    549     }
    550 
    551     int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
    552     mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
    553     err = mSharedBufferClient->queue(bufIdx);
    554     LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
    555 
    556     if (err == NO_ERROR) {
    557         // FIXME: can we avoid this IPC if we know there is one pending?
    558         client->signalServer();
    559     }
    560     return err;
    561 }
    562 
    563 int Surface::query(int what, int* value)
    564 {
    565     switch (what) {
    566     case NATIVE_WINDOW_WIDTH:
    567         *value = int(mWidth);
    568         return NO_ERROR;
    569     case NATIVE_WINDOW_HEIGHT:
    570         *value = int(mHeight);
    571         return NO_ERROR;
    572     case NATIVE_WINDOW_FORMAT:
    573         *value = int(mFormat);
    574         return NO_ERROR;
    575     }
    576     return BAD_VALUE;
    577 }
    578 
    579 int Surface::perform(int operation, va_list args)
    580 {
    581     int res = NO_ERROR;
    582     switch (operation) {
    583     case NATIVE_WINDOW_SET_USAGE:
    584         dispatch_setUsage( args );
    585         break;
    586     case NATIVE_WINDOW_CONNECT:
    587         res = dispatch_connect( args );
    588         break;
    589     case NATIVE_WINDOW_DISCONNECT:
    590         res = dispatch_disconnect( args );
    591         break;
    592     default:
    593         res = NAME_NOT_FOUND;
    594         break;
    595     }
    596     return res;
    597 }
    598 
    599 void Surface::dispatch_setUsage(va_list args) {
    600     int usage = va_arg(args, int);
    601     setUsage( usage );
    602 }
    603 int Surface::dispatch_connect(va_list args) {
    604     int api = va_arg(args, int);
    605     return connect( api );
    606 }
    607 int Surface::dispatch_disconnect(va_list args) {
    608     int api = va_arg(args, int);
    609     return disconnect( api );
    610 }
    611 
    612 
    613 void Surface::setUsage(uint32_t reqUsage)
    614 {
    615     Mutex::Autolock _l(mSurfaceLock);
    616     mUsage = reqUsage;
    617 }
    618 
    619 int Surface::connect(int api)
    620 {
    621     Mutex::Autolock _l(mSurfaceLock);
    622     int err = NO_ERROR;
    623     switch (api) {
    624         case NATIVE_WINDOW_API_EGL:
    625             if (mConnected) {
    626                 err = -EINVAL;
    627             } else {
    628                 mConnected = api;
    629             }
    630             break;
    631         default:
    632             err = -EINVAL;
    633             break;
    634     }
    635     return err;
    636 }
    637 
    638 int Surface::disconnect(int api)
    639 {
    640     Mutex::Autolock _l(mSurfaceLock);
    641     int err = NO_ERROR;
    642     switch (api) {
    643         case NATIVE_WINDOW_API_EGL:
    644             if (mConnected == api) {
    645                 mConnected = 0;
    646             } else {
    647                 err = -EINVAL;
    648             }
    649             break;
    650         default:
    651             err = -EINVAL;
    652             break;
    653     }
    654     return err;
    655 }
    656 
    657 uint32_t Surface::getUsage() const
    658 {
    659     Mutex::Autolock _l(mSurfaceLock);
    660     return mUsage;
    661 }
    662 
    663 int Surface::getConnectedApi() const
    664 {
    665     Mutex::Autolock _l(mSurfaceLock);
    666     return mConnected;
    667 }
    668 
    669 
    670 // ----------------------------------------------------------------------------
    671 
    672 status_t Surface::lock(SurfaceInfo* info, bool blocking) {
    673     return Surface::lock(info, NULL, blocking);
    674 }
    675 
    676 status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
    677 {
    678     if (getConnectedApi()) {
    679         LOGE("Surface::lock(%p) failed. Already connected to another API",
    680                 (android_native_window_t*)this);
    681         CallStack stack;
    682         stack.update();
    683         stack.dump("");
    684         return INVALID_OPERATION;
    685     }
    686 
    687     if (mApiLock.tryLock() != NO_ERROR) {
    688         LOGE("calling Surface::lock from different threads!");
    689         CallStack stack;
    690         stack.update();
    691         stack.dump("");
    692         return WOULD_BLOCK;
    693     }
    694 
    695     /* Here we're holding mApiLock */
    696 
    697     if (mLockedBuffer != 0) {
    698         LOGE("Surface::lock failed, already locked");
    699         mApiLock.unlock();
    700         return INVALID_OPERATION;
    701     }
    702 
    703     // we're intending to do software rendering from this point
    704     setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
    705 
    706     sp<GraphicBuffer> backBuffer;
    707     status_t err = dequeueBuffer(&backBuffer);
    708     LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
    709     if (err == NO_ERROR) {
    710         err = lockBuffer(backBuffer.get());
    711         LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
    712                 backBuffer->getIndex(), strerror(-err));
    713         if (err == NO_ERROR) {
    714             // we handle copy-back here...
    715 
    716             const Rect bounds(backBuffer->width, backBuffer->height);
    717             Region scratch(bounds);
    718             Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
    719 
    720             if (mNeedFullUpdate) {
    721                 // reset newDirtyRegion to bounds when a buffer is reallocated
    722                 // it would be better if this information was associated with
    723                 // the buffer and made available to outside of Surface.
    724                 // This will do for now though.
    725                 mNeedFullUpdate = false;
    726                 newDirtyRegion.set(bounds);
    727             } else {
    728                 newDirtyRegion.andSelf(bounds);
    729             }
    730 
    731             const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
    732             if (frontBuffer !=0 &&
    733                 backBuffer->width  == frontBuffer->width &&
    734                 backBuffer->height == frontBuffer->height &&
    735                 !(mFlags & ISurfaceComposer::eDestroyBackbuffer))
    736             {
    737                 const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
    738                 if (!copyback.isEmpty() && frontBuffer!=0) {
    739                     // copy front to back
    740                     copyBlt(backBuffer, frontBuffer, copyback);
    741                 }
    742             }
    743 
    744             mDirtyRegion = newDirtyRegion;
    745             mOldDirtyRegion = newDirtyRegion;
    746 
    747             void* vaddr;
    748             status_t res = backBuffer->lock(
    749                     GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
    750                     newDirtyRegion.bounds(), &vaddr);
    751 
    752             LOGW_IF(res, "failed locking buffer (handle = %p)",
    753                     backBuffer->handle);
    754 
    755             mLockedBuffer = backBuffer;
    756             other->w      = backBuffer->width;
    757             other->h      = backBuffer->height;
    758             other->s      = backBuffer->stride;
    759             other->usage  = backBuffer->usage;
    760             other->format = backBuffer->format;
    761             other->bits   = vaddr;
    762         }
    763     }
    764     mApiLock.unlock();
    765     return err;
    766 }
    767 
    768 status_t Surface::unlockAndPost()
    769 {
    770     if (mLockedBuffer == 0) {
    771         LOGE("Surface::unlockAndPost failed, no locked buffer");
    772         return INVALID_OPERATION;
    773     }
    774 
    775     status_t err = mLockedBuffer->unlock();
    776     LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
    777 
    778     err = queueBuffer(mLockedBuffer.get());
    779     LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
    780             mLockedBuffer->getIndex(), strerror(-err));
    781 
    782     mPostedBuffer = mLockedBuffer;
    783     mLockedBuffer = 0;
    784     return err;
    785 }
    786 
    787 void Surface::setSwapRectangle(const Rect& r) {
    788     Mutex::Autolock _l(mSurfaceLock);
    789     mSwapRectangle = r;
    790 }
    791 
    792 status_t Surface::getBufferLocked(int index, int usage)
    793 {
    794     sp<ISurface> s(mSurface);
    795     if (s == 0) return NO_INIT;
    796 
    797     status_t err = NO_MEMORY;
    798 
    799     // free the current buffer
    800     sp<GraphicBuffer>& currentBuffer(mBuffers[index]);
    801     if (currentBuffer != 0) {
    802         getBufferMapper().unregisterBuffer(currentBuffer->handle);
    803         currentBuffer.clear();
    804     }
    805 
    806     sp<GraphicBuffer> buffer = s->requestBuffer(index, usage);
    807     LOGE_IF(buffer==0,
    808             "ISurface::getBuffer(%d, %08x) returned NULL",
    809             index, usage);
    810     if (buffer != 0) { // this should never happen by construction
    811         LOGE_IF(buffer->handle == NULL,
    812                 "Surface (identity=%d) requestBuffer(%d, %08x) returned"
    813                 "a buffer with a null handle", mIdentity, index, usage);
    814         err = mSharedBufferClient->getStatus();
    815         LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
    816         if (!err && buffer->handle != NULL) {
    817             err = getBufferMapper().registerBuffer(buffer->handle);
    818             LOGW_IF(err, "registerBuffer(...) failed %d (%s)",
    819                     err, strerror(-err));
    820             if (err == NO_ERROR) {
    821                 currentBuffer = buffer;
    822                 currentBuffer->setIndex(index);
    823                 mNeedFullUpdate = true;
    824             }
    825         } else {
    826             err = err<0 ? err : NO_MEMORY;
    827         }
    828     }
    829     return err;
    830 }
    831 
    832 }; // namespace android
    833 
    834